Compare commits
	
		
			19 Commits
		
	
	
		
			0.3.1
			...
			property-d
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| cf95436aa9 | |||
| 0a9ea1982b | |||
| 0dfbb45238 | |||
| 7e7825760a | |||
| 203274a522 | |||
| 54c54e2adf | |||
| 6da9c16c4f | |||
| 5ace4e219c | |||
| c78eb1a272 | |||
| 7c39668eb6 | |||
| 4c3e370f70 | |||
| f7aaa76985 | |||
| 5ff49f4885 | |||
| 36c7eb1891 | |||
| 58210691ed | |||
| 0eb9886394 | |||
| 16ccec0d12 | |||
| e2fb1813f1 | |||
| 7245a4e212 | 
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@ -1,5 +1,6 @@
 | 
			
		||||
# User files
 | 
			
		||||
*.user
 | 
			
		||||
*.user.*
 | 
			
		||||
 | 
			
		||||
# Translation files
 | 
			
		||||
*.qm
 | 
			
		||||
 | 
			
		||||
@ -22,6 +22,9 @@ set (PPIC_CPP_FILES
 | 
			
		||||
    toolbutton.cpp
 | 
			
		||||
    settings.cpp
 | 
			
		||||
    settingsdialog.cpp
 | 
			
		||||
    aboutdialog.cpp
 | 
			
		||||
    metadatamodel.cpp
 | 
			
		||||
    metadatadialog.cpp
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
set (PPIC_HEADER_FILES
 | 
			
		||||
@ -34,6 +37,9 @@ set (PPIC_HEADER_FILES
 | 
			
		||||
    toolbutton.h
 | 
			
		||||
    settings.h
 | 
			
		||||
    settingsdialog.h
 | 
			
		||||
    aboutdialog.h
 | 
			
		||||
    metadatamodel.h
 | 
			
		||||
    metadatadialog.h
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
set (PPIC_QRC_FILES
 | 
			
		||||
@ -114,6 +120,9 @@ if (EXISTS "${CMAKE_SOURCE_DIR}/.git")
 | 
			
		||||
        )
 | 
			
		||||
        string (REGEX REPLACE "\n" "" _git_describe_long "${_git_describe_long}")
 | 
			
		||||
        ppic_set_version_via_describe(${_git_describe_long})
 | 
			
		||||
        target_compile_definitions(${EXE_NAME} PRIVATE
 | 
			
		||||
            GIT_DESCRIBE_VERSION_STRING="${_git_describe_long}"
 | 
			
		||||
        )
 | 
			
		||||
    endif ()
 | 
			
		||||
endif ()
 | 
			
		||||
 | 
			
		||||
@ -149,9 +158,15 @@ elseif (UNIX)
 | 
			
		||||
 | 
			
		||||
    # install shortcut
 | 
			
		||||
    install (
 | 
			
		||||
        FILES pineapple-pictures.desktop
 | 
			
		||||
        FILES dist/net.blumia.pineapple-pictures.desktop
 | 
			
		||||
        DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/applications"
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    # install app metadata file for appstream (and some other stuff using this metadata like snapcraft)
 | 
			
		||||
    install (
 | 
			
		||||
        FILES dist/appstream/net.blumia.pineapple-pictures.appdata.xml
 | 
			
		||||
        DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/metainfo"
 | 
			
		||||
    )
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
set (INSTALL_TARGETS_DEFAULT_ARGS
 | 
			
		||||
@ -184,7 +199,7 @@ set (CPACK_GENERATOR "TBZ2")
 | 
			
		||||
set (CPACK_PACKAGE_NAME "pineapple-pictures")
 | 
			
		||||
set (CPACK_PACKAGE_DESCRIPTION_SUMMARY "Yet another image viewer")
 | 
			
		||||
set (CPACK_PACKAGE_VENDOR "Gary Wang")
 | 
			
		||||
set (CPACK_PACKAGE_CONTACT "https://github.com/BLumia/PineapplePictures/issues/")
 | 
			
		||||
set (CPACK_PACKAGE_CONTACT "https://github.com/BLumia/pineapple-pictures/issues/")
 | 
			
		||||
if (WIN32)
 | 
			
		||||
    # ...
 | 
			
		||||
elseif (APPLE)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										2
									
								
								LICENSE
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								LICENSE
									
									
									
									
									
								
							@ -1,6 +1,6 @@
 | 
			
		||||
MIT License
 | 
			
		||||
 | 
			
		||||
Copyright (c) 2019 BLumia
 | 
			
		||||
Copyright (c) 2020 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
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										67
									
								
								README.zh_CN.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								README.zh_CN.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,67 @@
 | 
			
		||||
简单轻量的跨平台看图工具。
 | 
			
		||||
 | 
			
		||||
|CI|构建状态|
 | 
			
		||||
|---|---|
 | 
			
		||||
|Windows Build|[](https://ci.appveyor.com/project/BLumia/pineapplepictures/branch/master)|
 | 
			
		||||
|macOS Build||
 | 
			
		||||
|Ubuntu 20.04 Build||
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
## 立即获取!
 | 
			
		||||
 | 
			
		||||
 - [GitHub Release 页面](https://github.com/BLumia/pineapple-pictures/releases) | [gitee 发布页面](https://gitee.com/blumia/pineapple-pictures/releases)
 | 
			
		||||
 - Archlinux AUR: [pineapple-pictures-git](https://aur.archlinux.org/packages/pineapple-pictures-git/)
 | 
			
		||||
 | 
			
		||||
## 手动构建步骤:
 | 
			
		||||
 | 
			
		||||
当前状态,我们需要先确保如下依赖可用:
 | 
			
		||||
 | 
			
		||||
 - `cmake`: 我们所使用的构建系统
 | 
			
		||||
 - 包含 `qt5-svg` 与 `qt5-tools` 组件的 `qt5`: 此应用基于 Qt
 | 
			
		||||
 | 
			
		||||
然后我们就可以使用任何常规的 c++ 编译器如 g++ 或 msvc 来进行构建了
 | 
			
		||||
 | 
			
		||||
构建过程就是常规的 CMake 应用构建过程:
 | 
			
		||||
 | 
			
		||||
``` bash
 | 
			
		||||
$ mkdir build && cd build
 | 
			
		||||
$ cmake ..
 | 
			
		||||
$ cmake --build . # 如果你使用 Makefile 作为 CMake 生成器,也可以直接简单的使用 `make`
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
完毕后,一个名为 `ppic` 的可执行程序即会被生成以供使用。您也可以选择通过使用 CMake 生成的 `install` 目标继续将其安装到您的设备上(假设您使用 Makefile,即可执行 `make install` 来进行安装)。构建步骤完毕后,您也可以使用 `cpack` 来对应用程序进行打包。
 | 
			
		||||
 | 
			
		||||
此应用的图片格式支持依赖于 Qt 的 imageformats 插件,直接从您所用的发行版获取对应的图像格式插件即可。对于 Windows 用户,您可能需要手动构建和使用图像格式插件。下方给出了进一步的说明。
 | 
			
		||||
 | 
			
		||||
### Linux
 | 
			
		||||
 | 
			
		||||
常规的构建步骤即可完成构建,不需要额外的处理步骤 ;)
 | 
			
		||||
 | 
			
		||||
对于 Archlinux 发行版的用户,这里还有一个 [PKGBUILD](https://aur.archlinux.org/cgit/aur.git/tree/PKGBUILD?h=pineapple-pictures-git) 可供使用和参考。
 | 
			
		||||
 | 
			
		||||
对于在基于 debian 的发行版中进行打包的需求, `CMakeLists.txt` 已经提供了一些基本的 cpack 配置以便生成一个有效的 `.deb` 软件包。在构建步骤完毕后,使用 `cpack -G DEB` 即可生成 DEB 软件包。您也可以参考 `.github/workflows/ubuntu.yml` 来查看当前正在使用的 CI 配置是如何进行打包的。
 | 
			
		||||
 | 
			
		||||
目前,`DEB` 是当前唯一受到直接支持的 cpack 生成目标。若希望为此项目添加其它的 cpack 目标支持,欢迎发起合并请求。
 | 
			
		||||
 | 
			
		||||
### Windows
 | 
			
		||||
 | 
			
		||||
上述的构建步骤在 Windows 中也适用,但由于 Windows 中不具备类如大多 Linux 发行版中所提供的方便的软件包管理机制,故如果您需要任何 Qt 官方支持之外的图像格式例如 psd,xcf,kra 等格式的支持,你就可能需要自行获取并构建对应的 imageformats 插件,并在您最终生成的可执行文件中一并提供这些插件。若您不需要这些额外的图像格式支持,这个步骤也可以直接跳过。
 | 
			
		||||
 | 
			
		||||
我们所提供的预编译好的 Windows 程序包含了 kimageformats 插件来提供额外(kra, xcf, psd 等)格式的支持。您可以参考 `appveyor.yml` 来查看我们是如何构建并打包 Windows 可执行程序的。
 | 
			
		||||
 | 
			
		||||
[KDE Craft](https://community.kde.org/Craft) 环境也可以被用来构建此应用程序。我也创建了一个蓝图来进行此项目的构建和打包。但由于暂时并未配置 CI 部署此环境来进行 KDE Craft 环境下的构建,故对应的蓝图仓库也尚未公开提供,或许后续会开放出来。
 | 
			
		||||
 | 
			
		||||
### macOS
 | 
			
		||||
 | 
			
		||||
由于我没有 mac 设备,故 macOS 暂时不受任何支持。不过我们目前有一个 GitHub Action 来执行 macOS 环境下的构建(见 `.github/workflows/macos.yml`)所以至少 macOS 下是可以顺利进行构建的。如果您想完善对 macOS 的支持,也欢迎您创建合并请求 ;P
 | 
			
		||||
 | 
			
		||||
## 帮助翻译!
 | 
			
		||||
 | 
			
		||||
[在 Transifex 上帮助此项目翻译到更多语言!](https://www.transifex.com/blumia/pineapple-pictures/)
 | 
			
		||||
 | 
			
		||||
若 Transifex 上没有您所希望进行翻译的语言,请通过 Issue 的形式告诉我。
 | 
			
		||||
 | 
			
		||||
## 许可协议
 | 
			
		||||
 | 
			
		||||
此项目使用 MIT 协议进行发布。
 | 
			
		||||
							
								
								
									
										157
									
								
								aboutdialog.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										157
									
								
								aboutdialog.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,157 @@
 | 
			
		||||
#include "aboutdialog.h"
 | 
			
		||||
 | 
			
		||||
#include <QAbstractButton>
 | 
			
		||||
#include <QDialogButtonBox>
 | 
			
		||||
#include <QTextBrowser>
 | 
			
		||||
#include <QTabWidget>
 | 
			
		||||
#include <QVBoxLayout>
 | 
			
		||||
#include <QApplication>
 | 
			
		||||
#include <QLabel>
 | 
			
		||||
#include <QPushButton>
 | 
			
		||||
 | 
			
		||||
AboutDialog::AboutDialog(QWidget *parent)
 | 
			
		||||
    : 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)
 | 
			
		||||
{
 | 
			
		||||
    this->setWindowTitle(tr("About"));
 | 
			
		||||
 | 
			
		||||
    QStringList helpStr {
 | 
			
		||||
        QStringLiteral("<p>%1</p>").arg(tr("Launch application with image file path as argument to load the file.")),
 | 
			
		||||
        QStringLiteral("<p>%1</p>").arg(tr("Drag and drop image file onto the window is also supported.")),
 | 
			
		||||
        QStringLiteral("<p>%1</p>").arg(tr("Context menu option explanation:")),
 | 
			
		||||
        QStringLiteral("<ul>"),
 | 
			
		||||
        QStringLiteral("<li><b>%1</b>:<br/>%2</li>").arg(
 | 
			
		||||
            QCoreApplication::translate("MainWindow", "Stay on top"),
 | 
			
		||||
            this->tr("Make window stay on top of all other windows.")
 | 
			
		||||
        ),
 | 
			
		||||
        QStringLiteral("<li><b>%1</b>:<br/>%2</li>").arg(
 | 
			
		||||
            QCoreApplication::translate("MainWindow", "Protected mode"),
 | 
			
		||||
            this->tr("Avoid close window accidentally. (eg. by double clicking the window)")
 | 
			
		||||
        ),
 | 
			
		||||
        QStringLiteral("</ul>")
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    QStringList aboutStr {
 | 
			
		||||
        QStringLiteral("<center><img width='128' height='128' src=':/icons/app-icon.svg'/><br/>"),
 | 
			
		||||
        qApp->applicationDisplayName(),
 | 
			
		||||
#ifdef GIT_DESCRIBE_VERSION_STRING
 | 
			
		||||
        (QStringLiteral("<br/>") + tr("Version: %1").arg(GIT_DESCRIBE_VERSION_STRING)),
 | 
			
		||||
#endif // GIT_DESCRIBE_VERSION_STRING
 | 
			
		||||
        QStringLiteral("<hr/>"),
 | 
			
		||||
        tr("Copyright (c) 2020 %1").arg(QStringLiteral("<a href='https://github.com/BLumia'>@BLumia</a>")),
 | 
			
		||||
        QStringLiteral("<br/>"),
 | 
			
		||||
        tr("Logo designed by %1").arg(QStringLiteral("<a href='https://github.com/Lovelyblack'>@Lovelyblack</a>")),
 | 
			
		||||
        QStringLiteral("<hr/>"),
 | 
			
		||||
        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")),
 | 
			
		||||
        QStringLiteral("</center>")
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    QStringList specialThanksStr {
 | 
			
		||||
        QStringLiteral("<h1 align='center'>%1</h1><a href='%2'>%3</a><p>%4</p>").arg(
 | 
			
		||||
            tr("Contributors"),
 | 
			
		||||
            QStringLiteral("https://github.com/BLumia/pineapple-pictures/graphs/contributors"),
 | 
			
		||||
            tr("List of contributors on GitHub"),
 | 
			
		||||
            tr("Thanks to all people who contributed to this project.")
 | 
			
		||||
        ),
 | 
			
		||||
#if 0
 | 
			
		||||
        QStringLiteral("<h1 align='center'>%1</h1><p>%2</p>").arg(
 | 
			
		||||
            tr("Translators"),
 | 
			
		||||
            tr("I would like to thank the following people who volunteered to translate this application.")
 | 
			
		||||
        ),
 | 
			
		||||
#endif
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    QStringList licenseStr {
 | 
			
		||||
        QStringLiteral("<h1 align='center'><b>%1</b></h1>").arg(tr("Your Rights")),
 | 
			
		||||
        QStringLiteral("<p>%1</p><p>%2</p><ul><li>%3</li><li>%4</li><li>%5</li><li>%6</li></ul>").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(QStringLiteral("<i>%1</i>")),
 | 
			
		||||
        QStringLiteral("<p>%1</p>").arg(tr("The MIT license guarantees you this freedom. Nobody is ever permitted to take it away.")),
 | 
			
		||||
        QStringLiteral("<hr/><pre>%2</pre>")
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    QString mitLicense(QStringLiteral(R"(Expat/MIT License
 | 
			
		||||
 | 
			
		||||
Copyright (c) 2020 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.
 | 
			
		||||
)"));
 | 
			
		||||
 | 
			
		||||
    QStringList thirdPartyLibsStr {
 | 
			
		||||
        QStringLiteral("<h1 align='center'><b>%1</b></h1>").arg(tr("Third-party Libraries used by %1")),
 | 
			
		||||
        tr("%1 is built on the following free software libraries:"),
 | 
			
		||||
        QStringLiteral("<ul>"),
 | 
			
		||||
        QStringLiteral("<li><a href='%1'>%2</a>: %3</li>").arg("https://www.qt.io/", "Qt", "GPLv2 + GPLv3 + LGPLv2.1 + LGPLv3"),
 | 
			
		||||
        QStringLiteral("</ul>")
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    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(QStringLiteral("<i>%1</i>")).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()
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QSize AboutDialog::sizeHint() const
 | 
			
		||||
{
 | 
			
		||||
    return QSize(520, 350);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										32
									
								
								aboutdialog.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								aboutdialog.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,32 @@
 | 
			
		||||
#ifndef ABOUTDIALOG_H
 | 
			
		||||
#define ABOUTDIALOG_H
 | 
			
		||||
 | 
			
		||||
#include <QDialog>
 | 
			
		||||
 | 
			
		||||
QT_BEGIN_NAMESPACE
 | 
			
		||||
class QTextBrowser;
 | 
			
		||||
class QTabWidget;
 | 
			
		||||
class QDialogButtonBox;
 | 
			
		||||
QT_END_NAMESPACE
 | 
			
		||||
 | 
			
		||||
class AboutDialog : public QDialog
 | 
			
		||||
{
 | 
			
		||||
    Q_OBJECT
 | 
			
		||||
public:
 | 
			
		||||
    explicit AboutDialog(QWidget *parent = nullptr);
 | 
			
		||||
    ~AboutDialog() override;
 | 
			
		||||
 | 
			
		||||
    QSize sizeHint() const override;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    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
 | 
			
		||||
@ -33,7 +33,7 @@ BottomButtonGroup::BottomButtonGroup(QWidget *parent)
 | 
			
		||||
        QPushButton * btn = new QPushButton(QIcon(QStringLiteral(":/icons/") + text), "");
 | 
			
		||||
        btn->setIconSize(QSize(40, 40));
 | 
			
		||||
        btn->setFixedSize(40, 40);
 | 
			
		||||
        connect(btn, &QAbstractButton::clicked, btn, func);
 | 
			
		||||
        QObject::connect(btn, &QAbstractButton::clicked, btn, func);
 | 
			
		||||
        return btn;
 | 
			
		||||
    };
 | 
			
		||||
    addButton(newBtn("zoom-original", [this]() {
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										19
									
								
								dist/appstream/net.blumia.pineapple-pictures.appdata.xml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								dist/appstream/net.blumia.pineapple-pictures.appdata.xml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,19 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<component type="desktop-application">
 | 
			
		||||
  <id>net.blumia.pineapple-pictures</id>
 | 
			
		||||
  <metadata_license>CC0-1.0</metadata_license>
 | 
			
		||||
  <project_license>MIT</project_license>
 | 
			
		||||
  <name>Pineapple Pictures</name>
 | 
			
		||||
  <name xml:lang="zh-CN">菠萝看图</name>
 | 
			
		||||
  <summary>Image Viewer</summary>
 | 
			
		||||
  <summary xml:lang="zh-CN">图像查看器</summary>
 | 
			
		||||
  <description>
 | 
			
		||||
    <p>Pineapple Pictures is a lightweight and easy to use image viewer, comes with a handy navigation thumbnail when zoom-in, and doesn't contains any image management support.</p>
 | 
			
		||||
    <p xml:lang="zh-CN">菠萝看图是一个轻量级易用的图像查看器,在图片放大时提供了方便的鸟瞰导航功能,且不包含任何图片管理功能。</p>
 | 
			
		||||
  </description>
 | 
			
		||||
  <url type="homepage">https://github.com/BLumia/pineapple-pictures</url>
 | 
			
		||||
  <url type="bugtracker">https://github.com/BLumia/pineapple-pictures/issues</url>
 | 
			
		||||
  <provides>
 | 
			
		||||
    <binary>ppic</binary>
 | 
			
		||||
  </provides>
 | 
			
		||||
</component>
 | 
			
		||||
@ -24,7 +24,9 @@ GraphicsScene::~GraphicsScene()
 | 
			
		||||
void GraphicsScene::showImage(const QPixmap &pixmap)
 | 
			
		||||
{
 | 
			
		||||
    this->clear();
 | 
			
		||||
    m_theThing = this->addPixmap(pixmap);
 | 
			
		||||
    QGraphicsPixmapItem * pixmapItem = this->addPixmap(pixmap);
 | 
			
		||||
    pixmapItem->setShapeMode(QGraphicsPixmapItem::BoundingRectShape);
 | 
			
		||||
    m_theThing = pixmapItem;
 | 
			
		||||
    this->setSceneRect(m_theThing->boundingRect());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -35,10 +35,6 @@ void GraphicsView::showFileFromUrl(const QUrl &url, bool doRequestGallery)
 | 
			
		||||
    // TODO: remove this workaround when M$ change the "wsl$" hostname.
 | 
			
		||||
    if (Q_UNLIKELY(url.scheme() == QStringLiteral("qtbug-86277"))) {
 | 
			
		||||
        filePath = url.path();
 | 
			
		||||
        // Qt's QUrl won't work with such hostname anyway so the urls will
 | 
			
		||||
        // still be the wrong one when requesting gallery. So we just don't
 | 
			
		||||
        // request gallery here...
 | 
			
		||||
        doRequestGallery = false;
 | 
			
		||||
    }
 | 
			
		||||
#endif // Q_OS_WIN
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										1956
									
								
								icons/app-icon.svg
									
									
									
									
									
								
							
							
						
						
									
										1956
									
								
								icons/app-icon.svg
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| 
		 Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 44 KiB  | 
@ -1,6 +1,164 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<!DOCTYPE TS>
 | 
			
		||||
<TS version="2.1">
 | 
			
		||||
<context>
 | 
			
		||||
    <name>AboutDialog</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="22"/>
 | 
			
		||||
        <source>About</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="25"/>
 | 
			
		||||
        <source>Launch application with image file path as argument to load the file.</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="26"/>
 | 
			
		||||
        <source>Drag and drop image file onto the window is also supported.</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="27"/>
 | 
			
		||||
        <source>Context menu option explanation:</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="31"/>
 | 
			
		||||
        <source>Make window stay on top of all other windows.</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="35"/>
 | 
			
		||||
        <source>Avoid close window accidentally. (eg. by double clicking the window)</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="44"/>
 | 
			
		||||
        <source>Version: %1</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="47"/>
 | 
			
		||||
        <source>Copyright (c) 2020 %1</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="49"/>
 | 
			
		||||
        <source>Logo designed by %1</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="51"/>
 | 
			
		||||
        <source>Built with Qt %1 (%2)</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="52"/>
 | 
			
		||||
        <source>Source code</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="58"/>
 | 
			
		||||
        <source>Contributors</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="60"/>
 | 
			
		||||
        <source>List of contributors on GitHub</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="61"/>
 | 
			
		||||
        <source>Thanks to all people who contributed to this project.</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="65"/>
 | 
			
		||||
        <source>Translators</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="66"/>
 | 
			
		||||
        <source>I would like to thank the following people who volunteered to translate this application.</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="131"/>
 | 
			
		||||
        <source>&Special Thanks</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="133"/>
 | 
			
		||||
        <source>&Third-party Libraries</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="72"/>
 | 
			
		||||
        <source>Your Rights</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="74"/>
 | 
			
		||||
        <source>%1 is released under the MIT License.</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="75"/>
 | 
			
		||||
        <source>This license grants people a number of freedoms:</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="76"/>
 | 
			
		||||
        <source>You are free to use %1, for any purpose</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="77"/>
 | 
			
		||||
        <source>You are free to distribute %1</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="78"/>
 | 
			
		||||
        <source>You can study how %1 works and change it</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="79"/>
 | 
			
		||||
        <source>You can distribute changed versions of %1</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="81"/>
 | 
			
		||||
        <source>The MIT license guarantees you this freedom. Nobody is ever permitted to take it away.</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="109"/>
 | 
			
		||||
        <source>Third-party Libraries used by %1</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="110"/>
 | 
			
		||||
        <source>%1 is built on the following free software libraries:</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="129"/>
 | 
			
		||||
        <source>&Help</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="130"/>
 | 
			
		||||
        <source>&About</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="132"/>
 | 
			
		||||
        <source>&License</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
<context>
 | 
			
		||||
    <name>GraphicsScene</name>
 | 
			
		||||
    <message>
 | 
			
		||||
@ -12,22 +170,22 @@
 | 
			
		||||
<context>
 | 
			
		||||
    <name>GraphicsView</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../graphicsview.cpp" line="247"/>
 | 
			
		||||
        <location filename="../graphicsview.cpp" line="254"/>
 | 
			
		||||
        <source>File url list is empty</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../graphicsview.cpp" line="46"/>
 | 
			
		||||
        <location filename="../graphicsview.cpp" line="53"/>
 | 
			
		||||
        <source>File is not a valid image</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../graphicsview.cpp" line="255"/>
 | 
			
		||||
        <location filename="../graphicsview.cpp" line="262"/>
 | 
			
		||||
        <source>Image data is invalid</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../graphicsview.cpp" line="262"/>
 | 
			
		||||
        <location filename="../graphicsview.cpp" line="269"/>
 | 
			
		||||
        <source>Not supported mimedata: %1</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
@ -35,107 +193,134 @@
 | 
			
		||||
<context>
 | 
			
		||||
    <name>MainWindow</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../mainwindow.cpp" line="174"/>
 | 
			
		||||
        <location filename="../mainwindow.cpp" line="178"/>
 | 
			
		||||
        <source>File url list is empty</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../mainwindow.cpp" line="396"/>
 | 
			
		||||
        <location filename="../mainwindow.cpp" line="417"/>
 | 
			
		||||
        <source>&Copy</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../mainwindow.cpp" line="417"/>
 | 
			
		||||
        <location filename="../mainwindow.cpp" line="438"/>
 | 
			
		||||
        <source>Copy P&ixmap</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../mainwindow.cpp" line="422"/>
 | 
			
		||||
        <location filename="../mainwindow.cpp" line="443"/>
 | 
			
		||||
        <source>Copy &File Path</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../mainwindow.cpp" line="432"/>
 | 
			
		||||
        <location filename="../mainwindow.cpp" line="453"/>
 | 
			
		||||
        <source>&Paste Image</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../mainwindow.cpp" line="438"/>
 | 
			
		||||
        <location filename="../mainwindow.cpp" line="459"/>
 | 
			
		||||
        <source>&Paste Image File</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../mainwindow.cpp" line="443"/>
 | 
			
		||||
        <location filename="../mainwindow.cpp" line="471"/>
 | 
			
		||||
        <location filename="../mainwindow.cpp" line="492"/>
 | 
			
		||||
        <source>Properties</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="30"/>
 | 
			
		||||
        <location filename="../mainwindow.cpp" line="464"/>
 | 
			
		||||
        <source>Stay on top</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../mainwindow.cpp" line="450"/>
 | 
			
		||||
        <location filename="../mainwindow.cpp" line="472"/>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="34"/>
 | 
			
		||||
        <location filename="../mainwindow.cpp" line="471"/>
 | 
			
		||||
        <source>Protected mode</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../mainwindow.cpp" line="457"/>
 | 
			
		||||
        <location filename="../mainwindow.cpp" line="478"/>
 | 
			
		||||
        <source>Configure...</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../mainwindow.cpp" line="464"/>
 | 
			
		||||
        <location filename="../mainwindow.cpp" line="485"/>
 | 
			
		||||
        <source>Help</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
<context>
 | 
			
		||||
    <name>MetadataDialog</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../mainwindow.cpp" line="467"/>
 | 
			
		||||
        <source>Launch application with image file path as argument to load the file.</source>
 | 
			
		||||
        <location filename="../metadatadialog.cpp" line="16"/>
 | 
			
		||||
        <source>Image Metadata</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
<context>
 | 
			
		||||
    <name>MetadataModel</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../metadatamodel.cpp" line="29"/>
 | 
			
		||||
        <source>General</source>
 | 
			
		||||
        <comment>General info about the image, section name.</comment>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../mainwindow.cpp" line="468"/>
 | 
			
		||||
        <source>Drag and drop image file onto the window is also supported.</source>
 | 
			
		||||
        <location filename="../metadatamodel.cpp" line="32"/>
 | 
			
		||||
        <source>File Name</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../mainwindow.cpp" line="470"/>
 | 
			
		||||
        <source>Context menu option explanation:</source>
 | 
			
		||||
        <location filename="../metadatamodel.cpp" line="34"/>
 | 
			
		||||
        <source>File Size</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../mainwindow.cpp" line="471"/>
 | 
			
		||||
        <source>Make window stay on top of all other windows.</source>
 | 
			
		||||
        <location filename="../metadatamodel.cpp" line="36"/>
 | 
			
		||||
        <source>Last Modified</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../mainwindow.cpp" line="472"/>
 | 
			
		||||
        <source>Avoid close window accidentally. (eg. by double clicking the window)</source>
 | 
			
		||||
        <location filename="../metadatamodel.cpp" line="38"/>
 | 
			
		||||
        <source>Image Size</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../metadatamodel.cpp" line="46"/>
 | 
			
		||||
        <source>%1 x %2</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
<context>
 | 
			
		||||
    <name>SettingsDialog</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../settingsdialog.cpp" line="18"/>
 | 
			
		||||
        <source>Do nothing</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../settingsdialog.cpp" line="19"/>
 | 
			
		||||
        <source>Close the window</source>
 | 
			
		||||
        <location filename="../settingsdialog.cpp" line="15"/>
 | 
			
		||||
        <source>Settings</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../settingsdialog.cpp" line="20"/>
 | 
			
		||||
        <source>Do nothing</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../settingsdialog.cpp" line="21"/>
 | 
			
		||||
        <source>Close the window</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../settingsdialog.cpp" line="22"/>
 | 
			
		||||
        <source>Toggle maximize</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../settingsdialog.cpp" line="28"/>
 | 
			
		||||
        <location filename="../settingsdialog.cpp" line="30"/>
 | 
			
		||||
        <source>Stay on top when start-up</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../settingsdialog.cpp" line="29"/>
 | 
			
		||||
        <location filename="../settingsdialog.cpp" line="31"/>
 | 
			
		||||
        <source>Double-click behavior</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,164 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<!DOCTYPE TS>
 | 
			
		||||
<TS version="2.1" language="zh_CN">
 | 
			
		||||
<context>
 | 
			
		||||
    <name>AboutDialog</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="22"/>
 | 
			
		||||
        <source>About</source>
 | 
			
		||||
        <translation>关于</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="25"/>
 | 
			
		||||
        <source>Launch application with image file path as argument to load the file.</source>
 | 
			
		||||
        <translation>以图片文件的路径作为参数运行程序即可直接打开图片文件。</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="26"/>
 | 
			
		||||
        <source>Drag and drop image file onto the window is also supported.</source>
 | 
			
		||||
        <translation>也支持拖放图片文件到窗口内来加载图片。</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="27"/>
 | 
			
		||||
        <source>Context menu option explanation:</source>
 | 
			
		||||
        <translation>菜单项说明:</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="31"/>
 | 
			
		||||
        <source>Make window stay on top of all other windows.</source>
 | 
			
		||||
        <translation>使窗口始终至于其它非置顶窗口上方。</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="35"/>
 | 
			
		||||
        <source>Avoid close window accidentally. (eg. by double clicking the window)</source>
 | 
			
		||||
        <translation>避免窗口意外关闭。(如:不小心双击了窗口触发了关闭窗口行为)</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="44"/>
 | 
			
		||||
        <source>Version: %1</source>
 | 
			
		||||
        <translation>版本: %1</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="47"/>
 | 
			
		||||
        <source>Copyright (c) 2020 %1</source>
 | 
			
		||||
        <translation>版权所有 (c) 2020 %1</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="49"/>
 | 
			
		||||
        <source>Logo designed by %1</source>
 | 
			
		||||
        <translation>Logo 由 %1 设计</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="51"/>
 | 
			
		||||
        <source>Built with Qt %1 (%2)</source>
 | 
			
		||||
        <translation>使用 Qt %1 (%2) 进行构建</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="52"/>
 | 
			
		||||
        <source>Source code</source>
 | 
			
		||||
        <translation>源代码</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="58"/>
 | 
			
		||||
        <source>Contributors</source>
 | 
			
		||||
        <translation>贡献者</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="60"/>
 | 
			
		||||
        <source>List of contributors on GitHub</source>
 | 
			
		||||
        <translation>GitHub 上的贡献者列表</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="61"/>
 | 
			
		||||
        <source>Thanks to all people who contributed to this project.</source>
 | 
			
		||||
        <translation>感谢所有参与此项目的朋友。</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="65"/>
 | 
			
		||||
        <source>Translators</source>
 | 
			
		||||
        <translation>翻译者</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="66"/>
 | 
			
		||||
        <source>I would like to thank the following people who volunteered to translate this application.</source>
 | 
			
		||||
        <translation>我想要感谢下列自愿参与翻译此应用程序的朋友。</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="131"/>
 | 
			
		||||
        <source>&Special Thanks</source>
 | 
			
		||||
        <translation>致谢(&S)</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="133"/>
 | 
			
		||||
        <source>&Third-party Libraries</source>
 | 
			
		||||
        <translation>第三方程序库(&T)</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="72"/>
 | 
			
		||||
        <source>Your Rights</source>
 | 
			
		||||
        <translation>用户的权利</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="74"/>
 | 
			
		||||
        <source>%1 is released under the MIT License.</source>
 | 
			
		||||
        <translation>%1 是在 MIT 许可协议下发布的。</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="75"/>
 | 
			
		||||
        <source>This license grants people a number of freedoms:</source>
 | 
			
		||||
        <translation>此许可证赋予人们以下自由的权利:</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="76"/>
 | 
			
		||||
        <source>You are free to use %1, for any purpose</source>
 | 
			
		||||
        <translation>任何人都可以为了任何目的自由地使用 %1</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="77"/>
 | 
			
		||||
        <source>You are free to distribute %1</source>
 | 
			
		||||
        <translation>任何人都可以自由地分发 %1</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="78"/>
 | 
			
		||||
        <source>You can study how %1 works and change it</source>
 | 
			
		||||
        <translation>任何人都可以自由地研究 %1 的工作原理并对其进行修改</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="79"/>
 | 
			
		||||
        <source>You can distribute changed versions of %1</source>
 | 
			
		||||
        <translation>任何人都可以自由地分发修改过的 %1 版本</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="81"/>
 | 
			
		||||
        <source>The MIT license guarantees you this freedom. Nobody is ever permitted to take it away.</source>
 | 
			
		||||
        <translation>此软件通过 MIT 许可证赋予用户上述自由,任何人无权剥夺。</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="109"/>
 | 
			
		||||
        <source>Third-party Libraries used by %1</source>
 | 
			
		||||
        <translation>%1 使用的第三方程序库</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="110"/>
 | 
			
		||||
        <source>%1 is built on the following free software libraries:</source>
 | 
			
		||||
        <translation>%1 采用了下列自由软件程序库进行构建:</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="129"/>
 | 
			
		||||
        <source>&Help</source>
 | 
			
		||||
        <translation>帮助(&H)</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="130"/>
 | 
			
		||||
        <source>&About</source>
 | 
			
		||||
        <translation>关于(&A)</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="132"/>
 | 
			
		||||
        <source>&License</source>
 | 
			
		||||
        <translation>软件许可证(&L)</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
<context>
 | 
			
		||||
    <name>GraphicsScene</name>
 | 
			
		||||
    <message>
 | 
			
		||||
@ -12,22 +170,22 @@
 | 
			
		||||
<context>
 | 
			
		||||
    <name>GraphicsView</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../graphicsview.cpp" line="247"/>
 | 
			
		||||
        <location filename="../graphicsview.cpp" line="254"/>
 | 
			
		||||
        <source>File url list is empty</source>
 | 
			
		||||
        <translation>文件 URL 列表为空</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../graphicsview.cpp" line="46"/>
 | 
			
		||||
        <location filename="../graphicsview.cpp" line="53"/>
 | 
			
		||||
        <source>File is not a valid image</source>
 | 
			
		||||
        <translation>文件不是有效的图片文件</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../graphicsview.cpp" line="255"/>
 | 
			
		||||
        <location filename="../graphicsview.cpp" line="262"/>
 | 
			
		||||
        <source>Image data is invalid</source>
 | 
			
		||||
        <translation>图片数据无效</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../graphicsview.cpp" line="262"/>
 | 
			
		||||
        <location filename="../graphicsview.cpp" line="269"/>
 | 
			
		||||
        <source>Not supported mimedata: %1</source>
 | 
			
		||||
        <translation>不受支持的 MimeData 格式:%1</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
@ -35,111 +193,134 @@
 | 
			
		||||
<context>
 | 
			
		||||
    <name>MainWindow</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../mainwindow.cpp" line="174"/>
 | 
			
		||||
        <location filename="../mainwindow.cpp" line="178"/>
 | 
			
		||||
        <source>File url list is empty</source>
 | 
			
		||||
        <translation>文件 URL 列表为空</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../mainwindow.cpp" line="396"/>
 | 
			
		||||
        <location filename="../mainwindow.cpp" line="417"/>
 | 
			
		||||
        <source>&Copy</source>
 | 
			
		||||
        <translation>复制(&C)</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <source>Copy &Pixmap</source>
 | 
			
		||||
        <translation type="vanished">复制位图(&P)</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../mainwindow.cpp" line="417"/>
 | 
			
		||||
        <location filename="../mainwindow.cpp" line="438"/>
 | 
			
		||||
        <source>Copy P&ixmap</source>
 | 
			
		||||
        <translation>复制位图(&I)</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../mainwindow.cpp" line="422"/>
 | 
			
		||||
        <location filename="../mainwindow.cpp" line="443"/>
 | 
			
		||||
        <source>Copy &File Path</source>
 | 
			
		||||
        <translation>复制文件路径(&F)</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../mainwindow.cpp" line="432"/>
 | 
			
		||||
        <location filename="../mainwindow.cpp" line="453"/>
 | 
			
		||||
        <source>&Paste Image</source>
 | 
			
		||||
        <translation>粘贴图像(&P)</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../mainwindow.cpp" line="438"/>
 | 
			
		||||
        <location filename="../mainwindow.cpp" line="459"/>
 | 
			
		||||
        <source>&Paste Image File</source>
 | 
			
		||||
        <translation>粘贴图像文件(&P)</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../mainwindow.cpp" line="443"/>
 | 
			
		||||
        <location filename="../mainwindow.cpp" line="471"/>
 | 
			
		||||
        <location filename="../mainwindow.cpp" line="492"/>
 | 
			
		||||
        <source>Properties</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="30"/>
 | 
			
		||||
        <location filename="../mainwindow.cpp" line="464"/>
 | 
			
		||||
        <source>Stay on top</source>
 | 
			
		||||
        <translation>总在最前</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../mainwindow.cpp" line="450"/>
 | 
			
		||||
        <location filename="../mainwindow.cpp" line="472"/>
 | 
			
		||||
        <location filename="../aboutdialog.cpp" line="34"/>
 | 
			
		||||
        <location filename="../mainwindow.cpp" line="471"/>
 | 
			
		||||
        <source>Protected mode</source>
 | 
			
		||||
        <translation>保护模式</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../mainwindow.cpp" line="457"/>
 | 
			
		||||
        <location filename="../mainwindow.cpp" line="478"/>
 | 
			
		||||
        <source>Configure...</source>
 | 
			
		||||
        <translation>设置...</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../mainwindow.cpp" line="464"/>
 | 
			
		||||
        <location filename="../mainwindow.cpp" line="485"/>
 | 
			
		||||
        <source>Help</source>
 | 
			
		||||
        <translation>帮助</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
<context>
 | 
			
		||||
    <name>MetadataDialog</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../mainwindow.cpp" line="467"/>
 | 
			
		||||
        <source>Launch application with image file path as argument to load the file.</source>
 | 
			
		||||
        <translation>以图片文件的路径作为参数运行程序即可直接打开图片文件。</translation>
 | 
			
		||||
        <location filename="../metadatadialog.cpp" line="16"/>
 | 
			
		||||
        <source>Image Metadata</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
<context>
 | 
			
		||||
    <name>MetadataModel</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../metadatamodel.cpp" line="29"/>
 | 
			
		||||
        <source>General</source>
 | 
			
		||||
        <comment>General info about the image, section name.</comment>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../mainwindow.cpp" line="468"/>
 | 
			
		||||
        <source>Drag and drop image file onto the window is also supported.</source>
 | 
			
		||||
        <translation>也支持拖放图片文件到窗口内来加载图片。</translation>
 | 
			
		||||
        <location filename="../metadatamodel.cpp" line="32"/>
 | 
			
		||||
        <source>File Name</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../mainwindow.cpp" line="470"/>
 | 
			
		||||
        <source>Context menu option explanation:</source>
 | 
			
		||||
        <translation>菜单项说明:</translation>
 | 
			
		||||
        <location filename="../metadatamodel.cpp" line="34"/>
 | 
			
		||||
        <source>File Size</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../mainwindow.cpp" line="471"/>
 | 
			
		||||
        <source>Make window stay on top of all other windows.</source>
 | 
			
		||||
        <translation>使窗口始终至于其它非置顶窗口上方。</translation>
 | 
			
		||||
        <location filename="../metadatamodel.cpp" line="36"/>
 | 
			
		||||
        <source>Last Modified</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../mainwindow.cpp" line="472"/>
 | 
			
		||||
        <source>Avoid close window accidentally. (eg. by double clicking the window)</source>
 | 
			
		||||
        <translation>避免窗口意外关闭。(如:不小心双击了窗口触发了关闭窗口行为)</translation>
 | 
			
		||||
        <location filename="../metadatamodel.cpp" line="38"/>
 | 
			
		||||
        <source>Image Size</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../metadatamodel.cpp" line="46"/>
 | 
			
		||||
        <source>%1 x %2</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
<context>
 | 
			
		||||
    <name>SettingsDialog</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../settingsdialog.cpp" line="18"/>
 | 
			
		||||
        <location filename="../settingsdialog.cpp" line="15"/>
 | 
			
		||||
        <source>Settings</source>
 | 
			
		||||
        <translation>设定</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../settingsdialog.cpp" line="20"/>
 | 
			
		||||
        <source>Do nothing</source>
 | 
			
		||||
        <translation>什么也不做</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../settingsdialog.cpp" line="19"/>
 | 
			
		||||
        <location filename="../settingsdialog.cpp" line="21"/>
 | 
			
		||||
        <source>Close the window</source>
 | 
			
		||||
        <translation>关闭窗口</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../settingsdialog.cpp" line="20"/>
 | 
			
		||||
        <location filename="../settingsdialog.cpp" line="22"/>
 | 
			
		||||
        <source>Toggle maximize</source>
 | 
			
		||||
        <translation>最大化窗口</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../settingsdialog.cpp" line="28"/>
 | 
			
		||||
        <location filename="../settingsdialog.cpp" line="30"/>
 | 
			
		||||
        <source>Stay on top when start-up</source>
 | 
			
		||||
        <translation>启动时保持窗口总在最前</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../settingsdialog.cpp" line="29"/>
 | 
			
		||||
        <location filename="../settingsdialog.cpp" line="31"/>
 | 
			
		||||
        <source>Double-click behavior</source>
 | 
			
		||||
        <translation>双击时的行为</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
 | 
			
		||||
@ -7,6 +7,9 @@
 | 
			
		||||
#include "navigatorview.h"
 | 
			
		||||
#include "graphicsscene.h"
 | 
			
		||||
#include "settingsdialog.h"
 | 
			
		||||
#include "aboutdialog.h"
 | 
			
		||||
#include "metadatamodel.h"
 | 
			
		||||
#include "metadatadialog.h"
 | 
			
		||||
 | 
			
		||||
#include <QMouseEvent>
 | 
			
		||||
#include <QMovie>
 | 
			
		||||
@ -21,6 +24,7 @@
 | 
			
		||||
#include <QCollator>
 | 
			
		||||
#include <QClipboard>
 | 
			
		||||
#include <QMimeData>
 | 
			
		||||
#include <QWindow>
 | 
			
		||||
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
#include <windows.h>
 | 
			
		||||
@ -36,7 +40,7 @@ MainWindow::MainWindow(QWidget *parent) :
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    this->setAttribute(Qt::WA_TranslucentBackground, true);
 | 
			
		||||
    this->setMinimumSize(350, 350);
 | 
			
		||||
    this->setMinimumSize(350, 330);
 | 
			
		||||
    this->setWindowIcon(QIcon(":/icons/app-icon.svg"));
 | 
			
		||||
    this->setMouseTracking(true);
 | 
			
		||||
 | 
			
		||||
@ -238,9 +242,20 @@ void MainWindow::loadGalleryBySingleLocalFile(const QString &path)
 | 
			
		||||
    clearGallery();
 | 
			
		||||
 | 
			
		||||
    for (int i = 0; i < entryList.count(); i++) {
 | 
			
		||||
        const QString & oneEntry = entryList.at(i);
 | 
			
		||||
        m_files.append(QUrl::fromLocalFile(dir.absoluteFilePath(oneEntry)));
 | 
			
		||||
        if (oneEntry == currentFileName) {
 | 
			
		||||
        const QString & fileName = entryList.at(i);
 | 
			
		||||
        const QString & oneEntry = dir.absoluteFilePath(fileName);
 | 
			
		||||
        QUrl url = QUrl::fromLocalFile(oneEntry);
 | 
			
		||||
#ifdef Q_OS_WIN
 | 
			
		||||
        // TODO: remove this workaround when M$ change the "wsl$" hostname.
 | 
			
		||||
        // Qt will convert path "\\wsl$\" to "//wsl$/"...
 | 
			
		||||
        if (Q_UNLIKELY(oneEntry.startsWith(R"(//wsl$/)"))) {
 | 
			
		||||
            url.clear();
 | 
			
		||||
            url.setScheme(QStringLiteral("qtbug-86277"));
 | 
			
		||||
            url.setPath(oneEntry);
 | 
			
		||||
        }
 | 
			
		||||
#endif // Q_OS_WIN
 | 
			
		||||
        m_files.append(url);
 | 
			
		||||
        if (fileName == currentFileName) {
 | 
			
		||||
            m_currentFileIndex = i;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@ -327,7 +342,13 @@ void MainWindow::mousePressEvent(QMouseEvent *event)
 | 
			
		||||
void MainWindow::mouseMoveEvent(QMouseEvent *event)
 | 
			
		||||
{
 | 
			
		||||
    if (event->buttons() & Qt::LeftButton && m_clickedOnWindow && !isMaximized()) {
 | 
			
		||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
 | 
			
		||||
        if (!window()->windowHandle()->startSystemMove()) {
 | 
			
		||||
            move(event->globalPos() - m_oldMousePos);
 | 
			
		||||
        }
 | 
			
		||||
#else
 | 
			
		||||
        move(event->globalPos() - m_oldMousePos);
 | 
			
		||||
#endif // QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
 | 
			
		||||
        event->accept();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -463,15 +484,20 @@ void MainWindow::contextMenuEvent(QContextMenuEvent *event)
 | 
			
		||||
 | 
			
		||||
    QAction * helpAction = new QAction(tr("Help"));
 | 
			
		||||
    connect(helpAction, &QAction::triggered, this, [ = ](){
 | 
			
		||||
        QStringList sl {
 | 
			
		||||
            tr("Launch application with image file path as argument to load the file."),
 | 
			
		||||
            tr("Drag and drop image file onto the window is also supported."),
 | 
			
		||||
            "",
 | 
			
		||||
            tr("Context menu option explanation:"),
 | 
			
		||||
            (tr("Stay on top") + " : " + tr("Make window stay on top of all other windows.")),
 | 
			
		||||
            (tr("Protected mode") + " : " + tr("Avoid close window accidentally. (eg. by double clicking the window)"))
 | 
			
		||||
        };
 | 
			
		||||
        m_graphicsView->showText(sl.join('\n'));
 | 
			
		||||
        AboutDialog * ad = new AboutDialog(this);
 | 
			
		||||
        ad->exec();
 | 
			
		||||
        ad->deleteLater();
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    QAction * propertiesAction = new QAction(tr("Properties"));
 | 
			
		||||
    connect(propertiesAction, &QAction::triggered, this, [ = ](){
 | 
			
		||||
        MetadataModel * md = new MetadataModel();
 | 
			
		||||
        md->setFile(currentFileUrl.toLocalFile());
 | 
			
		||||
 | 
			
		||||
        MetadataDialog * ad = new MetadataDialog(this);
 | 
			
		||||
        ad->setMetadataModel(md);
 | 
			
		||||
        ad->exec();
 | 
			
		||||
        ad->deleteLater();
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    if (copyMenu->actions().count() == 1) {
 | 
			
		||||
@ -490,6 +516,10 @@ void MainWindow::contextMenuEvent(QContextMenuEvent *event)
 | 
			
		||||
    menu->addSeparator();
 | 
			
		||||
    menu->addAction(toggleSettings);
 | 
			
		||||
    menu->addAction(helpAction);
 | 
			
		||||
    if (currentFileUrl.isValid()) {
 | 
			
		||||
        menu->addSeparator();
 | 
			
		||||
        menu->addAction(propertiesAction);
 | 
			
		||||
    }
 | 
			
		||||
    menu->exec(mapToGlobal(event->pos()));
 | 
			
		||||
    menu->deleteLater();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										41
									
								
								metadatadialog.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								metadatadialog.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,41 @@
 | 
			
		||||
#include "metadatadialog.h"
 | 
			
		||||
 | 
			
		||||
#include <QDialogButtonBox>
 | 
			
		||||
#include <QTreeView>
 | 
			
		||||
#include <QVBoxLayout>
 | 
			
		||||
 | 
			
		||||
#include "metadatamodel.h"
 | 
			
		||||
 | 
			
		||||
MetadataDialog::MetadataDialog(QWidget *parent)
 | 
			
		||||
    : QDialog(parent)
 | 
			
		||||
    , m_treeView(new QTreeView(this))
 | 
			
		||||
{
 | 
			
		||||
    m_treeView->setRootIsDecorated(false);
 | 
			
		||||
    m_treeView->setIndentation(0);
 | 
			
		||||
 | 
			
		||||
    setWindowTitle(tr("Image Metadata"));
 | 
			
		||||
 | 
			
		||||
    QDialogButtonBox * buttonBox = new QDialogButtonBox(QDialogButtonBox::Close);
 | 
			
		||||
 | 
			
		||||
    setLayout(new QVBoxLayout);
 | 
			
		||||
    layout()->addWidget(m_treeView);
 | 
			
		||||
    layout()->addWidget(buttonBox);
 | 
			
		||||
 | 
			
		||||
    connect(buttonBox, &QDialogButtonBox::close, this, &QDialog::close);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MetadataDialog::~MetadataDialog()
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MetadataDialog::setMetadataModel(MetadataModel * model)
 | 
			
		||||
{
 | 
			
		||||
    m_treeView->setModel(model);
 | 
			
		||||
    m_treeView->expandAll();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QSize MetadataDialog::sizeHint() const
 | 
			
		||||
{
 | 
			
		||||
    return QSize(520, 350);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										26
									
								
								metadatadialog.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								metadatadialog.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,26 @@
 | 
			
		||||
#ifndef METADATADIALOG_H
 | 
			
		||||
#define METADATADIALOG_H
 | 
			
		||||
 | 
			
		||||
#include <QDialog>
 | 
			
		||||
 | 
			
		||||
QT_BEGIN_NAMESPACE
 | 
			
		||||
class QTreeView;
 | 
			
		||||
QT_END_NAMESPACE
 | 
			
		||||
 | 
			
		||||
class MetadataModel;
 | 
			
		||||
class MetadataDialog : public QDialog
 | 
			
		||||
{
 | 
			
		||||
    Q_OBJECT
 | 
			
		||||
public:
 | 
			
		||||
    explicit MetadataDialog(QWidget * parent);
 | 
			
		||||
    ~MetadataDialog() override;
 | 
			
		||||
 | 
			
		||||
    void setMetadataModel(MetadataModel * model);
 | 
			
		||||
 | 
			
		||||
    QSize sizeHint() const override;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    QTreeView * m_treeView = nullptr;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // METADATADIALOG_H
 | 
			
		||||
							
								
								
									
										159
									
								
								metadatamodel.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										159
									
								
								metadatamodel.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,159 @@
 | 
			
		||||
#include "metadatamodel.h"
 | 
			
		||||
 | 
			
		||||
#include <QDebug>
 | 
			
		||||
#include <QDateTime>
 | 
			
		||||
#include <QFileInfo>
 | 
			
		||||
#include <QImageReader>
 | 
			
		||||
 | 
			
		||||
MetadataModel::MetadataModel(QObject *parent)
 | 
			
		||||
    : QAbstractItemModel(parent)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MetadataModel::~MetadataModel()
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MetadataModel::setFile(const QString &imageFilePath)
 | 
			
		||||
{
 | 
			
		||||
    QFileInfo fileInfo(imageFilePath);
 | 
			
		||||
    // It'll be fine if we don't re-use the image reader we pass to the graphics scene for now.
 | 
			
		||||
    QImageReader imgReader(imageFilePath);
 | 
			
		||||
 | 
			
		||||
    const QString & sizeString = QLocale().formattedDataSize(fileInfo.size());
 | 
			
		||||
    const QString & timeString = QLocale().toString(fileInfo.lastModified(), QLocale::LongFormat);
 | 
			
		||||
    const QString & imageSizeString = imageSize(imgReader.size());
 | 
			
		||||
 | 
			
		||||
    appendSection(QStringLiteral("General"), tr("General", "General info about the image, section name."));
 | 
			
		||||
 | 
			
		||||
    appendProperty(QStringLiteral("General"), QStringLiteral("General.Name"),
 | 
			
		||||
                   tr("File Name"), fileInfo.fileName());
 | 
			
		||||
    appendProperty(QStringLiteral("General"), QStringLiteral("General.Size"),
 | 
			
		||||
                   tr("File Size"), sizeString);
 | 
			
		||||
    appendProperty(QStringLiteral("General"), QStringLiteral("General.Time"),
 | 
			
		||||
                   tr("Last Modified"), timeString);
 | 
			
		||||
    appendProperty(QStringLiteral("General"), QStringLiteral("General.ImageSize"),
 | 
			
		||||
                   tr("Image Size"), imageSizeString);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QString MetadataModel::imageSize(const QSize &size)
 | 
			
		||||
{
 | 
			
		||||
    QString imageSize;
 | 
			
		||||
 | 
			
		||||
    if (size.isValid()) {
 | 
			
		||||
        imageSize = tr("%1 x %2").arg(QString::number(size.width()), QString::number(size.height()));
 | 
			
		||||
    } else {
 | 
			
		||||
        imageSize = QLatin1Char('-');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return imageSize;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool MetadataModel::appendSection(const QString §ionKey, const QString §ionDisplayName)
 | 
			
		||||
{
 | 
			
		||||
    if (m_sections.contains(sectionKey)) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    m_sections.append(sectionKey);
 | 
			
		||||
    m_sectionProperties[sectionKey] = qMakePair<QString, QList<QString> >(sectionDisplayName, {});
 | 
			
		||||
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool MetadataModel::appendProperty(const QString §ionKey, const QString &propertyKey, const QString &propertyDisplayName, const QString &propertyValue)
 | 
			
		||||
{
 | 
			
		||||
    if (!m_sections.contains(sectionKey)) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    QList<QString> & propertyList = m_sectionProperties[sectionKey].second;
 | 
			
		||||
    if (!propertyList.contains(propertyKey)) {
 | 
			
		||||
        propertyList.append(propertyKey);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    m_properties[propertyKey] = qMakePair<QString, QString>(propertyDisplayName, propertyValue);
 | 
			
		||||
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool MetadataModel::updateProperty(const QString &propertyKey, const QString &propertyValue)
 | 
			
		||||
{
 | 
			
		||||
    if (m_properties.contains(propertyKey)) {
 | 
			
		||||
        m_properties[propertyKey].second = propertyValue;
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QModelIndex MetadataModel::index(int row, int column, const QModelIndex &parent) const
 | 
			
		||||
{
 | 
			
		||||
    if (!hasIndex(row, column, parent)) {
 | 
			
		||||
        return QModelIndex();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!parent.isValid()) {
 | 
			
		||||
        return createIndex(row, column, RowType::SectionRow);
 | 
			
		||||
    } else {
 | 
			
		||||
        // internalid param: row means nth section it belongs to.
 | 
			
		||||
        return createIndex(row, column, RowType::PropertyRow + parent.row());
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QModelIndex MetadataModel::parent(const QModelIndex &child) const
 | 
			
		||||
{
 | 
			
		||||
    if (!child.isValid()) {
 | 
			
		||||
        return QModelIndex();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (child.internalId() == RowType::SectionRow) {
 | 
			
		||||
        return QModelIndex();
 | 
			
		||||
    } else {
 | 
			
		||||
        return createIndex(child.internalId() - RowType::PropertyRow, 0, SectionRow);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int MetadataModel::rowCount(const QModelIndex &parent) const
 | 
			
		||||
{
 | 
			
		||||
    if (!parent.isValid()) {
 | 
			
		||||
        return m_sections.count();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (parent.internalId() == RowType::SectionRow) {
 | 
			
		||||
        const QString & sectionKey = m_sections[parent.row()];
 | 
			
		||||
        return m_sectionProperties[sectionKey].second.count();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int MetadataModel::columnCount(const QModelIndex &) const
 | 
			
		||||
{
 | 
			
		||||
    // Always key(display name) and value.
 | 
			
		||||
    return 2;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QVariant MetadataModel::data(const QModelIndex &index, int role) const
 | 
			
		||||
{
 | 
			
		||||
    if (!index.isValid()) {
 | 
			
		||||
        return QVariant();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (role != Qt::DisplayRole) {
 | 
			
		||||
        return QVariant();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (index.internalId() == RowType::SectionRow) {
 | 
			
		||||
        return (index.column() == 0) ? m_sectionProperties[m_sections[index.row()]].first
 | 
			
		||||
                                     : QVariant();
 | 
			
		||||
    } else {
 | 
			
		||||
        int sectionIndex = index.internalId() - RowType::PropertyRow;
 | 
			
		||||
        const QString & sectionKey = m_sections[sectionIndex];
 | 
			
		||||
        const QList<QString> & propertyList = m_sectionProperties[sectionKey].second;
 | 
			
		||||
        return (index.column() == 0) ? m_properties[propertyList[index.row()]].first
 | 
			
		||||
                                     : m_properties[propertyList[index.row()]].second;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										41
									
								
								metadatamodel.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								metadatamodel.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,41 @@
 | 
			
		||||
#ifndef METADATAMODEL_H
 | 
			
		||||
#define METADATAMODEL_H
 | 
			
		||||
 | 
			
		||||
#include <QAbstractItemModel>
 | 
			
		||||
 | 
			
		||||
class MetadataModel : public QAbstractItemModel
 | 
			
		||||
{
 | 
			
		||||
    Q_OBJECT
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    explicit MetadataModel(QObject *parent = nullptr);
 | 
			
		||||
    ~MetadataModel();
 | 
			
		||||
 | 
			
		||||
    void setFile(const QString & imageFilePath);
 | 
			
		||||
    static QString imageSize(const QSize &size);
 | 
			
		||||
    bool appendSection(const QString & sectionKey, const QString & sectionDisplayName);
 | 
			
		||||
    bool appendProperty(const QString & sectionKey, const QString & propertyKey,
 | 
			
		||||
                        const QString & propertyDisplayName, const QString & propertyValue = QString());
 | 
			
		||||
    bool updateProperty(const QString & propertyKey, const QString & propertyValue);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    enum RowType : quintptr {
 | 
			
		||||
        SectionRow,
 | 
			
		||||
        PropertyRow,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
 | 
			
		||||
    QModelIndex parent(const QModelIndex &child) const override;
 | 
			
		||||
    int rowCount(const QModelIndex &parent = QModelIndex()) const override;
 | 
			
		||||
    int columnCount(const QModelIndex & = QModelIndex()) const override;
 | 
			
		||||
    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
 | 
			
		||||
 | 
			
		||||
    // [SECTION_KEY]
 | 
			
		||||
    QList<QString> m_sections;
 | 
			
		||||
    // {SECTION_KEY: (SECTION_DISPLAY_NAME, [PROPERTY_KEY])}
 | 
			
		||||
    QMap<QString, QPair<QString, QList<QString> > > m_sectionProperties;
 | 
			
		||||
    // {PROPERTY_KEY: (PROPERTY_DISPLAY_NAME, PROPERTY_VALUE)}
 | 
			
		||||
    QMap<QString, QPair<QString, QString> > m_properties;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // METADATAMODEL_H
 | 
			
		||||
@ -1,14 +1,6 @@
 | 
			
		||||
#-------------------------------------------------
 | 
			
		||||
#
 | 
			
		||||
# Project created by QtCreator 2019-09-26T23:36:07
 | 
			
		||||
#
 | 
			
		||||
#-------------------------------------------------
 | 
			
		||||
QT       += core widgets gui svg
 | 
			
		||||
 | 
			
		||||
QT       += core gui svg
 | 
			
		||||
 | 
			
		||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
 | 
			
		||||
 | 
			
		||||
TARGET = PineapplePictures
 | 
			
		||||
TARGET = ppic
 | 
			
		||||
TEMPLATE = app
 | 
			
		||||
 | 
			
		||||
# The following define makes your compiler emit warnings if you use
 | 
			
		||||
@ -25,8 +17,9 @@ DEFINES += QT_DEPRECATED_WARNINGS
 | 
			
		||||
CONFIG += c++11 lrelease embed_translations
 | 
			
		||||
 | 
			
		||||
SOURCES += \
 | 
			
		||||
        main.cpp \
 | 
			
		||||
        mainwindow.cpp \
 | 
			
		||||
    aboutdialog.cpp \
 | 
			
		||||
    main.cpp \
 | 
			
		||||
    mainwindow.cpp \
 | 
			
		||||
    graphicsview.cpp \
 | 
			
		||||
    bottombuttongroup.cpp \
 | 
			
		||||
    graphicsscene.cpp \
 | 
			
		||||
@ -34,10 +27,13 @@ SOURCES += \
 | 
			
		||||
    opacityhelper.cpp \
 | 
			
		||||
    toolbutton.cpp \
 | 
			
		||||
    settings.cpp \
 | 
			
		||||
    settingsdialog.cpp
 | 
			
		||||
    settingsdialog.cpp \
 | 
			
		||||
    metadatamodel.cpp \
 | 
			
		||||
    metadatadialog.cpp
 | 
			
		||||
 | 
			
		||||
HEADERS += \
 | 
			
		||||
        mainwindow.h \
 | 
			
		||||
    aboutdialog.h \
 | 
			
		||||
    mainwindow.h \
 | 
			
		||||
    graphicsview.h \
 | 
			
		||||
    bottombuttongroup.h \
 | 
			
		||||
    graphicsscene.h \
 | 
			
		||||
@ -45,7 +41,9 @@ HEADERS += \
 | 
			
		||||
    opacityhelper.h \
 | 
			
		||||
    toolbutton.h \
 | 
			
		||||
    settings.h \
 | 
			
		||||
    settingsdialog.h
 | 
			
		||||
    settingsdialog.h \
 | 
			
		||||
    metadatamodel.h \
 | 
			
		||||
    metadatadialog.h
 | 
			
		||||
 | 
			
		||||
TRANSLATIONS = \
 | 
			
		||||
    languages/PineapplePictures.ts \
 | 
			
		||||
@ -62,3 +60,8 @@ RESOURCES += \
 | 
			
		||||
# Generate from svg:
 | 
			
		||||
# magick convert -background none app-icon.svg -define icon:auto-resize="16,32,48,64,128,256" app-icon.ico
 | 
			
		||||
RC_ICONS = icons/app-icon.ico
 | 
			
		||||
 | 
			
		||||
# Windows only, for rc file (we're not going to use the .rc file in this repo)
 | 
			
		||||
QMAKE_TARGET_PRODUCT = Pineapple Pictures
 | 
			
		||||
QMAKE_TARGET_DESCRIPTION = Pineapple Pictures - Image Viewer
 | 
			
		||||
QMAKE_TARGET_COPYRIGHT = MIT/Expat License - Copyright (C) 2020 Gary Wang
 | 
			
		||||
@ -12,6 +12,8 @@ SettingsDialog::SettingsDialog(QWidget *parent)
 | 
			
		||||
    , m_stayOnTop(new QCheckBox)
 | 
			
		||||
    , m_doubleClickBehavior(new QComboBox)
 | 
			
		||||
{
 | 
			
		||||
    this->setWindowTitle(tr("Settings"));
 | 
			
		||||
 | 
			
		||||
    QFormLayout * settingsForm = new QFormLayout(this);
 | 
			
		||||
 | 
			
		||||
    static QMap<DoubleClickBehavior, QString> _map {
 | 
			
		||||
 | 
			
		||||
@ -2,7 +2,6 @@
 | 
			
		||||
#define SETTINGSDIALOG_H
 | 
			
		||||
 | 
			
		||||
#include <QObject>
 | 
			
		||||
#include <QWidget>
 | 
			
		||||
#include <QDialog>
 | 
			
		||||
 | 
			
		||||
class QCheckBox;
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user