Undo/Redo piece move.

This commit is contained in:
Roman Telezhynskyi 2021-08-17 18:49:28 +03:00
parent b638be5b2e
commit 0908b5a1f7
20 changed files with 834 additions and 164 deletions

View file

@ -42,13 +42,13 @@ auto VPMimeDataPiece::formats() const -> QStringList
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VPMimeDataPiece::GetPiecePtr() const -> VPPiece* auto VPMimeDataPiece::GetPiecePtr() const -> VPPiecePtr
{ {
return m_piece; return m_piece;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPMimeDataPiece::SetPiecePtr(VPPiece* piece) void VPMimeDataPiece::SetPiecePtr(const VPPiecePtr &piece)
{ {
m_piece = piece; m_piece = piece;
} }

View file

@ -31,7 +31,7 @@
#include <QMimeData> #include <QMimeData>
class VPPiece; #include "../layout/layoutdef.h"
class VPMimeDataPiece : public QMimeData class VPMimeDataPiece : public QMimeData
{ {
@ -47,13 +47,13 @@ public:
* @brief GetPiecePtr Returns the piece pointer of the mime data * @brief GetPiecePtr Returns the piece pointer of the mime data
* @return piece pointer * @return piece pointer
*/ */
auto GetPiecePtr() const -> VPPiece*; auto GetPiecePtr() const -> VPPiecePtr;
/** /**
* @brief SetPiecePtr sets the piece pointer to the given value * @brief SetPiecePtr sets the piece pointer to the given value
* @param piece the piece pointer * @param piece the piece pointer
*/ */
void SetPiecePtr(VPPiece* piece); void SetPiecePtr(const VPPiecePtr &piece);
static auto DragCursor(const QPixmap &piecePixmap) -> QPixmap; static auto DragCursor(const QPixmap &piecePixmap) -> QPixmap;
@ -62,7 +62,7 @@ public:
private: private:
Q_DISABLE_COPY(VPMimeDataPiece) Q_DISABLE_COPY(VPMimeDataPiece)
VPPiece *m_piece{nullptr}; VPPiecePtr m_piece{};
}; };
#endif // VPMIMEDATAPIECE_H #endif // VPMIMEDATAPIECE_H

View file

@ -78,7 +78,8 @@ auto VPPiece::GetPosition() -> QPointF
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPPiece::RotateToGrainline() void VPPiece::RotateToGrainline()
{ {
if (not IsGrainlineEnabled() || m_sheet == nullptr) VPSheetPtr sheet = Sheet();
if (not IsGrainlineEnabled() || sheet.isNull())
{ {
return; return;
} }
@ -94,7 +95,7 @@ void VPPiece::RotateToGrainline()
QLineF canonical(grainlinePoints.first().x(), grainlinePoints.first().y(), QLineF canonical(grainlinePoints.first().x(), grainlinePoints.first().y(),
grainlinePoints.first().x()+100, grainlinePoints.first().y()); grainlinePoints.first().x()+100, grainlinePoints.first().y());
GrainlineType grainlineType = m_sheet->GrainlineType(); GrainlineType grainlineType = sheet->GrainlineType();
auto DegreesAtFront = [grainline, canonical, grainlineType]() auto DegreesAtFront = [grainline, canonical, grainlineType]()
{ {
@ -147,25 +148,25 @@ auto VPPiece::IsSelected() const -> bool
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VPPiece::Sheet() const -> VPSheet * auto VPPiece::Sheet() const -> VPSheetPtr
{ {
return m_sheet; return m_sheet;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPPiece::SetSheet(VPSheet *newSheet) void VPPiece::SetSheet(const VPSheetPtr &newSheet)
{ {
m_sheet = newSheet; m_sheet = newSheet;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VPPiece::Layout() const -> VPLayout * auto VPPiece::Layout() const -> VPLayoutPtr
{ {
return m_layout; return m_layout;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPPiece::SetLayout(VPLayout *layout) void VPPiece::SetLayout(const VPLayoutPtr &layout)
{ {
SCASSERT(layout != nullptr) SCASSERT(layout != nullptr)
m_layout = layout; m_layout = layout;

View file

@ -34,6 +34,7 @@
#include <QTransform> #include <QTransform>
#include "../vlayout/vlayoutpiece.h" #include "../vlayout/vlayoutpiece.h"
#include "../layout/layoutdef.h"
class VPLayout; class VPLayout;
class VPSheet; class VPSheet;
@ -77,11 +78,11 @@ public:
*/ */
auto IsSelected() const -> bool; auto IsSelected() const -> bool;
auto Sheet() const -> VPSheet *; auto Sheet() const -> VPSheetPtr;
void SetSheet(VPSheet *newSheet); void SetSheet(const VPSheetPtr &newSheet);
auto Layout() const -> VPLayout *; auto Layout() const -> VPLayoutPtr;
void SetLayout(VPLayout *layout); void SetLayout(const VPLayoutPtr &layout);
void SetGrainlineEnabled(bool enabled); void SetGrainlineEnabled(bool enabled);
void SetGrainlineAngle(qreal angle); void SetGrainlineAngle(qreal angle);
@ -103,11 +104,13 @@ public:
private: private:
Q_DISABLE_COPY(VPPiece) Q_DISABLE_COPY(VPPiece)
VPLayout *m_layout{nullptr}; VPLayoutWeakPtr m_layout{};
VPSheet *m_sheet{nullptr}; VPSheetWeakPtr m_sheet{};
bool m_isSelected{false}; bool m_isSelected{false};
}; };
Q_DECLARE_METATYPE(VPPiecePtr)
#endif // VPPIECE_H #endif // VPPIECE_H

View file

@ -30,27 +30,27 @@
#include "vplayout.h" #include "vplayout.h"
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
VPSheet::VPSheet(VPLayout* layout) : VPSheet::VPSheet(const VPLayoutPtr &layout) :
QObject(layout),
m_layout(layout) m_layout(layout)
{ {
SCASSERT(layout != nullptr) SCASSERT(layout != nullptr)
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VPSheet::GetLayout() -> VPLayout* auto VPSheet::GetLayout() const -> VPLayoutPtr
{ {
return m_layout; return m_layout;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VPSheet::GetPieces() const -> QList<VPPiece *> auto VPSheet::GetPieces() const -> QList<VPPiecePtr>
{ {
QList<VPPiece *> list; QList<VPPiecePtr> list;
if (m_layout != nullptr) VPLayoutPtr layout = GetLayout();
if (not layout.isNull())
{ {
return m_layout->PiecesForSheet(this); return layout->PiecesForSheet(m_uuid);
} }
return {}; return {};
@ -89,9 +89,10 @@ void VPSheet::SetVisible(bool visible)
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VPSheet::GrainlineType() const -> enum GrainlineType auto VPSheet::GrainlineType() const -> enum GrainlineType
{ {
if (m_layout != nullptr) VPLayoutPtr layout = GetLayout();
if (not layout.isNull())
{ {
QSizeF size = m_layout->LayoutSettings().GetSheetSize(); QSizeF size = layout->LayoutSettings().GetSheetSize();
if (size.height() < size.width()) if (size.height() < size.width())
{ {
return GrainlineType::Horizontal; return GrainlineType::Horizontal;
@ -112,3 +113,11 @@ void VPSheet::SetTransformationOrigin(const VPTransformationOrigon &newTransform
{ {
m_transformationOrigin = newTransformationOrigin; m_transformationOrigin = newTransformationOrigin;
} }
//---------------------------------------------------------------------------------------------------------------------
void VPSheet::Clear()
{
m_name.clear();
m_visible = true;
m_transformationOrigin = VPTransformationOrigon();
}

View file

@ -28,7 +28,6 @@
#ifndef VPSHEET_H #ifndef VPSHEET_H
#define VPSHEET_H #define VPSHEET_H
#include <QObject>
#include <QSizeF> #include <QSizeF>
#include <QMarginsF> #include <QMarginsF>
#include <QList> #include <QList>
@ -36,6 +35,7 @@
#include <QUuid> #include <QUuid>
#include "def.h" #include "def.h"
#include "layoutdef.h"
class VPLayout; class VPLayout;
class VPPiece; class VPPiece;
@ -52,11 +52,10 @@ struct VPTransformationOrigon
bool custom{false}; bool custom{false};
}; };
class VPSheet : public QObject class VPSheet
{ {
Q_OBJECT
public: public:
explicit VPSheet(VPLayout* layout); explicit VPSheet(const VPLayoutPtr &layout);
virtual ~VPSheet() = default; virtual ~VPSheet() = default;
@ -64,9 +63,9 @@ public:
* @brief GetLayout Returns the Layout of the sheet * @brief GetLayout Returns the Layout of the sheet
* @return Layout of the sheet * @return Layout of the sheet
*/ */
auto GetLayout() -> VPLayout*; auto GetLayout() const -> VPLayoutPtr;
auto GetPieces() const -> QList<VPPiece *>; auto GetPieces() const -> QList<VPPiecePtr>;
/** /**
* @brief GetName Returns the name of the sheet * @brief GetName Returns the name of the sheet
@ -90,10 +89,12 @@ public:
auto TransformationOrigin() const -> const VPTransformationOrigon &; auto TransformationOrigin() const -> const VPTransformationOrigon &;
void SetTransformationOrigin(const VPTransformationOrigon &newTransformationOrigin); void SetTransformationOrigin(const VPTransformationOrigon &newTransformationOrigin);
void Clear();
private: private:
Q_DISABLE_COPY(VPSheet) Q_DISABLE_COPY(VPSheet)
VPLayout *m_layout; VPLayoutWeakPtr m_layout{};
QString m_name{}; QString m_name{};
@ -104,4 +105,6 @@ private:
VPTransformationOrigon m_transformationOrigin{}; VPTransformationOrigon m_transformationOrigin{};
}; };
Q_DECLARE_METATYPE(VPSheetPtr)
#endif // VPSHEET_H #endif // VPSHEET_H

View file

@ -32,6 +32,7 @@
#include <QMimeData> #include <QMimeData>
#include <QKeyEvent> #include <QKeyEvent>
#include <QMenu> #include <QMenu>
#include <QUndoStack>
#include "../scene/vpgraphicssheet.h" #include "../scene/vpgraphicssheet.h"
#include "../scene/vpgraphicspiece.h" #include "../scene/vpgraphicspiece.h"
@ -44,6 +45,7 @@
#include "../vwidgets/vmaingraphicsscene.h" #include "../vwidgets/vmaingraphicsscene.h"
#include "vptilefactory.h" #include "vptilefactory.h"
#include "vpgraphicspiececontrols.h" #include "vpgraphicspiececontrols.h"
#include "../undocommands/vpundopiecemove.h"
#include <QLoggingCategory> #include <QLoggingCategory>
@ -56,12 +58,12 @@ const QKeySequence restoreOriginShortcut = QKeySequence(Qt::ControlModifier + Qt
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
VPMainGraphicsView::VPMainGraphicsView(VPLayout *layout, VPTileFactory *tileFactory, QWidget *parent) : VPMainGraphicsView::VPMainGraphicsView(const VPLayoutPtr &layout, VPTileFactory *tileFactory, QWidget *parent) :
VMainGraphicsView(parent), VMainGraphicsView(parent),
m_scene(new VMainGraphicsScene(this)), m_scene(new VMainGraphicsScene(this)),
m_layout(layout) m_layout(layout)
{ {
SCASSERT(m_layout != nullptr) SCASSERT(not m_layout.isNull())
setScene(m_scene); setScene(m_scene);
m_graphicsSheet = new VPGraphicsSheet(m_layout); m_graphicsSheet = new VPGraphicsSheet(m_layout);
@ -87,7 +89,7 @@ VPMainGraphicsView::VPMainGraphicsView(VPLayout *layout, VPTileFactory *tileFact
m_rotationOrigin, &VPGraphicsTransformationOrigin::SetTransformationOrigin); m_rotationOrigin, &VPGraphicsTransformationOrigin::SetTransformationOrigin);
// add the connections // add the connections
connect(m_layout, &VPLayout::PieceSheetChanged, this, &VPMainGraphicsView::on_PieceSheetChanged); connect(layout.get(), &VPLayout::PieceSheetChanged, this, &VPMainGraphicsView::on_PieceSheetChanged);
auto *restoreOrigin = new QAction(this); auto *restoreOrigin = new QAction(this);
restoreOrigin->setShortcut(restoreOriginShortcut); restoreOrigin->setShortcut(restoreOriginShortcut);
@ -143,13 +145,18 @@ void VPMainGraphicsView::RefreshPieces()
qDeleteAll(m_graphicsPieces); qDeleteAll(m_graphicsPieces);
m_graphicsPieces.clear(); m_graphicsPieces.clear();
VPSheet *sheet = m_layout->GetFocusedSheet(); VPLayoutPtr layout = m_layout.toStrongRef();
if (sheet != nullptr) if (not layout.isNull())
{ {
QList<VPPiece *> pieces = sheet->GetPieces(); VPSheetPtr sheet = layout->GetFocusedSheet();
if (not sheet.isNull())
{
QList<VPPiecePtr> pieces = sheet->GetPieces();
m_graphicsPieces.reserve(pieces.size()); m_graphicsPieces.reserve(pieces.size());
for (auto *piece : pieces) for (const auto &piece : pieces)
{
if (not piece.isNull())
{ {
auto *graphicsPiece = new VPGraphicsPiece(piece); auto *graphicsPiece = new VPGraphicsPiece(piece);
m_graphicsPieces.append(graphicsPiece); m_graphicsPieces.append(graphicsPiece);
@ -157,6 +164,8 @@ void VPMainGraphicsView::RefreshPieces()
ConnectPiece(graphicsPiece); ConnectPiece(graphicsPiece);
} }
} }
}
}
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -171,11 +180,15 @@ void VPMainGraphicsView::PrepareForExport()
m_graphicsSheet->SetShowBorder(false); m_graphicsSheet->SetShowBorder(false);
m_graphicsSheet->SetShowMargin(false); m_graphicsSheet->SetShowMargin(false);
m_showGridTmp = m_layout->GetFocusedSheet()->GetLayout()->LayoutSettings().GetShowGrid(); VPLayoutPtr layout = m_layout.toStrongRef();
m_layout->GetFocusedSheet()->GetLayout()->LayoutSettings().SetShowGrid(false); if (not layout.isNull())
{
m_showGridTmp = layout->GetFocusedSheet()->GetLayout()->LayoutSettings().GetShowGrid();
layout->GetFocusedSheet()->GetLayout()->LayoutSettings().SetShowGrid(false);
m_showTilesTmp = m_layout->LayoutSettings().GetShowTiles(); m_showTilesTmp = layout->LayoutSettings().GetShowTiles();
m_layout->LayoutSettings().SetShowTiles(false); layout->LayoutSettings().SetShowTiles(false);
}
RefreshLayout(); RefreshLayout();
} }
@ -186,9 +199,13 @@ void VPMainGraphicsView::CleanAfterExport()
m_graphicsSheet->SetShowBorder(true); m_graphicsSheet->SetShowBorder(true);
m_graphicsSheet->SetShowMargin(true); m_graphicsSheet->SetShowMargin(true);
m_layout->GetFocusedSheet()->GetLayout()->LayoutSettings().SetShowGrid(m_showGridTmp); VPLayoutPtr layout = m_layout.toStrongRef();
if (not layout.isNull())
{
layout->GetFocusedSheet()->GetLayout()->LayoutSettings().SetShowGrid(m_showGridTmp);
m_layout->LayoutSettings().SetShowTiles(m_showTilesTmp); layout->LayoutSettings().SetShowTiles(m_showTilesTmp);
}
RefreshLayout(); RefreshLayout();
} }
@ -233,9 +250,15 @@ void VPMainGraphicsView::dropEvent(QDropEvent *event)
{ {
const auto *mimePiece = qobject_cast<const VPMimeDataPiece *> (mime); const auto *mimePiece = qobject_cast<const VPMimeDataPiece *> (mime);
VPPiece *piece = mimePiece->GetPiecePtr(); VPPiecePtr piece = mimePiece->GetPiecePtr();
if(piece != nullptr) if(not piece.isNull())
{ {
VPLayoutPtr layout = m_layout.toStrongRef();
if (layout.isNull())
{
return;
}
qCDebug(pMainGraphicsView(), "element dropped, %s", qUtf8Printable(piece->GetName())); qCDebug(pMainGraphicsView(), "element dropped, %s", qUtf8Printable(piece->GetName()));
event->acceptProposedAction(); event->acceptProposedAction();
@ -243,7 +266,7 @@ void VPMainGraphicsView::dropEvent(QDropEvent *event)
piece->SetPosition(mapToScene(event->pos())); piece->SetPosition(mapToScene(event->pos()));
// change the piecelist of the piece // change the piecelist of the piece
piece->SetSheet(m_layout->GetFocusedSheet()); piece->SetSheet(layout->GetFocusedSheet());
auto *graphicsPiece = new VPGraphicsPiece(piece); auto *graphicsPiece = new VPGraphicsPiece(piece);
m_graphicsPieces.append(graphicsPiece); m_graphicsPieces.append(graphicsPiece);
@ -264,12 +287,12 @@ void VPMainGraphicsView::keyPressEvent(QKeyEvent *event)
{ {
for(auto *graphicsPiece : m_graphicsPieces) for(auto *graphicsPiece : m_graphicsPieces)
{ {
VPPiece *piece = graphicsPiece->GetPiece(); VPPiecePtr piece = graphicsPiece->GetPiece();
if(piece->IsSelected()) if(not piece.isNull() && piece->IsSelected())
{ {
piece->SetSelected(false); piece->SetSelected(false);
piece->SetSheet(nullptr); piece->SetSheet(VPSheetPtr());
m_graphicsPieces.removeAll(graphicsPiece); m_graphicsPieces.removeAll(graphicsPiece);
delete graphicsPiece; delete graphicsPiece;
} }
@ -321,6 +344,17 @@ void VPMainGraphicsView::keyPressEvent(QKeyEvent *event)
} }
} }
//---------------------------------------------------------------------------------------------------------------------
void VPMainGraphicsView::keyReleaseEvent(QKeyEvent *event)
{
VMainGraphicsView::keyReleaseEvent(event);
if (event->key() != Qt::Key_Left && event->key() != Qt::Key_Right && event->key() != Qt::Key_Up &&
event->key() != Qt::Key_Down)
{
m_allowChangeMerge = false;
}
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPMainGraphicsView::contextMenuEvent(QContextMenuEvent *event) void VPMainGraphicsView::contextMenuEvent(QContextMenuEvent *event)
{ {
@ -331,15 +365,22 @@ void VPMainGraphicsView::contextMenuEvent(QContextMenuEvent *event)
return; return;
} }
VPLayoutPtr layout = m_layout.toStrongRef();
if (layout.isNull())
{
return;
}
VPSheetPtr sheet = layout->GetFocusedSheet();
QMenu menu; QMenu menu;
VPSheet *sheet = m_layout->GetFocusedSheet();
QAction *restoreOriginAction = menu.addAction(tr("Restore transformation origin")); QAction *restoreOriginAction = menu.addAction(tr("Restore transformation origin"));
restoreOriginAction->setShortcut(restoreOriginShortcut); restoreOriginAction->setShortcut(restoreOriginShortcut);
restoreOriginAction->setEnabled(sheet != nullptr && sheet->TransformationOrigin().custom); restoreOriginAction->setEnabled(not sheet.isNull() && sheet->TransformationOrigin().custom);
QAction *removeSheetAction = menu.addAction(QIcon::fromTheme(QStringLiteral("edit-delete")), tr("Remove sheet")); QAction *removeSheetAction = menu.addAction(QIcon::fromTheme(QStringLiteral("edit-delete")), tr("Remove sheet"));
removeSheetAction->setEnabled(sheet != nullptr && m_layout->GetSheets().size() > 1); removeSheetAction->setEnabled(not sheet.isNull() && layout->GetSheets().size() > 1);
QAction *selectedAction = menu.exec(event->globalPos()); QAction *selectedAction = menu.exec(event->globalPos());
if (selectedAction == removeSheetAction) if (selectedAction == removeSheetAction)
@ -348,16 +389,18 @@ void VPMainGraphicsView::contextMenuEvent(QContextMenuEvent *event)
{ {
sheet->SetVisible(false); sheet->SetVisible(false);
QList<VPPiece *> pieces = sheet->GetPieces(); QList<VPPiecePtr> pieces = sheet->GetPieces();
for (auto *piece : pieces) for (const auto &piece : pieces)
{
if (not piece.isNull())
{ {
piece->SetSheet(nullptr); piece->SetSheet(nullptr);
} }
} }
}
m_layout->SetFocusedSheet(nullptr); layout->SetFocusedSheet(VPSheetPtr());
emit on_SheetRemoved(); emit on_SheetRemoved();
RefreshPieces();
} }
else if (selectedAction == restoreOriginAction) else if (selectedAction == restoreOriginAction)
{ {
@ -369,8 +412,14 @@ void VPMainGraphicsView::contextMenuEvent(QContextMenuEvent *event)
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPMainGraphicsView::RestoreOrigin() const void VPMainGraphicsView::RestoreOrigin() const
{ {
VPSheet *sheet = m_layout->GetFocusedSheet(); VPLayoutPtr layout = m_layout.toStrongRef();
if (sheet != nullptr) if (layout.isNull())
{
return;
}
VPSheetPtr sheet = layout->GetFocusedSheet();
if (not sheet.isNull())
{ {
VPTransformationOrigon origin = sheet->TransformationOrigin(); VPTransformationOrigon origin = sheet->TransformationOrigin();
origin.custom = false; origin.custom = false;
@ -420,9 +469,13 @@ void VPMainGraphicsView::ConnectPiece(VPGraphicsPiece *piece)
{ {
SCASSERT(piece != nullptr) SCASSERT(piece != nullptr)
VPLayoutPtr layout = m_layout.toStrongRef();
connect(layout.get(), &VPLayout::PieceTransformationChanged, piece,
&VPGraphicsPiece::on_RefreshPiece);
connect(piece, &VPGraphicsPiece::PieceSelectionChanged, connect(piece, &VPGraphicsPiece::PieceSelectionChanged,
m_rotationControls, &VPGraphicsPieceControls::on_UpdateControls); m_rotationControls, &VPGraphicsPieceControls::on_UpdateControls);
connect(piece, &VPGraphicsPiece::PiecePositionChanged, connect(piece, &VPGraphicsPiece::PieceTransformationChanged,
m_rotationControls, &VPGraphicsPieceControls::on_UpdateControls); m_rotationControls, &VPGraphicsPieceControls::on_UpdateControls);
connect(m_rotationControls, &VPGraphicsPieceControls::Rotate, piece, &VPGraphicsPiece::on_Rotate); connect(m_rotationControls, &VPGraphicsPieceControls::Rotate, piece, &VPGraphicsPiece::on_Rotate);
connect(piece, &VPGraphicsPiece::HideTransformationHandles, connect(piece, &VPGraphicsPiece::HideTransformationHandles,
@ -434,8 +487,14 @@ void VPMainGraphicsView::ConnectPiece(VPGraphicsPiece *piece)
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPMainGraphicsView::RotatePiecesByAngle(qreal angle) const void VPMainGraphicsView::RotatePiecesByAngle(qreal angle) const
{ {
VPSheet *sheet = m_layout->GetFocusedSheet(); VPLayoutPtr layout = m_layout.toStrongRef();
if (sheet == nullptr) if (layout.isNull())
{
return;
}
VPSheetPtr sheet = layout->GetFocusedSheet();
if (sheet.isNull())
{ {
return; return;
} }
@ -453,20 +512,56 @@ void VPMainGraphicsView::RotatePiecesByAngle(qreal angle) const
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPMainGraphicsView::TranslatePiecesOn(qreal dx, qreal dy) const void VPMainGraphicsView::TranslatePiecesOn(qreal dx, qreal dy)
{ {
for(auto *graphicsPiece : m_graphicsPieces) if (m_graphicsPieces.isEmpty())
{
return;
}
VPPiecePtr piece = m_graphicsPieces.first()->GetPiece();
if (piece.isNull())
{
return;
}
VPLayoutPtr layout = piece->Layout();
if (layout.isNull())
{
return;
}
auto PreparePieces = [this]()
{
QVector<VPPiecePtr> pieces;
for (auto *graphicsPiece : m_graphicsPieces)
{ {
if (graphicsPiece->isSelected()) if (graphicsPiece->isSelected())
{ {
graphicsPiece->TranslatePiece(dx, dy); pieces.append(graphicsPiece->GetPiece());
m_rotationControls->on_UpdateControls();
} }
} }
return pieces;
};
QVector<VPPiecePtr> pieces = PreparePieces();
if (pieces.size() == 1)
{
auto *command = new VPUndoPieceMove(pieces.first(), dx, dy, m_allowChangeMerge);
layout->UndoStack()->push(command);
}
else if (pieces.size() > 1)
{
auto *command = new VPUndoPiecesMove(pieces, dx, dy, m_allowChangeMerge);
layout->UndoStack()->push(command);
}
m_allowChangeMerge = true;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPMainGraphicsView::on_PieceSheetChanged(VPPiece *piece) void VPMainGraphicsView::on_PieceSheetChanged(const VPPiecePtr &piece)
{ {
VPGraphicsPiece *_graphicsPiece = nullptr; VPGraphicsPiece *_graphicsPiece = nullptr;
for(auto *graphicPiece : m_graphicsPieces) for(auto *graphicPiece : m_graphicsPieces)
@ -477,8 +572,14 @@ void VPMainGraphicsView::on_PieceSheetChanged(VPPiece *piece)
} }
} }
if (piece->Sheet() == nullptr || piece->Sheet() == m_layout->GetTrashSheet() || VPLayoutPtr layout = piece->Layout();
piece->Sheet() != m_layout->GetFocusedSheet()) // remove if (layout.isNull())
{
return;
}
if (piece->Sheet().isNull() || piece->Sheet() == layout->GetTrashSheet() ||
piece->Sheet() != layout->GetFocusedSheet()) // remove
{ {
if (_graphicsPiece != nullptr) if (_graphicsPiece != nullptr)
{ {

View file

@ -30,6 +30,7 @@
#define VPMAINGRAPHICSVIEW_H #define VPMAINGRAPHICSVIEW_H
#include "../vwidgets/vmaingraphicsview.h" #include "../vwidgets/vmaingraphicsview.h"
#include "../layout/layoutdef.h"
class VMainGraphicsScene; class VMainGraphicsScene;
class VPGraphicsPieceControls; class VPGraphicsPieceControls;
@ -45,7 +46,7 @@ class VPMainGraphicsView : public VMainGraphicsView
{ {
Q_OBJECT Q_OBJECT
public: public:
VPMainGraphicsView(VPLayout *layout, VPTileFactory *tileFactory, QWidget *parent); VPMainGraphicsView(const VPLayoutPtr &layout, VPTileFactory *tileFactory, QWidget *parent);
~VPMainGraphicsView() = default; ~VPMainGraphicsView() = default;
/** /**
@ -78,7 +79,7 @@ public slots:
* the other given piece list * the other given piece list
* @param piece the piece that was moved * @param piece the piece that was moved
*/ */
void on_PieceSheetChanged(VPPiece *piece); void on_PieceSheetChanged(const VPPiecePtr &piece);
void RefreshPieces(); void RefreshPieces();
@ -89,6 +90,7 @@ protected:
void dropEvent(QDropEvent *event) override; void dropEvent(QDropEvent *event) override;
void keyPressEvent(QKeyEvent *event) override; void keyPressEvent(QKeyEvent *event) override;
void keyReleaseEvent(QKeyEvent *event) override;
void contextMenuEvent(QContextMenuEvent *event) override; void contextMenuEvent(QContextMenuEvent *event) override;
@ -115,7 +117,7 @@ private:
VPGraphicsPieceControls *m_rotationControls{nullptr}; VPGraphicsPieceControls *m_rotationControls{nullptr};
VPGraphicsTransformationOrigin *m_rotationOrigin{nullptr}; VPGraphicsTransformationOrigin *m_rotationOrigin{nullptr};
VPLayout *m_layout; VPLayoutWeakPtr m_layout;
QList<VPGraphicsPiece*> m_graphicsPieces{}; QList<VPGraphicsPiece*> m_graphicsPieces{};
@ -128,11 +130,12 @@ private:
* variable to hold temporarly hte value of the show grid * variable to hold temporarly hte value of the show grid
*/ */
bool m_showGridTmp{false}; bool m_showGridTmp{false};
bool m_allowChangeMerge{false};
void ConnectPiece(VPGraphicsPiece *piece); void ConnectPiece(VPGraphicsPiece *piece);
void RotatePiecesByAngle(qreal angle) const; void RotatePiecesByAngle(qreal angle) const;
void TranslatePiecesOn(qreal dx, qreal dy) const; void TranslatePiecesOn(qreal dx, qreal dy);
}; };

View file

@ -0,0 +1,35 @@
/************************************************************************
**
** @file vpundocommand.cpp
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 16 8, 2021
**
** @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) 2021 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 "vpundocommand.h"
Q_LOGGING_CATEGORY(vpUndo, "vp.undo")
//---------------------------------------------------------------------------------------------------------------------
VPUndoCommand::VPUndoCommand(QUndoCommand *parent)
: QUndoCommand(parent)
{}

View file

@ -0,0 +1,57 @@
/************************************************************************
**
** @file vpundocommand.h
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 16 8, 2021
**
** @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) 2021 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 VPUNDOCOMMAND_H
#define VPUNDOCOMMAND_H
#include <QObject>
#include <QUndoCommand>
#include <QLoggingCategory>
namespace ML
{
enum class UndoCommand: qint8
{
MovePiece = 0,
MovePieces = 1
};
}
Q_DECLARE_LOGGING_CATEGORY(vpUndo)
class VPUndoCommand : public QObject, public QUndoCommand
{
Q_OBJECT
public:
explicit VPUndoCommand(QUndoCommand *parent = nullptr);
virtual ~VPUndoCommand() =default;
private:
Q_DISABLE_COPY(VPUndoCommand)
};
#endif // VPUNDOCOMMAND_H

View file

@ -0,0 +1,282 @@
/************************************************************************
**
** @file vpundopiecemove.cpp
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 16 8, 2021
**
** @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) 2021 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 "vpundopiecemove.h"
#include "../vmisc/def.h"
#include "../layout/vppiece.h"
#include "../layout/vplayout.h"
//---------------------------------------------------------------------------------------------------------------------
VPUndoPieceMove::VPUndoPieceMove(const VPPiecePtr &piece, qreal dx, qreal dy, bool allowMerge, QUndoCommand *parent)
: VPUndoCommand(parent),
m_piece(piece),
m_dx(dx),
m_dy(dy),
m_allowMerge(allowMerge)
{
SCASSERT(not piece.isNull())
m_oldTransform = piece->GetMatrix();
setText(QObject::tr("move piece"));
}
//---------------------------------------------------------------------------------------------------------------------
void VPUndoPieceMove::undo()
{
VPPiecePtr piece = Piece();
if (piece.isNull())
{
return;
}
VPLayoutPtr layout = piece->Layout();
if (layout.isNull())
{
return;
}
layout->SetFocusedSheet(piece->Sheet());
piece->SetMatrix(m_oldTransform);
emit layout->PieceTransformationChanged(piece);
}
//---------------------------------------------------------------------------------------------------------------------
void VPUndoPieceMove::redo()
{
VPPiecePtr piece = Piece();
if (piece.isNull())
{
return;
}
VPLayoutPtr layout = piece->Layout();
if (layout.isNull())
{
return;
}
layout->SetFocusedSheet(piece->Sheet());
piece->Translate(m_dx, m_dy);
emit layout->PieceTransformationChanged(piece);
}
//---------------------------------------------------------------------------------------------------------------------
auto VPUndoPieceMove::mergeWith(const QUndoCommand *command) -> bool
{
if (command->id() != id()) // make sure other is also an VPUndoPieceMove command
{
return false;
}
const auto *moveCommand = dynamic_cast<const VPUndoPieceMove *>(command);
SCASSERT(moveCommand != nullptr)
VPPiecePtr piece = Piece();
if (moveCommand->Piece().isNull() || piece.isNull())
{
return false;
}
if (moveCommand->Piece() != piece)
{
return false;
}
if (not moveCommand->AllowMerge())
{
return false;
}
m_dx += moveCommand->Dx();
m_dy += moveCommand->Dy();
return true;
}
//---------------------------------------------------------------------------------------------------------------------
auto VPUndoPieceMove::id() const -> int
{
return static_cast<int>(ML::UndoCommand::MovePiece);
}
// move pieces
//---------------------------------------------------------------------------------------------------------------------
VPUndoPiecesMove::VPUndoPiecesMove(const QVector<VPPiecePtr> &pieces, qreal dx, qreal dy, bool allowMerge,
QUndoCommand *parent)
: VPUndoCommand(parent),
m_dx(dx),
m_dy(dy),
m_allowMerge(allowMerge)
{
setText(QObject::tr("move pieces"));
for (const auto& piece : pieces)
{
if (not piece.isNull())
{
m_pieces.append(piece);
m_oldTransforms.insert(piece->GetUniqueID(), piece->GetMatrix());
}
}
}
//---------------------------------------------------------------------------------------------------------------------
void VPUndoPiecesMove::undo()
{
if (m_pieces.isEmpty())
{
return;
}
VPLayoutPtr layout = Layout();
if (layout.isNull())
{
return;
}
layout->SetFocusedSheet(Sheet());
for (const auto& piece : m_pieces)
{
VPPiecePtr p = piece.toStrongRef();
if (not p.isNull())
{
if (m_oldTransforms.contains(p->GetUniqueID()))
{
p->SetMatrix(m_oldTransforms.value(p->GetUniqueID()));
emit layout->PieceTransformationChanged(p);
}
}
}
}
//---------------------------------------------------------------------------------------------------------------------
void VPUndoPiecesMove::redo()
{
if (m_pieces.isEmpty())
{
return;
}
VPLayoutPtr layout = Layout();
if (layout.isNull())
{
return;
}
layout->SetFocusedSheet(Sheet());
for (const auto& piece : m_pieces)
{
VPPiecePtr p = piece.toStrongRef();
if (not p.isNull())
{
p->Translate(m_dx, m_dy);
emit layout->PieceTransformationChanged(p);
}
}
}
//---------------------------------------------------------------------------------------------------------------------
auto VPUndoPiecesMove::mergeWith(const QUndoCommand *command) -> bool
{
if (command->id() != id()) // make sure other is also an VPUndoPieceMove command
{
return false;
}
const auto *moveCommand = dynamic_cast<const VPUndoPiecesMove *>(command);
SCASSERT(moveCommand != nullptr)
if (moveCommand->PieceIds() != PieceIds())
{
return false;
}
if (not moveCommand->AllowMerge())
{
return false;
}
m_dx += moveCommand->Dx();
m_dy += moveCommand->Dy();
return true;
}
//---------------------------------------------------------------------------------------------------------------------
auto VPUndoPiecesMove::id() const -> int
{
return static_cast<int>(ML::UndoCommand::MovePieces);
}
//---------------------------------------------------------------------------------------------------------------------
auto VPUndoPiecesMove::Layout() const -> VPLayoutPtr
{
for (const auto& piece : m_pieces)
{
VPPiecePtr p = piece.toStrongRef();
if (not p.isNull())
{
return p->Layout();
}
}
return nullptr;
}
//---------------------------------------------------------------------------------------------------------------------
auto VPUndoPiecesMove::Sheet() const -> VPSheetPtr
{
for (const auto& piece : m_pieces)
{
VPPiecePtr p = piece.toStrongRef();
if (not p.isNull())
{
return p->Sheet();
}
}
return nullptr;
}
//---------------------------------------------------------------------------------------------------------------------
inline auto VPUndoPiecesMove::PieceIds() const -> QSet<QString>
{
QSet<QString> ids;
for (const auto& piece : m_pieces)
{
VPPiecePtr p = piece.toStrongRef();
if (not p.isNull())
{
ids.insert(p->GetUniqueID());
}
};
return ids;
}

View file

@ -0,0 +1,141 @@
/************************************************************************
**
** @file vpundopiecemove.h
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 16 8, 2021
**
** @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) 2021 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 VPUNDOPIECEMOVE_H
#define VPUNDOPIECEMOVE_H
#include "vpundocommand.h"
#include <QTransform>
#include "../layout/layoutdef.h"
class VPUndoPieceMove : public VPUndoCommand
{
Q_OBJECT
public:
explicit VPUndoPieceMove(const VPPiecePtr &piece, qreal dx, qreal dy, bool allowMerge,
QUndoCommand *parent = nullptr);
virtual ~VPUndoPieceMove()=default;
virtual void undo() override;
virtual void redo() override;
// cppcheck-suppress unusedFunction
virtual auto mergeWith(const QUndoCommand *command) -> bool override;
virtual auto id() const -> int override ;
auto Piece() const -> VPPiecePtr;
auto Dx() const -> qreal;
auto Dy() const -> qreal;
auto AllowMerge() const -> bool;
private:
Q_DISABLE_COPY(VPUndoPieceMove)
VPPieceWeakPtr m_piece;
QTransform m_oldTransform{};
qreal m_dx;
qreal m_dy;
bool m_allowMerge;
};
//---------------------------------------------------------------------------------------------------------------------
inline auto VPUndoPieceMove::Piece() const -> VPPiecePtr
{
return m_piece;
}
//---------------------------------------------------------------------------------------------------------------------
inline auto VPUndoPieceMove::Dx() const -> qreal
{
return m_dx;
}
//---------------------------------------------------------------------------------------------------------------------
inline auto VPUndoPieceMove::Dy() const -> qreal
{
return m_dy;
}
//---------------------------------------------------------------------------------------------------------------------
inline auto VPUndoPieceMove::AllowMerge() const -> bool
{
return m_allowMerge;
}
// Move pieces
class VPUndoPiecesMove : public VPUndoCommand
{
Q_OBJECT
public:
explicit VPUndoPiecesMove(const QVector<VPPiecePtr> &pieces, qreal dx, qreal dy, bool allowMerge,
QUndoCommand *parent = nullptr);
virtual ~VPUndoPiecesMove()=default;
virtual void undo() override;
virtual void redo() override;
// cppcheck-suppress unusedFunction
virtual auto mergeWith(const QUndoCommand *command) -> bool override;
virtual auto id() const -> int override ;
auto PieceIds() const -> QSet<QString>;
auto Dx() const -> qreal;
auto Dy() const -> qreal;
auto AllowMerge() const -> bool;
private:
Q_DISABLE_COPY(VPUndoPiecesMove)
QVector<VPPieceWeakPtr> m_pieces{};
QMap<QString, QTransform> m_oldTransforms{};
qreal m_dx;
qreal m_dy;
bool m_allowMerge;
auto Layout() const -> VPLayoutPtr;
auto Sheet() const -> VPSheetPtr;
};
//---------------------------------------------------------------------------------------------------------------------
inline auto VPUndoPiecesMove::Dx() const -> qreal
{
return m_dx;
}
//---------------------------------------------------------------------------------------------------------------------
inline auto VPUndoPiecesMove::Dy() const -> qreal
{
return m_dy;
}
//---------------------------------------------------------------------------------------------------------------------
inline auto VPUndoPiecesMove::AllowMerge() const -> bool
{
return m_allowMerge;
}
#endif // VPUNDOPIECEMOVE_H

View file

@ -33,6 +33,7 @@
#include <QSvgGenerator> #include <QSvgGenerator>
#include <QFileSystemWatcher> #include <QFileSystemWatcher>
#include <QSaveFile> #include <QSaveFile>
#include <QUndoStack>
#include "ui_vpmainwindow.h" #include "ui_vpmainwindow.h"
#include "dialogs/vpdialogabout.h" #include "dialogs/vpdialogabout.h"
@ -69,10 +70,17 @@ VPMainWindow::VPMainWindow(const VPCommandLinePtr &cmd, QWidget *parent) :
VAbstractMainWindow(parent), VAbstractMainWindow(parent),
ui(new Ui::VPMainWindow), ui(new Ui::VPMainWindow),
m_cmd(cmd), m_cmd(cmd),
m_undoStack(new QUndoStack(this)),
m_layout{VPLayout::CreateLayout(m_undoStack)},
m_statusLabel(new QLabel(this)), m_statusLabel(new QLabel(this)),
m_layoutWatcher(new QFileSystemWatcher(this)) m_layoutWatcher(new QFileSystemWatcher(this))
{ {
// // ----- for test purposes, to be removed------------------ ui->setupUi(this);
// create a standard sheet
AddSheet();
// ----- for test purposes, to be removed------------------
m_layout->LayoutSettings().SetUnit(Unit::Cm); m_layout->LayoutSettings().SetUnit(Unit::Cm);
m_layout->LayoutSettings().SetWarningSuperpositionOfPieces(true); m_layout->LayoutSettings().SetWarningSuperpositionOfPieces(true);
m_layout->LayoutSettings().SetTitle(QString("My Test Layout")); m_layout->LayoutSettings().SetTitle(QString("My Test Layout"));
@ -85,11 +93,6 @@ VPMainWindow::VPMainWindow(const VPCommandLinePtr &cmd, QWidget *parent) :
// -------------------------------------------------------- // --------------------------------------------------------
ui->setupUi(this);
// create a standard sheet
AddSheet();
// init the tile factory // init the tile factory
m_tileFactory = new VPTileFactory(m_layout, VPApplication::VApp()->Settings()); m_tileFactory = new VPTileFactory(m_layout, VPApplication::VApp()->Settings());
m_tileFactory->refreshTileInfos(); m_tileFactory->refreshTileInfos();
@ -196,9 +199,7 @@ auto VPMainWindow::LoadFile(QString path) -> bool
file.open(QIODevice::ReadOnly); file.open(QIODevice::ReadOnly);
VPLayoutFileReader fileReader; VPLayoutFileReader fileReader;
m_layout->Clear();
delete m_layout;
m_layout = new VPLayout();
fileReader.ReadFile(m_layout, &file); fileReader.ReadFile(m_layout, &file);
@ -318,9 +319,9 @@ void VPMainWindow::ImportRawLayouts(const QStringList &rawLayouts)
// TODO for feature "Update piece" : CreateOrUpdate() function indstead of CreatePiece() // TODO for feature "Update piece" : CreateOrUpdate() function indstead of CreatePiece()
VPPiece *piece = CreatePiece(rawPiece); VPPiecePtr piece(CreatePiece(rawPiece));
piece->SetSheet(nullptr); // just in case piece->SetSheet(nullptr); // just in case
m_layout->AddPiece(piece); VPLayout::AddPiece(m_layout, piece);
} }
m_carrousel->Refresh(); m_carrousel->Refresh();
@ -378,9 +379,6 @@ void VPMainWindow::SetupMenu()
connect(ui->actionExit, &QAction::triggered, this, &VPMainWindow::close); connect(ui->actionExit, &QAction::triggered, this, &VPMainWindow::close);
ui->actionExit->setShortcuts(QKeySequence::Quit); ui->actionExit->setShortcuts(QKeySequence::Quit);
// -------------------- connects the actions for the edit menu
// TODO : initialise the undo / redo
// -------------------- connects the actions for the windows menu // -------------------- connects the actions for the windows menu
// TODO : initialise the entries for the different windows // TODO : initialise the entries for the different windows
@ -388,6 +386,23 @@ void VPMainWindow::SetupMenu()
QAction* actionDockWidgetToolOptions = ui->dockWidgetProperties->toggleViewAction(); QAction* actionDockWidgetToolOptions = ui->dockWidgetProperties->toggleViewAction();
ui->menuEdit->addAction(actionDockWidgetToolOptions); ui->menuEdit->addAction(actionDockWidgetToolOptions);
auto *separatorAct = new QAction(this);
separatorAct->setSeparator(true);
ui->menuEdit->addAction(separatorAct);
// Add Undo/Redo actions.
undoAction = m_layout->UndoStack()->createUndoAction(this, tr("&Undo"));
undoAction->setShortcuts(QKeySequence::Undo);
undoAction->setIcon(QIcon::fromTheme("edit-undo"));
ui->menuEdit->addAction(undoAction);
ui->toolBarUndoCommands->addAction(undoAction);
redoAction = m_layout->UndoStack()->createRedoAction(this, tr("&Redo"));
redoAction->setShortcuts(QKeySequence::Redo);
redoAction->setIcon(QIcon::fromTheme("edit-redo"));
ui->menuEdit->addAction(redoAction);
ui->toolBarUndoCommands->addAction(redoAction);
// File // File
m_recentFileActs.fill(nullptr); m_recentFileActs.fill(nullptr);
for (auto & recentFileAct : m_recentFileActs) for (auto & recentFileAct : m_recentFileActs)
@ -570,7 +585,6 @@ void VPMainWindow::InitPropertyTabTiles()
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::InitPropertyTabLayout() void VPMainWindow::InitPropertyTabLayout()
{ {
// FIXME ---- For MVP we hide a few things. To be displayed when functions there // FIXME ---- For MVP we hide a few things. To be displayed when functions there
ui->groupBoxLayoutControl->hide(); ui->groupBoxLayoutControl->hide();
@ -768,9 +782,8 @@ void VPMainWindow::InitMainGraphics()
connect(m_graphicsView, &VPMainGraphicsView::ScaleChanged, this, &VPMainWindow::on_ScaleChanged); connect(m_graphicsView, &VPMainGraphicsView::ScaleChanged, this, &VPMainWindow::on_ScaleChanged);
connect(m_graphicsView->GetScene(), &VMainGraphicsScene::mouseMove, this, &VPMainWindow::on_MouseMoved); connect(m_graphicsView->GetScene(), &VMainGraphicsScene::mouseMove, this, &VPMainWindow::on_MouseMoved);
connect(m_carrousel, &VPCarrousel::on_ActiveSheetChanged, m_graphicsView, &VPMainGraphicsView::RefreshPieces);
connect(m_graphicsView, &VPMainGraphicsView::on_SheetRemoved, m_carrousel, &VPCarrousel::Refresh); connect(m_graphicsView, &VPMainGraphicsView::on_SheetRemoved, m_carrousel, &VPCarrousel::Refresh);
connect(m_layout, &VPLayout::PieceSheetChanged, m_carrousel, &VPCarrousel::Refresh); connect(m_layout.get(), &VPLayout::PieceSheetChanged, m_carrousel, &VPCarrousel::Refresh);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -1109,7 +1122,7 @@ void VPMainWindow::CreateWindowMenu(QMenu *menu)
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::AddSheet() void VPMainWindow::AddSheet()
{ {
auto *sheet = new VPSheet(m_layout); VPSheetPtr sheet(new VPSheet(m_layout));
sheet->SetName(QObject::tr("Sheet %1").arg(m_layout->GetSheets().size()+1)); sheet->SetName(QObject::tr("Sheet %1").arg(m_layout->GetSheets().size()+1));
m_layout->AddSheet(sheet); m_layout->AddSheet(sheet);
m_layout->SetFocusedSheet(sheet); m_layout->SetFocusedSheet(sheet);
@ -1191,6 +1204,8 @@ void VPMainWindow::changeEvent(QEvent *event)
{ {
// retranslate designer form (single inheritance approach) // retranslate designer form (single inheritance approach)
ui->retranslateUi(this); ui->retranslateUi(this);
undoAction->setText(tr("&Undo"));
redoAction->setText(tr("&Redo"));
WindowsLocale(); WindowsLocale();
UpdateWindowTitle(); UpdateWindowTitle();
@ -1726,7 +1741,7 @@ void VPMainWindow::on_pushButtonSheetExport_clicked()
LayoutExportFormats format = static_cast<LayoutExportFormats>(ui->comboBoxSheetExportFormat->currentData().toInt()); LayoutExportFormats format = static_cast<LayoutExportFormats>(ui->comboBoxSheetExportFormat->currentData().toInt());
VPExporter exporter; VPExporter exporter;
exporter.Export(m_layout, format, m_graphicsView); exporter.Export(m_layout.get(), format, m_graphicsView);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------

View file

@ -417,7 +417,9 @@ private:
VPCommandLinePtr m_cmd; VPCommandLinePtr m_cmd;
VPLayout *m_layout{new VPLayout(this)}; QUndoStack *m_undoStack;
VPLayoutPtr m_layout;
QList<VPPiece *>m_selectedPieces{QList<VPPiece *>()}; QList<VPPiece *>m_selectedPieces{QList<VPPiece *>()};
VPTileFactory *m_tileFactory{nullptr}; VPTileFactory *m_tileFactory{nullptr};
@ -442,6 +444,9 @@ private:
QFileSystemWatcher *m_layoutWatcher; QFileSystemWatcher *m_layoutWatcher;
QAction *undoAction{nullptr};
QAction *redoAction{nullptr};
/** /**
* @brief CreatePiece creates a piece from the given VLayoutPiece data * @brief CreatePiece creates a piece from the given VLayoutPiece data
* @param rawPiece the raw piece data * @param rawPiece the raw piece data

View file

@ -669,7 +669,7 @@
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>0</x> <x>0</x>
<y>-170</y> <y>0</y>
<width>342</width> <width>342</width>
<height>870</height> <height>870</height>
</rect> </rect>
@ -1589,6 +1589,17 @@
<bool>false</bool> <bool>false</bool>
</attribute> </attribute>
</widget> </widget>
<widget class="QToolBar" name="toolBarUndoCommands">
<property name="windowTitle">
<string>Undo commands</string>
</property>
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<action name="actionOpen"> <action name="actionOpen">
<property name="icon"> <property name="icon">
<iconset theme="document-open"> <iconset theme="document-open">

View file

@ -5,32 +5,26 @@
#include "../vwidgets/vmaingraphicsscene.h" #include "../vwidgets/vmaingraphicsscene.h"
#include "layout/vpsheet.h" #include "layout/vpsheet.h"
#include "scene/vpmaingraphicsview.h" #include "scene/vpmaingraphicsview.h"
#include "layout/vplayout.h"
#include "../vmisc/def.h" #include "../vmisc/def.h"
#include "../vmisc/vcommonsettings.h" #include "../vmisc/vcommonsettings.h"
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
VPTileFactory::VPTileFactory(VPLayout *layout, VCommonSettings *commonSettings): VPTileFactory::VPTileFactory(const VPLayoutPtr &layout, VCommonSettings *commonSettings):
m_layout(layout), m_layout(layout),
m_commonSettings(commonSettings) m_commonSettings(commonSettings)
{ {
m_infoStripeWidth = UnitConvertor(1, Unit::Cm, Unit::Px); m_infoStripeWidth = UnitConvertor(1, Unit::Cm, Unit::Px);
} }
//---------------------------------------------------------------------------------------------------------------------
VPTileFactory::~VPTileFactory()
{
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPTileFactory::refreshTileInfos() void VPTileFactory::refreshTileInfos()
{ {
if(m_layout != nullptr) VPLayoutPtr layout = m_layout.toStrongRef();
if(not layout.isNull())
{ {
PageOrientation tilesOrientation = m_layout->LayoutSettings().GetTilesOrientation(); PageOrientation tilesOrientation = layout->LayoutSettings().GetTilesOrientation();
QSizeF tilesSize = m_layout->LayoutSettings().GetTilesSize(); QSizeF tilesSize = layout->LayoutSettings().GetTilesSize();
QMarginsF tilesMargins = m_layout->LayoutSettings().GetTilesMargins(); QMarginsF tilesMargins = layout->LayoutSettings().GetTilesMargins();
// sets the drawing height // sets the drawing height
m_drawingAreaHeight = (tilesOrientation == PageOrientation::Portrait)? m_drawingAreaHeight = (tilesOrientation == PageOrientation::Portrait)?
@ -45,11 +39,11 @@ void VPTileFactory::refreshTileInfos()
tilesMargins.left() + tilesMargins.right() + m_infoStripeWidth; tilesMargins.left() + tilesMargins.right() + m_infoStripeWidth;
QSizeF sheetSize = m_layout->LayoutSettings().GetSheetSize(); QSizeF sheetSize = layout->LayoutSettings().GetSheetSize();
qreal totalDrawingWidth = 0; qreal totalDrawingWidth = 0;
qreal totaldrawingHeight = 0; qreal totaldrawingHeight = 0;
if(m_layout->LayoutSettings().GetOrientation() == PageOrientation::Portrait) if(layout->LayoutSettings().GetOrientation() == PageOrientation::Portrait)
{ {
totalDrawingWidth = sheetSize.width(); totalDrawingWidth = sheetSize.width();
totaldrawingHeight = sheetSize.height(); totaldrawingHeight = sheetSize.height();
@ -69,9 +63,17 @@ void VPTileFactory::refreshTileInfos()
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPTileFactory::drawTile(QPainter *painter, VPMainGraphicsView *graphicsView, int row, int col) void VPTileFactory::drawTile(QPainter *painter, VPMainGraphicsView *graphicsView, int row, int col)
{ {
QMarginsF tilesMargins = m_layout->LayoutSettings().GetTilesMargins(); VPLayoutPtr layout = m_layout.toStrongRef();
QPen penTileInfos = QPen(QColor(180,180,180), m_commonSettings->WidthHairLine(), Qt::DashLine, Qt::RoundCap, Qt::RoundJoin); if(layout.isNull())
QPen penTileDrawing = QPen(Qt::black, m_commonSettings->WidthMainLine(), Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin); {
return
;
}
QMarginsF tilesMargins = layout->LayoutSettings().GetTilesMargins();
QPen penTileInfos = QPen(QColor(180,180,180), m_commonSettings->WidthHairLine(), Qt::DashLine, Qt::RoundCap,
Qt::RoundJoin);
QPen penTileDrawing = QPen(Qt::black, m_commonSettings->WidthMainLine(), Qt::SolidLine, Qt::RoundCap,
Qt::RoundJoin);
QSvgRenderer* svgRenderer = new QSvgRenderer(); QSvgRenderer* svgRenderer = new QSvgRenderer();
@ -280,7 +282,7 @@ void VPTileFactory::drawTile(QPainter *painter, VPMainGraphicsView *graphicsView
"<td align='center'>%1 - %2</td>" "<td align='center'>%1 - %2</td>"
"</tr>" "</tr>"
"</table>") "</table>")
.arg(page).arg(m_layout->GetFocusedSheet()->GetName())); .arg(page).arg(layout->GetFocusedSheet()->GetName()));
painter->save(); painter->save();
painter->rotate(-90); painter->rotate(-90);
painter->translate(QPointF(-(m_drawingAreaHeight+tilesMargins.top()) + UnitConvertor(1, Unit::Cm, Unit::Px), painter->translate(QPointF(-(m_drawingAreaHeight+tilesMargins.top()) + UnitConvertor(1, Unit::Cm, Unit::Px),

View file

@ -32,8 +32,9 @@
#include <QtMath> #include <QtMath>
#include <QObject> #include <QObject>
#include "layout/vplayout.h"
class VPMainGraphicsView; class VPMainGraphicsView;
class VPLayout;
class VCommonSettings; class VCommonSettings;
class QPainter; class QPainter;
@ -42,9 +43,9 @@ class VPTileFactory : QObject
Q_OBJECT Q_OBJECT
public: public:
VPTileFactory(VPLayout *layout, VCommonSettings *commonSettings); VPTileFactory(const VPLayoutPtr &layout, VCommonSettings *commonSettings);
virtual ~VPTileFactory(); virtual ~VPTileFactory() = default;
/** /**
* @brief drawTile draws the tile of given coordinate (row, col) from the * @brief drawTile draws the tile of given coordinate (row, col) from the
@ -87,7 +88,7 @@ public:
private: private:
Q_DISABLE_COPY(VPTileFactory) Q_DISABLE_COPY(VPTileFactory)
VPLayout *m_layout{nullptr}; VPLayoutWeakPtr m_layout;
VCommonSettings *m_commonSettings{nullptr}; VCommonSettings *m_commonSettings{nullptr};
/** /**

View file

@ -47,29 +47,29 @@ public:
VPLayoutFileReader()=default; VPLayoutFileReader()=default;
~VPLayoutFileReader()=default; ~VPLayoutFileReader()=default;
auto ReadFile(VPLayout *layout, QFile *file) -> bool; auto ReadFile(const VPLayoutPtr &layout, QFile *file) -> bool;
private: private:
Q_DISABLE_COPY(VPLayoutFileReader) Q_DISABLE_COPY(VPLayoutFileReader)
void ReadLayout(VPLayout *layout); void ReadLayout(const VPLayoutPtr &layout);
void ReadProperties(VPLayout *layout); void ReadProperties(const VPLayoutPtr &layout);
void ReadControl(VPLayout *layout); void ReadControl(const VPLayoutPtr &layout);
void ReadTiles(VPLayout *layout); void ReadTiles(const VPLayoutPtr &layout);
void ReadUnplacedPieces(VPLayout *layout); void ReadUnplacedPieces(const VPLayoutPtr &layout);
void ReadSheets(VPLayout *layout); void ReadSheets(const VPLayoutPtr &layout);
void ReadSheet(VPLayout *layout); void ReadSheet(const VPLayoutPtr &layout);
void ReadPieces(VPLayout *layout, VPSheet *sheet=nullptr); void ReadPieces(const VPLayoutPtr &layout, const VPSheetPtr &sheet=VPSheetPtr());
void ReadPiece(VPPiece *piece); void ReadPiece(const VPPiecePtr &piece);
void ReadSeamAllowance(VPPiece *piece); void ReadSeamAllowance(const VPPiecePtr &piece);
void ReadGrainline(VPPiece *piece); void ReadGrainline(const VPPiecePtr &piece);
void ReadNotches(VPPiece *piece); void ReadNotches(const VPPiecePtr &piece);
auto ReadNotch() -> VLayoutPassmark; auto ReadNotch() -> VLayoutPassmark;
void ReadInternalPaths(VPPiece *piece); void ReadInternalPaths(const VPPiecePtr &piece);
auto ReadInternalPath() -> VLayoutPiecePath; auto ReadInternalPath() -> VLayoutPiecePath;
void ReadMarkers(VPPiece *piece); void ReadMarkers(const VPPiecePtr &piece);
auto ReadMarker() -> VLayoutPlaceLabel; auto ReadMarker() -> VLayoutPlaceLabel;
void ReadLabels(VPPiece *piece); void ReadLabels(const VPPiecePtr &piece);
auto ReadLabelLines() -> VTextManager; auto ReadLabelLines() -> VTextManager;
auto ReadLabelLine() -> TextLine; auto ReadLabelLine() -> TextLine;

View file

@ -137,7 +137,7 @@ auto GrainlineArrowDirrectionToString(GrainlineArrowDirection type) -> QString
} // namespace } // namespace
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPLayoutFileWriter::WriteFile(VPLayout *layout, QIODevice *file) void VPLayoutFileWriter::WriteFile(const VPLayoutPtr &layout, QIODevice *file)
{ {
setDevice(file); setDevice(file);
setAutoFormatting(true); setAutoFormatting(true);
@ -152,7 +152,7 @@ void VPLayoutFileWriter::WriteFile(VPLayout *layout, QIODevice *file)
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPLayoutFileWriter::WriteLayout(VPLayout *layout) void VPLayoutFileWriter::WriteLayout(const VPLayoutPtr &layout)
{ {
writeStartElement(ML::TagLayout); writeStartElement(ML::TagLayout);
SetAttribute(ML::AttrVersion, VLayoutConverter::LayoutMaxVerStr); SetAttribute(ML::AttrVersion, VLayoutConverter::LayoutMaxVerStr);
@ -163,7 +163,7 @@ void VPLayoutFileWriter::WriteLayout(VPLayout *layout)
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPLayoutFileWriter::WriteProperties(VPLayout *layout) void VPLayoutFileWriter::WriteProperties(const VPLayoutPtr &layout)
{ {
writeStartElement(ML::TagProperties); writeStartElement(ML::TagProperties);
@ -187,12 +187,12 @@ void VPLayoutFileWriter::WriteProperties(VPLayout *layout)
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPLayoutFileWriter::WriteSheets(VPLayout *layout) void VPLayoutFileWriter::WriteSheets(const VPLayoutPtr &layout)
{ {
writeStartElement(ML::TagSheets); writeStartElement(ML::TagSheets);
QList<VPSheet *> sheets = layout->GetSheets(); QList<VPSheetPtr> sheets = layout->GetSheets();
for (auto *sheet : sheets) for (const auto &sheet : sheets)
{ {
WriteSheet(sheet); WriteSheet(sheet);
} }
@ -201,7 +201,7 @@ void VPLayoutFileWriter::WriteSheets(VPLayout *layout)
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPLayoutFileWriter::WriteSheet(VPSheet* sheet) void VPLayoutFileWriter::WriteSheet(const VPSheetPtr &sheet)
{ {
writeStartElement(ML::TagSheet); writeStartElement(ML::TagSheet);
@ -213,7 +213,7 @@ void VPLayoutFileWriter::WriteSheet(VPSheet* sheet)
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPLayoutFileWriter::WriteTiles(VPLayout *layout) void VPLayoutFileWriter::WriteTiles(const VPLayoutPtr &layout)
{ {
Q_UNUSED(layout); // to be removed Q_UNUSED(layout); // to be removed
@ -228,10 +228,10 @@ void VPLayoutFileWriter::WriteTiles(VPLayout *layout)
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPLayoutFileWriter::WritePieceList(const QList<VPPiece *> &list, const QString &tagName) void VPLayoutFileWriter::WritePieceList(const QList<VPPiecePtr> &list, const QString &tagName)
{ {
writeStartElement(tagName); // piece list writeStartElement(tagName); // piece list
for (auto *piece : list) for (const auto &piece : list)
{ {
WritePiece(piece); WritePiece(piece);
} }
@ -240,7 +240,7 @@ void VPLayoutFileWriter::WritePieceList(const QList<VPPiece *> &list, const QStr
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPLayoutFileWriter::WritePiece(VPPiece *piece) void VPLayoutFileWriter::WritePiece(const VPPiecePtr &piece)
{ {
writeStartElement(ML::TagPiece); writeStartElement(ML::TagPiece);
SetAttribute(ML::AttrID, piece->GetUUID().toString()); SetAttribute(ML::AttrID, piece->GetUUID().toString());

View file

@ -35,6 +35,7 @@
#include <functional> #include <functional>
#include "../vmisc/literals.h" #include "../vmisc/literals.h"
#include "../layout/layoutdef.h"
class VPLayout; class VPLayout;
class VPSheet; class VPSheet;
@ -51,16 +52,16 @@ public:
VPLayoutFileWriter()= default; VPLayoutFileWriter()= default;
~VPLayoutFileWriter()= default; ~VPLayoutFileWriter()= default;
void WriteFile(VPLayout *layout, QIODevice *file); void WriteFile(const VPLayoutPtr &layout, QIODevice *file);
private: private:
void WriteLayout(VPLayout *layout); void WriteLayout(const VPLayoutPtr &layout);
void WriteProperties(VPLayout *layout); void WriteProperties(const VPLayoutPtr &layout);
void WriteSheets(VPLayout *layout); void WriteSheets(const VPLayoutPtr &layout);
void WriteSheet(VPSheet* sheet); void WriteSheet(const VPSheetPtr &sheet);
void WriteTiles(VPLayout *layout); void WriteTiles(const VPLayoutPtr &layout);
void WritePieceList(const QList<VPPiece *> &list, const QString &tagName); void WritePieceList(const QList<VPPiecePtr> &list, const QString &tagName);
void WritePiece(VPPiece *piece); void WritePiece(const VPPiecePtr &piece);
void WriteLabel(const QVector<QPointF> &labelShape, const VTextManager &tm, const QString &tagName); void WriteLabel(const QVector<QPointF> &labelShape, const VTextManager &tm, const QString &tagName);
void WriteLabelLines(const VTextManager &tm); void WriteLabelLines(const VTextManager &tm);