diff --git a/graphicsscene.cpp b/graphicsscene.cpp index f741d09..6b6d582 100644 --- a/graphicsscene.cpp +++ b/graphicsscene.cpp @@ -8,6 +8,7 @@ #include #include #include +#include GraphicsScene::GraphicsScene(QObject *parent) : QGraphicsScene(parent) @@ -58,3 +59,12 @@ void GraphicsScene::showGif(const QString &filepath) QPen(Qt::transparent)); this->setSceneRect(m_theThing->boundingRect()); } + +QPixmap GraphicsScene::renderToPixmap() +{ + QPixmap pixmap(sceneRect().toRect().size()); + QPainter p(&pixmap); + render(&p, sceneRect()); + + return pixmap; +} diff --git a/graphicsscene.h b/graphicsscene.h index 7e24882..facd045 100644 --- a/graphicsscene.h +++ b/graphicsscene.h @@ -15,6 +15,8 @@ public: void showSvg(const QString &filepath); void showGif(const QString &filepath); + QPixmap renderToPixmap(); + private: QGraphicsItem * m_theThing; }; diff --git a/graphicsview.cpp b/graphicsview.cpp index db76c5e..011a0bb 100644 --- a/graphicsview.cpp +++ b/graphicsview.cpp @@ -59,6 +59,13 @@ void GraphicsView::showImage(const QPixmap &pixmap) checkAndDoFitInView(); } +void GraphicsView::showImage(const QImage &image) +{ + resetTransform(); + scene()->showImage(QPixmap::fromImage(image)); + checkAndDoFitInView(); +} + void GraphicsView::showText(const QString &text) { resetTransform(); diff --git a/graphicsview.h b/graphicsview.h index bfb7713..60ce62e 100644 --- a/graphicsview.h +++ b/graphicsview.h @@ -14,6 +14,7 @@ public: void showFileFromUrl(const QUrl &url, bool requestGallery = false); void showImage(const QPixmap &pixmap); + void showImage(const QImage &image); void showText(const QString &text); void showSvg(const QString &filepath); void showGif(const QString &filepath); diff --git a/languages/PineapplePictures.ts b/languages/PineapplePictures.ts index e6ef946..097dd7d 100644 --- a/languages/PineapplePictures.ts +++ b/languages/PineapplePictures.ts @@ -4,7 +4,7 @@ GraphicsScene - + Drag image here @@ -12,22 +12,22 @@ GraphicsView - + File url list is empty - + File is not a valid image - + Image data is invalid - + Not supported mimedata: %1 @@ -35,44 +35,74 @@ MainWindow - - + + File url list is empty + + + + + &Copy + + + + + Copy &Pixmap + + + + + Copy &File Path + + + + + &Paste Image + + + + + &Paste Image File + + + + + Stay on top - - + + Protected mode - + Help - + Launch application with image file path as argument to load the file. - + Drag and drop image file onto the window is also supported. - + Context menu option explanation: - + Make window stay on top of all other windows. - + Avoid close window accidentally. (eg. by double clicking the window) diff --git a/languages/PineapplePictures_zh_CN.ts b/languages/PineapplePictures_zh_CN.ts index e246f70..cba86e3 100644 --- a/languages/PineapplePictures_zh_CN.ts +++ b/languages/PineapplePictures_zh_CN.ts @@ -4,7 +4,7 @@ GraphicsScene - + Drag image here 拖放图片至此 @@ -12,22 +12,22 @@ GraphicsView - + File url list is empty 文件 URL 列表为空 - + File is not a valid image 文件不是有效的图片文件 - + Image data is invalid 图片数据无效 - + Not supported mimedata: %1 不受支持的 MimeData 格式:%1 @@ -35,44 +35,74 @@ MainWindow - - + + File url list is empty + 文件 URL 列表为空 + + + + &Copy + 复制(&C) + + + + Copy &Pixmap + 复制位图(&P) + + + + Copy &File Path + 复制文件路径(&F) + + + + &Paste Image + 粘贴图像(&P) + + + + &Paste Image File + 粘贴图像文件(&P) + + + + Stay on top 总在最前 - - + + Protected mode 保护模式 - + Help 帮助 - + Launch application with image file path as argument to load the file. 以图片文件的路径作为参数运行程序即可直接打开图片文件。 - + Drag and drop image file onto the window is also supported. 也支持拖放图片文件到窗口内来加载图片。 - + Context menu option explanation: 菜单项说明: - + Make window stay on top of all other windows. 使窗口始终至于其它非置顶窗口上方。 - + Avoid close window accidentally. (eg. by double clicking the window) 避免窗口意外关闭。(如:不小心双击了窗口触发了关闭窗口行为) diff --git a/mainwindow.cpp b/mainwindow.cpp index e751fc0..41008b5 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -17,6 +17,8 @@ #include #include #include +#include +#include #ifdef _WIN32 #include @@ -173,12 +175,22 @@ void MainWindow::adjustWindowSizeBySceneRect() } } +// can be empty if it is NOT from a local file. +QUrl MainWindow::currentImageFileUrl() const +{ + if (m_currentFileIndex != -1) { + return m_files.value(m_currentFileIndex); + } + + return QUrl(); +} + void MainWindow::loadGalleryBySingleLocalFile(const QString &path) { QFileInfo info(path); QDir dir(info.path()); QString currentFileName = info.fileName(); - QStringList entryList = dir.entryList({"*.jpg", "*.jpeg", "*.png", "*.gif", "*.svg"}, + QStringList entryList = dir.entryList({"*.jpg", "*.jpeg", "*.png", "*.gif", "*.svg", "*.bmp"}, QDir::Files | QDir::NoSymLinks, QDir::NoSort); QCollator collator; @@ -197,7 +209,7 @@ void MainWindow::loadGalleryBySingleLocalFile(const QString &path) } } - qDebug() << m_files << m_currentFileIndex; +// qDebug() << m_files << m_currentFileIndex; } void MainWindow::galleryPrev() @@ -307,6 +319,52 @@ void MainWindow::resizeEvent(QResizeEvent *event) void MainWindow::contextMenuEvent(QContextMenuEvent *event) { QMenu * menu = new QMenu; + QMenu * copyMenu = new QMenu(tr("&Copy")); + QUrl currentFileUrl = currentImageFileUrl(); + QImage clipboardImage; + QUrl clipboardFileUrl; + + const QMimeData * clipboardData = QApplication::clipboard()->mimeData(); + if (clipboardData->hasImage()) { + QVariant imageVariant(clipboardData->imageData()); + if (imageVariant.isValid()) { + clipboardImage = qvariant_cast(imageVariant); + } + } else if (clipboardData->hasText()) { + QString clipboardText(clipboardData->text()); + if (clipboardText.startsWith("PICTURE:")) { + QString maybeFilename(clipboardText.mid(8)); + if (QFile::exists(maybeFilename)) { + clipboardFileUrl = QUrl::fromLocalFile(maybeFilename); + } + } + } + + QAction * copyPixmap = new QAction(tr("Copy &Pixmap")); + connect(copyPixmap, &QAction::triggered, this, [ = ](){ + QClipboard *cb = QApplication::clipboard(); + cb->setPixmap(m_graphicsView->scene()->renderToPixmap()); + }); + QAction * copyFilePath = new QAction(tr("Copy &File Path")); + connect(copyFilePath, &QAction::triggered, this, [ = ](){ + QClipboard *cb = QApplication::clipboard(); + cb->setText(currentFileUrl.toLocalFile()); + }); + copyMenu->addAction(copyPixmap); + if (currentFileUrl.isValid()) { + copyMenu->addAction(copyFilePath); + } + + QAction * pasteImage = new QAction(tr("&Paste Image")); + connect(pasteImage, &QAction::triggered, this, [ = ](){ + m_graphicsView->showImage(clipboardImage); + }); + + QAction * pasteImageFile = new QAction(tr("&Paste Image File")); + connect(pasteImageFile, &QAction::triggered, this, [ = ](){ + m_graphicsView->showFileFromUrl(clipboardFileUrl, true); + }); + QAction * stayOnTopMode = new QAction(tr("Stay on top")); connect(stayOnTopMode, &QAction::triggered, this, [ = ](){ toggleStayOnTop(); @@ -331,6 +389,18 @@ void MainWindow::contextMenuEvent(QContextMenuEvent *event) }; m_graphicsView->showText(sl.join('\n')); }); + + if (copyMenu->actions().count() == 1) { + menu->addActions(copyMenu->actions()); + } else { + menu->addMenu(copyMenu); + } + if (!clipboardImage.isNull()) { + menu->addAction(pasteImage); + } else if (clipboardFileUrl.isValid()) { + menu->addAction(pasteImageFile); + } + menu->addSeparator(); menu->addAction(stayOnTopMode); menu->addAction(protectedMode); menu->addSeparator(); diff --git a/mainwindow.h b/mainwindow.h index b4ee4a9..eb613dc 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -25,6 +25,7 @@ public: void showUrls(const QList &urls); void adjustWindowSizeBySceneRect(); + QUrl currentImageFileUrl() const; void loadGalleryBySingleLocalFile(const QString &path); void galleryPrev();