Implement exporting subpage image to clipboard
This commit is contained in:
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
#include <QActionGroup>
|
#include <QActionGroup>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
#include <QClipboard>
|
||||||
#include <QDesktopServices>
|
#include <QDesktopServices>
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QFileSystemWatcher>
|
#include <QFileSystemWatcher>
|
||||||
@@ -184,6 +185,64 @@ void MainWindow::reload()
|
|||||||
m_textWidget->document()->selectSubPageIndex(subPageIndex, true);
|
m_textWidget->document()->selectSubPageIndex(subPageIndex, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::extractImages(QImage sceneImage[], bool smooth, bool flashExtract)
|
||||||
|
{
|
||||||
|
// Prepare widget image for extraction
|
||||||
|
m_textScene->hideGUIElements(true);
|
||||||
|
// Disable exporting in Mix mode as it corrupts the background
|
||||||
|
bool reMix = m_textWidget->pageRender()->renderMode() == TeletextPageRender::RenderMix;
|
||||||
|
if (reMix)
|
||||||
|
m_textScene->setRenderMode(TeletextPageRender::RenderNormal);
|
||||||
|
|
||||||
|
const int flashTiming = flashExtract ? m_textWidget->flashTiming() : 0;
|
||||||
|
|
||||||
|
// Allocate initial image, with additional images for flashing if necessary
|
||||||
|
QImage interImage[6];
|
||||||
|
|
||||||
|
interImage[0] = QImage(m_textScene->sceneRect().size().toSize(), QImage::Format_RGB32);
|
||||||
|
if (flashTiming != 0) {
|
||||||
|
interImage[3] = QImage(m_textScene->sceneRect().size().toSize(), QImage::Format_RGB32);
|
||||||
|
if (flashTiming == 2) {
|
||||||
|
interImage[1] = QImage(m_textScene->sceneRect().size().toSize(), QImage::Format_RGB32);
|
||||||
|
interImage[2] = QImage(m_textScene->sceneRect().size().toSize(), QImage::Format_RGB32);
|
||||||
|
interImage[4] = QImage(m_textScene->sceneRect().size().toSize(), QImage::Format_RGB32);
|
||||||
|
interImage[5] = QImage(m_textScene->sceneRect().size().toSize(), QImage::Format_RGB32);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now extract the image(s) from the scene
|
||||||
|
for (int p=0; p<6; p++)
|
||||||
|
if (!interImage[p].isNull()) {
|
||||||
|
m_textWidget->pauseFlash(p);
|
||||||
|
// This ought to make the background transparent in Mix mode, but it doesn't
|
||||||
|
// if (m_textWidget->pageDecode()->mix())
|
||||||
|
// interImage.fill(QColor(0, 0, 0, 0));
|
||||||
|
QPainter interPainter(&interImage[p]);
|
||||||
|
m_textScene->render(&interPainter);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now we've extracted the image we can put the GUI things back
|
||||||
|
m_textScene->hideGUIElements(false);
|
||||||
|
if (reMix)
|
||||||
|
m_textScene->setRenderMode(TeletextPageRender::RenderMix);
|
||||||
|
m_textWidget->resumeFlash();
|
||||||
|
|
||||||
|
// Now scale the extracted image(s) to the selected aspect ratio
|
||||||
|
for (int p=0; p<6; p++)
|
||||||
|
if (!interImage[p].isNull()) {
|
||||||
|
if (m_viewAspectRatio == 3)
|
||||||
|
// Aspect ratio is Pixel 1:2 so we only need to double the vertical height
|
||||||
|
sceneImage[p] = interImage[p].scaled(interImage[p].width(), interImage[p].height()*2, Qt::IgnoreAspectRatio, Qt::FastTransformation);
|
||||||
|
else {
|
||||||
|
// Scale the image in two steps so that smoothing only occurs on vertical lines
|
||||||
|
// Double the vertical height first
|
||||||
|
const QImage doubleHeightImage = interImage[p].scaled(interImage[p].width(), interImage[p].height()*2, Qt::IgnoreAspectRatio, Qt::FastTransformation);
|
||||||
|
// then scale it horizontally to the selected aspect ratio
|
||||||
|
sceneImage[p] = doubleHeightImage.scaled((int)((float)doubleHeightImage.width() * aspectRatioHorizontalScaling[m_viewAspectRatio] * 2), doubleHeightImage.height(), Qt::IgnoreAspectRatio, (smooth) ? Qt::SmoothTransformation : Qt::FastTransformation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::exportImage()
|
void MainWindow::exportImage()
|
||||||
{
|
{
|
||||||
QString exportFileName, selectedFilter, gifFilter;
|
QString exportFileName, selectedFilter, gifFilter;
|
||||||
@@ -222,64 +281,8 @@ void MainWindow::exportImage()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disable flash exporting if extension is not GIF
|
|
||||||
const int flashTiming = suffix == "gif" ? m_textWidget->flashTiming() : 0;
|
|
||||||
|
|
||||||
// Prepare widget image for extraction
|
|
||||||
m_textScene->hideGUIElements(true);
|
|
||||||
// Disable exporting in Mix mode as it corrupts the background
|
|
||||||
bool reMix = m_textWidget->pageRender()->renderMode() == TeletextPageRender::RenderMix;
|
|
||||||
if (reMix)
|
|
||||||
m_textScene->setRenderMode(TeletextPageRender::RenderNormal);
|
|
||||||
|
|
||||||
// Allocate initial image, with additional images for flashing if necessary
|
|
||||||
QImage interImage[6];
|
|
||||||
|
|
||||||
interImage[0] = QImage(m_textScene->sceneRect().size().toSize(), QImage::Format_RGB32);
|
|
||||||
if (flashTiming != 0) {
|
|
||||||
interImage[3] = QImage(m_textScene->sceneRect().size().toSize(), QImage::Format_RGB32);
|
|
||||||
if (flashTiming == 2) {
|
|
||||||
interImage[1] = QImage(m_textScene->sceneRect().size().toSize(), QImage::Format_RGB32);
|
|
||||||
interImage[2] = QImage(m_textScene->sceneRect().size().toSize(), QImage::Format_RGB32);
|
|
||||||
interImage[4] = QImage(m_textScene->sceneRect().size().toSize(), QImage::Format_RGB32);
|
|
||||||
interImage[5] = QImage(m_textScene->sceneRect().size().toSize(), QImage::Format_RGB32);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now extract the image(s) from the scene
|
|
||||||
for (int p=0; p<6; p++)
|
|
||||||
if (!interImage[p].isNull()) {
|
|
||||||
m_textWidget->pauseFlash(p);
|
|
||||||
// This ought to make the background transparent in Mix mode, but it doesn't
|
|
||||||
// if (m_textWidget->pageDecode()->mix())
|
|
||||||
// interImage.fill(QColor(0, 0, 0, 0));
|
|
||||||
QPainter interPainter(&interImage[p]);
|
|
||||||
m_textScene->render(&interPainter);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now we've extracted the image we can put the GUI things back
|
|
||||||
m_textScene->hideGUIElements(false);
|
|
||||||
if (reMix)
|
|
||||||
m_textScene->setRenderMode(TeletextPageRender::RenderMix);
|
|
||||||
m_textWidget->resumeFlash();
|
|
||||||
|
|
||||||
// Now scale the extracted image(s) to the selected aspect ratio
|
|
||||||
QImage scaledImage[6];
|
QImage scaledImage[6];
|
||||||
|
extractImages(scaledImage, suffix != "gif", suffix == "gif");
|
||||||
for (int p=0; p<6; p++)
|
|
||||||
if (!interImage[p].isNull()) {
|
|
||||||
if (m_viewAspectRatio == 3)
|
|
||||||
// Aspect ratio is Pixel 1:2 so we only need to double the vertical height
|
|
||||||
scaledImage[p] = interImage[p].scaled(interImage[p].width(), interImage[p].height()*2, Qt::IgnoreAspectRatio, Qt::FastTransformation);
|
|
||||||
else {
|
|
||||||
// Scale the image in two steps so that smoothing only occurs on vertical lines
|
|
||||||
// Double the vertical height first
|
|
||||||
const QImage doubleHeightImage = interImage[p].scaled(interImage[p].width(), interImage[p].height()*2, Qt::IgnoreAspectRatio, Qt::FastTransformation);
|
|
||||||
// then scale it horizontally to the selected aspect ratio
|
|
||||||
// Don't smooth GIF as it's bound to break the 256 colour limit
|
|
||||||
scaledImage[p] = doubleHeightImage.scaled((int)((float)doubleHeightImage.width() * aspectRatioHorizontalScaling[m_viewAspectRatio] * 2), doubleHeightImage.height(), Qt::IgnoreAspectRatio, (suffix == "gif") ? Qt::FastTransformation : Qt::SmoothTransformation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (suffix == "png") {
|
if (suffix == "png") {
|
||||||
if (scaledImage[0].save(exportFileName, "PNG"))
|
if (scaledImage[0].save(exportFileName, "PNG"))
|
||||||
@@ -294,7 +297,7 @@ void MainWindow::exportImage()
|
|||||||
if (scaledImage[3].isNull())
|
if (scaledImage[3].isNull())
|
||||||
// No flashing
|
// No flashing
|
||||||
gif.addFrame(scaledImage[0], 0);
|
gif.addFrame(scaledImage[0], 0);
|
||||||
else if (interImage[1].isNull()) {
|
else if (scaledImage[1].isNull()) {
|
||||||
// 1Hz flashing
|
// 1Hz flashing
|
||||||
gif.addFrame(scaledImage[0], 500);
|
gif.addFrame(scaledImage[0], 500);
|
||||||
gif.addFrame(scaledImage[3], 500);
|
gif.addFrame(scaledImage[3], 500);
|
||||||
@@ -310,6 +313,17 @@ void MainWindow::exportImage()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef QT_NO_CLIPBOARD
|
||||||
|
void MainWindow::imageToClipboard()
|
||||||
|
{
|
||||||
|
QImage scaledImage[1];
|
||||||
|
QClipboard *clipboard = QApplication::clipboard();
|
||||||
|
|
||||||
|
extractImages(scaledImage, true);
|
||||||
|
clipboard->setImage(scaledImage[0]);
|
||||||
|
}
|
||||||
|
#endif // !QT_NO_CLIPBOARD
|
||||||
|
|
||||||
void MainWindow::exportZXNet()
|
void MainWindow::exportZXNet()
|
||||||
{
|
{
|
||||||
QDesktopServices::openUrl(QUrl("http://zxnet.co.uk/teletext/editor/" + exportHashStringPage(m_textWidget->document()->currentSubPage()) + exportHashStringPackets(m_textWidget->document()->currentSubPage())));
|
QDesktopServices::openUrl(QUrl("http://zxnet.co.uk/teletext/editor/" + exportHashStringPage(m_textWidget->document()->currentSubPage()) + exportHashStringPackets(m_textWidget->document()->currentSubPage())));
|
||||||
@@ -545,6 +559,11 @@ void MainWindow::createActions()
|
|||||||
editMenu->addAction(pasteAct);
|
editMenu->addAction(pasteAct);
|
||||||
editToolBar->addAction(pasteAct);
|
editToolBar->addAction(pasteAct);
|
||||||
|
|
||||||
|
QAction *copyImageAct = editMenu->addAction(tr("Copy as image"));
|
||||||
|
copyImageAct->setShortcut(QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_C));
|
||||||
|
copyImageAct->setStatusTip(tr("Copy this subpage as an image to the clipboard"));
|
||||||
|
connect(copyImageAct, &QAction::triggered, this, &MainWindow::imageToClipboard);
|
||||||
|
|
||||||
editMenu->addSeparator();
|
editMenu->addSeparator();
|
||||||
#endif // !QT_NO_CLIPBOARD
|
#endif // !QT_NO_CLIPBOARD
|
||||||
|
|
||||||
|
|||||||
@@ -25,9 +25,10 @@
|
|||||||
#include <QGraphicsProxyWidget>
|
#include <QGraphicsProxyWidget>
|
||||||
#include <QGraphicsScene>
|
#include <QGraphicsScene>
|
||||||
#include <QGraphicsView>
|
#include <QGraphicsView>
|
||||||
#include <QMainWindow>
|
#include <QImage>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
|
#include <QMainWindow>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QSlider>
|
#include <QSlider>
|
||||||
#include <QToolButton>
|
#include <QToolButton>
|
||||||
@@ -78,6 +79,9 @@ private slots:
|
|||||||
void updatePageWidgets();
|
void updatePageWidgets();
|
||||||
void updateCursorPosition();
|
void updateCursorPosition();
|
||||||
|
|
||||||
|
#ifndef QT_NO_CLIPBOARD
|
||||||
|
void imageToClipboard();
|
||||||
|
#endif // !QT_NO_CLIPBOARD
|
||||||
void insertRow(bool copyRow);
|
void insertRow(bool copyRow);
|
||||||
void deleteRow();
|
void deleteRow();
|
||||||
void insertSubPage(bool afterCurrentSubPage, bool copyCurrentSubPage);
|
void insertSubPage(bool afterCurrentSubPage, bool copyCurrentSubPage);
|
||||||
@@ -112,6 +116,7 @@ private:
|
|||||||
bool maybeSave();
|
bool maybeSave();
|
||||||
void openFile(const QString &fileName);
|
void openFile(const QString &fileName);
|
||||||
void loadFile(const QString &fileName);
|
void loadFile(const QString &fileName);
|
||||||
|
void extractImages(QImage sceneImage[], bool smooth = false, bool flashExtract = false);
|
||||||
static bool hasRecentFiles();
|
static bool hasRecentFiles();
|
||||||
void prependToRecentFiles(const QString &fileName);
|
void prependToRecentFiles(const QString &fileName);
|
||||||
void setRecentFilesVisible(bool visible);
|
void setRecentFilesVisible(bool visible);
|
||||||
|
|||||||
Reference in New Issue
Block a user