diff --git a/src/app/core/vapplication.h b/src/app/core/vapplication.h index e7f074944..da5df856d 100644 --- a/src/app/core/vapplication.h +++ b/src/app/core/vapplication.h @@ -279,7 +279,7 @@ inline void VApplication::setCurrentDocument(VPattern *doc) inline VPattern *VApplication::getCurrentDocument() const { SCASSERT(doc != nullptr) - return doc; + return doc; } #endif // VAPPLICATION_H diff --git a/src/app/main.cpp b/src/app/main.cpp index 1bf5555fb..d5f8dcaa5 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -51,6 +51,7 @@ int main(int argc, char *argv[]) Q_INIT_RESOURCE(schema); Q_INIT_RESOURCE(theme); Q_INIT_RESOURCE(flags); + Q_INIT_RESOURCE(icons); QT_REQUIRE_VERSION(argc, argv, "5.0.0"); diff --git a/src/app/options.h b/src/app/options.h index 57380992a..9ea81af9c 100644 --- a/src/app/options.h +++ b/src/app/options.h @@ -30,6 +30,7 @@ #define OPTIONS_H #include "../libs/ifc/ifcdef.h" +#include "../../utils/def.h" #ifdef Q_OS_WIN32 # if defined( Q_CC_MSVC ) // MSVC USED diff --git a/src/app/share/resources/icon.qrc b/src/app/share/resources/icon.qrc index 329cd555f..439657321 100644 --- a/src/app/share/resources/icon.qrc +++ b/src/app/share/resources/icon.qrc @@ -55,5 +55,6 @@ icon/16x16/landscape.png icon/16x16/portrait.png icon/16x16/template.png + icon/32x32/pdf.png diff --git a/src/app/share/resources/icon/32x32/pdf.png b/src/app/share/resources/icon/32x32/pdf.png new file mode 100644 index 000000000..0c65ce2ff Binary files /dev/null and b/src/app/share/resources/icon/32x32/pdf.png differ diff --git a/src/app/share/resources/icons/win.icon.theme/16x16/actions/document-print-preview.png b/src/app/share/resources/icons/win.icon.theme/16x16/actions/document-print-preview.png new file mode 100644 index 000000000..7441695cd Binary files /dev/null and b/src/app/share/resources/icons/win.icon.theme/16x16/actions/document-print-preview.png differ diff --git a/src/app/share/resources/icons/win.icon.theme/16x16/actions/document-print.png b/src/app/share/resources/icons/win.icon.theme/16x16/actions/document-print.png new file mode 100644 index 000000000..9fdc4d6bd Binary files /dev/null and b/src/app/share/resources/icons/win.icon.theme/16x16/actions/document-print.png differ diff --git a/src/app/share/resources/icons/win.icon.theme/24x24/actions/document-print-preview.png b/src/app/share/resources/icons/win.icon.theme/24x24/actions/document-print-preview.png new file mode 100755 index 000000000..ce9285b78 Binary files /dev/null and b/src/app/share/resources/icons/win.icon.theme/24x24/actions/document-print-preview.png differ diff --git a/src/app/share/resources/icons/win.icon.theme/24x24/actions/document-print.png b/src/app/share/resources/icons/win.icon.theme/24x24/actions/document-print.png new file mode 100755 index 000000000..07daa41eb Binary files /dev/null and b/src/app/share/resources/icons/win.icon.theme/24x24/actions/document-print.png differ diff --git a/src/app/share/resources/icons/win.icon.theme/32x32/actions/document-print-preview.png b/src/app/share/resources/icons/win.icon.theme/32x32/actions/document-print-preview.png new file mode 100644 index 000000000..d28c6e999 Binary files /dev/null and b/src/app/share/resources/icons/win.icon.theme/32x32/actions/document-print-preview.png differ diff --git a/src/app/share/resources/icons/win.icon.theme/32x32/actions/document-print.png b/src/app/share/resources/icons/win.icon.theme/32x32/actions/document-print.png new file mode 100644 index 000000000..17f4bcc09 Binary files /dev/null and b/src/app/share/resources/icons/win.icon.theme/32x32/actions/document-print.png differ diff --git a/src/app/share/resources/theme.qrc b/src/app/share/resources/theme.qrc index 9a816625f..05b2ad324 100644 --- a/src/app/share/resources/theme.qrc +++ b/src/app/share/resources/theme.qrc @@ -61,5 +61,11 @@ icons/win.icon.theme/16x16/actions/help-contents.png icons/win.icon.theme/24x24/actions/help-contents.png icons/win.icon.theme/32x32/actions/help-contents.png + icons/win.icon.theme/16x16/actions/document-print.png + icons/win.icon.theme/24x24/actions/document-print.png + icons/win.icon.theme/32x32/actions/document-print.png + icons/win.icon.theme/16x16/actions/document-print-preview.png + icons/win.icon.theme/24x24/actions/document-print-preview.png + icons/win.icon.theme/32x32/actions/document-print-preview.png diff --git a/src/app/tablewindow.cpp b/src/app/tablewindow.cpp index 8d0d2d6ed..091397397 100644 --- a/src/app/tablewindow.cpp +++ b/src/app/tablewindow.cpp @@ -36,10 +36,13 @@ #include "../../libs/vlayout/vlayoutgenerator.h" #include "../dialogs/app/dialoglayoutprogress.h" #include "../dialogs/app/dialogsavelayout.h" +#include "../../libs/vlayout/vposter.h" #include #include #include +#include +#include #include #ifdef Q_OS_WIN @@ -78,6 +81,9 @@ TableWindow::TableWindow(QWidget *parent) connect(ui->actionSave, &QAction::triggered, this, &TableWindow::SaveLayout); connect(ui->actionLayout, &QAction::triggered, this, &TableWindow::Layout); connect(ui->listWidget, &QListWidget::currentRowChanged, this, &TableWindow::ShowPaper); + connect(ui->actionPrint_pre_view, &QAction::triggered, this, &TableWindow::PrintPreview); + connect(ui->action_Print, &QAction::triggered, this, &TableWindow::LayoutPrint); + connect(ui->actionSave_to_p_df, &QAction::triggered, this, &TableWindow::PrintToPdf); } //--------------------------------------------------------------------------------------------------------------------- @@ -238,7 +244,7 @@ void TableWindow::ShowPaper(int index) if (index < 0 || index > scenes.size()) { ui->view->setScene(tempScene); - ui->actionSave->setEnabled(false); + EnableActions(false); } else { @@ -248,6 +254,114 @@ void TableWindow::ShowPaper(int index) ui->view->fitInView(ui->view->scene()->sceneRect(), Qt::KeepAspectRatio); } +//--------------------------------------------------------------------------------------------------------------------- +void TableWindow::PrintPreview() +{ + QPrinterInfo def = QPrinterInfo::defaultPrinter(); + + //if there is no default printer set the print preview won't show + if(def.isNull() || def.printerName().isEmpty()) + { + if(QPrinterInfo::availablePrinters().isEmpty()) + { + QMessageBox::critical(this, tr("Print error"), + tr("Cannot proceed because there are no available printers in your system."), + QMessageBox::Ok); + return; + } + else + { + def = QPrinterInfo::availablePrinters().first(); + } + } + + QPrinter printer(def, QPrinter::ScreenResolution); + printer.setResolution(static_cast(VApplication::PrintDPI)); + printer.setCreator(qApp->applicationDisplayName()+" "+qApp->applicationVersion()); + printer.setDocName(fileName); + + // display print preview dialog + QPrintPreviewDialog preview(&printer); + connect(&preview, &QPrintPreviewDialog::paintRequested, this, &TableWindow::Print); + preview.exec(); +} + +//--------------------------------------------------------------------------------------------------------------------- +void TableWindow::Print(QPrinter *printer) +{ + if (printer == nullptr) + { + return; + } + + const QVector images = AllSheets(); + + VPoster posterazor(printer); + QVector poster; + for (int i=0; i < images.size(); i++) + { + poster += posterazor.Generate(images.at(i), i+1, images.size()); + } + + QPainter painter; + if (not painter.begin(printer)) + { // failed to open file + qWarning("failed to open file, is it writable?"); + return; + } + + for (int i=0; i < poster.size(); i++) + { + painter.drawImage(QPointF(), poster.at(i)); + + if (i+1 < poster.size()) + { + if (not printer->newPage()) + { + qWarning("failed in flushing page to disk, disk full?"); + return; + } + } + } + + painter.end(); +} + +//--------------------------------------------------------------------------------------------------------------------- +void TableWindow::LayoutPrint() +{ + // display print dialog and if accepted print + QPrinter printer; + printer.setCreator(qApp->applicationDisplayName()+" "+qApp->applicationVersion()); + printer.setDocName(fileName); + QPrintDialog dialog( &printer, this ); + if ( dialog.exec() == QDialog::Accepted ) + { + printer.setResolution(static_cast(VApplication::PrintDPI)); + Print( &printer ); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void TableWindow::PrintToPdf() +{ + // display print dialog and if accepted print + QPrinter printer; + printer.setCreator(qApp->applicationDisplayName()+" "+qApp->applicationVersion()); + printer.setDocName(fileName); + printer.setOutputFormat(QPrinter::PdfFormat); + + const QString fileName = QFileDialog::getSaveFileName(this, tr("Print to pdf"), + QDir::homePath()+"/"+this->fileName+".pdf", + tr("PDF file (*.pdf)")); + if (fileName.isEmpty()) + { + printer.setOutputFileName(fileName); + printer.setResolution(static_cast(VApplication::PrintDPI)); + Print( &printer ); + } +} + //--------------------------------------------------------------------------------------------------------------------- void TableWindow::Layout() { @@ -281,8 +395,8 @@ void TableWindow::Layout() { case LayoutErrors::NoError: ClearLayout(); - papers = lGenerator.GetPapersItems(); - details = lGenerator.GetAllDetails(); + papers = lGenerator.GetPapersItems();// Blank sheets + details = lGenerator.GetAllDetails();// All details CreateShadows(); CreateScenes(); PrepareSceneList(); @@ -462,6 +576,49 @@ void TableWindow::ObjFile(const QString &name, int i) const } } +//--------------------------------------------------------------------------------------------------------------------- +QVector TableWindow::AllSheets() +{ + QVector images; + for (int i=0; i < scenes.size(); ++i) + { + QGraphicsRectItem *paper = qgraphicsitem_cast(papers.at(i)); + if (paper) + { + // Hide shadow and paper border + QBrush *brush = new QBrush(); + brush->setColor( QColor( Qt::white ) ); + scenes[i]->setBackgroundBrush( *brush ); + shadows[i]->setVisible(false); + paper->setPen(QPen(Qt::white, 0.1, Qt::NoPen));// border + + // Render png + const QRectF r = paper->rect(); + // Create the image with the exact size of the shrunk scene + QImage image(QSize(static_cast(r.width()), static_cast(r.height())), QImage::Format_RGB32); + image.fill(Qt::white); + QPainter painter(&image); + painter.setFont( QFont( "Arial", 8, QFont::Normal ) ); + painter.setRenderHint(QPainter::Antialiasing, true); + painter.setPen(QPen(Qt::black, qApp->toPixel(qApp->widthMainLine()), Qt::SolidLine, Qt::RoundCap, + Qt::RoundJoin)); + painter.setBrush ( QBrush ( Qt::NoBrush ) ); + scenes.at(i)->render(&painter); + painter.end(); + images.append(image); + + // Resore + paper->setPen(QPen(Qt::black, qApp->toPixel(qApp->widthMainLine()))); + brush->setColor( QColor( Qt::gray ) ); + brush->setStyle( Qt::SolidPattern ); + scenes[i]->setBackgroundBrush( *brush ); + shadows[i]->setVisible(true); + delete brush; + } + } + return images; +} + //--------------------------------------------------------------------------------------------------------------------- void TableWindow::ClearLayout() { @@ -470,6 +627,7 @@ void TableWindow::ClearLayout() shadows.clear(); papers.clear(); ui->listWidget->clear(); + EnableActions(false); } //--------------------------------------------------------------------------------------------------------------------- @@ -529,7 +687,7 @@ void TableWindow::PrepareSceneList() if (scenes.isEmpty() == false) { ui->listWidget->setCurrentRow(0); - ui->actionSave->setEnabled(true); + EnableActions(true); } } @@ -587,3 +745,12 @@ QMap TableWindow::InitFormates() const } return extByMessage; } + +//--------------------------------------------------------------------------------------------------------------------- +void TableWindow::EnableActions(bool enable) +{ + ui->actionSave->setEnabled(enable); + ui->actionSave_to_p_df->setEnabled(enable); + ui->actionPrint_pre_view->setEnabled(enable); + ui->action_Print->setEnabled(enable); +} diff --git a/src/app/tablewindow.h b/src/app/tablewindow.h index 171d3495f..c988a6f77 100644 --- a/src/app/tablewindow.h +++ b/src/app/tablewindow.h @@ -42,6 +42,7 @@ namespace Ui class QGraphicsScene; class QGraphicsRectItem; +class QPrinter; /** * @brief TableWindow class layout window. @@ -54,12 +55,15 @@ public: ~TableWindow(); public slots: - void ModelChosen(QVector listDetails, const QString &fileName, - const QString &description); - void Layout(); - void StopTable(); - void SaveLayout(); - void ShowPaper(int index); + void ModelChosen(QVector listDetails, const QString &fileName, const QString &description); + void Layout(); + void StopTable(); + void SaveLayout(); + void ShowPaper(int index); + void PrintPreview(); + void Print (QPrinter *printer); + void LayoutPrint(); + void PrintToPdf(); signals: /** @brief closed emit if window is closing. */ @@ -91,13 +95,15 @@ private: QGraphicsScene* tempScene; - void SvgFile(const QString &name, int i)const; - void PngFile(const QString &name, int i)const; - void PdfFile(const QString &name, int i)const; - void EpsFile(const QString &name, int i)const; - void PsFile(const QString &name, int i)const; - void PdfToPs(const QStringList ¶ms)const; - void ObjFile(const QString &name, int i)const; + void SvgFile(const QString &name, int i)const; + void PngFile(const QString &name, int i)const; + void PdfFile(const QString &name, int i)const; + void EpsFile(const QString &name, int i)const; + void PsFile(const QString &name, int i)const; + void PdfToPs(const QStringList ¶ms)const; + void ObjFile(const QString &name, int i)const; + + QVector AllSheets(); void ClearLayout(); void CreateShadows(); @@ -105,6 +111,8 @@ private: void PrepareSceneList(); QIcon ScenePreview(int i) const; QMap InitFormates() const; + + void EnableActions(bool enable); }; #endif // TABLEWINDOW_H diff --git a/src/app/tablewindow.ui b/src/app/tablewindow.ui index 11bcf6891..c3c213e30 100644 --- a/src/app/tablewindow.ui +++ b/src/app/tablewindow.ui @@ -39,7 +39,7 @@ - toolBar + Main toolbar @@ -133,6 +133,56 @@ + + + + 0 + 0 + 1000 + 25 + + + + + File + + + + + + + + + + Edit + + + + + + + Layout + + + + + + + + + + Toolbar print + + + TopToolBarArea + + + false + + + + + false @@ -143,11 +193,14 @@ - Save + &Save As... Save layout + + Ctrl+S + @@ -197,6 +250,43 @@ Layout + + + false + + + + + + Print pre&view... + + + + + false + + + + + + &Print... + + + Ctrl+P + + + + + false + + + + :/icon/32x32/pdf.png:/icon/32x32/pdf.png + + + Print to p&df + + diff --git a/src/libs/ifc/exception/vexception.cpp b/src/libs/ifc/exception/vexception.cpp index 94dab8cfe..e1da1d3e1 100644 --- a/src/libs/ifc/exception/vexception.cpp +++ b/src/libs/ifc/exception/vexception.cpp @@ -28,6 +28,7 @@ #include "vexception.h" #include "../../../utils/logging.h" +#include "../../../utils/def.h" #include #include diff --git a/src/libs/ifc/ifcdef.h b/src/libs/ifc/ifcdef.h index a3d98ad03..506533397 100644 --- a/src/libs/ifc/ifcdef.h +++ b/src/libs/ifc/ifcdef.h @@ -29,7 +29,6 @@ #ifndef IFCDEF_H #define IFCDEF_H -#include #include #ifdef Q_OS_WIN32 @@ -45,63 +44,6 @@ static const quint32 null_id = 0; #define NULL_ID null_id//use this value for initialization variables that keeps id values. 0 mean uknown id value. #define NULL_ID_STR "0" -/* - * This macros SCASSERT (for Stop and Continue Assert) will break into the debugger on the line of the assert and allow - * you to continue afterwards should you choose to. - * idea: Q_ASSERT no longer pauses debugger - http://qt-project.org/forums/viewthread/13148 - * Usefull links: - * 1. What's the difference between __PRETTY_FUNCTION__, __FUNCTION__, __func__? - - * https://stackoverflow.com/questions/4384765/whats-the-difference-between-pretty-function-function-func - * - * 2. Windows Predefined Macros - http://msdn.microsoft.com/library/b0084kay.aspx - * - * 3. Windows DebugBreak function - http://msdn.microsoft.com/en-us/library/ms679297%28VS.85%29.aspx - * - * 4. Continue to debug after failed assertion on Linux? [C/C++] - - * https://stackoverflow.com/questions/1721543/continue-to-debug-after-failed-assertion-on-linux-c-c - */ -#ifndef V_NO_ASSERT -#ifdef Q_OS_WIN32 -#ifdef Q_CC_MSVC -#define SCASSERT(cond) \ -{ \ - if (!(cond)) \ - { \ - qDebug("ASSERT: %s in %s (%s:%u)", \ - #cond, __FUNCSIG__, __FILE__, __LINE__); \ - DebugBreak(); \ - } \ -} \ - -#else // GCC (Windows) - -#define SCASSERT(cond) \ -{ \ - if (!(cond)) \ - { \ - qDebug("ASSERT: %s in %s (%s:%u)", \ - #cond, __PRETTY_FUNCTION__, __FILE__, __LINE__);\ - DebugBreak(); \ - } \ -} \ - -#endif /*Q_CC_MSVC*/ -#else // UNIX -#define SCASSERT(cond) \ -{ \ - if (!(cond)) \ - { \ - qDebug("ASSERT: %s in %s (%s:%u)", \ - #cond, __PRETTY_FUNCTION__, __FILE__, __LINE__);\ - std::raise(SIGTRAP); \ - } \ -} \ - -#endif /* Q_OS_WIN32 */ -#else // define but disable this function if debugging is not set -#define SCASSERT(cond) qt_noop(); -#endif /* V_NO_ASSERT */ - // Detect whether the compiler supports C++11 noexcept exception specifications. # if defined(__clang__) # if __has_feature(cxx_noexcept) diff --git a/src/libs/vlayout/share/icons.qrc b/src/libs/vlayout/share/icons.qrc new file mode 100644 index 000000000..daa859f6f --- /dev/null +++ b/src/libs/vlayout/share/icons.qrc @@ -0,0 +1,6 @@ + + + scissors_horizontal.png + scissors_vertical.png + + diff --git a/src/libs/vlayout/share/scissors_horizontal.png b/src/libs/vlayout/share/scissors_horizontal.png new file mode 100644 index 000000000..3f732e4ce Binary files /dev/null and b/src/libs/vlayout/share/scissors_horizontal.png differ diff --git a/src/libs/vlayout/share/scissors_vertical.png b/src/libs/vlayout/share/scissors_vertical.png new file mode 100644 index 000000000..2508af525 Binary files /dev/null and b/src/libs/vlayout/share/scissors_vertical.png differ diff --git a/src/libs/vlayout/vlayout.pri b/src/libs/vlayout/vlayout.pri index 65bebdf49..36aba3f20 100644 --- a/src/libs/vlayout/vlayout.pri +++ b/src/libs/vlayout/vlayout.pri @@ -15,7 +15,8 @@ HEADERS += \ $$PWD/vcontour.h \ $$PWD/vcontour_p.h \ $$PWD/vbestsquare.h \ - $$PWD/vposition.h + $$PWD/vposition.h \ + vposter.h SOURCES += \ $$PWD/stable.cpp \ @@ -26,4 +27,5 @@ SOURCES += \ $$PWD/vbank.cpp \ $$PWD/vcontour.cpp \ $$PWD/vbestsquare.cpp \ - $$PWD/vposition.cpp + $$PWD/vposition.cpp \ + vposter.cpp diff --git a/src/libs/vlayout/vlayout.pro b/src/libs/vlayout/vlayout.pro index 97fb5fe86..1e49cda60 100644 --- a/src/libs/vlayout/vlayout.pro +++ b/src/libs/vlayout/vlayout.pro @@ -7,7 +7,7 @@ # File with common stuff for whole project include(../../../Valentina.pri) -QT += core gui widgets +QT += core gui widgets printsupport # Name of library TARGET = vlayout @@ -93,3 +93,6 @@ CONFIG(debug, debug|release){ QMAKE_LFLAGS_RELEASE = } } + +RESOURCES += \ + share/icons.qrc diff --git a/src/libs/vlayout/vposter.cpp b/src/libs/vlayout/vposter.cpp new file mode 100644 index 000000000..6fb36b266 --- /dev/null +++ b/src/libs/vlayout/vposter.cpp @@ -0,0 +1,239 @@ +/************************************************************************ + ** + ** @file vposter.cpp + ** @author Roman Telezhynskyi + ** @date 11 4, 2015 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2015 Valentina project + ** All Rights Reserved. + ** + ** Valentina 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 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see . + ** + *************************************************************************/ + +#include "vposter.h" +#include +#include +#include + +#include "../../utils/def.h" + +//--------------------------------------------------------------------------------------------------------------------- +VPoster::VPoster(const QPrinter *printer) + :printer(printer), allowence(38)//1 cm +{ +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector VPoster::Generate(const QImage &image, int page, int pages) const +{ + QVector poster; + + if (printer == nullptr) + { + return poster; + } + + const int rows = CountRows(image.rect().height()); + const int colomns = CountColomns(image.rect().width()); + + for (int i=0; i < rows; i++) + { + for (int j=0; j< colomns; j++) + { + QImage img = Cut(i, j, image); + img = Borders(rows, colomns, i, j, img, page, pages); + poster.append(img); + } + } + + return poster; +} + +//--------------------------------------------------------------------------------------------------------------------- +int VPoster::CountRows(int height) const +{ + const qreal imgLength = height; + const qreal pageLength = PageRect().height(); + + // Example + // ― ― + // * * + // * * + // * * + // * * ― + // ― ― * + // * * + // * * + // * * ― + // * ― * + // — * + // * * + // * * ― + // * ― * + // * * + // — * + // * * ― + // * ― * <-(2) + // * + * + // * + * + // — + * ― <-(4) + // ^ ^ ― * + //(3) (1) * + // * + // * + // ― + + const int pCount = qCeil(imgLength/pageLength);// Pages count without allowence (or allowence = 0) (3) + + // Calculate how many pages will be after using allowence. + // We know start pages count. This number not enought because + // each n-1 pages add (n-1)*allowence length to page (1). + const qreal addionalLength = (pCount-1)*allowence; + + // Calculate additional length form pages that will cover this length (2). + // In the end add page length (3). + // Bottom page have mandatory border (4) + return qCeil((addionalLength + + qCeil(addionalLength/pageLength)*allowence + allowence + imgLength)/pageLength); +} + +//--------------------------------------------------------------------------------------------------------------------- +int VPoster::CountColomns(int width) const +{ + const qreal imgLength = width; + const qreal pageLength = PageRect().width(); + + // Example + // |----|----|----|----| <- (3) + // |----|+++++++++++++++ + // |----|+++++++++++ + // |----|+++++++ + // |----|+++ <- (1) + // |----| + // ^ + // (2) + const int pCount = qCeil(imgLength/pageLength);// Pages count without allowence (or allowence = 0) (3) + + // Calculate how many pages will be after using allowence. + // We know start pages count. This number not enought because + // each n-1 pages add (n-1)*allowence length to page (1). + const qreal addionalLength = (pCount-1)*allowence; + + // Calculate additional length form pages that will cover this length (2). + // In the end add page length (3). + return qCeil((addionalLength + qCeil(addionalLength/pageLength)*allowence + imgLength)/pageLength); +} + +//--------------------------------------------------------------------------------------------------------------------- +QImage VPoster::Cut(int i, int j, const QImage &image) const +{ + const int x = j*PageRect().width() - j*allowence; + const int y = i*PageRect().height() - i*allowence; + + SCASSERT(x <= image.rect().width()); + SCASSERT(y <= image.rect().height()); + + QRect copyRect(x, y, PageRect().width(), PageRect().height()); + + if (not image.rect().contains(copyRect)) + { + QImage fullPage(copyRect.size(), image.format()); + fullPage.fill(Qt::white); + + copyRect = image.rect().intersected(copyRect); + + QPainter painter(&fullPage); + painter.drawImage(QPointF(), image.copy( copyRect)); + painter.end(); + + return fullPage; + } + else + { + return image.copy(copyRect); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +QImage VPoster::Borders(int rows, int colomns, int i, int j, QImage &image, int page, int pages) const +{ + QPainter painter(&image); + + QPen pen = QPen(Qt::NoBrush, 1, Qt::DashLine); + pen.setColor(Qt::black); + painter.setPen(pen); + + if (j != 0) + {// Left border + painter.drawLine(QLine(0, 0, 0, image.rect().height())); + painter.drawImage(QPoint(0, image.rect().height()-allowence), QImage("://scissors_vertical.png")); + } + + if (j != colomns-1) + {// Right border + painter.drawLine(QLine(image.rect().width()-allowence, 0, + image.rect().width()-allowence, image.rect().height())); + } + + if (i != 0) + {// Top border + painter.drawLine(QLine(0, 0, image.rect().width(), 0)); + painter.drawImage(QPoint(image.rect().width()-allowence, 0), QImage("://scissors_horizontal.png")); + } + + // Bottom border (mandatory) + painter.drawLine(QLine(0, image.rect().height()-allowence, + image.rect().width(), image.rect().height()-allowence)); + if (i == rows-1) + { + painter.drawImage(QPoint(image.rect().width()-allowence, image.rect().height()-allowence), + QImage("://scissors_horizontal.png")); + } + + // Labels + const int layoutX = 15; + const int layoutY = 5; + QRect labels(layoutX, image.rect().height()-allowence+layoutY, + image.rect().width()-(allowence+layoutX), allowence-layoutY); + painter.drawText(labels, Qt::AlignLeft, tr("Grid ( %1 , %2 )").arg(i).arg(j)); + painter.drawText(labels, Qt::AlignHCenter, tr("Page %1 of %2").arg(i*(colomns)+j+1).arg(rows*colomns)); + if (pages > 1) + { + painter.drawText(labels, Qt::AlignRight, tr("Sheet %1 of %2").arg(page).arg(pages)); + } + + painter.end(); + return image; +} + +//--------------------------------------------------------------------------------------------------------------------- +QRect VPoster::PageRect() const +{ + + const QRectF rect = printer->pageRect(QPrinter::Millimeter); + QRect pageRect(qFloor(ToPixel(rect.x())), qFloor(ToPixel(rect.y())), qFloor(ToPixel(rect.width())), + qFloor(ToPixel(rect.height()))); + return pageRect; +} + +//--------------------------------------------------------------------------------------------------------------------- +qreal VPoster::ToPixel(qreal val) const +{ + return val / 25.4 * printer->resolution(); // Mm to pixels with current dpi. +} diff --git a/src/libs/vlayout/vposter.h b/src/libs/vlayout/vposter.h new file mode 100644 index 000000000..334358cf8 --- /dev/null +++ b/src/libs/vlayout/vposter.h @@ -0,0 +1,60 @@ +/************************************************************************ + ** + ** @file vposter.h + ** @author Roman Telezhynskyi + ** @date 11 4, 2015 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2015 Valentina project + ** All Rights Reserved. + ** + ** Valentina 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 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see . + ** + *************************************************************************/ + +#ifndef VPOSTER_H +#define VPOSTER_H + +#include +#include +#include + +class QPrinter; + +class VPoster +{ + Q_DECLARE_TR_FUNCTIONS(VPoster) +public: + VPoster(const QPrinter *printer); + + QVector Generate(const QImage &image, int page, int pages = 1) const; +private: + const QPrinter *printer; + unsigned int allowence; + + int CountRows(int height) const; + int CountColomns(int width) const; + + QImage Cut(int i, int j, const QImage &image) const; + QImage Borders(int rows, int colomns, int i, int j, QImage &image, int page, int pages) const; + + QRect PageRect() const; + + qreal ToPixel(qreal val) const; +}; + +#endif // VPOSTER_H diff --git a/src/utils/def.h b/src/utils/def.h new file mode 100644 index 000000000..cd02e81c2 --- /dev/null +++ b/src/utils/def.h @@ -0,0 +1,92 @@ +/************************************************************************ + ** + ** @file def.h + ** @author Roman Telezhynskyi + ** @date 11 4, 2015 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2015 Valentina project + ** All Rights Reserved. + ** + ** Valentina 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 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see . + ** + *************************************************************************/ + +#ifndef DEF_H +#define DEF_H + +#include +#include + +/* + * This macros SCASSERT (for Stop and Continue Assert) will break into the debugger on the line of the assert and allow + * you to continue afterwards should you choose to. + * idea: Q_ASSERT no longer pauses debugger - http://qt-project.org/forums/viewthread/13148 + * Usefull links: + * 1. What's the difference between __PRETTY_FUNCTION__, __FUNCTION__, __func__? - + * https://stackoverflow.com/questions/4384765/whats-the-difference-between-pretty-function-function-func + * + * 2. Windows Predefined Macros - http://msdn.microsoft.com/library/b0084kay.aspx + * + * 3. Windows DebugBreak function - http://msdn.microsoft.com/en-us/library/ms679297%28VS.85%29.aspx + * + * 4. Continue to debug after failed assertion on Linux? [C/C++] - + * https://stackoverflow.com/questions/1721543/continue-to-debug-after-failed-assertion-on-linux-c-c + */ +#ifndef V_NO_ASSERT +#ifdef Q_OS_WIN32 +#ifdef Q_CC_MSVC +#define SCASSERT(cond) \ +{ \ + if (!(cond)) \ + { \ + qDebug("ASSERT: %s in %s (%s:%u)", \ + #cond, __FUNCSIG__, __FILE__, __LINE__); \ + DebugBreak(); \ + } \ +} \ + +#else // GCC (Windows) + +#define SCASSERT(cond) \ +{ \ + if (!(cond)) \ + { \ + qDebug("ASSERT: %s in %s (%s:%u)", \ + #cond, __PRETTY_FUNCTION__, __FILE__, __LINE__);\ + DebugBreak(); \ + } \ +} \ + +#endif /*Q_CC_MSVC*/ +#else // UNIX +#define SCASSERT(cond) \ +{ \ + if (!(cond)) \ + { \ + qDebug("ASSERT: %s in %s (%s:%u)", \ + #cond, __PRETTY_FUNCTION__, __FILE__, __LINE__);\ + std::raise(SIGTRAP); \ + } \ +} \ + +#endif /* Q_OS_WIN32 */ +#else // define but disable this function if debugging is not set +#define SCASSERT(cond) qt_noop(); +#endif /* V_NO_ASSERT */ + +#endif // DEF_H diff --git a/src/utils/utils.pri b/src/utils/utils.pri index 851661377..0fc1408a4 100644 --- a/src/utils/utils.pri +++ b/src/utils/utils.pri @@ -1,3 +1,4 @@ HEADERS += \ $$PWD/logging.h \ - $$PWD/vmath.h + $$PWD/vmath.h \ + $$PWD/def.h