diff options
Diffstat (limited to 'src/pixeltool/qpixeltool.cpp')
-rw-r--r-- | src/pixeltool/qpixeltool.cpp | 214 |
1 files changed, 100 insertions, 114 deletions
diff --git a/src/pixeltool/qpixeltool.cpp b/src/pixeltool/qpixeltool.cpp index 760c3f01e..9142d387e 100644 --- a/src/pixeltool/qpixeltool.cpp +++ b/src/pixeltool/qpixeltool.cpp @@ -1,36 +1,10 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "qpixeltool.h" #include <qapplication.h> #include <qdir.h> -#include <qapplication.h> #include <qscreen.h> #if QT_CONFIG(clipboard) #include <qclipboard.h> @@ -43,7 +17,6 @@ #include <qmenu.h> #include <qactiongroup.h> #include <qimagewriter.h> -#include <qscreen.h> #include <qstandardpaths.h> #include <qtextstream.h> #include <qwindow.h> @@ -51,14 +24,28 @@ #include <qdebug.h> +#include <cmath> + QT_BEGIN_NAMESPACE -static QPoint initialPos(const QSettings &settings, const QSize &initialSize) +using namespace Qt::StringLiterals; + +static constexpr auto settingsGroup = "QPixelTool"_L1; +static constexpr auto organization = "QtProject"_L1; +static constexpr auto autoUpdateKey = "autoUpdate"_L1; +static constexpr auto gridSizeKey = "gridSize"_L1; +static constexpr auto gridActiveKey = "gridActive"_L1; +static constexpr auto zoomKey = "zoom"_L1; +static constexpr auto initialSizeKey = "initialSize"_L1; +static constexpr auto positionKey = "position"_L1; +static constexpr auto lcdModeKey = "lcdMode"_L1; + +static QPoint initialPos(const QSettings &settings, QSize initialSize) { const QPoint defaultPos = QGuiApplication::primaryScreen()->availableGeometry().topLeft(); const QPoint savedPos = - settings.value(QLatin1String("position"), QVariant(defaultPos)).toPoint(); - auto savedScreen = QGuiApplication::screenAt(savedPos); + settings.value(positionKey, QVariant(defaultPos)).toPoint(); + auto *savedScreen = QGuiApplication::screenAt(savedPos); return savedScreen != nullptr && savedScreen->availableGeometry().intersects(QRect(savedPos, initialSize)) ? savedPos : defaultPos; @@ -68,13 +55,13 @@ QPixelTool::QPixelTool(QWidget *parent) : QWidget(parent) { setWindowTitle(QCoreApplication::applicationName()); - QSettings settings(QLatin1String("QtProject"), QLatin1String("QPixelTool")); - m_autoUpdate = settings.value(QLatin1String("autoUpdate"), 0).toBool(); - m_gridSize = settings.value(QLatin1String("gridSize"), 1).toInt(); - m_gridActive = settings.value(QLatin1String("gridActive"), 1).toInt(); - m_zoom = settings.value(QLatin1String("zoom"), 4).toInt(); - m_initialSize = settings.value(QLatin1String("initialSize"), QSize(250, 200)).toSize(); - m_lcdMode = settings.value(QLatin1String("lcdMode"), 0).toInt(); + QSettings settings(organization, settingsGroup); + m_autoUpdate = settings.value(autoUpdateKey, 0).toBool(); + m_gridSize = settings.value(gridSizeKey, 1).toInt(); + m_gridActive = settings.value(gridActiveKey, 1).toInt(); + m_zoom = settings.value(zoomKey, 4).toInt(); + m_initialSize = settings.value(initialSizeKey, QSize(250, 200)).toSize(); + m_lcdMode = settings.value(lcdModeKey, 0).toInt(); move(initialPos(settings, m_initialSize)); @@ -85,14 +72,14 @@ QPixelTool::QPixelTool(QWidget *parent) QPixelTool::~QPixelTool() { - QSettings settings(QLatin1String("QtProject"), QLatin1String("QPixelTool")); - settings.setValue(QLatin1String("autoUpdate"), int(m_autoUpdate)); - settings.setValue(QLatin1String("gridSize"), m_gridSize); - settings.setValue(QLatin1String("gridActive"), m_gridActive); - settings.setValue(QLatin1String("zoom"), m_zoom); - settings.setValue(QLatin1String("initialSize"), size()); - settings.setValue(QLatin1String("position"), pos()); - settings.setValue(QLatin1String("lcdMode"), m_lcdMode); + QSettings settings(organization, settingsGroup); + settings.setValue(autoUpdateKey, int(m_autoUpdate)); + settings.setValue(gridSizeKey, m_gridSize); + settings.setValue(gridActiveKey, m_gridActive); + settings.setValue(zoomKey, m_zoom); + settings.setValue(initialSizeKey, size()); + settings.setValue(positionKey, pos()); + settings.setValue(lcdModeKey, m_lcdMode); } void QPixelTool::setPreviewImage(const QImage &image) @@ -231,18 +218,18 @@ void QPixelTool::paintEvent(QPaintEvent *) } } - QFont f(QStringList{u"courier"_qs}, -1, QFont::Bold); + QFont f(QStringList{u"courier"_s}, -1, QFont::Bold); p.setFont(f); if (m_displayZoom) { render_string(&p, w, h, - QLatin1String("Zoom: x") + QString::number(m_zoom), + "Zoom: x"_L1 + QString::number(m_zoom), Qt::AlignTop | Qt::AlignRight); } if (m_displayGridSize) { render_string(&p, w, h, - QLatin1String("Grid size: ") + QString::number(m_gridSize), + "Grid size: "_L1 + QString::number(m_gridSize), Qt::AlignBottom | Qt::AlignLeft); } @@ -314,7 +301,7 @@ void QPixelTool::keyPressEvent(QKeyEvent *e) break; #endif // QT_CONFIG(clipboard) case Qt::Key_S: - if (e->modifiers() & Qt::ControlModifier) { + if (e->modifiers().testFlag(Qt::ControlModifier)) { releaseKeyboard(); saveToFile(); } @@ -398,66 +385,66 @@ void QPixelTool::contextMenuEvent(QContextMenuEvent *e) m_freeze = true; QMenu menu; - menu.addAction(QLatin1String("Qt Pixel Zooming Tool"))->setEnabled(false); + menu.addAction("Qt Pixel Zooming Tool"_L1)->setEnabled(false); menu.addSeparator(); // Grid color options... - QActionGroup *gridGroup = new QActionGroup(&menu); - addCheckableAction(menu, QLatin1String("White grid"), m_gridActive == 2, + auto *gridGroup = new QActionGroup(&menu); + addCheckableAction(menu, "White grid"_L1, m_gridActive == 2, Qt::Key_W, gridGroup); - QAction *blackGrid = addCheckableAction(menu, QLatin1String("Black grid"), + QAction *blackGrid = addCheckableAction(menu, "Black grid"_L1, m_gridActive == 1, Qt::Key_B, gridGroup); - QAction *noGrid = addCheckableAction(menu, QLatin1String("No grid"), m_gridActive == 0, + QAction *noGrid = addCheckableAction(menu, "No grid"_L1, m_gridActive == 0, Qt::Key_N, gridGroup); menu.addSeparator(); // Grid size options - menu.addAction(QLatin1String("Increase grid size"), - this, &QPixelTool::increaseGridSize, Qt::Key_PageUp); - menu.addAction(QLatin1String("Decrease grid size"), - this, &QPixelTool::decreaseGridSize, Qt::Key_PageDown); + menu.addAction("Increase grid size"_L1, Qt::Key_PageUp, + this, &QPixelTool::increaseGridSize); + menu.addAction("Decrease grid size"_L1, Qt::Key_PageDown, + this, &QPixelTool::decreaseGridSize); menu.addSeparator(); - QActionGroup *lcdGroup = new QActionGroup(&menu); - addCheckableAction(menu, QLatin1String("No subpixels"), m_lcdMode == 0, + auto *lcdGroup = new QActionGroup(&menu); + addCheckableAction(menu, "No subpixels"_L1, m_lcdMode == 0, QKeySequence(), lcdGroup); - QAction *rgbPixels = addCheckableAction(menu, QLatin1String("RGB subpixels"), + QAction *rgbPixels = addCheckableAction(menu, "RGB subpixels"_L1, m_lcdMode == 1, QKeySequence(), lcdGroup); - QAction *bgrPixels = addCheckableAction(menu, QLatin1String("BGR subpixels"), + QAction *bgrPixels = addCheckableAction(menu, "BGR subpixels"_L1, m_lcdMode == 2, QKeySequence(), lcdGroup); - QAction *vrgbPixels = addCheckableAction(menu, QLatin1String("VRGB subpixels"), + QAction *vrgbPixels = addCheckableAction(menu, "VRGB subpixels"_L1, m_lcdMode == 3, QKeySequence(), lcdGroup); - QAction *vbgrPixels = addCheckableAction(menu, QLatin1String("VBGR subpixels"), + QAction *vbgrPixels = addCheckableAction(menu, "VBGR subpixels"_L1, m_lcdMode == 4, QKeySequence(), lcdGroup); menu.addSeparator(); // Zoom options - menu.addAction(QLatin1String("Zoom in"), - this, &QPixelTool::increaseZoom, Qt::Key_Plus); - menu.addAction(QLatin1String("Zoom out"), - this, &QPixelTool::decreaseZoom, Qt::Key_Minus); + menu.addAction("Zoom in"_L1, Qt::Key_Plus, + this, &QPixelTool::increaseZoom); + menu.addAction("Zoom out"_L1, Qt::Key_Minus, + this, &QPixelTool::decreaseZoom); menu.addSeparator(); // Freeze / Autoupdate - QAction *freeze = addCheckableAction(menu, QLatin1String("Frozen"), + QAction *freeze = addCheckableAction(menu, "Frozen"_L1, tmpFreeze, Qt::Key_Space); - QAction *autoUpdate = addCheckableAction(menu, QLatin1String("Continuous update"), + QAction *autoUpdate = addCheckableAction(menu, "Continuous update"_L1, m_autoUpdate, Qt::Key_A); menu.addSeparator(); // Copy to clipboard / save - menu.addAction(QLatin1String("Save as image..."), - this, &QPixelTool::saveToFile, QKeySequence::SaveAs); + menu.addAction("Save as image..."_L1, QKeySequence::SaveAs, + this, &QPixelTool::saveToFile); #if QT_CONFIG(clipboard) - menu.addAction(QLatin1String("Copy to clipboard"), - this, &QPixelTool::copyToClipboard, QKeySequence::Copy); - menu.addAction(QLatin1String("Copy color value to clipboard"), - this, &QPixelTool::copyColorToClipboard, Qt::Key_C); + menu.addAction("Copy to clipboard"_L1, QKeySequence::Copy, + this, &QPixelTool::copyToClipboard); + menu.addAction("Copy color value to clipboard"_L1, Qt::Key_C, + this, &QPixelTool::copyColorToClipboard); #endif // QT_CONFIG(clipboard) menu.addSeparator(); - menu.addAction(QLatin1String("About Qt"), qApp, &QApplication::aboutQt); - menu.addAction(QLatin1String("About Qt Pixeltool"), this, &QPixelTool::aboutPixelTool); + menu.addAction("About Qt"_L1, qApp, &QApplication::aboutQt); + menu.addAction("About Qt Pixeltool"_L1, this, &QPixelTool::aboutPixelTool); menu.exec(mapToGlobal(e->pos())); @@ -485,7 +472,7 @@ void QPixelTool::contextMenuEvent(QContextMenuEvent *e) m_freeze = freeze->isChecked(); // LCD mode looks off unless zoom is dividable by 3 - if (m_lcdMode && m_zoom % 3) + if (m_lcdMode && (m_zoom % 3) != 0) setZoom(qMax(3, (m_zoom + 1) / 3)); } @@ -494,15 +481,13 @@ QSize QPixelTool::sizeHint() const return m_initialSize; } -static inline QString pixelToolTitle(QPoint pos, const QColor ¤tColor) +static inline QString pixelToolTitle(QPoint pos, const QScreen *screen, const QColor ¤tColor) { - if (QHighDpiScaling::isActive()) { - if (auto screen = QGuiApplication::screenAt(pos)) - pos = QHighDpi::toNativePixels(pos, screen); - } - return QCoreApplication::applicationName() + QLatin1String(" [") + if (screen != nullptr) + pos = QHighDpi::toNativePixels(pos, screen); + return QCoreApplication::applicationName() + " ["_L1 + QString::number(pos.x()) - + QLatin1String(", ") + QString::number(pos.y()) + QLatin1String("] ") + + ", "_L1 + QString::number(pos.y()) + "] "_L1 + currentColor.name(); } @@ -520,37 +505,38 @@ void QPixelTool::grabScreen() if (mousePos == m_lastMousePos && !m_autoUpdate) return; - if (m_lastMousePos != mousePos) - setWindowTitle(pixelToolTitle(mousePos, m_currentColor)); - - int w = int(width() / float(m_zoom)); - int h = int(height() / float(m_zoom)); + QScreen *screen = QGuiApplication::screenAt(mousePos); - if (width() % m_zoom > 0) - ++w; - if (height() % m_zoom > 0) - ++h; + if (m_lastMousePos != mousePos) + setWindowTitle(pixelToolTitle(mousePos, screen, m_currentColor)); - int x = mousePos.x() - w/2; - int y = mousePos.y() - h/2; + const auto widgetDpr = devicePixelRatioF(); + const auto screenDpr = screen != nullptr ? screen->devicePixelRatio() : widgetDpr; + // When grabbing from another screen, we grab an area fitting our size using our DPR. + const auto factor = widgetDpr / screenDpr / qreal(m_zoom); + const QSize size{int(std::ceil(width() * factor)), int(std::ceil(height() * factor))}; + const QPoint pos = mousePos - QPoint{size.width(), size.height()} / 2; const QBrush darkBrush = palette().color(QPalette::Dark); - if (QScreen *screen = this->screen()) { - m_buffer = screen->grabWindow(0, x, y, w, h); + if (screen != nullptr) { + const QPoint screenPos = pos - screen->geometry().topLeft(); + m_buffer = screen->grabWindow(0, screenPos.x(), screenPos.y(), size.width(), size.height()); } else { - m_buffer = QPixmap(w, h); + m_buffer = QPixmap(size); m_buffer.fill(darkBrush.color()); } - QRegion geom(x, y, w, h); + m_buffer.setDevicePixelRatio(widgetDpr); + + QRegion geom(QRect{pos, size}); QRect screenRect; const auto screens = QGuiApplication::screens(); - for (auto screen : screens) + for (auto *screen : screens) screenRect |= screen->geometry(); geom -= screenRect; const auto rectsInRegion = geom.rectCount(); - if (rectsInRegion > 0) { + if (!geom.isEmpty()) { QPainter p(&m_buffer); - p.translate(-x, -y); + p.translate(-pos); p.setPen(Qt::NoPen); p.setBrush(darkBrush); p.drawRects(geom.begin(), rectsInRegion); @@ -657,7 +643,7 @@ void QPixelTool::saveToFile() m_freeze = true; QFileDialog fileDialog(this); - fileDialog.setWindowTitle(QLatin1String("Save as image")); + fileDialog.setWindowTitle("Save as image"_L1); fileDialog.setAcceptMode(QFileDialog::AcceptSave); fileDialog.setDirectory(QStandardPaths::writableLocation(QStandardPaths::PicturesLocation)); QStringList mimeTypes; @@ -665,17 +651,17 @@ void QPixelTool::saveToFile() for (const QByteArray &mimeTypeB : supportedMimeTypes) mimeTypes.append(QString::fromLatin1(mimeTypeB)); fileDialog.setMimeTypeFilters(mimeTypes); - const QString pngType = QLatin1String("image/png"); + const QString pngType = "image/png"_L1; if (mimeTypes.contains(pngType)) { fileDialog.selectMimeTypeFilter(pngType); - fileDialog.setDefaultSuffix(QLatin1String("png")); + fileDialog.setDefaultSuffix("png"_L1); } while (fileDialog.exec() == QDialog::Accepted && !m_buffer.save(fileDialog.selectedFiles().constFirst())) { - QMessageBox::warning(this, QLatin1String("Unable to write image"), - QLatin1String("Unable to write ") - + QDir::toNativeSeparators(fileDialog.selectedFiles().first())); + QMessageBox::warning(this, "Unable to write image"_L1, + "Unable to write "_L1 + + QDir::toNativeSeparators(fileDialog.selectedFiles().constFirst())); } m_freeze = oldFreeze; } @@ -700,11 +686,11 @@ QString QPixelTool::aboutText() const QString result; QTextStream str(&result); - str << "<html></head><body><h2>Qt Pixeltool</h2><p>Qt " << QT_VERSION_STR + str << "<html><head></head><body><h2>Qt Pixeltool</h2><p>Qt " << QT_VERSION_STR << "</p><p>Copyright (C) 2017 The Qt Company Ltd.</p><h3>Screens</h3><ul>"; for (const QScreen *screen : screens) str << "<li>" << (screen == windowScreen ? "* " : " ") << screen << "</li>"; - str << "<ul></body></html>"; + str << "</ul></body></html>"; return result; } |