Undo/Redo piece rotate.

This commit is contained in:
Roman Telezhynskyi 2021-08-18 20:33:47 +03:00
parent 0908b5a1f7
commit a35e46f845
26 changed files with 1152 additions and 402 deletions

View File

@ -34,6 +34,7 @@
#include "../vmisc/backport/qoverload.h" #include "../vmisc/backport/qoverload.h"
#include "../layout/vpsheet.h" #include "../layout/vpsheet.h"
#include "../layout/vplayout.h"
#include <QLoggingCategory> #include <QLoggingCategory>
#include <QMenu> #include <QMenu>
@ -42,12 +43,12 @@
Q_LOGGING_CATEGORY(pCarrousel, "p.carrousel") Q_LOGGING_CATEGORY(pCarrousel, "p.carrousel")
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
VPCarrousel::VPCarrousel(VPLayout *layout, QWidget *parent) : VPCarrousel::VPCarrousel(const VPLayoutPtr &layout, QWidget *parent) :
QWidget(parent), QWidget(parent),
ui(new Ui::VPCarrousel), ui(new Ui::VPCarrousel),
m_layout(layout) m_layout(layout)
{ {
SCASSERT(m_layout != nullptr) SCASSERT(not layout.isNull())
ui->setupUi(this); ui->setupUi(this);
ui->listWidget->SetCarrousel(this); ui->listWidget->SetCarrousel(this);
@ -55,6 +56,8 @@ VPCarrousel::VPCarrousel(VPLayout *layout, QWidget *parent) :
connect(ui->comboBoxPieceList, QOverload<int>::of(&QComboBox::currentIndexChanged), this, connect(ui->comboBoxPieceList, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
&VPCarrousel::on_ActivePieceListChanged); &VPCarrousel::on_ActivePieceListChanged);
connect(layout.get(), &VPLayout::ActiveSheetChanged, this, &VPCarrousel::on_ActiveSheetChanged);
// ------ then we fill the carrousel with the layout content // ------ then we fill the carrousel with the layout content
Refresh(); Refresh();
} }
@ -73,26 +76,27 @@ void VPCarrousel::Refresh()
// Do not rely on m_layout because we do not control it. // Do not rely on m_layout because we do not control it.
m_pieceLists = QList<VPCarrouselSheet>(); m_pieceLists = QList<VPCarrouselSheet>();
if (m_layout != nullptr) VPLayoutPtr layout = m_layout.toStrongRef();
if (not layout.isNull())
{ {
{ {
VPCarrouselSheet carrouselSheet; VPCarrouselSheet carrouselSheet;
carrouselSheet.unplaced = true; carrouselSheet.unplaced = true;
carrouselSheet.active = false; carrouselSheet.active = false;
carrouselSheet.name = tr("Unplaced pieces"); carrouselSheet.name = tr("Unplaced pieces");
carrouselSheet.pieces = m_layout->GetUnplacedPieces(); carrouselSheet.pieces = layout->GetUnplacedPieces();
m_pieceLists.append(carrouselSheet); m_pieceLists.append(carrouselSheet);
} }
QList<VPSheet *> sheets = m_layout->GetSheets(); QList<VPSheetPtr> sheets = layout->GetSheets();
for (auto *sheet : sheets) for (const auto &sheet : sheets)
{ {
if (sheet->IsVisible()) if (not sheet.isNull() && sheet->IsVisible())
{ {
VPCarrouselSheet carrouselSheet; VPCarrouselSheet carrouselSheet;
carrouselSheet.unplaced = false; carrouselSheet.unplaced = false;
carrouselSheet.active = (sheet == m_layout->GetFocusedSheet()); carrouselSheet.active = (sheet == layout->GetFocusedSheet());
carrouselSheet.name = sheet->GetName(); carrouselSheet.name = sheet->GetName();
carrouselSheet.pieces = sheet->GetPieces(); carrouselSheet.pieces = sheet->GetPieces();
carrouselSheet.sheetUuid = sheet->Uuid(); carrouselSheet.sheetUuid = sheet->Uuid();
@ -121,18 +125,41 @@ void VPCarrousel::Refresh()
RefreshOrientation(); RefreshOrientation();
} }
//---------------------------------------------------------------------------------------------------------------------
void VPCarrousel::on_ActiveSheetChanged(const VPSheetPtr &sheet)
{
if (not sheet.isNull())
{
int index = ui->comboBoxPieceList->findData(sheet->Uuid());
if (index != -1)
{
ui->comboBoxPieceList->setCurrentIndex(index);
}
}
else
{
ui->comboBoxPieceList->setCurrentIndex(0);
}
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPCarrousel::RefreshSheetNames() void VPCarrousel::RefreshSheetNames()
{ {
VPLayoutPtr layout = m_layout.toStrongRef();
if (layout.isNull())
{
return;
}
for (int i=0; i < m_pieceLists.size(); ++i) for (int i=0; i < m_pieceLists.size(); ++i)
{ {
if (not m_pieceLists.at(i).unplaced) if (not m_pieceLists.at(i).unplaced)
{ {
VPSheet *sheet = m_layout->GetSheet(m_pieceLists.at(i).sheetUuid); VPSheetPtr sheet = layout->GetSheet(m_pieceLists.at(i).sheetUuid);
if (sheet != nullptr) if (not sheet.isNull())
{ {
m_pieceLists[i].name = sheet->GetName(); m_pieceLists[i].name = sheet->GetName();
m_pieceLists[i].active = (sheet == m_layout->GetFocusedSheet()); m_pieceLists[i].active = (sheet == layout->GetFocusedSheet());
} }
} }
else else
@ -158,6 +185,12 @@ void VPCarrousel::on_ActivePieceListChanged(int index)
{ {
qCDebug(pCarrousel, "index changed %i", index); qCDebug(pCarrousel, "index changed %i", index);
VPLayoutPtr layout = m_layout.toStrongRef();
if (layout.isNull())
{
return;
}
if (not m_pieceLists.isEmpty() && index >= 0 && index < m_pieceLists.size()) if (not m_pieceLists.isEmpty() && index >= 0 && index < m_pieceLists.size())
{ {
ui->listWidget->SetCurrentPieceList(m_pieceLists.at(index).pieces); ui->listWidget->SetCurrentPieceList(m_pieceLists.at(index).pieces);
@ -165,20 +198,22 @@ void VPCarrousel::on_ActivePieceListChanged(int index)
if (index > 0) if (index > 0)
{ {
QUuid sheetUuid = ui->comboBoxPieceList->currentData().toUuid(); QUuid sheetUuid = ui->comboBoxPieceList->currentData().toUuid();
VPSheet *sheet = m_layout->GetSheet(sheetUuid); VPSheetPtr sheet = layout->GetSheet(sheetUuid);
if (sheet != nullptr) if (not sheet.isNull())
{ {
m_layout->SetFocusedSheet(sheet); m_ignoreActiveSheetChange = true;
emit on_ActiveSheetChanged(); layout->SetFocusedSheet(sheet);
m_ignoreActiveSheetChange = false;
} }
} }
} }
else else
{ {
ui->listWidget->SetCurrentPieceList(QList<VPPiece *>()); ui->listWidget->SetCurrentPieceList(QList<VPPiecePtr>());
m_layout->SetFocusedSheet(nullptr); m_ignoreActiveSheetChange = true;
emit on_ActiveSheetChanged(); layout->SetFocusedSheet(VPSheetPtr());
m_ignoreActiveSheetChange = false;
} }
RefreshSheetNames(); RefreshSheetNames();

View File

@ -32,8 +32,8 @@
#include <QWidget> #include <QWidget>
#include <QComboBox> #include <QComboBox>
#include <QScrollArea> #include <QScrollArea>
#include "../layout/vplayout.h"
#include "../layout/vppiece.h" #include "../layout/vppiece.h"
#include "../layout/layoutdef.h"
namespace Ui namespace Ui
{ {
@ -45,7 +45,7 @@ struct VPCarrouselSheet
bool unplaced{true}; bool unplaced{true};
bool active{false}; bool active{false};
QString name{}; QString name{};
QList<VPPiece *> pieces{}; QList<VPPiecePtr> pieces{};
QUuid sheetUuid{}; QUuid sheetUuid{};
}; };
@ -53,7 +53,7 @@ class VPCarrousel : public QWidget
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit VPCarrousel(VPLayout *layout, QWidget *parent = nullptr); explicit VPCarrousel(const VPLayoutPtr &layout, QWidget *parent = nullptr);
virtual ~VPCarrousel() = default; virtual ~VPCarrousel() = default;
/** /**
@ -69,8 +69,6 @@ public:
*/ */
void RefreshOrientation(); void RefreshOrientation();
void RefreshSheetNames(); void RefreshSheetNames();
/** /**
@ -78,14 +76,12 @@ public:
*/ */
void Clear(); void Clear();
signals:
void on_ActiveSheetChanged();
public slots: public slots:
/** /**
* @brief Refresh Refreshes the content of the carrousel * @brief Refresh Refreshes the content of the carrousel
*/ */
void Refresh(); void Refresh();
void on_ActiveSheetChanged(const VPSheetPtr &sheet);
protected: protected:
virtual void changeEvent(QEvent* event) override; virtual void changeEvent(QEvent* event) override;
@ -102,12 +98,14 @@ private:
Q_DISABLE_COPY(VPCarrousel) Q_DISABLE_COPY(VPCarrousel)
Ui::VPCarrousel *ui; Ui::VPCarrousel *ui;
VPLayout *m_layout{nullptr}; VPLayoutWeakPtr m_layout{};
QList<VPCarrouselSheet> m_pieceLists{}; QList<VPCarrouselSheet> m_pieceLists{};
Qt::Orientation m_orientation{Qt::Vertical}; Qt::Orientation m_orientation{Qt::Vertical};
bool m_ignoreActiveSheetChange{false};
static auto GetSheetName(const VPCarrouselSheet &sheet) -> QString; static auto GetSheetName(const VPCarrouselSheet &sheet) -> QString;
}; };

View File

@ -44,7 +44,7 @@ Q_LOGGING_CATEGORY(pCarrouselPiece, "p.carrouselPiece")
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
VPCarrouselPiece::VPCarrouselPiece(VPPiece *piece, QListWidget* parent) : VPCarrouselPiece::VPCarrouselPiece(const VPPiecePtr &piece, QListWidget* parent) :
QListWidgetItem(parent, Type), QListWidgetItem(parent, Type),
m_piece(piece) m_piece(piece)
{ {
@ -57,7 +57,7 @@ VPCarrouselPiece::VPCarrouselPiece(VPPiece *piece, QListWidget* parent) :
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VPCarrouselPiece::GetPiece() -> VPPiece * auto VPCarrouselPiece::GetPiece() const -> VPPiecePtr
{ {
return m_piece; return m_piece;
} }
@ -65,13 +65,23 @@ auto VPCarrouselPiece::GetPiece() -> VPPiece *
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPCarrouselPiece::RefreshSelection() void VPCarrouselPiece::RefreshSelection()
{ {
setSelected(m_piece->IsSelected()); VPPiecePtr piece = GetPiece();
if (not piece.isNull())
{
setSelected(piece->IsSelected());
}
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VPCarrouselPiece::CreatePieceIcon(const QSize &size, bool isDragIcon) const -> QIcon auto VPCarrouselPiece::CreatePieceIcon(const QSize &size, bool isDragIcon) const -> QIcon
{ {
QRectF boundingRect = m_piece->DetailBoundingRect(); VPPiecePtr piece = GetPiece();
if (piece.isNull())
{
return {};
}
QRectF boundingRect = piece->DetailBoundingRect();
qreal canvasSize = qMax(boundingRect.height(), boundingRect.width()); qreal canvasSize = qMax(boundingRect.height(), boundingRect.width());
QRectF canvas = QRectF(0, 0, canvasSize, canvasSize); QRectF canvas = QRectF(0, 0, canvasSize, canvasSize);
@ -133,7 +143,7 @@ auto VPCarrouselPiece::CreatePieceIcon(const QSize &size, bool isDragIcon) const
painter.setBrush(QBrush(Qt::white)); painter.setBrush(QBrush(Qt::white));
} }
m_piece->DrawMiniature(painter); piece->DrawMiniature(painter);
painter.end(); painter.end();

View File

@ -31,21 +31,21 @@
#include <QMouseEvent> #include <QMouseEvent>
#include <QListWidgetItem> #include <QListWidgetItem>
class VPPiece; #include "../layout/layoutdef.h"
class VPCarrouselPiece : public QListWidgetItem class VPCarrouselPiece : public QListWidgetItem
{ {
public: public:
enum { Type = UserType + 1}; enum { Type = UserType + 1};
explicit VPCarrouselPiece(VPPiece *piece, QListWidget* parent); explicit VPCarrouselPiece(const VPPiecePtr &piece, QListWidget* parent);
virtual ~VPCarrouselPiece() = default; virtual ~VPCarrouselPiece() = default;
/** /**
* @brief GetPiece Returns the corresponding layout piece * @brief GetPiece Returns the corresponding layout piece
* @return the corresponding layout piece * @return the corresponding layout piece
*/ */
auto GetPiece() -> VPPiece *; auto GetPiece() const -> VPPiecePtr;
/** /**
* @brief RefreshSelection refreshes the selection of the piece according to the selection information of m_piece * @brief RefreshSelection refreshes the selection of the piece according to the selection information of m_piece
@ -62,7 +62,7 @@ public:
private: private:
Q_DISABLE_COPY(VPCarrouselPiece) Q_DISABLE_COPY(VPCarrouselPiece)
VPPiece *m_piece; VPPieceWeakPtr m_piece;
}; };
#endif // VPCARROUSELPIECE_H #endif // VPCARROUSELPIECE_H

View File

@ -38,6 +38,7 @@
#include "../vmisc/backport/qoverload.h" #include "../vmisc/backport/qoverload.h"
#include "vpmimedatapiece.h" #include "vpmimedatapiece.h"
#include "../layout/vpsheet.h" #include "../layout/vpsheet.h"
#include "../layout/vplayout.h"
#include <QLoggingCategory> #include <QLoggingCategory>
@ -68,18 +69,21 @@ void VPCarrouselPieceList::Refresh()
if(not m_pieceList.isEmpty()) if(not m_pieceList.isEmpty())
{ {
// create the corresponding carrousel pieces // create the corresponding carrousel pieces
for (auto *piece : m_pieceList) for (auto piece : m_pieceList)
{ {
// update the label of the piece if (not piece.isNull())
auto* carrouselpiece = new VPCarrouselPiece(piece, this); {
carrouselpiece->setSelected(piece->IsSelected()); // update the label of the piece
auto* carrouselpiece = new VPCarrouselPiece(piece, this);
carrouselpiece->setSelected(piece->IsSelected());
}
} }
sortItems(); sortItems();
} }
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPCarrouselPieceList::SetCurrentPieceList(const QList<VPPiece *> &pieceList) void VPCarrouselPieceList::SetCurrentPieceList(const QList<VPPiecePtr> &pieceList)
{ {
m_pieceList = pieceList; m_pieceList = pieceList;
@ -135,7 +139,7 @@ void VPCarrouselPieceList::startDrag(Qt::DropActions supportedActions)
// starts the dragging // starts the dragging
auto *drag = new QDrag(this); auto *drag = new QDrag(this);
auto *mimeData = new VPMimeDataPiece(); auto *mimeData = new VPMimeDataPiece();
VPPiece* piece = pieceItem->GetPiece(); VPPiecePtr piece = pieceItem->GetPiece();
mimeData->SetPiecePtr(piece); mimeData->SetPiecePtr(piece);
QPixmap pixmap = pieceItem->CreatePieceIcon(QSize(120, 120), true).pixmap(QSize(120, 120)); QPixmap pixmap = pieceItem->CreatePieceIcon(QSize(120, 120), true).pixmap(QSize(120, 120));
@ -189,18 +193,23 @@ void VPCarrouselPieceList::contextMenuEvent(QContextMenuEvent *event)
QAction *selectedAction = menu.exec(event->globalPos()); QAction *selectedAction = menu.exec(event->globalPos());
VPPiece *piece = pieceItem->GetPiece(); VPPiecePtr piece = pieceItem->GetPiece();
VPLayout *layout = piece->Layout(); VPLayoutPtr layout = piece->Layout();
if (piece.isNull() || layout.isNull())
{
return;
}
if (selectedAction == moveAction) if (selectedAction == moveAction)
{ {
VPSheet *sheet = layout->GetFocusedSheet(); VPSheetPtr sheet = layout->GetFocusedSheet();
piece->SetSheet(sheet); piece->SetSheet(sheet);
emit layout->PieceSheetChanged(piece); emit layout->PieceSheetChanged(piece);
} }
else if (selectedAction == deleteAction) else if (selectedAction == deleteAction)
{ {
VPSheet *sheet = layout->GetTrashSheet(); VPSheetPtr sheet = layout->GetTrashSheet();
piece->SetSheet(sheet); piece->SetSheet(sheet);
emit layout->PieceSheetChanged(piece); emit layout->PieceSheetChanged(piece);
} }

View File

@ -50,7 +50,7 @@ public:
* @brief SetCurrentPieceList Sets the current piece list to the given piece list and redraw * @brief SetCurrentPieceList Sets the current piece list to the given piece list and redraw
* the carrousel. * the carrousel.
*/ */
void SetCurrentPieceList(const QList<VPPiece *> &pieceList); void SetCurrentPieceList(const QList<VPPiecePtr> &pieceList);
/** /**
* @brief SetCarrousel Sets the carrousel corresponding to the list * @brief SetCarrousel Sets the carrousel corresponding to the list
@ -76,7 +76,7 @@ protected:
private: private:
Q_DISABLE_COPY(VPCarrouselPieceList) Q_DISABLE_COPY(VPCarrouselPieceList)
QList<VPPiece *> m_pieceList{}; QList<VPPiecePtr> m_pieceList{};
QPoint m_dragStart{}; QPoint m_dragStart{};
VPCarrousel *m_carrousel{nullptr}; VPCarrousel *m_carrousel{nullptr};
}; };

View File

@ -0,0 +1,45 @@
/************************************************************************
**
** @file layoutdef.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 LAYOUTDEF_H
#define LAYOUTDEF_H
#include <QSharedPointer>
class VPLayout;
using VPLayoutPtr = QSharedPointer<VPLayout>;
using VPLayoutWeakPtr = QWeakPointer<VPLayout>;
class VPPiece;
using VPPiecePtr = QSharedPointer<VPPiece>;
using VPPieceWeakPtr = QWeakPointer<VPPiece>;
class VPSheet;
using VPSheetPtr = QSharedPointer<VPSheet>;
using VPSheetWeakPtr = QWeakPointer<VPSheet>;
#endif // LAYOUTDEF_H

View File

@ -31,109 +31,118 @@
#include "vpsheet.h" #include "vpsheet.h"
#include <QLoggingCategory> #include <QLoggingCategory>
#include <QUndoStack>
Q_LOGGING_CATEGORY(pLayout, "p.layout") Q_LOGGING_CATEGORY(pLayout, "p.layout")
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
VPLayout::VPLayout(QObject *parent) : VPLayout::VPLayout(QUndoStack *undoStack) :
QObject(parent), m_undoStack(undoStack)
m_trashSheet(new VPSheet(this))
{}
//---------------------------------------------------------------------------------------------------------------------
VPLayout::~VPLayout()
{ {
qDeleteAll(m_pieces); SCASSERT(m_undoStack != nullptr)
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPLayout::AddPiece(VPPiece *piece) VPLayoutPtr VPLayout::CreateLayout(QUndoStack *undoStack)
{ {
if ((piece != nullptr) && not m_pieces.contains(piece)) SCASSERT(undoStack != nullptr)
undoStack->clear();
VPLayoutPtr layout(new VPLayout(undoStack));
layout->AddTrashSheet(VPSheetPtr(new VPSheet(layout)));
return layout;
}
//---------------------------------------------------------------------------------------------------------------------
void VPLayout::AddPiece(const VPLayoutPtr &layout, const VPPiecePtr &piece)
{
piece->SetLayout(layout);
layout->AddPiece(piece);
}
//---------------------------------------------------------------------------------------------------------------------
void VPLayout::AddPiece(const VPPiecePtr &piece)
{
if ((piece != nullptr) && not m_pieces.contains(piece->GetUniqueID()))
{ {
piece->SetLayout(this); m_pieces.insert(piece->GetUniqueID(), piece);
m_pieces.append(piece);
} }
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VPLayout::GetPieces() const -> QList<VPPiece *> auto VPLayout::GetPieces() const -> QList<VPPiecePtr>
{ {
return m_pieces; return m_pieces.values();
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VPLayout::GetUnplacedPieces() const -> QList<VPPiece *> auto VPLayout::GetUnplacedPieces() const -> QList<VPPiecePtr>
{ {
return PiecesForSheet(nullptr); return PiecesForSheet(VPSheetPtr());
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VPLayout::GetTrashedPieces() const -> QList<VPPiece *> auto VPLayout::GetTrashedPieces() const -> QList<VPPiecePtr>
{ {
return PiecesForSheet(m_trashSheet); if (m_trashSheet.isNull())
} {
return {};
//--------------------------------------------------------------------------------------------------------------------- }
auto VPLayout::AddSheet() -> VPSheet* return PiecesForSheet(m_trashSheet->Uuid());
{ }
auto *newSheet = new VPSheet(this);
m_sheets.append(newSheet); //---------------------------------------------------------------------------------------------------------------------
return newSheet; auto VPLayout::AddSheet(const VPSheetPtr &sheet) -> VPSheetPtr
} {
if (not sheet.isNull() && GetSheet(sheet->Uuid()).isNull())
//---------------------------------------------------------------------------------------------------------------------
auto VPLayout::AddSheet(VPSheet *sheet) -> VPSheet*
{
if ((sheet != nullptr) && not m_sheets.contains(sheet))
{ {
sheet->setParent(this);
m_sheets.append(sheet); m_sheets.append(sheet);
} }
return sheet; return sheet;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VPLayout::GetSheets() -> QList<VPSheet *> auto VPLayout::GetSheets() -> QList<VPSheetPtr>
{ {
return m_sheets; return m_sheets;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VPLayout::GetSheet(const QUuid &uuid) -> VPSheet * auto VPLayout::GetSheet(const QUuid &uuid) -> VPSheetPtr
{ {
for (auto *sheet : m_sheets) auto sheet = std::find_if(m_sheets.begin(), m_sheets.end(),
[uuid](const VPSheetPtr &sheet) { return sheet->Uuid() == uuid; });
if (sheet != m_sheets.end())
{ {
if (sheet->Uuid() == uuid) return *sheet;
{
return sheet;
}
} }
return nullptr; return {};
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPLayout::SetFocusedSheet(VPSheet *focusedSheet) void VPLayout::SetFocusedSheet(const VPSheetPtr &focusedSheet)
{ {
if (m_sheets.isEmpty()) if (m_sheets.isEmpty())
{ {
m_focusedSheet = nullptr; m_focusedSheet = {};
} }
else else
{ {
m_focusedSheet = focusedSheet == nullptr ? m_sheets.first() : focusedSheet; m_focusedSheet = focusedSheet.isNull() ? m_sheets.first() : focusedSheet;
} }
emit ActiveSheetChanged(m_focusedSheet);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VPLayout::GetFocusedSheet() -> VPSheet* auto VPLayout::GetFocusedSheet() -> VPSheetPtr
{ {
return m_focusedSheet; return m_focusedSheet;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VPLayout::GetTrashSheet() -> VPSheet* auto VPLayout::GetTrashSheet() -> VPSheetPtr
{ {
return m_trashSheet; return m_trashSheet;
} }
@ -145,14 +154,14 @@ auto VPLayout::LayoutSettings() -> VPLayoutSettings &
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VPLayout::PiecesForSheet(const VPSheet *sheet) const -> QList<VPPiece *> auto VPLayout::PiecesForSheet(const VPSheetPtr &sheet) const -> QList<VPPiecePtr>
{ {
QList<VPPiece *> list; QList<VPPiecePtr> list;
list.reserve(m_pieces.size()); list.reserve(m_pieces.size());
for (auto *piece : m_pieces) for (auto piece : m_pieces)
{ {
if ((piece != nullptr) && piece->Sheet() == sheet) if (not piece.isNull() && piece->Sheet() == sheet)
{ {
list.append(piece); list.append(piece);
} }
@ -160,3 +169,57 @@ auto VPLayout::PiecesForSheet(const VPSheet *sheet) const -> QList<VPPiece *>
return list; return list;
} }
//---------------------------------------------------------------------------------------------------------------------
QList<VPPiecePtr> VPLayout::PiecesForSheet(const QUuid &uuid) const
{
QList<VPPiecePtr> list;
list.reserve(m_pieces.size());
for (auto piece : m_pieces)
{
if (not piece.isNull())
{
VPSheetPtr sheet = piece->Sheet();
if (not sheet.isNull() && sheet->Uuid() == uuid)
{
list.append(piece);
}
}
}
return list;
}
//---------------------------------------------------------------------------------------------------------------------
QUndoStack *VPLayout::UndoStack() const
{
return m_undoStack;
}
//---------------------------------------------------------------------------------------------------------------------
void VPLayout::SetUndoStack(QUndoStack *newUndoStack)
{
m_undoStack = newUndoStack;
}
//---------------------------------------------------------------------------------------------------------------------
void VPLayout::Clear()
{
if (m_undoStack != nullptr)
{
m_undoStack->clear();
}
m_pieces.clear();
m_trashSheet->Clear();
m_sheets.clear();
m_focusedSheet.clear();
m_layoutSettings = VPLayoutSettings();
}
//---------------------------------------------------------------------------------------------------------------------
void VPLayout::AddTrashSheet(const VPSheetPtr &sheet)
{
m_trashSheet = sheet;
}

View File

@ -29,64 +29,86 @@
#define VPLAYOUT_H #define VPLAYOUT_H
#include <QList> #include <QList>
#include <QMap>
#include "def.h" #include "def.h"
#include "vplayoutsettings.h" #include "vplayoutsettings.h"
#include "layoutdef.h"
class VPPiece; class VPPiece;
class VPSheet; class VPSheet;
class QUndoStack;
class VPLayout : public QObject class VPLayout : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit VPLayout(QObject *parent=nullptr); virtual ~VPLayout() = default;
virtual ~VPLayout();
void AddPiece(VPPiece *piece); static auto CreateLayout(QUndoStack *undoStack) -> VPLayoutPtr;
auto GetPieces() const -> QList<VPPiece *>; static void AddPiece(const VPLayoutPtr &layout, const VPPiecePtr &piece);
auto GetUnplacedPieces() const -> QList<VPPiece *>;
auto GetTrashedPieces() const -> QList<VPPiece *>;
auto AddSheet() -> VPSheet*; auto GetPieces() const -> QList<VPPiecePtr>;
auto AddSheet(VPSheet *sheet) -> VPSheet*; auto GetUnplacedPieces() const -> QList<VPPiecePtr>;
auto GetSheets() -> QList<VPSheet *>; auto GetTrashedPieces() const -> QList<VPPiecePtr>;
auto GetSheet(const QUuid &uuid) -> VPSheet *;
auto AddSheet(const VPSheetPtr &sheet) -> VPSheetPtr;
auto GetSheets() -> QList<VPSheetPtr>;
auto GetSheet(const QUuid &uuid) -> VPSheetPtr;
/** /**
* @brief SetFocusedSheet Sets the focused sheet, to which pieces are added from the carrousel via drag * @brief SetFocusedSheet Sets the focused sheet, to which pieces are added from the carrousel via drag
* and drop * and drop
* @param focusedSheet the new active sheet. If nullptr, then it sets automaticaly the first sheet from m_sheets * @param focusedSheet the new active sheet. If nullptr, then it sets automaticaly the first sheet from m_sheets
*/ */
void SetFocusedSheet(VPSheet *focusedSheet = nullptr); void SetFocusedSheet(const VPSheetPtr &focusedSheet = VPSheetPtr());
/** /**
* @brief GetFocusedSheet Returns the focused sheet, to which pieces are added from the carrousel via drag * @brief GetFocusedSheet Returns the focused sheet, to which pieces are added from the carrousel via drag
* and drop * and drop
* @return the focused sheet * @return the focused sheet
*/ */
auto GetFocusedSheet() -> VPSheet*; auto GetFocusedSheet() -> VPSheetPtr;
auto GetTrashSheet() -> VPSheet*; void AddTrashSheet(const VPSheetPtr &sheet);
auto GetTrashSheet() -> VPSheetPtr;
auto LayoutSettings() -> VPLayoutSettings &; auto LayoutSettings() -> VPLayoutSettings &;
auto PiecesForSheet(const VPSheet* sheet) const -> QList<VPPiece *>; auto PiecesForSheet(const VPSheetPtr &sheet) const -> QList<VPPiecePtr>;
auto PiecesForSheet(const QUuid &uuid) const -> QList<VPPiecePtr>;
QUndoStack *UndoStack() const;
void SetUndoStack(QUndoStack *newUndoStack);
void Clear();
signals: signals:
void PieceSheetChanged(VPPiece *piece); void PieceSheetChanged(const VPPiecePtr &piece);
void ActiveSheetChanged(const VPSheetPtr &focusedSheet);
void PieceTransformationChanged(const VPPiecePtr &piece);
protected:
explicit VPLayout(QUndoStack *undoStack);
void AddPiece(const VPPiecePtr &piece);
private: private:
Q_DISABLE_COPY(VPLayout) Q_DISABLE_COPY(VPLayout)
QList<VPPiece *> m_pieces{}; QMap<QString, VPPiecePtr> m_pieces{};
VPSheet* m_trashSheet; VPSheetPtr m_trashSheet{};
QList<VPSheet*> m_sheets{}; QList<VPSheetPtr> m_sheets{};
VPSheet *m_focusedSheet{nullptr}; VPSheetPtr m_focusedSheet{};
VPLayoutSettings m_layoutSettings{}; VPLayoutSettings m_layoutSettings{};
QUndoStack *m_undoStack;
}; };
Q_DECLARE_METATYPE(VPLayoutPtr)
#endif // VPLAYOUT_H #endif // VPLAYOUT_H

View File

@ -7,6 +7,9 @@ SOURCES += \
$$PWD/dialogs/dialogpuzzlepreferences.cpp \ $$PWD/dialogs/dialogpuzzlepreferences.cpp \
$$PWD/dialogs/vpdialogabout.cpp \ $$PWD/dialogs/vpdialogabout.cpp \
$$PWD/main.cpp \ $$PWD/main.cpp \
$$PWD/undocommands/vpundocommand.cpp \
$$PWD/undocommands/vpundopiecemove.cpp \
$$PWD/undocommands/vpundopiecerotate.cpp \
$$PWD/vpapplication.cpp \ $$PWD/vpapplication.cpp \
$$PWD/carousel/vpcarrousel.cpp \ $$PWD/carousel/vpcarrousel.cpp \
$$PWD/carousel/vpcarrouselpiece.cpp \ $$PWD/carousel/vpcarrouselpiece.cpp \
@ -38,8 +41,12 @@ HEADERS += \
$$PWD/dialogs/configpages/puzzlepreferencespathpage.h \ $$PWD/dialogs/configpages/puzzlepreferencespathpage.h \
$$PWD/dialogs/dialogpuzzlepreferences.h \ $$PWD/dialogs/dialogpuzzlepreferences.h \
$$PWD/dialogs/vpdialogabout.h \ $$PWD/dialogs/vpdialogabout.h \
$$PWD/layout/layoutdef.h \
$$PWD/scene/scenedef.h \ $$PWD/scene/scenedef.h \
$$PWD/stable.h \ $$PWD/stable.h \
$$PWD/undocommands/vpundocommand.h \
$$PWD/undocommands/vpundopiecemove.h \
$$PWD/undocommands/vpundopiecerotate.h \
$$PWD/vpapplication.h \ $$PWD/vpapplication.h \
$$PWD/carousel/vpcarrousel.h \ $$PWD/carousel/vpcarrousel.h \
$$PWD/carousel/vpcarrouselpiece.h \ $$PWD/carousel/vpcarrouselpiece.h \

View File

@ -46,6 +46,8 @@
#include "vlayoutpiecepath.h" #include "vlayoutpiecepath.h"
#include "vplacelabelitem.h" #include "vplacelabelitem.h"
#include "undocommands/vpundopiecemove.h"
#include <QLoggingCategory> #include <QLoggingCategory>
Q_LOGGING_CATEGORY(pGraphicsPiece, "p.graphicsPiece") Q_LOGGING_CATEGORY(pGraphicsPiece, "p.graphicsPiece")
@ -55,7 +57,7 @@ constexpr qreal penWidth = 1;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
VPGraphicsPiece::VPGraphicsPiece(VPPiece *piece, QGraphicsItem *parent) : VPGraphicsPiece::VPGraphicsPiece(const VPPiecePtr &piece, QGraphicsItem *parent) :
QGraphicsObject(parent), QGraphicsObject(parent),
m_piece(piece) m_piece(piece)
{ {
@ -71,25 +73,11 @@ VPGraphicsPiece::VPGraphicsPiece(VPPiece *piece, QGraphicsItem *parent) :
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VPGraphicsPiece::GetPiece() -> VPPiece* auto VPGraphicsPiece::GetPiece() -> VPPiecePtr
{ {
return m_piece; return m_piece;
} }
//---------------------------------------------------------------------------------------------------------------------
void VPGraphicsPiece::TranslatePiece(qreal dx, qreal dy)
{
TranslatePiece(QPointF(dx, dy));
}
//---------------------------------------------------------------------------------------------------------------------
void VPGraphicsPiece::TranslatePiece(const QPointF &p)
{
prepareGeometryChange();
m_piece->Translate(p);
PaintPiece(); // refresh shapes
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VPGraphicsPiece::boundingRect() const -> QRectF auto VPGraphicsPiece::boundingRect() const -> QRectF
{ {
@ -149,6 +137,7 @@ void VPGraphicsPiece::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
GroupMove(event->pos()); GroupMove(event->pos());
m_moveStartPoint = event->pos(); m_moveStartPoint = event->pos();
allowChangeMerge = true;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -161,18 +150,29 @@ void VPGraphicsPiece::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
if (event->button() == Qt::LeftButton) if (event->button() == Qt::LeftButton)
{ {
setCursor(Qt::OpenHandCursor); setCursor(Qt::OpenHandCursor);
GroupMove(event->pos());
emit HideTransformationHandles(false); emit HideTransformationHandles(false);
allowChangeMerge = false;
} }
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPGraphicsPiece::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) void VPGraphicsPiece::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
{ {
QMenu menu; VPPiecePtr piece = m_piece.toStrongRef();
if (piece.isNull())
{
return;
}
QList<VPSheet *> sheets = m_piece->Layout()->GetSheets(); VPLayoutPtr layout = piece->Layout();
sheets.removeAll(m_piece->Sheet()); if (layout.isNull())
{
return;
}
QMenu menu;
QList<VPSheetPtr> sheets = layout->GetSheets();
sheets.removeAll(piece->Sheet());
QVector<QAction*> moveToActions; QVector<QAction*> moveToActions;
@ -180,11 +180,14 @@ void VPGraphicsPiece::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
{ {
QMenu *moveMenu = menu.addMenu(tr("Move to")); QMenu *moveMenu = menu.addMenu(tr("Move to"));
for (auto *sheet : sheets) for (const auto &sheet : sheets)
{ {
QAction* moveToSheet = moveMenu->addAction(sheet->GetName()); if (not sheet.isNull())
moveToSheet->setData(QVariant::fromValue(sheet)); {
moveToActions.append(moveToSheet); QAction* moveToSheet = moveMenu->addAction(sheet->GetName());
moveToSheet->setData(QVariant::fromValue(sheet));
moveToActions.append(moveToSheet);
}
} }
} }
@ -195,13 +198,13 @@ void VPGraphicsPiece::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
if (moveToActions.contains(selectedAction)) if (moveToActions.contains(selectedAction))
{ {
m_piece->SetSheet(qvariant_cast<VPSheet *>(selectedAction->data())); piece->SetSheet(qvariant_cast<VPSheetPtr>(selectedAction->data()));
emit m_piece->Layout()->PieceSheetChanged(m_piece); emit layout->PieceSheetChanged(piece);
} }
else if (selectedAction == removeAction) else if (selectedAction == removeAction)
{ {
m_piece->SetSheet(nullptr); piece->SetSheet(nullptr);
emit m_piece->Layout()->PieceSheetChanged(m_piece); emit layout->PieceSheetChanged(piece);
} }
} }
@ -211,11 +214,14 @@ void VPGraphicsPiece::PaintPiece(QPainter *painter)
QBrush noBrush(Qt::NoBrush); QBrush noBrush(Qt::NoBrush);
QBrush selectionBrush(QColor(255,160,160,60)); QBrush selectionBrush(QColor(255,160,160,60));
QRectF rect = m_piece->MappedDetailBoundingRect(); VPPiecePtr piece = m_piece.toStrongRef();
QPointF p = rect.topLeft(); if (piece.isNull())
{
return;
}
// initialises the seam line // initialises the seam line
QVector<QPointF> seamLinePoints = m_piece->GetMappedContourPoints(); QVector<QPointF> seamLinePoints = piece->GetMappedContourPoints();
if(!seamLinePoints.isEmpty()) if(!seamLinePoints.isEmpty())
{ {
m_seamLine = QPainterPath(); m_seamLine = QPainterPath();
@ -235,7 +241,7 @@ void VPGraphicsPiece::PaintPiece(QPainter *painter)
} }
// initiliases the cutting line // initiliases the cutting line
QVector<QPointF> cuttingLinepoints = m_piece->GetMappedSeamAllowancePoints(); QVector<QPointF> cuttingLinepoints = piece->GetMappedSeamAllowancePoints();
if(!cuttingLinepoints.isEmpty()) if(!cuttingLinepoints.isEmpty())
{ {
m_cuttingLine = QPainterPath(); m_cuttingLine = QPainterPath();
@ -255,9 +261,9 @@ void VPGraphicsPiece::PaintPiece(QPainter *painter)
} }
// initialises the grainline // initialises the grainline
if(m_piece->IsGrainlineEnabled()) if(piece->IsGrainlineEnabled())
{ {
QVector<QPointF> grainLinepoints = m_piece->GetMappedGrainline(); QVector<QPointF> grainLinepoints = piece->GetMappedGrainline();
if(!grainLinepoints.isEmpty()) if(!grainLinepoints.isEmpty())
{ {
QPainterPath grainline; QPainterPath grainline;
@ -282,10 +288,10 @@ void VPGraphicsPiece::PaintPiece(QPainter *painter)
} }
// initialises the internal paths // initialises the internal paths
QVector<VLayoutPiecePath> internalPaths = m_piece->GetInternalPaths(); QVector<VLayoutPiecePath> internalPaths = piece->GetInternalPaths();
for (const auto& piecePath : internalPaths) for (const auto& piecePath : internalPaths)
{ {
QPainterPath path = m_piece->GetMatrix().map(piecePath.GetPainterPath()); QPainterPath path = piece->GetMatrix().map(piecePath.GetPainterPath());
if (painter != nullptr) if (painter != nullptr)
{ {
@ -297,7 +303,7 @@ void VPGraphicsPiece::PaintPiece(QPainter *painter)
} }
// initialises the passmarks // initialises the passmarks
QVector<VLayoutPassmark> passmarks = m_piece->GetMappedPassmarks(); QVector<VLayoutPassmark> passmarks = piece->GetMappedPassmarks();
for(auto &passmark : passmarks) for(auto &passmark : passmarks)
{ {
QPainterPath passmarkPath; QPainterPath passmarkPath;
@ -317,7 +323,7 @@ void VPGraphicsPiece::PaintPiece(QPainter *painter)
} }
// initialises the place labels (buttons etc) // initialises the place labels (buttons etc)
QVector<VLayoutPlaceLabel> placeLabels = m_piece->GetMappedPlaceLabels(); QVector<VLayoutPlaceLabel> placeLabels = piece->GetMappedPlaceLabels();
for(auto &placeLabel : placeLabels) for(auto &placeLabel : placeLabels)
{ {
QPainterPath path = VPlaceLabelItem::LabelShapePath(placeLabel.shape); QPainterPath path = VPlaceLabelItem::LabelShapePath(placeLabel.shape);
@ -345,27 +351,63 @@ void VPGraphicsPiece::GroupMove(const QPointF &pos)
if (scene() != nullptr) if (scene() != nullptr)
{ {
QList<QGraphicsItem *> list = scene()->selectedItems(); QList<QGraphicsItem *> list = scene()->selectedItems();
for (auto *item : list)
if (list.isEmpty())
{ {
if (item->type() == UserType + static_cast<int>(PGraphicsItem::Piece)) return;
{ }
auto *pieceItem = dynamic_cast<VPGraphicsPiece*>(item);
pieceItem->TranslatePiece(pos-m_moveStartPoint); VPPiecePtr piece = m_piece.toStrongRef();
} if (piece.isNull())
{
return;
}
VPLayoutPtr layout = piece->Layout();
if (layout.isNull())
{
return;
}
auto PreparePieces = [list]()
{
QVector<VPPiecePtr> pieces;
for (auto *item : list)
{
if (item->type() == VPGraphicsPiece::Type)
{
auto *pieceItem = dynamic_cast<VPGraphicsPiece*>(item);
pieces.append(pieceItem->GetPiece());
}
}
return pieces;
};
QVector<VPPiecePtr> pieces = PreparePieces();
QPointF newPos = pos - m_moveStartPoint;
if (pieces.size() == 1)
{
auto *command = new VPUndoPieceMove(pieces.first(), newPos.x(), newPos.y(), allowChangeMerge);
layout->UndoStack()->push(command);
}
else if (pieces.size() > 1)
{
auto *command = new VPUndoPiecesMove(pieces, newPos.x(), newPos.y(), allowChangeMerge);
layout->UndoStack()->push(command);
} }
emit PiecePositionChanged();
} }
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPGraphicsPiece::on_Rotate(const QPointF &center, qreal angle) void VPGraphicsPiece::on_RefreshPiece(const VPPiecePtr &piece)
{ {
if (isSelected()) if (m_piece == piece)
{ {
prepareGeometryChange(); prepareGeometryChange();
m_piece->Rotate(center, angle); PaintPiece(); // refresh shapes
PaintPiece(); // Update shapes emit PieceTransformationChanged();
update();
} }
} }
@ -376,8 +418,12 @@ auto VPGraphicsPiece::itemChange(GraphicsItemChange change, const QVariant &valu
{ {
if(change == ItemSelectedHasChanged) if(change == ItemSelectedHasChanged)
{ {
emit PieceSelectionChanged(); VPPiecePtr piece = m_piece.toStrongRef();
m_piece->SetSelected(value.toBool()); if (not piece.isNull())
{
emit PieceSelectionChanged();
piece->SetSelected(value.toBool());
}
} }
} }

View File

@ -33,24 +33,20 @@
#include <QCursor> #include <QCursor>
#include "scenedef.h" #include "scenedef.h"
#include "../layout/layoutdef.h"
class VPPiece;
class VPGraphicsPiece : public QGraphicsObject class VPGraphicsPiece : public QGraphicsObject
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit VPGraphicsPiece(VPPiece *piece, QGraphicsItem *parent = nullptr); explicit VPGraphicsPiece(const VPPiecePtr &piece, QGraphicsItem *parent = nullptr);
~VPGraphicsPiece() = default; ~VPGraphicsPiece() = default;
/** /**
* @brief GetPiece Returns the piece that corresponds to the graphics piece * @brief GetPiece Returns the piece that corresponds to the graphics piece
* @return the piece * @return the piece
*/ */
auto GetPiece() -> VPPiece*; auto GetPiece() -> VPPiecePtr;
void TranslatePiece(qreal dx, qreal dy);
void TranslatePiece(const QPointF &p);
virtual int type() const override {return Type;} virtual int type() const override {return Type;}
enum { Type = UserType + static_cast<int>(PGraphicsItem::Piece)}; enum { Type = UserType + static_cast<int>(PGraphicsItem::Piece)};
@ -58,10 +54,10 @@ public:
signals: signals:
void PieceSelectionChanged(); void PieceSelectionChanged();
void HideTransformationHandles(bool hide); void HideTransformationHandles(bool hide);
void PiecePositionChanged(); void PieceTransformationChanged();
public slots: public slots:
void on_Rotate(const QPointF &center, qreal angle); void on_RefreshPiece(const VPPiecePtr &piece);
protected: protected:
auto boundingRect() const -> QRectF override; auto boundingRect() const -> QRectF override;
@ -78,7 +74,7 @@ protected:
private: private:
Q_DISABLE_COPY(VPGraphicsPiece) Q_DISABLE_COPY(VPGraphicsPiece)
VPPiece *m_piece; VPPieceWeakPtr m_piece;
QPainterPath m_cuttingLine{}; QPainterPath m_cuttingLine{};
QPainterPath m_seamLine{}; QPainterPath m_seamLine{};
@ -88,6 +84,8 @@ private:
QCursor m_rotateCursor{}; QCursor m_rotateCursor{};
bool allowChangeMerge{false};
void PaintPiece(QPainter *painter=nullptr); void PaintPiece(QPainter *painter=nullptr);
void GroupMove(const QPointF &pos); void GroupMove(const QPointF &pos);

View File

@ -37,6 +37,8 @@
#include "../vmisc/compatibility.h" #include "../vmisc/compatibility.h"
#include "../vwidgets/global.h" #include "../vwidgets/global.h"
#include "../layout/vplayout.h" #include "../layout/vplayout.h"
#include "../undocommands/vpundopiecerotate.h"
#include "vpgraphicspiece.h"
namespace namespace
{ {
@ -67,11 +69,11 @@ enum class HandleCorner : int
BottomLeft = 4 BottomLeft = 4
}; };
auto TransformationOrigin(VPLayout *layout, const QRectF &boundingRect) -> QPointF auto TransformationOrigin(const VPLayoutPtr &layout, const QRectF &boundingRect) -> QPointF
{ {
SCASSERT(layout != nullptr) SCASSERT(layout != nullptr)
VPSheet *sheet = layout->GetFocusedSheet(); VPSheetPtr sheet = layout->GetFocusedSheet();
if (sheet != nullptr) if (not sheet.isNull())
{ {
VPTransformationOrigon origin = sheet->TransformationOrigin(); VPTransformationOrigon origin = sheet->TransformationOrigin();
return origin.origin; return origin.origin;
@ -82,7 +84,7 @@ auto TransformationOrigin(VPLayout *layout, const QRectF &boundingRect) -> QPoin
} // namespace } // namespace
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
VPGraphicsTransformationOrigin::VPGraphicsTransformationOrigin(VPLayout *layout, QGraphicsItem *parent) VPGraphicsTransformationOrigin::VPGraphicsTransformationOrigin(const VPLayoutPtr &layout, QGraphicsItem *parent)
: QGraphicsObject(parent), : QGraphicsObject(parent),
m_layout(layout), m_layout(layout),
m_color(defaultColor) m_color(defaultColor)
@ -113,14 +115,14 @@ void VPGraphicsTransformationOrigin::on_ShowOrigin(bool show)
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QRectF VPGraphicsTransformationOrigin::boundingRect() const auto VPGraphicsTransformationOrigin::boundingRect() const -> QRectF
{ {
constexpr qreal halfPenWidth = penWidth/2.; constexpr qreal halfPenWidth = penWidth/2.;
return Center2().boundingRect().adjusted(-halfPenWidth, -halfPenWidth, halfPenWidth, halfPenWidth); return Center2().boundingRect().adjusted(-halfPenWidth, -halfPenWidth, halfPenWidth, halfPenWidth);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QPainterPath VPGraphicsTransformationOrigin::shape() const auto VPGraphicsTransformationOrigin::shape() const -> QPainterPath
{ {
return Center2(); return Center2();
} }
@ -170,15 +172,19 @@ void VPGraphicsTransformationOrigin::mousePressEvent(QGraphicsSceneMouseEvent *e
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPGraphicsTransformationOrigin::mouseMoveEvent(QGraphicsSceneMouseEvent *event) void VPGraphicsTransformationOrigin::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{ {
VPSheet *sheet = m_layout->GetFocusedSheet(); VPLayoutPtr layout = m_layout.toStrongRef();
if (sheet != nullptr) if (not layout.isNull())
{ {
VPTransformationOrigon origin = sheet->TransformationOrigin(); VPSheetPtr sheet = layout->GetFocusedSheet();
origin.origin = event->scenePos(); if (not sheet.isNull())
origin.custom = true; {
sheet->SetTransformationOrigin(origin); VPTransformationOrigon origin = sheet->TransformationOrigin();
origin.origin = event->scenePos();
origin.custom = true;
sheet->SetTransformationOrigin(origin);
}
prepareGeometryChange();
} }
prepareGeometryChange();
QGraphicsObject::mouseMoveEvent(event); QGraphicsObject::mouseMoveEvent(event);
} }
@ -251,7 +257,7 @@ auto VPGraphicsTransformationOrigin::RotationCenter(QPainter *painter) const ->
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QPainterPath VPGraphicsTransformationOrigin::Center1() const auto VPGraphicsTransformationOrigin::Center1() const -> QPainterPath
{ {
const qreal scale = SceneScale(scene()); const qreal scale = SceneScale(scene());
qreal radius = centerRadius1/scale; qreal radius = centerRadius1/scale;
@ -265,7 +271,7 @@ QPainterPath VPGraphicsTransformationOrigin::Center1() const
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QPainterPath VPGraphicsTransformationOrigin::Center2() const auto VPGraphicsTransformationOrigin::Center2() const -> QPainterPath
{ {
const qreal scale = SceneScale(scene()); const qreal scale = SceneScale(scene());
qreal radius = centerRadius2/scale; qreal radius = centerRadius2/scale;
@ -280,7 +286,7 @@ QPainterPath VPGraphicsTransformationOrigin::Center2() const
// VPGraphicsPieceControls // VPGraphicsPieceControls
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
VPGraphicsPieceControls::VPGraphicsPieceControls(VPLayout *layout, QGraphicsItem *parent) VPGraphicsPieceControls::VPGraphicsPieceControls(const VPLayoutPtr &layout, QGraphicsItem *parent)
: QGraphicsObject(parent), : QGraphicsObject(parent),
m_layout(layout) m_layout(layout)
{ {
@ -294,20 +300,30 @@ VPGraphicsPieceControls::VPGraphicsPieceControls(VPLayout *layout, QGraphicsItem
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPGraphicsPieceControls::on_UpdateControls() void VPGraphicsPieceControls::on_UpdateControls()
{ {
m_pieceRect = PiecesBoundingRect(); if (m_ignorePieceTransformation)
{
return;
}
m_selectedPieces = SelectedPieces();
m_pieceRect = PiecesBoundingRect(m_selectedPieces);
setVisible(not m_pieceRect.isNull()); setVisible(not m_pieceRect.isNull());
if (not m_pieceRect.isNull()) if (not m_pieceRect.isNull())
{ {
VPSheet *sheet = m_layout->GetFocusedSheet(); VPLayoutPtr layout = m_layout.toStrongRef();
if (sheet != nullptr) if (not layout.isNull())
{ {
VPTransformationOrigon origin = sheet->TransformationOrigin(); VPSheetPtr sheet = layout->GetFocusedSheet();
if (not origin.custom) if (not sheet.isNull())
{ {
origin.origin = m_pieceRect.center(); VPTransformationOrigon origin = sheet->TransformationOrigin();
sheet->SetTransformationOrigin(origin); if (not origin.custom)
emit TransformationOriginChanged(); {
origin.origin = m_pieceRect.center();
sheet->SetTransformationOrigin(origin);
emit TransformationOriginChanged();
}
} }
} }
} }
@ -320,6 +336,7 @@ void VPGraphicsPieceControls::on_UpdateControls()
void VPGraphicsPieceControls::on_HideHandles(bool hide) void VPGraphicsPieceControls::on_HideHandles(bool hide)
{ {
m_controlsVisible = not hide; m_controlsVisible = not hide;
update();
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -364,6 +381,7 @@ void VPGraphicsPieceControls::mousePressEvent(QGraphicsSceneMouseEvent *event)
m_rotationStartPoint = event->scenePos(); m_rotationStartPoint = event->scenePos();
m_controlsVisible = false; m_controlsVisible = false;
m_handleCorner = HandleCorner(event->scenePos()); m_handleCorner = HandleCorner(event->scenePos());
m_ignorePieceTransformation = true;
prepareGeometryChange(); prepareGeometryChange();
} }
else else
@ -380,35 +398,39 @@ void VPGraphicsPieceControls::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{ {
if (not m_originSaved) if (not m_originSaved)
{ {
VPSheet *sheet = m_layout->GetFocusedSheet(); VPLayoutPtr layout = m_layout.toStrongRef();
if (sheet != nullptr) if (not layout.isNull())
{ {
m_savedOrigin = sheet->TransformationOrigin(); VPSheetPtr sheet = layout->GetFocusedSheet();
m_originSaved = true; if (not sheet.isNull())
m_pieceRect = PiecesBoundingRect(); {
m_savedOrigin = sheet->TransformationOrigin();
m_originSaved = true;
m_pieceRect = PiecesBoundingRect(m_selectedPieces);
VPTransformationOrigon origin; VPTransformationOrigon origin;
origin.custom = true; origin.custom = true;
if (static_cast<enum HandleCorner>(m_handleCorner) == HandleCorner::TopLeft) if (static_cast<enum HandleCorner>(m_handleCorner) == HandleCorner::TopLeft)
{ {
origin.origin = m_pieceRect.topLeft(); origin.origin = m_pieceRect.topLeft();
} }
else if (static_cast<enum HandleCorner>(m_handleCorner) == HandleCorner::TopRight) else if (static_cast<enum HandleCorner>(m_handleCorner) == HandleCorner::TopRight)
{ {
origin.origin = m_pieceRect.topRight(); origin.origin = m_pieceRect.topRight();
} }
else if (static_cast<enum HandleCorner>(m_handleCorner) == HandleCorner::BottomRight) else if (static_cast<enum HandleCorner>(m_handleCorner) == HandleCorner::BottomRight)
{ {
origin.origin = m_pieceRect.bottomRight(); origin.origin = m_pieceRect.bottomRight();
} }
else if (static_cast<enum HandleCorner>(m_handleCorner) == HandleCorner::BottomLeft) else if (static_cast<enum HandleCorner>(m_handleCorner) == HandleCorner::BottomLeft)
{ {
origin.origin = m_pieceRect.bottomLeft(); origin.origin = m_pieceRect.bottomLeft();
} }
sheet->SetTransformationOrigin(origin); sheet->SetTransformationOrigin(origin);
emit TransformationOriginChanged(); emit TransformationOriginChanged();
}
} }
} }
} }
@ -416,18 +438,22 @@ void VPGraphicsPieceControls::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{ {
if (m_originSaved) if (m_originSaved)
{ {
VPSheet *sheet = m_layout->GetFocusedSheet(); VPLayoutPtr layout = m_layout.toStrongRef();
if (sheet != nullptr) if (not layout.isNull())
{ {
if (not m_savedOrigin.custom) VPSheetPtr sheet = layout->GetFocusedSheet();
if (sheet != nullptr)
{ {
m_pieceRect = PiecesBoundingRect(); if (not m_savedOrigin.custom)
m_savedOrigin.origin = m_pieceRect.center(); {
m_pieceRect = PiecesBoundingRect(m_selectedPieces);
m_savedOrigin.origin = m_pieceRect.center();
}
sheet->SetTransformationOrigin(m_savedOrigin);
emit TransformationOriginChanged();
} }
sheet->SetTransformationOrigin(m_savedOrigin); m_originSaved = false;
emit TransformationOriginChanged();
} }
m_originSaved = false;
} }
} }
@ -442,7 +468,33 @@ void VPGraphicsPieceControls::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
if (not qFuzzyIsNull(angle)) if (not qFuzzyIsNull(angle))
{ {
emit Rotate(rotationOrigin, angle); auto PreparePieces = [this]()
{
QVector<VPPiecePtr> pieces;
for (auto *item : m_selectedPieces)
{
pieces.append(item->GetPiece());
}
return pieces;
};
QVector<VPPiecePtr> pieces = PreparePieces();
VPLayoutPtr layout = m_layout.toStrongRef();
if (not layout.isNull())
{
if (pieces.size() == 1)
{
auto *command = new VPUndoPieceRotate(pieces.first(), rotationOrigin, angle, allowChangeMerge);
layout->UndoStack()->push(command);
}
else if (pieces.size() > 1)
{
auto *command = new VPUndoPiecesRotate(pieces, rotationOrigin, angle, allowChangeMerge);
layout->UndoStack()->push(command);
}
}
} }
if (m_originSaved && m_savedOrigin.custom) if (m_originSaved && m_savedOrigin.custom)
@ -453,6 +505,7 @@ void VPGraphicsPieceControls::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
} }
m_rotationStartPoint = rotationNewPoint; m_rotationStartPoint = rotationNewPoint;
allowChangeMerge = true;
QGraphicsObject::mouseMoveEvent(event); QGraphicsObject::mouseMoveEvent(event);
} }
@ -462,28 +515,40 @@ void VPGraphicsPieceControls::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
if(event->button() == Qt::LeftButton) if(event->button() == Qt::LeftButton)
{ {
m_controlsVisible = true; m_controlsVisible = true;
m_ignorePieceTransformation = false;
if (m_originSaved) if (m_originSaved)
{ {
VPSheet *sheet = m_layout->GetFocusedSheet(); VPLayoutPtr layout = m_layout.toStrongRef();
if (sheet != nullptr) if (not layout.isNull())
{ {
if (not m_savedOrigin.custom) VPSheetPtr sheet = layout->GetFocusedSheet();
if (not sheet.isNull())
{ {
m_pieceRect = PiecesBoundingRect(); if (not m_savedOrigin.custom)
m_savedOrigin.origin = m_pieceRect.center(); {
m_pieceRect = PiecesBoundingRect(m_selectedPieces);
m_savedOrigin.origin = m_pieceRect.center();
}
sheet->SetTransformationOrigin(m_savedOrigin);
emit TransformationOriginChanged();
} }
sheet->SetTransformationOrigin(m_savedOrigin); m_originSaved = false;
emit TransformationOriginChanged();
} }
m_originSaved = false;
} }
on_UpdateControls(); on_UpdateControls();
allowChangeMerge = false;
} }
QGraphicsObject::mouseReleaseEvent(event); QGraphicsObject::mouseReleaseEvent(event);
} }
//---------------------------------------------------------------------------------------------------------------------
void VPGraphicsPieceControls::SetIgnorePieceTransformation(bool newIgnorePieceTransformation)
{
m_ignorePieceTransformation = newIgnorePieceTransformation;
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VPGraphicsPieceControls::TopLeftControl(QPainter *painter) const -> QPainterPath auto VPGraphicsPieceControls::TopLeftControl(QPainter *painter) const -> QPainterPath
{ {
@ -522,7 +587,7 @@ auto VPGraphicsPieceControls::BottomRightControl(QPainter *painter) const -> QPa
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QPainterPath VPGraphicsPieceControls::Handles() const auto VPGraphicsPieceControls::Handles() const -> QPainterPath
{ {
QPainterPath path; QPainterPath path;
@ -690,22 +755,38 @@ auto VPGraphicsPieceControls::ArrowPath() const -> QPainterPath
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QRectF VPGraphicsPieceControls::PiecesBoundingRect() const auto VPGraphicsPieceControls::SelectedPieces() const -> QVector<VPGraphicsPiece *>
{ {
QRectF rect; QVector<VPGraphicsPiece *> pieces;
QGraphicsScene *scene = this->scene(); QGraphicsScene *scene = this->scene();
if (scene != nullptr) if (scene != nullptr)
{ {
QList<QGraphicsItem *> list = scene->selectedItems(); QList<QGraphicsItem *> list = scene->selectedItems();
for (auto *item : list) for (auto *item : list)
{ {
if (item->type() == UserType + static_cast<int>(PGraphicsItem::Piece)) if (item->type() == VPGraphicsPiece::Type)
{ {
rect = rect.united(item->sceneBoundingRect()); auto *pieceItem = dynamic_cast<VPGraphicsPiece*>(item);
if (pieceItem != nullptr)
{
pieces.append(pieceItem);
}
} }
} }
} }
return pieces;
}
//---------------------------------------------------------------------------------------------------------------------
auto VPGraphicsPieceControls::PiecesBoundingRect(const QVector<VPGraphicsPiece *> &selectedPieces) const -> QRectF
{
QRectF rect;
for (auto *item : selectedPieces)
{
rect = rect.united(item->sceneBoundingRect());
}
return rect; return rect;
} }

View File

@ -35,12 +35,13 @@
#include "../layout/vpsheet.h" #include "../layout/vpsheet.h"
class VPLayout; class VPLayout;
class VPGraphicsPiece;
class VPGraphicsTransformationOrigin : public QGraphicsObject class VPGraphicsTransformationOrigin : public QGraphicsObject
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit VPGraphicsTransformationOrigin(VPLayout *layout, QGraphicsItem * parent = nullptr); explicit VPGraphicsTransformationOrigin(const VPLayoutPtr &layout, QGraphicsItem * parent = nullptr);
virtual int type() const override {return Type;} virtual int type() const override {return Type;}
enum { Type = UserType + static_cast<int>(PGraphicsItem::TransformationOrigin)}; enum { Type = UserType + static_cast<int>(PGraphicsItem::TransformationOrigin)};
@ -65,9 +66,9 @@ protected:
private: private:
Q_DISABLE_COPY(VPGraphicsTransformationOrigin) Q_DISABLE_COPY(VPGraphicsTransformationOrigin)
bool m_originVisible{true}; bool m_originVisible{true};
VPLayout *m_layout; VPLayoutWeakPtr m_layout{};
QColor m_color; QColor m_color;
auto RotationCenter(QPainter *painter = nullptr) const -> QPainterPath; auto RotationCenter(QPainter *painter = nullptr) const -> QPainterPath;
auto Center1() const -> QPainterPath; auto Center1() const -> QPainterPath;
@ -78,13 +79,14 @@ class VPGraphicsPieceControls : public QGraphicsObject
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit VPGraphicsPieceControls(VPLayout *layout, QGraphicsItem * parent = nullptr); explicit VPGraphicsPieceControls(const VPLayoutPtr &layout, QGraphicsItem * parent = nullptr);
virtual int type() const override {return Type;} virtual int type() const override {return Type;}
enum { Type = UserType + static_cast<int>(PGraphicsItem::Handles)}; enum { Type = UserType + static_cast<int>(PGraphicsItem::Handles)};
void SetIgnorePieceTransformation(bool newIgnorePieceTransformation);
signals: signals:
void Rotate(const QPointF &center, qreal angle);
void ShowOrigin(bool show); void ShowOrigin(bool show);
void TransformationOriginChanged(); void TransformationOriginChanged();
@ -103,13 +105,16 @@ protected:
private: private:
Q_DISABLE_COPY(VPGraphicsPieceControls) Q_DISABLE_COPY(VPGraphicsPieceControls)
QRectF m_pieceRect{}; QRectF m_pieceRect{};
QPointF m_rotationStartPoint{}; QPointF m_rotationStartPoint{};
bool m_controlsVisible{true}; bool m_controlsVisible{true};
VPLayout *m_layout; VPLayoutWeakPtr m_layout{};
int m_handleCorner{0}; int m_handleCorner{0};
VPTransformationOrigon m_savedOrigin{}; VPTransformationOrigon m_savedOrigin{};
bool m_originSaved{false}; bool m_originSaved{false};
bool allowChangeMerge{false};
QVector<VPGraphicsPiece *> m_selectedPieces{};
bool m_ignorePieceTransformation{false};
auto TopLeftControl(QPainter *painter = nullptr) const -> QPainterPath; auto TopLeftControl(QPainter *painter = nullptr) const -> QPainterPath;
auto TopRightControl(QPainter *painter = nullptr) const -> QPainterPath; auto TopRightControl(QPainter *painter = nullptr) const -> QPainterPath;
@ -122,7 +127,8 @@ private:
auto ArrowPath() const -> QPainterPath; auto ArrowPath() const -> QPainterPath;
auto PiecesBoundingRect() const -> QRectF; auto SelectedPieces() const -> QVector<VPGraphicsPiece *>;
auto PiecesBoundingRect(const QVector<VPGraphicsPiece *> &selectedPieces) const -> QRectF;
auto HandleCorner(const QPointF &pos) const -> int; auto HandleCorner(const QPointF &pos) const -> int;
}; };

View File

@ -1,4 +1,4 @@
/************************************************************************ /*******************************************************************
** **
** @file vpgraphicssheet.cpp ** @file vpgraphicssheet.cpp
** @author Ronan Le Tiec ** @author Ronan Le Tiec
@ -33,7 +33,7 @@
#include <QtMath> #include <QtMath>
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
VPGraphicsSheet::VPGraphicsSheet(VPLayout *layout, QGraphicsItem *parent): VPGraphicsSheet::VPGraphicsSheet(const VPLayoutPtr &layout, QGraphicsItem *parent):
QGraphicsItem(parent), QGraphicsItem(parent),
m_layout(layout), m_layout(layout),
m_boundingRect(GetSheetRect()) m_boundingRect(GetSheetRect())
@ -66,12 +66,14 @@ void VPGraphicsSheet::paint(QPainter *painter, const QStyleOptionGraphicsItem *o
painter->drawRect(sheetRect); painter->drawRect(sheetRect);
} }
if(m_layout->LayoutSettings().GetShowGrid()) VPLayoutPtr layout = m_layout.toStrongRef();
if(not layout.isNull() && layout->LayoutSettings().GetShowGrid())
{ {
pen.setColor(QColor(204,204,204)); pen.setColor(QColor(204,204,204));
painter->setPen(pen); painter->setPen(pen);
qreal colWidth = m_layout->LayoutSettings().GetGridColWidth(); qreal colWidth = layout->LayoutSettings().GetGridColWidth();
if(colWidth > 0) if(colWidth > 0)
{ {
qreal colX = colWidth; qreal colX = colWidth;
@ -83,7 +85,7 @@ void VPGraphicsSheet::paint(QPainter *painter, const QStyleOptionGraphicsItem *o
} }
} }
qreal rowHeight = m_layout->LayoutSettings().GetGridRowHeight(); qreal rowHeight = layout->LayoutSettings().GetGridRowHeight();
if(rowHeight > 0) if(rowHeight > 0)
{ {
qreal rowY = rowHeight; qreal rowY = rowHeight;
@ -101,11 +103,17 @@ void VPGraphicsSheet::paint(QPainter *painter, const QStyleOptionGraphicsItem *o
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QRectF VPGraphicsSheet::GetSheetRect() const auto VPGraphicsSheet::GetSheetRect() const -> QRectF
{ {
VPLayoutPtr layout = m_layout.toStrongRef();
if (layout.isNull())
{
return {};
}
QPoint topLeft = QPoint(0,0); QPoint topLeft = QPoint(0,0);
QSizeF size = m_layout->LayoutSettings().GetSheetSize(); QSizeF size = layout->LayoutSettings().GetSheetSize();
if(m_layout->LayoutSettings().GetOrientation() == PageOrientation::Landscape) if(layout->LayoutSettings().GetOrientation() == PageOrientation::Landscape)
{ {
size.transpose(); size.transpose();
} }
@ -114,20 +122,24 @@ QRectF VPGraphicsSheet::GetSheetRect() const
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QRectF VPGraphicsSheet::GetMarginsRect() const auto VPGraphicsSheet::GetMarginsRect() const -> QRectF
{ {
QMarginsF margins = m_layout->LayoutSettings().GetSheetMargins(); VPLayoutPtr layout = m_layout.toStrongRef();
QSizeF size = m_layout->LayoutSettings().GetSheetSize(); if (layout.isNull())
{
return {};
}
if(m_layout->LayoutSettings().GetOrientation() == PageOrientation::Landscape) QMarginsF margins = layout->LayoutSettings().GetSheetMargins();
QSizeF size = layout->LayoutSettings().GetSheetSize();
if(layout->LayoutSettings().GetOrientation() == PageOrientation::Landscape)
{ {
size.transpose(); size.transpose();
} }
QRectF rect = QRectF( QRectF rect = QRectF(QPointF(margins.left(),margins.top()),
QPointF(margins.left(),margins.top()), QPointF(size.width()-margins.right(), size.height()-margins.bottom()));
QPointF(size.width()-margins.right(), size.height()-margins.bottom())
);
return rect; return rect;
} }
@ -140,11 +152,11 @@ void VPGraphicsSheet::SetShowMargin(bool value)
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPGraphicsSheet::SetShowBorder(bool value) void VPGraphicsSheet::SetShowBorder(bool value)
{ {
m_showBorder = value; m_showBorder = value;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QRectF VPGraphicsSheet::boundingRect() const auto VPGraphicsSheet::boundingRect() const -> QRectF
{ {
return m_boundingRect; return m_boundingRect;
} }

View File

@ -32,19 +32,21 @@
#include <QGraphicsItem> #include <QGraphicsItem>
#include <QPainter> #include <QPainter>
#include "../layout/layoutdef.h"
class VPLayout; class VPLayout;
class VPGraphicsSheet : public QGraphicsItem class VPGraphicsSheet : public QGraphicsItem
{ {
public: public:
explicit VPGraphicsSheet(VPLayout *sheet, QGraphicsItem *parent = nullptr); explicit VPGraphicsSheet(const VPLayoutPtr &layout, QGraphicsItem *parent = nullptr);
~VPGraphicsSheet()=default; ~VPGraphicsSheet()=default;
QRectF boundingRect() const override; auto boundingRect() const -> QRectF override;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
QRectF GetSheetRect() const; auto GetSheetRect() const -> QRectF;
QRectF GetMarginsRect() const; auto GetMarginsRect() const -> QRectF;
/** /**
* @brief SetShowMargin Sets Wether we see the margin * @brief SetShowMargin Sets Wether we see the margin
@ -61,7 +63,7 @@ public:
private: private:
Q_DISABLE_COPY(VPGraphicsSheet) Q_DISABLE_COPY(VPGraphicsSheet)
VPLayout *m_layout{nullptr}; VPLayoutWeakPtr m_layout{};
QRectF m_boundingRect; QRectF m_boundingRect;
bool m_showMargin{true}; bool m_showMargin{true};

View File

@ -4,7 +4,7 @@
#include "../layout/vplayout.h" #include "../layout/vplayout.h"
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
VPGraphicsTileGrid::VPGraphicsTileGrid(VPLayout *layout, VPTileFactory *tileFactory,QGraphicsItem *parent): VPGraphicsTileGrid::VPGraphicsTileGrid(const VPLayoutPtr &layout, VPTileFactory *tileFactory, QGraphicsItem *parent):
QGraphicsItem(parent), QGraphicsItem(parent),
m_tileFactory(tileFactory), m_tileFactory(tileFactory),
m_layout(layout) m_layout(layout)
@ -21,7 +21,8 @@ VPGraphicsTileGrid::~VPGraphicsTileGrid()
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QRectF VPGraphicsTileGrid::boundingRect() const QRectF VPGraphicsTileGrid::boundingRect() const
{ {
if(m_layout->LayoutSettings().GetShowTiles()) VPLayoutPtr layout = m_layout.toStrongRef();
if(not layout.isNull() && layout->LayoutSettings().GetShowTiles())
{ {
return QRectF(0, return QRectF(0,
0, 0,
@ -39,7 +40,8 @@ void VPGraphicsTileGrid::paint(QPainter *painter, const QStyleOptionGraphicsItem
Q_UNUSED(widget); Q_UNUSED(widget);
Q_UNUSED(option); Q_UNUSED(option);
if(m_layout->LayoutSettings().GetShowTiles()) VPLayoutPtr layout = m_layout.toStrongRef();
if(not layout.isNull() && layout->LayoutSettings().GetShowTiles())
{ {
QPen pen(QColor(255,0,0,127), 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin); QPen pen(QColor(255,0,0,127), 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
pen.setCosmetic(true); pen.setCosmetic(true);

View File

@ -33,6 +33,7 @@
#include <QPainter> #include <QPainter>
#include "../vmisc/def.h" #include "../vmisc/def.h"
#include "../layout/layoutdef.h"
class VPTileFactory; class VPTileFactory;
class VPLayout; class VPLayout;
@ -40,7 +41,7 @@ class VPLayout;
class VPGraphicsTileGrid : public QGraphicsItem class VPGraphicsTileGrid : public QGraphicsItem
{ {
public: public:
explicit VPGraphicsTileGrid(VPLayout* layout, VPTileFactory *tileFactory, QGraphicsItem *parent = nullptr); explicit VPGraphicsTileGrid(const VPLayoutPtr &layout, VPTileFactory *tileFactory, QGraphicsItem *parent = nullptr);
~VPGraphicsTileGrid(); ~VPGraphicsTileGrid();
QRectF boundingRect() const override; QRectF boundingRect() const override;
@ -50,8 +51,8 @@ public:
private: private:
Q_DISABLE_COPY(VPGraphicsTileGrid) Q_DISABLE_COPY(VPGraphicsTileGrid)
VPTileFactory *m_tileFactory{nullptr}; VPTileFactory * m_tileFactory{nullptr};
VPLayout *m_layout{nullptr}; VPLayoutWeakPtr m_layout{};
}; };
#endif // VPGRAPHICSTILEGRID_H #endif // VPGRAPHICSTILEGRID_H

View File

@ -46,6 +46,7 @@
#include "vptilefactory.h" #include "vptilefactory.h"
#include "vpgraphicspiececontrols.h" #include "vpgraphicspiececontrols.h"
#include "../undocommands/vpundopiecemove.h" #include "../undocommands/vpundopiecemove.h"
#include "../undocommands/vpundopiecerotate.h"
#include <QLoggingCategory> #include <QLoggingCategory>
@ -95,36 +96,6 @@ VPMainGraphicsView::VPMainGraphicsView(const VPLayoutPtr &layout, VPTileFactory
restoreOrigin->setShortcut(restoreOriginShortcut); restoreOrigin->setShortcut(restoreOriginShortcut);
connect(restoreOrigin, &QAction::triggered, this, &VPMainGraphicsView::RestoreOrigin); connect(restoreOrigin, &QAction::triggered, this, &VPMainGraphicsView::RestoreOrigin);
this->addAction(restoreOrigin); this->addAction(restoreOrigin);
auto *rotateByPlus15 = new QAction(this);
rotateByPlus15->setShortcut(QKeySequence(Qt::Key_BracketLeft));
connect(rotateByPlus15, &QAction::triggered, this, &VPMainGraphicsView::RotatePiecesByPlus15);
this->addAction(rotateByPlus15);
auto *rotateByMinus15 = new QAction(this);
rotateByMinus15->setShortcut(QKeySequence(Qt::Key_BracketRight));
connect(rotateByMinus15, &QAction::triggered, this, &VPMainGraphicsView::RotatePiecesByMinus15);
this->addAction(rotateByMinus15);
auto *rotateByPlus90 = new QAction(this);
rotateByPlus90->setShortcut(QKeySequence(Qt::ControlModifier + Qt::Key_BracketLeft));
connect(rotateByPlus90, &QAction::triggered, this, &VPMainGraphicsView::RotatePiecesByPlus90);
this->addAction(rotateByPlus90);
auto *rotateByMinus90 = new QAction(this);
rotateByMinus90->setShortcut(QKeySequence(Qt::ControlModifier + Qt::Key_BracketRight));
connect(rotateByMinus90, &QAction::triggered, this, &VPMainGraphicsView::RotatePiecesByMinus90);
this->addAction(rotateByMinus90);
auto *rotateByPlus1 = new QAction(this);
rotateByPlus1->setShortcut(QKeySequence(Qt::AltModifier + Qt::Key_BracketLeft));
connect(rotateByPlus1, &QAction::triggered, this, &VPMainGraphicsView::RotatePiecesByPlus1);
this->addAction(rotateByPlus1);
auto *rotateByMinus1 = new QAction(this);
rotateByMinus1->setShortcut(QKeySequence(Qt::AltModifier + Qt::Key_BracketRight));
connect(rotateByMinus1, &QAction::triggered, this, &VPMainGraphicsView::RotatePiecesByMinus1);
this->addAction(rotateByMinus1);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -342,17 +313,62 @@ void VPMainGraphicsView::keyPressEvent(QKeyEvent *event)
TranslatePiecesOn(0, 1); TranslatePiecesOn(0, 1);
} }
} }
else if (event->key() == Qt::Key_BracketLeft)
{
if((event->modifiers() & Qt::ControlModifier) != 0U)
{
RotatePiecesByAngle(90);
}
else if((event->modifiers() & Qt::AltModifier) != 0U)
{
RotatePiecesByAngle(1);
}
else
{
RotatePiecesByAngle(15);
}
}
else if (event->key() == Qt::Key_BracketRight)
{
if((event->modifiers() & Qt::ControlModifier) != 0U)
{
RotatePiecesByAngle(-90);
}
else if((event->modifiers() & Qt::AltModifier) != 0U)
{
RotatePiecesByAngle(-1);
}
else
{
RotatePiecesByAngle(-15);
}
}
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPMainGraphicsView::keyReleaseEvent(QKeyEvent *event) void VPMainGraphicsView::keyReleaseEvent(QKeyEvent *event)
{ {
VMainGraphicsView::keyReleaseEvent(event); if (event->key() == Qt::Key_Left ||
if (event->key() != Qt::Key_Left && event->key() != Qt::Key_Right && event->key() != Qt::Key_Up && event->key() == Qt::Key_Right ||
event->key() != Qt::Key_Down) event->key() == Qt::Key_Up ||
event->key() == Qt::Key_Down ||
event->key() == Qt::Key_BracketLeft ||
event->key() == Qt::Key_BracketRight)
{ {
m_allowChangeMerge = false; if (not event->isAutoRepeat())
{
m_allowChangeMerge = false;
}
} }
if (event->key() == Qt::Key_BracketLeft || event->key() == Qt::Key_BracketRight)
{
if (not event->isAutoRepeat())
{
m_rotationControls->SetIgnorePieceTransformation(false);
}
}
VMainGraphicsView::keyReleaseEvent(event);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -428,42 +444,6 @@ void VPMainGraphicsView::RestoreOrigin() const
} }
} }
//---------------------------------------------------------------------------------------------------------------------
void VPMainGraphicsView::RotatePiecesByPlus15() const
{
RotatePiecesByAngle(15);
}
//---------------------------------------------------------------------------------------------------------------------
void VPMainGraphicsView::RotatePiecesByMinus15() const
{
RotatePiecesByAngle(-15);
}
//---------------------------------------------------------------------------------------------------------------------
void VPMainGraphicsView::RotatePiecesByPlus90() const
{
RotatePiecesByAngle(90);
}
//---------------------------------------------------------------------------------------------------------------------
void VPMainGraphicsView::RotatePiecesByMinus90() const
{
RotatePiecesByAngle(-90);
}
//---------------------------------------------------------------------------------------------------------------------
void VPMainGraphicsView::RotatePiecesByPlus1() const
{
RotatePiecesByAngle(1);
}
//---------------------------------------------------------------------------------------------------------------------
void VPMainGraphicsView::RotatePiecesByMinus1() const
{
RotatePiecesByAngle(-1);
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPMainGraphicsView::ConnectPiece(VPGraphicsPiece *piece) void VPMainGraphicsView::ConnectPiece(VPGraphicsPiece *piece)
{ {
@ -477,7 +457,6 @@ void VPMainGraphicsView::ConnectPiece(VPGraphicsPiece *piece)
m_rotationControls, &VPGraphicsPieceControls::on_UpdateControls); m_rotationControls, &VPGraphicsPieceControls::on_UpdateControls);
connect(piece, &VPGraphicsPiece::PieceTransformationChanged, connect(piece, &VPGraphicsPiece::PieceTransformationChanged,
m_rotationControls, &VPGraphicsPieceControls::on_UpdateControls); m_rotationControls, &VPGraphicsPieceControls::on_UpdateControls);
connect(m_rotationControls, &VPGraphicsPieceControls::Rotate, piece, &VPGraphicsPiece::on_Rotate);
connect(piece, &VPGraphicsPiece::HideTransformationHandles, connect(piece, &VPGraphicsPiece::HideTransformationHandles,
m_rotationControls, &VPGraphicsPieceControls::on_HideHandles); m_rotationControls, &VPGraphicsPieceControls::on_HideHandles);
connect(piece, &VPGraphicsPiece::HideTransformationHandles, connect(piece, &VPGraphicsPiece::HideTransformationHandles,
@ -485,8 +464,10 @@ void VPMainGraphicsView::ConnectPiece(VPGraphicsPiece *piece)
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPMainGraphicsView::RotatePiecesByAngle(qreal angle) const void VPMainGraphicsView::RotatePiecesByAngle(qreal angle)
{ {
m_rotationControls->SetIgnorePieceTransformation(true);
VPLayoutPtr layout = m_layout.toStrongRef(); VPLayoutPtr layout = m_layout.toStrongRef();
if (layout.isNull()) if (layout.isNull())
{ {
@ -501,14 +482,34 @@ void VPMainGraphicsView::RotatePiecesByAngle(qreal angle) const
VPTransformationOrigon origin = sheet->TransformationOrigin(); VPTransformationOrigon origin = sheet->TransformationOrigin();
for(auto *graphicsPiece : m_graphicsPieces) auto PreparePieces = [this]()
{ {
if (graphicsPiece->isSelected()) QVector<VPPiecePtr> pieces;
for (auto *item : m_graphicsPieces)
{ {
graphicsPiece->on_Rotate(origin.origin, angle); if (item->isSelected())
m_rotationControls->on_UpdateControls(); {
pieces.append(item->GetPiece());
}
} }
return pieces;
};
QVector<VPPiecePtr> pieces = PreparePieces();
if (pieces.size() == 1)
{
auto *command = new VPUndoPieceRotate(pieces.first(), origin.origin, angle, m_allowChangeMerge);
layout->UndoStack()->push(command);
} }
else if (pieces.size() > 1)
{
auto *command = new VPUndoPiecesRotate(pieces, origin.origin, angle, m_allowChangeMerge);
layout->UndoStack()->push(command);
}
m_allowChangeMerge = true;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------

View File

@ -98,12 +98,6 @@ protected:
private slots: private slots:
void RestoreOrigin() const; void RestoreOrigin() const;
void RotatePiecesByPlus15() const;
void RotatePiecesByMinus15() const;
void RotatePiecesByPlus90() const;
void RotatePiecesByMinus90() const;
void RotatePiecesByPlus1() const;
void RotatePiecesByMinus1() const;
private: private:
Q_DISABLE_COPY(VPMainGraphicsView) Q_DISABLE_COPY(VPMainGraphicsView)
@ -134,7 +128,7 @@ private:
void ConnectPiece(VPGraphicsPiece *piece); void ConnectPiece(VPGraphicsPiece *piece);
void RotatePiecesByAngle(qreal angle) const; void RotatePiecesByAngle(qreal angle);
void TranslatePiecesOn(qreal dx, qreal dy); void TranslatePiecesOn(qreal dx, qreal dy);
}; };

View File

@ -37,7 +37,9 @@ namespace ML
enum class UndoCommand: qint8 enum class UndoCommand: qint8
{ {
MovePiece = 0, MovePiece = 0,
MovePieces = 1 MovePieces = 1,
RotatePiece = 2,
RotatePieces = 3,
}; };
} }

View File

@ -0,0 +1,266 @@
/************************************************************************
**
** @file vpundopiecerotate.cpp
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 18 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 "vpundopiecerotate.h"
#include "../layout/vppiece.h"
#include "../layout/vplayout.h"
//---------------------------------------------------------------------------------------------------------------------
VPUndoPieceRotate::VPUndoPieceRotate(const VPPiecePtr &piece, const QPointF &origin, qreal angle, bool allowMerge,
QUndoCommand *parent)
: VPUndoCommand(parent),
m_piece(piece),
m_origin(origin),
m_angle(angle),
m_allowMerge(allowMerge)
{
SCASSERT(not piece.isNull())
m_oldTransform = piece->GetMatrix();
setText(QObject::tr("rotate piece"));
}
//---------------------------------------------------------------------------------------------------------------------
void VPUndoPieceRotate::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 VPUndoPieceRotate::redo()
{
VPPiecePtr piece = Piece();
if (piece.isNull())
{
return;
}
VPLayoutPtr layout = piece->Layout();
if (layout.isNull())
{
return;
}
layout->SetFocusedSheet(piece->Sheet());
piece->Rotate(m_origin, m_angle);
emit layout->PieceTransformationChanged(piece);
}
//---------------------------------------------------------------------------------------------------------------------
auto VPUndoPieceRotate::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 VPUndoPieceRotate *>(command);
SCASSERT(moveCommand != nullptr)
VPPiecePtr piece = Piece();
if (not moveCommand->AllowMerge() || (moveCommand->Piece().isNull() || piece.isNull()) ||
moveCommand->Piece() != piece || moveCommand->Origin() != m_origin)
{
return false;
}
m_angle += moveCommand->Angle();
return true;
}
//---------------------------------------------------------------------------------------------------------------------
auto VPUndoPieceRotate::id() const -> int
{
return static_cast<int>(ML::UndoCommand::RotatePiece);
}
// rotate pieces
//---------------------------------------------------------------------------------------------------------------------
VPUndoPiecesRotate::VPUndoPiecesRotate(const QVector<VPPiecePtr> &pieces, const QPointF &origin, qreal angle,
bool allowMerge, QUndoCommand *parent)
: VPUndoCommand(parent),
m_origin(origin),
m_angle(angle),
m_allowMerge(allowMerge)
{
setText(QObject::tr("rotate pieces"));
for (const auto& piece : pieces)
{
if (not piece.isNull())
{
m_pieces.append(piece);
m_oldTransforms.insert(piece->GetUniqueID(), piece->GetMatrix());
}
}
}
//---------------------------------------------------------------------------------------------------------------------
void VPUndoPiecesRotate::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 VPUndoPiecesRotate::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->Rotate(m_origin, m_angle);
emit layout->PieceTransformationChanged(p);
}
}
}
//---------------------------------------------------------------------------------------------------------------------
auto VPUndoPiecesRotate::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 VPUndoPiecesRotate *>(command);
SCASSERT(moveCommand != nullptr)
if (not moveCommand->AllowMerge() || moveCommand->PieceIds() != PieceIds() || moveCommand->Origin() != m_origin)
{
return false;
}
m_angle += moveCommand->Angle();
return true;
}
//---------------------------------------------------------------------------------------------------------------------
auto VPUndoPiecesRotate::id() const -> int
{
return static_cast<int>(ML::UndoCommand::RotatePieces);
}
//---------------------------------------------------------------------------------------------------------------------
auto VPUndoPiecesRotate::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;
}
//---------------------------------------------------------------------------------------------------------------------
auto VPUndoPiecesRotate::Layout() const -> VPLayoutPtr
{
for (const auto& piece : m_pieces)
{
VPPiecePtr p = piece.toStrongRef();
if (not p.isNull())
{
return p->Layout();
}
}
return nullptr;
}
//---------------------------------------------------------------------------------------------------------------------
auto VPUndoPiecesRotate::Sheet() const -> VPSheetPtr
{
for (const auto& piece : m_pieces)
{
VPPiecePtr p = piece.toStrongRef();
if (not p.isNull())
{
return p->Sheet();
}
}
return nullptr;
}

View File

@ -0,0 +1,142 @@
/************************************************************************
**
** @file vpundopiecerotate.h
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 18 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 VPUNDOPIECEROTATE_H
#define VPUNDOPIECEROTATE_H
#include "vpundocommand.h"
#include <QTransform>
#include "../layout/layoutdef.h"
class VPUndoPieceRotate : public VPUndoCommand
{
Q_OBJECT
public:
VPUndoPieceRotate(const VPPiecePtr &piece, const QPointF &origin, qreal angle, bool allowMerge,
QUndoCommand *parent = nullptr);
virtual ~VPUndoPieceRotate()=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 Origin() const -> QPointF;
auto Angle() const -> qreal;
auto AllowMerge() const -> bool;
private:
Q_DISABLE_COPY(VPUndoPieceRotate)
VPPieceWeakPtr m_piece;
QTransform m_oldTransform{};
QPointF m_origin;
qreal m_angle;
bool m_allowMerge;
};
//---------------------------------------------------------------------------------------------------------------------
inline auto VPUndoPieceRotate::Piece() const -> VPPiecePtr
{
return m_piece;
}
//---------------------------------------------------------------------------------------------------------------------
inline auto VPUndoPieceRotate::Origin() const -> QPointF
{
return m_origin;
}
//---------------------------------------------------------------------------------------------------------------------
inline auto VPUndoPieceRotate::Angle() const -> qreal
{
return m_angle;
}
//---------------------------------------------------------------------------------------------------------------------
inline auto VPUndoPieceRotate::AllowMerge() const -> bool
{
return m_allowMerge;
}
// Rotate pieces
class VPUndoPiecesRotate : public VPUndoCommand
{
Q_OBJECT
public:
explicit VPUndoPiecesRotate(const QVector<VPPiecePtr> &pieces, const QPointF &origin, qreal angle, bool allowMerge,
QUndoCommand *parent = nullptr);
virtual ~VPUndoPiecesRotate()=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 Origin() const -> QPointF;
auto Angle() const -> qreal;
auto AllowMerge() const -> bool;
private:
Q_DISABLE_COPY(VPUndoPiecesRotate)
QVector<VPPieceWeakPtr> m_pieces{};
QMap<QString, QTransform> m_oldTransforms{};
QPointF m_origin;
qreal m_angle;
bool m_allowMerge;
auto Layout() const -> VPLayoutPtr;
auto Sheet() const -> VPSheetPtr;
};
//---------------------------------------------------------------------------------------------------------------------
inline auto VPUndoPiecesRotate::Origin() const -> QPointF
{
return m_origin;
}
//---------------------------------------------------------------------------------------------------------------------
inline auto VPUndoPiecesRotate::Angle() const -> qreal
{
return m_angle;
}
//---------------------------------------------------------------------------------------------------------------------
inline auto VPUndoPiecesRotate::AllowMerge() const -> bool
{
return m_allowMerge;
}
#endif // VPUNDOPIECEROTATE_H

View File

@ -179,7 +179,7 @@ auto StringToMarkerShape(const QString &string) -> PlaceLabelImg
} // namespace } // namespace
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VPLayoutFileReader::ReadFile(VPLayout *layout, QFile *file) -> bool auto VPLayoutFileReader::ReadFile(const VPLayoutPtr &layout, QFile *file) -> bool
{ {
setDevice(file); setDevice(file);
@ -199,7 +199,7 @@ auto VPLayoutFileReader::ReadFile(VPLayout *layout, QFile *file) -> bool
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPLayoutFileReader::ReadLayout(VPLayout *layout) void VPLayoutFileReader::ReadLayout(const VPLayoutPtr &layout)
{ {
AssertRootTag(ML::TagLayout); AssertRootTag(ML::TagLayout);
@ -232,7 +232,7 @@ void VPLayoutFileReader::ReadLayout(VPLayout *layout)
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPLayoutFileReader::ReadProperties(VPLayout *layout) void VPLayoutFileReader::ReadProperties(const VPLayoutPtr &layout)
{ {
AssertRootTag(ML::TagProperties); AssertRootTag(ML::TagProperties);
@ -288,7 +288,7 @@ void VPLayoutFileReader::ReadProperties(VPLayout *layout)
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPLayoutFileReader::ReadControl(VPLayout *layout) void VPLayoutFileReader::ReadControl(const VPLayoutPtr &layout)
{ {
AssertRootTag(ML::TagControl); AssertRootTag(ML::TagControl);
@ -304,7 +304,7 @@ void VPLayoutFileReader::ReadControl(VPLayout *layout)
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPLayoutFileReader::ReadUnplacedPieces(VPLayout *layout) void VPLayoutFileReader::ReadUnplacedPieces(const VPLayoutPtr &layout)
{ {
AssertRootTag(ML::TagUnplacedPieces); AssertRootTag(ML::TagUnplacedPieces);
@ -312,7 +312,7 @@ void VPLayoutFileReader::ReadUnplacedPieces(VPLayout *layout)
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPLayoutFileReader::ReadTiles(VPLayout *layout) void VPLayoutFileReader::ReadTiles(const VPLayoutPtr &layout)
{ {
AssertRootTag(ML::TagTiles); AssertRootTag(ML::TagTiles);
@ -347,7 +347,7 @@ void VPLayoutFileReader::ReadTiles(VPLayout *layout)
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPLayoutFileReader::ReadSheets(VPLayout *layout) void VPLayoutFileReader::ReadSheets(const VPLayoutPtr &layout)
{ {
AssertRootTag(ML::TagSheets); AssertRootTag(ML::TagSheets);
@ -366,7 +366,7 @@ void VPLayoutFileReader::ReadSheets(VPLayout *layout)
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPLayoutFileReader::ReadSheet(VPLayout *layout) void VPLayoutFileReader::ReadSheet(const VPLayoutPtr &layout)
{ {
AssertRootTag(ML::TagSheet); AssertRootTag(ML::TagSheet);
@ -376,7 +376,7 @@ void VPLayoutFileReader::ReadSheet(VPLayout *layout)
ML::TagPieces // 1 ML::TagPieces // 1
}; };
QScopedPointer<VPSheet> sheet (new VPSheet(layout)); VPSheetPtr sheet(new VPSheet(layout));
while (readNextStartElement()) while (readNextStartElement())
{ {
@ -386,11 +386,7 @@ void VPLayoutFileReader::ReadSheet(VPLayout *layout)
sheet->SetName(readElementText()); sheet->SetName(readElementText());
break; break;
case 1: // pieces case 1: // pieces
#if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0) ReadPieces(layout, sheet);
ReadPieces(layout, sheet.get());
#else
ReadPieces(layout, sheet.data());
#endif
break; break;
default: default:
qCDebug(MLReader, "Ignoring tag %s", qUtf8Printable(name().toString())); qCDebug(MLReader, "Ignoring tag %s", qUtf8Printable(name().toString()));
@ -401,21 +397,21 @@ void VPLayoutFileReader::ReadSheet(VPLayout *layout)
readElementText(); readElementText();
layout->AddSheet(sheet.take()); layout->AddSheet(sheet);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPLayoutFileReader::ReadPieces(VPLayout *layout, VPSheet *sheet) void VPLayoutFileReader::ReadPieces(const VPLayoutPtr &layout, const VPSheetPtr &sheet)
{ {
while (readNextStartElement()) while (readNextStartElement())
{ {
if (name() == ML::TagPiece) if (name() == ML::TagPiece)
{ {
QScopedPointer<VPPiece>piece(new VPPiece()); VPPiecePtr piece(new VPPiece());
ReadPiece(piece.data()); ReadPiece(piece);
piece->SetSheet(sheet); piece->SetSheet(sheet);
layout->AddPiece(piece.take()); VPLayout::AddPiece(layout, piece);
} }
else else
{ {
@ -426,7 +422,7 @@ void VPLayoutFileReader::ReadPieces(VPLayout *layout, VPSheet *sheet)
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPLayoutFileReader::ReadPiece(VPPiece *piece) void VPLayoutFileReader::ReadPiece(const VPPiecePtr &piece)
{ {
AssertRootTag(ML::TagPiece); AssertRootTag(ML::TagPiece);
@ -490,7 +486,7 @@ void VPLayoutFileReader::ReadPiece(VPPiece *piece)
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPLayoutFileReader::ReadSeamAllowance(VPPiece *piece) void VPLayoutFileReader::ReadSeamAllowance(const VPPiecePtr &piece)
{ {
AssertRootTag(ML::TagSeamAllowance); AssertRootTag(ML::TagSeamAllowance);
@ -512,7 +508,7 @@ void VPLayoutFileReader::ReadSeamAllowance(VPPiece *piece)
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPLayoutFileReader::ReadGrainline(VPPiece *piece) void VPLayoutFileReader::ReadGrainline(const VPPiecePtr &piece)
{ {
AssertRootTag(ML::TagGrainline); AssertRootTag(ML::TagGrainline);
@ -533,7 +529,7 @@ void VPLayoutFileReader::ReadGrainline(VPPiece *piece)
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPLayoutFileReader::ReadNotches(VPPiece *piece) void VPLayoutFileReader::ReadNotches(const VPPiecePtr &piece)
{ {
AssertRootTag(ML::TagNotches); AssertRootTag(ML::TagNotches);
@ -576,7 +572,7 @@ auto VPLayoutFileReader::ReadNotch() -> VLayoutPassmark
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPLayoutFileReader::ReadInternalPaths(VPPiece *piece) void VPLayoutFileReader::ReadInternalPaths(const VPPiecePtr &piece)
{ {
AssertRootTag(ML::TagInternalPaths); AssertRootTag(ML::TagInternalPaths);
@ -615,7 +611,7 @@ auto VPLayoutFileReader::ReadInternalPath() -> VLayoutPiecePath
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPLayoutFileReader::ReadMarkers(VPPiece *piece) void VPLayoutFileReader::ReadMarkers(const VPPiecePtr &piece)
{ {
AssertRootTag(ML::TagMarkers); AssertRootTag(ML::TagMarkers);
@ -658,7 +654,7 @@ auto VPLayoutFileReader::ReadMarker() -> VLayoutPlaceLabel
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPLayoutFileReader::ReadLabels(VPPiece *piece) void VPLayoutFileReader::ReadLabels(const VPPiecePtr &piece)
{ {
AssertRootTag(ML::TagLabels); AssertRootTag(ML::TagLabels);

View File

@ -1630,6 +1630,12 @@ void VAbstractPiece::SetUUID(const QString &uuid)
d->m_uuid = temp.isNull() ? QUuid::createUuid() : temp; d->m_uuid = temp.isNull() ? QUuid::createUuid() : temp;
} }
//---------------------------------------------------------------------------------------------------------------------
QString VAbstractPiece::GetUniqueID() const
{
return d->m_uuid.toString();
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
qreal VSAPoint::GetSABefore(qreal width) const qreal VSAPoint::GetSABefore(qreal width) const
{ {

View File

@ -96,6 +96,12 @@ public:
void SetUUID(const QUuid &uuid); void SetUUID(const QUuid &uuid);
void SetUUID(const QString &uuid); void SetUUID(const QString &uuid);
/**
* @brief GetUniqueID returns unique piece id. Combines UUID and gradation label.
* @return unique piece id.
*/
QString GetUniqueID() const;
static QVector<QPointF> Equidistant(QVector<VSAPoint> points, qreal width, const QString &name); static QVector<QPointF> Equidistant(QVector<VSAPoint> points, qreal width, const QString &name);
static qreal SumTrapezoids(const QVector<QPointF> &points); static qreal SumTrapezoids(const QVector<QPointF> &points);
static QVector<QPointF> CheckLoops(const QVector<QPointF> &points); static QVector<QPointF> CheckLoops(const QVector<QPointF> &points);