diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index 79b4a29..056c2ab 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -1,1745 +1,1745 @@ /* * Copyright (C) 2010-2015 by Stephen Allewell * steve.allewell@gmail.com * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. */ #include "MainWindow.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "BackgroundImage.h" #include "configuration.h" #include "ConfigurationDialogs.h" #include "Commands.h" #include "Document.h" #include "Editor.h" #include "ExtendPatternDlg.h" #include "FilePropertiesDlg.h" #include "Floss.h" #include "FlossScheme.h" #include "ImportImageDlg.h" #include "Palette.h" #include "PaletteManagerDlg.h" #include "PaperSizes.h" #include "Preview.h" #include "PrintSetupDlg.h" #include "QVariantPtr.h" #include "Scale.h" #include "ScaledPixmapLabel.h" #include "SchemeManager.h" #include "SymbolLibrary.h" #include "SymbolManager.h" MainWindow::MainWindow() : m_printer(nullptr) { setupActions(); } MainWindow::MainWindow(const QUrl &url) : m_printer(nullptr) { setupMainWindow(); setupLayout(); setupDockWindows(); setupActions(); setupDocument(); setupConnections(); setupActionDefaults(); loadSettings(); fileOpen(url); setupActionsFromDocument(); setCaption(m_document->url().fileName(), !m_document->undoStack().isClean()); this->findChild(QStringLiteral("ImportedImage#"))->hide(); } MainWindow::MainWindow(const QString &source) : m_printer(nullptr) { setupMainWindow(); setupLayout(); setupDockWindows(); setupActions(); setupDocument(); setupConnections(); setupActionDefaults(); loadSettings(); convertImage(source); setupActionsFromDocument(); setCaption(m_document->url().fileName(), !m_document->undoStack().isClean()); this->findChild(QStringLiteral("ImportedImage#"))->show(); } void MainWindow::setupMainWindow() { setObjectName(QStringLiteral("MainWindow#")); setAutoSaveSettings(); } void MainWindow::setupLayout() { QScrollArea *scrollArea = new QScrollArea(); scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn); m_editor = new Editor(scrollArea); scrollArea->installEventFilter(m_editor); scrollArea->setWidget(m_editor); m_horizontalScale = m_editor->horizontalScale(); m_verticalScale = m_editor->verticalScale(); QGridLayout *gridLayout = new QGridLayout(this); gridLayout->addWidget(m_horizontalScale, 0, 1); gridLayout->addWidget(m_verticalScale, 1, 0); gridLayout->addWidget(scrollArea, 1, 1); QWidget *layout = new QWidget(); layout->setLayout(gridLayout); setCentralWidget(layout); setStatusBar(nullptr); } void MainWindow::setupDocument() { m_document = new Document(); m_editor->setDocument(m_document); m_editor->setPreview(m_preview); m_palette->setDocument(m_document); m_preview->setDocument(m_document); m_history->setStack(&(m_document->undoStack())); m_document->addView(m_editor); m_document->addView(m_preview); m_document->addView(m_palette); } void MainWindow::setupConnections() { KActionCollection *actions = actionCollection(); connect(&(m_document->undoStack()), &QUndoStack::canUndoChanged, actions->action(QStringLiteral("edit_undo")), &QAction::setEnabled); connect(&(m_document->undoStack()), &QUndoStack::canUndoChanged, actions->action(QStringLiteral("file_revert")), &QAction::setEnabled); connect(&(m_document->undoStack()), &QUndoStack::canRedoChanged, actions->action(QStringLiteral("edit_redo")), &QAction::setEnabled); connect(QApplication::clipboard(), &QClipboard::dataChanged, this, &MainWindow::clipboardDataChanged); connect(m_editor, &Editor::selectionMade, actionCollection()->action(QStringLiteral("edit_cut")), &QAction::setEnabled); connect(m_editor, &Editor::selectionMade, actionCollection()->action(QStringLiteral("edit_copy")), &QAction::setEnabled); connect(m_editor, &Editor::selectionMade, actionCollection()->action(QStringLiteral("mirrorHorizontal")), &QAction::setEnabled); connect(m_editor, &Editor::selectionMade, actionCollection()->action(QStringLiteral("mirrorVertical")), &QAction::setEnabled); connect(m_editor, &Editor::selectionMade, actionCollection()->action(QStringLiteral("rotate90")), &QAction::setEnabled); connect(m_editor, &Editor::selectionMade, actionCollection()->action(QStringLiteral("rotate180")), &QAction::setEnabled); connect(m_editor, &Editor::selectionMade, actionCollection()->action(QStringLiteral("rotate270")), &QAction::setEnabled); connect(m_editor, &Editor::selectionMade, actionCollection()->action(QStringLiteral("patternCropToSelection")), &QAction::setEnabled); connect(m_editor, &Editor::selectionMade, actionCollection()->action(QStringLiteral("insertColumns")), &QAction::setEnabled); connect(m_editor, &Editor::selectionMade, actionCollection()->action(QStringLiteral("insertRows")), &QAction::setEnabled); connect(&(m_document->undoStack()), &QUndoStack::undoTextChanged, this, &MainWindow::undoTextChanged); connect(&(m_document->undoStack()), &QUndoStack::redoTextChanged, this, &MainWindow::redoTextChanged); connect(&(m_document->undoStack()), &QUndoStack::cleanChanged, this, &MainWindow::documentModified); connect(m_palette, &Palette::colorSelected, m_editor, static_cast(&Editor::drawContents)); connect(m_palette, static_cast(&Palette::swapColors), this, &MainWindow::paletteSwapColors); connect(m_palette, static_cast(&Palette::replaceColor), this, &MainWindow::paletteReplaceColor); connect(m_palette, &Palette::signalStateChanged, this, static_cast(&KXmlGuiWindow::slotStateChanged)); connect(m_palette, &Palette::customContextMenuRequested, this, &MainWindow::paletteContextMenu); connect(m_editor, &Editor::changedVisibleCells, m_preview, &Preview::setVisibleCells); connect(m_preview, static_cast(&Preview::clicked), m_editor, static_cast(&Editor::previewClicked)); connect(m_preview, static_cast(&Preview::clicked), m_editor, static_cast(&Editor::previewClicked)); } void MainWindow::setupActionDefaults() { KActionCollection *actions = actionCollection(); actions->action(QStringLiteral("maskStitch"))->setChecked(false); actions->action(QStringLiteral("maskColor"))->setChecked(false); actions->action(QStringLiteral("maskBackstitch"))->setChecked(false); actions->action(QStringLiteral("maskKnot"))->setChecked(false); actions->action(QStringLiteral("stitchFull"))->trigger(); // Select full stitch actions->action(QStringLiteral("toolPaint"))->trigger(); // Select paint tool clipboardDataChanged(); } MainWindow::~MainWindow() { delete m_printer; } Editor *MainWindow::editor() { return m_editor; } Preview *MainWindow::preview() { return m_preview; } Palette *MainWindow::palette() { return m_palette; } bool MainWindow::queryClose() { if (m_document->undoStack().isClean()) { return true; } while (true) { int messageBoxResult = KMessageBox::warningYesNoCancel(this, i18n("Save changes to document?\nSelecting No discards changes.")); switch (messageBoxResult) { case KMessageBox::Yes : fileSave(); if (m_document->undoStack().isClean()) { return true; } else { KMessageBox::error(this, i18n("Unable to save the file")); } break; case KMessageBox::No : return true; case KMessageBox::Cancel : return false; } } } void MainWindow::setupActionsFromDocument() { KActionCollection *actions = actionCollection(); actions->action(QStringLiteral("file_revert"))->setEnabled(!m_document->undoStack().isClean()); actions->action(QStringLiteral("edit_undo"))->setEnabled(m_document->undoStack().canUndo()); actions->action(QStringLiteral("edit_redo"))->setEnabled(m_document->undoStack().canRedo()); updateBackgroundImageActionLists(); } void MainWindow::fileNew() { MainWindow *window = new MainWindow(QUrl()); window->show(); } void MainWindow::fileOpen() { fileOpen(QFileDialog::getOpenFileUrl(this, i18n("Open file"), QUrl::fromLocalFile(QDir::homePath()), i18n("KXStitch Patterns (*.kxs);;PC Stitch Patterns (*.pat);;All Files (*)"))); } void MainWindow::fileOpen(const QUrl &url) { MainWindow *window; bool docEmpty = (m_document->undoStack().isClean() && (m_document->url().toString() == i18n("Untitled"))); if (url.isValid()) { if (docEmpty) { QTemporaryFile tmpFile; if (tmpFile.open()) { tmpFile.close(); KIO::FileCopyJob *job = KIO::file_copy(url, QUrl::fromLocalFile(tmpFile.fileName()), -1, KIO::Overwrite); if (job->exec()) { /* In earlier versions of KDE/Qt creating a QDataStream on tmpFile allowed reading the data from the copied file. * Somewhere after KDE 5.55.0/Qt 5.9.7 this no longer possible as tmpFile size() is reported with a length of 0 * whereas previously tmpFile size() was reported as the size of the copied file. * Therefore open a new QFile on the temporary file after downloading to allow reading. */ QFile reader(tmpFile.fileName()); if (reader.open(QIODevice::ReadOnly)) { QDataStream stream(&reader); try { m_document->readKXStitch(stream); m_document->setUrl(url); KRecentFilesAction *action = static_cast(actionCollection()->action(QStringLiteral("file_open_recent"))); action->addUrl(url); action->saveEntries(KConfigGroup(KSharedConfig::openConfig(), QStringLiteral("RecentFiles"))); } catch (const InvalidFile &e) { stream.device()->seek(0); try { m_document->readPCStitch(stream); } catch (const InvalidFile &e) { KMessageBox::sorry(nullptr, i18n("The file does not appear to be a recognized cross stitch file.")); } } catch (const InvalidFileVersion &e) { KMessageBox::sorry(nullptr, i18n("This version of the file is not supported.\n%1", e.version)); } catch (const FailedReadFile &e) { KMessageBox::error(nullptr, i18n("Failed to read the file.\n%1.", e.status)); m_document->initialiseNew(); } setupActionsFromDocument(); m_editor->readDocumentSettings(); m_preview->readDocumentSettings(); m_palette->update(); documentModified(true); // this is the clean value true reader.close(); } else { KMessageBox::error(nullptr, reader.errorString()); } } else { KMessageBox::error(nullptr, job->errorString()); } tmpFile.close(); } else { KMessageBox::error(nullptr, tmpFile.errorString()); } } else { window = new MainWindow(url); window->show(); } } } void MainWindow::fileSave() { QUrl url = m_document->url(); if (url.toString() == i18n("Untitled")) { fileSaveAs(); } else { // ### Why use QUrl everywhere if this only supports local files? QSaveFile file(url.toLocalFile()); if (file.open(QIODevice::WriteOnly)) { QDataStream stream(&file); try { m_document->write(stream); if (!file.commit()) { throw FailedWriteFile(stream.status()); } m_document->undoStack().setClean(); } catch (const FailedWriteFile &e) { KMessageBox::error(nullptr, QString(i18n("Failed to save the file.\n%1", file.errorString()))); file.cancelWriting(); } } else { KMessageBox::error(nullptr, QString(i18n("Failed to open the file.\n%1", file.errorString()))); } } } void MainWindow::fileSaveAs() { QUrl url = QFileDialog::getSaveFileUrl(this, i18n("Save As..."), QUrl::fromLocalFile(QDir::homePath()), i18n("Cross Stitch Patterns (*.kxs)")); if (url.isValid()) { KIO::StatJob *statJob = KIO::stat(url, KIO::StatJob::DestinationSide, 0); if (statJob->exec()) { if (KMessageBox::warningYesNo(this, i18n("This file already exists\nDo you want to overwrite it?")) == KMessageBox::No) { return; } } m_document->setUrl(url); fileSave(); KRecentFilesAction *action = static_cast(actionCollection()->action(QStringLiteral("file_open_recent"))); action->addUrl(url); action->saveEntries(KConfigGroup(KSharedConfig::openConfig(), QStringLiteral("RecentFiles"))); } } void MainWindow::fileRevert() { if (!m_document->undoStack().isClean()) { if (KMessageBox::warningYesNo(this, i18n("Revert changes to document?")) == KMessageBox::Yes) { m_document->undoStack().setIndex(m_document->undoStack().cleanIndex()); } } } void MainWindow::filePrintSetup() { if (m_printer == nullptr) { m_printer = new QPrinter(); } QPointer printSetupDlg = new PrintSetupDlg(this, m_document, m_printer); if (printSetupDlg->exec() == QDialog::Accepted) { m_document->undoStack().push(new UpdatePrinterConfigurationCommand(m_document, printSetupDlg->printerConfiguration())); } delete printSetupDlg; } void MainWindow::filePrint() { if (m_printer == nullptr) { filePrintSetup(); } if (!m_document->printerConfiguration().pages().isEmpty()) { m_printer->setFullPage(true); m_printer->setPrintRange(QPrinter::AllPages); m_printer->setFromTo(1, m_document->printerConfiguration().pages().count()); QPointer printDialog = new QPrintDialog(m_printer, this); if (printDialog->exec() == QDialog::Accepted) { printPages(); } delete printDialog; } else { KMessageBox::information(this, i18n("There is nothing to print")); } } void MainWindow::printPages() { QList pages = m_document->printerConfiguration().pages(); int fromPage = 1; int toPage = pages.count(); if (m_printer->printRange() == QPrinter::PageRange) { fromPage = m_printer->fromPage(); toPage = m_printer->toPage(); } while (toPage < pages.count()) pages.removeLast(); while (--fromPage) pages.removeFirst(); int totalPages = pages.count(); const Page *page = (m_printer->pageOrder() == QPrinter::FirstPageFirst)?pages.takeFirst():pages.takeLast(); - m_printer->setPaperSize(page->paperSize()); // DEPRECATED - m_printer->setOrientation(page->orientation()); // DEPRECATED + m_printer->setPageSize(page->pageSize()); + m_printer->setPageOrientation(page->orientation()); QPainter painter; painter.begin(m_printer); painter.setRenderHint(QPainter::Antialiasing, true); for (int p = 0 ; p < totalPages ;) { - int paperWidth = PaperSizes::width(page->paperSize(), page->orientation()); - int paperHeight = PaperSizes::height(page->paperSize(), page->orientation()); + int paperWidth = PageSizes::width(page->pageSize().id(), page->orientation()); + int paperHeight = PageSizes::height(page->pageSize().id(), page->orientation()); painter.setWindow(0, 0, paperWidth, paperHeight); page->render(m_document, &painter); if (++p < totalPages) { page = (m_printer->pageOrder() == QPrinter::FirstPageFirst)?pages.takeFirst():pages.takeLast(); - m_printer->setPaperSize(page->paperSize()); // DEPRECATED - m_printer->setOrientation(page->orientation()); // DEPRECATED + m_printer->setPageSize(page->pageSize()); + m_printer->setPageOrientation(page->orientation()); m_printer->newPage(); } } painter.end(); } void MainWindow::fileImportImage() { MainWindow *window; bool docEmpty = ((m_document->undoStack().isClean()) && (m_document->url().toString() == i18n("Untitled"))); QUrl url = QFileDialog::getOpenFileUrl(this, i18n("Import Image"), QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)), i18n("Images (*.bmp *.gif *.jpg *.png *.pbm *.pgm *.ppm *.xbm *.xpm *.svg)")); if (url.isValid()) { QTemporaryFile tmpFile; if (tmpFile.open()) { KIO::FileCopyJob *job = KIO::file_copy(url, QUrl::fromLocalFile(tmpFile.fileName()), -1, KIO::Overwrite); if (job->exec()) { if (docEmpty) { convertImage(tmpFile.fileName()); this->findChild(QStringLiteral("ImportedImage#"))->show(); } else { window = new MainWindow(tmpFile.fileName()); window->show(); } } else { KMessageBox::error(nullptr, job->errorString()); } } } } void MainWindow::convertImage(const QString &source) { Magick::Image image(source.toStdString()); QMap documentFlosses; QList symbolIndexes = SymbolManager::library(Configuration::palette_DefaultSymbolLibrary())->indexes(); QPointer importImageDlg = new ImportImageDlg(this, image); if (importImageDlg->exec()) { Magick::Image convertedImage = importImageDlg->convertedImage(); int imageWidth = convertedImage.columns(); int imageHeight = convertedImage.rows(); int documentWidth = imageWidth; int documentHeight = imageHeight; bool useFractionals = importImageDlg->useFractionals(); /* * ImageMagick prior to V7 used matte (opacity) to determine if an image has transparency. * 0.0 for transparent to 1.0 for opaque * * ImageMagick V7 now uses alpha (transparency). * 1.0 for transparent to 0.0 for opaque * * Access to pixels has changed too, V7 can use pixelColor to access the color of a particular * pixel, but although this was available in V6, it doesn't appear to produce the same result * and has resulted in black images when importing. */ #if MagickLibVersion < 0x700 bool hasTransparency = convertedImage.matte(); double transparent = 1.0; const Magick::PixelPacket *pixels = convertedImage.getConstPixels(0, 0, imageWidth, imageHeight); #else bool hasTransparency = convertedImage.alpha(); double transparent = 0.0; #endif bool ignoreColor = importImageDlg->ignoreColor(); Magick::Color ignoreColorValue = importImageDlg->ignoreColorValue(); int pixelCount = imageWidth * imageHeight; if (useFractionals) { documentWidth /= 2; documentHeight /= 2; } QString schemeName = importImageDlg->flossScheme(); FlossScheme *flossScheme = SchemeManager::scheme(schemeName); QUndoCommand *importImageCommand = new ImportImageCommand(m_document); new ResizeDocumentCommand(m_document, documentWidth, documentHeight, importImageCommand); new ChangeSchemeCommand(m_document, schemeName, importImageCommand); QProgressDialog progress(i18n("Converting to stitches"), i18n("Cancel"), 0, pixelCount, this); progress.setWindowModality(Qt::WindowModal); for (int dy = 0 ; dy < imageHeight ; dy++) { progress.setValue(dy * imageWidth); QApplication::processEvents(); if (progress.wasCanceled()) { delete importImageDlg; delete importImageCommand; return; } for (int dx = 0 ; dx < imageWidth ; dx++) { #if MagickLibVersion < 0x700 Magick::ColorRGB rgb = Magick::Color(*pixels++); #else Magick::ColorRGB rgb = convertedImage.pixelColor(dx, dy); #endif if (hasTransparency && (rgb.alpha() == transparent)) { // ignore this pixel as it is transparent } else { if (!(ignoreColor && (rgb == ignoreColorValue))) { int flossIndex; QColor color((int)(255*rgb.red()), (int)(255*rgb.green()), (int)(255*rgb.blue())); for (flossIndex = 0 ; flossIndex < documentFlosses.count() ; ++flossIndex) { if (documentFlosses[flossIndex] == color) { break; } } if (flossIndex == documentFlosses.count()) { // reached the end of the list qint16 stitchSymbol = symbolIndexes.takeFirst(); Qt::PenStyle backstitchSymbol(Qt::SolidLine); Floss *floss = flossScheme->find(color); DocumentFloss *documentFloss = new DocumentFloss(floss->name(), stitchSymbol, backstitchSymbol, Configuration::palette_StitchStrands(), Configuration::palette_BackstitchStrands()); documentFloss->setFlossColor(floss->color()); new AddDocumentFlossCommand(m_document, flossIndex, documentFloss, importImageCommand); documentFlosses.insert(flossIndex, color); } // at this point // flossIndex will be the index for the found color if (useFractionals) { int zone = (dy % 2) * 2 + (dx % 2); new AddStitchCommand(m_document, QPoint(dx / 2, dy / 2), stitchMap[0][zone], flossIndex, importImageCommand); } else { new AddStitchCommand(m_document, QPoint(dx, dy), Stitch::Full, flossIndex, importImageCommand); } } } } } new SetPropertyCommand(m_document, QStringLiteral("horizontalClothCount"), importImageDlg->horizontalClothCount(), importImageCommand); new SetPropertyCommand(m_document, QStringLiteral("verticalClothCount"), importImageDlg->verticalClothCount(), importImageCommand); m_document->undoStack().push(importImageCommand); convertPreview(source, importImageDlg->croppedArea()); } delete importImageDlg; } void MainWindow::convertPreview(const QString &source, const QRect &croppedArea) { QPixmap pixmap; pixmap.load(source); pixmap = pixmap.copy(croppedArea); m_imageLabel->setPixmap(pixmap); } void MainWindow::fileProperties() { QPointer filePropertiesDlg = new FilePropertiesDlg(this, m_document); if (filePropertiesDlg->exec()) { QUndoCommand *cmd = new FilePropertiesCommand(m_document); if ((filePropertiesDlg->documentWidth() != m_document->pattern()->stitches().width()) || (filePropertiesDlg->documentHeight() != m_document->pattern()->stitches().height())) { new ResizeDocumentCommand(m_document, filePropertiesDlg->documentWidth(), filePropertiesDlg->documentHeight(), cmd); } if (filePropertiesDlg->unitsFormat() != static_cast(m_document->property(QStringLiteral("unitsFormat")).toInt())) { new SetPropertyCommand(m_document, QStringLiteral("unitsFormat"), QVariant(filePropertiesDlg->unitsFormat()), cmd); } if (filePropertiesDlg->horizontalClothCount() != m_document->property(QStringLiteral("horizontalClothCount")).toDouble()) { new SetPropertyCommand(m_document, QStringLiteral("horizontalClothCount"), QVariant(filePropertiesDlg->horizontalClothCount()), cmd); } if (filePropertiesDlg->clothCountLink() != m_document->property(QStringLiteral("clothCountLink")).toBool()) { new SetPropertyCommand(m_document, QStringLiteral("clothCountLink"), QVariant(filePropertiesDlg->clothCountLink()), cmd); } if (filePropertiesDlg->verticalClothCount() != m_document->property(QStringLiteral("verticalClothCount")).toDouble()) { new SetPropertyCommand(m_document, QStringLiteral("verticalClothCount"), QVariant(filePropertiesDlg->verticalClothCount()), cmd); } if (filePropertiesDlg->clothCountUnits() != static_cast(m_document->property(QStringLiteral("clothCountUnits")).toInt())) { new SetPropertyCommand(m_document, QStringLiteral("clothCountUnits"), QVariant(filePropertiesDlg->clothCountUnits()), cmd); } if (filePropertiesDlg->title() != m_document->property(QStringLiteral("title")).toString()) { new SetPropertyCommand(m_document, QStringLiteral("title"), QVariant(filePropertiesDlg->title()), cmd); } if (filePropertiesDlg->author() != m_document->property(QStringLiteral("author")).toString()) { new SetPropertyCommand(m_document, QStringLiteral("author"), QVariant(filePropertiesDlg->author()), cmd); } if (filePropertiesDlg->copyright() != m_document->property(QStringLiteral("copyright")).toString()) { new SetPropertyCommand(m_document, QStringLiteral("copyright"), QVariant(filePropertiesDlg->copyright()), cmd); } if (filePropertiesDlg->fabric() != m_document->property(QStringLiteral("fabric")).toString()) { new SetPropertyCommand(m_document, QStringLiteral("fabric"), QVariant(filePropertiesDlg->fabric()), cmd); } if (filePropertiesDlg->fabricColor() != m_document->property(QStringLiteral("fabricColor")).value()) { new SetPropertyCommand(m_document, QStringLiteral("fabricColor"), QVariant(filePropertiesDlg->fabricColor()), cmd); } if (filePropertiesDlg->instructions() != m_document->property(QStringLiteral("instructions")).toString()) { new SetPropertyCommand(m_document, QStringLiteral("instructions"), QVariant(filePropertiesDlg->instructions()), cmd); } if (filePropertiesDlg->flossScheme() != m_document->pattern()->palette().schemeName()) { new ChangeSchemeCommand(m_document, filePropertiesDlg->flossScheme(), cmd); } if (cmd->childCount()) { m_document->undoStack().push(cmd); } else { delete cmd; } } delete filePropertiesDlg; } void MainWindow::fileAddBackgroundImage() { QUrl url = QFileDialog::getOpenFileUrl(this, i18n("Background Image"), QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)), i18n("Images (*.bmp *.gif *.jpg *.png *.pbm *.pgm *.ppm *.xbm *.xpm *.svg)")); if (!url.isEmpty()) { QRect patternArea(0, 0, m_document->pattern()->stitches().width(), m_document->pattern()->stitches().height()); QRect selectionArea = m_editor->selectionArea(); QSharedPointer backgroundImage(new BackgroundImage(url, (selectionArea.isValid() ? selectionArea : patternArea))); if (backgroundImage->isValid()) { m_document->undoStack().push(new AddBackgroundImageCommand(m_document, backgroundImage, this)); } } } void MainWindow::fileRemoveBackgroundImage() { QAction *action = qobject_cast(sender()); m_document->undoStack().push(new RemoveBackgroundImageCommand(m_document, action->data().value>(), this)); } void MainWindow::fileClose() { if (queryClose()) { m_document->initialiseNew(); setupActionsFromDocument(); m_editor->readDocumentSettings(); m_preview->readDocumentSettings(); } close(); } void MainWindow::fileQuit() { close(); } void MainWindow::editUndo() { m_document->undoStack().undo(); } void MainWindow::editRedo() { m_document->undoStack().redo(); } void MainWindow::undoTextChanged(const QString &text) { actionCollection()->action(QStringLiteral("edit_undo"))->setText(i18n("Undo %1", text)); } void MainWindow::redoTextChanged(const QString &text) { actionCollection()->action(QStringLiteral("edit_redo"))->setText(i18n("Redo %1", text)); } void MainWindow::clipboardDataChanged() { actionCollection()->action(QStringLiteral("edit_paste"))->setEnabled(QApplication::clipboard()->mimeData()->hasFormat(QStringLiteral("application/kxstitch"))); } void MainWindow::paletteManager() { QPointer paletteManagerDlg = new PaletteManagerDlg(this, m_document); if (paletteManagerDlg->exec()) { DocumentPalette palette = paletteManagerDlg->palette(); if (palette != m_document->pattern()->palette()) { m_document->undoStack().push(new UpdateDocumentPaletteCommand(m_document, palette)); } } delete paletteManagerDlg; } void MainWindow::paletteShowSymbols(bool show) { m_palette->showSymbols(show); } void MainWindow::paletteClearUnused() { QMap flossUsage = m_document->pattern()->stitches().flossUsage(); QMapIterator flosses(m_document->pattern()->palette().flosses()); ClearUnusedFlossesCommand *clearUnusedFlossesCommand = new ClearUnusedFlossesCommand(m_document); while (flosses.hasNext()) { flosses.next(); if (flossUsage[flosses.key()].totalStitches() == 0) { new RemoveDocumentFlossCommand(m_document, flosses.key(), flosses.value(), clearUnusedFlossesCommand); } } if (clearUnusedFlossesCommand->childCount()) { m_document->undoStack().push(clearUnusedFlossesCommand); } else { delete clearUnusedFlossesCommand; } } void MainWindow::paletteCalibrateScheme() { } void MainWindow::paletteSwapColors(int originalIndex, int replacementIndex) { if (originalIndex != replacementIndex) { m_document->undoStack().push(new PaletteSwapColorCommand(m_document, originalIndex, replacementIndex)); } } void MainWindow::paletteReplaceColor(int originalIndex, int replacementIndex) { if (originalIndex != replacementIndex) { m_document->undoStack().push(new PaletteReplaceColorCommand(m_document, originalIndex, replacementIndex)); } } void MainWindow::viewFitBackgroundImage() { QAction *action = qobject_cast(sender()); m_document->undoStack().push(new FitBackgroundImageCommand(m_document, action->data().value>(), m_editor->selectionArea())); } void MainWindow::paletteContextMenu(const QPoint &pos) { static_cast(guiFactory()->container(QStringLiteral("PalettePopup"), this))->popup(qobject_cast(sender())->mapToGlobal(pos)); } void MainWindow::viewShowBackgroundImage() { QAction *action = qobject_cast(sender()); m_document->undoStack().push(new ShowBackgroundImageCommand(m_document, action->data().value>(), action->isChecked())); } void MainWindow::patternExtend() { QPointer extendPatternDlg = new ExtendPatternDlg(this); if (extendPatternDlg->exec()) { int top = extendPatternDlg->top(); int left = extendPatternDlg->left(); int right = extendPatternDlg->right(); int bottom = extendPatternDlg->bottom(); if (top || left || right || bottom) { m_document->undoStack().push(new ExtendPatternCommand(m_document, top, left, right, bottom)); } } delete extendPatternDlg; } void MainWindow::patternCentre() { m_document->undoStack().push(new CentrePatternCommand(m_document)); } void MainWindow::patternCrop() { m_document->undoStack().push(new CropToPatternCommand(m_document)); } void MainWindow::patternCropToSelection() { m_document->undoStack().push(new CropToSelectionCommand(m_document, m_editor->selectionArea())); } void MainWindow::insertColumns() { m_document->undoStack().push(new InsertColumnsCommand(m_document, m_editor->selectionArea())); } void MainWindow::insertRows() { m_document->undoStack().push(new InsertRowsCommand(m_document, m_editor->selectionArea())); } void MainWindow::preferences() { if (KConfigDialog::showDialog(QStringLiteral("preferences"))) { return; } KConfigDialog *dialog = new KConfigDialog(this, QStringLiteral("preferences"), Configuration::self()); dialog->setFaceType(KPageDialog::List); dialog->addPage(new EditorConfigPage(0, QStringLiteral("EditorConfigPage")), i18nc("The Editor config page", "Editor"), QStringLiteral("preferences-desktop")); dialog->addPage(new PatternConfigPage(0, QStringLiteral("PatternConfigPage")), i18n("Pattern"), QStringLiteral("ksnapshot")); PaletteConfigPage *paletteConfigPage = new PaletteConfigPage(0, QStringLiteral("PaletteConfigPage")); dialog->addPage(paletteConfigPage, i18n("Palette"), QStringLiteral("preferences-desktop-color")); dialog->addPage(new ImportConfigPage(0, QStringLiteral("ImportConfigPage")), i18n("Import"), QStringLiteral("insert-image")); dialog->addPage(new LibraryConfigPage(0, QStringLiteral("LibraryConfigPage")), i18n("Library"), QStringLiteral("accessories-dictionary")); dialog->addPage(new PrinterConfigPage(0, QStringLiteral("PrinterConfigPage")), i18n("Printer Configuration"), QStringLiteral("preferences-desktop-printer")); connect(dialog, &KConfigDialog::settingsChanged, this, &MainWindow::settingsChanged); dialog->show(); } void MainWindow::settingsChanged() { QList documentChanges; ConfigurationCommand *configurationCommand = new ConfigurationCommand(this); if (m_document->property(QStringLiteral("cellHorizontalGrouping")) != Configuration::editor_CellHorizontalGrouping()) { documentChanges.append(new SetPropertyCommand(m_document, QStringLiteral("cellHorizontalGrouping"), Configuration::editor_CellHorizontalGrouping(), configurationCommand)); } if (m_document->property(QStringLiteral("cellVerticalGrouping")) != Configuration::editor_CellVerticalGrouping()) { documentChanges.append(new SetPropertyCommand(m_document, QStringLiteral("cellVerticalGrouping"), Configuration::editor_CellVerticalGrouping(), configurationCommand)); } if (m_document->property(QStringLiteral("thickLineColor")) != Configuration::editor_ThickLineColor()) { documentChanges.append(new SetPropertyCommand(m_document, QStringLiteral("thickLineColor"), Configuration::editor_ThickLineColor(), configurationCommand)); } if (m_document->property(QStringLiteral("thinLineColor")) != Configuration::editor_ThinLineColor()) { documentChanges.append(new SetPropertyCommand(m_document, QStringLiteral("thinLineColor"), Configuration::editor_ThinLineColor(), configurationCommand)); } if (documentChanges.count()) { m_document->undoStack().push(configurationCommand); } else { delete configurationCommand; } loadSettings(); } void MainWindow::loadSettings() { m_horizontalScale->setMinimumSize(0, Configuration::editor_HorizontalScaleHeight()); m_verticalScale->setMinimumSize(Configuration::editor_VerticalScaleWidth(), 0); m_horizontalScale->setCellGrouping(Configuration::editor_CellHorizontalGrouping()); m_verticalScale->setCellGrouping(Configuration::editor_CellVerticalGrouping()); m_editor->loadSettings(); m_preview->loadSettings(); m_palette->loadSettings(); KActionCollection *actions = actionCollection(); actions->action(QStringLiteral("makesCopies"))->setChecked(Configuration::tool_MakesCopies()); actions->action(QStringLiteral("colorHighlight"))->setChecked(Configuration::renderer_ColorHilight()); actions->action(QStringLiteral("renderStitches"))->setChecked(Configuration::renderer_RenderStitches()); actions->action(QStringLiteral("renderBackstitches"))->setChecked(Configuration::renderer_RenderBackstitches()); actions->action(QStringLiteral("renderFrenchKnots"))->setChecked(Configuration::renderer_RenderFrenchKnots()); actions->action(QStringLiteral("renderGrid"))->setChecked(Configuration::renderer_RenderGrid()); actions->action(QStringLiteral("renderBackgroundImages"))->setChecked(Configuration::renderer_RenderBackgroundImages()); switch (Configuration::editor_FormatScalesAs()) { case Configuration::EnumEditor_FormatScalesAs::Stitches: actions->action(QStringLiteral("formatScalesAsStitches"))->trigger(); break; case Configuration::EnumEditor_FormatScalesAs::Inches: actions->action(QStringLiteral("formatScalesAsInches"))->trigger(); break; case Configuration::EnumEditor_FormatScalesAs::Centimeters: actions->action(QStringLiteral("formatScalesAsCentimeters"))->trigger(); break; default: break; } switch (Configuration::renderer_RenderStitchesAs()) { case Configuration::EnumRenderer_RenderStitchesAs::Stitches: actions->action(QStringLiteral("renderStitchesAsRegularStitches"))->trigger(); break; case Configuration::EnumRenderer_RenderStitchesAs::BlackWhiteSymbols: actions->action(QStringLiteral("renderStitchesAsBlackWhiteSymbols"))->trigger(); break; case Configuration::EnumRenderer_RenderStitchesAs::ColorSymbols: actions->action(QStringLiteral("renderStitchesAsColorSymbols"))->trigger(); break; case Configuration::EnumRenderer_RenderStitchesAs::ColorBlocks: actions->action(QStringLiteral("renderStitchesAsColorBlocks"))->trigger(); break; case Configuration::EnumRenderer_RenderStitchesAs::ColorBlocksSymbols: actions->action(QStringLiteral("renderStitchesAsColorBlocksSymbols"))->trigger(); break; default: break; } switch (Configuration::renderer_RenderBackstitchesAs()) { case Configuration::EnumRenderer_RenderBackstitchesAs::ColorLines: actions->action(QStringLiteral("renderBackstitchesAsColorLines"))->trigger(); break; case Configuration::EnumRenderer_RenderBackstitchesAs::BlackWhiteSymbols: actions->action(QStringLiteral("renderBackstitchesAsBlackWhiteSymbols"))->trigger(); break; default: break; } switch (Configuration::renderer_RenderKnotsAs()) { case Configuration::EnumRenderer_RenderKnotsAs::ColorBlocks: actions->action(QStringLiteral("renderKnotsAsColorBlocks"))->trigger(); break; case Configuration::EnumRenderer_RenderKnotsAs::ColorBlocksSymbols: actions->action(QStringLiteral("renderKnotsAsColorBlocksSymbols"))->trigger(); break; case Configuration::EnumRenderer_RenderKnotsAs::ColorSymbols: actions->action(QStringLiteral("renderKnotsAsColorSymbols"))->trigger(); break; case Configuration::EnumRenderer_RenderKnotsAs::BlackWhiteSymbols: actions->action(QStringLiteral("renderKnotsAsBlackWhiteSymbols"))->trigger(); break; default: break; } actions->action(QStringLiteral("paletteShowSymbols"))->setChecked(Configuration::palette_ShowSymbols()); } void MainWindow::documentModified(bool clean) { setCaption(m_document->url().fileName(), !clean); } void MainWindow::setupActions() { QAction *action; QActionGroup *actionGroup; KActionCollection *actions = actionCollection(); // File menu KStandardAction::openNew(this, &MainWindow::fileNew, actions); KStandardAction::open(this, static_cast(&MainWindow::fileOpen), actions); KStandardAction::openRecent(this, static_cast(&MainWindow::fileOpen), actions)->loadEntries(KConfigGroup(KSharedConfig::openConfig(), QStringLiteral("RecentFiles"))); KStandardAction::save(this, &MainWindow::fileSave, actions); KStandardAction::saveAs(this, &MainWindow::fileSaveAs, actions); KStandardAction::revert(this, &MainWindow::fileRevert, actions); action = new QAction(this); action->setText(i18n("Print Setup...")); connect(action, &QAction::triggered, this, &MainWindow::filePrintSetup); actions->addAction(QStringLiteral("filePrintSetup"), action); KStandardAction::print(this, &MainWindow::filePrint, actions); action = new QAction(this); action->setText(i18n("Import Image")); connect(action, &QAction::triggered, this, &MainWindow::fileImportImage); actions->addAction(QStringLiteral("fileImportImage"), action); action = new QAction(this); action->setText(i18n("File Properties")); connect(action, &QAction::triggered, this, &MainWindow::fileProperties); actions->addAction(QStringLiteral("fileProperties"), action); action = new QAction(this); action->setText(i18n("Add Background Image...")); connect(action, &QAction::triggered, this, &MainWindow::fileAddBackgroundImage); actions->addAction(QStringLiteral("fileAddBackgroundImage"), action); KStandardAction::close(this, &MainWindow::fileClose, actions); KStandardAction::quit(this, &MainWindow::fileQuit, actions); // Edit menu KStandardAction::undo(this, &MainWindow::editUndo, actions); KStandardAction::redo(this, &MainWindow::editRedo, actions); KStandardAction::cut(m_editor, &Editor::editCut, actions); actions->action(QStringLiteral("edit_cut"))->setEnabled(false); KStandardAction::copy(m_editor, &Editor::editCopy, actions); actions->action(QStringLiteral("edit_copy"))->setEnabled(false); KStandardAction::paste(m_editor, &Editor::editPaste, actions); action = new QAction(this); action->setText(i18n("Mirror/Rotate makes copies")); action->setCheckable(true); connect(action, &QAction::triggered, m_editor, &Editor::setMakesCopies); actions->addAction(QStringLiteral("makesCopies"), action); action = new QAction(this); action->setText(i18n("Horizontally")); action->setData(Qt::Horizontal); connect(action, &QAction::triggered, m_editor, &Editor::mirrorSelection); action->setEnabled(false); actions->addAction(QStringLiteral("mirrorHorizontal"), action); action = new QAction(this); action->setText(i18n("Vertically")); action->setData(Qt::Vertical); connect(action, &QAction::triggered, m_editor, &Editor::mirrorSelection); action->setEnabled(false); actions->addAction(QStringLiteral("mirrorVertical"), action); action = new QAction(this); action->setText(i18n("90 Degrees")); action->setData(StitchData::Rotate90); connect(action, &QAction::triggered, m_editor, &Editor::rotateSelection); action->setEnabled(false); actions->addAction(QStringLiteral("rotate90"), action); action = new QAction(this); action->setText(i18n("180 Degrees")); action->setData(StitchData::Rotate180); connect(action, &QAction::triggered, m_editor, &Editor::rotateSelection); action->setEnabled(false); actions->addAction(QStringLiteral("rotate180"), action); action = new QAction(this); action->setText(i18n("270 Degrees")); action->setData(StitchData::Rotate270); connect(action, &QAction::triggered, m_editor, &Editor::rotateSelection); action->setEnabled(false); actions->addAction(QStringLiteral("rotate270"), action); // Selection mask sub menu action = new QAction(this); action->setText(i18n("Stitch Mask")); action->setCheckable(true); connect(action, &QAction::triggered, m_editor, &Editor::setMaskStitch); actions->addAction(QStringLiteral("maskStitch"), action); action = new QAction(this); action->setText(i18n("Color Mask")); action->setCheckable(true); connect(action, &QAction::triggered, m_editor, &Editor::setMaskColor); actions->addAction(QStringLiteral("maskColor"), action); action = new QAction(this); action->setText(i18n("Exclude Backstitches")); action->setCheckable(true); connect(action, &QAction::triggered, m_editor, &Editor::setMaskBackstitch); actions->addAction(QStringLiteral("maskBackstitch"), action); action = new QAction(this); action->setText(i18n("Exclude Knots")); action->setCheckable(true); connect(action, &QAction::triggered, m_editor, &Editor::setMaskKnot); actions->addAction(QStringLiteral("maskKnot"), action); // View menu KStandardAction::zoomIn(m_editor, &Editor::zoomIn, actions); KStandardAction::zoomOut(m_editor, &Editor::zoomOut, actions); KStandardAction::actualSize(m_editor, &Editor::actualSize, actions); action = KStandardAction::fitToPage(m_editor, &Editor::fitToPage, actions); action->setIcon(QIcon::fromTheme(QStringLiteral("zoom-fit-best"))); action = KStandardAction::fitToWidth(m_editor, &Editor::fitToWidth, actions); action->setIcon(QIcon::fromTheme(QStringLiteral("zoom-fit-width"))); action = KStandardAction::fitToHeight(m_editor, &Editor::fitToHeight, actions); action->setIcon(QIcon::fromTheme(QStringLiteral("zoom-fit-height"))); // Entries for Show/Hide Preview and Palette dock windows are added dynamically // Entries for Show/Hide and Remove background images are added dynamically // Stitches Menu actionGroup = new QActionGroup(this); actionGroup->setExclusive(true); action = new QAction(this); action->setText(i18n("Quarter Stitch")); action->setIcon(QIcon::fromTheme(QStringLiteral("kxstitch-quarter-stitch"))); action->setCheckable(true); connect(action, &QAction::triggered, m_editor, [=]() { m_editor->selectStitch(Editor::StitchQuarter); }); actions->addAction(QStringLiteral("stitchQuarter"), action); actionGroup->addAction(action); action = new QAction(this); action->setText(i18n("Half Stitch")); action->setIcon(QIcon::fromTheme(QStringLiteral("kxstitch-half-stitch"))); action->setCheckable(true); connect(action, &QAction::triggered, m_editor, [=]() { m_editor->selectStitch(Editor::StitchHalf); }); actions->addAction(QStringLiteral("stitchHalf"), action); actionGroup->addAction(action); action = new QAction(this); action->setText(i18n("3 Quarter Stitch")); action->setIcon(QIcon::fromTheme(QStringLiteral("kxstitch-3quarter-stitch"))); action->setCheckable(true); connect(action, &QAction::triggered, m_editor, [=]() { m_editor->selectStitch(Editor::Stitch3Quarter); }); actions->addAction(QStringLiteral("stitch3Quarter"), action); actionGroup->addAction(action); action = new QAction(this); action->setText(i18n("Full Stitch")); action->setIcon(QIcon::fromTheme(QStringLiteral("kxstitch-full-stitch"))); action->setCheckable(true); connect(action, &QAction::triggered, m_editor, [=]() { m_editor->selectStitch(Editor::StitchFull); }); actions->addAction(QStringLiteral("stitchFull"), action); actionGroup->addAction(action); action = new QAction(this); action->setText(i18n("Small Half Stitch")); action->setIcon(QIcon::fromTheme(QStringLiteral("kxstitch-small-half-stitch"))); action->setCheckable(true); connect(action, &QAction::triggered, m_editor, [=]() { m_editor->selectStitch(Editor::StitchSmallHalf); }); actions->addAction(QStringLiteral("stitchSmallHalf"), action); actionGroup->addAction(action); action = new QAction(this); action->setText(i18n("Small Full Stitch")); action->setIcon(QIcon::fromTheme(QStringLiteral("kxstitch-small-full-stitch"))); action->setCheckable(true); connect(action, &QAction::triggered, m_editor, [=]() { m_editor->selectStitch(Editor::StitchSmallFull); }); actions->addAction(QStringLiteral("stitchSmallFull"), action); actionGroup->addAction(action); action = new QAction(this); action->setText(i18n("French Knot")); action->setIcon(QIcon::fromTheme(QStringLiteral("kxstitch-frenchknot"))); action->setCheckable(true); connect(action, &QAction::triggered, m_editor, [=]() { m_editor->selectStitch(Editor::StitchFrenchKnot); }); actions->addAction(QStringLiteral("stitchFrenchKnot"), action); actionGroup->addAction(action); // Tools Menu actionGroup = new QActionGroup(this); actionGroup->setExclusive(true); action = new QAction(this); action->setText(i18n("Paint")); action->setIcon(QIcon::fromTheme(QStringLiteral("draw-brush"))); action->setCheckable(true); connect(action, &QAction::triggered, m_editor, [=]() {m_editor->selectTool(Editor::ToolPaint);}); actions->addAction(QStringLiteral("toolPaint"), action); actionGroup->addAction(action); action = new QAction(this); action->setText(i18n("Draw")); action->setIcon(QIcon::fromTheme(QStringLiteral("draw-freehand"))); action->setCheckable(true); connect(action, &QAction::triggered, m_editor, [=]() {m_editor->selectTool(Editor::ToolDraw);}); actions->addAction(QStringLiteral("toolDraw"), action); actionGroup->addAction(action); action = new QAction(this); action->setText(i18n("Erase")); action->setIcon(QIcon::fromTheme(QStringLiteral("draw-eraser"))); action->setCheckable(true); connect(action, &QAction::triggered, m_editor, [=]() {m_editor->selectTool(Editor::ToolErase);}); actions->addAction(QStringLiteral("toolErase"), action); actionGroup->addAction(action); action = new QAction(this); action->setText(i18n("Draw Rectangle")); action->setIcon(QIcon::fromTheme(QStringLiteral("draw-rectangle"))); action->setCheckable(true); connect(action, &QAction::triggered, m_editor, [=]() {m_editor->selectTool(Editor::ToolRectangle);}); actions->addAction(QStringLiteral("toolRectangle"), action); actionGroup->addAction(action); action = new QAction(this); action->setText(i18n("Fill Rectangle")); action->setIcon(QIcon::fromTheme(QStringLiteral("kxstitch-draw-rectangle-filled"))); action->setCheckable(true); connect(action, &QAction::triggered, m_editor, [=]() {m_editor->selectTool(Editor::ToolFillRectangle);}); actions->addAction(QStringLiteral("toolFillRectangle"), action); actionGroup->addAction(action); action = new QAction(this); action->setText(i18n("Draw Ellipse")); action->setIcon(QIcon::fromTheme(QStringLiteral("draw-ellipse"))); action->setCheckable(true); connect(action, &QAction::triggered, m_editor, [=]() {m_editor->selectTool(Editor::ToolEllipse);}); actions->addAction(QStringLiteral("toolEllipse"), action); actionGroup->addAction(action); action = new QAction(this); action->setText(i18n("Fill Ellipse")); action->setIcon(QIcon::fromTheme(QStringLiteral("kxstitch-draw-ellipse-filled"))); action->setCheckable(true); connect(action, &QAction::triggered, m_editor, [=]() {m_editor->selectTool(Editor::ToolFillEllipse);}); actions->addAction(QStringLiteral("toolFillEllipse"), action); actionGroup->addAction(action); action = new QAction(this); action->setText(i18n("Fill Polygon")); action->setIcon(QIcon::fromTheme(QStringLiteral("draw-polyline"))); action->setCheckable(true); connect(action, &QAction::triggered, m_editor, [=]() {m_editor->selectTool(Editor::ToolFillPolygon);}); actions->addAction(QStringLiteral("toolFillPolygon"), action); actionGroup->addAction(action); action = new QAction(this); action->setText(i18n("Text")); action->setIcon(QIcon::fromTheme(QStringLiteral("draw-text"))); action->setCheckable(true); connect(action, &QAction::triggered, m_editor, [=]() {m_editor->selectTool(Editor::ToolText);}); actions->addAction(QStringLiteral("toolText"), action); actionGroup->addAction(action); action = new QAction(this); action->setText(i18n("Alphabet")); action->setIcon(QIcon::fromTheme(QStringLiteral("text-field"))); action->setCheckable(true); connect(action, &QAction::triggered, m_editor, [=]() {m_editor->selectTool(Editor::ToolAlphabet);}); actions->addAction(QStringLiteral("toolAlphabet"), action); actionGroup->addAction(action); action = new QAction(this); action->setText(i18nc("Select an area of the pattern", "Select")); action->setIcon(QIcon::fromTheme(QStringLiteral("select-rectangular"))); action->setCheckable(true); connect(action, &QAction::triggered, m_editor, [=]() {m_editor->selectTool(Editor::ToolSelect);}); actions->addAction(QStringLiteral("toolSelectRectangle"), action); actionGroup->addAction(action); action = new QAction(this); action->setText(i18n("Backstitch")); action->setIcon(QIcon::fromTheme(QStringLiteral("kxstitch-backstitch"))); action->setCheckable(true); connect(action, &QAction::triggered, m_editor, [=]() {m_editor->selectTool(Editor::ToolBackstitch);}); actions->addAction(QStringLiteral("toolBackstitch"), action); actionGroup->addAction(action); action = new QAction(this); action->setText(i18n("Color Picker")); action->setIcon(QIcon::fromTheme(QStringLiteral("color-picker"))); action->setCheckable(true); connect(action, &QAction::triggered, m_editor, [=]() {m_editor->selectTool(Editor::ToolColorPicker);}); actions->addAction(QStringLiteral("toolColorPicker"), action); actionGroup->addAction(action); // Palette Menu action = new QAction(this); action->setText(i18n("Palette Manager...")); action->setIcon(QIcon::fromTheme(QStringLiteral("kxstitch-color-add"))); connect(action, &QAction::triggered, this, &MainWindow::paletteManager); actions->addAction(QStringLiteral("paletteManager"), action); action = new QAction(this); action->setText(i18n("Show Symbols")); action->setCheckable(true); connect(action, &QAction::toggled, this, &MainWindow::paletteShowSymbols); actions->addAction(QStringLiteral("paletteShowSymbols"), action); action = new QAction(this); action->setText(i18n("Clear Unused")); connect(action, &QAction::triggered, this, &MainWindow::paletteClearUnused); actions->addAction(QStringLiteral("paletteClearUnused"), action); action = new QAction(this); action->setText(i18n("Calibrate Scheme...")); connect(action, &QAction::triggered, this, &MainWindow::paletteCalibrateScheme); actions->addAction(QStringLiteral("paletteCalibrateScheme"), action); action = new QAction(this); action->setText(i18n("Swap Colors")); connect(action, &QAction::triggered, m_palette, static_cast(&Palette::swapColors)); actions->addAction(QStringLiteral("paletteSwapColors"), action); action = new QAction(this); action->setText(i18n("Replace Colors")); connect(action, &QAction::triggered, m_palette, static_cast(&Palette::replaceColor)); actions->addAction(QStringLiteral("paletteReplaceColor"), action); // Pattern Menu action = new QAction(this); action->setText(i18n("Extend Pattern...")); action->setIcon(QIcon::fromTheme(QStringLiteral("kxstitch-extend-pattern"))); connect(action, &QAction::triggered, this, &MainWindow::patternExtend); actions->addAction(QStringLiteral("patternExtend"), action); action = new QAction(this); action->setText(i18n("Center Pattern")); action->setIcon(QIcon::fromTheme(QStringLiteral("kxstitch-center-pattern"))); connect(action, &QAction::triggered, this, &MainWindow::patternCentre); actions->addAction(QStringLiteral("patternCentre"), action); action = new QAction(this); action->setText(i18n("Crop Canvas to Pattern")); connect(action, &QAction::triggered, this, &MainWindow::patternCrop); actions->addAction(QStringLiteral("patternCrop"), action); action = new QAction(this); action->setText(i18n("Crop Canvas to Selection")); action->setIcon(QIcon::fromTheme(QStringLiteral("transform-crop"))); connect(action, &QAction::triggered, this, &MainWindow::patternCropToSelection); action->setEnabled(false); actions->addAction(QStringLiteral("patternCropToSelection"), action); action = new QAction(this); action->setText(i18n("Insert Rows")); connect(action, &QAction::triggered, this, &MainWindow::insertRows); action->setEnabled(false); actions->addAction(QStringLiteral("insertRows"), action); action = new QAction(this); action->setText(i18n("Insert Columns")); connect(action, &QAction::triggered, this, &MainWindow::insertColumns); action->setEnabled(false); actions->addAction(QStringLiteral("insertColumns"), action); // Library Menu action = new QAction(this); action->setText(i18n("Library Manager...")); connect(action, &QAction::triggered, m_editor, &Editor::libraryManager); actions->addAction(QStringLiteral("libraryManager"), action); // Settings Menu KStandardAction::preferences(this, &MainWindow::preferences, actions); // formatScalesAs actionGroup = new QActionGroup(this); actionGroup->setExclusive(true); action = new QAction(this); action->setText(i18n("Stitches")); action->setCheckable(true); connect(action, &QAction::triggered, m_editor, &Editor::formatScalesAsStitches); actions->addAction(QStringLiteral("formatScalesAsStitches"), action); actionGroup->addAction(action); action = new QAction(this); action->setText(i18n("Centimeters")); action->setCheckable(true); connect(action, &QAction::triggered, m_editor, &Editor::formatScalesAsCentimeters); actions->addAction(QStringLiteral("formatScalesAsCentimeters"), action); actionGroup->addAction(action); action = new QAction(this); action->setText(i18n("Inches")); action->setCheckable(true); connect(action, &QAction::triggered, m_editor, &Editor::formatScalesAsInches); actions->addAction(QStringLiteral("formatScalesAsInches"), action); actionGroup->addAction(action); // ShowStitchesAs actionGroup = new QActionGroup(this); actionGroup->setExclusive(true); action = new QAction(this); action->setText(i18n("Regular Stitches")); action->setCheckable(true); action->setChecked(true); connect(action, &QAction::triggered, m_editor, [=]() {m_editor->renderStitchesAs(Configuration::EnumRenderer_RenderStitchesAs::Stitches);}); actions->addAction(QStringLiteral("renderStitchesAsRegularStitches"), action); actionGroup->addAction(action); action = new QAction(this); action->setText(i18n("Black & White Symbols")); action->setCheckable(true); connect(action, &QAction::triggered, m_editor, [=]() {m_editor->renderStitchesAs(Configuration::EnumRenderer_RenderStitchesAs::BlackWhiteSymbols);}); actions->addAction(QStringLiteral("renderStitchesAsBlackWhiteSymbols"), action); actionGroup->addAction(action); action = new QAction(this); action->setText(i18n("Color Symbols")); action->setCheckable(true); connect(action, &QAction::triggered, m_editor, [=]() {m_editor->renderStitchesAs(Configuration::EnumRenderer_RenderStitchesAs::ColorSymbols);}); actions->addAction(QStringLiteral("renderStitchesAsColorSymbols"), action); actionGroup->addAction(action); action = new QAction(this); action->setText(i18n("Color Blocks")); action->setCheckable(true); connect(action, &QAction::triggered, m_editor, [=]() {m_editor->renderStitchesAs(Configuration::EnumRenderer_RenderStitchesAs::ColorBlocks);}); actions->addAction(QStringLiteral("renderStitchesAsColorBlocks"), action); actionGroup->addAction(action); action = new QAction(this); action->setText(i18n("Color Blocks & Symbols")); action->setCheckable(true); connect(action, &QAction::triggered, m_editor, [=]() {m_editor->renderStitchesAs(Configuration::EnumRenderer_RenderStitchesAs::ColorBlocksSymbols);}); actions->addAction(QStringLiteral("renderStitchesAsColorBlocksSymbols"), action); actionGroup->addAction(action); // ShowBackstitchesAs actionGroup = new QActionGroup(this); actionGroup->setExclusive(true); action = new QAction(this); action->setText(i18n("Color Lines")); action->setCheckable(true); action->setChecked(true); connect(action, &QAction::triggered, m_editor, [=]() {m_editor->renderBackstitchesAs(Configuration::EnumRenderer_RenderBackstitchesAs::ColorLines);}); actions->addAction(QStringLiteral("renderBackstitchesAsColorLines"), action); actionGroup->addAction(action); action = new QAction(this); action->setText(i18n("Black & White Symbols")); action->setCheckable(true); connect(action, &QAction::triggered, m_editor, [=]() {m_editor->renderBackstitchesAs(Configuration::EnumRenderer_RenderBackstitchesAs::BlackWhiteSymbols);}); actions->addAction(QStringLiteral("renderBackstitchesAsBlackWhiteSymbols"), action); actionGroup->addAction(action); // ShowKnotsAs actionGroup = new QActionGroup(this); actionGroup->setExclusive(true); action = new QAction(this); action->setText(i18n("Color Blocks")); action->setCheckable(true); action->setChecked(true); connect(action, &QAction::triggered, m_editor, [=]() {m_editor->renderKnotsAs(Configuration::EnumRenderer_RenderKnotsAs::ColorBlocks);}); actions->addAction(QStringLiteral("renderKnotsAsColorBlocks"), action); actionGroup->addAction(action); action = new QAction(this); action->setText(i18n("Color Blocks & Symbols")); action->setCheckable(true); connect(action, &QAction::triggered, m_editor, [=]() {m_editor->renderKnotsAs(Configuration::EnumRenderer_RenderKnotsAs::ColorBlocksSymbols);}); actions->addAction(QStringLiteral("renderKnotsAsColorBlocksSymbols"), action); actionGroup->addAction(action); action = new QAction(this); action->setText(i18n("Color Symbols")); action->setCheckable(true); connect(action, &QAction::triggered, m_editor, [=]() {m_editor->renderKnotsAs(Configuration::EnumRenderer_RenderKnotsAs::ColorSymbols);}); actions->addAction(QStringLiteral("renderKnotsAsColorSymbols"), action); actionGroup->addAction(action); action = new QAction(this); action->setText(i18n("Black & White Symbols")); action->setCheckable(true); connect(action, &QAction::triggered, m_editor, [=]() {m_editor->renderKnotsAs(Configuration::EnumRenderer_RenderKnotsAs::BlackWhiteSymbols);}); actions->addAction(QStringLiteral("renderKnotsAsBlackWhiteSymbols"), action); actionGroup->addAction(action); action = new QAction(this); action->setText(i18n("Color Highlight")); action->setCheckable(true); connect(action, &QAction::toggled, m_editor, &Editor::colorHighlight); actions->addAction(QStringLiteral("colorHighlight"), action); action = new QAction(this); action->setText(i18n("Show Stitches")); action->setCheckable(true); connect(action, &QAction::toggled, m_editor, static_cast(&Editor::renderStitches)); actions->addAction(QStringLiteral("renderStitches"), action); action = new QAction(this); action->setText(i18n("Show Backstitches")); action->setCheckable(true); connect(action, &QAction::toggled, m_editor, static_cast(&Editor::renderBackstitches)); actions->addAction(QStringLiteral("renderBackstitches"), action); action = new QAction(this); action->setText(i18n("Show French Knots")); action->setCheckable(true); connect(action, &QAction::toggled, m_editor, static_cast(&Editor::renderFrenchKnots)); actions->addAction(QStringLiteral("renderFrenchKnots"), action); action = new QAction(this); action->setText(i18n("Show Grid")); action->setCheckable(true); connect(action, &QAction::toggled, m_editor, static_cast(&Editor::renderGrid)); actions->addAction(QStringLiteral("renderGrid"), action); action = new QAction(this); action->setText(i18n("Show Background Images")); action->setCheckable(true); connect(action, &QAction::toggled, m_editor, static_cast(&Editor::renderBackgroundImages)); actions->addAction(QStringLiteral("renderBackgroundImages"), action); m_horizontalScale->addAction(actions->action(QStringLiteral("formatScalesAsStitches"))); m_horizontalScale->addAction(actions->action(QStringLiteral("formatScalesAsCentimeters"))); m_horizontalScale->addAction(actions->action(QStringLiteral("formatScalesAsInches"))); m_verticalScale->addAction(actions->action(QStringLiteral("formatScalesAsStitches"))); m_verticalScale->addAction(actions->action(QStringLiteral("formatScalesAsCentimeters"))); m_verticalScale->addAction(actions->action(QStringLiteral("formatScalesAsInches"))); setupGUI(KXmlGuiWindow::Default, QStringLiteral("kxstitchui.rc")); } void MainWindow::updateBackgroundImageActionLists() { auto backgroundImages = m_document->backgroundImages().backgroundImages(); unplugActionList(QStringLiteral("removeBackgroundImageActions")); unplugActionList(QStringLiteral("fitBackgroundImageActions")); unplugActionList(QStringLiteral("showBackgroundImageActions")); QList removeBackgroundImageActions; QList fitBackgroundImageActions; QList showBackgroundImageActions; while (backgroundImages.hasNext()) { QSharedPointer backgroundImage = backgroundImages.next(); QAction *action = new QAction(backgroundImage->url().fileName(), this); action->setData(QVariant::fromValue(backgroundImage)); action->setIcon(backgroundImage->icon()); connect(action, &QAction::triggered, this, &MainWindow::fileRemoveBackgroundImage); removeBackgroundImageActions.append(action); action = new QAction(backgroundImage->url().fileName(), this); action->setData(QVariant::fromValue(backgroundImage)); action->setIcon(backgroundImage->icon()); connect(action, &QAction::triggered, this, &MainWindow::viewFitBackgroundImage); fitBackgroundImageActions.append(action); action = new QAction(backgroundImage->url().fileName(), this); action->setData(QVariant::fromValue(backgroundImage)); action->setIcon(backgroundImage->icon()); action->setCheckable(true); action->setChecked(backgroundImage->isVisible()); connect(action, &QAction::triggered, this, &MainWindow::viewShowBackgroundImage); showBackgroundImageActions.append(action); } plugActionList(QStringLiteral("removeBackgroundImageActions"), removeBackgroundImageActions); plugActionList(QStringLiteral("fitBackgroundImageActions"), fitBackgroundImageActions); plugActionList(QStringLiteral("showBackgroundImageActions"), showBackgroundImageActions); } void MainWindow::setupDockWindows() { QDockWidget *dock = new QDockWidget(i18n("Preview"), this); dock->setObjectName(QStringLiteral("PreviewDock#")); dock->setAllowedAreas(Qt::AllDockWidgetAreas); QScrollArea *scrollArea = new QScrollArea(); m_preview = new Preview(scrollArea); scrollArea->setWidget(m_preview); scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn); scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); scrollArea->setMinimumSize(std::min(300, m_preview->width()), std::min(400, m_preview->height())); dock->setWidget(scrollArea); addDockWidget(Qt::LeftDockWidgetArea, dock); actionCollection()->addAction(QStringLiteral("showPreviewDockWidget"), dock->toggleViewAction()); dock = new QDockWidget(i18n("Palette"), this); dock->setObjectName(QStringLiteral("PaletteDock#")); dock->setAllowedAreas(Qt::AllDockWidgetAreas); m_palette = new Palette(this); m_palette->setContextMenuPolicy(Qt::CustomContextMenu); dock->setWidget(m_palette); addDockWidget(Qt::LeftDockWidgetArea, dock); actionCollection()->addAction(QStringLiteral("showPaletteDockWidget"), dock->toggleViewAction()); dock = new QDockWidget(i18n("History"), this); dock->setObjectName(QStringLiteral("HistoryDock#")); dock->setAllowedAreas(Qt::AllDockWidgetAreas); m_history = new QUndoView(this); dock->setWidget(m_history); addDockWidget(Qt::LeftDockWidgetArea, dock); actionCollection()->addAction(QStringLiteral("showHistoryDockWidget"), dock->toggleViewAction()); dock = new QDockWidget(i18n("Imported Image"), this); dock->setObjectName(QStringLiteral("ImportedImage#")); dock->setAllowedAreas(Qt::AllDockWidgetAreas); m_imageLabel = new ScaledPixmapLabel(this); m_imageLabel->setScaledContents(false); dock->setWidget(m_imageLabel); addDockWidget(Qt::LeftDockWidgetArea, dock); actionCollection()->addAction(QStringLiteral("showImportedDockWidget"), dock->toggleViewAction()); } diff --git a/src/Page.cpp b/src/Page.cpp index 64a3688..0169042 100644 --- a/src/Page.cpp +++ b/src/Page.cpp @@ -1,350 +1,310 @@ /* * Copyright (C) 2010-2015 by Stephen Allewell * steve.allewell@gmail.com * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. */ #include "Page.h" #include #include #include #include "Document.h" #include "Element.h" #include "Exceptions.h" #include "PaperSizes.h" -Page::Page(QPrinter::PaperSize paperSize, QPrinter::Orientation orientation) - : m_pageNumber(0), - m_paperSize(paperSize), - m_orientation(orientation), - m_margins(QMargins(Configuration::page_MarginLeft(), Configuration::page_MarginTop(), Configuration::page_MarginRight(), Configuration::page_MarginBottom())) +Page::Page(QPageSize pageSize, QPageLayout::Orientation orientation) + : QPageLayout(pageSize, orientation, QMarginsF(Configuration::page_MarginLeft(), Configuration::page_MarginTop(), Configuration::page_MarginRight(), Configuration::page_MarginBottom()), QPageLayout::Millimeter), + m_pageNumber(0) { } Page::Page(const Page &other) + : QPageLayout(other) { *this = other; } Page::~Page() { qDeleteAll(m_elements); } Page &Page::operator=(const Page &other) { if (this != &other) { qDeleteAll(m_elements); m_elements.clear(); m_pageNumber = other.m_pageNumber; - m_paperSize = other.m_paperSize; - m_orientation = other.m_orientation; - m_margins = other.m_margins; QListIterator elementIterator(other.m_elements); while (elementIterator.hasNext()) { Element *element = elementIterator.next(); if (element->type() != Element::Plan) { Element *cloned = element->clone(); cloned->setParent(this); m_elements.append(cloned); if (cloned->type() == Element::Pattern) { if (dynamic_cast(cloned)->showPlan()) { cloned = dynamic_cast(cloned)->planElement(); cloned->setParent(this); m_elements.append(cloned); } } } } } return *this; } int Page::pageNumber() const { return m_pageNumber; } -QPrinter::PaperSize Page::paperSize() const -{ - return m_paperSize; -} - - -QPrinter::Orientation Page::orientation() const -{ - return m_orientation; -} - - -const QMargins &Page::margins() const -{ - return m_margins; -} - - const QList Page::elements() const { return m_elements; } void Page::setPageNumber(int pageNumber) { m_pageNumber = pageNumber; } -void Page::setPaperSize(QPrinter::PaperSize paperSize) -{ - m_paperSize = paperSize; -} - - -void Page::setOrientation(QPrinter::Orientation orientation) -{ - m_orientation = orientation; -} - - -void Page::setMargins(const QMargins &margins) -{ - m_margins = margins; -} - - void Page::addElement(Element *element) { m_elements.append(element); } void Page::removeElement(Element *element) { m_elements.removeOne(element); } void Page::render(Document *document, QPainter *painter) const { painter->save(); if (painter->device()->paintEngine() == nullptr) { painter->setPen(QPen(Qt::red, 0.05)); - painter->drawRect(painter->window().marginsRemoved(m_margins)); + painter->drawRect(painter->window().marginsRemoved(margins().toMargins())); } QListIterator elementIterator(m_elements); while (elementIterator.hasNext()) { Element *element = elementIterator.next(); element->render(document, painter); } painter->restore(); } Element *Page::itemAt(const QPoint &pos) const { Element *element = nullptr; if (m_elements.count()) { QListIterator elementIterator(m_elements); elementIterator.toBack(); // start from the end of the list while (elementIterator.hasPrevious()) { Element *testElement = elementIterator.previous(); if (testElement->rectangle().contains(pos)) { element = testElement; break; } } } return element; // will be the element under the cursor or 0 } QDataStream &operator<<(QDataStream &stream, const Page &page) { stream << qint32(page.version); stream << qint32(page.m_pageNumber) - << qint32(page.m_paperSize) - << qint32(page.m_orientation) - << qint32(page.m_margins.left()) - << qint32(page.m_margins.top()) - << qint32(page.m_margins.right()) - << qint32(page.m_margins.bottom()) + << qint32(page.pageSize().id()) + << qint32(page.orientation()) + << qint32(page.margins().left()) + << qint32(page.margins().top()) + << qint32(page.margins().right()) + << qint32(page.margins().bottom()) << qint32(page.m_elements.count()); QListIterator elementIterator(page.m_elements); while (elementIterator.hasNext()) { const Element *element = elementIterator.next(); stream << qint32(element->type()); if (element->type() != Element::Plan) { stream << *element; } } if (stream.status() != QDataStream::Ok) { throw FailedWriteFile(stream.status()); } return stream; } QDataStream &operator>>(QDataStream &stream, Page &page) { qint32 version; qint32 pageNumber; - qint32 paperSize; + qint32 pageSizeId; qint32 orientation; qint32 left; qint32 top; qint32 right; qint32 bottom; qint32 showGrid; qint32 gridX; qint32 gridY; qreal zoomFactor; stream >> version; switch (version) { case 102: stream >> pageNumber - >> paperSize + >> pageSizeId >> orientation >> left >> top >> right >> bottom; page.m_pageNumber = pageNumber; - page.m_paperSize = static_cast(paperSize); - page.m_orientation = static_cast(orientation); - page.m_margins = QMargins(left, top, right, bottom); + page.setPageSize(QPageSize(static_cast(pageSizeId))); + page.setOrientation(static_cast(orientation)); + page.setMargins(QMarginsF(left, top, right, bottom)); page.readElements(stream); break; case 101: stream >> pageNumber - >> paperSize + >> pageSizeId >> orientation >> left >> top >> right >> bottom >> showGrid >> gridX >> gridY; page.m_pageNumber = pageNumber; - page.m_paperSize = static_cast(paperSize); - page.m_orientation = static_cast(orientation); - page.m_margins = QMargins(left, top, right, bottom); + page.setPageSize(QPageSize(static_cast(pageSizeId))); + page.setOrientation(static_cast(orientation)); + page.setMargins(QMarginsF(left, top, right, bottom)); page.readElements(stream); stream >> zoomFactor; break; case 100: - stream >> paperSize + stream >> pageSizeId >> orientation >> left >> top >> right >> bottom; - page.m_paperSize = static_cast(paperSize); - page.m_orientation = static_cast(orientation); - page.m_margins = QMargins(left, top, right, bottom); + page.setPageSize(QPageSize(static_cast(pageSizeId))); + page.setOrientation(static_cast(orientation)); + page.setMargins(QMarginsF(left, top, right, bottom)); page.readElements(stream); stream >> zoomFactor; break; default: throw InvalidFileVersion(QString(i18n("Page version %1", version))); break; } return stream; } void Page::readElements(QDataStream &stream) { qint32 elements; qint32 type; Element *element; stream >> elements; while (elements--) { stream >> type; switch (static_cast(type)) { case Element::Text: element = new TextElement(this, QRect()); break; case Element::Pattern: element = new PatternElement(this, QRect()); break; case Element::Plan: element = nullptr; // handled by the PatternElement break; case Element::Key: element = new KeyElement(this, QRect()); break; case Element::Image: element = new ImageElement(this, QRect()); break; default: throw FailedReadFile(QString(i18n("Invalid element type"))); break; } if (element) { stream >> *element; m_elements.append(element); if (element->type() == Element::Pattern) { if (dynamic_cast(element)->showPlan()) { m_elements.append(dynamic_cast(element)->planElement()); } } } } } diff --git a/src/Page.h b/src/Page.h index f2bf58c..230b106 100644 --- a/src/Page.h +++ b/src/Page.h @@ -1,75 +1,64 @@ /* * Copyright (C) 2010-2015 by Stephen Allewell * steve.allewell@gmail.com * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. */ #ifndef Page_H #define Page_H #include #include #include #include class Document; class Element; class QPainter; -class Page +class Page : public QPageLayout { public: - explicit Page(QPrinter::PaperSize paperSize = QPrinter::A4, QPrinter::Orientation orientation = QPrinter::Portrait); + explicit Page(QPageSize pageSize = QPageSize(QPageSize::A4), QPageLayout::Orientation orientation = QPageLayout::Portrait); Page(const Page &); ~Page(); Page &operator=(const Page &); int pageNumber() const; - QPrinter::PaperSize paperSize() const; - QPrinter::Orientation orientation() const; - const QMargins &margins() const; const QList elements() const; void setPageNumber(int); - void setPaperSize(QPrinter::PaperSize); - void setOrientation(QPrinter::Orientation); - void setMargins(const QMargins &); void addElement(Element *); void removeElement(Element *); void render(Document *, QPainter *) const; Element *itemAt(const QPoint &) const; friend QDataStream &operator<<(QDataStream &, const Page &); friend QDataStream &operator>>(QDataStream &, Page &); friend class PagePropertiesDlg; private: void readElements(QDataStream &); static const int version = 102; int m_pageNumber; - QPrinter::PaperSize m_paperSize; - QPrinter::Orientation m_orientation; - - QMargins m_margins; - QList m_elements; }; #endif // Page_H diff --git a/src/PagePreviewListWidgetItem.cpp b/src/PagePreviewListWidgetItem.cpp index 3bfbfa8..3929448 100644 --- a/src/PagePreviewListWidgetItem.cpp +++ b/src/PagePreviewListWidgetItem.cpp @@ -1,92 +1,92 @@ /* * Copyright (C) 2010-2015 by Stephen Allewell * steve.allewell@gmail.com * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. */ #include "PagePreviewListWidgetItem.h" #include #include #include #include #include "Page.h" #include "PaperSizes.h" PagePreviewListWidgetItem::PagePreviewListWidgetItem(Document *document, Page *page) : QListWidgetItem(0, QListWidgetItem::UserType), m_document(document), m_page(page) { generatePreviewIcon(); } -QPrinter::PaperSize PagePreviewListWidgetItem::paperSize() const +QPageSize PagePreviewListWidgetItem::pageSize() const { - return m_page->paperSize(); + return m_page->pageSize(); } -QPrinter::Orientation PagePreviewListWidgetItem::orientation() const +QPageLayout::Orientation PagePreviewListWidgetItem::orientation() const { return m_page->orientation(); } int PagePreviewListWidgetItem::paperWidth() const { return m_paperWidth; } int PagePreviewListWidgetItem::paperHeight() const { return m_paperHeight; } -void PagePreviewListWidgetItem::setPaperSize(QPrinter::PaperSize paperSize) +void PagePreviewListWidgetItem::setPageSize(QPageSize pageSize) { - m_page->setPaperSize(paperSize); + m_page->setPageSize(pageSize); generatePreviewIcon(); } -void PagePreviewListWidgetItem::setOrientation(QPrinter::Orientation orientation) +void PagePreviewListWidgetItem::setOrientation(QPageLayout::Orientation orientation) { m_page->setOrientation(orientation); generatePreviewIcon(); } Page *PagePreviewListWidgetItem::page() const { return m_page; } void PagePreviewListWidgetItem::generatePreviewIcon() { - m_paperWidth = PaperSizes::width(m_page->paperSize(), m_page->orientation()); - m_paperHeight = PaperSizes::height(m_page->paperSize(), m_page->orientation()); + m_paperWidth = PageSizes::width(m_page->pageSize().id(), m_page->orientation()); + m_paperHeight = PageSizes::height(m_page->pageSize().id(), m_page->orientation()); QPixmap pixmap(m_paperWidth, m_paperHeight); pixmap.fill(Qt::white); QPainter painter; painter.begin(&pixmap); painter.setRenderHint(QPainter::Antialiasing, true); m_page->render(m_document, &painter); painter.end(); setIcon(pixmap); } diff --git a/src/PagePreviewListWidgetItem.h b/src/PagePreviewListWidgetItem.h index 8af01b7..e292a3d 100644 --- a/src/PagePreviewListWidgetItem.h +++ b/src/PagePreviewListWidgetItem.h @@ -1,50 +1,50 @@ /* * Copyright (C) 2010-2015 by Stephen Allewell * steve.allewell@gmail.com * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. */ #ifndef PagePreviewListWidgetItem_H #define PagePreviewListWidgetItem_H #include #include class Document; class Page; class PagePreviewListWidgetItem : public QListWidgetItem { public: PagePreviewListWidgetItem(Document *, Page *); virtual ~PagePreviewListWidgetItem() = default; - QPrinter::PaperSize paperSize() const; - QPrinter::Orientation orientation() const; + QPageSize pageSize() const; + QPageLayout::Orientation orientation() const; int paperWidth() const; int paperHeight() const; - void setPaperSize(QPrinter::PaperSize); - void setOrientation(QPrinter::Orientation); + void setPageSize(QPageSize); + void setOrientation(QPageLayout::Orientation); Page *page() const; void generatePreviewIcon(); private: Document *m_document; Page *m_page; int m_paperWidth; int m_paperHeight; }; #endif // PagePreviewListWidgetItem_H diff --git a/src/PaperSizes.cpp b/src/PaperSizes.cpp index 1eb9bcc..cda75da 100644 --- a/src/PaperSizes.cpp +++ b/src/PaperSizes.cpp @@ -1,116 +1,116 @@ /* * Copyright (C) 2010-2015 by Stephen Allewell * steve.allewell@gmail.com * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. */ #include "PaperSizes.h" -const struct PaperSize { - QPrinter::PaperSize size; - QString name; - int width; - int height; -} PaperSizeList[] = { - { QPrinter::A0, QStringLiteral("A0"), 841, 1189 }, - { QPrinter::A1, QStringLiteral("A1"), 594, 841 }, - { QPrinter::A2, QStringLiteral("A2"), 420, 594 }, - { QPrinter::A3, QStringLiteral("A3"), 297, 420 }, - { QPrinter::A4, QStringLiteral("A4"), 210, 297 }, - { QPrinter::A5, QStringLiteral("A5"), 148, 210 }, - { QPrinter::A6, QStringLiteral("A6"), 105, 148 }, - { QPrinter::A7, QStringLiteral("A7"), 74, 105 }, - { QPrinter::A8, QStringLiteral("A8"), 52, 74 }, - { QPrinter::A9, QStringLiteral("A9"), 37, 52 }, - { QPrinter::B0, QStringLiteral("B0"), 1000, 1414 }, - { QPrinter::B1, QStringLiteral("B1"), 707, 1000 }, - { QPrinter::B2, QStringLiteral("B2"), 500, 707 }, - { QPrinter::B3, QStringLiteral("B3"), 353, 500 }, - { QPrinter::B4, QStringLiteral("B4"), 250, 353 }, - { QPrinter::B5, QStringLiteral("B5"), 176, 250 }, - { QPrinter::B6, QStringLiteral("B6"), 125, 176 }, - { QPrinter::B7, QStringLiteral("B7"), 88, 125 }, - { QPrinter::B8, QStringLiteral("B8"), 62, 88 }, - { QPrinter::B9, QStringLiteral("B9"), 44, 62 }, - { QPrinter::B10 , QStringLiteral("B10"), 31, 44 }, - { QPrinter::C5E, QStringLiteral("C5E"), 163, 229 }, - { QPrinter::Comm10E, QStringLiteral("Comm10E"), 105, 241 }, - { QPrinter::DLE, QStringLiteral("DLE"), 110, 220 }, - { QPrinter::Executive, QStringLiteral("Executive"),191, 254 }, - { QPrinter::Folio, QStringLiteral("Folio"), 210, 330 }, - { QPrinter::Ledger, QStringLiteral("Ledger"), 432, 279 }, - { QPrinter::Legal, QStringLiteral("Legal"), 216, 356 }, - { QPrinter::Letter, QStringLiteral("Letter"), 216, 279 }, - { QPrinter::Tabloid, QStringLiteral("Tabloid"), 279, 432 }, - { QPrinter::Custom, QStringLiteral("Unknown"), 0, 0 } +const struct PageSize { + QPageSize::PageSizeId size; + QString name; + int width; + int height; +} PageSizeList[] = { + { QPageSize::A0, QStringLiteral("A0"), 841, 1189 }, + { QPageSize::A1, QStringLiteral("A1"), 594, 841 }, + { QPageSize::A2, QStringLiteral("A2"), 420, 594 }, + { QPageSize::A3, QStringLiteral("A3"), 297, 420 }, + { QPageSize::A4, QStringLiteral("A4"), 210, 297 }, + { QPageSize::A5, QStringLiteral("A5"), 148, 210 }, + { QPageSize::A6, QStringLiteral("A6"), 105, 148 }, + { QPageSize::A7, QStringLiteral("A7"), 74, 105 }, + { QPageSize::A8, QStringLiteral("A8"), 52, 74 }, + { QPageSize::A9, QStringLiteral("A9"), 37, 52 }, + { QPageSize::B0, QStringLiteral("B0"), 1000, 1414 }, + { QPageSize::B1, QStringLiteral("B1"), 707, 1000 }, + { QPageSize::B2, QStringLiteral("B2"), 500, 707 }, + { QPageSize::B3, QStringLiteral("B3"), 353, 500 }, + { QPageSize::B4, QStringLiteral("B4"), 250, 353 }, + { QPageSize::B5, QStringLiteral("B5"), 176, 250 }, + { QPageSize::B6, QStringLiteral("B6"), 125, 176 }, + { QPageSize::B7, QStringLiteral("B7"), 88, 125 }, + { QPageSize::B8, QStringLiteral("B8"), 62, 88 }, + { QPageSize::B9, QStringLiteral("B9"), 44, 62 }, + { QPageSize::B10 , QStringLiteral("B10"), 31, 44 }, + { QPageSize::C5E, QStringLiteral("C5E"), 163, 229 }, + { QPageSize::Comm10E, QStringLiteral("Comm10E"), 105, 241 }, + { QPageSize::DLE, QStringLiteral("DLE"), 110, 220 }, + { QPageSize::Executive, QStringLiteral("Executive"),191, 254 }, + { QPageSize::Folio, QStringLiteral("Folio"), 210, 330 }, + { QPageSize::Ledger, QStringLiteral("Ledger"), 432, 279 }, + { QPageSize::Legal, QStringLiteral("Legal"), 216, 356 }, + { QPageSize::Letter, QStringLiteral("Letter"), 216, 279 }, + { QPageSize::Tabloid, QStringLiteral("Tabloid"), 279, 432 }, + { QPageSize::Custom, QStringLiteral("Unknown"), 0, 0 } }; -QPrinter::PaperSize PaperSizes::size(const QString &name) +QPageSize::PageSizeId PageSizes::size(const QString &name) { int i = 0; - while (PaperSizeList[i].size != QPrinter::Custom) { - if (PaperSizeList[i].name == name) { + while (PageSizeList[i].size != QPageSize::Custom) { + if (PageSizeList[i].name == name) { break; } ++i; } - return PaperSizeList[i].size; // will return QPrinter::Custom if name isn't found + return PageSizeList[i].size; // will return QPageSize::Custom if name isn't found } -QString PaperSizes::name(QPrinter::PaperSize size) +QString PageSizes::name(QPageSize::PageSizeId size) { int i = 0; - while (PaperSizeList[i].size != QPrinter::Custom) { - if (PaperSizeList[i].size == size) { + while (PageSizeList[i].size != QPageSize::Custom) { + if (PageSizeList[i].size == size) { break; } ++i; } - return PaperSizeList[i].name; + return PageSizeList[i].name; } -int PaperSizes::width(QPrinter::PaperSize size, QPrinter::Orientation orientation) +int PageSizes::width(QPageSize::PageSizeId size, QPageLayout::Orientation orientation) { int i = 0; - while (PaperSizeList[i].size != QPrinter::Custom) { - if (PaperSizeList[i].size == size) { + while (PageSizeList[i].size != QPageSize::Custom) { + if (PageSizeList[i].size == size) { break; } ++i; } - return (orientation == QPrinter::Portrait) ? PaperSizeList[i].width : PaperSizeList[i].height; + return (orientation == QPageLayout::Portrait) ? PageSizeList[i].width : PageSizeList[i].height; } -int PaperSizes::height(QPrinter::PaperSize size, QPrinter::Orientation orientation) +int PageSizes::height(QPageSize::PageSizeId size, QPageLayout::Orientation orientation) { int i = 0; - while (PaperSizeList[i].size != QPrinter::Custom) { - if (PaperSizeList[i].size == size) { + while (PageSizeList[i].size != QPageSize::Custom) { + if (PageSizeList[i].size == size) { break; } ++i; } - return (orientation == QPrinter::Portrait) ? PaperSizeList[i].height : PaperSizeList[i].width; + return (orientation == QPageLayout::Portrait) ? PageSizeList[i].height : PageSizeList[i].width; } diff --git a/src/PaperSizes.h b/src/PaperSizes.h index f390c66..4190101 100644 --- a/src/PaperSizes.h +++ b/src/PaperSizes.h @@ -1,29 +1,29 @@ /* * Copyright (C) 2010-2015 by Stephen Allewell * steve.allewell@gmail.com * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. */ #ifndef PaperSizes_H #define PaperSizes_H -#include +#include -class PaperSizes +class PageSizes { public: - static QPrinter::PaperSize size(const QString &); - static QString name(QPrinter::PaperSize); - static int width(QPrinter::PaperSize, QPrinter::Orientation); - static int height(QPrinter::PaperSize, QPrinter::Orientation); + static QPageSize::PageSizeId size(const QString &); + static QString name(QPageSize::PageSizeId); + static int width(QPageSize::PageSizeId, QPageLayout::Orientation); + static int height(QPageSize::PageSizeId, QPageLayout::Orientation); }; #endif // PaperSizes_H diff --git a/src/PrintSetupDlg.cpp b/src/PrintSetupDlg.cpp index 5e9af19..36d9885 100644 --- a/src/PrintSetupDlg.cpp +++ b/src/PrintSetupDlg.cpp @@ -1,608 +1,608 @@ /* * Copyright (C) 2010-2015 by Stephen Allewell * steve.allewell@gmail.com * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. */ #include "PrintSetupDlg.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include "Document.h" #include "Element.h" #include "ImageElementDlg.h" #include "KeyElementDlg.h" #include "Page.h" #include "PageLayoutEditor.h" #include "PagePropertiesDlg.h" #include "PaperSizes.h" #include "PatternElementDlg.h" #include "TextElementDlg.h" static const double zoomFactors[] = {0.25, 0.5, 1.0, 1.5, 2.0, 4.0, 8.0, 16.0}; PrintSetupDlg::PrintSetupDlg(QWidget *parent, Document *document, QPrinter *printer) : QDialog(parent), m_printerConfiguration(document->printerConfiguration()), m_elementUnderCursor(0), m_document(document), m_printer(printer) { setWindowModality(Qt::WindowModal); - + setWindowTitle(i18n("Print Setup")); ui.setupUi(this); m_pageLayoutEditor = new PageLayoutEditor(ui.PagePreview, m_document); ui.PagePreview->setWidget(m_pageLayoutEditor); ui.AddPage->setIcon(QIcon::fromTheme(QStringLiteral("document-new"))); ui.InsertPage->setIcon(QIcon::fromTheme(QStringLiteral("document-import"))); ui.DeletePage->setIcon(QIcon::fromTheme(QStringLiteral("document-close"))); ui.SelectElement->setIcon(QIcon::fromTheme(QStringLiteral("edit-select"))); ui.TextElement->setIcon(QIcon::fromTheme(QStringLiteral("insert-text"))); ui.PatternElement->setIcon(QIcon::fromTheme(QStringLiteral("insert-table"))); ui.ImageElement->setIcon(QIcon::fromTheme(QStringLiteral("insert-image"))); ui.KeyElement->setIcon(QIcon::fromTheme(QStringLiteral("documentation"))); m_buttonGroup.addButton(ui.SelectElement); m_buttonGroup.addButton(ui.TextElement); m_buttonGroup.addButton(ui.PatternElement); m_buttonGroup.addButton(ui.ImageElement); m_buttonGroup.addButton(ui.KeyElement); m_buttonGroup.setExclusive(true); connect(m_pageLayoutEditor, &PageLayoutEditor::selectionMade, this, &PrintSetupDlg::selectionMade); connect(m_pageLayoutEditor, &PageLayoutEditor::elementGeometryChanged, this, &PrintSetupDlg::elementGeometryChanged); connect(m_pageLayoutEditor, &PageLayoutEditor::customContextMenuRequested, this, &PrintSetupDlg::previewContextMenuRequested); - ui.PaperSize->setCurrentIndex(Configuration::page_Size()); + ui.PageSize->setCurrentIndex(Configuration::page_Size()); ui.Orientation->setCurrentIndex(Configuration::page_Orientation()); ui.Zoom->setCurrentIndex(4); // 200% ui.SelectElement->click(); // select mode } PrintSetupDlg::~PrintSetupDlg() { delete m_pageLayoutEditor; } const PrinterConfiguration &PrintSetupDlg::printerConfiguration() const { return m_printerConfiguration; } void PrintSetupDlg::hideEvent(QHideEvent *event) { KConfigGroup(KSharedConfig::openConfig(), QStringLiteral("DialogSizes")).writeEntry(QStringLiteral("PrintSetupDlg"), size()); QDialog::hideEvent(event); } void PrintSetupDlg::showEvent(QShowEvent *event) { QDialog::showEvent(event); if (KConfigGroup(KSharedConfig::openConfig(), QStringLiteral("DialogSizes")).hasKey(QStringLiteral("PrintSetupDlg"))) { resize(KConfigGroup(KSharedConfig::openConfig(), QStringLiteral("DialogSizes")).readEntry(QStringLiteral("PrintSetupDlg"), QSize())); } if (ui.Pages->count() == 0) { initialiseFromConfig(); } if (ui.Pages->count()) { ui.Pages->setCurrentRow(0); } else { on_AddPage_clicked(); } } -void PrintSetupDlg::on_PaperSize_currentIndexChanged(const QString &paperSize) +void PrintSetupDlg::on_PageSize_currentIndexChanged(const QString &pageSize) { if (ui.Pages->count() && ui.Pages->currentItem()) { PagePreviewListWidgetItem *pagePreview = static_cast(ui.Pages->currentItem()); - pagePreview->setPaperSize(PaperSizes::size(paperSize)); + pagePreview->setPageSize(QPageSize(PageSizes::size(pageSize))); m_pageLayoutEditor->updatePagePreview(); ui.Pages->repaint(); } } void PrintSetupDlg::on_Orientation_currentIndexChanged(int orientation) { if (ui.Pages->count() && ui.Pages->currentItem()) { PagePreviewListWidgetItem *pagePreview = static_cast(ui.Pages->currentItem()); - pagePreview->setOrientation((orientation == 0) ? QPrinter::Portrait : QPrinter::Landscape); + pagePreview->setOrientation((orientation == 0) ? QPageLayout::Portrait : QPageLayout::Landscape); m_pageLayoutEditor->updatePagePreview(); ui.Pages->repaint(); } } void PrintSetupDlg::on_Zoom_currentIndexChanged(int zoomIndex) { m_pageLayoutEditor->setZoomFactor(zoomFactors[zoomIndex]); m_pageLayoutEditor->updatePagePreview(); } void PrintSetupDlg::on_Pages_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous) { Q_UNUSED(previous); if (current) { PagePreviewListWidgetItem *pagePreview = static_cast(current); m_pageLayoutEditor->setPagePreview(pagePreview); - ui.PaperSize->setCurrentItem(PaperSizes::name(pagePreview->paperSize())); - ui.Orientation->setCurrentIndex((pagePreview->orientation() == QPrinter::Portrait) ? 0 : 1); + ui.PageSize->setCurrentItem(PageSizes::name(pagePreview->pageSize().id())); + ui.Orientation->setCurrentIndex((pagePreview->orientation() == QPageLayout::Portrait) ? 0 : 1); ui.InsertPage->setEnabled(true); ui.DeletePage->setEnabled(true); } else { m_pageLayoutEditor->setPagePreview(nullptr); ui.InsertPage->setEnabled(false); ui.DeletePage->setEnabled(false); } } void PrintSetupDlg::on_AddPage_clicked() { - Page *page = new Page(selectedPaperSize(), selectedOrientation()); + Page *page = new Page(selectedPageSize(), selectedOrientation()); m_printerConfiguration.addPage(page); addPage(ui.Pages->count(), page); } void PrintSetupDlg::on_InsertPage_clicked() { - Page *page = new Page(selectedPaperSize(), selectedOrientation()); + Page *page = new Page(selectedPageSize(), selectedOrientation()); m_printerConfiguration.insertPage(ui.Pages->currentRow(), page); addPage(ui.Pages->currentRow(), page); } void PrintSetupDlg::on_DeletePage_clicked() { if (ui.Pages->count() && ui.Pages->currentItem()) { int currentRow = ui.Pages->row(ui.Pages->currentItem()); PagePreviewListWidgetItem *pagePreview = static_cast(ui.Pages->takeItem(currentRow)); m_printerConfiguration.removePage(pagePreview->page()); delete pagePreview->page(); delete pagePreview; if (int rows = ui.Pages->count()) { ui.Pages->setCurrentRow(std::min(currentRow, rows - 1)); } else { on_Pages_currentItemChanged(0, 0); } } updatePageNumbers(); } void PrintSetupDlg::on_SelectElement_clicked() { m_elementMode = Select; m_pageLayoutEditor->setSelecting(true); } void PrintSetupDlg::on_TextElement_clicked() { m_elementMode = Text; m_pageLayoutEditor->setSelecting(false); } void PrintSetupDlg::on_PatternElement_clicked() { m_elementMode = Pattern; m_pageLayoutEditor->setSelecting(false); } void PrintSetupDlg::on_ImageElement_clicked() { m_elementMode = Image; m_pageLayoutEditor->setSelecting(false); } void PrintSetupDlg::on_KeyElement_clicked() { m_elementMode = Key; m_pageLayoutEditor->setSelecting(false); } void PrintSetupDlg::on_DialogButtonBox_accepted() { accept(); } void PrintSetupDlg::on_DialogButtonBox_rejected() { reject(); } void PrintSetupDlg::on_DialogButtonBox_helpRequested() { KHelpClient::invokeHelp(QStringLiteral("PrinterDialog"), QStringLiteral("kxstitch")); } void PrintSetupDlg::selectionMade(const QRect &rectangle) { PagePreviewListWidgetItem *pagePreview = static_cast(ui.Pages->currentItem()); Page *page = pagePreview->page(); PatternElement *patternElement; ImageElement *imageElement; switch (m_elementMode) { case Text: page->addElement(new TextElement(page, rectangle)); break; case Pattern: patternElement = new PatternElement(page, rectangle); page->addElement(patternElement); patternElement->setPatternRect(QRect(0, 0, m_document->pattern()->stitches().width(), m_document->pattern()->stitches().height())); break; case Image: imageElement = new ImageElement(page, rectangle); page->addElement(imageElement); imageElement->setPatternRect(QRect(0, 0, m_document->pattern()->stitches().width(), m_document->pattern()->stitches().height())); break; case Key: page->addElement(new KeyElement(page, rectangle)); break; default: break; } pagePreview->generatePreviewIcon(); m_pageLayoutEditor->update(); ui.SelectElement->click(); // select mode } void PrintSetupDlg::elementGeometryChanged() { if (ui.Pages->currentItem()) { PagePreviewListWidgetItem *pagePreview = static_cast(ui.Pages->currentItem()); pagePreview->generatePreviewIcon(); } } void PrintSetupDlg::previewContextMenuRequested(const QPoint &pos) { PagePreviewListWidgetItem *pagePreview = static_cast(ui.Pages->currentItem()); if (pagePreview) { m_elementUnderCursor = pagePreview->page()->itemAt(m_pageLayoutEditor->unscale(pos)); QMenu *contextMenu = new QMenu(this); if (m_elementUnderCursor == nullptr || m_elementUnderCursor->type() != Element::Plan) { contextMenu->addAction(i18n("Properties"), this, &PrintSetupDlg::properties); if (m_elementUnderCursor) { contextMenu->addSeparator(); contextMenu->addAction(i18n("Delete Element"), this, &PrintSetupDlg::deleteElement); } } if (contextMenu->isEmpty()) { delete contextMenu; } else { contextMenu->popup(m_pageLayoutEditor->mapToGlobal(pos)); } } } void PrintSetupDlg::properties() { PagePreviewListWidgetItem *pagePreview = static_cast(ui.Pages->currentItem()); bool updatePreviews = false; if (m_elementUnderCursor) { if (m_elementUnderCursor->type() == Element::Text) { QPointer textElementDlg = new TextElementDlg(this, static_cast(m_elementUnderCursor)); updatePreviews = (textElementDlg->exec() == QDialog::Accepted); delete textElementDlg; } if (m_elementUnderCursor->type() == Element::Pattern) { QMap > patternRects; QListIterator pageIterator(m_printerConfiguration.pages()); while (pageIterator.hasNext()) { Page *page = pageIterator.next(); QListIterator elementIterator(page->elements()); while (elementIterator.hasNext()) { Element *element = elementIterator.next(); if (element->type() == Element::Pattern) { patternRects[page->pageNumber()].append(static_cast(element)->patternRect()); } } } QPointer patternElementDlg = new PatternElementDlg(this, static_cast(m_elementUnderCursor), m_document, patternRects); if (patternElementDlg->exec() == QDialog::Accepted) { updatePreviews = true; if (patternElementDlg->showPlan() && !pagePreview->page()->elements().contains(patternElementDlg->planElement())) { pagePreview->page()->addElement(patternElementDlg->planElement()); } else if (!patternElementDlg->showPlan() && pagePreview->page()->elements().contains(patternElementDlg->planElement())) { pagePreview->page()->removeElement(patternElementDlg->planElement()); } } delete patternElementDlg; } if (m_elementUnderCursor->type() == Element::Image) { QPointer imageElementDlg = new ImageElementDlg(this, static_cast(m_elementUnderCursor), m_document); updatePreviews = (imageElementDlg->exec() == QDialog::Accepted); delete imageElementDlg; } if (m_elementUnderCursor->type() == Element::Key) { QPointer keyElementDlg = new KeyElementDlg(this, static_cast(m_elementUnderCursor)); updatePreviews = (keyElementDlg->exec() == QDialog::Accepted); delete keyElementDlg; } } else { - QPointer pagePropertiesDlg = new PagePropertiesDlg(this, pagePreview->page()->margins(), m_pageLayoutEditor->showGrid(), m_pageLayoutEditor->gridSize()); + QPointer pagePropertiesDlg = new PagePropertiesDlg(this, pagePreview->page()->margins().toMargins(), m_pageLayoutEditor->showGrid(), m_pageLayoutEditor->gridSize()); if (pagePropertiesDlg->exec() == QDialog::Accepted) { updatePreviews = true; pagePreview->page()->setMargins(pagePropertiesDlg->margins()); m_pageLayoutEditor->setShowGrid(pagePropertiesDlg->showGrid()); m_pageLayoutEditor->setGridSize(pagePropertiesDlg->gridSize()); } } if (updatePreviews) { PagePreviewListWidgetItem *pagePreview = static_cast(ui.Pages->currentItem()); m_pageLayoutEditor->update(); pagePreview->generatePreviewIcon(); } } void PrintSetupDlg::deleteElement() { PagePreviewListWidgetItem *pagePreview = static_cast(ui.Pages->currentItem()); pagePreview->page()->removeElement(m_elementUnderCursor); m_pageLayoutEditor->update(); pagePreview->generatePreviewIcon(); } void PrintSetupDlg::initialiseFromConfig() { QListIterator pageIterator(m_printerConfiguration.pages()); while (pageIterator.hasNext()) { addPage(ui.Pages->count(), pageIterator.next()); } } void PrintSetupDlg::addPage(int position, Page *page) { PagePreviewListWidgetItem *pagePreview = new PagePreviewListWidgetItem(m_document, page); ui.Pages->insertItem(position, pagePreview); ui.Pages->setCurrentRow(position); updatePageNumbers(); } -QPrinter::PaperSize PrintSetupDlg::selectedPaperSize() +QPageSize PrintSetupDlg::selectedPageSize() { - return PaperSizes::size(ui.PaperSize->currentText()); + return QPageSize(PageSizes::size(ui.PageSize->currentText())); } -QPrinter::Orientation PrintSetupDlg::selectedOrientation() +QPageLayout::Orientation PrintSetupDlg::selectedOrientation() { - return (ui.Orientation->currentIndex() == 0) ? QPrinter::Portrait : QPrinter::Landscape; + return (ui.Orientation->currentIndex() == 0) ? QPageLayout::Portrait : QPageLayout::Landscape; } double PrintSetupDlg::selectedZoom() { return zoomFactors[ui.Zoom->currentIndex()]; } void PrintSetupDlg::updatePageNumbers() { for (int i = 0 ; i < ui.Pages->count() ; ++i) { PagePreviewListWidgetItem *pagePreview = dynamic_cast(ui.Pages->item(i)); pagePreview->setText(i18n("Page %1 of %2", pagePreview->page()->pageNumber(), ui.Pages->count())); } } void PrintSetupDlg::on_Templates_clicked() { // QString templateName = qobject_cast(sender())->data().toString(); bool okToCreate = true; if (!m_printerConfiguration.isEmpty()) { okToCreate = (KMessageBox::questionYesNo(this, i18n("Overwrite the current configuration?"), i18n("Overwrite")) == KMessageBox::Yes); } if (okToCreate) { // TODO this section is currently a hack to allow creation of a printerConfiguration // based on the KDE3 version of KXStitch. It is intended to create a template based // functionality so that various templates can be created and selected as required. // clear the current configuration m_printerConfiguration = PrinterConfiguration(); ui.Pages->clear(); // create pages based on template // Cover sheet QFont titleFont; titleFont.setPointSize(16); QFont pageFont; pageFont.setPointSize(8); - Page *page = new Page(QPrinter::A4, QPrinter::Portrait); + Page *page = new Page(QPageSize(QPageSize::A4), QPageLayout::Portrait); m_printerConfiguration.addPage(page); addPage(ui.Pages->count(), page); QRect printableArea(page->margins().left(), page->margins().top(), 210 - page->margins().left() - page->margins().right(), 297 - page->margins().top() - page->margins().bottom()); QRect headerTitleArea(printableArea.topLeft(), QSize(printableArea.width(), 10)); QRect patternArea(headerTitleArea.bottomLeft() + QPoint(0, 5), QSize(printableArea.width(), printableArea.height() - 10 - 35)); QRect mapArea(patternArea.bottomRight() - QPoint(30, 5), QSize(30, 30)); QRect pageNumberArea(printableArea.bottomLeft() - QPoint(0, 10), QSize(printableArea.width(), 10)); Element *element = new TextElement(page, QRect(printableArea.topLeft(), QSize(printableArea.width(), 30))); static_cast(element)->setTextFont(titleFont); static_cast(element)->setAlignment(Qt::AlignCenter); static_cast(element)->setText(QStringLiteral("${title}")); page->addElement(element); element = new ImageElement(page, QRect(printableArea.topLeft() + QPoint(0, 60), QSize(printableArea.width(), printableArea.height() / 3))); static_cast(element)->setPatternRect(QRect(0, 0, m_document->pattern()->stitches().width(), m_document->pattern()->stitches().height())); static_cast(element)->setShowBorder(true); static_cast(element)->setBorderThickness(2); page->addElement(element); element = new TextElement(page, QRect(printableArea.topLeft() + QPoint(20, 60 + printableArea.height() / 3 + 5), QSize(printableArea.width() - 40, 60))); static_cast(element)->setAlignment(Qt::AlignTop | Qt::AlignLeft); static_cast(element)->setText(i18nc("Do not translate elements in ${...} which are substituted by properties", "Created by ${author}\n(C) ${copyright}\n\nPattern Size: ${width.stitches} x ${height.stitches}\nFlosses from the ${scheme} range.")); page->addElement(element); element = new TextElement(page, pageNumberArea); static_cast(element)->setTextFont(pageFont); static_cast(element)->setAlignment(Qt::AlignCenter); static_cast(element)->setText(i18nc("Do not translate elements in ${...} which are substituted by properties", "Page ${page}")); page->addElement(element); // pattern sheets int documentWidth = m_document->pattern()->stitches().width(); int documentHeight = m_document->pattern()->stitches().height(); // calculate the aspect ratio and the size of the cells to fit within the rectangle and the overall paint area size double cellWidth = Configuration::patternElement_MinimumCellSize(); // mm double aspect = m_document->property(QStringLiteral("horizontalClothCount")).toDouble() / m_document->property(QStringLiteral("verticalClothCount")).toDouble(); double cellHeight = cellWidth * aspect; if (cellHeight < cellWidth) { cellHeight = cellWidth; cellWidth = cellHeight / aspect; } // at this point, based on a minimum preferred cell size a physical width and height have been calculated // which can be used to calculate the number of pages wide and tall that the pattern needs to occupy // based on the size of the pattern area on the page. int horizontalCellsPerPage = int(double(patternArea.width()) / cellWidth); int verticalCellsPerPage = int(double(patternArea.height()) / cellHeight); int pagesWide = (documentWidth / horizontalCellsPerPage) + (((documentWidth % horizontalCellsPerPage) < Configuration::patternElement_MinimumOverflow()) ? 0 : 1); int pagesTall = (documentHeight / verticalCellsPerPage) + (((documentHeight % verticalCellsPerPage) < Configuration::patternElement_MinimumOverflow()) ? 0 : 1); // the number of pages wide and tall has been calculated based on the minimum cell size. // try and make use of the available space across the pages expanding the cell size to fill the space. horizontalCellsPerPage = (documentWidth / pagesWide) + ((documentWidth % pagesWide) ? 1 : 0); // equal number per page verticalCellsPerPage = (documentHeight / pagesTall) + ((documentHeight % pagesTall) ? 1 : 0); // equal number per page for (int verticalPage = 0 ; verticalPage < pagesTall ; ++verticalPage) { for (int horizontalPage = 0 ; horizontalPage < pagesWide ; ++horizontalPage) { - page = new Page(QPrinter::A4, QPrinter::Portrait); + page = new Page(QPageSize(QPageSize::A4), QPageLayout::Portrait); m_printerConfiguration.addPage(page); addPage(ui.Pages->count(), page); element = new TextElement(page, headerTitleArea); static_cast(element)->setTextFont(titleFont); static_cast(element)->setAlignment(Qt::AlignCenter); static_cast(element)->setText(QStringLiteral("${title}")); page->addElement(element); element = new PatternElement(page, patternArea); static_cast(element)->setPatternRect(QRect(horizontalPage * horizontalCellsPerPage, verticalPage * verticalCellsPerPage, std::min(horizontalCellsPerPage, documentWidth - (horizontalCellsPerPage * horizontalPage)), std::min(verticalCellsPerPage, documentHeight - (verticalCellsPerPage * verticalPage)))); static_cast(element)->setShowScales(true); static_cast(element)->setRenderStitchesAs(Configuration::EnumRenderer_RenderStitchesAs::BlackWhiteSymbols); static_cast(element)->setRenderBackstitchesAs(Configuration::EnumRenderer_RenderBackstitchesAs::BlackWhiteSymbols); static_cast(element)->setRenderKnotsAs(Configuration::EnumRenderer_RenderKnotsAs::BlackWhiteSymbols); page->addElement(element); element = new TextElement(page, pageNumberArea); static_cast(element)->setTextFont(pageFont); static_cast(element)->setAlignment(Qt::AlignCenter); static_cast(element)->setText(i18nc("Do not translate elements in ${...} which are substituted by properties", "Page ${page}")); page->addElement(element); } } // key page - page = new Page(QPrinter::A4, QPrinter::Portrait); + page = new Page(QPageSize(QPageSize::A4), QPageLayout::Portrait); m_printerConfiguration.addPage(page); addPage(ui.Pages->count(), page); element = new TextElement(page, headerTitleArea); static_cast(element)->setTextFont(titleFont); static_cast(element)->setAlignment(Qt::AlignCenter); static_cast(element)->setText(QStringLiteral("${title}")); page->addElement(element); element = new KeyElement(page, patternArea.adjusted(20, 0, -20, 0)); page->addElement(element); element = new TextElement(page, pageNumberArea); static_cast(element)->setTextFont(titleFont); static_cast(element)->setAlignment(Qt::AlignCenter); static_cast(element)->setText(i18nc("Do not translate elements in ${...} which are substituted by properties", "Page ${page}")); page->addElement(element); for (int i = 0 ; i < ui.Pages->count() ; ++i) { static_cast(ui.Pages->item(i))->generatePreviewIcon(); } } } diff --git a/src/PrintSetupDlg.h b/src/PrintSetupDlg.h index 33c007c..580b224 100644 --- a/src/PrintSetupDlg.h +++ b/src/PrintSetupDlg.h @@ -1,101 +1,101 @@ /* * Copyright (C) 2010-2015 by Stephen Allewell * steve.allewell@gmail.com * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. */ #ifndef PrintSetupDlg_H #define PrintSetupDlg_H #include #include #include #include "PagePreviewListWidgetItem.h" #include "PrinterConfiguration.h" #include "ui_PrintSetup.h" class QHideEvent; class QResizeEvent; class QShowEvent; class QString; class Document; class Element; class PageLayoutEditor; class PrintSetupDlg : public QDialog { Q_OBJECT public: PrintSetupDlg(QWidget *, Document *, QPrinter *); virtual ~PrintSetupDlg(); const PrinterConfiguration &printerConfiguration() const; protected: virtual void hideEvent(QHideEvent *) Q_DECL_OVERRIDE; virtual void showEvent(QShowEvent *) Q_DECL_OVERRIDE; private slots: - void on_PaperSize_currentIndexChanged(const QString &); + void on_PageSize_currentIndexChanged(const QString &); void on_Orientation_currentIndexChanged(int); void on_Zoom_currentIndexChanged(int); void on_Pages_currentItemChanged(QListWidgetItem *, QListWidgetItem *); void on_Templates_clicked(); void on_AddPage_clicked(); void on_InsertPage_clicked(); void on_DeletePage_clicked(); void on_SelectElement_clicked(); void on_TextElement_clicked(); void on_PatternElement_clicked(); void on_ImageElement_clicked(); void on_KeyElement_clicked(); void on_DialogButtonBox_accepted(); void on_DialogButtonBox_rejected(); void on_DialogButtonBox_helpRequested(); void selectionMade(const QRect &); void elementGeometryChanged(); void previewContextMenuRequested(const QPoint &); void properties(); void deleteElement(); private: enum ElementMode {Select, Text, Pattern, Key, Image}; void initialiseFromConfig(); void addPage(int, Page *); void updatePageNumbers(); // void selectTemplate(); - QPrinter::PaperSize selectedPaperSize(); - QPrinter::Orientation selectedOrientation(); + QPageSize selectedPageSize(); + QPageLayout::Orientation selectedOrientation(); double selectedZoom(); Ui::PrintSetup ui; PrinterConfiguration m_printerConfiguration; double m_scale; QButtonGroup m_buttonGroup; ElementMode m_elementMode; Element *m_elementUnderCursor; Document *m_document; QPrinter *m_printer; PageLayoutEditor *m_pageLayoutEditor; }; #endif // PrintSetupDlg_H diff --git a/ui/PrintSetup.ui b/ui/PrintSetup.ui index 6780ac7..b1abf42 100644 --- a/ui/PrintSetup.ui +++ b/ui/PrintSetup.ui @@ -1,678 +1,678 @@ PrintSetup 0 0 700 550 700 550 Print Setup 0 24 0 24 16777215 24 9 Pages 24 24 24 24 Create a default layout ... QToolButton::DelayedPopup Qt::NoArrow 0 0 24 24 24 24 18 Append a page 22 22 0 0 24 24 24 24 18 Insert a page before the selected page 22 22 0 0 24 24 24 24 18 Delete the selected page 22 22 - + 0 0 Select a paper size A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 C5E Comm10E DLE Executive Folio Ledger Legal Letter Tabloid 0 0 Select the paper orientation Portrait Landscape 0 0 Zoom factor 25% 50% 100% 150% 200% 400% 800% 1600% Qt::Horizontal 40 20 Select an element ... 22 22 true false Insert a text element ... 22 22 true false Insert a pattern element ... 22 22 true Insert a picture element ... Insert a key element ... 22 22 true 0 100 200 16777215 214 210 208 214 210 208 244 244 244 Page list 140 140 170 170 QListView::IconMode 100 100 Page preview Qt::ScrollBarAlwaysOn Qt::ScrollBarAlwaysOn false Qt::AlignCenter - 8 - 21 + 4 + 0 450 450 QDialogButtonBox::Cancel|QDialogButtonBox::Help|QDialogButtonBox::Ok KComboBox QComboBox
kcombobox.h