Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eeaf2210d2 | ||
|
|
df5debb962 | ||
|
|
184209ece5 | ||
|
|
b964fdc77f | ||
|
|
d6d2703c93 | ||
|
|
c6068ba23d | ||
|
|
fbdd858fbd | ||
|
|
8333f17199 | ||
|
|
30eb06cba7 | ||
|
|
0a45cd7c22 |
@@ -1,43 +1,47 @@
|
||||
name: Windows CI
|
||||
|
||||
on: [push, pull_request, workflow_dispatch]
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
msvc-qmake-build:
|
||||
# msvc-qmake-build:
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- qt_ver: '6.9.0'
|
||||
vs: '2022'
|
||||
aqt_arch: 'win64_msvc2022_64'
|
||||
msvc_arch: 'x64'
|
||||
# strategy:
|
||||
# matrix:
|
||||
# include:
|
||||
# - qt_ver: '6.9.0'
|
||||
# vs: '2022'
|
||||
# aqt_arch: 'win64_msvc2022_64'
|
||||
# msvc_arch: 'x64'
|
||||
|
||||
runs-on: windows-2022
|
||||
# runs-on: windows-2022
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v4
|
||||
with:
|
||||
arch: ${{ matrix.aqt_arch }}
|
||||
version: ${{ matrix.qt_ver }}
|
||||
modules: 'qtimageformats'
|
||||
- name: Build
|
||||
shell: cmd
|
||||
run: |
|
||||
set VS=${{ matrix.vs }}
|
||||
set VCVARS="C:\Program Files (x86)\Microsoft Visual Studio\%VS%\Enterprise\VC\Auxiliary\Build\vcvarsall.bat"
|
||||
if not exist %VCVARS% set VCVARS="C:\Program Files\Microsoft Visual Studio\%VS%\Enterprise\VC\Auxiliary\Build\vcvarsall.bat"
|
||||
call %VCVARS% ${{ matrix.msvc_arch }}
|
||||
qmake pineapple-pictures.pro
|
||||
nmake
|
||||
nmake clean
|
||||
windeployqt --verbose=2 --no-quick-import --no-translations --no-opengl-sw --no-system-d3d-compiler --no-system-dxc-compiler --skip-plugin-types tls,networkinformation release\ppic.exe
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: "windows-msvc${{ matrix.vs }}-qt${{ matrix.qt_ver }}-qmake-package"
|
||||
path: release/*
|
||||
# steps:
|
||||
# - uses: actions/checkout@v4
|
||||
# - name: Install Qt
|
||||
# uses: jurplel/install-qt-action@v4
|
||||
# with:
|
||||
# arch: ${{ matrix.aqt_arch }}
|
||||
# version: ${{ matrix.qt_ver }}
|
||||
# modules: 'qtimageformats'
|
||||
# - name: Build
|
||||
# shell: cmd
|
||||
# run: |
|
||||
# set VS=${{ matrix.vs }}
|
||||
# set VCVARS="C:\Program Files (x86)\Microsoft Visual Studio\%VS%\Enterprise\VC\Auxiliary\Build\vcvarsall.bat"
|
||||
# if not exist %VCVARS% set VCVARS="C:\Program Files\Microsoft Visual Studio\%VS%\Enterprise\VC\Auxiliary\Build\vcvarsall.bat"
|
||||
# call %VCVARS% ${{ matrix.msvc_arch }}
|
||||
# qmake pineapple-pictures.pro
|
||||
# nmake
|
||||
# nmake clean
|
||||
# windeployqt --verbose=2 --no-quick-import --no-translations --no-opengl-sw --no-system-d3d-compiler --no-system-dxc-compiler --skip-plugin-types tls,networkinformation release\ppic.exe
|
||||
# - uses: actions/upload-artifact@v4
|
||||
# with:
|
||||
# name: "windows-msvc${{ matrix.vs }}-qt${{ matrix.qt_ver }}-qmake-package"
|
||||
# path: release/*
|
||||
|
||||
msvc-cmake-build:
|
||||
|
||||
@@ -126,8 +130,11 @@ jobs:
|
||||
robocopy ./dependencies_bin/bin build/bin *.dll
|
||||
if ErrorLevel 8 (exit /B 1)
|
||||
copy LICENSE build\bin
|
||||
copy build\dist\ppic.iss build\bin\ppic.iss
|
||||
iscc /Q build\bin\ppic.iss
|
||||
if not ErrorLevel 0 (exit /B 1)
|
||||
exit /B 0
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: "windows-msvc${{ matrix.vs }}-qt${{ matrix.qt_ver }}-cmake-package"
|
||||
path: build/bin/*
|
||||
name: "ppic-windows-msvc${{ matrix.vs }}-qt${{ matrix.qt_ver }}-cmake-setup"
|
||||
path: build/bin/ppic-setup.exe
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
project(pineapple-pictures VERSION 0.9.2) # don't forget to update NEWS file and AppStream metadata.
|
||||
project(pineapple-pictures VERSION 1.0.0) # don't forget to update NEWS file and AppStream metadata.
|
||||
|
||||
include(GNUInstallDirs)
|
||||
include(FeatureSummary)
|
||||
@@ -118,10 +118,16 @@ add_executable (${EXE_NAME}
|
||||
)
|
||||
|
||||
if (${QT_VERSION_MAJOR} EQUAL "6")
|
||||
set(ADD_TRANSLATIONS_ADDITIONAL_ARGS)
|
||||
|
||||
if (Qt6_VERSION VERSION_GREATER_EQUAL "6.9.0")
|
||||
set(ADD_TRANSLATIONS_ADDITIONAL_ARGS MERGE_QT_TRANSLATIONS)
|
||||
endif()
|
||||
|
||||
if (TRANSLATION_RESOURCE_EMBEDDING)
|
||||
qt_add_translations(${EXE_NAME} TS_FILES ${PPIC_TS_FILES})
|
||||
qt_add_translations(${EXE_NAME} ${ADD_TRANSLATIONS_ADDITIONAL_ARGS} TS_FILES ${PPIC_TS_FILES})
|
||||
else()
|
||||
qt_add_translations(${EXE_NAME} TS_FILES ${PPIC_TS_FILES} QM_FILES_OUTPUT_VARIABLE PPIC_QM_FILES)
|
||||
qt_add_translations(${EXE_NAME} ${ADD_TRANSLATIONS_ADDITIONAL_ARGS} TS_FILES ${PPIC_TS_FILES} QM_FILES_OUTPUT_VARIABLE PPIC_QM_FILES)
|
||||
endif()
|
||||
else()
|
||||
qt_create_translation(PPIC_QM_FILES ${PPIC_CPP_FILES_FOR_I18N} ${PPIC_TS_FILES})
|
||||
@@ -211,6 +217,11 @@ if (WIN32)
|
||||
set_target_properties(${EXE_NAME} PROPERTIES
|
||||
WIN32_EXECUTABLE TRUE
|
||||
)
|
||||
configure_file(
|
||||
${CMAKE_CURRENT_LIST_DIR}/dist/ppic.iss.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/dist/ppic.iss
|
||||
@ONLY
|
||||
)
|
||||
elseif (APPLE)
|
||||
set_source_files_properties(assets/icons/app-icon.icns PROPERTIES
|
||||
MACOSX_PACKAGE_LOCATION "Resources"
|
||||
|
||||
@@ -1,3 +1,23 @@
|
||||
Version 1.0.0
|
||||
~~~~~~~~~~~~~
|
||||
Released: 2025-05-03
|
||||
|
||||
Features:
|
||||
* Support enforce windowed mode on start-up
|
||||
* Reload image automatically when current image gets updated
|
||||
|
||||
Bugfixes:
|
||||
* Refer to the right exiv2 CMake module so it can be found on Linux
|
||||
* Display correct text language on macOS
|
||||
|
||||
Miscellaneous:
|
||||
* Use native text for shortcut editor's label
|
||||
* Display native commandline message when possible
|
||||
* Merge Qt translations into app applications as well
|
||||
|
||||
Contributors:
|
||||
Heimen Stoffels, albanobattistella, mmahhi
|
||||
|
||||
Version 0.9.2
|
||||
~~~~~~~~~~~~~
|
||||
Released: 2025-03-05
|
||||
@@ -123,7 +143,7 @@ Version 0.7.1
|
||||
Released: 2023-07-08
|
||||
|
||||
Features:
|
||||
* TIF and TIFF format files in the same folder will now be automatedly added to the gallery
|
||||
* TIF and TIFF format files in the same folder will now be automatically added to the gallery
|
||||
* Built-in window resizing now also supports Linux desktop. (macOS might also works as well)
|
||||
|
||||
Bugfixes:
|
||||
|
||||
@@ -48,25 +48,25 @@ void ActionManager::setupAction(MainWindow *mainWindow)
|
||||
};
|
||||
#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, actionToggleMaximize, view-fullscreen);
|
||||
CREATE_NEW_ICON_ACTION(mainWindow, actionFitInView, fit-in-view);
|
||||
CREATE_NEW_ICON_ACTION(mainWindow, actionHorizontalFlip, horizontal-flip);
|
||||
CREATE_NEW_ICON_ACTION(mainWindow, actionZoomIn, zoom-in);
|
||||
CREATE_NEW_ICON_ACTION(mainWindow, actionZoomOut, zoom-out);
|
||||
CREATE_NEW_ICON_ACTION(mainWindow, actionToggleCheckerboard, view-background-checkerboard);
|
||||
CREATE_NEW_ICON_ACTION(mainWindow, actionRotateClockwise, object-rotate-right);
|
||||
CREATE_NEW_ICON_ACTION(mainWindow, actionRotateCounterClockwise, object-rotate-left);
|
||||
CREATE_NEW_ICON_ACTION(mainWindow, actionPrevPicture, go-previous);
|
||||
CREATE_NEW_ICON_ACTION(mainWindow, actionNextPicture, go-next);
|
||||
#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, actionToggleMaximize);
|
||||
|
||||
CREATE_NEW_ACTION(mainWindow, actionTogglePauseAnimation);
|
||||
CREATE_NEW_ACTION(mainWindow, actionAnimationNextFrame);
|
||||
|
||||
CREATE_NEW_THEMEICON_ACTION(mainWindow, actionOpen, document-open);
|
||||
CREATE_NEW_ACTION(mainWindow, actionHorizontalFlip);
|
||||
CREATE_NEW_ACTION(mainWindow, actionFitInView);
|
||||
CREATE_NEW_ACTION(mainWindow, actionFitByWidth);
|
||||
CREATE_NEW_THEMEICON_ACTION(mainWindow, actionCopyPixmap, edit-copy);
|
||||
CREATE_NEW_ACTION(mainWindow, actionCopyFilePath);
|
||||
@@ -161,3 +161,8 @@ void ActionManager::setupShortcuts()
|
||||
});
|
||||
}
|
||||
|
||||
void ActionManager::setPrevNextPictureActionEnabled(bool enabled)
|
||||
{
|
||||
actionPrevPicture->setEnabled(enabled);
|
||||
actionNextPicture->setEnabled(enabled);
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ public:
|
||||
void setupAction(MainWindow * mainWindow);
|
||||
void retranslateUi(MainWindow *MainWindow);
|
||||
void setupShortcuts();
|
||||
void setPrevNextPictureActionEnabled(bool enabled);
|
||||
|
||||
static QIcon loadHidpiIcon(const QString &resp, QSize sz = QSize(32, 32));
|
||||
|
||||
|
||||
@@ -21,11 +21,7 @@ BottomButtonGroup::BottomButtonGroup(const std::vector<QAction *> &actionList, Q
|
||||
this->setLayout(mainLayout);
|
||||
this->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
||||
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;"
|
||||
@@ -45,6 +41,7 @@ BottomButtonGroup::BottomButtonGroup(const std::vector<QAction *> &actionList, Q
|
||||
for (QAction * action : actionList) {
|
||||
addButton(newActionBtn(action));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void BottomButtonGroup::setOpacity(qreal opacity, bool animated)
|
||||
|
||||
@@ -14,22 +14,9 @@
|
||||
FramelessWindow::FramelessWindow(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, m_centralLayout(new QVBoxLayout(this))
|
||||
, m_oldCursorShape(Qt::ArrowCursor)
|
||||
, m_oldEdges()
|
||||
{
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
this->setWindowFlags(Qt::Window | Qt::FramelessWindowHint | Qt::WindowMinMaxButtonsHint);
|
||||
#else
|
||||
// There is a bug in Qt 5 that will make pressing Meta+Up cause the app
|
||||
// fullscreen under Windows, see QTBUG-91226 to learn more.
|
||||
// The bug seems no longer exists in Qt 6 (I only tested it under Qt 6.3.0).
|
||||
this->setWindowFlags(Qt::Window | Qt::FramelessWindowHint | Qt::WindowMinimizeButtonHint);
|
||||
#endif // QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
this->setMouseTracking(true);
|
||||
this->setAttribute(Qt::WA_Hover, true);
|
||||
this->installEventFilter(this);
|
||||
|
||||
m_centralLayout->setContentsMargins(QMargins());
|
||||
this->setWindowFlags(Qt::Window | Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint);
|
||||
m_centralLayout->setContentsMargins(QMargins(0, 0, 0, 60));
|
||||
}
|
||||
|
||||
void FramelessWindow::setCentralWidget(QWidget *widget)
|
||||
@@ -42,106 +29,3 @@ void FramelessWindow::setCentralWidget(QWidget *widget)
|
||||
m_centralLayout->addWidget(widget);
|
||||
m_centralWidget = widget;
|
||||
}
|
||||
|
||||
void FramelessWindow::installResizeCapture(QObject* widget)
|
||||
{
|
||||
widget->installEventFilter(this);
|
||||
}
|
||||
|
||||
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();
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
Qt::Edges edges = this->getEdgesByPos(event->globalPosition().toPoint(), win->frameGeometry());
|
||||
#else
|
||||
Qt::Edges edges = this->getEdgesByPos(event->globalPos(), win->frameGeometry());
|
||||
#endif // QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,22 +16,9 @@ class FramelessWindow : public QWidget
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit FramelessWindow(QWidget *parent = nullptr);
|
||||
|
||||
void setCentralWidget(QWidget * widget);
|
||||
void installResizeCapture(QObject* widget);
|
||||
|
||||
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.
|
||||
};
|
||||
|
||||
@@ -119,7 +119,7 @@ void GraphicsScene::showText(const QString &text)
|
||||
{
|
||||
this->clear();
|
||||
QGraphicsTextItem * textItem = this->addText(text);
|
||||
textItem->setDefaultTextColor(QColor("White"));
|
||||
textItem->setDefaultTextColor(QColor("Black"));
|
||||
m_theThing = textItem;
|
||||
this->setSceneRect(m_theThing->boundingRect());
|
||||
}
|
||||
|
||||
@@ -22,8 +22,7 @@ GraphicsView::GraphicsView(QWidget *parent)
|
||||
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
setResizeAnchor(QGraphicsView::AnchorUnderMouse);
|
||||
setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
|
||||
setStyleSheet("background-color: rgba(0, 0, 0, 220);"
|
||||
"border-radius: 3px;");
|
||||
setStyleSheet("border-style: none;");
|
||||
setAcceptDrops(false);
|
||||
setCheckerboardEnabled(false);
|
||||
|
||||
@@ -118,7 +117,7 @@ qreal GraphicsView::scaleFactor() const
|
||||
|
||||
void GraphicsView::resetTransform()
|
||||
{
|
||||
if (!m_avoidResetTransform) {
|
||||
if (!shouldAvoidTransform()) {
|
||||
QGraphicsView::resetTransform();
|
||||
}
|
||||
}
|
||||
@@ -196,7 +195,7 @@ void GraphicsView::fitByOrientation(Qt::Orientation ori, bool scaleDownOnly)
|
||||
|
||||
void GraphicsView::displayScene()
|
||||
{
|
||||
if (m_avoidResetTransform) {
|
||||
if (shouldAvoidTransform()) {
|
||||
emit navigatorViewRequired(!isThingSmallerThanWindowWith(transform()), transform());
|
||||
return;
|
||||
}
|
||||
@@ -206,6 +205,7 @@ void GraphicsView::displayScene()
|
||||
}
|
||||
|
||||
m_enableFitInView = true;
|
||||
m_firstUserMediaLoaded = true;
|
||||
}
|
||||
|
||||
bool GraphicsView::isSceneBiggerThanView() const
|
||||
@@ -365,3 +365,8 @@ void GraphicsView::applyTransformationModeByScaleFactor()
|
||||
scene()->trySetTransformationMode(Qt::FastTransformation, this->scaleFactor());
|
||||
}
|
||||
}
|
||||
|
||||
bool GraphicsView::shouldAvoidTransform() const
|
||||
{
|
||||
return m_firstUserMediaLoaded && m_avoidResetTransform;
|
||||
}
|
||||
|
||||
@@ -64,6 +64,8 @@ private:
|
||||
void setCheckerboardEnabled(bool enabled, bool invertColor = false);
|
||||
void applyTransformationModeByScaleFactor();
|
||||
|
||||
inline bool shouldAvoidTransform() const;
|
||||
|
||||
// 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.
|
||||
@@ -71,6 +73,7 @@ private:
|
||||
bool m_avoidResetTransform = false;
|
||||
bool m_checkerboardEnabled = false;
|
||||
bool m_useLightCheckerboard = false;
|
||||
bool m_firstUserMediaLoaded = false;
|
||||
};
|
||||
|
||||
#endif // GRAPHICSVIEW_H
|
||||
|
||||
@@ -52,8 +52,13 @@ int main(int argc, char *argv[])
|
||||
parser.process(a);
|
||||
|
||||
if (parser.isSet(supportedImageFormats)) {
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 9, 0)
|
||||
fputs(qPrintable(MainWindow::supportedImageFormats().join(QChar('\n'))), stdout);
|
||||
::exit(EXIT_SUCCESS);
|
||||
#else
|
||||
QCommandLineParser::showMessageAndExit(QCommandLineParser::MessageType::Information,
|
||||
MainWindow::supportedImageFormats().join(QChar('\n')));
|
||||
#endif
|
||||
}
|
||||
|
||||
MainWindow w;
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include "mainwindow.h"
|
||||
|
||||
#include "settings.h"
|
||||
#include "toolbutton.h"
|
||||
#include "bottombuttongroup.h"
|
||||
#include "graphicsview.h"
|
||||
#include "navigatorview.h"
|
||||
@@ -54,31 +53,12 @@ MainWindow::MainWindow(QWidget *parent)
|
||||
this->setWindowFlag(Qt::WindowStaysOnTopHint);
|
||||
}
|
||||
|
||||
this->setAttribute(Qt::WA_TranslucentBackground, true);
|
||||
this->setMinimumSize(350, 330);
|
||||
this->setMinimumSize(600, 400);
|
||||
this->setWindowIcon(QIcon(":/icons/app-icon.svg"));
|
||||
this->setMouseTracking(true);
|
||||
this->setAcceptDrops(true);
|
||||
|
||||
m_pm->setAutoLoadFilterSuffixes(supportedImageFormats());
|
||||
|
||||
m_fadeOutAnimation = new QPropertyAnimation(this, "windowOpacity");
|
||||
m_fadeOutAnimation->setDuration(300);
|
||||
m_fadeOutAnimation->setStartValue(1);
|
||||
m_fadeOutAnimation->setEndValue(0);
|
||||
m_floatUpAnimation = new QPropertyAnimation(this, "geometry");
|
||||
m_floatUpAnimation->setDuration(300);
|
||||
m_floatUpAnimation->setEasingCurve(QEasingCurve::OutCirc);
|
||||
m_exitAnimationGroup = new QParallelAnimationGroup(this);
|
||||
m_exitAnimationGroup->addAnimation(m_fadeOutAnimation);
|
||||
m_exitAnimationGroup->addAnimation(m_floatUpAnimation);
|
||||
connect(m_exitAnimationGroup, &QParallelAnimationGroup::finished,
|
||||
#ifdef Q_OS_MAC
|
||||
this, &QWidget::hide);
|
||||
#else
|
||||
this, &QWidget::close);
|
||||
#endif
|
||||
|
||||
GraphicsScene * scene = new GraphicsScene(this);
|
||||
|
||||
m_graphicsView = new GraphicsView(this);
|
||||
@@ -86,7 +66,7 @@ MainWindow::MainWindow(QWidget *parent)
|
||||
this->setCentralWidget(m_graphicsView);
|
||||
|
||||
m_gv = new NavigatorView(this);
|
||||
m_gv->setFixedSize(220, 160);
|
||||
m_gv->setFixedSize(82, 60);
|
||||
m_gv->setScene(scene);
|
||||
m_gv->setMainView(m_graphicsView);
|
||||
m_gv->fitInView(m_gv->sceneRect(), Qt::KeepAspectRatio);
|
||||
@@ -102,48 +82,25 @@ MainWindow::MainWindow(QWidget *parent)
|
||||
connect(m_graphicsView, &GraphicsView::viewportRectChanged,
|
||||
m_gv, &NavigatorView::updateMainViewportRegion);
|
||||
|
||||
m_closeButton = new ToolButton(true, m_graphicsView);
|
||||
m_closeButton->setIconSize(QSize(32, 32));
|
||||
m_closeButton->setFixedSize(QSize(50, 50));
|
||||
m_closeButton->setIconResourcePath(":/icons/window-close.svg");
|
||||
|
||||
connect(m_closeButton, &QAbstractButton::clicked,
|
||||
this, &MainWindow::closeWindow);
|
||||
|
||||
m_prevButton = new ToolButton(false, m_graphicsView);
|
||||
m_prevButton->setIconSize(QSize(75, 75));
|
||||
m_prevButton->setIconResourcePath(":/icons/go-previous.svg");
|
||||
m_prevButton->setVisible(false);
|
||||
m_prevButton->setOpacity(0, false);
|
||||
m_nextButton = new ToolButton(false, m_graphicsView);
|
||||
m_nextButton->setIconSize(QSize(75, 75));
|
||||
m_nextButton->setIconResourcePath(":/icons/go-next.svg");
|
||||
m_nextButton->setVisible(false);
|
||||
m_nextButton->setOpacity(0, false);
|
||||
|
||||
connect(m_prevButton, &QAbstractButton::clicked,
|
||||
this, &MainWindow::galleryPrev);
|
||||
connect(m_nextButton, &QAbstractButton::clicked,
|
||||
this, &MainWindow::galleryNext);
|
||||
|
||||
m_am->setupAction(this);
|
||||
m_am->setPrevNextPictureActionEnabled(false);
|
||||
|
||||
m_bottomButtonGroup = new BottomButtonGroup({
|
||||
m_am->actionActualSize,
|
||||
m_am->actionToggleMaximize,
|
||||
m_am->actionFitInView,
|
||||
m_am->actionZoomIn,
|
||||
m_am->actionZoomOut,
|
||||
m_am->actionToggleCheckerboard,
|
||||
m_am->actionRotateClockwise
|
||||
m_am->actionPrevPicture,
|
||||
m_am->actionNextPicture,
|
||||
m_am->actionRotateCounterClockwise,
|
||||
m_am->actionRotateClockwise,
|
||||
m_am->actionHorizontalFlip,
|
||||
m_am->actionToggleCheckerboard
|
||||
}, this);
|
||||
|
||||
m_bottomButtonGroup->setOpacity(0, false);
|
||||
m_gv->setOpacity(0, false);
|
||||
m_closeButton->setOpacity(0, false);
|
||||
m_bottomButtonGroup->setFixedHeight(60);
|
||||
|
||||
connect(m_pm, &PlaylistManager::totalCountChanged, this, [this](int galleryFileCount) {
|
||||
m_prevButton->setVisible(galleryFileCount > 1);
|
||||
m_nextButton->setVisible(galleryFileCount > 1);
|
||||
m_am->setPrevNextPictureActionEnabled(galleryFileCount > 1);
|
||||
});
|
||||
|
||||
connect(m_pm->model(), &PlaylistModel::modelReset, this, std::bind(&MainWindow::galleryCurrent, this, false, false));
|
||||
@@ -164,12 +121,6 @@ MainWindow::MainWindow(QWidget *parent)
|
||||
Settings::instance()->applyUserShortcuts(this);
|
||||
});
|
||||
|
||||
// allow some mouse events can go through these widgets for resizing window.
|
||||
installResizeCapture(m_closeButton);
|
||||
installResizeCapture(m_graphicsView);
|
||||
installResizeCapture(m_graphicsView->viewport());
|
||||
installResizeCapture(m_gv);
|
||||
installResizeCapture(m_gv->viewport());
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
@@ -304,75 +255,6 @@ void MainWindow::showEvent(QShowEvent *event)
|
||||
return FramelessWindow::showEvent(event);
|
||||
}
|
||||
|
||||
void MainWindow::enterEvent(QT_ENTER_EVENT *event)
|
||||
{
|
||||
m_bottomButtonGroup->setOpacity(1);
|
||||
m_gv->setOpacity(1);
|
||||
|
||||
m_closeButton->setOpacity(1);
|
||||
m_prevButton->setOpacity(1);
|
||||
m_nextButton->setOpacity(1);
|
||||
|
||||
return FramelessWindow::enterEvent(event);
|
||||
}
|
||||
|
||||
void MainWindow::leaveEvent(QEvent *event)
|
||||
{
|
||||
m_bottomButtonGroup->setOpacity(0);
|
||||
m_gv->setOpacity(0);
|
||||
|
||||
m_closeButton->setOpacity(0);
|
||||
m_prevButton->setOpacity(0);
|
||||
m_nextButton->setOpacity(0);
|
||||
|
||||
return FramelessWindow::leaveEvent(event);
|
||||
}
|
||||
|
||||
void MainWindow::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
if (event->buttons() & Qt::LeftButton && !isMaximized()) {
|
||||
m_clickedOnWindow = true;
|
||||
m_oldMousePos = event->pos();
|
||||
// qDebug() << m_oldMousePos << m_graphicsView->transform().m11()
|
||||
// << m_graphicsView->transform().m22() << m_graphicsView->matrix().m12();
|
||||
event->accept();
|
||||
}
|
||||
|
||||
return FramelessWindow::mousePressEvent(event);
|
||||
}
|
||||
|
||||
void MainWindow::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
if (event->buttons() & Qt::LeftButton && m_clickedOnWindow && !isMaximized() && !isFullScreen()) {
|
||||
if (!window()->windowHandle()->startSystemMove()) {
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
move(event->globalPosition().toPoint() - m_oldMousePos);
|
||||
#else
|
||||
move(event->globalPos() - m_oldMousePos);
|
||||
#endif // QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
}
|
||||
event->accept();
|
||||
}
|
||||
|
||||
return FramelessWindow::mouseMoveEvent(event);
|
||||
}
|
||||
|
||||
void MainWindow::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
m_clickedOnWindow = false;
|
||||
|
||||
// It seems the forward/back mouse button won't generate a key event [1] so we can't use
|
||||
// QShortcut or QKeySequence to indicate these shortcuts, so we do it here.
|
||||
// Reference:
|
||||
// [1]: https://codereview.qt-project.org/c/qt/qtbase/+/177475
|
||||
if (event->button() == Qt::ForwardButton || event->button() == Qt::BackButton) {
|
||||
event->button() == Qt::BackButton ? galleryPrev() : galleryNext();
|
||||
event->accept();
|
||||
}
|
||||
|
||||
return FramelessWindow::mouseReleaseEvent(event);
|
||||
}
|
||||
|
||||
void MainWindow::mouseDoubleClickEvent(QMouseEvent *event)
|
||||
{
|
||||
// The forward/back mouse button can also used to trigger a mouse double-click event
|
||||
@@ -584,20 +466,12 @@ void MainWindow::centerWindow()
|
||||
|
||||
void MainWindow::closeWindow()
|
||||
{
|
||||
QRect windowRect(this->geometry());
|
||||
m_floatUpAnimation->setStartValue(windowRect);
|
||||
m_floatUpAnimation->setEndValue(windowRect.adjusted(0, -80, 0, 0));
|
||||
m_floatUpAnimation->setStartValue(QRect(this->geometry().x(), this->geometry().y(), this->geometry().width(), this->geometry().height()));
|
||||
m_floatUpAnimation->setEndValue(QRect(this->geometry().x(), this->geometry().y()-80, this->geometry().width(), this->geometry().height()));
|
||||
m_exitAnimationGroup->start();
|
||||
// YYC Mark: Exit animation is not supported in Remix fork.
|
||||
this->close();
|
||||
}
|
||||
|
||||
void MainWindow::updateWidgetsPosition()
|
||||
{
|
||||
m_closeButton->move(width() - m_closeButton->width(), 0);
|
||||
m_prevButton->move(25, (height() - m_prevButton->sizeHint().height()) / 2);
|
||||
m_nextButton->move(width() - m_nextButton->sizeHint().width() - 25,
|
||||
(height() - m_prevButton->sizeHint().height()) / 2);
|
||||
m_bottomButtonGroup->move((width() - m_bottomButtonGroup->width()) / 2,
|
||||
height() - m_bottomButtonGroup->height());
|
||||
m_gv->move(width() - m_gv->width(), height() - m_gv->height());
|
||||
@@ -606,9 +480,7 @@ void MainWindow::updateWidgetsPosition()
|
||||
void MainWindow::toggleProtectedMode()
|
||||
{
|
||||
m_protectedMode = !m_protectedMode;
|
||||
m_closeButton->setVisible(!m_protectedMode);
|
||||
m_prevButton->setVisible(!m_protectedMode);
|
||||
m_nextButton->setVisible(!m_protectedMode);
|
||||
// YYC Mark: Protected mode is not supported in Remix fork.
|
||||
}
|
||||
|
||||
void MainWindow::toggleStayOnTop()
|
||||
@@ -647,7 +519,9 @@ bool MainWindow::canPaste() const
|
||||
|
||||
void MainWindow::quitAppAction(bool force)
|
||||
{
|
||||
if (!m_protectedMode || force) {
|
||||
// YYC Mark: Protect mode is not supported in Remix fork
|
||||
// Assume we are always in non-protected mode.
|
||||
if (/*!m_protectedMode*/ true || force) {
|
||||
closeWindow();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,11 +51,6 @@ public:
|
||||
|
||||
protected slots:
|
||||
void showEvent(QShowEvent *event) override;
|
||||
void enterEvent(QT_ENTER_EVENT *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;
|
||||
@@ -119,19 +114,11 @@ private:
|
||||
ActionManager *m_am;
|
||||
PlaylistManager *m_pm;
|
||||
|
||||
QPoint m_oldMousePos;
|
||||
QPropertyAnimation *m_fadeOutAnimation;
|
||||
QPropertyAnimation *m_floatUpAnimation;
|
||||
QParallelAnimationGroup *m_exitAnimationGroup;
|
||||
QFileSystemWatcher *m_fileSystemWatcher;
|
||||
ToolButton *m_closeButton;
|
||||
ToolButton *m_prevButton;
|
||||
ToolButton *m_nextButton;
|
||||
GraphicsView *m_graphicsView;
|
||||
NavigatorView *m_gv;
|
||||
BottomButtonGroup *m_bottomButtonGroup;
|
||||
bool m_protectedMode = false;
|
||||
bool m_clickedOnWindow = false;
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
||||
|
||||
@@ -18,7 +18,7 @@ NavigatorView::NavigatorView(QWidget *parent)
|
||||
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
setStyleSheet("background-color: rgba(0, 0, 0, 120);"
|
||||
"border-radius: 3px;");
|
||||
"border-style: none;");
|
||||
}
|
||||
|
||||
// doesn't take or manage its ownership
|
||||
|
||||
@@ -47,7 +47,7 @@ Settings *Settings::instance()
|
||||
|
||||
bool Settings::stayOnTop()
|
||||
{
|
||||
return m_qsettings->value("stay_on_top", true).toBool();
|
||||
return m_qsettings->value("stay_on_top", false).toBool();
|
||||
}
|
||||
|
||||
bool Settings::useLightCheckerboard()
|
||||
@@ -57,9 +57,9 @@ bool Settings::useLightCheckerboard()
|
||||
|
||||
Settings::DoubleClickBehavior Settings::doubleClickBehavior() const
|
||||
{
|
||||
QString result = m_qsettings->value("double_click_behavior", "Close").toString();
|
||||
QString result = m_qsettings->value("double_click_behavior", "Ignore").toString();
|
||||
|
||||
return QEnumHelper::fromString<DoubleClickBehavior>(result, DoubleClickBehavior::Close);
|
||||
return QEnumHelper::fromString<DoubleClickBehavior>(result, DoubleClickBehavior::Ignore);
|
||||
}
|
||||
|
||||
Settings::MouseWheelBehavior Settings::mouseWheelBehavior() const
|
||||
@@ -71,9 +71,9 @@ Settings::MouseWheelBehavior Settings::mouseWheelBehavior() const
|
||||
|
||||
Settings::WindowSizeBehavior Settings::initWindowSizeBehavior() const
|
||||
{
|
||||
QString result = m_qsettings->value("init_window_size_behavior", "Auto").toString();
|
||||
QString result = m_qsettings->value("init_window_size_behavior", "Maximized").toString();
|
||||
|
||||
return QEnumHelper::fromString<WindowSizeBehavior>(result, WindowSizeBehavior::Auto);
|
||||
return QEnumHelper::fromString<WindowSizeBehavior>(result, WindowSizeBehavior::Maximized);
|
||||
}
|
||||
|
||||
Qt::HighDpiScaleFactorRoundingPolicy Settings::hiDpiScaleFactorBehavior() const
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1">
|
||||
<TS version="2.1" language="en_US">
|
||||
<context>
|
||||
<name>AboutDialog</name>
|
||||
<message>
|
||||
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><title>fit-to-screen</title><path d="M17 4H20C21.1 4 22 4.9 22 6V8H20V6H17V4M4 8V6H7V4H4C2.9 4 2 4.9 2 6V8H4M20 16V18H17V20H20C21.1 20 22 19.1 22 18V16H20M7 18H4V16H2V18C2 19.1 2.9 20 4 20H7V18M18 8H6V16H18V8Z" /></svg>
|
||||
|
After Width: | Height: | Size: 279 B |
@@ -1,15 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 75 75" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;">
|
||||
<g transform="matrix(1,0,0,1,-119,-102)">
|
||||
<g id="go-next" transform="matrix(1.25,0,0,1.44231,119,-7.61538)">
|
||||
<rect x="0" y="76" width="60" height="52" style="fill:none;"/>
|
||||
<g transform="matrix(0.8,0,0,0.693333,0.260244,25.056)">
|
||||
<circle cx="37.175" cy="110.977" r="33.175" style="fill-opacity:0.15;stroke:white;stroke-width:2px;"/>
|
||||
</g>
|
||||
<g id="path867" transform="matrix(0.8,0,0,0.693333,1.80436,76.0055)">
|
||||
<path d="M31.578,26.175L42.911,37.508L31.578,48.809" style="fill:none;fill-rule:nonzero;stroke:white;stroke-width:2px;"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><title>page-last</title><path d="M5.59,7.41L10.18,12L5.59,16.59L7,18L13,12L7,6L5.59,7.41M16,6H18V18H16V6Z" /></svg>
|
||||
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 175 B |
@@ -1,15 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 75 75" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;">
|
||||
<g transform="matrix(1,0,0,1,-39,-102)">
|
||||
<g id="go-previous" transform="matrix(1.25,0,0,1.44231,39,-7.61538)">
|
||||
<rect x="0" y="76" width="60" height="52" style="fill:none;"/>
|
||||
<g transform="matrix(0.8,0,0,0.693333,0.260244,25.056)">
|
||||
<circle cx="37.175" cy="110.977" r="33.175" style="fill-opacity:0.15;stroke:white;stroke-width:2px;"/>
|
||||
</g>
|
||||
<g id="path867" transform="matrix(0.8,0,0,0.693333,-1.8205,76.0055)">
|
||||
<path d="M43.442,26.175L32.109,37.508L43.442,48.809" style="fill:none;fill-rule:nonzero;stroke:white;stroke-width:2px;"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><title>page-first</title><path d="M18.41,16.59L13.82,12L18.41,7.41L17,6L11,12L17,18L18.41,16.59M6,6H8V18H6V6Z" /></svg>
|
||||
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 179 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><title>flip-horizontal</title><path d="M15 21H17V19H15M19 9H21V7H19M3 5V19C3 20.1 3.9 21 5 21H9V19H5V5H9V3H5C3.9 3 3 3.9 3 5M19 3V5H21C21 3.9 20.1 3 19 3M11 23H13V1H11M19 17H21V15H19M15 5H17V3H15M19 13H21V11H19M19 21C20.1 21 21 20.1 21 19H19Z" /></svg>
|
||||
|
After Width: | Height: | Size: 312 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><title>rotate-left</title><path d="M13,4.07V1L8.45,5.55L13,10V6.09C15.84,6.57 18,9.03 18,12C18,14.97 15.84,17.43 13,17.91V19.93C16.95,19.44 20,16.08 20,12C20,7.92 16.95,4.56 13,4.07M7.1,18.32C8.26,19.22 9.61,19.76 11,19.93V17.9C10.13,17.75 9.29,17.41 8.54,16.87L7.1,18.32M6.09,13H4.07C4.24,14.39 4.79,15.73 5.69,16.89L7.1,15.47C6.58,14.72 6.23,13.88 6.09,13M7.11,8.53L5.7,7.11C4.8,8.27 4.24,9.61 4.07,11H6.09C6.23,10.13 6.58,9.28 7.11,8.53Z" /></svg>
|
||||
|
After Width: | Height: | Size: 510 B |
@@ -1,17 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5;">
|
||||
<g transform="matrix(1,0,0,1,-74,-7.10543e-15)">
|
||||
<g id="object-rotate-right" transform="matrix(1,0,0,1,74,7.10543e-15)">
|
||||
<rect x="0" y="0" width="32" height="32" style="fill:none;"/>
|
||||
<g transform="matrix(1,0,0,1,-1,-0.275147)">
|
||||
<g transform="matrix(1,0,0,1,-74,-7.10543e-15)">
|
||||
<path d="M100,18C100,22.967 95.967,27 91,27C86.033,27 82,22.967 82,18C82,13.033 86.033,9 91,9" style="fill:none;stroke:white;stroke-width:2px;"/>
|
||||
</g>
|
||||
<g transform="matrix(0.984136,-0.177418,0.177418,0.984136,-74.2676,16.4198)">
|
||||
<path d="M89,13L93,9L89,5" style="fill:none;stroke:white;stroke-width:2px;"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><title>rotate-right</title><path d="M16.89,15.5L18.31,16.89C19.21,15.73 19.76,14.39 19.93,13H17.91C17.77,13.87 17.43,14.72 16.89,15.5M13,17.9V19.92C14.39,19.75 15.74,19.21 16.9,18.31L15.46,16.87C14.71,17.41 13.87,17.76 13,17.9M19.93,11C19.76,9.61 19.21,8.27 18.31,7.11L16.89,8.53C17.43,9.28 17.77,10.13 17.91,11M15.55,5.55L11,1V4.07C7.06,4.56 4,7.92 4,12C4,16.08 7.05,19.44 11,19.93V17.91C8.16,17.43 6,14.97 6,12C6,9.03 8.16,6.57 11,6.09V10L15.55,5.55Z" /></svg>
|
||||
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 522 B |
@@ -1,24 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5;">
|
||||
<g transform="matrix(1,0,0,1,0,-37)">
|
||||
<g id="view-background-checkerboard" transform="matrix(1,0,0,1,0,37)">
|
||||
<rect x="0" y="0" width="32" height="32" style="fill:none;"/>
|
||||
<g id="rect814" transform="matrix(0.964431,0,0,0.907545,0.187581,-988.266)">
|
||||
<rect x="6.027" y="1095.56" width="10.369" height="11.019" style="fill:white;fill-opacity:0.87;"/>
|
||||
</g>
|
||||
<g id="rect814-4" transform="matrix(0.984615,0,0,0.898704,-0.143354,-978.502)">
|
||||
<rect x="16.396" y="1106.6" width="10.156" height="11.127" style="fill:white;fill-opacity:0.87;"/>
|
||||
</g>
|
||||
<g id="rect814-2" transform="matrix(0.963684,0,0,0.898697,0.199828,-978.495)">
|
||||
<rect x="6.019" y="1106.6" width="10.377" height="11.127" style="fill:white;fill-opacity:0.07;"/>
|
||||
</g>
|
||||
<g id="rect814-2-6" transform="matrix(0.980558,0,0,0.898693,-0.0768322,-978.47)">
|
||||
<rect x="16.396" y="1095.45" width="10.198" height="11.127" style="fill:white;fill-opacity:0.07;"/>
|
||||
</g>
|
||||
<g transform="matrix(1,0,0,0.952381,-74,-34)">
|
||||
<rect x="80" y="42" width="20" height="21" style="fill:none;stroke:white;stroke-width:2.05px;"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><title>checkerboard</title><path d="M2 2V22H22V2H2M20 12H16V16H20V20H16V16H12V20H8V16H4V12H8V8H4V4H8V8H12V4H16V8H20V12M16 8V12H12V8H16M12 12V16H8V12H12Z" /></svg>
|
||||
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 222 B |
@@ -1,24 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5;">
|
||||
<g transform="matrix(1,0,0,1,-37,-37)">
|
||||
<g id="view-fullscreen" transform="matrix(1,0,0,1,37,37)">
|
||||
<rect x="0" y="0" width="32" height="32" style="fill:none;"/>
|
||||
<g transform="matrix(1,0,0,1,-36,-37)">
|
||||
<path d="M42,49L42,43L48,43" style="fill:none;stroke:white;stroke-width:2px;"/>
|
||||
</g>
|
||||
<g transform="matrix(-1,1.22465e-16,1.22465e-16,1,68,-37)">
|
||||
<path d="M42,49L42,43L48,43" style="fill:none;stroke:white;stroke-width:2px;"/>
|
||||
</g>
|
||||
<g transform="matrix(1,-2.46519e-32,-2.46519e-32,-1,-36,69)">
|
||||
<path d="M42,49L42,43L48,43" style="fill:none;stroke:white;stroke-width:2px;"/>
|
||||
</g>
|
||||
<g transform="matrix(1.11111,0,0,1.14286,-42.3333,-42.8571)">
|
||||
<rect x="48" y="48" width="9" height="7" style="fill:none;stroke:white;stroke-width:1.77px;"/>
|
||||
</g>
|
||||
<g transform="matrix(-1,-1.22465e-16,1.22465e-16,-1,68,69)">
|
||||
<path d="M42,49L42,43L48,43" style="fill:none;stroke:white;stroke-width:2px;"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.6 KiB |
@@ -1,71 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="32"
|
||||
height="32"
|
||||
viewBox="0 0 8.4666665 8.4666669"
|
||||
version="1.1"
|
||||
id="svg8"
|
||||
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
|
||||
sodipodi:docname="window-close.svg">
|
||||
<defs
|
||||
id="defs2" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#000000"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.69803922"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="22.627417"
|
||||
inkscape:cx="19.29838"
|
||||
inkscape:cy="15.79404"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:pagecheckerboard="true"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1001"
|
||||
inkscape:window-x="-9"
|
||||
inkscape:window-y="-9"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-288.5333)">
|
||||
<path
|
||||
style="fill:none;stroke:#ffffff;stroke-width:0.396875;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
d="m 2.100237,290.55098 4.3234589,4.22265"
|
||||
id="path817"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;stroke:#ffffff;stroke-width:0.396875;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
d="m 2.099406,294.78651 4.3414732,-4.24185"
|
||||
id="path819"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 2.3 KiB |
@@ -1,17 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5;">
|
||||
<rect id="zoom-in" x="0" y="0" width="32" height="32" style="fill:none;"/>
|
||||
<g id="zoom-in1" serif:id="zoom-in">
|
||||
<g>
|
||||
<g transform="matrix(1,0,0,1,-1,0)">
|
||||
<circle cx="16" cy="15" r="9" style="fill:none;stroke:white;stroke-width:2px;"/>
|
||||
</g>
|
||||
<g transform="matrix(0.8,0.8,-0.8,0.8,27.6,-17.2)">
|
||||
<path d="M21,28L26,28" style="fill:none;stroke:white;stroke-width:2.65px;"/>
|
||||
</g>
|
||||
<path d="M11,15L19,15" style="fill:none;stroke:white;stroke-width:2px;"/>
|
||||
<path d="M15,11L15,19" style="fill:none;stroke:white;stroke-width:2px;"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><title>magnify-plus-outline</title><path d="M15.5,14L20.5,19L19,20.5L14,15.5V14.71L13.73,14.43C12.59,15.41 11.11,16 9.5,16A6.5,6.5 0 0,1 3,9.5A6.5,6.5 0 0,1 9.5,3A6.5,6.5 0 0,1 16,9.5C16,11.11 15.41,12.59 14.43,13.73L14.71,14H15.5M9.5,14C12,14 14,12 14,9.5C14,7 12,5 9.5,5C7,5 5,7 5,9.5C5,12 7,14 9.5,14M12,10H10V12H9V10H7V9H9V7H10V9H12V10Z" /></svg>
|
||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 410 B |
@@ -5,19 +5,19 @@
|
||||
<g id="zoom-original" transform="matrix(1,0,0,1,74,37)">
|
||||
<rect x="0" y="0" width="32" height="32" style="fill:none;"/>
|
||||
<g transform="matrix(1,0,0,1,-73,-37)">
|
||||
<path d="M85,57L85,49L84,49" style="fill:none;stroke:white;stroke-width:2px;"/>
|
||||
<path d="M85,57L85,49L84,49" style="fill:none;stroke:black;stroke-width:2px;"/>
|
||||
</g>
|
||||
<g transform="matrix(1,0,0,1,-74,-37)">
|
||||
<rect x="89" y="50" width="2" height="2" style="fill:white;"/>
|
||||
<rect x="89" y="50" width="2" height="2" style="fill:black;"/>
|
||||
</g>
|
||||
<g transform="matrix(1,0,0,1,-74,-33)">
|
||||
<rect x="89" y="50" width="2" height="2" style="fill:white;"/>
|
||||
<rect x="89" y="50" width="2" height="2" style="fill:black;"/>
|
||||
</g>
|
||||
<g transform="matrix(1,0,0,1,-64,-37)">
|
||||
<path d="M85,57L85,49L84,49" style="fill:none;stroke:white;stroke-width:2px;"/>
|
||||
<path d="M85,57L85,49L84,49" style="fill:none;stroke:black;stroke-width:2px;"/>
|
||||
</g>
|
||||
<g transform="matrix(1,0,0,0.952381,-74,-34)">
|
||||
<rect x="80" y="42" width="20" height="21" style="fill:none;stroke:white;stroke-width:2.05px;stroke-linecap:round;stroke-linejoin:round;"/>
|
||||
<rect x="80" y="42" width="20" height="21" style="fill:none;stroke:black;stroke-width:2.05px;stroke-linecap:round;stroke-linejoin:round;"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
|
||||
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
@@ -1,18 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5;">
|
||||
<g transform="matrix(1,0,0,1,-74,0)">
|
||||
<g id="zoom-out" transform="matrix(1,0,0,1,74,0)">
|
||||
<rect x="0" y="0" width="32" height="32" style="fill:none;"/>
|
||||
<g>
|
||||
<g transform="matrix(1,0,0,1,-1,0)">
|
||||
<circle cx="16" cy="15" r="9" style="fill:none;stroke:white;stroke-width:2px;"/>
|
||||
</g>
|
||||
<g transform="matrix(0.8,0.8,-0.8,0.8,27.6,-17.2)">
|
||||
<path d="M21,28L26,28" style="fill:none;stroke:white;stroke-width:2.65px;"/>
|
||||
</g>
|
||||
<path d="M11,15L19,15" style="fill:none;stroke:white;stroke-width:2px;"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><title>magnify-minus-outline</title><path d="M15.5,14H14.71L14.43,13.73C15.41,12.59 16,11.11 16,9.5A6.5,6.5 0 0,0 9.5,3A6.5,6.5 0 0,0 3,9.5A6.5,6.5 0 0,0 9.5,16C11.11,16 12.59,15.41 13.73,14.43L14,14.71V15.5L19,20.5L20.5,19L15.5,14M9.5,14C7,14 5,12 5,9.5C5,7 7,5 9.5,5C12,5 14,7 14,9.5C14,12 12,14 9.5,14M7,9H12V10H7V9Z" /></svg>
|
||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 389 B |
@@ -2,12 +2,13 @@
|
||||
<qresource prefix="/">
|
||||
<file>icons/zoom-in.svg</file>
|
||||
<file>icons/zoom-out.svg</file>
|
||||
<file>icons/view-fullscreen.svg</file>
|
||||
<file>icons/fit-in-view.svg</file>
|
||||
<file>icons/horizontal-flip.svg</file>
|
||||
<file>icons/zoom-original.svg</file>
|
||||
<file>icons/object-rotate-left.svg</file>
|
||||
<file>icons/object-rotate-right.svg</file>
|
||||
<file>icons/view-background-checkerboard.svg</file>
|
||||
<file>icons/app-icon.svg</file>
|
||||
<file>icons/window-close.svg</file>
|
||||
<file>icons/go-next.svg</file>
|
||||
<file>icons/go-previous.svg</file>
|
||||
<file>plain/translators.html</file>
|
||||
|
||||
@@ -30,6 +30,28 @@
|
||||
<true/>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>${MACOSX_BUNDLE_COPYRIGHT}</string>
|
||||
<!-- FIXME: this list can't be automatically generated by Qt's CMake API, don't know why. -->
|
||||
<key>CFBundleLocalizations</key>
|
||||
<array>
|
||||
<string>en</string>
|
||||
<string>ca</string>
|
||||
<string>de</string>
|
||||
<string>es</string>
|
||||
<string>fr</string>
|
||||
<string>id</string>
|
||||
<string>it</string>
|
||||
<string>ja</string>
|
||||
<string>ko</string>
|
||||
<string>nb_NO</string>
|
||||
<string>nl</string>
|
||||
<string>pa_PK</string>
|
||||
<string>ru</string>
|
||||
<string>si</string>
|
||||
<string>ta</string>
|
||||
<string>tr</string>
|
||||
<string>uk</string>
|
||||
<string>zh_CN</string>
|
||||
</array>
|
||||
<key>CFBundleDocumentTypes</key>
|
||||
<array>
|
||||
<!-- JPEG -->
|
||||
|
||||
@@ -80,6 +80,28 @@
|
||||
</screenshot>
|
||||
</screenshots>
|
||||
<releases>
|
||||
<release type="stable" version="1.0.0" date="2025-05-03T00:00:00Z">
|
||||
<description>
|
||||
<p>This release adds the following features:</p>
|
||||
<ul>
|
||||
<li>Support enforce windowed mode on start-up</li>
|
||||
<li>Reload image automatically when current image gets updated</li>
|
||||
</ul>
|
||||
<p>This release fixes the following bugs:</p>
|
||||
<ul>
|
||||
<li>Refer to the right exiv2 CMake module so it can be found on Linux</li>
|
||||
<li>Display correct text language on macOS</li>
|
||||
</ul>
|
||||
<p>This release includes the following changes:</p>
|
||||
<ul>
|
||||
<li>Use native text for shortcut editor's label</li>
|
||||
<li>Display native commandline message when possible</li>
|
||||
<li>Merge Qt translations into app applications as well</li>
|
||||
</ul>
|
||||
<p>With contributions from:</p>
|
||||
<p>Heimen Stoffels, albanobattistella, mmahhi</p>
|
||||
</description>
|
||||
</release>
|
||||
<release type="stable" version="0.9.2" date="2025-03-05T00:00:00Z">
|
||||
<description>
|
||||
<p>This release fixes the following bug:</p>
|
||||
@@ -210,7 +232,7 @@
|
||||
<description>
|
||||
<p>This release adds the following features:</p>
|
||||
<ul>
|
||||
<li>TIF and TIFF format files in the same folder will now be automatedly added to the gallery</li>
|
||||
<li>TIF and TIFF format files in the same folder will now be automatically added to the gallery</li>
|
||||
<li>Built-in window resizing now also supports Linux desktop. (macOS might also works as well)</li>
|
||||
</ul>
|
||||
<p>This release fixes the following bugs:</p>
|
||||
|
||||
@@ -0,0 +1,193 @@
|
||||
; Script generated by the Inno Setup Script Wizard.
|
||||
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
|
||||
|
||||
; YYC MARK:
|
||||
; This file MUST be placed with "ppic.exe" before compiling this script.
|
||||
; Otherwise exception will be thrown.
|
||||
|
||||
#define MyAppName "Pineapple Pictures"
|
||||
#define MyAppVersion "@PROJECT_VERSION@"
|
||||
#define MyAppPublisher "BLumia"
|
||||
#define MyAppURL "https://github.com/BLumia/pineapple-pictures"
|
||||
#define MyAppExeName "ppic.exe"
|
||||
|
||||
[Setup]
|
||||
; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications.
|
||||
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
|
||||
AppId={{B5291320-FE7C-4069-BF87-A0AC327FCD20}
|
||||
AppName={#MyAppName}
|
||||
AppVersion={#MyAppVersion}
|
||||
;AppVerName={#MyAppName} {#MyAppVersion}
|
||||
AppPublisher={#MyAppPublisher}
|
||||
AppPublisherURL={#MyAppURL}
|
||||
AppSupportURL={#MyAppURL}
|
||||
AppUpdatesURL={#MyAppURL}
|
||||
DefaultDirName={autopf}\pineapple-pictures
|
||||
UninstallDisplayIcon={app}\{#MyAppExeName}
|
||||
; "ArchitecturesAllowed=x64compatible" specifies that Setup cannot run
|
||||
; on anything but x64 and Windows 11 on Arm.
|
||||
ArchitecturesAllowed=x64compatible
|
||||
; "ArchitecturesInstallIn64BitMode=x64compatible" requests that the
|
||||
; install be done in "64-bit mode" on x64 or Windows 11 on Arm,
|
||||
; meaning it should use the native 64-bit Program Files directory and
|
||||
; the 64-bit view of the registry.
|
||||
ArchitecturesInstallIn64BitMode=x64compatible
|
||||
ChangesAssociations=yes
|
||||
DefaultGroupName={#MyAppName}
|
||||
AllowNoIcons=yes
|
||||
LicenseFile=LICENSE
|
||||
; Uncomment the following line to run in non administrative install mode (install for current user only).
|
||||
;PrivilegesRequired=lowest
|
||||
PrivilegesRequiredOverridesAllowed=dialog
|
||||
OutputDir=.
|
||||
OutputBaseFilename=ppic-setup
|
||||
SolidCompression=yes
|
||||
WizardStyle=modern
|
||||
|
||||
[Languages]
|
||||
Name: "english"; MessagesFile: "compiler:Default.isl"
|
||||
|
||||
[CustomMessages]
|
||||
english.Other=Other:
|
||||
english.AssociateWithFiles=Associate %1 with its supported file types.
|
||||
english.InstallVcRedist=Installing Microsoft Visual C++ Redistributable...
|
||||
|
||||
[Tasks]
|
||||
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
|
||||
Name: "associatewithfiles"; Description: "{cm:AssociateWithFiles,{#MyAppName}}"; GroupDescription: "{cm:Other}"
|
||||
|
||||
[Files]
|
||||
Source: "{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion
|
||||
Source: "*"; Excludes: "vc_redist.x64.exe,ppic-setup.exe,ppic.iss"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
|
||||
Source: "vc_redist.x64.exe"; DestDir: "{tmp}"; Flags: deleteafterinstall
|
||||
; NOTE: Don't use "Flags: ignoreversion" on any shared system files
|
||||
|
||||
[Registry]
|
||||
; YYC MARK:
|
||||
; When adding new supported file estensions, pleasse copy following comment and de-comment it.
|
||||
; Then search "wtf" (case insensitive) inside it and replace it (preserve word case) with your desired file extension.
|
||||
|
||||
; ; .wtf File Type
|
||||
; Root: HKA; Subkey: "Software\Classes\.wtf\OpenWithProgids"; ValueType: string; ValueName: "PineapplePictures.wtf"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles
|
||||
; Root: HKA; Subkey: "Software\Classes\PineapplePictures.wtf"; ValueType: string; ValueName: ""; ValueData: "Pineapple Pictures WTF Image"; Flags: uninsdeletekey; Tasks: associatewithfiles
|
||||
; Root: HKA; Subkey: "Software\Classes\PineapplePictures.wtf\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\{#MyAppExeName},0"; Tasks: associatewithfiles
|
||||
; Root: HKA; Subkey: "Software\Classes\PineapplePictures.wtf\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1"""; Tasks: associatewithfiles
|
||||
|
||||
; .jpg File Type
|
||||
Root: HKA; Subkey: "Software\Classes\.jpg\OpenWithProgids"; ValueType: string; ValueName: "PineapplePictures.jpg"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles
|
||||
Root: HKA; Subkey: "Software\Classes\PineapplePictures.jpg"; ValueType: string; ValueName: ""; ValueData: "Pineapple Pictures JPG Image"; Flags: uninsdeletekey; Tasks: associatewithfiles
|
||||
Root: HKA; Subkey: "Software\Classes\PineapplePictures.jpg\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\{#MyAppExeName},0"; Tasks: associatewithfiles
|
||||
Root: HKA; Subkey: "Software\Classes\PineapplePictures.jpg\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1"""; Tasks: associatewithfiles
|
||||
|
||||
; .jfif File Type
|
||||
Root: HKA; Subkey: "Software\Classes\.jfif\OpenWithProgids"; ValueType: string; ValueName: "PineapplePictures.jfif"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles
|
||||
Root: HKA; Subkey: "Software\Classes\PineapplePictures.jfif"; ValueType: string; ValueName: ""; ValueData: "Pineapple Pictures JFIF Image"; Flags: uninsdeletekey; Tasks: associatewithfiles
|
||||
Root: HKA; Subkey: "Software\Classes\PineapplePictures.jfif\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\{#MyAppExeName},0"; Tasks: associatewithfiles
|
||||
Root: HKA; Subkey: "Software\Classes\PineapplePictures.jfif\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1"""; Tasks: associatewithfiles
|
||||
|
||||
; .gif File Type
|
||||
Root: HKA; Subkey: "Software\Classes\.gif\OpenWithProgids"; ValueType: string; ValueName: "PineapplePictures.gif"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles
|
||||
Root: HKA; Subkey: "Software\Classes\PineapplePictures.gif"; ValueType: string; ValueName: ""; ValueData: "Pineapple Pictures GIF Image"; Flags: uninsdeletekey; Tasks: associatewithfiles
|
||||
Root: HKA; Subkey: "Software\Classes\PineapplePictures.gif\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\{#MyAppExeName},0"; Tasks: associatewithfiles
|
||||
Root: HKA; Subkey: "Software\Classes\PineapplePictures.gif\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1"""; Tasks: associatewithfiles
|
||||
|
||||
; .bmp File Type
|
||||
Root: HKA; Subkey: "Software\Classes\.bmp\OpenWithProgids"; ValueType: string; ValueName: "PineapplePictures.bmp"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles
|
||||
Root: HKA; Subkey: "Software\Classes\PineapplePictures.bmp"; ValueType: string; ValueName: ""; ValueData: "Pineapple Pictures BMP Image"; Flags: uninsdeletekey; Tasks: associatewithfiles
|
||||
Root: HKA; Subkey: "Software\Classes\PineapplePictures.bmp\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\{#MyAppExeName},0"; Tasks: associatewithfiles
|
||||
Root: HKA; Subkey: "Software\Classes\PineapplePictures.bmp\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1"""; Tasks: associatewithfiles
|
||||
|
||||
; .png File Type
|
||||
Root: HKA; Subkey: "Software\Classes\.png\OpenWithProgids"; ValueType: string; ValueName: "PineapplePictures.png"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles
|
||||
Root: HKA; Subkey: "Software\Classes\PineapplePictures.png"; ValueType: string; ValueName: ""; ValueData: "Pineapple Pictures PNG Image"; Flags: uninsdeletekey; Tasks: associatewithfiles
|
||||
Root: HKA; Subkey: "Software\Classes\PineapplePictures.png\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\{#MyAppExeName},0"; Tasks: associatewithfiles
|
||||
Root: HKA; Subkey: "Software\Classes\PineapplePictures.png\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1"""; Tasks: associatewithfiles
|
||||
|
||||
; .ico File Type
|
||||
Root: HKA; Subkey: "Software\Classes\.ico\OpenWithProgids"; ValueType: string; ValueName: "PineapplePictures.ico"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles
|
||||
Root: HKA; Subkey: "Software\Classes\PineapplePictures.ico"; ValueType: string; ValueName: ""; ValueData: "Pineapple Pictures ICO Image"; Flags: uninsdeletekey; Tasks: associatewithfiles
|
||||
Root: HKA; Subkey: "Software\Classes\PineapplePictures.ico\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\{#MyAppExeName},0"; Tasks: associatewithfiles
|
||||
Root: HKA; Subkey: "Software\Classes\PineapplePictures.ico\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1"""; Tasks: associatewithfiles
|
||||
|
||||
; .jpeg File Type
|
||||
Root: HKA; Subkey: "Software\Classes\.jpeg\OpenWithProgids"; ValueType: string; ValueName: "PineapplePictures.jpeg"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles
|
||||
Root: HKA; Subkey: "Software\Classes\PineapplePictures.jpeg"; ValueType: string; ValueName: ""; ValueData: "Pineapple Pictures JPEG Image"; Flags: uninsdeletekey; Tasks: associatewithfiles
|
||||
Root: HKA; Subkey: "Software\Classes\PineapplePictures.jpeg\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\{#MyAppExeName},0"; Tasks: associatewithfiles
|
||||
Root: HKA; Subkey: "Software\Classes\PineapplePictures.jpeg\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1"""; Tasks: associatewithfiles
|
||||
|
||||
; .tif File Type
|
||||
Root: HKA; Subkey: "Software\Classes\.tif\OpenWithProgids"; ValueType: string; ValueName: "PineapplePictures.tif"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles
|
||||
Root: HKA; Subkey: "Software\Classes\PineapplePictures.tif"; ValueType: string; ValueName: ""; ValueData: "Pineapple Pictures TIF Image"; Flags: uninsdeletekey; Tasks: associatewithfiles
|
||||
Root: HKA; Subkey: "Software\Classes\PineapplePictures.tif\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\{#MyAppExeName},0"; Tasks: associatewithfiles
|
||||
Root: HKA; Subkey: "Software\Classes\PineapplePictures.tif\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1"""; Tasks: associatewithfiles
|
||||
|
||||
; .tiff File Type
|
||||
Root: HKA; Subkey: "Software\Classes\.tiff\OpenWithProgids"; ValueType: string; ValueName: "PineapplePictures.tiff"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles
|
||||
Root: HKA; Subkey: "Software\Classes\PineapplePictures.tiff"; ValueType: string; ValueName: ""; ValueData: "Pineapple Pictures TIFF Image"; Flags: uninsdeletekey; Tasks: associatewithfiles
|
||||
Root: HKA; Subkey: "Software\Classes\PineapplePictures.tiff\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\{#MyAppExeName},0"; Tasks: associatewithfiles
|
||||
Root: HKA; Subkey: "Software\Classes\PineapplePictures.tiff\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1"""; Tasks: associatewithfiles
|
||||
|
||||
; .webp File Type
|
||||
Root: HKA; Subkey: "Software\Classes\.webp\OpenWithProgids"; ValueType: string; ValueName: "PineapplePictures.webp"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles
|
||||
Root: HKA; Subkey: "Software\Classes\PineapplePictures.webp"; ValueType: string; ValueName: ""; ValueData: "Pineapple Pictures WEBP Image"; Flags: uninsdeletekey; Tasks: associatewithfiles
|
||||
Root: HKA; Subkey: "Software\Classes\PineapplePictures.webp\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\{#MyAppExeName},0"; Tasks: associatewithfiles
|
||||
Root: HKA; Subkey: "Software\Classes\PineapplePictures.webp\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1"""; Tasks: associatewithfiles
|
||||
|
||||
; .psd File Type
|
||||
Root: HKA; Subkey: "Software\Classes\.psd\OpenWithProgids"; ValueType: string; ValueName: "PineapplePictures.psd"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles
|
||||
Root: HKA; Subkey: "Software\Classes\PineapplePictures.psd"; ValueType: string; ValueName: ""; ValueData: "Pineapple Pictures PSD Image"; Flags: uninsdeletekey; Tasks: associatewithfiles
|
||||
Root: HKA; Subkey: "Software\Classes\PineapplePictures.psd\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\{#MyAppExeName},0"; Tasks: associatewithfiles
|
||||
Root: HKA; Subkey: "Software\Classes\PineapplePictures.psd\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1"""; Tasks: associatewithfiles
|
||||
|
||||
; .svg File Type
|
||||
Root: HKA; Subkey: "Software\Classes\.svg\OpenWithProgids"; ValueType: string; ValueName: "PineapplePictures.svg"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles
|
||||
Root: HKA; Subkey: "Software\Classes\PineapplePictures.svg"; ValueType: string; ValueName: ""; ValueData: "Pineapple Pictures SVG Image"; Flags: uninsdeletekey; Tasks: associatewithfiles
|
||||
Root: HKA; Subkey: "Software\Classes\PineapplePictures.svg\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\{#MyAppExeName},0"; Tasks: associatewithfiles
|
||||
Root: HKA; Subkey: "Software\Classes\PineapplePictures.svg\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1"""; Tasks: associatewithfiles
|
||||
|
||||
; .kra File Type
|
||||
Root: HKA; Subkey: "Software\Classes\.kra\OpenWithProgids"; ValueType: string; ValueName: "PineapplePictures.kra"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles
|
||||
Root: HKA; Subkey: "Software\Classes\PineapplePictures.kra"; ValueType: string; ValueName: ""; ValueData: "Pineapple Pictures KRA Image"; Flags: uninsdeletekey; Tasks: associatewithfiles
|
||||
Root: HKA; Subkey: "Software\Classes\PineapplePictures.kra\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\{#MyAppExeName},0"; Tasks: associatewithfiles
|
||||
Root: HKA; Subkey: "Software\Classes\PineapplePictures.kra\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1"""; Tasks: associatewithfiles
|
||||
|
||||
; .xcf File Type
|
||||
Root: HKA; Subkey: "Software\Classes\.xcf\OpenWithProgids"; ValueType: string; ValueName: "PineapplePictures.xcf"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles
|
||||
Root: HKA; Subkey: "Software\Classes\PineapplePictures.xcf"; ValueType: string; ValueName: ""; ValueData: "Pineapple Pictures XCF Image"; Flags: uninsdeletekey; Tasks: associatewithfiles
|
||||
Root: HKA; Subkey: "Software\Classes\PineapplePictures.xcf\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\{#MyAppExeName},0"; Tasks: associatewithfiles
|
||||
Root: HKA; Subkey: "Software\Classes\PineapplePictures.xcf\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1"""; Tasks: associatewithfiles
|
||||
|
||||
; .avif File Type
|
||||
Root: HKA; Subkey: "Software\Classes\.avif\OpenWithProgids"; ValueType: string; ValueName: "PineapplePictures.avif"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles
|
||||
Root: HKA; Subkey: "Software\Classes\PineapplePictures.avif"; ValueType: string; ValueName: ""; ValueData: "Pineapple Pictures AVIF Image"; Flags: uninsdeletekey; Tasks: associatewithfiles
|
||||
Root: HKA; Subkey: "Software\Classes\PineapplePictures.avif\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\{#MyAppExeName},0"; Tasks: associatewithfiles
|
||||
Root: HKA; Subkey: "Software\Classes\PineapplePictures.avif\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1"""; Tasks: associatewithfiles
|
||||
|
||||
; .qoi File Type
|
||||
Root: HKA; Subkey: "Software\Classes\.qoi\OpenWithProgids"; ValueType: string; ValueName: "PineapplePictures.qoi"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles
|
||||
Root: HKA; Subkey: "Software\Classes\PineapplePictures.qoi"; ValueType: string; ValueName: ""; ValueData: "Pineapple Pictures QOI Image"; Flags: uninsdeletekey; Tasks: associatewithfiles
|
||||
Root: HKA; Subkey: "Software\Classes\PineapplePictures.qoi\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\{#MyAppExeName},0"; Tasks: associatewithfiles
|
||||
Root: HKA; Subkey: "Software\Classes\PineapplePictures.qoi\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1"""; Tasks: associatewithfiles
|
||||
|
||||
; .apng File Type
|
||||
Root: HKA; Subkey: "Software\Classes\.apng\OpenWithProgids"; ValueType: string; ValueName: "PineapplePictures.apng"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles
|
||||
Root: HKA; Subkey: "Software\Classes\PineapplePictures.apng"; ValueType: string; ValueName: ""; ValueData: "Pineapple Pictures APNG Image"; Flags: uninsdeletekey; Tasks: associatewithfiles
|
||||
Root: HKA; Subkey: "Software\Classes\PineapplePictures.apng\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\{#MyAppExeName},0"; Tasks: associatewithfiles
|
||||
Root: HKA; Subkey: "Software\Classes\PineapplePictures.apng\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1"""; Tasks: associatewithfiles
|
||||
|
||||
; .exr File Type
|
||||
Root: HKA; Subkey: "Software\Classes\.exr\OpenWithProgids"; ValueType: string; ValueName: "PineapplePictures.exr"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles
|
||||
Root: HKA; Subkey: "Software\Classes\PineapplePictures.exr"; ValueType: string; ValueName: ""; ValueData: "Pineapple Pictures EXR Image"; Flags: uninsdeletekey; Tasks: associatewithfiles
|
||||
Root: HKA; Subkey: "Software\Classes\PineapplePictures.exr\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\{#MyAppExeName},0"; Tasks: associatewithfiles
|
||||
Root: HKA; Subkey: "Software\Classes\PineapplePictures.exr\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1"""; Tasks: associatewithfiles
|
||||
|
||||
[Icons]
|
||||
Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
|
||||
Name: "{group}\{cm:ProgramOnTheWeb,{#MyAppName}}"; Filename: "{#MyAppURL}"
|
||||
Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}"
|
||||
Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
|
||||
|
||||
[Run]
|
||||
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent
|
||||
Filename: "{tmp}\vc_redist.x64.exe"; Parameters: "/install /quiet /norestart"; StatusMsg: "{cm:InstallVcRedist}"; Flags: waituntilterminated
|
||||
|
||||
@@ -9,6 +9,10 @@ TARGET = ppic
|
||||
TEMPLATE = app
|
||||
DEFINES += PPIC_VERSION_STRING=\\\"x.y.z\\\"
|
||||
|
||||
win32 {
|
||||
DEFINES += FLAG_PORTABLE_MODE_SUPPORT=1
|
||||
}
|
||||
|
||||
# The following define makes your compiler emit warnings if you use
|
||||
# any feature of Qt which has been marked as deprecated (the exact warnings
|
||||
# depend on your compiler). Please consult the documentation of the
|
||||
@@ -64,7 +68,7 @@ HEADERS += \
|
||||
app/fileopeneventhandler.h
|
||||
|
||||
TRANSLATIONS = \
|
||||
app/translations/PineapplePictures.ts \
|
||||
app/translations/PineapplePictures_en.ts \
|
||||
app/translations/PineapplePictures_zh_CN.ts \
|
||||
app/translations/PineapplePictures_de.ts \
|
||||
app/translations/PineapplePictures_es.ts \
|
||||
|
||||