From ced638a782842b70cb99879309d11edf6d14bc18 Mon Sep 17 00:00:00 2001 From: Roman Telezhynskyi Date: Thu, 3 Dec 2015 14:07:51 +0200 Subject: [PATCH] Support a proxy icon on Mac OS. --HG-- branch : develop --- src/app/tape/tmainwindow.cpp | 119 ++++++++++++++++++++++++++++++ src/app/tape/tmainwindow.h | 7 ++ src/app/valentina/mainwindow.cpp | 120 +++++++++++++++++++++++++++++++ src/app/valentina/mainwindow.h | 6 ++ src/libs/vmisc/def.cpp | 25 +++++++ src/libs/vmisc/def.h | 2 + 6 files changed, 279 insertions(+) diff --git a/src/app/tape/tmainwindow.cpp b/src/app/tape/tmainwindow.cpp index 4cf7a7f7c..8101bc34f 100644 --- a/src/app/tape/tmainwindow.cpp +++ b/src/app/tape/tmainwindow.cpp @@ -51,6 +51,11 @@ #include #include +#if defined(Q_OS_MAC) +#include +#include +#endif //defined(Q_OS_MAC) + #define DIALOG_MAX_FORMULA_HEIGHT 64 #if defined(Q_CC_CLANG) @@ -558,6 +563,81 @@ void TMainWindow::showEvent(QShowEvent *event) isInitialized = true;//first show windows are held } +//--------------------------------------------------------------------------------------------------------------------- +#if defined(Q_OS_MAC) +bool TMainWindow::event(QEvent *event) +{ + if (not isActiveWindow()) + { + return QMainWindow::event(event); + } + + switch (event->type()) + { + case QEvent::IconDrag: + { + event->accept(); + const Qt::KeyboardModifiers currentModifiers = qApp->keyboardModifiers(); + + if (currentModifiers == Qt::NoModifier) + { + QDrag *drag = new QDrag(this); + QMimeData *data = new QMimeData(); + data->setUrls(QList() << QUrl::fromLocalFile(curFile)); + drag->setMimeData(data); + const QPixmap cursorPixmap = style()->standardPixmap(QStyle::SP_FileIcon, 0, this); + drag->setPixmap(cursorPixmap); + + QPoint hotspot(cursorPixmap.width() - 5, 5); + drag->setHotSpot(hotspot); + + drag->start(Qt::LinkAction | Qt::CopyAction); + } + else if (currentModifiers == Qt::ControlModifier) + { + QMenu menu(this); + connect(&menu, &QMenu::triggered, this, &TMainWindow::OpenAt); + + QFileInfo info(curFile); + QAction *action = menu.addAction(info.fileName()); + action->setIcon(QIcon(QApplication::applicationDirPath() + + QLatin1Literal("/../Resources/measurements.icns"))); + const QStringList folders = info.absolutePath().split('/'); + QStringListIterator it(folders); + + it.toBack(); + while (it.hasPrevious()) + { + QString string = it.previous(); + QIcon icon; + + if (not string.isEmpty()) + { + icon = style()->standardIcon(QStyle::SP_DirClosedIcon, 0, this); + } + else + { // At the root + string = "/"; + icon = style()->standardIcon(QStyle::SP_DriveHDIcon, 0, this); + } + action = menu.addAction(string); + action->setIcon(icon); + } + QPoint pos(QCursor::pos().x() - 20, frameGeometry().y()); + menu.exec(pos); + } + else + { + event->ignore(); + } + return true; + } + default: + return QMainWindow::event(event); + } +} +#endif //defined(Q_OS_MAC) + //--------------------------------------------------------------------------------------------------------------------- void TMainWindow::FileSave() { @@ -704,6 +784,21 @@ void TMainWindow::AboutQt() QMessageBox::aboutQt(this, tr("About Qt")); } +//--------------------------------------------------------------------------------------------------------------------- +#if defined(Q_OS_MAC) +void TMainWindow::OpenAt(QAction *where) +{ + const QString path = curFile.left(curFile.indexOf(where->text())) + where->text(); + if (path == curFile) + { + return; + } + QProcess process; + process.start(QStringLiteral("/usr/bin/open"), QStringList() << path, QIODevice::ReadOnly); + process.waitForFinished(); +} +#endif //defined(Q_OS_MAC) + //--------------------------------------------------------------------------------------------------------------------- void TMainWindow::SaveGivenName() { @@ -1986,6 +2081,30 @@ void TMainWindow::SetCurrentFile(const QString &fileName) } shownName += "[*]"; setWindowTitle(shownName); + +#if defined(Q_OS_MAC) + static QIcon fileIcon = QIcon(QApplication::applicationDirPath() + + QLatin1Literal("/../Resources/measurements.icns")); + QIcon icon; + if (not curFile.isEmpty()) + { + if (not isWindowModified()) + { + icon = fileIcon; + } + else + { + static QIcon darkIcon; + + if (darkIcon.isNull()) + { + darkIcon = QIcon(darkenPixmap(fileIcon.pixmap(16, 16))); + } + icon = darkIcon; + } + } + setWindowIcon(icon); +#endif //defined(Q_OS_MAC) } //--------------------------------------------------------------------------------------------------------------------- diff --git a/src/app/tape/tmainwindow.h b/src/app/tape/tmainwindow.h index a9be0e379..13831d054 100644 --- a/src/app/tape/tmainwindow.h +++ b/src/app/tape/tmainwindow.h @@ -74,6 +74,9 @@ protected: virtual void closeEvent(QCloseEvent *event) Q_DECL_OVERRIDE; virtual void changeEvent(QEvent* event) Q_DECL_OVERRIDE; virtual void showEvent(QShowEvent *event) Q_DECL_OVERRIDE; +#if defined(Q_OS_MAC) + virtual bool event(QEvent *event) Q_DECL_OVERRIDE; +#endif //defined(Q_OS_MAC) private slots: void FileSave(); @@ -83,6 +86,10 @@ private slots: void AboutApplication(); void AboutQt(); +#if defined(Q_OS_MAC) + void OpenAt(QAction *where); +#endif //defined(Q_OS_MAC) + void SaveGivenName(); void SaveFamilyName(); void SaveEmail(); diff --git a/src/app/valentina/mainwindow.cpp b/src/app/valentina/mainwindow.cpp index 470bff114..2f6b9a94b 100644 --- a/src/app/valentina/mainwindow.cpp +++ b/src/app/valentina/mainwindow.cpp @@ -67,6 +67,11 @@ #include #include +#if defined(Q_OS_MAC) +#include +#include +#endif //defined(Q_OS_MAC) + #if defined(Q_CC_CLANG) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wmissing-prototypes" @@ -1114,6 +1119,82 @@ void MainWindow::customEvent(QEvent *event) } } + +//--------------------------------------------------------------------------------------------------------------------- +#if defined(Q_OS_MAC) +bool MainWindow::event(QEvent *event) +{ + if (not isActiveWindow()) + { + return MainWindowsNoGUI::event(event); + } + + switch (event->type()) + { + case QEvent::IconDrag: + { + event->accept(); + const Qt::KeyboardModifiers currentModifiers = qApp->keyboardModifiers(); + + if (currentModifiers == Qt::NoModifier) + { + QDrag *drag = new QDrag(this); + QMimeData *data = new QMimeData(); + data->setUrls(QList() << QUrl::fromLocalFile(curFile)); + drag->setMimeData(data); + const QPixmap cursorPixmap = style()->standardPixmap(QStyle::SP_FileIcon, 0, this); + drag->setPixmap(cursorPixmap); + + QPoint hotspot(cursorPixmap.width() - 5, 5); + drag->setHotSpot(hotspot); + + drag->start(Qt::LinkAction | Qt::CopyAction); + } + else if (currentModifiers == Qt::ControlModifier) + { + QMenu menu(this); + connect(&menu, &QMenu::triggered, this, &MainWindow::OpenAt); + + QFileInfo info(curFile); + QAction *action = menu.addAction(info.fileName()); + action->setIcon(QIcon(QApplication::applicationDirPath() + + QLatin1Literal("/../Resources/measurements.icns"))); + const QStringList folders = info.absolutePath().split('/'); + QStringListIterator it(folders); + + it.toBack(); + while (it.hasPrevious()) + { + QString string = it.previous(); + QIcon icon; + + if (not string.isEmpty()) + { + icon = style()->standardIcon(QStyle::SP_DirClosedIcon, 0, this); + } + else + { // At the root + string = "/"; + icon = style()->standardIcon(QStyle::SP_DriveHDIcon, 0, this); + } + action = menu.addAction(string); + action->setIcon(icon); + } + QPoint pos(QCursor::pos().x() - 20, frameGeometry().y()); + menu.exec(pos); + } + else + { + event->ignore(); + } + return true; + } + default: + return MainWindowsNoGUI::event(event); + } +} +#endif //defined(Q_OS_MAC) + //--------------------------------------------------------------------------------------------------------------------- void MainWindow::CleanLayout() { @@ -1327,6 +1408,21 @@ void MainWindow::SyncMeasurements() ToggleMSync(false); } +//--------------------------------------------------------------------------------------------------------------------- +#if defined(Q_OS_MAC) +void MainWindow::OpenAt(QAction *where) +{ + const QString path = curFile.left(curFile.indexOf(where->text())) + where->text(); + if (path == curFile) + { + return; + } + QProcess process; + process.start(QStringLiteral("/usr/bin/open"), QStringList() << path, QIODevice::ReadOnly); + process.waitForFinished(); +} +#endif //defined(Q_OS_MAC) + //--------------------------------------------------------------------------------------------------------------------- /** * @brief ToolBarOption enable option toolbar. @@ -2881,6 +2977,30 @@ void MainWindow::setCurrentFile(const QString &fileName) settings->SetRestoreFileList(restoreFiles); } +#if defined(Q_OS_MAC) + static QIcon fileIcon = QIcon(QApplication::applicationDirPath() + + QLatin1Literal("/../Resources/measurements.icns")); + QIcon icon; + if (not curFile.isEmpty()) + { + if (not isWindowModified()) + { + icon = fileIcon; + } + else + { + static QIcon darkIcon; + + if (darkIcon.isNull()) + { + darkIcon = QIcon(darkenPixmap(fileIcon.pixmap(16, 16))); + } + icon = darkIcon; + } + } + setWindowIcon(icon); +#endif //defined(Q_OS_MAC) + UpdateWindowTitle(); } diff --git a/src/app/valentina/mainwindow.h b/src/app/valentina/mainwindow.h index 4efbeba65..923365c98 100644 --- a/src/app/valentina/mainwindow.h +++ b/src/app/valentina/mainwindow.h @@ -159,6 +159,9 @@ protected: virtual void showEvent(QShowEvent *event) Q_DECL_OVERRIDE; virtual void closeEvent(QCloseEvent *event) Q_DECL_OVERRIDE; virtual void customEvent(QEvent * event) Q_DECL_OVERRIDE; +#if defined(Q_OS_MAC) + virtual bool event(QEvent *event) Q_DECL_OVERRIDE; +#endif //defined(Q_OS_MAC) virtual void CleanLayout() Q_DECL_OVERRIDE; virtual void PrepareSceneList() Q_DECL_OVERRIDE; @@ -170,6 +173,9 @@ private slots: void ShowMeasurements(); void MeasurementsChanged(const QString &path); void SyncMeasurements(); +#if defined(Q_OS_MAC) + void OpenAt(QAction *where); +#endif //defined(Q_OS_MAC) void ChangedSize(const QString &text); void ChangedHeight(const QString & text); diff --git a/src/libs/vmisc/def.cpp b/src/libs/vmisc/def.cpp index 78226eda8..23883173c 100644 --- a/src/libs/vmisc/def.cpp +++ b/src/libs/vmisc/def.cpp @@ -1761,3 +1761,28 @@ QSharedPointer DefaultPrinter() printer->setResolution(static_cast(PrintDPI)); return printer; } + +//--------------------------------------------------------------------------------------------------------------------- +QPixmap darkenPixmap(const QPixmap &pixmap) +{ + QImage img = pixmap.toImage().convertToFormat(QImage::Format_ARGB32); + const int imgh = img.height(); + const int imgw = img.width(); + for (int y = 0; y < imgh; ++y) + { + for (int x = 0; x < imgw; ++x) + { + int h, s, v; + QRgb pixel = img.pixel(x, y); + const int a = qAlpha(pixel); + QColor hsvColor(pixel); + hsvColor.getHsv(&h, &s, &v); + s = qMin(100, s * 2); + v = v / 2; + hsvColor.setHsv(h, s, v); + pixel = hsvColor.rgb(); + img.setPixel(x, y, qRgba(qRed(pixel), qGreen(pixel), qBlue(pixel), a)); + } + } + return QPixmap::fromImage(img); +} diff --git a/src/libs/vmisc/def.h b/src/libs/vmisc/def.h index 16fd1e99d..becdec863 100644 --- a/src/libs/vmisc/def.h +++ b/src/libs/vmisc/def.h @@ -597,4 +597,6 @@ QString AbsoluteMPath(const QString &patternPath, const QString &relativeMPath); QSharedPointer DefaultPrinter(); +QPixmap darkenPixmap(const QPixmap &pixmap); + #endif // DEF_H