Merge branch 'feature/manual-layout' into 'feature/manual-layout'

Puzzle, work on the UI, the file reader and writer

See merge request smart-pattern/valentina!5
This commit is contained in:
Roman Telezhynskyi 2020-04-23 08:04:43 +00:00
commit a0fb0f8ee3
14 changed files with 1717 additions and 85 deletions

View File

@ -8,7 +8,12 @@ SOURCES += \
$$PWD/puzzleapplication.cpp \ $$PWD/puzzleapplication.cpp \
$$PWD/vpuzzlecommandline.cpp \ $$PWD/vpuzzlecommandline.cpp \
$$PWD/dialogs/dialogaboutpuzzle.cpp \ $$PWD/dialogs/dialogaboutpuzzle.cpp \
$$PWD/vpiececarrousel.cpp $$PWD/vpiececarrousel.cpp \
$$PWD/vpuzzlelayout.cpp \
$$PWD/vpuzzlelayer.cpp \
$$PWD/vpuzzlepiece.cpp \
$$PWD/xml/vpuzzlelayoutfilewriter.cpp \
$$PWD/xml/vpuzzlelayoutfilereader.cpp
*msvc*:SOURCES += $$PWD/stable.cpp *msvc*:SOURCES += $$PWD/stable.cpp
@ -19,7 +24,12 @@ HEADERS += \
$$PWD/puzzleapplication.h \ $$PWD/puzzleapplication.h \
$$PWD/vpuzzlecommandline.h \ $$PWD/vpuzzlecommandline.h \
$$PWD/dialogs/dialogaboutpuzzle.h \ $$PWD/dialogs/dialogaboutpuzzle.h \
$$PWD/vpiececarrousel.h $$PWD/vpiececarrousel.h \
$$PWD/vpuzzlelayout.h \
$$PWD/vpuzzlelayer.h \
$$PWD/vpuzzlepiece.h \
$$PWD/xml/vpuzzlelayoutfilewriter.h \
$$PWD/xml/vpuzzlelayoutfilereader.h
FORMS += \ FORMS += \
$$PWD/puzzlemainwindow.ui \ $$PWD/puzzlemainwindow.ui \

View File

@ -26,8 +26,14 @@
** **
*************************************************************************/ *************************************************************************/
#include "puzzlemainwindow.h" #include "puzzlemainwindow.h"
#include <QFileDialog>
#include "ui_puzzlemainwindow.h" #include "ui_puzzlemainwindow.h"
#include "dialogs/dialogaboutpuzzle.h" #include "dialogs/dialogaboutpuzzle.h"
#include "xml/vpuzzlelayoutfilewriter.h"
#include "xml/vpuzzlelayoutfilereader.h"
#include "puzzleapplication.h"
#include "../vlayout/vrawlayout.h" #include "../vlayout/vrawlayout.h"
#include "../vmisc/vsysexits.h" #include "../vmisc/vsysexits.h"
@ -46,6 +52,8 @@ PuzzleMainWindow::PuzzleMainWindow(const VPuzzleCommandLinePtr &cmd, QWidget *pa
QMainWindow(parent), QMainWindow(parent),
ui(new Ui::PuzzleMainWindow), ui(new Ui::PuzzleMainWindow),
pieceCarrousel(new VPieceCarrousel), pieceCarrousel(new VPieceCarrousel),
m_layout (nullptr),
m_selectedPiece (nullptr),
m_cmd(cmd) m_cmd(cmd)
{ {
ui->setupUi(this); ui->setupUi(this);
@ -53,6 +61,16 @@ PuzzleMainWindow::PuzzleMainWindow(const VPuzzleCommandLinePtr &cmd, QWidget *pa
InitMenuBar(); InitMenuBar();
InitProperties(); InitProperties();
InitPieceCarrousel(); InitPieceCarrousel();
// ----- for test purposes, to be removed------------------
m_layout = new VPuzzleLayout();
m_layout->SetLayoutMarginsConverted(1.5, 2.00, 4.21, 0.25);
m_layout->SetLayoutSizeConverted(30.0, 29.7);
m_layout->SetPiecesGapConverted(1.27);
m_layout->SetUnit(Unit::Cm);
m_layout->SetWarningSuperpositionOfPieces(true);
SetPropertiesData();
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -65,7 +83,34 @@ PuzzleMainWindow::~PuzzleMainWindow()
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
bool PuzzleMainWindow::LoadFile(const QString &path) bool PuzzleMainWindow::LoadFile(const QString &path)
{ {
Q_UNUSED(path) QFile file(path);
file.open(QIODevice::ReadOnly);
VPuzzleLayoutFileReader *fileReader = new VPuzzleLayoutFileReader();
if(m_layout == nullptr)
{
m_layout = new VPuzzleLayout();
}
fileReader->ReadFile(m_layout, &file);
// TODO / FIXME : better return value and error handling
return true;
}
//---------------------------------------------------------------------------------------------------------------------
bool PuzzleMainWindow::SaveFile(const QString &path)
{
QFile file(path);
file.open(QIODevice::WriteOnly);
VPuzzleLayoutFileWriter *fileWriter = new VPuzzleLayoutFileWriter();
fileWriter->WriteFile(m_layout, &file);
// TODO / FIXME : better return value and error handling
return true; return true;
} }
@ -254,6 +299,114 @@ void PuzzleMainWindow::InitPieceCarrousel()
} }
//---------------------------------------------------------------------------------------------------------------------
void PuzzleMainWindow::SetPropertiesData()
{
if(m_layout == nullptr)
{
// TODO : hide the tabs when there is no layout
}
else
{
SetPropertyTabCurrentPieceData();
SetPropertyTabLayoutData();
SetPropertyTabTilesData();
SetPropertyTabLayersData();
}
}
//---------------------------------------------------------------------------------------------------------------------
void PuzzleMainWindow::SetPropertyTabCurrentPieceData()
{
if(m_selectedPiece == nullptr)
{
if(false) // check for multiple piece selection
{
// TODO in the future
}
else
{
// TODO : update current piece data to show a "no current piece selected"
}
}
else
{
// TODO set the values of the piece currently selected
}
}
//---------------------------------------------------------------------------------------------------------------------
void PuzzleMainWindow::SetPropertyTabLayoutData()
{
// set Unit
int index = ui->comboBoxLayoutUnit->findData(QVariant(UnitsToStr(m_layout->getUnit())));
if(index != -1)
{
ui->comboBoxLayoutUnit->blockSignals(true); // FIXME: is there a better way to block the signals?
ui->comboBoxLayoutUnit->setCurrentIndex(index);
ui->comboBoxLayoutUnit->blockSignals(false);
}
// set Width / Length
QSizeF size = m_layout->GetLayoutSizeConverted();
SetDoubleSpinBoxValue(ui->doubleSpinBoxLayoutWidth, size.width());
SetDoubleSpinBoxValue(ui->doubleSpinBoxLayoutLength, size.height());
// Set Orientation
if(size.width() <= size.height())
{
ui->radioButtonLayoutPortrait->setChecked(true);
}
else
{
ui->radioButtonLayoutLandscape->setChecked(true);
}
// set margins
QMarginsF margins = m_layout->GetLayoutMarginsConverted();
SetDoubleSpinBoxValue(ui->doubleSpinBoxLayoutMarginLeft, margins.left());
SetDoubleSpinBoxValue(ui->doubleSpinBoxLayoutMarginTop, margins.top());
SetDoubleSpinBoxValue(ui->doubleSpinBoxLayoutMarginRight, margins.right());
SetDoubleSpinBoxValue(ui->doubleSpinBoxLayoutMarginBottom, margins.bottom());
// set pieces gap
SetDoubleSpinBoxValue(ui->doubleSpinBoxLayoutPiecesGap, m_layout->GetPiecesGapConverted());
// set the checkboxes
SetCheckBoxValue(ui->checkBoxLayoutWarningPiecesOutOfBound, m_layout->GetWarningPiecesOutOfBound());
SetCheckBoxValue(ui->checkBoxLayoutWarningPiecesSuperposition, m_layout->GetWarningSuperpositionOfPieces());
SetCheckBoxValue(ui->checkBoxLayoutStickyEdges, m_layout->GetStickyEdges());
}
//---------------------------------------------------------------------------------------------------------------------
void PuzzleMainWindow::SetPropertyTabTilesData()
{
}
//---------------------------------------------------------------------------------------------------------------------
void PuzzleMainWindow::SetPropertyTabLayersData()
{
}
//---------------------------------------------------------------------------------------------------------------------
void PuzzleMainWindow::SetDoubleSpinBoxValue(QDoubleSpinBox *spinBox, qreal value)
{
spinBox->blockSignals(true);
spinBox->setValue(value);
spinBox->blockSignals(false);
}
//---------------------------------------------------------------------------------------------------------------------
void PuzzleMainWindow::SetCheckBoxValue(QCheckBox *checkbox, bool value)
{
checkbox->blockSignals(true);
checkbox->setChecked(value);
checkbox->blockSignals(false);
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -274,14 +427,60 @@ void PuzzleMainWindow::New()
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void PuzzleMainWindow::Open() void PuzzleMainWindow::Open()
{ {
// just for test purpuses, to be removed: qCDebug(pWindow, "Openning puzzle layout file.");
QMessageBox msgBox;
msgBox.setText("TODO PuzzleMainWindow::Open");
int ret = msgBox.exec();
Q_UNUSED(ret); const QString filter(tr("Layout files") + QLatin1String(" (*.vlt)"));
// TODO //Get list last open files
QStringList recentFiles = qApp->PuzzleSettings()->GetRecentFileList();
QString dir;
if (recentFiles.isEmpty())
{
dir = QDir::homePath();
}
else
{
//Absolute path to last open file
dir = QFileInfo(recentFiles.first()).absolutePath();
}
qCDebug(pWindow, "Run QFileDialog::getOpenFileName: dir = %s.", qUtf8Printable(dir));
const QString filePath = QFileDialog::getOpenFileName(
this, tr("Open file"), dir, filter, nullptr,
#ifdef Q_OS_LINUX
QFileDialog::DontUseNativeDialog
#endif
);
if (filePath.isEmpty())
{
return;
}
// TODO : if m_layout == nullptr, open in current window
// otherwise open in new window
// TODO : if layout file has a lock, warning message
if(!LoadFile(filePath))
{
return;
}
// Updates the list of recent files
recentFiles.removeAll(filePath);
recentFiles.prepend(filePath);
while (recentFiles.size() > MaxRecentFiles)
{
recentFiles.removeLast();
}
qApp->PuzzleSettings()->SetRecentFileList(recentFiles);
// updates the properties with the loaded data
SetPropertiesData();
// TODO : update the Carrousel and the QGraphicView
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -300,14 +499,31 @@ void PuzzleMainWindow::Save()
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void PuzzleMainWindow::SaveAs() void PuzzleMainWindow::SaveAs()
{ {
// just for test purpuses, to be removed: // TODO / FIXME : See valentina how the save is done over there. we need to add the extension .vlt, check for empty file names etc.
QMessageBox msgBox;
msgBox.setText("TODO PuzzleMainWindow::SaveAs");
int ret = msgBox.exec();
Q_UNUSED(ret); //Get list last open files
QStringList recentFiles = qApp->PuzzleSettings()->GetRecentFileList();
QString dir;
if (recentFiles.isEmpty())
{
dir = QDir::homePath();
}
else
{
//Absolute path to last open file
dir = QFileInfo(recentFiles.first()).absolutePath();
}
// TODO QString filters(tr("Layout files") + QLatin1String("(*.vlt)"));
QString fileName = QFileDialog::getSaveFileName(this, tr("Save as"),
dir + QLatin1String("/") + tr("Layout") + QLatin1String(".vlt"),
filters, nullptr
#ifdef Q_OS_LINUX
, QFileDialog::DontUseNativeDialog
#endif
);
SaveFile(fileName);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -353,17 +569,24 @@ void PuzzleMainWindow::AboutPuzzle()
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void PuzzleMainWindow::LayoutUnitChanged(int index) void PuzzleMainWindow::LayoutUnitChanged(int index)
{ {
// just for test purpuses, to be removed:
QMessageBox msgBox;
msgBox.setText("TODO PuzzleMainWindow::LayoutUnitChanged");
int ret = msgBox.exec();
Q_UNUSED(index); Q_UNUSED(index);
Q_UNUSED(ret); QVariant comboBoxValue = ui->comboBoxLayoutUnit->currentData();
if(comboBoxValue == QVariant(UnitsToStr(Unit::Cm)))
{
m_layout->SetUnit(Unit::Cm);
}
else if(comboBoxValue == QVariant(UnitsToStr(Unit::Mm)))
{
m_layout->SetUnit(Unit::Mm);
}
else if(comboBoxValue == QVariant(UnitsToStr(Unit::Inch)))
{
m_layout->SetUnit(Unit::Inch);
}
// TODO SetPropertyTabLayoutData();
SetPropertyTabCurrentPieceData();
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -384,27 +607,36 @@ void PuzzleMainWindow::LayoutTemplateChanged(int index)
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void PuzzleMainWindow::LayoutSizeChanged() void PuzzleMainWindow::LayoutSizeChanged()
{ {
// just for test purpuses, to be removed: m_layout->SetLayoutSizeConverted(ui->doubleSpinBoxLayoutWidth->value(), ui->doubleSpinBoxLayoutLength->value());
QMessageBox msgBox;
msgBox.setText("TODO PuzzleMainWindow::LayoutSizeChanged");
int ret = msgBox.exec();
Q_UNUSED(ret); // updates orientation - no need to block signals because the signal reacts on "clicked"
if(ui->doubleSpinBoxLayoutWidth->value() <= ui->doubleSpinBoxLayoutLength->value())
{
//portrait
ui->radioButtonLayoutPortrait->setChecked(true);
}
else
{
//landscape
ui->radioButtonLayoutLandscape->setChecked(true);
}
// TODO // TODO Undo / Redo
// TODO update the QGraphicView
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void PuzzleMainWindow::LayoutOrientationChanged() void PuzzleMainWindow::LayoutOrientationChanged()
{ {
// just for test purpuses, to be removed: // swap the width and length
QMessageBox msgBox; qreal width_before = ui->doubleSpinBoxLayoutWidth->value();
msgBox.setText("TODO PuzzleMainWindow::LayoutOrientationChanged"); qreal length_before = ui->doubleSpinBoxLayoutLength->value();
int ret = msgBox.exec();
Q_UNUSED(ret); SetDoubleSpinBoxValue(ui->doubleSpinBoxLayoutWidth, length_before);
SetDoubleSpinBoxValue(ui->doubleSpinBoxLayoutLength, width_before);
// TODO // TODO Undo / Redo
// TODO update the QGraphicView
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -424,14 +656,15 @@ void PuzzleMainWindow::LayoutRemoveUnusedLength()
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void PuzzleMainWindow::LayoutMarginChanged() void PuzzleMainWindow::LayoutMarginChanged()
{ {
// just for test purpuses, to be removed: m_layout->SetLayoutMarginsConverted(
QMessageBox msgBox; ui->doubleSpinBoxLayoutMarginLeft->value(),
msgBox.setText("TODO PuzzleMainWindow::LayoutMarginChanged"); ui->doubleSpinBoxLayoutMarginTop->value(),
int ret = msgBox.exec(); ui->doubleSpinBoxLayoutMarginRight->value(),
ui->doubleSpinBoxLayoutMarginBottom->value()
);
Q_UNUSED(ret); // TODO Undo / Redo
// TODO update the QGraphicView
// TODO
} }
@ -452,60 +685,37 @@ void PuzzleMainWindow::LayoutFollowGrainlineChanged()
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void PuzzleMainWindow::LayoutPiecesGapChanged(double value) void PuzzleMainWindow::LayoutPiecesGapChanged(double value)
{ {
// just for test purpuses, to be removed: m_layout->SetPiecesGapConverted(value);
QMessageBox msgBox;
msgBox.setText("TODO PuzzleMainWindow::LayoutPieceGapChanged");
int ret = msgBox.exec();
Q_UNUSED(value); // TODO Undo / Redo
Q_UNUSED(ret); // TODO update the QGraphicView
// TODO
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void PuzzleMainWindow::LayoutWarningPiecesSuperpositionChanged(bool checked) void PuzzleMainWindow::LayoutWarningPiecesSuperpositionChanged(bool checked)
{ {
// just for test purpuses, to be removed: m_layout->SetWarningSuperpositionOfPieces(checked);
QMessageBox msgBox;
msgBox.setText("TODO PuzzleMainWindow::LayoutWarningPiecesSuperpositionChanged");
int ret = msgBox.exec();
Q_UNUSED(checked); // TODO Undo / Redo
Q_UNUSED(ret); // TODO update the QGraphicView
// TODO
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void PuzzleMainWindow::LayoutWarningPiecesOutOfBoundChanged(bool checked) void PuzzleMainWindow::LayoutWarningPiecesOutOfBoundChanged(bool checked)
{ {
// just for test purpuses, to be removed: m_layout->SetWarningPiecesOutOfBound(checked);
QMessageBox msgBox;
msgBox.setText("TODO PuzzleMainWindow::LayoutWarningPiecesOutOfBoundChanged");
int ret = msgBox.exec();
Q_UNUSED(checked);
Q_UNUSED(ret);
// TODO
// TODO Undo / Redo
// TODO update the QGraphicView
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void PuzzleMainWindow::LayoutStickyEdgesChanged(bool checked) void PuzzleMainWindow::LayoutStickyEdgesChanged(bool checked)
{ {
// just for test purpuses, to be removed: m_layout->SetStickyEdges(checked);
QMessageBox msgBox;
msgBox.setText("TODO PuzzleMainWindow::LayoutStickyEdgesChanged");
int ret = msgBox.exec();
Q_UNUSED(checked);
Q_UNUSED(ret);
// TODO
// TODO Undo / Redo
// TODO update the QGraphicView
} }

View File

@ -30,9 +30,12 @@
#include <QMainWindow> #include <QMainWindow>
#include <QMessageBox> #include <QMessageBox>
#include <QDoubleSpinBox>
#include "../vmisc/def.h" #include "../vmisc/def.h"
#include "vpiececarrousel.h" #include "vpiececarrousel.h"
#include "vpuzzlelayout.h"
#include "vpuzzlepiece.h"
#include "vpuzzlecommandline.h" #include "vpuzzlecommandline.h"
namespace Ui namespace Ui
@ -48,19 +51,40 @@ public:
PuzzleMainWindow(const VPuzzleCommandLinePtr &cmd, QWidget *parent = nullptr); PuzzleMainWindow(const VPuzzleCommandLinePtr &cmd, QWidget *parent = nullptr);
virtual ~PuzzleMainWindow(); virtual ~PuzzleMainWindow();
/**
* @brief LoadFile Loads the layout file of given path in m_layout.
* This function doesn't update the gui.
* @param path
* @return
*/
bool LoadFile(const QString &path); bool LoadFile(const QString &path);
/**
* @brief SaveFile Saves the current layout to the layout file of given path
* @param path
* @return
*/
bool SaveFile(const QString &path);
void ImportRawLayouts(const QStringList &layouts); void ImportRawLayouts(const QStringList &layouts);
public slots: public slots:
void New(); void New();
protected:
enum { MaxRecentFiles = 5 };
private: private:
Q_DISABLE_COPY(PuzzleMainWindow) Q_DISABLE_COPY(PuzzleMainWindow)
Ui::PuzzleMainWindow *ui; Ui::PuzzleMainWindow *ui;
VPieceCarrousel *pieceCarrousel; VPieceCarrousel *pieceCarrousel;
VPuzzleCommandLinePtr m_cmd; VPuzzleCommandLinePtr m_cmd;
VPuzzleLayout *m_layout;
VPuzzlePiece *m_selectedPiece;
void InitMenuBar(); void InitMenuBar();
void InitProperties(); void InitProperties();
void InitPropertyTabCurrentPiece(); void InitPropertyTabCurrentPiece();
@ -69,6 +93,53 @@ private:
void InitPropertyTabLayers(); void InitPropertyTabLayers();
void InitPieceCarrousel(); void InitPieceCarrousel();
/**
* @brief SetPropertiesData Sets the values of UI elements
* in all the property tabs to the values saved in m_layout
*/
void SetPropertiesData();
/**
* @brief SetPropertyTabCurrentPieceData Sets the values of UI elements
* in the Current Piece Tab to the values saved in m_layout
*/
void SetPropertyTabCurrentPieceData();
/**
* @brief SetPropertyTabLayoutData Sets the values of UI elements
* in the Layout Tab to the values saved in m_layout
*/
void SetPropertyTabLayoutData();
/**
* @brief SetPropertyTabTilesData Sets the values of UI elements
* in the Tiles Tab to the values saved in m_layout
*/
void SetPropertyTabTilesData();
/**
* @brief SetPropertyTabLayersData Sets the values of UI elements
* in the Layers Tab to the values saved in m_layout
*/
void SetPropertyTabLayersData();
/**
* @brief SetDoubleSpinBoxValue sets the given spinbox to the given value.
* the signals are blocked before changing the value and unblocked after
* @param spinbox
* @param value
*/
void SetDoubleSpinBoxValue(QDoubleSpinBox *spinBox, qreal value);
/**
* @brief SetCheckBoxValue sets the given checkbox to the given value.
* the signals are blocked before changing the value and unblocked after
* @param checkbox
* @param value
*/
void SetCheckBoxValue(QCheckBox *checkbox, bool value);
private slots: private slots:
void Open(); void Open();
void Save(); void Save();

View File

@ -228,8 +228,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>356</width> <width>170</width>
<height>760</height> <height>452</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
@ -495,10 +495,18 @@
</widget> </widget>
</item> </item>
<item row="2" column="1"> <item row="2" column="1">
<widget class="QDoubleSpinBox" name="doubleSpinBoxLayoutWidth"/> <widget class="QDoubleSpinBox" name="doubleSpinBoxLayoutWidth">
<property name="maximum">
<double>100000.000000000000000</double>
</property>
</widget>
</item> </item>
<item row="3" column="1"> <item row="3" column="1">
<widget class="QDoubleSpinBox" name="doubleSpinBoxLayoutLength"/> <widget class="QDoubleSpinBox" name="doubleSpinBoxLayoutLength">
<property name="maximum">
<double>100000.000000000000000</double>
</property>
</widget>
</item> </item>
<item row="3" column="0"> <item row="3" column="0">
<widget class="QLabel" name="labelLayoutLength"> <widget class="QLabel" name="labelLayoutLength">
@ -850,8 +858,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>356</width> <width>98</width>
<height>760</height> <height>41</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_3"> <layout class="QVBoxLayout" name="verticalLayout_3">
@ -930,8 +938,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>356</width> <width>98</width>
<height>760</height> <height>41</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_4"> <layout class="QVBoxLayout" name="verticalLayout_4">
@ -1064,6 +1072,7 @@
</tabstops> </tabstops>
<resources> <resources>
<include location="share/resources/puzzleicon.qrc"/> <include location="share/resources/puzzleicon.qrc"/>
<include location="share/resources/puzzleicon.qrc"/>
</resources> </resources>
<connections/> <connections/>
</ui> </ui>

View File

@ -0,0 +1,85 @@
/************************************************************************
**
** @file vpuzzlelayer.cpp
** @author Ronan Le Tiec
** @date 13 4, 2020
**
** @brief
** @copyright
** This source code is part of the Valentina project, a pattern making
** program, whose allow create and modeling patterns of clothing.
** Copyright (C) 2020 Valentina project
** <https://gitlab.com/smart-pattern/valentina> 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 <http://www.gnu.org/licenses/>.
**
*************************************************************************/
#include "vpuzzlelayer.h"
//---------------------------------------------------------------------------------------------------------------------
VPuzzleLayer::VPuzzleLayer() :
m_name(QString("")),
m_pieces(QList<VPuzzlePiece*>()),
m_isVisible(true)
{
}
//---------------------------------------------------------------------------------------------------------------------
VPuzzleLayer::~VPuzzleLayer()
{
}
//---------------------------------------------------------------------------------------------------------------------
QList<VPuzzlePiece *> VPuzzleLayer::GetPieces()
{
return m_pieces;
}
//---------------------------------------------------------------------------------------------------------------------
void VPuzzleLayer::AddPiece(VPuzzlePiece *piece)
{
m_pieces.append(piece);
}
//---------------------------------------------------------------------------------------------------------------------
void VPuzzleLayer::RemovePiece(VPuzzlePiece *piece)
{
m_pieces.removeAll(piece);
}
//---------------------------------------------------------------------------------------------------------------------
QString VPuzzleLayer::GetName()
{
return m_name;
}
//---------------------------------------------------------------------------------------------------------------------
void VPuzzleLayer::SetName(QString name)
{
m_name = name;
}
//---------------------------------------------------------------------------------------------------------------------
void VPuzzleLayer::SetIsVisible(bool value)
{
m_isVisible = value;
}
//---------------------------------------------------------------------------------------------------------------------
bool VPuzzleLayer::GetIsVisible()
{
return m_isVisible;
}

View File

@ -0,0 +1,62 @@
/************************************************************************
**
** @file vpuzzlelayer.h
** @author Ronan Le Tiec
** @date 13 4, 2020
**
** @brief
** @copyright
** This source code is part of the Valentina project, a pattern making
** program, whose allow create and modeling patterns of clothing.
** Copyright (C) 2020 Valentina project
** <https://gitlab.com/smart-pattern/valentina> 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 <http://www.gnu.org/licenses/>.
**
*************************************************************************/
#ifndef VPUZZLELAYER_H
#define VPUZZLELAYER_H
#include <QList>
#include "vpuzzlepiece.h"
class VPuzzleLayer
{
public:
VPuzzleLayer();
~VPuzzleLayer();
QList<VPuzzlePiece *> GetPieces();
void AddPiece(VPuzzlePiece *piece);
void RemovePiece(VPuzzlePiece *piece);
// here add some more function if we want to add/move a piece at a
// certain position in the list
QString GetName();
void SetName(QString name);
void SetIsVisible(bool value);
bool GetIsVisible();
private:
QString m_name;
QList<VPuzzlePiece *> m_pieces;
// control
bool m_isVisible;
};
#endif // VPUZZLELAYER_H

View File

@ -0,0 +1,249 @@
/************************************************************************
**
** @file vpuzzlelayout.cpp
** @author Ronan Le Tiec
** @date 13 4, 2020
**
** @brief
** @copyright
** This source code is part of the Valentina project, a pattern making
** program, whose allow create and modeling patterns of clothing.
** Copyright (C) 2020 Valentina project
** <https://gitlab.com/smart-pattern/valentina> 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 <http://www.gnu.org/licenses/>.
**
*************************************************************************/
#include "vpuzzlelayout.h"
//---------------------------------------------------------------------------------------------------------------------
VPuzzleLayout::VPuzzleLayout() :
m_unplacedPiecesLayer(new VPuzzleLayer()),
m_layers(QList<VPuzzleLayer *>()),
m_unit(Unit::Cm),
m_size(QSizeF()),
m_margins(QMarginsF()),
m_followGrainLine(FollowGrainline::No),
m_piecesGap(0),
m_warningSuperpositionOfPieces(false),
m_warningPiecesOutOfBound(false),
m_stickyEdges(false)
{
}
//---------------------------------------------------------------------------------------------------------------------
VPuzzleLayout::~VPuzzleLayout()
{
// TODO
}
//---------------------------------------------------------------------------------------------------------------------
VPuzzleLayer* VPuzzleLayout::GetUnplacedPiecesLayer()
{
return m_unplacedPiecesLayer;
}
//---------------------------------------------------------------------------------------------------------------------
VPuzzleLayer* VPuzzleLayout::AddLayer()
{
VPuzzleLayer *newLayer = new VPuzzleLayer();
m_layers.append(newLayer);
return newLayer;
}
//---------------------------------------------------------------------------------------------------------------------
VPuzzleLayer* VPuzzleLayout::AddLayer(VPuzzleLayer *layer)
{
m_layers.append(layer);
return layer;
}
//---------------------------------------------------------------------------------------------------------------------
QList<VPuzzleLayer *> VPuzzleLayout::GetLayers()
{
return m_layers;
}
//---------------------------------------------------------------------------------------------------------------------
void VPuzzleLayout::SetUnit(Unit unit)
{
m_unit = unit;
}
//---------------------------------------------------------------------------------------------------------------------
Unit VPuzzleLayout::getUnit()
{
return m_unit;
}
//---------------------------------------------------------------------------------------------------------------------
void VPuzzleLayout::SetLayoutSize(qreal width, qreal height)
{
m_size.setWidth(width);
m_size.setHeight(height);
}
//---------------------------------------------------------------------------------------------------------------------
void VPuzzleLayout::SetLayoutSizeConverted(qreal width, qreal height)
{
m_size.setWidth(UnitConvertor(width, m_unit,Unit::Px));
m_size.setHeight(UnitConvertor(height, m_unit,Unit::Px));
}
//---------------------------------------------------------------------------------------------------------------------
void VPuzzleLayout::SetLayoutSize(QSizeF size)
{
m_size = size;
}
//---------------------------------------------------------------------------------------------------------------------
void VPuzzleLayout::SetLayoutSizeConverted(QSizeF size)
{
m_size = QSizeF(
UnitConvertor(size.width(), m_unit,Unit::Px),
UnitConvertor(size.height(), m_unit,Unit::Px)
);
}
//---------------------------------------------------------------------------------------------------------------------
QSizeF VPuzzleLayout::GetLayoutSize()
{
return m_size;
}
//---------------------------------------------------------------------------------------------------------------------
QSizeF VPuzzleLayout::GetLayoutSizeConverted()
{
QSizeF convertedSize = QSizeF(
UnitConvertor(m_size.width(), Unit::Px, m_unit),
UnitConvertor(m_size.height(), Unit::Px, m_unit)
);
return convertedSize;
}
//---------------------------------------------------------------------------------------------------------------------
void VPuzzleLayout::SetLayoutMargins(qreal left, qreal top, qreal right, qreal bottom)
{
m_margins.setLeft(left);
m_margins.setTop(top);
m_margins.setRight(right);
m_margins.setBottom(bottom);
}
//---------------------------------------------------------------------------------------------------------------------
void VPuzzleLayout::SetLayoutMarginsConverted(qreal left, qreal top, qreal right, qreal bottom)
{
m_margins.setLeft(UnitConvertor(left, m_unit, Unit::Px));
m_margins.setTop(UnitConvertor(top, m_unit, Unit::Px));
m_margins.setRight(UnitConvertor(right, m_unit, Unit::Px));
m_margins.setBottom(UnitConvertor(bottom, m_unit, Unit::Px));
}
//---------------------------------------------------------------------------------------------------------------------
void VPuzzleLayout::SetLayoutMargins(QMarginsF margins)
{
m_margins = margins;
}
//---------------------------------------------------------------------------------------------------------------------
void VPuzzleLayout::SetLayoutMarginsConverted(QMarginsF margins)
{
m_margins = UnitConvertor(margins, m_unit, Unit::Px);
}
//---------------------------------------------------------------------------------------------------------------------
QMarginsF VPuzzleLayout::GetLayoutMargins()
{
return m_margins;
}
//---------------------------------------------------------------------------------------------------------------------
QMarginsF VPuzzleLayout::GetLayoutMarginsConverted()
{
return UnitConvertor(m_margins, Unit::Px, m_unit);
}
//---------------------------------------------------------------------------------------------------------------------
void VPuzzleLayout::SetFollowGrainline(FollowGrainline state)
{
m_followGrainLine = state;
}
//---------------------------------------------------------------------------------------------------------------------
FollowGrainline VPuzzleLayout::SetFollowGrainline()
{
return m_followGrainLine;
}
//---------------------------------------------------------------------------------------------------------------------
void VPuzzleLayout::SetPiecesGap(qreal value)
{
m_piecesGap = value;
}
//---------------------------------------------------------------------------------------------------------------------
void VPuzzleLayout::SetPiecesGapConverted(qreal value)
{
m_piecesGap = UnitConvertor(value, m_unit, Unit::Px);
}
//---------------------------------------------------------------------------------------------------------------------
qreal VPuzzleLayout::GetPiecesGap()
{
return m_piecesGap;
}
//---------------------------------------------------------------------------------------------------------------------
qreal VPuzzleLayout::GetPiecesGapConverted()
{
return UnitConvertor(m_piecesGap, Unit::Px, m_unit);
}
//---------------------------------------------------------------------------------------------------------------------
void VPuzzleLayout::SetWarningSuperpositionOfPieces(bool state)
{
m_warningSuperpositionOfPieces = state;
}
//---------------------------------------------------------------------------------------------------------------------
bool VPuzzleLayout::GetWarningSuperpositionOfPieces()
{
return m_warningSuperpositionOfPieces;
}
//---------------------------------------------------------------------------------------------------------------------
void VPuzzleLayout::SetWarningPiecesOutOfBound(bool state)
{
m_warningPiecesOutOfBound = state;
}
//---------------------------------------------------------------------------------------------------------------------
bool VPuzzleLayout::GetWarningPiecesOutOfBound()
{
return m_warningPiecesOutOfBound;
}
//---------------------------------------------------------------------------------------------------------------------
void VPuzzleLayout::SetStickyEdges(bool state)
{
m_stickyEdges = state;
}
//---------------------------------------------------------------------------------------------------------------------
bool VPuzzleLayout::GetStickyEdges()
{
return m_stickyEdges;
}

View File

@ -0,0 +1,202 @@
/************************************************************************
**
** @file vpuzzlelayout.h
** @author Ronan Le Tiec
** @date 13 4, 2020
**
** @brief
** @copyright
** This source code is part of the Valentina project, a pattern making
** program, whose allow create and modeling patterns of clothing.
** Copyright (C) 2020 Valentina project
** <https://gitlab.com/smart-pattern/valentina> 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 <http://www.gnu.org/licenses/>.
**
*************************************************************************/
#ifndef VPUZZLELAYOUT_H
#define VPUZZLELAYOUT_H
#include <QSizeF>
#include <QMarginsF>
#include <QList>
#include "vpuzzlelayer.h"
#include "def.h"
// is this the right place for the definition?
enum class FollowGrainline : qint8 { No = 0, Follow90 = 1, Follow180 = 2};
class VPuzzleLayout
{
public:
VPuzzleLayout();
virtual ~VPuzzleLayout();
VPuzzleLayer* GetUnplacedPiecesLayer();
VPuzzleLayer* AddLayer();
VPuzzleLayer* AddLayer(VPuzzleLayer *layer);
QList<VPuzzleLayer *> GetLayers();
void SetUnit(Unit unit);
Unit getUnit();
/**
* @brief SetLayoutSize sets the size of the layout, the values have to be in Unit::Px
* @param width
* @param height
*/
void SetLayoutSize(qreal width, qreal height);
/**
* @brief SetLayoutSize sets the size of the layout, the values have to be in the layout's unit
* @param width
* @param height
*/
void SetLayoutSizeConverted(qreal width, qreal height);
/**
* @brief SetLayoutSize sets the size of the layout, the values have to be in Unit::Px
* @param size
*/
void SetLayoutSize(QSizeF size);
/**
* @brief SetLayoutSizeConverted sets the size of the layout, the values have to be in the layout's unit
* @param size
*/
void SetLayoutSizeConverted(QSizeF size);
/**
* @brief GetLayoutSize Returns the size in Unit::Px
* @return
*/
QSizeF GetLayoutSize();
/**
* @brief GetLayoutSizeConverted Returns the size in the layout's unit
* @return
*/
QSizeF GetLayoutSizeConverted();
/**
* @brief SetLayoutMargins, set the margins of the layout, the values have to be in Unit::Px
* @param left in Unit::Px
* @param top in Unit::Px
* @param right in Unit::Px
* @param bottom in Unit::Px
*/
void SetLayoutMargins(qreal left, qreal top, qreal right, qreal bottom);
/**
* @brief SetLayoutMargins, set the margins of the layout, the values have to be in the unit of the layout
* @param left in Unit::Px
* @param top in Unit::Px
* @param right in Unit::Px
* @param bottom in Unit::Px
*/
void SetLayoutMarginsConverted(qreal left, qreal top, qreal right, qreal bottom);
/**
* @brief SetLayoutMargins set the margins of the layout, the values have to be in Unit::Px
* @param margins
*/
void SetLayoutMargins(QMarginsF margins);
/**
* @brief SetLayoutMargins set the margins of the layout, the values have to be in the unit of the layout
* @param margins
*/
void SetLayoutMarginsConverted(QMarginsF margins);
/**
* @brief GetLayoutMargins Returns the size in Unit::Px
* @return
*/
QMarginsF GetLayoutMargins();
/**
* @brief GetLayoutMarginsConverted Returns the margins in the layout's unit
* @return
*/
QMarginsF GetLayoutMarginsConverted();
void SetFollowGrainline(FollowGrainline state);
FollowGrainline SetFollowGrainline();
/**
* @brief SetPiecesGap sets the pieces gap to the given value, the unit has to be in Unit::Px
* @param value
*/
void SetPiecesGap(qreal value);
/**
* @brief SetPiecesGapConverted sets the pieces gap to the given value, the unit has to be in the layout's unit
* @param value
*/
void SetPiecesGapConverted(qreal value);
/**
* @brief GetPiecesGap returns the pieces gap in Unit::Px
* @return
*/
qreal GetPiecesGap();
/**
* @brief GetPiecesGapConverted returns the pieces gap in the layout's unit
* @return
*/
qreal GetPiecesGapConverted();
void SetWarningSuperpositionOfPieces(bool state);
bool GetWarningSuperpositionOfPieces();
void SetWarningPiecesOutOfBound(bool state);
bool GetWarningPiecesOutOfBound();
void SetStickyEdges(bool state);
bool GetStickyEdges();
private:
Q_DISABLE_COPY(VPuzzleLayout)
VPuzzleLayer *m_unplacedPiecesLayer;
QList<VPuzzleLayer *> m_layers;
// format
Unit m_unit;
/**
* @brief m_size the Size in Unit::Px
*/
QSizeF m_size;
// margins
/**
* @brief m_margins the margins in Unit::Px
*/
QMarginsF m_margins;
// control
FollowGrainline m_followGrainLine;
/**
* @brief m_piecesGap the pieces gap in Unit::Px
*/
qreal m_piecesGap;
bool m_warningSuperpositionOfPieces;
bool m_warningPiecesOutOfBound;
bool m_stickyEdges;
};
#endif // VPUZZLELAYOUT_H

View File

@ -0,0 +1,41 @@
/************************************************************************
**
** @file vpuzzlepiece.cpp
** @author Ronan Le Tiec
** @date 13 4, 2020
**
** @brief
** @copyright
** This source code is part of the Valentina project, a pattern making
** program, whose allow create and modeling patterns of clothing.
** Copyright (C) 2020 Valentina project
** <https://gitlab.com/smart-pattern/valentina> 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 <http://www.gnu.org/licenses/>.
**
*************************************************************************/
#include "vpuzzlepiece.h"
//---------------------------------------------------------------------------------------------------------------------
VPuzzlePiece::VPuzzlePiece()
{
}
//---------------------------------------------------------------------------------------------------------------------
VPuzzlePiece::~VPuzzlePiece()
{
}

View File

@ -0,0 +1,41 @@
/************************************************************************
**
** @file vpuzzlepiece.h
** @author Ronan Le Tiec
** @date 13 4, 2020
**
** @brief
** @copyright
** This source code is part of the Valentina project, a pattern making
** program, whose allow create and modeling patterns of clothing.
** Copyright (C) 2020 Valentina project
** <https://gitlab.com/smart-pattern/valentina> 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 <http://www.gnu.org/licenses/>.
**
*************************************************************************/
#ifndef VPUZZLEPIECE_H
#define VPUZZLEPIECE_H
class VPuzzlePiece
{
public:
VPuzzlePiece();
~VPuzzlePiece();
private:
};
#endif // VPUZZLEPIECE_H

View File

@ -0,0 +1,305 @@
/************************************************************************
**
** @file vpuzzlelayoutfilereader.cpp
** @author Ronan Le Tiec
** @date 18 4, 2020
**
** @brief
** @copyright
** This source code is part of the Valentina project, a pattern making
** program, whose allow create and modeling patterns of clothing.
** Copyright (C) 2020 Valentina project
** <https://gitlab.com/smart-pattern/valentina> 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 <http://www.gnu.org/licenses/>.
**
** *************************************************************************/
#include <QXmlStreamAttributes>
#include "vpuzzlelayoutfilereader.h"
#include "vpuzzlelayoutfilewriter.h"
VPuzzleLayoutFileReader::VPuzzleLayoutFileReader()
{
}
//---------------------------------------------------------------------------------------------------------------------
VPuzzleLayoutFileReader::~VPuzzleLayoutFileReader()
{
// TODO
}
//---------------------------------------------------------------------------------------------------------------------
bool VPuzzleLayoutFileReader::ReadFile(VPuzzleLayout *layout, QFile *file)
{
setDevice(file);
if (readNextStartElement())
{
// TODO extend the handling
// if it doesn't start with layout, error
// if it starts with version > than current version, error
if (name() == QString("layout"))
{
QString versionStr = attributes().value(QString("version")).toString();
QStringList versionStrParts = versionStr.split('.');
m_layoutFormatVersion = FORMAT_VERSION(versionStrParts.at(0).toInt(),versionStrParts.at(1).toInt(),versionStrParts.at(2).toInt());
if(VPuzzleLayoutFileWriter::LayoutFileFormatVersion >= m_layoutFormatVersion)
{
ReadLayout(layout);
}
else
{
// TODO better error handling
raiseError(QObject::tr("You're trying to open a layout that was created with a newer version of puzzle"));
}
}
else
{
raiseError(QObject::tr("Wrong file structure"));
}
}
return !error();
}
//---------------------------------------------------------------------------------------------------------------------
void VPuzzleLayoutFileReader::ReadLayout(VPuzzleLayout *layout)
{
Q_ASSERT(isStartElement() && name() == QString("layout"));
while (readNextStartElement()) {
if (name() == QString("properties"))
{
ReadProperties(layout);
}
else if (name() == QString("layers"))
{
ReadLayers(layout);
}
else
{
// TODO error handling, we encountered a tag that isn't defined in the specification
}
}
}
//---------------------------------------------------------------------------------------------------------------------
void VPuzzleLayoutFileReader::ReadProperties(VPuzzleLayout *layout)
{
Q_ASSERT(isStartElement() && name() == QString("properties"));
while (readNextStartElement()) {
qDebug(name().toString().toLatin1());
if (name() == QString("unit"))
{
qDebug("read unit");
QString unit = readElementText();
if(unit == UnitsToStr(Unit::Inch))
{
layout->SetUnit(Unit::Inch);
}
else if(unit == UnitsToStr(Unit::Mm))
{
layout->SetUnit(Unit::Cm);
}
else // no condition here to have a default value just in case
{
layout->SetUnit(Unit::Cm);
}
}
else if (name() == QString("description"))
{
qDebug("read description");
QString description = readElementText();
// TODO read the description info
}
else if (name() == QString("size"))
{
qDebug("read size");
QSizeF size = ReadSize();
layout->SetLayoutSize(size);
readElementText();
}
else if (name() == QString("margin"))
{
qDebug("read margin");
QMarginsF margins = ReadMargins();
layout->SetLayoutMargins(margins);
readElementText();
}
else if (name() == QString("control"))
{
qDebug("read control");
QXmlStreamAttributes attribs = attributes();
// attribs.value("followGrainLine"); // TODO
layout->SetWarningSuperpositionOfPieces(attribs.value("warningSuperposition") == "true");
layout->SetWarningPiecesOutOfBound(attribs.value("warningOutOfBound") == "true");
layout->SetStickyEdges(attribs.value("stickyEdges") == "true");
layout->SetPiecesGap(attribs.value("piecesGap").toDouble());
readElementText();
}
else if (name() == QString("tiles"))
{
qDebug("read tiles");
ReadTiles(layout);
readElementText();
}
else
{
// TODO error handling, we encountered a tag that isn't defined in the specification
skipCurrentElement();
}
}
}
//---------------------------------------------------------------------------------------------------------------------
void VPuzzleLayoutFileReader::ReadTiles(VPuzzleLayout *layout)
{
Q_UNUSED(layout); // to be removed when used
Q_ASSERT(isStartElement() && name() == QString("tiles"));
QXmlStreamAttributes attribs = attributes();
// attribs.value("visible"); // TODO
// attribs.value("matchingMarks"); // TODO
while (readNextStartElement()) {
if (name() == QString("size"))
{
QSizeF size = ReadSize();
// TODO set layout tiled size
Q_UNUSED(size);
readElementText();
}
else if (name() == QString("margin"))
{
QMarginsF margins = ReadMargins();
// TODO set layout tiled margins
Q_UNUSED(margins);
readElementText();
}
else
{
// TODO error handling, we encountered a tag that isn't defined in the specification
skipCurrentElement();
}
}
}
//---------------------------------------------------------------------------------------------------------------------
void VPuzzleLayoutFileReader::ReadLayers(VPuzzleLayout *layout)
{
Q_ASSERT(isStartElement() && name() == QString("layers"));
while (readNextStartElement()) {
if (name() == QString("unplacedPiecesLayer"))
{
ReadLayer(layout->GetUnplacedPiecesLayer());
}
else if (name() == QString("layer"))
{
VPuzzleLayer *layer = layout->AddLayer();
ReadLayer(layer);
}
else
{
// TODO error handling, we encountered a tag that isn't defined in the specification
skipCurrentElement();
}
}
}
//---------------------------------------------------------------------------------------------------------------------
void VPuzzleLayoutFileReader::ReadLayer(VPuzzleLayer *layer)
{
Q_ASSERT(isStartElement() && name() == QString("layer"));
QXmlStreamAttributes attribs = attributes();
layer->SetName(attribs.value("name").toString());
layer->SetIsVisible(attribs.value("visible") == "true");
while (readNextStartElement()) {
if (name() == QString("piece"))
{
VPuzzlePiece *piece = new VPuzzlePiece();
ReadPiece(piece);
layer->AddPiece(piece);
}
else
{
// TODO error handling, we encountered a tag that isn't defined in the specification
skipCurrentElement();
}
}
}
//---------------------------------------------------------------------------------------------------------------------
void VPuzzleLayoutFileReader::ReadPiece(VPuzzlePiece *piece)
{
Q_UNUSED(piece);
Q_ASSERT(isStartElement() && name() == QString("piece"));
// TODO read the attributes
while (readNextStartElement()) {
if (name() == QString("..."))
{
// TODO
readElementText();
}
else
{
// TODO error handling, we encountered a tag that isn't defined in the specification
skipCurrentElement();
}
}
}
//---------------------------------------------------------------------------------------------------------------------
QMarginsF VPuzzleLayoutFileReader::ReadMargins()
{
QMarginsF margins = QMarginsF();
QXmlStreamAttributes attribs = attributes();
margins.setLeft(attribs.value("left").toDouble());
margins.setTop(attribs.value("top").toDouble());
margins.setRight(attribs.value("right").toDouble());
margins.setBottom(attribs.value("bottom").toDouble());
return margins;
}
//---------------------------------------------------------------------------------------------------------------------
QSizeF VPuzzleLayoutFileReader::ReadSize()
{
QSizeF size = QSize();
QXmlStreamAttributes attribs = attributes();
size.setWidth(attribs.value("width").toDouble());
size.setHeight(attribs.value("length").toDouble());
return size;
}

View File

@ -0,0 +1,64 @@
/************************************************************************
**
** @file vpuzzlelayoutfilereader.h
** @author Ronan Le Tiec
** @date 18 4, 2020
**
** @brief
** @copyright
** This source code is part of the Valentina project, a pattern making
** program, whose allow create and modeling patterns of clothing.
** Copyright (C) 2020 Valentina project
** <https://gitlab.com/smart-pattern/valentina> 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 <http://www.gnu.org/licenses/>.
**
** *************************************************************************/
#ifndef VPUZZLELAYOUTFILEREADER_H
#define VPUZZLELAYOUTFILEREADER_H
#include <QXmlStreamReader>
#include "../ifc/xml/vabstractconverter.h"
#include "vpuzzlelayout.h"
#include "vpuzzlelayer.h"
#include "vpuzzlepiece.h"
class VPuzzleLayoutFileReader : public QXmlStreamReader
{
public:
VPuzzleLayoutFileReader();
~VPuzzleLayoutFileReader();
bool ReadFile(VPuzzleLayout *layout, QFile *file);
private:
/**
* @brief m_layoutFormatVersion holds the version of the layout currently being read
*/
int m_layoutFormatVersion;
void ReadLayout(VPuzzleLayout *layout);
void ReadProperties(VPuzzleLayout *layout);
void ReadTiles(VPuzzleLayout *layout);
void ReadLayers(VPuzzleLayout *layout);
void ReadLayer(VPuzzleLayer *layer);
void ReadPiece(VPuzzlePiece *piece);
QMarginsF ReadMargins();
QSizeF ReadSize();
};
#endif // VPUZZLELAYOUTFILEREADER_H

View File

@ -0,0 +1,207 @@
/************************************************************************
**
** @file vpuzzlelayoutfilewriter.cpp
** @author Ronan Le Tiec
** @date 18 4, 2020
**
** @brief
** @copyright
** This source code is part of the Valentina project, a pattern making
** program, whose allow create and modeling patterns of clothing.
** Copyright (C) 2020 Valentina project
** <https://gitlab.com/smart-pattern/valentina> 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 <http://www.gnu.org/licenses/>.
**
*************************************************************************/
#include "vpuzzlelayoutfilewriter.h"
//---------------------------------------------------------------------------------------------------------------------
VPuzzleLayoutFileWriter::VPuzzleLayoutFileWriter()
{
}
//---------------------------------------------------------------------------------------------------------------------
VPuzzleLayoutFileWriter::~VPuzzleLayoutFileWriter()
{
}
//---------------------------------------------------------------------------------------------------------------------
void VPuzzleLayoutFileWriter::WriteFile(VPuzzleLayout *layout, QFile *file)
{
setDevice(file);
setAutoFormatting(true);
writeStartDocument();
WriteLayout(layout);
writeEndDocument();
file->close();
}
//---------------------------------------------------------------------------------------------------------------------
void VPuzzleLayoutFileWriter::WriteLayout(VPuzzleLayout *layout)
{
writeStartElement("layout");
writeAttribute("version", LayoutFileFormatVersionStr);
WriteProperties(layout);
WriteLayers(layout);
writeEndElement(); //layout
}
//---------------------------------------------------------------------------------------------------------------------
void VPuzzleLayoutFileWriter::WriteProperties(VPuzzleLayout *layout)
{
writeStartElement("properties");
writeTextElement("unit", UnitsToStr(layout->getUnit()));
writeTextElement("description", ""); // TODO : define the value in layout
WriteSize(layout->GetLayoutSize());
WriteMargins(layout->GetLayoutMargins());
writeStartElement("control");
writeAttribute("followGrainLine", "no"); // TODO / Fixme get the right value
writeAttribute("warningSuperposition", QString(layout->GetWarningSuperpositionOfPieces() ? "true" : "false"));
writeAttribute("warningOutOfBound", QString(layout->GetWarningPiecesOutOfBound() ? "true" : "false"));
writeAttribute("stickyEdges", QString(layout->GetStickyEdges() ? "true" : "false"));
writeAttribute("piecesGap", QString::number(layout->GetPiecesGap()));
writeEndElement(); // control
// WriteTiles(layout); TODO: when tile functionality implemented, then uncomment this line
writeEndElement(); // properties
}
//---------------------------------------------------------------------------------------------------------------------
void VPuzzleLayoutFileWriter::WriteTiles(VPuzzleLayout *layout)
{
Q_UNUSED(layout); // to be removed
writeStartElement("tiles");
writeAttribute("visible", QString(false ? "true" : "false")); // TODO / Fixme get the right value
writeAttribute("matchingMarks", "standard"); // TODO / Fixme get the right value
QSizeF size = QSizeF(); // TODO get the right size
WriteSize(size);
QMarginsF margins = QMarginsF(); // TODO get the right margins
WriteMargins(margins);
writeEndElement(); // tiles
}
//---------------------------------------------------------------------------------------------------------------------
void VPuzzleLayoutFileWriter::WriteLayers(VPuzzleLayout *layout)
{
writeStartElement("layers");
WriteLayer(layout->GetUnplacedPiecesLayer(), "unplacedPieces");
QList<VPuzzleLayer*> layers = layout->GetLayers();
for (auto layer : layers)
{
WriteLayer(layer);
}
writeEndElement(); // layers
}
//---------------------------------------------------------------------------------------------------------------------
void VPuzzleLayoutFileWriter::WriteLayer(VPuzzleLayer *layer)
{
WriteLayer(layer, "layer");
}
//---------------------------------------------------------------------------------------------------------------------
void VPuzzleLayoutFileWriter::WriteLayer(VPuzzleLayer *layer, const QString &tagName)
{
writeStartElement(tagName); // layer
writeAttribute("name", layer->GetName());
writeAttribute("visible", QString(layer->GetIsVisible()? "true" : "false"));
// TODO selected info. Not sure how it's saved yet
//writeAttribute("selected", QString(layer->GetIsSelected()? "true" : "false"));
QList<VPuzzlePiece*> pieces = layer->GetPieces();
for (auto piece : pieces)
{
WritePiece(piece);
}
writeEndElement(); // layer
}
//---------------------------------------------------------------------------------------------------------------------
void VPuzzleLayoutFileWriter::WritePiece(VPuzzlePiece *piece)
{
Q_UNUSED(piece);
writeStartElement("piece");
writeAttribute("id", "uuid1"); // TODO / Fixme get the right value
writeAttribute("name", "Piece name"); // TODO / Fixme get the right value
writeAttribute("mirrored", "false"); // TODO / Fixme get the right value
writeAttribute("transform", "string representation of the transformation"); // TODO / Fixme get the right value
// TODO cuttingLine
// TODO seamLine
// TODO grainline
// TODO passmarks
// TODO internal paths
// TODO placeLabels (buttonholes etc.)
// TODO labels
writeEndElement();
}
//---------------------------------------------------------------------------------------------------------------------
void VPuzzleLayoutFileWriter::WriteMargins(QMarginsF margins)
{
writeStartElement("margin");
writeAttribute("left", QString::number(margins.left()));
writeAttribute("top", QString::number(margins.top()));
writeAttribute("right", QString::number(margins.right()));
writeAttribute("bottom", QString::number(margins.bottom()));
writeEndElement(); // margin
}
//---------------------------------------------------------------------------------------------------------------------
void VPuzzleLayoutFileWriter::WriteSize(QSizeF size)
{
// maybe not necessary to test this, the writer should "stupidly write", the application should take care of these tests
qreal width = size.width();
if(width < 0) {
width = 0;
}
qreal length = size.height();
if(length < 0) {
length = 0;
}
writeStartElement("size");
writeAttribute("width", QString::number(width));
writeAttribute("length", QString::number(length));
writeEndElement(); // size
}

View File

@ -0,0 +1,76 @@
/************************************************************************
**
** @file vpuzzlelayoutfilewriter.h
** @author Ronan Le Tiec
** @date 18 4, 2020
**
** @brief
** @copyright
** This source code is part of the Valentina project, a pattern making
** program, whose allow create and modeling patterns of clothing.
** Copyright (C) 2020 Valentina project
** <https://gitlab.com/smart-pattern/valentina> 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 <http://www.gnu.org/licenses/>.
**
** *************************************************************************/
#ifndef VPUZZLELAYOUTFILEWRITER_H
#define VPUZZLELAYOUTFILEWRITER_H
#include <QXmlStreamWriter>
#include "../ifc/xml/vabstractconverter.h"
#include "vpuzzlelayout.h"
#include "vpuzzlelayer.h"
#include "vpuzzlepiece.h"
class VPuzzleLayoutFileWriter : public QXmlStreamWriter
{
public:
VPuzzleLayoutFileWriter();
~VPuzzleLayoutFileWriter();
void WriteFile(VPuzzleLayout *layout, QFile *file);
/*
* Version rules:
* 1. Version have three parts "major.minor.patch";
* 2. major part only for stable releases;
* 3. minor - 10 or more patch changes, or one big change;
* 4. patch - little change.
*/
/**
* @brief LayoutFileFormatVersion holds the version
*
*/
static Q_DECL_CONSTEXPR const int LayoutFileFormatVersion = FORMAT_VERSION(1, 0, 0);
const QString LayoutFileFormatVersionStr = QStringLiteral("1.0.0");
private:
void WriteLayout(VPuzzleLayout *layout);
void WriteProperties(VPuzzleLayout *layout);
void WriteTiles(VPuzzleLayout *layout);
void WriteLayers(VPuzzleLayout *layout);
void WriteLayer(VPuzzleLayer *layer);
void WriteLayer(VPuzzleLayer *layer, const QString &tagName);
void WritePiece(VPuzzlePiece *piece);
void WriteMargins(QMarginsF margins);
void WriteSize(QSizeF size);
};
#endif // VPUZZLELAYOUTFILEWRITER_H