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 @@
+
+
+
+ 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