New feature Background image. Closes #43
|
@ -27,6 +27,7 @@
|
|||
- Backport fix vulnerability CVE-2021-21900.
|
||||
- Improved main path validations.
|
||||
- New path validation Invalid segment.
|
||||
- [smart-pattern/valentina#43] Background image.
|
||||
|
||||
# Valentina 0.7.49 July 1, 2021
|
||||
- Fix crash.
|
||||
|
|
|
@ -657,7 +657,7 @@ void VPMainGraphicsView::SwitchScene(const VPSheetPtr &sheet)
|
|||
{
|
||||
VMainGraphicsScene *scene = sheet->SceneData()->Scene();
|
||||
setScene(scene);
|
||||
connect(scene, &VMainGraphicsScene::ItemClicked, this, &VPMainGraphicsView::on_ItemClicked,
|
||||
connect(scene, &VMainGraphicsScene::ItemByMousePress, this, &VPMainGraphicsView::on_ItemClicked,
|
||||
Qt::UniqueConnection);
|
||||
connect(scene, &VMainGraphicsScene::mouseMove, this, &VPMainGraphicsView::on_SceneMouseMove,
|
||||
Qt::UniqueConnection);
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
|
||||
#include "vtooloptionspropertybrowser.h"
|
||||
#include "../vtools/tools/drawTools/drawtools.h"
|
||||
#include "../vtools/tools/backgroundimage/vbackgroundpixmapitem.h"
|
||||
#include "../vtools/tools/backgroundimage/vbackgroundsvgitem.h"
|
||||
#include "../core/vapplication.h"
|
||||
#include "../vwidgets/vmaingraphicsview.h"
|
||||
#include "../vwidgets/vgraphicssimpletextitem.h"
|
||||
|
@ -46,6 +48,12 @@
|
|||
#include <QDebug>
|
||||
#include <QRegularExpression>
|
||||
|
||||
namespace
|
||||
{
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(const QString, AttrHold, (QLatin1String("hold")))
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(const QString, AttrVisible, (QLatin1String("visible")))
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VToolOptionsPropertyBrowser::VToolOptionsPropertyBrowser(QDockWidget *parent)
|
||||
:QObject(parent), PropertyModel(nullptr), formView(nullptr), currentItem(nullptr),
|
||||
|
@ -79,7 +87,7 @@ void VToolOptionsPropertyBrowser::ClearPropertyBrowser()
|
|||
void VToolOptionsPropertyBrowser::ShowItemOptions(QGraphicsItem *item)
|
||||
{
|
||||
// This check helps to find missed tools in the switch
|
||||
Q_STATIC_ASSERT_X(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 55, "Not all tools were used in switch.");
|
||||
Q_STATIC_ASSERT_X(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 59, "Not all tools were used in switch.");
|
||||
|
||||
switch (item->type())
|
||||
{
|
||||
|
@ -192,6 +200,12 @@ void VToolOptionsPropertyBrowser::ShowItemOptions(QGraphicsItem *item)
|
|||
case VToolEllipticalArc::Type:
|
||||
ShowOptionsToolEllipticalArc(item);
|
||||
break;
|
||||
case VBackgroundPixmapItem::Type:
|
||||
ShowOptionsBackgroundPixmapItem(item);
|
||||
break;
|
||||
case VBackgroundSVGItem::Type:
|
||||
ShowOptionsBackgroundSVGItem(item);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -206,7 +220,7 @@ void VToolOptionsPropertyBrowser::UpdateOptions()
|
|||
}
|
||||
|
||||
// This check helps to find missed tools in the switch
|
||||
Q_STATIC_ASSERT_X(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 55, "Not all tools were used in switch.");
|
||||
Q_STATIC_ASSERT_X(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 59, "Not all tools were used in switch.");
|
||||
|
||||
switch (currentItem->type())
|
||||
{
|
||||
|
@ -316,6 +330,12 @@ void VToolOptionsPropertyBrowser::UpdateOptions()
|
|||
case VToolEllipticalArc::Type:
|
||||
UpdateOptionsToolEllipticalArc();
|
||||
break;
|
||||
case VBackgroundPixmapItem::Type:
|
||||
UpdateOptionsBackgroundPixmapItem();
|
||||
break;
|
||||
case VBackgroundSVGItem::Type:
|
||||
UpdateOptionsBackgroundSVGItem();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -351,7 +371,7 @@ void VToolOptionsPropertyBrowser::userChangedData(VPE::VProperty *property)
|
|||
}
|
||||
|
||||
// This check helps to find missed tools in the switch
|
||||
Q_STATIC_ASSERT_X(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 55, "Not all tools were used in switch.");
|
||||
Q_STATIC_ASSERT_X(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 59, "Not all tools were used in switch.");
|
||||
|
||||
switch (currentItem->type())
|
||||
{
|
||||
|
@ -457,6 +477,12 @@ void VToolOptionsPropertyBrowser::userChangedData(VPE::VProperty *property)
|
|||
case VToolEllipticalArc::Type:
|
||||
ChangeDataToolEllipticalArc(prop);
|
||||
break;
|
||||
case VBackgroundPixmapItem::Type:
|
||||
ChangeDataBackgroundPixmapItem(prop);
|
||||
break;
|
||||
case VBackgroundSVGItem::Type:
|
||||
ChangeDataBackgroundSVGItem(prop);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -613,6 +639,14 @@ void VToolOptionsPropertyBrowser::AddPropertyText(const QString &propertyName, c
|
|||
AddProperty(itemText, attrName);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VToolOptionsPropertyBrowser::AddPropertyBool(const QString &propertyName, bool value, const QString &attrName)
|
||||
{
|
||||
auto *itemBool = new VPE::VBoolProperty(propertyName);
|
||||
itemBool->setValue(value);
|
||||
AddProperty(itemBool, attrName);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
template<class Tool>
|
||||
void VToolOptionsPropertyBrowser::AddPropertyCrossPoint(Tool *i, const QString &propertyName)
|
||||
|
@ -719,6 +753,66 @@ void VToolOptionsPropertyBrowser::AddPropertyApproximationScale(const QString &p
|
|||
AddProperty(aScaleProperty, AttrAScale);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
template<class Tool>
|
||||
void VToolOptionsPropertyBrowser::SetName(VPE::VProperty *property)
|
||||
{
|
||||
if (auto *i = qgraphicsitem_cast<Tool *>(currentItem))
|
||||
{
|
||||
QString name = property->data(VPE::VProperty::DPC_Data, Qt::DisplayRole).toString();
|
||||
if (name == i->name())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
i->setName(name);
|
||||
}
|
||||
else
|
||||
{
|
||||
qWarning()<<"Can't cast item";
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
template<class Tool>
|
||||
void VToolOptionsPropertyBrowser::SetHold(VPE::VProperty *property)
|
||||
{
|
||||
if (auto *i = qgraphicsitem_cast<Tool *>(currentItem))
|
||||
{
|
||||
bool hold = property->data(VPE::VProperty::DPC_Data, Qt::DisplayRole).toBool();
|
||||
if (hold == i->IsHold())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
i->SetHold(hold);
|
||||
}
|
||||
else
|
||||
{
|
||||
qWarning()<<"Can't cast item";
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
template<class Tool>
|
||||
void VToolOptionsPropertyBrowser::SetVisible(VPE::VProperty *property)
|
||||
{
|
||||
if (auto *i = qgraphicsitem_cast<Tool *>(currentItem))
|
||||
{
|
||||
bool visible = property->data(VPE::VProperty::DPC_Data, Qt::DisplayRole).toBool();
|
||||
if (visible == i->IsVisible())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
i->SetVisible(visible);
|
||||
}
|
||||
else
|
||||
{
|
||||
qWarning()<<"Can't cast item";
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
template<class Tool>
|
||||
void VToolOptionsPropertyBrowser::SetPointName(VPE::VProperty *property)
|
||||
|
@ -2513,6 +2607,54 @@ void VToolOptionsPropertyBrowser::ChangeDataToolEllipticalArc(VPE::VProperty *pr
|
|||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VToolOptionsPropertyBrowser::ChangeDataBackgroundPixmapItem(VPE::VProperty *property)
|
||||
{
|
||||
SCASSERT(property != nullptr)
|
||||
|
||||
const QString id = propertyToId[property];
|
||||
|
||||
switch (PropertiesList().indexOf(id))
|
||||
{
|
||||
case 0: // AttrName
|
||||
SetName<VBackgroundPixmapItem>(property);
|
||||
break;
|
||||
case 65: // AttrHold
|
||||
SetHold<VBackgroundPixmapItem>(property);
|
||||
break;
|
||||
case 66: // AttrVisible
|
||||
SetVisible<VBackgroundPixmapItem>(property);
|
||||
break;
|
||||
default:
|
||||
qWarning()<<"Unknown property type. id = "<<id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VToolOptionsPropertyBrowser::ChangeDataBackgroundSVGItem(VPE::VProperty *property)
|
||||
{
|
||||
SCASSERT(property != nullptr)
|
||||
|
||||
const QString id = propertyToId[property];
|
||||
|
||||
switch (PropertiesList().indexOf(id))
|
||||
{
|
||||
case 0: // AttrName
|
||||
SetName<VBackgroundSVGItem>(property);
|
||||
break;
|
||||
case 65: // AttrHold
|
||||
SetHold<VBackgroundSVGItem>(property);
|
||||
break;
|
||||
case 66: // AttrVisible
|
||||
SetVisible<VBackgroundSVGItem>(property);
|
||||
break;
|
||||
default:
|
||||
qWarning()<<"Unknown property type. id = "<<id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VToolOptionsPropertyBrowser::ShowOptionsToolSinglePoint(QGraphicsItem *item)
|
||||
{
|
||||
|
@ -3084,6 +3226,28 @@ void VToolOptionsPropertyBrowser::ShowOptionsToolEllipticalArc(QGraphicsItem *it
|
|||
AddPropertyText(tr("Notes:"), i->GetNotes(), AttrNotes);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VToolOptionsPropertyBrowser::ShowOptionsBackgroundPixmapItem(QGraphicsItem *item)
|
||||
{
|
||||
auto *i = qgraphicsitem_cast<VBackgroundPixmapItem *>(item);
|
||||
formView->setTitle(tr("Background image"));
|
||||
|
||||
AddPropertyObjectName(i, tr("Name:"), false);
|
||||
AddPropertyBool(tr("Hold:"), i->IsHold(), *AttrHold);
|
||||
AddPropertyBool(tr("Visible:"), i->IsVisible(), *AttrVisible);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VToolOptionsPropertyBrowser::ShowOptionsBackgroundSVGItem(QGraphicsItem *item)
|
||||
{
|
||||
auto *i = qgraphicsitem_cast<VBackgroundSVGItem *>(item);
|
||||
formView->setTitle(tr("Background image"));
|
||||
|
||||
AddPropertyObjectName(i, tr("Name:"), false);
|
||||
AddPropertyBool(tr("Hold:"), i->IsHold(), *AttrHold);
|
||||
AddPropertyBool(tr("Visible:"), i->IsVisible(), *AttrVisible);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VToolOptionsPropertyBrowser::UpdateOptionsToolSinglePoint()
|
||||
{
|
||||
|
@ -4028,6 +4192,26 @@ void VToolOptionsPropertyBrowser::UpdateOptionsToolEllipticalArc()
|
|||
idToProperty[AttrAlias]->setValue(i->GetAliasSuffix());
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VToolOptionsPropertyBrowser::UpdateOptionsBackgroundPixmapItem()
|
||||
{
|
||||
auto *i = qgraphicsitem_cast<VBackgroundPixmapItem *>(currentItem);
|
||||
|
||||
idToProperty.value(AttrName)->setValue(i->name());
|
||||
idToProperty.value(*AttrHold)->setValue(i->IsHold());
|
||||
idToProperty.value(*AttrVisible)->setValue(i->IsVisible());
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VToolOptionsPropertyBrowser::UpdateOptionsBackgroundSVGItem()
|
||||
{
|
||||
auto *i = qgraphicsitem_cast<VBackgroundSVGItem *>(currentItem);
|
||||
|
||||
idToProperty.value(AttrName)->setValue(i->name());
|
||||
idToProperty.value(*AttrHold)->setValue(i->IsHold());
|
||||
idToProperty.value(*AttrVisible)->setValue(i->IsVisible());
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
QStringList VToolOptionsPropertyBrowser::PropertiesList() const
|
||||
{
|
||||
|
@ -4096,7 +4280,9 @@ QStringList VToolOptionsPropertyBrowser::PropertiesList() const
|
|||
AttrNotes, /* 61 */
|
||||
AttrAlias, /* 62 */
|
||||
AttrAlias1, /* 63 */
|
||||
AttrAlias2 /* 64 */
|
||||
AttrAlias2, /* 64 */
|
||||
*AttrHold, /* 65 */
|
||||
*AttrVisible /* 66 */
|
||||
};
|
||||
return attr;
|
||||
}
|
||||
|
|
|
@ -66,6 +66,15 @@ private:
|
|||
void AddProperty(VPE::VProperty *property, const QString &id);
|
||||
void ShowItemOptions(QGraphicsItem *item);
|
||||
|
||||
template<class Tool>
|
||||
void SetName(VPE::VProperty *property);
|
||||
|
||||
template<class Tool>
|
||||
void SetHold(VPE::VProperty *property);
|
||||
|
||||
template<class Tool>
|
||||
void SetVisible(VPE::VProperty *property);
|
||||
|
||||
template<class Tool>
|
||||
void SetPointName(VPE::VProperty *property);
|
||||
|
||||
|
@ -183,6 +192,7 @@ private:
|
|||
void AddPropertyParentPointName(const QString &pointName, const QString &propertyName,
|
||||
const QString &propertyAttribure);
|
||||
void AddPropertyText(const QString &propertyName, const QString &text, const QString &attrName);
|
||||
void AddPropertyBool(const QString &propertyName, bool value, const QString &attrName);
|
||||
|
||||
QStringList PropertiesList() const;
|
||||
|
||||
|
@ -220,6 +230,8 @@ private:
|
|||
void ChangeDataToolFlippingByLine(VPE::VProperty *property);
|
||||
void ChangeDataToolFlippingByAxis(VPE::VProperty *property);
|
||||
void ChangeDataToolEllipticalArc(VPE::VProperty *property);
|
||||
void ChangeDataBackgroundPixmapItem(VPE::VProperty *property);
|
||||
void ChangeDataBackgroundSVGItem(VPE::VProperty *property);
|
||||
|
||||
void ShowOptionsToolSinglePoint(QGraphicsItem *item);
|
||||
void ShowOptionsToolEndLine(QGraphicsItem *item);
|
||||
|
@ -255,6 +267,8 @@ private:
|
|||
void ShowOptionsToolFlippingByLine(QGraphicsItem *item);
|
||||
void ShowOptionsToolFlippingByAxis(QGraphicsItem *item);
|
||||
void ShowOptionsToolEllipticalArc(QGraphicsItem *item);
|
||||
void ShowOptionsBackgroundPixmapItem(QGraphicsItem *item);
|
||||
void ShowOptionsBackgroundSVGItem(QGraphicsItem *item);
|
||||
|
||||
void UpdateOptionsToolSinglePoint();
|
||||
void UpdateOptionsToolEndLine();
|
||||
|
@ -290,6 +304,8 @@ private:
|
|||
void UpdateOptionsToolFlippingByLine();
|
||||
void UpdateOptionsToolFlippingByAxis();
|
||||
void UpdateOptionsToolEllipticalArc();
|
||||
void UpdateOptionsBackgroundPixmapItem();
|
||||
void UpdateOptionsBackgroundSVGItem();
|
||||
};
|
||||
|
||||
#endif // VTOOLOPTIONSPROPERTYBROWSER_H
|
||||
|
|
55
src/app/valentina/dialogs/dialogaddbackgroundimage.cpp
Normal file
|
@ -0,0 +1,55 @@
|
|||
/************************************************************************
|
||||
**
|
||||
** @file dialogaddbackgroundimage.cpp
|
||||
** @author Roman Telezhynskyi <dismine(at)gmail.com>
|
||||
** @date 21 1, 2022
|
||||
**
|
||||
** @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) 2022 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 "dialogaddbackgroundimage.h"
|
||||
#include "ui_dialogaddbackgroundimage.h"
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
DialogAddBackgroundImage::DialogAddBackgroundImage(QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::DialogAddBackgroundImage)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
DialogAddBackgroundImage::~DialogAddBackgroundImage()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto DialogAddBackgroundImage::Name() const -> QString
|
||||
{
|
||||
return ui->lineEditName->text();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto DialogAddBackgroundImage::BuiltIn() const -> bool
|
||||
{
|
||||
return ui->checkBoxBuiltIn->isChecked();
|
||||
}
|
58
src/app/valentina/dialogs/dialogaddbackgroundimage.h
Normal file
|
@ -0,0 +1,58 @@
|
|||
/************************************************************************
|
||||
**
|
||||
** @file dialogaddbackgroundimage.h
|
||||
** @author Roman Telezhynskyi <dismine(at)gmail.com>
|
||||
** @date 21 1, 2022
|
||||
**
|
||||
** @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) 2022 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 DIALOGADDBACKGROUNDIMAGE_H
|
||||
#define DIALOGADDBACKGROUNDIMAGE_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 13, 0)
|
||||
#include "../vmisc/defglobal.h"
|
||||
#endif // QT_VERSION < QT_VERSION_CHECK(5, 13, 0)
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class DialogAddBackgroundImage;
|
||||
}
|
||||
|
||||
class DialogAddBackgroundImage : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit DialogAddBackgroundImage(QWidget *parent = nullptr);
|
||||
~DialogAddBackgroundImage() override;
|
||||
|
||||
auto Name() const -> QString;
|
||||
auto BuiltIn() const -> bool;
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY_MOVE(DialogAddBackgroundImage)
|
||||
Ui::DialogAddBackgroundImage *ui;
|
||||
};
|
||||
|
||||
#endif // DIALOGADDBACKGROUNDIMAGE_H
|
94
src/app/valentina/dialogs/dialogaddbackgroundimage.ui
Normal file
|
@ -0,0 +1,94 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>DialogAddBackgroundImage</class>
|
||||
<widget class="QDialog" name="DialogAddBackgroundImage">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>204</width>
|
||||
<height>105</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Background image</string>
|
||||
</property>
|
||||
<property name="windowIcon">
|
||||
<iconset resource="../../../libs/vmisc/share/resources/icon.qrc">
|
||||
<normaloff>:/icon/64x64/icon64x64.png</normaloff>:/icon/64x64/icon64x64.png</iconset>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Name:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineEditName"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxBuiltIn">
|
||||
<property name="toolTip">
|
||||
<string>Determine should an image built in or added as path to the file.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Built in</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../../../libs/vmisc/share/resources/icon.qrc"/>
|
||||
</resources>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>DialogAddBackgroundImage</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>DialogAddBackgroundImage</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
|
@ -233,7 +233,7 @@ QT_WARNING_DISABLE_GCC("-Wswitch-default")
|
|||
HistoryRecord DialogHistory::Record(const VToolRecord &tool) const
|
||||
{
|
||||
// This check helps to find missed tools in the switch
|
||||
Q_STATIC_ASSERT_X(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 55, "Not all tools were used in history.");
|
||||
Q_STATIC_ASSERT_X(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 59, "Not all tools were used in history.");
|
||||
|
||||
HistoryRecord record;
|
||||
record.id = tool.getId();
|
||||
|
@ -257,6 +257,10 @@ HistoryRecord DialogHistory::Record(const VToolRecord &tool) const
|
|||
case Tool::Cut:
|
||||
case Tool::Midpoint:// Same as Tool::AlongLine, but tool will never has such type
|
||||
case Tool::ArcIntersectAxis:// Same as Tool::CurveIntersectAxis, but tool will never has such type
|
||||
case Tool::BackgroundImage:
|
||||
case Tool::BackgroundImageControls:
|
||||
case Tool::BackgroundPixmapImage:
|
||||
case Tool::BackgroundSVGImage:
|
||||
case Tool::LAST_ONE_DO_NOT_USE:
|
||||
Q_UNREACHABLE(); //-V501
|
||||
break;
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
#include "../vmisc/vvalentinasettings.h"
|
||||
#include "../qmuparser/qmudef.h"
|
||||
#include "../ifc/xml/vpatternimage.h"
|
||||
#include "../ifc/xml/utils.h"
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
DialogPatternProperties::DialogPatternProperties(VPattern *doc, VContainer *pattern, QWidget *parent)
|
||||
|
@ -327,33 +328,9 @@ void DialogPatternProperties::InitImage()
|
|||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void DialogPatternProperties::ChangeImage()
|
||||
{
|
||||
auto PrepareFilter = []()
|
||||
{
|
||||
const QList<QByteArray> supportedFormats = QImageReader::supportedImageFormats();
|
||||
const QSet<QString> filterFormats{"bmp", "jpeg", "jpg", "png", "svg", "svgz", "tif", "tiff", "webp"};
|
||||
QStringList sufixes;
|
||||
for (const auto& format : supportedFormats)
|
||||
{
|
||||
if (filterFormats.contains(format))
|
||||
{
|
||||
sufixes.append(QStringLiteral("*.%1").arg(QString(format)));
|
||||
}
|
||||
}
|
||||
|
||||
QStringList filters;
|
||||
|
||||
if (not sufixes.isEmpty())
|
||||
{
|
||||
filters.append(tr("Images") + QStringLiteral(" (%1)").arg(sufixes.join(' ')));
|
||||
}
|
||||
|
||||
filters.append(tr("All files") + QStringLiteral(" (*.*)"));
|
||||
|
||||
return filters.join(QStringLiteral(";;"));
|
||||
};
|
||||
|
||||
const QString fileName = QFileDialog::getOpenFileName(this, tr("Image for pattern"), QString(), PrepareFilter(),
|
||||
nullptr, VAbstractApplication::VApp()->NativeFileDialog());
|
||||
const QString fileName = QFileDialog::getOpenFileName(this, tr("Image for pattern"), QString(),
|
||||
PrepareImageFilters(), nullptr,
|
||||
VAbstractApplication::VApp()->NativeFileDialog());
|
||||
if (not fileName.isEmpty())
|
||||
{
|
||||
VPatternImage image = VPatternImage::FromFile(fileName);
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
# This need for corect working file translations.pro
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/dialogaddbackgroundimage.h \
|
||||
$$PWD/dialogs.h \
|
||||
$$PWD/dialogincrements.h \
|
||||
$$PWD/dialoghistory.h \
|
||||
|
@ -11,6 +12,7 @@ HEADERS += \
|
|||
$$PWD/dialoglayoutsettings.h \
|
||||
$$PWD/dialoglayoutprogress.h \
|
||||
$$PWD/dialogsavelayout.h \
|
||||
$$PWD/vwidgetbackgroundimages.h \
|
||||
$$PWD/vwidgetgroups.h \
|
||||
$$PWD/vwidgetdetails.h \
|
||||
$$PWD/dialogpreferences.h \
|
||||
|
@ -22,6 +24,7 @@ HEADERS += \
|
|||
$$PWD/dialogfinalmeasurements.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/dialogaddbackgroundimage.cpp \
|
||||
$$PWD/dialogincrements.cpp \
|
||||
$$PWD/dialoghistory.cpp \
|
||||
$$PWD/dialogpatternproperties.cpp \
|
||||
|
@ -30,6 +33,7 @@ SOURCES += \
|
|||
$$PWD/dialoglayoutsettings.cpp \
|
||||
$$PWD/dialoglayoutprogress.cpp \
|
||||
$$PWD/dialogsavelayout.cpp \
|
||||
$$PWD/vwidgetbackgroundimages.cpp \
|
||||
$$PWD/vwidgetgroups.cpp \
|
||||
$$PWD/vwidgetdetails.cpp \
|
||||
$$PWD/dialogpreferences.cpp \
|
||||
|
@ -41,6 +45,7 @@ SOURCES += \
|
|||
$$PWD/dialogfinalmeasurements.cpp
|
||||
|
||||
FORMS += \
|
||||
$$PWD/dialogaddbackgroundimage.ui \
|
||||
$$PWD/dialogincrements.ui \
|
||||
$$PWD/dialoghistory.ui \
|
||||
$$PWD/dialogpatternproperties.ui \
|
||||
|
@ -49,6 +54,7 @@ FORMS += \
|
|||
$$PWD/dialoglayoutsettings.ui \
|
||||
$$PWD/dialoglayoutprogress.ui \
|
||||
$$PWD/dialogsavelayout.ui \
|
||||
$$PWD/vwidgetbackgroundimages.ui \
|
||||
$$PWD/vwidgetgroups.ui \
|
||||
$$PWD/vwidgetdetails.ui \
|
||||
$$PWD/dialogpreferences.ui \
|
||||
|
|
1013
src/app/valentina/dialogs/vwidgetbackgroundimages.cpp
Normal file
112
src/app/valentina/dialogs/vwidgetbackgroundimages.h
Normal file
|
@ -0,0 +1,112 @@
|
|||
/************************************************************************
|
||||
**
|
||||
** @file vwidgetbackgroundimages.h
|
||||
** @author Roman Telezhynskyi <dismine(at)gmail.com>
|
||||
** @date 26 1, 2022
|
||||
**
|
||||
** @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) 2022 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 VWIDGETBACKGROUNDIMAGES_H
|
||||
#define VWIDGETBACKGROUNDIMAGES_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 13, 0)
|
||||
#include "../vmisc/defglobal.h"
|
||||
#endif // QT_VERSION < QT_VERSION_CHECK(5, 13, 0)
|
||||
|
||||
#include "../vmisc/def.h"
|
||||
|
||||
class VAbstractPattern;
|
||||
class VBackgroundPatternImage;
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class VWidgetBackgroundImages;
|
||||
}
|
||||
|
||||
enum class ScaleUnit {Percent, Mm, Cm, Inch, Px};
|
||||
|
||||
class VWidgetBackgroundImages : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit VWidgetBackgroundImages(VAbstractPattern *doc, QWidget *parent = nullptr);
|
||||
~VWidgetBackgroundImages() override;
|
||||
|
||||
signals:
|
||||
void DeleteImage(const QUuid &id);
|
||||
void SelectImage(const QUuid &id);
|
||||
|
||||
public slots:
|
||||
void UpdateImages();
|
||||
void UpdateImage(const QUuid &id);
|
||||
void ImageSelected(const QUuid &id);
|
||||
|
||||
private slots:
|
||||
void ImageHoldChanged(int row, int column);
|
||||
void ImageVisibilityChanged(int row, int column);
|
||||
void ImageNameChanged(int row, int column);
|
||||
void ContextMenu(const QPoint &pos);
|
||||
void CurrentImageChanged(int currentRow, int currentColumn, int previousRow, int previousColumn);
|
||||
void MoveImageOnTop();
|
||||
void MoveImageUp();
|
||||
void MoveImageDown();
|
||||
void MoveImageBottom();
|
||||
void ApplyImageTransformation();
|
||||
void ResetImageTransformationSettings();
|
||||
void RelativeTranslationChanged(bool checked);
|
||||
void ScaleProportionallyChanged(bool checked);
|
||||
void ScaleWidthChanged(double value);
|
||||
void ScaleHeightChanged(double value);
|
||||
void ImagePositionChanged(const QUuid &id);
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY_MOVE(VWidgetBackgroundImages)
|
||||
Ui::VWidgetBackgroundImages *ui;
|
||||
VAbstractPattern *m_doc;
|
||||
|
||||
Unit m_oldImageTranslationUnit{Unit::Mm};
|
||||
ScaleUnit m_oldImageScaleUnit{ScaleUnit::Percent};
|
||||
|
||||
void FillTable(const QVector<VBackgroundPatternImage> &images);
|
||||
|
||||
void ToggleImageHold(const QUuid &id) const;
|
||||
void ToggleImageVisibility(const QUuid &id) const;
|
||||
|
||||
Q_REQUIRED_RESULT auto ImageRow(const QUuid &id) const -> int;
|
||||
|
||||
Q_REQUIRED_RESULT auto CurrentTranslateUnit() const -> Unit;
|
||||
Q_REQUIRED_RESULT auto CurrentScaleUnit() const -> ScaleUnit;
|
||||
void InitImageTranslation();
|
||||
|
||||
Q_REQUIRED_RESULT auto ImageWidth() const -> qreal;
|
||||
Q_REQUIRED_RESULT auto ImageHeight() const -> qreal;
|
||||
|
||||
Q_REQUIRED_RESULT auto WidthScaleUnitConvertor(qreal value, enum ScaleUnit from, enum ScaleUnit to) const -> qreal;
|
||||
Q_REQUIRED_RESULT auto HeightScaleUnitConvertor(qreal value, enum ScaleUnit from, enum ScaleUnit to) const -> qreal;
|
||||
|
||||
void SetAbsolutePisition(const QUuid &id);
|
||||
};
|
||||
|
||||
#endif // VWIDGETBACKGROUNDIMAGES_H
|
418
src/app/valentina/dialogs/vwidgetbackgroundimages.ui
Normal file
|
@ -0,0 +1,418 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>VWidgetBackgroundImages</class>
|
||||
<widget class="QWidget" name="VWidgetBackgroundImages">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>401</width>
|
||||
<height>640</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QScrollArea" name="scrollArea">
|
||||
<property name="widgetResizable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QWidget" name="scrollAreaWidgetContents">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>381</width>
|
||||
<height>620</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBoxPieceTransformation">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Transformation</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_25">
|
||||
<item>
|
||||
<widget class="QTabWidget" name="tabWidgetImageTransformation">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tabTranslate">
|
||||
<attribute name="title">
|
||||
<string comment="Translate piece">Translate</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="labelCurrentPieceTranslateX">
|
||||
<property name="text">
|
||||
<string>Horizontal:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBoxImageHorizontalTranslate">
|
||||
<property name="minimum">
|
||||
<double>-10000.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>10000.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.100000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QComboBox" name="comboBoxTranslateUnit"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="labelCurrentPieceTranslateY">
|
||||
<property name="text">
|
||||
<string>Vertical:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBoxImageVerticalTranslate">
|
||||
<property name="minimum">
|
||||
<double>-10000.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>10000.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.100000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxRelativeTranslation">
|
||||
<property name="text">
|
||||
<string>Relative translation</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tabScale">
|
||||
<attribute name="title">
|
||||
<string>Scale</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="labelImageScaleWidth">
|
||||
<property name="text">
|
||||
<string>Width:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBoxScaleWidth">
|
||||
<property name="minimum">
|
||||
<double>-10000.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>10000.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.100000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QComboBox" name="comboBoxScaleUnit"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="labelImageScaleHeight">
|
||||
<property name="text">
|
||||
<string>Height:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBoxScaleHeight">
|
||||
<property name="minimum">
|
||||
<double>-10000.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>10000.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.100000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxScaleProportionally">
|
||||
<property name="text">
|
||||
<string>Scale proportionally</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tabRotate">
|
||||
<attribute name="title">
|
||||
<string>Rotate</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_24">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBoxCurrentPieceRotation">
|
||||
<property name="title">
|
||||
<string>Rotation</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="3">
|
||||
<widget class="QToolButton" name="toolButtonImageRotationClockwise">
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="object-rotate-right">
|
||||
<normaloff>../../puzzle</normaloff>../../puzzle</iconset>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">buttonGroup</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBoxRotationAngle">
|
||||
<property name="suffix">
|
||||
<string notr="true">°</string>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>-360.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>360.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.100000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="4">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QToolButton" name="toolButtonImageRotationAnticlockwise">
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="object-rotate-left">
|
||||
<normaloff>../../puzzle</normaloff>../../puzzle</iconset>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">buttonGroup</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="labelCurrentPieceAngle">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Angle:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Apply|QDialogButtonBox::Reset</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Z Value</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QToolButton" name="toolButtonBottom">
|
||||
<property name="text">
|
||||
<string notr="true">...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="go-bottom"/>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="toolButtonDown">
|
||||
<property name="text">
|
||||
<string notr="true">...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="go-down"/>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="toolButtonUp">
|
||||
<property name="text">
|
||||
<string notr="true">...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="go-up"/>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="toolButtonTop">
|
||||
<property name="text">
|
||||
<string notr="true">...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="go-top"/>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTableWidget" name="tableWidget">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>1</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="alternatingRowColors">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::SingleSelection</enum>
|
||||
</property>
|
||||
<property name="selectionBehavior">
|
||||
<enum>QAbstractItemView::SelectRows</enum>
|
||||
</property>
|
||||
<attribute name="horizontalHeaderVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<attribute name="horizontalHeaderMinimumSectionSize">
|
||||
<number>16</number>
|
||||
</attribute>
|
||||
<attribute name="horizontalHeaderStretchLastSection">
|
||||
<bool>true</bool>
|
||||
</attribute>
|
||||
<attribute name="verticalHeaderVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<attribute name="verticalHeaderMinimumSectionSize">
|
||||
<number>10</number>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
<buttongroups>
|
||||
<buttongroup name="buttonGroup"/>
|
||||
</buttongroups>
|
||||
</ui>
|
|
@ -61,6 +61,7 @@
|
|||
#include "dialogs/vwidgetgroups.h"
|
||||
#include "../vtools/undocommands/undogroup.h"
|
||||
#include "dialogs/vwidgetdetails.h"
|
||||
#include "dialogs/dialogaddbackgroundimage.h"
|
||||
#include "../vpatterndb/vpiecepath.h"
|
||||
#include "../qmuparser/qmuparsererror.h"
|
||||
#include "../vtools/dialogs/support/dialogeditlabel.h"
|
||||
|
@ -71,6 +72,15 @@
|
|||
#include "../vwidgets/vgraphicssimpletextitem.h"
|
||||
#include "../vlayout/dialogs/dialoglayoutscale.h"
|
||||
#include "../vmisc/dialogs/dialogselectlanguage.h"
|
||||
#include "../ifc/xml/vbackgroundpatternimage.h"
|
||||
#include "../vtools/tools/backgroundimage/vbackgroundimageitem.h"
|
||||
#include "../vtools/tools/backgroundimage/vbackgroundpixmapitem.h"
|
||||
#include "../vtools/tools/backgroundimage/vbackgroundsvgitem.h"
|
||||
#include "../vtools/tools/backgroundimage/vbackgroundimagecontrols.h"
|
||||
#include "../vtools/undocommands/image/addbackgroundimage.h"
|
||||
#include "../vtools/undocommands/image/deletebackgroundimage.h"
|
||||
#include "../ifc/xml/utils.h"
|
||||
#include "dialogs/vwidgetbackgroundimages.h"
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 12, 0)
|
||||
#include "../vmisc/backport/qscopeguard.h"
|
||||
|
@ -104,6 +114,8 @@
|
|||
#include <QFuture>
|
||||
#include <QtConcurrent>
|
||||
#include <QStyleFactory>
|
||||
#include <QImageReader>
|
||||
#include <QUuid>
|
||||
|
||||
#if defined(Q_OS_WIN32) && QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
|
||||
#include <QWinTaskbarButton>
|
||||
|
@ -250,6 +262,8 @@ MainWindow::MainWindow(QWidget *parent)
|
|||
ToolBarStages();
|
||||
InitToolButtons();
|
||||
|
||||
connect(ui->actionAddBackgroundImage, &QAction::triggered, this, &MainWindow::ActionAddBackgroundImage);
|
||||
|
||||
m_progressBar->setVisible(false);
|
||||
#if defined(Q_OS_WIN32) && QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
|
||||
m_taskbarProgress->setVisible(false);
|
||||
|
@ -495,6 +509,7 @@ void MainWindow::InitScenes()
|
|||
connect(this, &MainWindow::EnableSplinePathHover, sceneDraw, &VMainGraphicsScene::ToggleSplinePathHover);
|
||||
|
||||
connect(sceneDraw, &VMainGraphicsScene::mouseMove, this, &MainWindow::MouseMove);
|
||||
connect(sceneDraw, &VMainGraphicsScene::AddBackgroundImage, this, &MainWindow::PlaceBackgroundImage);
|
||||
|
||||
sceneDetails = new VMainGraphicsScene(this);
|
||||
connect(this, &MainWindow::EnableItemMove, sceneDetails, &VMainGraphicsScene::EnableItemMove);
|
||||
|
@ -662,7 +677,7 @@ void MainWindow::SetToolButton(bool checked, Tool t, const QString &cursor, cons
|
|||
dialogTool = new Dialog(pattern, 0, this);
|
||||
|
||||
// This check helps to find missed tools in the switch
|
||||
Q_STATIC_ASSERT_X(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 55, "Check if need to extend.");
|
||||
Q_STATIC_ASSERT_X(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 59, "Check if need to extend.");
|
||||
|
||||
switch(t)
|
||||
{
|
||||
|
@ -1364,6 +1379,50 @@ void MainWindow::ZoomFitBestCurrent()
|
|||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void MainWindow::PlaceBackgroundImage(const QPointF &pos, const QString &fileName)
|
||||
{
|
||||
DialogAddBackgroundImage dialog(this);
|
||||
if (dialog.exec() == QDialog::Rejected)
|
||||
{
|
||||
qCritical() << tr("Unable to add background image");
|
||||
return;
|
||||
}
|
||||
|
||||
VBackgroundPatternImage image = VBackgroundPatternImage::FromFile(fileName, dialog.BuiltIn());
|
||||
image.SetName(dialog.Name());
|
||||
|
||||
QTransform m;
|
||||
m.translate(pos.x(), pos.y());
|
||||
|
||||
QTransform imageMatrix = image.Matrix();
|
||||
imageMatrix *= m;
|
||||
|
||||
image.SetMatrix(m);
|
||||
|
||||
if (not image.IsValid())
|
||||
{
|
||||
qCritical() << tr("Invalid image. Error: %1").arg(image.ErrorString());
|
||||
return;
|
||||
}
|
||||
|
||||
auto* addBackgroundImage = new AddBackgroundImage(image, doc);
|
||||
connect(addBackgroundImage, &AddBackgroundImage::AddItem, this, &MainWindow::AddBackgroundImageItem);
|
||||
connect(addBackgroundImage, &AddBackgroundImage::DeleteItem, this, &MainWindow::DeleteBackgroundImageItem);
|
||||
VApplication::VApp()->getUndoStack()->push(addBackgroundImage);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void MainWindow::RemoveBackgroundImage(const QUuid &id)
|
||||
{
|
||||
VBackgroundPatternImage image = doc->GetBackgroundImage(id);
|
||||
|
||||
auto* deleteBackgroundImage = new DeleteBackgroundImage(image, doc);
|
||||
connect(deleteBackgroundImage, &DeleteBackgroundImage::AddItem, this, &MainWindow::AddBackgroundImageItem);
|
||||
connect(deleteBackgroundImage, &DeleteBackgroundImage::DeleteItem, this, &MainWindow::DeleteBackgroundImageItem);
|
||||
VApplication::VApp()->getUndoStack()->push(deleteBackgroundImage);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief ToolCutArc handler tool cutArc.
|
||||
|
@ -2302,7 +2361,7 @@ void MainWindow::ExportDraw(const QString &fileName)
|
|||
// Restore scale, scrollbars and current active pattern piece
|
||||
ui->view->setTransform(viewTransform);
|
||||
VMainGraphicsView::NewSceneRect(ui->view->scene(), ui->view);
|
||||
emit ScaleChanged(ui->view->transform().m11());
|
||||
ScaleChanged(ui->view->transform().m11());
|
||||
|
||||
ui->view->verticalScrollBar()->setValue(verticalScrollBarValue);
|
||||
ui->view->horizontalScrollBar()->setValue(horizontalScrollBarValue);
|
||||
|
@ -2310,6 +2369,70 @@ void MainWindow::ExportDraw(const QString &fileName)
|
|||
doc->ChangeActivPP(doc->GetNameActivPP(), Document::FullParse);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void MainWindow::NewBackgroundImageItem(const VBackgroundPatternImage &image)
|
||||
{
|
||||
if (m_backgroudcontrols == nullptr)
|
||||
{
|
||||
m_backgroudcontrols = new VBackgroundImageControls(doc);
|
||||
connect(sceneDraw, &VMainGraphicsScene::ItemByMouseRelease, m_backgroudcontrols,
|
||||
&VBackgroundImageControls::DeactivateControls);
|
||||
sceneDraw->addItem(m_backgroudcontrols);
|
||||
}
|
||||
|
||||
if (m_backgroundImages.contains(image.Id()))
|
||||
{
|
||||
VBackgroundImageItem *item = m_backgroundImages.value(image.Id());
|
||||
if (item != nullptr)
|
||||
{
|
||||
item->SetImage(image);
|
||||
}
|
||||
}
|
||||
else if (m_deletedBackgroundImageItems.contains(image.Id()))
|
||||
{
|
||||
VBackgroundImageItem *item = m_deletedBackgroundImageItems.value(image.Id());
|
||||
if (item != nullptr)
|
||||
{
|
||||
item->SetImage(image);
|
||||
sceneDraw->addItem(item);
|
||||
m_backgroundImages.insert(image.Id(), item);
|
||||
}
|
||||
m_deletedBackgroundImageItems.remove(image.Id());
|
||||
}
|
||||
else
|
||||
{
|
||||
VBackgroundImageItem *item = nullptr;
|
||||
if (image.Type() == PatternImage::Raster)
|
||||
{
|
||||
item = new VBackgroundPixmapItem(image, doc);
|
||||
}
|
||||
else if (image.Type() == PatternImage::Vector || image.Type() == PatternImage::Unknown)
|
||||
{
|
||||
item = new VBackgroundSVGItem(image, doc);
|
||||
}
|
||||
|
||||
if (item != nullptr)
|
||||
{
|
||||
connect(item, &VBackgroundImageItem::UpdateControls, m_backgroudcontrols,
|
||||
&VBackgroundImageControls::UpdateControls);
|
||||
connect(item, &VBackgroundImageItem::ActivateControls, m_backgroudcontrols,
|
||||
&VBackgroundImageControls::ActivateControls);
|
||||
connect(item, &VBackgroundImageItem::DeleteImage, this, &MainWindow::RemoveBackgroundImage);
|
||||
connect(this, &MainWindow::EnableBackgroundImageSelection, item, &VBackgroundImageItem::EnableSelection);
|
||||
connect(item, &VBackgroundImageItem::ShowImageInExplorer, this, &MainWindow::ShowBackgroundImageInExplorer);
|
||||
connect(item, &VBackgroundImageItem::SaveImage, this, &MainWindow::SaveBackgroundImage);
|
||||
connect(m_backgroudcontrols, &VBackgroundImageControls::ActiveImageChanged, backgroundImagesWidget,
|
||||
&VWidgetBackgroundImages::ImageSelected);
|
||||
connect(backgroundImagesWidget, &VWidgetBackgroundImages::SelectImage, m_backgroudcontrols,
|
||||
&VBackgroundImageControls::ActivateControls);
|
||||
sceneDraw->addItem(item);
|
||||
m_backgroundImages.insert(image.Id(), item);
|
||||
}
|
||||
}
|
||||
|
||||
VMainGraphicsView::NewSceneRect(sceneDraw, ui->view);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
#if defined(Q_OS_MAC)
|
||||
void MainWindow::OpenAt(QAction *where)
|
||||
|
@ -2543,7 +2666,7 @@ void MainWindow::InitToolButtons()
|
|||
}
|
||||
|
||||
// This check helps to find missed tools
|
||||
Q_STATIC_ASSERT_X(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 55, "Check if all tools were connected.");
|
||||
Q_STATIC_ASSERT_X(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 59, "Check if all tools were connected.");
|
||||
|
||||
connect(ui->toolButtonEndLine, &QToolButton::clicked, this, &MainWindow::ToolEndLine);
|
||||
connect(ui->toolButtonLine, &QToolButton::clicked, this, &MainWindow::ToolLine);
|
||||
|
@ -2622,7 +2745,7 @@ QT_WARNING_DISABLE_GCC("-Wswitch-default")
|
|||
void MainWindow::CancelTool()
|
||||
{
|
||||
// This check helps to find missed tools in the switch
|
||||
Q_STATIC_ASSERT_X(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 55, "Not all tools were handled.");
|
||||
Q_STATIC_ASSERT_X(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 59, "Not all tools were handled.");
|
||||
|
||||
qCDebug(vMainWindow, "Canceling tool.");
|
||||
if(not dialogTool.isNull())
|
||||
|
@ -2664,6 +2787,10 @@ void MainWindow::CancelTool()
|
|||
case Tool::NodeElArc:
|
||||
case Tool::NodeSpline:
|
||||
case Tool::NodeSplinePath:
|
||||
case Tool::BackgroundImage:
|
||||
case Tool::BackgroundImageControls:
|
||||
case Tool::BackgroundPixmapImage:
|
||||
case Tool::BackgroundSVGImage:
|
||||
Q_UNREACHABLE(); //-V501
|
||||
//Nothing to do here because we can't create this tool from main window.
|
||||
break;
|
||||
|
@ -2837,6 +2964,7 @@ void MainWindow::ArrowTool(bool checked)
|
|||
emit EnableNodeLabelSelection(true);
|
||||
emit EnableNodePointSelection(true);
|
||||
emit EnableDetailSelection(true);// Disable when done visualization details
|
||||
emit EnableBackgroundImageSelection(true);
|
||||
|
||||
// Hovering
|
||||
emit EnableLabelHover(true);
|
||||
|
@ -2849,6 +2977,7 @@ void MainWindow::ArrowTool(bool checked)
|
|||
emit EnableNodeLabelHover(true);
|
||||
emit EnableNodePointHover(true);
|
||||
emit EnableDetailHover(true);
|
||||
emit EnableImageBackgroundHover(true);
|
||||
|
||||
ui->view->AllowRubberBand(true);
|
||||
ui->view->viewport()->unsetCursor();
|
||||
|
@ -2967,12 +3096,14 @@ void MainWindow::ActionDraw(bool checked)
|
|||
}
|
||||
|
||||
ui->dockWidgetLayoutPages->setVisible(false);
|
||||
ui->dockWidgetToolOptions->setVisible(isDockToolOptionsVisible);
|
||||
ui->dockWidgetToolOptions->setVisible(m_toolOptionsActive);
|
||||
|
||||
ui->dockWidgetGroups->setWidget(groupsWidget);
|
||||
ui->dockWidgetGroups->setWindowTitle(tr("Groups of visibility"));
|
||||
ui->dockWidgetGroups->setVisible(isDockGroupsVisible);
|
||||
ui->dockWidgetGroups->setVisible(m_groupsActive);
|
||||
ui->dockWidgetGroups->setToolTip(tr("Contains all visibility groups"));
|
||||
|
||||
ui->dockWidgetBackgroundImages->setVisible(m_backgroundImagesActive);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -3045,10 +3176,11 @@ void MainWindow::ActionDetails(bool checked)
|
|||
|
||||
ui->dockWidgetGroups->setWidget(detailsWidget);
|
||||
ui->dockWidgetGroups->setWindowTitle(tr("Details"));
|
||||
ui->dockWidgetGroups->setVisible(isDockGroupsVisible);
|
||||
ui->dockWidgetGroups->setVisible(m_groupsActive);
|
||||
ui->dockWidgetGroups->setToolTip(tr("Show which details will go in layout"));
|
||||
|
||||
ui->dockWidgetToolOptions->setVisible(isDockToolOptionsVisible);
|
||||
ui->dockWidgetToolOptions->setVisible(m_toolOptionsActive);
|
||||
ui->dockWidgetBackgroundImages->setVisible(false);
|
||||
|
||||
m_statusLabel->setText(QString());
|
||||
|
||||
|
@ -3159,14 +3291,9 @@ void MainWindow::ActionLayout(bool checked)
|
|||
}
|
||||
|
||||
ui->dockWidgetLayoutPages->setVisible(true);
|
||||
|
||||
ui->dockWidgetToolOptions->blockSignals(true);
|
||||
ui->dockWidgetToolOptions->setVisible(false);
|
||||
ui->dockWidgetToolOptions->blockSignals(false);
|
||||
|
||||
ui->dockWidgetGroups->blockSignals(true);
|
||||
ui->dockWidgetGroups->setVisible(false);
|
||||
ui->dockWidgetGroups->blockSignals(false);
|
||||
ui->dockWidgetBackgroundImages->setVisible(false);
|
||||
|
||||
ShowPaper(ui->listWidget->currentRow());
|
||||
|
||||
|
@ -3548,6 +3675,18 @@ void MainWindow::on_actionUpdateManualLayout_triggered()
|
|||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void MainWindow::ActionAddBackgroundImage()
|
||||
{
|
||||
const QString fileName = QFileDialog::getOpenFileName(this, tr("Select background image"), QString(),
|
||||
PrepareImageFilters(), nullptr,
|
||||
VAbstractApplication::VApp()->NativeFileDialog());
|
||||
if (not fileName.isEmpty())
|
||||
{
|
||||
PlaceBackgroundImage(QPointF(), fileName);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Clear reset to default window.
|
||||
|
@ -3570,8 +3709,10 @@ void MainWindow::Clear()
|
|||
UpdateWindowTitle();
|
||||
UpdateVisibilityGroups();
|
||||
detailsWidget->UpdateList();
|
||||
backgroundImagesWidget->UpdateImages();
|
||||
qCDebug(vMainWindow, "Clearing scenes.");
|
||||
sceneDraw->clear();
|
||||
sceneDraw->SetAcceptDrop(false);
|
||||
sceneDetails->clear();
|
||||
ArrowTool(true);
|
||||
comboBoxDraws->clear();
|
||||
|
@ -3603,6 +3744,7 @@ void MainWindow::Clear()
|
|||
ui->actionEditCurrent->setEnabled(false);
|
||||
ui->actionPreviousPatternPiece->setEnabled(false);
|
||||
ui->actionNextPatternPiece->setEnabled(false);
|
||||
ui->actionAddBackgroundImage->setEnabled(false);
|
||||
SetEnableTool(false);
|
||||
VAbstractValApplication::VApp()->SetPatternUnits(Unit::Cm);
|
||||
VAbstractValApplication::VApp()->SetMeasurementsType(MeasurementsType::Unknown);
|
||||
|
@ -3985,6 +4127,7 @@ void MainWindow::SetEnableWidgets(bool enable)
|
|||
ui->actionUnloadMeasurements->setEnabled(enable && designStage);
|
||||
ui->actionPreviousPatternPiece->setEnabled(enable && drawStage);
|
||||
ui->actionNextPatternPiece->setEnabled(enable && drawStage);
|
||||
ui->actionAddBackgroundImage->setEnabled(enable && drawStage);
|
||||
ui->actionIncreaseLabelFont->setEnabled(enable);
|
||||
ui->actionDecreaseLabelFont->setEnabled(enable);
|
||||
ui->actionOriginalLabelFont->setEnabled(enable);
|
||||
|
@ -3998,6 +4141,7 @@ void MainWindow::SetEnableWidgets(bool enable)
|
|||
|
||||
actionDockWidgetToolOptions->setEnabled(enable && designStage);
|
||||
actionDockWidgetGroups->setEnabled(enable && designStage);
|
||||
actionDockWidgetBackgroundImages->setEnabled(enable && drawStage);
|
||||
|
||||
undoAction->setEnabled(enable && designStage && VAbstractApplication::VApp()->getUndoStack()->canUndo());
|
||||
redoAction->setEnabled(enable && designStage && VAbstractApplication::VApp()->getUndoStack()->canRedo());
|
||||
|
@ -4189,6 +4333,98 @@ void MainWindow::SetDefaultGUILanguage()
|
|||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void MainWindow::AddBackgroundImageItem(const QUuid &id)
|
||||
{
|
||||
NewBackgroundImageItem(doc->GetBackgroundImage(id));
|
||||
|
||||
if (backgroundImagesWidget != nullptr)
|
||||
{
|
||||
backgroundImagesWidget->UpdateImages();
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void MainWindow::DeleteBackgroundImageItem(const QUuid &id)
|
||||
{
|
||||
if (m_backgroundImages.contains(id))
|
||||
{
|
||||
VBackgroundImageItem *item = m_backgroundImages.value(id);
|
||||
emit ui->view->itemClicked(nullptr); // Hide visualization to avoid a crash
|
||||
sceneDraw->removeItem(item);
|
||||
if (m_backgroudcontrols != nullptr && m_backgroudcontrols->Id() == id)
|
||||
{
|
||||
m_backgroudcontrols->ActivateControls(QUuid());
|
||||
}
|
||||
m_backgroundImages.remove(id);
|
||||
m_deletedBackgroundImageItems.insert(id, item);
|
||||
|
||||
if (backgroundImagesWidget != nullptr)
|
||||
{
|
||||
backgroundImagesWidget->UpdateImages();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void MainWindow::ShowBackgroundImageInExplorer(const QUuid &id)
|
||||
{
|
||||
ShowInGraphicalShell(doc->GetBackgroundImage(id).FilePath());
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void MainWindow::SaveBackgroundImage(const QUuid &id)
|
||||
{
|
||||
VBackgroundPatternImage image = doc->GetBackgroundImage(id);
|
||||
|
||||
if (not image.IsValid())
|
||||
{
|
||||
qCritical() << tr("Unable to save image. Error: %1").arg(image.ErrorString());
|
||||
return;
|
||||
}
|
||||
|
||||
if (image.ContentData().isEmpty())
|
||||
{
|
||||
qCritical() << tr("Unable to save image. No data.");
|
||||
return;
|
||||
}
|
||||
|
||||
const QByteArray imageData = QByteArray::fromBase64(image.ContentData());
|
||||
QMimeType mime = MimeTypeFromByteArray(imageData);
|
||||
QString path = QDir::homePath() + QDir::separator() + tr("untitled");
|
||||
QStringList filters;
|
||||
|
||||
if (mime.isValid())
|
||||
{
|
||||
QStringList suffixes = mime.suffixes();
|
||||
if (not suffixes.isEmpty())
|
||||
{
|
||||
path += '.' + suffixes.at(0);
|
||||
}
|
||||
|
||||
filters.append(mime.filterString());
|
||||
}
|
||||
|
||||
filters.append(tr("All files") + QStringLiteral(" (*.*)"));
|
||||
|
||||
QString filter = filters.join(QStringLiteral(";;"));
|
||||
|
||||
QString filename = QFileDialog::getSaveFileName(this, tr("Save Image"), path, filter, nullptr,
|
||||
VAbstractApplication::VApp()->NativeFileDialog());
|
||||
if (not filename.isEmpty())
|
||||
{
|
||||
QFile file(filename);
|
||||
if (file.open(QIODevice::WriteOnly))
|
||||
{
|
||||
file.write(imageData);
|
||||
}
|
||||
else
|
||||
{
|
||||
qCritical() << tr("Unable to save image. Error: %1").arg(file.errorString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void MainWindow::InitDimensionControls()
|
||||
{
|
||||
|
@ -4396,7 +4632,7 @@ QT_WARNING_DISABLE_GCC("-Wswitch-default")
|
|||
QT_WARNING_POP
|
||||
|
||||
// This check helps to find missed tools
|
||||
Q_STATIC_ASSERT_X(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 55, "Not all tools were handled.");
|
||||
Q_STATIC_ASSERT_X(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 59, "Not all tools were handled.");
|
||||
|
||||
//Drawing Tools
|
||||
ui->toolButtonEndLine->setEnabled(drawTools);
|
||||
|
@ -4593,9 +4829,15 @@ void MainWindow::ReadSettings()
|
|||
restoreState(settings->GetWindowState());
|
||||
restoreState(settings->GetToolbarsState(), AppVersion());
|
||||
|
||||
ui->dockWidgetGroups->setVisible(settings->IsDockWidgetGroupsActive());
|
||||
ui->dockWidgetToolOptions->setVisible(settings->IsDockWidgetToolOptionsActive());
|
||||
ui->dockWidgetMessages->setVisible(settings->IsDockWidgetPatternMessagesActive());
|
||||
m_groupsActive = settings->IsDockWidgetGroupsActive();
|
||||
m_toolOptionsActive = settings->IsDockWidgetToolOptionsActive();
|
||||
m_patternMessagesActive = settings->IsDockWidgetPatternMessagesActive();
|
||||
m_backgroundImagesActive = settings->IsDockWidgetBackgroundImagesActive();
|
||||
|
||||
ui->dockWidgetGroups->setVisible(m_groupsActive);
|
||||
ui->dockWidgetToolOptions->setVisible(m_toolOptionsActive);
|
||||
ui->dockWidgetMessages->setVisible(m_patternMessagesActive);
|
||||
ui->dockWidgetBackgroundImages->setVisible(m_backgroundImagesActive);
|
||||
|
||||
// Scene antialiasing
|
||||
ui->view->SetAntialiasing(settings->GetGraphicalOutput());
|
||||
|
@ -4609,9 +4851,6 @@ void MainWindow::ReadSettings()
|
|||
// Tool box scaling
|
||||
ToolBoxSizePolicy();
|
||||
|
||||
isDockToolOptionsVisible = ui->dockWidgetToolOptions->isEnabled();
|
||||
isDockGroupsVisible = ui->dockWidgetGroups->isEnabled();
|
||||
|
||||
QFont f = ui->plainTextEditPatternMessages->font();
|
||||
f.setPointSize(settings->GetPatternMessageFontSize(f.pointSize()));
|
||||
ui->plainTextEditPatternMessages->setFont(f);
|
||||
|
@ -4635,9 +4874,10 @@ void MainWindow::WriteSettings()
|
|||
settings->SetWindowState(saveState());
|
||||
settings->SetToolbarsState(saveState(AppVersion()));
|
||||
|
||||
settings->SetDockWidgetGroupsActive(ui->dockWidgetGroups->isEnabled());
|
||||
settings->SetDockWidgetToolOptionsActive(ui->dockWidgetToolOptions->isEnabled());
|
||||
settings->SetDockWidgetPatternMessagesActive(ui->dockWidgetMessages->isEnabled());
|
||||
settings->SetDockWidgetGroupsActive(ui->dockWidgetGroups->isVisible());
|
||||
settings->SetDockWidgetToolOptionsActive(ui->dockWidgetToolOptions->isVisible());
|
||||
settings->SetDockWidgetPatternMessagesActive(ui->dockWidgetMessages->isVisible());
|
||||
settings->SetDockWidgetBackgroundImagesActive(actionDockWidgetBackgroundImages->isChecked());
|
||||
|
||||
settings->sync();
|
||||
if (settings->status() == QSettings::AccessError)
|
||||
|
@ -4734,7 +4974,7 @@ QT_WARNING_DISABLE_GCC("-Wswitch-default")
|
|||
void MainWindow::LastUsedTool()
|
||||
{
|
||||
// This check helps to find missed tools in the switch
|
||||
Q_STATIC_ASSERT_X(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 55, "Not all tools were handled.");
|
||||
Q_STATIC_ASSERT_X(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 59, "Not all tools were handled.");
|
||||
|
||||
if (currentTool == lastUsedTool)
|
||||
{
|
||||
|
@ -4762,6 +5002,10 @@ void MainWindow::LastUsedTool()
|
|||
case Tool::NodeElArc:
|
||||
case Tool::NodeSpline:
|
||||
case Tool::NodeSplinePath:
|
||||
case Tool::BackgroundImage:
|
||||
case Tool::BackgroundImageControls:
|
||||
case Tool::BackgroundPixmapImage:
|
||||
case Tool::BackgroundSVGImage:
|
||||
Q_UNREACHABLE(); //-V501
|
||||
//Nothing to do here because we can't create this tool from main window.
|
||||
break;
|
||||
|
@ -4949,20 +5193,32 @@ void MainWindow::AddDocks()
|
|||
|
||||
//Add dock
|
||||
actionDockWidgetToolOptions = ui->dockWidgetToolOptions->toggleViewAction();
|
||||
ui->menuWindow->addAction(actionDockWidgetToolOptions);
|
||||
connect(actionDockWidgetToolOptions, &QAction::triggered, this, [this](bool checked)
|
||||
{
|
||||
isDockToolOptionsVisible = checked;
|
||||
m_toolOptionsActive = checked;
|
||||
});
|
||||
ui->menuWindow->addAction(actionDockWidgetToolOptions);
|
||||
|
||||
actionDockWidgetGroups = ui->dockWidgetGroups->toggleViewAction();
|
||||
ui->menuWindow->addAction(actionDockWidgetGroups);
|
||||
connect(actionDockWidgetGroups, &QAction::triggered, this, [this](bool checked)
|
||||
{
|
||||
isDockGroupsVisible = checked;
|
||||
m_groupsActive = checked;
|
||||
});
|
||||
ui->menuWindow->addAction(actionDockWidgetGroups);
|
||||
|
||||
ui->menuWindow->addAction(ui->dockWidgetMessages->toggleViewAction());
|
||||
QAction *action = ui->dockWidgetMessages->toggleViewAction();
|
||||
connect(action, &QAction::triggered, this, [this](bool checked)
|
||||
{
|
||||
m_patternMessagesActive = checked;
|
||||
});
|
||||
ui->menuWindow->addAction(action);
|
||||
|
||||
actionDockWidgetBackgroundImages = ui->dockWidgetBackgroundImages->toggleViewAction();
|
||||
connect(actionDockWidgetBackgroundImages, &QAction::triggered, this, [this](bool checked)
|
||||
{
|
||||
m_backgroundImagesActive = checked;
|
||||
});
|
||||
ui->menuWindow->addAction(actionDockWidgetBackgroundImages);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -4977,7 +5233,7 @@ void MainWindow::InitDocksContain()
|
|||
qCDebug(vMainWindow, "Initialization groups dock.");
|
||||
groupsWidget = new VWidgetGroups(doc, this);
|
||||
ui->dockWidgetGroups->setWidget(groupsWidget);
|
||||
connect(doc,&VAbstractPattern::UpdateGroups , this, &MainWindow::UpdateVisibilityGroups);
|
||||
connect(doc, &VAbstractPattern::UpdateGroups, this, &MainWindow::UpdateVisibilityGroups);
|
||||
|
||||
detailsWidget = new VWidgetDetails(pattern, doc, this);
|
||||
connect(doc, &VPattern::FullUpdateFromFile, detailsWidget, &VWidgetDetails::UpdateList);
|
||||
|
@ -4985,6 +5241,10 @@ void MainWindow::InitDocksContain()
|
|||
connect(doc, &VPattern::ShowDetail, detailsWidget, &VWidgetDetails::SelectDetail);
|
||||
connect(detailsWidget, &VWidgetDetails::Highlight, sceneDetails, &VMainGraphicsScene::HighlightItem);
|
||||
detailsWidget->setVisible(false);
|
||||
|
||||
backgroundImagesWidget = new VWidgetBackgroundImages(doc, this);
|
||||
ui->dockWidgetBackgroundImages->setWidget(backgroundImagesWidget);
|
||||
connect(backgroundImagesWidget, &VWidgetBackgroundImages::DeleteImage, this, &MainWindow::RemoveBackgroundImage);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -5316,6 +5576,8 @@ MainWindow::~MainWindow()
|
|||
|
||||
delete doc;
|
||||
delete ui;
|
||||
|
||||
qDeleteAll(m_deletedBackgroundImageItems);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -5576,9 +5838,20 @@ bool MainWindow::LoadPattern(QString fileName, const QString& customMeasureFile)
|
|||
/* Collect garbage only after successfully parse. This way wrongly accused items have one more time to restore
|
||||
* a reference. */
|
||||
QTimer::singleShot(100, Qt::CoarseTimer, this, [this](){doc->GarbageCollector(true);});
|
||||
|
||||
QTimer::singleShot(500, Qt::CoarseTimer, this, [this]()
|
||||
{
|
||||
QVector<VBackgroundPatternImage> allImages = doc->GetBackgroundImages();
|
||||
for (const auto &image : allImages)
|
||||
{
|
||||
NewBackgroundImageItem(image);
|
||||
}
|
||||
backgroundImagesWidget->UpdateImages();
|
||||
});
|
||||
}
|
||||
|
||||
patternReadOnly = doc->IsReadOnly();
|
||||
sceneDraw->SetAcceptDrop(true);
|
||||
SetEnableWidgets(true);
|
||||
setCurrentFile(fileName);
|
||||
qCDebug(vMainWindow, "File loaded.");
|
||||
|
@ -6562,6 +6835,7 @@ void MainWindow::ToolSelectPoint()
|
|||
emit EnableElArcSelection(false);
|
||||
emit EnableSplineSelection(false);
|
||||
emit EnableSplinePathSelection(false);
|
||||
emit EnableBackgroundImageSelection(false);
|
||||
|
||||
// Hovering
|
||||
emit EnableLabelHover(true);
|
||||
|
@ -6571,6 +6845,7 @@ void MainWindow::ToolSelectPoint()
|
|||
emit EnableElArcHover(false);
|
||||
emit EnableSplineHover(false);
|
||||
emit EnableSplinePathHover(false);
|
||||
emit EnableImageBackgroundHover(false);
|
||||
|
||||
ui->view->AllowRubberBand(false);
|
||||
}
|
||||
|
@ -6600,6 +6875,7 @@ void MainWindow::ToolSelectSpline()
|
|||
emit EnableElArcSelection(false);
|
||||
emit EnableSplineSelection(false);
|
||||
emit EnableSplinePathSelection(false);
|
||||
emit EnableBackgroundImageSelection(false);
|
||||
|
||||
// Hovering
|
||||
emit EnableLabelHover(false);
|
||||
|
@ -6609,6 +6885,7 @@ void MainWindow::ToolSelectSpline()
|
|||
emit EnableElArcHover(false);
|
||||
emit EnableSplineHover(true);
|
||||
emit EnableSplinePathHover(false);
|
||||
emit EnableImageBackgroundHover(false);
|
||||
|
||||
emit ItemsSelection(SelectionType::ByMouseRelease);
|
||||
|
||||
|
@ -6626,6 +6903,7 @@ void MainWindow::ToolSelectSplinePath()
|
|||
emit EnableElArcSelection(false);
|
||||
emit EnableSplineSelection(false);
|
||||
emit EnableSplinePathSelection(false);
|
||||
emit EnableBackgroundImageSelection(false);
|
||||
|
||||
// Hovering
|
||||
emit EnableLabelHover(false);
|
||||
|
@ -6635,6 +6913,7 @@ void MainWindow::ToolSelectSplinePath()
|
|||
emit EnableElArcHover(false);
|
||||
emit EnableSplineHover(false);
|
||||
emit EnableSplinePathHover(true);
|
||||
emit EnableImageBackgroundHover(false);
|
||||
|
||||
emit ItemsSelection(SelectionType::ByMouseRelease);
|
||||
|
||||
|
@ -6652,6 +6931,7 @@ void MainWindow::ToolSelectArc()
|
|||
emit EnableElArcSelection(false);
|
||||
emit EnableSplineSelection(false);
|
||||
emit EnableSplinePathSelection(false);
|
||||
emit EnableBackgroundImageSelection(false);
|
||||
|
||||
// Hovering
|
||||
emit EnableLabelHover(false);
|
||||
|
@ -6661,6 +6941,7 @@ void MainWindow::ToolSelectArc()
|
|||
emit EnableElArcHover(false);
|
||||
emit EnableSplineHover(false);
|
||||
emit EnableSplinePathHover(false);
|
||||
emit EnableImageBackgroundHover(false);
|
||||
|
||||
emit ItemsSelection(SelectionType::ByMouseRelease);
|
||||
|
||||
|
@ -6678,6 +6959,7 @@ void MainWindow::ToolSelectPointArc()
|
|||
emit EnableElArcSelection(false);
|
||||
emit EnableSplineSelection(false);
|
||||
emit EnableSplinePathSelection(false);
|
||||
emit EnableBackgroundImageSelection(false);
|
||||
|
||||
// Hovering
|
||||
emit EnableLabelHover(true);
|
||||
|
@ -6687,6 +6969,7 @@ void MainWindow::ToolSelectPointArc()
|
|||
emit EnableElArcHover(false);
|
||||
emit EnableSplineHover(false);
|
||||
emit EnableSplinePathHover(false);
|
||||
emit EnableImageBackgroundHover(false);
|
||||
|
||||
emit ItemsSelection(SelectionType::ByMouseRelease);
|
||||
|
||||
|
@ -6704,6 +6987,7 @@ void MainWindow::ToolSelectCurve()
|
|||
emit EnableElArcSelection(false);
|
||||
emit EnableSplineSelection(false);
|
||||
emit EnableSplinePathSelection(false);
|
||||
emit EnableBackgroundImageSelection(false);
|
||||
|
||||
// Hovering
|
||||
emit EnableLabelHover(false);
|
||||
|
@ -6713,6 +6997,7 @@ void MainWindow::ToolSelectCurve()
|
|||
emit EnableElArcHover(true);
|
||||
emit EnableSplineHover(true);
|
||||
emit EnableSplinePathHover(true);
|
||||
emit EnableImageBackgroundHover(false);
|
||||
|
||||
emit ItemsSelection(SelectionType::ByMouseRelease);
|
||||
|
||||
|
@ -6730,6 +7015,7 @@ void MainWindow::ToolSelectAllDrawObjects()
|
|||
emit EnableElArcSelection(false);
|
||||
emit EnableSplineSelection(false);
|
||||
emit EnableSplinePathSelection(false);
|
||||
emit EnableBackgroundImageSelection(false);
|
||||
|
||||
// Hovering
|
||||
emit EnableLabelHover(true);
|
||||
|
@ -6739,6 +7025,7 @@ void MainWindow::ToolSelectAllDrawObjects()
|
|||
emit EnableElArcHover(true);
|
||||
emit EnableSplineHover(true);
|
||||
emit EnableSplinePathHover(true);
|
||||
emit EnableImageBackgroundHover(false);
|
||||
|
||||
emit ItemsSelection(SelectionType::ByMouseRelease);
|
||||
|
||||
|
@ -6756,6 +7043,7 @@ void MainWindow::ToolSelectOperationObjects()
|
|||
emit EnableElArcSelection(true);
|
||||
emit EnableSplineSelection(true);
|
||||
emit EnableSplinePathSelection(true);
|
||||
emit EnableBackgroundImageSelection(false);
|
||||
|
||||
// Hovering
|
||||
emit EnableLabelHover(true);
|
||||
|
@ -6765,6 +7053,7 @@ void MainWindow::ToolSelectOperationObjects()
|
|||
emit EnableElArcHover(true);
|
||||
emit EnableSplineHover(true);
|
||||
emit EnableSplinePathHover(true);
|
||||
emit EnableImageBackgroundHover(false);
|
||||
|
||||
emit ItemsSelection(SelectionType::ByMouseRelease);
|
||||
|
||||
|
|
|
@ -55,6 +55,10 @@ class VWidgetDetails;
|
|||
class QToolButton;
|
||||
class QProgressBar;
|
||||
class WatermarkWindow;
|
||||
class Quuid;
|
||||
class VBackgroundImageItem;
|
||||
class VBackgroundImageControls;
|
||||
class VWidgetBackgroundImages;
|
||||
|
||||
/**
|
||||
* @brief The MainWindow class main windows.
|
||||
|
@ -74,6 +78,8 @@ public slots:
|
|||
virtual void UpdateVisibilityGroups() override;
|
||||
virtual void UpdateDetailsList() override;
|
||||
virtual void ZoomFitBestCurrent() override;
|
||||
void PlaceBackgroundImage(const QPointF &pos, const QString &fileName);
|
||||
void RemoveBackgroundImage(const QUuid &id);
|
||||
|
||||
signals:
|
||||
void RefreshHistory();
|
||||
|
@ -90,6 +96,7 @@ signals:
|
|||
void EnableNodeLabelSelection(bool enable);
|
||||
void EnableNodePointSelection(bool enable);
|
||||
void EnableDetailSelection(bool enable);
|
||||
void EnableBackgroundImageSelection(bool enable);
|
||||
|
||||
void EnableLabelHover(bool enable);
|
||||
void EnablePointHover(bool enable);
|
||||
|
@ -101,6 +108,7 @@ signals:
|
|||
void EnableNodeLabelHover(bool enable);
|
||||
void EnableNodePointHover(bool enable);
|
||||
void EnableDetailHover(bool enable);
|
||||
void EnableImageBackgroundHover(bool enable);
|
||||
protected:
|
||||
virtual void keyPressEvent(QKeyEvent *event) override;
|
||||
virtual void showEvent(QShowEvent *event) override;
|
||||
|
@ -192,6 +200,8 @@ private slots:
|
|||
void on_actionCreateManualLayout_triggered();
|
||||
void on_actionUpdateManualLayout_triggered();
|
||||
|
||||
void ActionAddBackgroundImage();
|
||||
|
||||
void ClosedDialogUnionDetails(int result);
|
||||
void ClosedDialogDuplicateDetail(int result);
|
||||
void ClosedDialogGroup(int result);
|
||||
|
@ -226,6 +236,11 @@ private slots:
|
|||
|
||||
void SetDefaultGUILanguage();
|
||||
|
||||
void AddBackgroundImageItem(const QUuid &id);
|
||||
void DeleteBackgroundImageItem(const QUuid &id);
|
||||
void ShowBackgroundImageInExplorer(const QUuid &id);
|
||||
void SaveBackgroundImage(const QUuid &id);
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(MainWindow)
|
||||
/** @brief ui keeps information about user interface */
|
||||
|
@ -269,9 +284,6 @@ private:
|
|||
/** @brief currentToolBoxIndex save current set of tools. */
|
||||
qint32 currentToolBoxIndex;
|
||||
|
||||
bool isDockToolOptionsVisible{false};
|
||||
bool isDockGroupsVisible{false};
|
||||
|
||||
/** @brief drawMode true if we current draw scene. */
|
||||
bool drawMode;
|
||||
|
||||
|
@ -291,6 +303,7 @@ private:
|
|||
VToolOptionsPropertyBrowser *toolOptions;
|
||||
VWidgetGroups *groupsWidget;
|
||||
VWidgetDetails *detailsWidget;
|
||||
VWidgetBackgroundImages *backgroundImagesWidget{nullptr};
|
||||
QSharedPointer<VLockGuard<char>> lock;
|
||||
|
||||
QList<QToolButton*> toolButtonPointerList;
|
||||
|
@ -308,6 +321,15 @@ private:
|
|||
|
||||
QTimer *m_gradation;
|
||||
|
||||
QMap<QUuid, VBackgroundImageItem *> m_backgroundImages{};
|
||||
QMap<QUuid, VBackgroundImageItem *> m_deletedBackgroundImageItems{};
|
||||
VBackgroundImageControls *m_backgroudcontrols{nullptr};
|
||||
|
||||
bool m_groupsActive{false};
|
||||
bool m_toolOptionsActive{false};
|
||||
bool m_patternMessagesActive{false};
|
||||
bool m_backgroundImagesActive{false};
|
||||
|
||||
void InitDimensionControls();
|
||||
void InitDimensionGradation(int index, const MeasurementDimension_p &dimension, const QPointer<QComboBox> &control);
|
||||
|
||||
|
@ -422,6 +444,8 @@ private:
|
|||
void StoreDimensions();
|
||||
|
||||
void ExportDraw(const QString &fileName);
|
||||
|
||||
void NewBackgroundImageItem(const VBackgroundPatternImage &image);
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
||||
|
|
|
@ -1613,7 +1613,7 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>140</width>
|
||||
<height>168</height>
|
||||
<height>169</height>
|
||||
</rect>
|
||||
</property>
|
||||
<attribute name="icon">
|
||||
|
@ -1778,6 +1778,8 @@
|
|||
<addaction name="actionLast_tool"/>
|
||||
<addaction name="actionShowCurveDetails"/>
|
||||
<addaction name="actionShowMainPath"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionAddBackgroundImage"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuMeasurements">
|
||||
<property name="title">
|
||||
|
@ -2185,6 +2187,15 @@
|
|||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QDockWidget" name="dockWidgetBackgroundImages">
|
||||
<property name="windowTitle">
|
||||
<string>Background images</string>
|
||||
</property>
|
||||
<attribute name="dockWidgetArea">
|
||||
<number>2</number>
|
||||
</attribute>
|
||||
<widget class="QWidget" name="dockWidgetContents_3"/>
|
||||
</widget>
|
||||
<action name="actionNew">
|
||||
<property name="icon">
|
||||
<iconset theme="document-new">
|
||||
|
@ -3094,6 +3105,14 @@
|
|||
<string>Shop</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionAddBackgroundImage">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Add background image</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<customwidgets>
|
||||
|
|
|
@ -107,6 +107,7 @@ protected:
|
|||
QAction *redoAction{nullptr};
|
||||
QAction *actionDockWidgetToolOptions{nullptr};
|
||||
QAction *actionDockWidgetGroups{nullptr};
|
||||
QAction *actionDockWidgetBackgroundImages{nullptr};
|
||||
|
||||
bool isNoScaling{false};
|
||||
bool isNeedAutosave{false};
|
||||
|
|
|
@ -4408,7 +4408,7 @@ QT_WARNING_DISABLE_GCC("-Wswitch-default")
|
|||
QRectF VPattern::ActiveDrawBoundingRect() const
|
||||
{
|
||||
// This check helps to find missed tools in the switch
|
||||
Q_STATIC_ASSERT_X(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 55, "Not all tools were used.");
|
||||
Q_STATIC_ASSERT_X(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 59, "Not all tools were used.");
|
||||
|
||||
QRectF rec;
|
||||
|
||||
|
@ -4427,6 +4427,10 @@ QRectF VPattern::ActiveDrawBoundingRect() const
|
|||
case Tool::Cut:
|
||||
case Tool::Midpoint:// Same as Tool::AlongLine, but tool will never has such type
|
||||
case Tool::ArcIntersectAxis:// Same as Tool::CurveIntersectAxis, but tool will never has such type
|
||||
case Tool::BackgroundImage:// Not part of active draw
|
||||
case Tool::BackgroundImageControls:// Not part of active draw
|
||||
case Tool::BackgroundPixmapImage:// Not part of active draw
|
||||
case Tool::BackgroundSVGImage:// Not part of active draw
|
||||
case Tool::LAST_ONE_DO_NOT_USE:
|
||||
Q_UNREACHABLE();
|
||||
break;
|
||||
|
|
|
@ -59,6 +59,28 @@
|
|||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="backgroudImages" minOccurs="0" maxOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:sequence minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="backgroudImage" minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:complexType>
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="xs:string">
|
||||
<xs:attribute name="imageId" type="uuid" use="required"/>
|
||||
<xs:attribute name="contentType" type="contentType"/>
|
||||
<xs:attribute name="path" type="xs:string"/>
|
||||
<xs:attribute name="name" type="xs:string"/>
|
||||
<xs:attribute name="transform" type="Transformation"/>
|
||||
<xs:attribute name="hold" type="xs:boolean"/>
|
||||
<xs:attribute name="visible" type="xs:boolean"/>
|
||||
<xs:attribute name="zValue" type="xs:unsignedInt"/>
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="measurements" type="xs:string"/>
|
||||
<xs:element name="increments">
|
||||
<xs:complexType>
|
||||
|
@ -778,6 +800,10 @@
|
|||
<xs:selector xpath="patternMaterials/material"/>
|
||||
<xs:field xpath="@number"/>
|
||||
</xs:unique>
|
||||
<xs:unique name="imageId">
|
||||
<xs:selector xpath="backgroudImages/backgroudImage"/>
|
||||
<xs:field xpath="@imageId"/>
|
||||
</xs:unique>
|
||||
</xs:element>
|
||||
<xs:simpleType name="shortName">
|
||||
<xs:restriction base="xs:string">
|
||||
|
@ -1129,4 +1155,9 @@
|
|||
<xs:attribute name="alignment" type="alignmentType"/>
|
||||
<xs:attribute name="sfIncrement" type="xs:unsignedInt"/>
|
||||
</xs:complexType>
|
||||
<xs:simpleType name="Transformation">
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:pattern value="([-+]?\d+\.?\d*([eE][-+]?\d+)?;){8,}[-+]?\d+\.?\d*([eE][-+]?\d+)?"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
</xs:schema>
|
||||
|
|
110
src/libs/ifc/xml/utils.cpp
Normal file
|
@ -0,0 +1,110 @@
|
|||
/************************************************************************
|
||||
**
|
||||
** @file utils.cpp
|
||||
** @author Roman Telezhynskyi <dismine(at)gmail.com>
|
||||
** @date 12 1, 2022
|
||||
**
|
||||
** @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) 2022 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 "utils.h"
|
||||
|
||||
#include <QImageReader>
|
||||
#include <QMimeDatabase>
|
||||
#include <QMimeType>
|
||||
#include <QRegularExpressionMatch>
|
||||
#include <QSet>
|
||||
#include <QStringList>
|
||||
#include <QSvgRenderer>
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto IsMimeTypeImage(const QMimeType &mime) -> bool
|
||||
{
|
||||
QStringList aliases = mime.aliases();
|
||||
aliases.prepend(mime.name());
|
||||
|
||||
QRegularExpression rx(QStringLiteral("^image\\/[-\\w]+(\\.[-\\w]+)*([+][-\\w]+)?$"));
|
||||
|
||||
return std::any_of(aliases.begin(), aliases.end(), [rx](const QString &name) { return rx.match(name).hasMatch(); });
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto SplitString(QString str) -> QStringList
|
||||
{
|
||||
QStringList list;
|
||||
|
||||
const int n = 80;
|
||||
while (not str.isEmpty())
|
||||
{
|
||||
list.append(str.left(n));
|
||||
str.remove(0, n);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto MimeTypeFromByteArray(const QByteArray &data) -> QMimeType
|
||||
{
|
||||
QMimeType mime = QMimeDatabase().mimeTypeForData(data);
|
||||
|
||||
QSet<QString> aliases = mime.aliases().toSet();
|
||||
aliases.insert(mime.name());
|
||||
|
||||
QSet<QString> gzipMime {"application/gzip", "application/x-gzip"};
|
||||
|
||||
if (gzipMime.contains(aliases))
|
||||
{
|
||||
QSvgRenderer render(data);
|
||||
if (render.isValid())
|
||||
{
|
||||
mime = QMimeDatabase().mimeTypeForName(QStringLiteral("image/svg+xml-compressed"));
|
||||
}
|
||||
}
|
||||
|
||||
return mime;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto PrepareImageFilters() -> QString
|
||||
{
|
||||
const QList<QByteArray> supportedFormats = QImageReader::supportedImageFormats();
|
||||
const QSet<QString> filterFormats{"bmp", "jpeg", "jpg", "png", "svg", "svgz", "tif", "tiff", "webp"};
|
||||
QStringList sufixes;
|
||||
for (const auto& format : supportedFormats)
|
||||
{
|
||||
if (filterFormats.contains(format))
|
||||
{
|
||||
sufixes.append(QStringLiteral("*.%1").arg(QString(format)));
|
||||
}
|
||||
}
|
||||
|
||||
QStringList filters;
|
||||
|
||||
if (not sufixes.isEmpty())
|
||||
{
|
||||
filters.append(QObject::tr("Images") + QStringLiteral(" (%1)").arg(sufixes.join(' ')));
|
||||
}
|
||||
|
||||
filters.append(QObject::tr("All files") + QStringLiteral(" (*.*)"));
|
||||
|
||||
return filters.join(QStringLiteral(";;"));
|
||||
}
|
42
src/libs/ifc/xml/utils.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
/************************************************************************
|
||||
**
|
||||
** @file utils.h
|
||||
** @author Roman Telezhynskyi <dismine(at)gmail.com>
|
||||
** @date 12 1, 2022
|
||||
**
|
||||
** @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) 2022 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 UTILS_H
|
||||
#define UTILS_H
|
||||
|
||||
class QMimeType;
|
||||
class QString;
|
||||
class QStringList;
|
||||
class QMimeType;
|
||||
class QByteArray;
|
||||
|
||||
auto IsMimeTypeImage(const QMimeType &mime) -> bool;
|
||||
auto SplitString(QString str) -> QStringList;
|
||||
auto MimeTypeFromByteArray(const QByteArray &data) -> QMimeType;
|
||||
auto PrepareImageFilters() -> QString;
|
||||
|
||||
#endif // UTILS_H
|
|
@ -59,6 +59,7 @@
|
|||
#include "../vmisc/compatibility.h"
|
||||
#include "../vlayout/vtextmanager.h"
|
||||
#include "vpatternimage.h"
|
||||
#include "vbackgroundpatternimage.h"
|
||||
|
||||
class QDomElement;
|
||||
|
||||
|
@ -102,6 +103,8 @@ const QString VAbstractPattern::TagGrainline = QStringLiteral("grainline"
|
|||
const QString VAbstractPattern::TagPath = QStringLiteral("path");
|
||||
const QString VAbstractPattern::TagNodes = QStringLiteral("nodes");
|
||||
const QString VAbstractPattern::TagNode = QStringLiteral("node");
|
||||
const QString VAbstractPattern::TagBackgroundImages = QStringLiteral("backgroudImages");
|
||||
const QString VAbstractPattern::TagBackgroundImage = QStringLiteral("backgroudImage");
|
||||
|
||||
const QString VAbstractPattern::AttrName = QStringLiteral("name");
|
||||
const QString VAbstractPattern::AttrVisible = QStringLiteral("visible");
|
||||
|
@ -138,6 +141,10 @@ const QString VAbstractPattern::AttrManualPassmarkLength = QStringLiteral("manua
|
|||
const QString VAbstractPattern::AttrPassmarkLength = QStringLiteral("passmarkLength");
|
||||
const QString VAbstractPattern::AttrOpacity = QStringLiteral("opacity");
|
||||
const QString VAbstractPattern::AttrTags = QStringLiteral("tags");
|
||||
const QString VAbstractPattern::AttrTransform = QStringLiteral("transform");
|
||||
const QString VAbstractPattern::AttrHold = QStringLiteral("hold");
|
||||
const QString VAbstractPattern::AttrZValue = QStringLiteral("zValue");
|
||||
const QString VAbstractPattern::AttrImageId = QStringLiteral("imageId");
|
||||
|
||||
const QString VAbstractPattern::AttrContentType = QStringLiteral("contentType");
|
||||
|
||||
|
@ -235,8 +242,55 @@ QString PrepareGroupTags(QStringList tags)
|
|||
|
||||
return ConvertToList(ConvertToSet<QString>(tags)).join(',');
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto StringToTransfrom(const QString &matrix) -> QTransform
|
||||
{
|
||||
QStringList elements = matrix.split(QChar(';'));
|
||||
if (elements.count() == 9)
|
||||
{
|
||||
qreal m11 = elements.at(0).toDouble();
|
||||
qreal m12 = elements.at(1).toDouble();
|
||||
qreal m13 = elements.at(2).toDouble();
|
||||
qreal m21 = elements.at(3).toDouble();
|
||||
qreal m22 = elements.at(4).toDouble();
|
||||
qreal m23 = elements.at(5).toDouble();
|
||||
qreal m31 = elements.at(6).toDouble();
|
||||
qreal m32 = elements.at(7).toDouble();
|
||||
qreal m33 = elements.at(8).toDouble();
|
||||
return {m11, m12, m13, m21, m22, m23, m31, m32, m33};
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
template <class T>
|
||||
auto NumberToString(T number) -> QString
|
||||
{
|
||||
const QLocale locale = QLocale::c();
|
||||
return locale.toString(number, 'g', 12).remove(locale.groupSeparator());
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto TransformToString(const QTransform &m) -> QString
|
||||
{
|
||||
QStringList matrix
|
||||
{
|
||||
NumberToString(m.m11()),
|
||||
NumberToString(m.m12()),
|
||||
NumberToString(m.m13()),
|
||||
NumberToString(m.m21()),
|
||||
NumberToString(m.m22()),
|
||||
NumberToString(m.m23()),
|
||||
NumberToString(m.m31()),
|
||||
NumberToString(m.m32()),
|
||||
NumberToString(m.m33())
|
||||
};
|
||||
return matrix.join(QChar(';'));
|
||||
}
|
||||
} // namespace
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VAbstractPattern::VAbstractPattern(QObject *parent)
|
||||
: VDomDocument(parent),
|
||||
|
@ -848,7 +902,7 @@ void VAbstractPattern::SetMPath(const QString &path)
|
|||
quint32 VAbstractPattern::SiblingNodeId(const quint32 &nodeId) const
|
||||
{
|
||||
// This check helps to find missed tools in the switch
|
||||
Q_STATIC_ASSERT_X(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 55, "Check if need to ignore modeling tools.");
|
||||
Q_STATIC_ASSERT_X(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 59, "Check if need to ignore modeling tools.");
|
||||
|
||||
quint32 siblingId = NULL_ID;
|
||||
|
||||
|
@ -882,6 +936,10 @@ quint32 VAbstractPattern::SiblingNodeId(const quint32 &nodeId) const
|
|||
case Tool::PiecePath:
|
||||
case Tool::InsertNode:
|
||||
case Tool::DuplicateDetail:
|
||||
case Tool::BackgroundImage:
|
||||
case Tool::BackgroundImageControls:
|
||||
case Tool::BackgroundPixmapImage:
|
||||
case Tool::BackgroundSVGImage:
|
||||
continue;
|
||||
default:
|
||||
siblingId = tool.getId();
|
||||
|
@ -1267,6 +1325,126 @@ void VAbstractPattern::DeleteImage()
|
|||
emit patternChanged(false);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VAbstractPattern::GetBackgroundImages() const -> QVector<VBackgroundPatternImage>
|
||||
{
|
||||
QVector<VBackgroundPatternImage> images;
|
||||
const QDomNodeList list = elementsByTagName(TagBackgroundImages);
|
||||
if (list.isEmpty())
|
||||
{
|
||||
return images;
|
||||
}
|
||||
|
||||
QDomElement imagesTag = list.at(0).toElement();
|
||||
if (not imagesTag.isNull())
|
||||
{
|
||||
QDomNode imageNode = imagesTag.firstChild();
|
||||
while (not imageNode.isNull())
|
||||
{
|
||||
const QDomElement imageElement = imageNode.toElement();
|
||||
if (not imageElement.isNull())
|
||||
{
|
||||
images.append(GetBackgroundPatternImage(imageElement));
|
||||
}
|
||||
imageNode = imageNode.nextSibling();
|
||||
}
|
||||
}
|
||||
|
||||
return images;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VAbstractPattern::SaveBackgroundImages(const QVector<VBackgroundPatternImage> &images)
|
||||
{
|
||||
QDomElement imagesElement = CheckTagExists(TagBackgroundImages);
|
||||
RemoveAllChildren(imagesElement);
|
||||
|
||||
for (const auto& image : images)
|
||||
{
|
||||
if (not image.Id().isNull())
|
||||
{
|
||||
QDomElement imageElement = createElement(TagBackgroundImage);
|
||||
WriteBackgroundImage(imageElement, image);
|
||||
imagesElement.appendChild(imageElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VAbstractPattern::GetBackgroundImage(const QUuid &id) const -> VBackgroundPatternImage
|
||||
{
|
||||
const QDomElement imageElement = GetBackgroundImageElement(id);
|
||||
if (not imageElement.isNull())
|
||||
{
|
||||
return GetBackgroundPatternImage(imageElement);
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VAbstractPattern::SaveBackgroundImage(const VBackgroundPatternImage &image)
|
||||
{
|
||||
QDomElement imageElement = GetBackgroundImageElement(image.Id());
|
||||
if (imageElement.isNull())
|
||||
{
|
||||
QDomElement imageElement = createElement(TagBackgroundImage);
|
||||
WriteBackgroundImage(imageElement, image);
|
||||
QDomElement imagesElement = CheckTagExists(TagBackgroundImages);
|
||||
imagesElement.appendChild(imageElement);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteBackgroundImage(imageElement, image);
|
||||
}
|
||||
|
||||
modified = true;
|
||||
emit patternChanged(false);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VAbstractPattern::DeleteBackgroundImage(const QUuid &id)
|
||||
{
|
||||
const QDomNodeList list = elementsByTagName(TagBackgroundImages);
|
||||
if (list.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QDomElement imagesTag = list.at(0).toElement();
|
||||
if (not imagesTag.isNull())
|
||||
{
|
||||
QDomNode imageNode = imagesTag.firstChild();
|
||||
while (not imageNode.isNull())
|
||||
{
|
||||
const QDomElement imageElement = imageNode.toElement();
|
||||
if (not imageElement.isNull())
|
||||
{
|
||||
QUuid imageId = QUuid(GetParametrEmptyString(imageElement, AttrImageId));
|
||||
if (imageId == id)
|
||||
{
|
||||
imagesTag.removeChild(imageElement);
|
||||
|
||||
if (imagesTag.childNodes().size() == 0)
|
||||
{
|
||||
QDomNode parent = imagesTag.parentNode();
|
||||
if (not parent.isNull())
|
||||
{
|
||||
parent.removeChild(imagesTag);
|
||||
}
|
||||
}
|
||||
|
||||
modified = true;
|
||||
emit patternChanged(false);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
imageNode = imageNode.nextSibling();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
QString VAbstractPattern::GetVersion() const
|
||||
{
|
||||
|
@ -1357,7 +1535,7 @@ void VAbstractPattern::SetActivPP(const QString &name)
|
|||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
QDomElement VAbstractPattern::CheckTagExists(const QString &tag)
|
||||
auto VAbstractPattern::CheckTagExists(const QString &tag) -> QDomElement
|
||||
{
|
||||
const QDomNodeList list = elementsByTagName(tag);
|
||||
QDomElement element;
|
||||
|
@ -1378,7 +1556,8 @@ QDomElement VAbstractPattern::CheckTagExists(const QString &tag)
|
|||
TagPatternLabel, // 10
|
||||
TagWatermark, // 11
|
||||
TagPatternMaterials, // 12
|
||||
TagFinalMeasurements // 13
|
||||
TagFinalMeasurements, // 13
|
||||
TagBackgroundImages // 14
|
||||
};
|
||||
|
||||
switch (tags.indexOf(tag))
|
||||
|
@ -1422,9 +1601,12 @@ QDomElement VAbstractPattern::CheckTagExists(const QString &tag)
|
|||
case 13: // TagFinalMeasurements
|
||||
element = createElement(TagFinalMeasurements);
|
||||
break;
|
||||
case 14: // TagBackgroundImages
|
||||
element = createElement(TagBackgroundImages);
|
||||
break;
|
||||
case 0: //TagUnit (Mandatory tag)
|
||||
default:
|
||||
return QDomElement();
|
||||
return {};
|
||||
}
|
||||
InsertTag(tags, element);
|
||||
return element;
|
||||
|
@ -1531,7 +1713,7 @@ QVector<VFormulaField> VAbstractPattern::ListPointExpressions() const
|
|||
// Check if new tool doesn't bring new attribute with a formula.
|
||||
// If no just increment a number.
|
||||
// If new tool bring absolutely new type and has formula(s) create new method to cover it.
|
||||
Q_STATIC_ASSERT(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 55);
|
||||
Q_STATIC_ASSERT(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 59);
|
||||
|
||||
QVector<VFormulaField> expressions;
|
||||
const QDomNodeList list = elementsByTagName(TagPoint);
|
||||
|
@ -1559,7 +1741,7 @@ QVector<VFormulaField> VAbstractPattern::ListArcExpressions() const
|
|||
// Check if new tool doesn't bring new attribute with a formula.
|
||||
// If no just increment number.
|
||||
// If new tool bring absolutely new type and has formula(s) create new method to cover it.
|
||||
Q_STATIC_ASSERT(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 55);
|
||||
Q_STATIC_ASSERT(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 59);
|
||||
|
||||
QVector<VFormulaField> expressions;
|
||||
const QDomNodeList list = elementsByTagName(TagArc);
|
||||
|
@ -1583,7 +1765,7 @@ QVector<VFormulaField> VAbstractPattern::ListElArcExpressions() const
|
|||
// Check if new tool doesn't bring new attribute with a formula.
|
||||
// If no just increment number.
|
||||
// If new tool bring absolutely new type and has formula(s) create new method to cover it.
|
||||
Q_STATIC_ASSERT(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 55);
|
||||
Q_STATIC_ASSERT(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 59);
|
||||
|
||||
QVector<VFormulaField> expressions;
|
||||
const QDomNodeList list = elementsByTagName(TagElArc);
|
||||
|
@ -1616,7 +1798,7 @@ QVector<VFormulaField> VAbstractPattern::ListPathPointExpressions() const
|
|||
// Check if new tool doesn't bring new attribute with a formula.
|
||||
// If no just increment number.
|
||||
// If new tool bring absolutely new type and has formula(s) create new method to cover it.
|
||||
Q_STATIC_ASSERT(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 55);
|
||||
Q_STATIC_ASSERT(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 59);
|
||||
|
||||
QVector<VFormulaField> expressions;
|
||||
const QDomNodeList list = elementsByTagName(AttrPathPoint);
|
||||
|
@ -1654,7 +1836,7 @@ QVector<VFormulaField> VAbstractPattern::ListOperationExpressions() const
|
|||
// Check if new tool doesn't bring new attribute with a formula.
|
||||
// If no just increment number.
|
||||
// If new tool bring absolutely new type and has formula(s) create new method to cover it.
|
||||
Q_STATIC_ASSERT(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 55);
|
||||
Q_STATIC_ASSERT(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 59);
|
||||
|
||||
QVector<VFormulaField> expressions;
|
||||
const QDomNodeList list = elementsByTagName(TagOperation);
|
||||
|
@ -1676,7 +1858,7 @@ QVector<VFormulaField> VAbstractPattern::ListNodesExpressions(const QDomElement
|
|||
// Check if new tool doesn't bring new attribute with a formula.
|
||||
// If no just increment number.
|
||||
// If new tool bring absolutely new type and has formula(s) create new method to cover it.
|
||||
Q_STATIC_ASSERT(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 55);
|
||||
Q_STATIC_ASSERT(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 59);
|
||||
|
||||
QVector<VFormulaField> expressions;
|
||||
|
||||
|
@ -1700,7 +1882,7 @@ QVector<VFormulaField> VAbstractPattern::ListPathExpressions() const
|
|||
// Check if new tool doesn't bring new attribute with a formula.
|
||||
// If no just increment number.
|
||||
// If new tool bring absolutely new type and has formula(s) create new method to cover it.
|
||||
Q_STATIC_ASSERT(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 55);
|
||||
Q_STATIC_ASSERT(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 59);
|
||||
|
||||
QVector<VFormulaField> expressions;
|
||||
const QDomNodeList list = elementsByTagName(TagPath);
|
||||
|
@ -1738,7 +1920,7 @@ QVector<VFormulaField> VAbstractPattern::ListPieceExpressions() const
|
|||
// Check if new tool doesn't bring new attribute with a formula.
|
||||
// If no just increment number.
|
||||
// If new tool bring absolutely new type and has formula(s) create new method to cover it.
|
||||
Q_STATIC_ASSERT(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 55);
|
||||
Q_STATIC_ASSERT(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 59);
|
||||
|
||||
QVector<VFormulaField> expressions;
|
||||
const QDomNodeList list = elementsByTagName(TagDetail);
|
||||
|
@ -1951,6 +2133,96 @@ void VAbstractPattern::SetFMeasurements(QDomElement &element, const QVector<VFin
|
|||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VAbstractPattern::GetBackgroundPatternImage(const QDomElement &element) const -> VBackgroundPatternImage
|
||||
{
|
||||
VBackgroundPatternImage image;
|
||||
image.SetId(QUuid(GetParametrEmptyString(element, AttrImageId)));
|
||||
QString path = GetParametrEmptyString(element, AttrPath);
|
||||
|
||||
if (not path.isEmpty())
|
||||
{
|
||||
image.SetFilePath(path);
|
||||
}
|
||||
else
|
||||
{
|
||||
QString contentType = GetParametrEmptyString(element, AttrContentType);
|
||||
QByteArray contentData = element.text().toLatin1();
|
||||
image.SetContentData(contentData, contentType);
|
||||
}
|
||||
|
||||
image.SetName(GetParametrEmptyString(element, AttrName));
|
||||
image.SetHold(GetParametrBool(element, AttrHold, falseStr));
|
||||
image.SetZValue(GetParametrUInt(element, AttrZValue, QChar('0')));
|
||||
image.SetVisible(GetParametrBool(element, AttrVisible, trueStr));
|
||||
|
||||
QString matrix = GetParametrEmptyString(element, AttrTransform);
|
||||
image.SetMatrix(StringToTransfrom(matrix));
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VAbstractPattern::GetBackgroundImageElement(const QUuid &id) const -> QDomElement
|
||||
{
|
||||
const QDomNodeList list = elementsByTagName(TagBackgroundImages);
|
||||
if (not list.isEmpty())
|
||||
{
|
||||
QDomElement imagesTag = list.at(0).toElement();
|
||||
if (not imagesTag.isNull())
|
||||
{
|
||||
QDomNode imageNode = imagesTag.firstChild();
|
||||
while (not imageNode.isNull())
|
||||
{
|
||||
if (imageNode.isElement())
|
||||
{
|
||||
const QDomElement imageElement = imageNode.toElement();
|
||||
if (not imageElement.isNull())
|
||||
{
|
||||
QUuid imageId = QUuid(GetParametrEmptyString(imageElement, AttrImageId));
|
||||
if (imageId == id)
|
||||
{
|
||||
return imageElement;
|
||||
}
|
||||
}
|
||||
}
|
||||
imageNode = imageNode.nextSibling();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VAbstractPattern::WriteBackgroundImage(QDomElement &element, const VBackgroundPatternImage &image)
|
||||
{
|
||||
SetAttribute(element, AttrImageId, image.Id().toString());
|
||||
|
||||
if (not image.FilePath().isEmpty())
|
||||
{
|
||||
SetAttribute(element, AttrPath, image.FilePath());
|
||||
element.removeAttribute(AttrContentType);
|
||||
setTagText(element, QString());
|
||||
}
|
||||
else
|
||||
{
|
||||
SetAttributeOrRemoveIf<QString>(element, AttrContentType, image.ContentType(),
|
||||
[](const QString &contentType) noexcept {return contentType.isEmpty();});
|
||||
setTagText(element, image.ContentData());
|
||||
SetAttributeOrRemoveIf<QString>(element, AttrPath, image.FilePath(),
|
||||
[](const QString &path) noexcept {return path.isEmpty();});
|
||||
}
|
||||
|
||||
SetAttributeOrRemoveIf<QString>(element, AttrName, image.Name(),
|
||||
[](const QString &name) noexcept {return name.isEmpty();});
|
||||
SetAttribute(element, AttrTransform, TransformToString(image.Matrix()));
|
||||
|
||||
SetAttributeOrRemoveIf<bool>(element, AttrHold, image.Hold(), [](bool hold) noexcept {return not hold;});
|
||||
SetAttributeOrRemoveIf<qreal>(element, AttrZValue, image.ZValue(), [](qreal z) noexcept {return qFuzzyIsNull(z);});
|
||||
SetAttributeOrRemoveIf<bool>(element, AttrVisible, image.Visible(), [](bool visible) noexcept {return visible;});
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief IsModified state of the document for cases that do not cover QUndoStack.
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include <QStringList>
|
||||
#include <QVector>
|
||||
#include <QtGlobal>
|
||||
#include <QUuid>
|
||||
|
||||
#include "../vmisc/def.h"
|
||||
#include "vdomdocument.h"
|
||||
|
@ -49,6 +50,7 @@ class QDomElement;
|
|||
class VPiecePath;
|
||||
class VPieceNode;
|
||||
class VPatternImage;
|
||||
class VBackgroundPatternImage;
|
||||
|
||||
enum class Document : qint8 { FullLiteParse, LiteParse, LitePPParse, FullParse };
|
||||
enum class LabelType : qint8 {NewPatternPiece, NewLabel};
|
||||
|
@ -205,6 +207,12 @@ public:
|
|||
bool SetImage(const VPatternImage &image);
|
||||
void DeleteImage();
|
||||
|
||||
auto GetBackgroundImages() const -> QVector<VBackgroundPatternImage>;
|
||||
void SaveBackgroundImages(const QVector<VBackgroundPatternImage> &images);
|
||||
auto GetBackgroundImage(const QUuid &id) const -> VBackgroundPatternImage;
|
||||
void SaveBackgroundImage(const VBackgroundPatternImage &image);
|
||||
void DeleteBackgroundImage(const QUuid &id);
|
||||
|
||||
QString GetVersion() const;
|
||||
void SetVersion();
|
||||
|
||||
|
@ -282,6 +290,8 @@ public:
|
|||
static const QString TagPath;
|
||||
static const QString TagNodes;
|
||||
static const QString TagNode;
|
||||
static const QString TagBackgroundImages;
|
||||
static const QString TagBackgroundImage;
|
||||
|
||||
static const QString AttrName;
|
||||
static const QString AttrVisible;
|
||||
|
@ -318,6 +328,10 @@ public:
|
|||
static const QString AttrPassmarkLength;
|
||||
static const QString AttrOpacity;
|
||||
static const QString AttrTags;
|
||||
static const QString AttrTransform;
|
||||
static const QString AttrHold;
|
||||
static const QString AttrZValue;
|
||||
static const QString AttrImageId;
|
||||
|
||||
static const QString AttrContentType;
|
||||
|
||||
|
@ -378,6 +392,15 @@ signals:
|
|||
void UpdateGroups();
|
||||
void UpdateToolTip();
|
||||
|
||||
void BackgroundImageTransformationChanged(QUuid id);
|
||||
void BackgroundImagesHoldChanged();
|
||||
void BackgroundImageHoldChanged(const QUuid &id);
|
||||
void BackgroundImageVisibilityChanged(const QUuid &id);
|
||||
void BackgroundImagesVisibilityChanged();
|
||||
void BackgroundImageNameChanged(const QUuid &id);
|
||||
void BackgroundImagesZValueChanged();
|
||||
void BackgroundImagePositionChanged(const QUuid &id);
|
||||
|
||||
public slots:
|
||||
virtual void LiteParseTree(const Document &parse)=0;
|
||||
void haveLiteChange();
|
||||
|
@ -473,6 +496,10 @@ private:
|
|||
|
||||
QVector<VFinalMeasurement> GetFMeasurements(const QDomElement &element) const;
|
||||
void SetFMeasurements(QDomElement &element, const QVector<VFinalMeasurement> &measurements);
|
||||
|
||||
auto GetBackgroundPatternImage(const QDomElement &element) const -> VBackgroundPatternImage;
|
||||
auto GetBackgroundImageElement(const QUuid &id) const -> QDomElement;
|
||||
void WriteBackgroundImage(QDomElement &element, const VBackgroundPatternImage &image);
|
||||
};
|
||||
|
||||
QT_WARNING_POP
|
||||
|
|
310
src/libs/ifc/xml/vbackgroundpatternimage.cpp
Normal file
|
@ -0,0 +1,310 @@
|
|||
/************************************************************************
|
||||
**
|
||||
** @file vbackgroundpatternimage.cpp
|
||||
** @author Roman Telezhynskyi <dismine(at)gmail.com>
|
||||
** @date 11 1, 2022
|
||||
**
|
||||
** @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) 2022 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 "vbackgroundpatternimage.h"
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
#include <QMimeType>
|
||||
#include <QDebug>
|
||||
#include <QFile>
|
||||
#include <QMimeDatabase>
|
||||
#include <QPixmap>
|
||||
#include <QBuffer>
|
||||
#include <QImageReader>
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VBackgroundPatternImage::FromFile(const QString &fileName, bool builtIn) -> VBackgroundPatternImage
|
||||
{
|
||||
VBackgroundPatternImage image;
|
||||
QMimeType mime = QMimeDatabase().mimeTypeForFile(fileName);
|
||||
|
||||
if (not IsMimeTypeImage(mime))
|
||||
{
|
||||
qCritical() << tr("Unexpected mime type: %1").arg(mime.name());
|
||||
return {};
|
||||
}
|
||||
|
||||
if (builtIn)
|
||||
{
|
||||
QFile file(fileName);
|
||||
if (not file.open(QIODevice::ReadOnly))
|
||||
{
|
||||
qCritical() << tr("Couldn't read the image. Error: %1").arg(file.errorString());
|
||||
return {};
|
||||
}
|
||||
|
||||
QString base64 = SplitString(QString::fromLatin1(file.readAll().toBase64().data())).join('\n');
|
||||
image.SetContentData(base64.toLatin1(), mime.name());
|
||||
}
|
||||
else
|
||||
{
|
||||
image.SetFilePath(fileName);
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VBackgroundPatternImage::ContentType() const -> const QString &
|
||||
{
|
||||
return m_contentType;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VBackgroundPatternImage::ContentData() const -> const QByteArray &
|
||||
{
|
||||
return m_contentData;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VBackgroundPatternImage::SetContentData(const QByteArray &newContentData, const QString &newContentType)
|
||||
{
|
||||
m_contentData = newContentData;
|
||||
m_contentType = newContentType;
|
||||
m_filePath.clear();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VBackgroundPatternImage::IsNull() const -> bool
|
||||
{
|
||||
return m_filePath.isEmpty() && m_contentData.isEmpty();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VBackgroundPatternImage::IsValid() const -> bool
|
||||
{
|
||||
m_errorString.clear();
|
||||
|
||||
if (IsNull())
|
||||
{
|
||||
m_errorString = tr("No data.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_id.isNull())
|
||||
{
|
||||
m_errorString = tr("Invalid id.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (not m_filePath.isEmpty())
|
||||
{
|
||||
QMimeType mime = MimeTypeFromData();
|
||||
|
||||
if (not IsMimeTypeImage(mime))
|
||||
{
|
||||
qCritical() << tr("Unexpected mime type: %1").arg(mime.name());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_contentType.isEmpty())
|
||||
{
|
||||
m_errorString = tr("Content type is empty.");
|
||||
return false;
|
||||
}
|
||||
|
||||
QMimeType mime = MimeTypeFromData();
|
||||
QSet<QString> aliases = mime.aliases().toSet();
|
||||
aliases.insert(mime.name());
|
||||
|
||||
if (not aliases.contains(m_contentType))
|
||||
{
|
||||
m_errorString = tr("Content type mistmatch.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (not IsMimeTypeImage(mime))
|
||||
{
|
||||
m_errorString = tr("Not image.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VBackgroundPatternImage::MimeTypeFromData() const -> QMimeType
|
||||
{
|
||||
if (not m_filePath.isEmpty())
|
||||
{
|
||||
return QMimeDatabase().mimeTypeForFile(m_filePath);
|
||||
}
|
||||
|
||||
if (not m_contentData.isEmpty())
|
||||
{
|
||||
return MimeTypeFromByteArray(QByteArray::fromBase64(m_contentData));
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VBackgroundPatternImage::FilePath() const -> const QString &
|
||||
{
|
||||
return m_filePath;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VBackgroundPatternImage::SetFilePath(const QString &newFilePath)
|
||||
{
|
||||
m_filePath = newFilePath;
|
||||
m_contentData.clear();
|
||||
m_contentType.clear();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VBackgroundPatternImage::Name() const -> const QString &
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VBackgroundPatternImage::SetName(const QString &newName)
|
||||
{
|
||||
m_name = newName;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VBackgroundPatternImage::ZValue() const -> qreal
|
||||
{
|
||||
return m_zValue;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VBackgroundPatternImage::SetZValue(qreal newZValue)
|
||||
{
|
||||
m_zValue = newZValue;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VBackgroundPatternImage::Hold() const -> bool
|
||||
{
|
||||
return m_hold;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VBackgroundPatternImage::SetHold(bool newHold)
|
||||
{
|
||||
m_hold = newHold;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VBackgroundPatternImage::Id() const -> QUuid
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VBackgroundPatternImage::SetId(const QUuid &newId)
|
||||
{
|
||||
m_id = newId;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VBackgroundPatternImage::Size() const -> QSize
|
||||
{
|
||||
if (not IsValid())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
if (not m_filePath.isEmpty())
|
||||
{
|
||||
return QImageReader(m_filePath).size();
|
||||
}
|
||||
|
||||
if (not m_contentData.isEmpty())
|
||||
{
|
||||
QByteArray array = QByteArray::fromBase64(m_contentData);
|
||||
QBuffer buffer(&array);
|
||||
buffer.open(QIODevice::ReadOnly);
|
||||
|
||||
return QImageReader(&buffer).size();
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VBackgroundPatternImage::ErrorString() const -> const QString &
|
||||
{
|
||||
return m_errorString;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VBackgroundPatternImage::Matrix() const -> const QTransform &
|
||||
{
|
||||
return m_matrix;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VBackgroundPatternImage::SetMatrix(const QTransform &newMatrix)
|
||||
{
|
||||
m_matrix = newMatrix;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VBackgroundPatternImage::Type() const -> PatternImage
|
||||
{
|
||||
if (not IsValid())
|
||||
{
|
||||
return PatternImage::Unknown;
|
||||
}
|
||||
|
||||
QMimeType mime = MimeTypeFromData();
|
||||
|
||||
if (mime.name().startsWith(u"image/svg+xml"))
|
||||
{
|
||||
return PatternImage::Vector;
|
||||
}
|
||||
|
||||
return PatternImage::Raster;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VBackgroundPatternImage::BoundingRect() const -> QRectF
|
||||
{
|
||||
QSize imageSize = Size();
|
||||
QRectF imageRect({0, 0}, QSizeF(imageSize.width(), imageSize.height()));
|
||||
return m_matrix.mapRect(imageRect);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VBackgroundPatternImage::Visible() const -> bool
|
||||
{
|
||||
return m_visible;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VBackgroundPatternImage::SetVisible(bool newVisible)
|
||||
{
|
||||
m_visible = newVisible;
|
||||
}
|
109
src/libs/ifc/xml/vbackgroundpatternimage.h
Normal file
|
@ -0,0 +1,109 @@
|
|||
/************************************************************************
|
||||
**
|
||||
** @file vbackgroundpatternimage.h
|
||||
** @author Roman Telezhynskyi <dismine(at)gmail.com>
|
||||
** @date 11 1, 2022
|
||||
**
|
||||
** @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) 2022 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 VBACKGROUNDPATTERNIMAGE_H
|
||||
#define VBACKGROUNDPATTERNIMAGE_H
|
||||
|
||||
#include <QPoint>
|
||||
#include <QCoreApplication>
|
||||
#include <QUuid>
|
||||
#include <QTransform>
|
||||
|
||||
#include "../vmisc/typedef.h"
|
||||
|
||||
class QPixmap;
|
||||
class QMimeType;
|
||||
|
||||
enum class PatternImage
|
||||
{
|
||||
Raster,
|
||||
Vector,
|
||||
Unknown
|
||||
};
|
||||
|
||||
class VBackgroundPatternImage
|
||||
{
|
||||
Q_DECLARE_TR_FUNCTIONS(VBackgroundPatternImage)
|
||||
public:
|
||||
VBackgroundPatternImage() = default;
|
||||
|
||||
static auto FromFile(const QString &fileName, bool builtIn) -> VBackgroundPatternImage;
|
||||
|
||||
auto ContentType() const -> const QString &;
|
||||
|
||||
auto ContentData() const -> const QByteArray &;
|
||||
void SetContentData(const QByteArray &newContentData, const QString & newContentType);
|
||||
|
||||
auto IsNull() const -> bool;
|
||||
auto IsValid() const -> bool;
|
||||
|
||||
auto MimeTypeFromData() const -> QMimeType;
|
||||
|
||||
auto FilePath() const -> const QString &;
|
||||
void SetFilePath(const QString &newFilePath);
|
||||
|
||||
auto Name() const -> const QString &;
|
||||
void SetName(const QString &newName);
|
||||
|
||||
auto ZValue() const -> qreal;
|
||||
void SetZValue(qreal newZValue);
|
||||
|
||||
auto Hold() const -> bool;
|
||||
void SetHold(bool newHold);
|
||||
|
||||
auto Id() const -> QUuid;
|
||||
void SetId(const QUuid &newId);
|
||||
|
||||
auto Size() const -> QSize;
|
||||
void SetSize(const QSize &newSize);
|
||||
|
||||
auto ErrorString() const -> const QString &;
|
||||
|
||||
auto Matrix() const -> const QTransform &;
|
||||
void SetMatrix(const QTransform &newMatrix);
|
||||
|
||||
auto Type() const -> PatternImage;
|
||||
|
||||
auto BoundingRect() const -> QRectF;
|
||||
|
||||
auto Visible() const -> bool;
|
||||
void SetVisible(bool newVisible);
|
||||
|
||||
private:
|
||||
QUuid m_id{QUuid::createUuid()};
|
||||
QString m_contentType{};
|
||||
QByteArray m_contentData{};
|
||||
mutable QString m_errorString{};
|
||||
QString m_filePath{};
|
||||
QString m_name{};
|
||||
qreal m_zValue{0};
|
||||
QTransform m_matrix{};
|
||||
bool m_hold{false};
|
||||
bool m_visible{true};
|
||||
};
|
||||
|
||||
#endif // VBACKGROUNDPATTERNIMAGE_H
|
|
@ -39,34 +39,7 @@
|
|||
#include <QSize>
|
||||
#include <QFile>
|
||||
|
||||
namespace
|
||||
{
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto IsMimeTypeImage(const QMimeType &mime) -> bool
|
||||
{
|
||||
QStringList aliases = mime.aliases();
|
||||
aliases.prepend(mime.name());
|
||||
|
||||
QRegularExpression rx(QStringLiteral("^image\\/[-\\w]+(\\.[-\\w]+)*([+][-\\w]+)?$"));
|
||||
|
||||
return std::any_of(aliases.begin(), aliases.end(), [rx](const QString &name) { return rx.match(name).hasMatch(); });
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto SplitString(QString str) -> QStringList
|
||||
{
|
||||
QStringList list;
|
||||
|
||||
const int n = 80;
|
||||
while (not str.isEmpty())
|
||||
{
|
||||
list.append(str.left(n));
|
||||
str.remove(0, n);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
} // namespace
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -140,19 +113,6 @@ auto VPatternImage::IsValid() const -> bool
|
|||
QSet<QString> aliases = mime.aliases().toSet();
|
||||
aliases.insert(mime.name());
|
||||
|
||||
QSet<QString> gzipMime {"application/gzip", "application/x-gzip"};
|
||||
|
||||
if (gzipMime.contains(aliases))
|
||||
{
|
||||
QSvgRenderer render(QByteArray::fromBase64(m_contentData));
|
||||
if (render.isValid())
|
||||
{
|
||||
mime = QMimeDatabase().mimeTypeForName(QStringLiteral("image/svg+xml-compressed"));
|
||||
aliases = mime.aliases().toSet();
|
||||
aliases.insert(mime.name());
|
||||
}
|
||||
}
|
||||
|
||||
if (not aliases.contains(m_contentType))
|
||||
{
|
||||
m_errorString = tr("Content type mistmatch.");
|
||||
|
@ -202,7 +162,7 @@ auto VPatternImage::ErrorString() const -> const QString &
|
|||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPatternImage::MimeTypeFromData() const -> QMimeType
|
||||
{
|
||||
return QMimeDatabase().mimeTypeForData(QByteArray::fromBase64(m_contentData));
|
||||
return MimeTypeFromByteArray(QByteArray::fromBase64(m_contentData));
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
|
|
@ -31,7 +31,6 @@
|
|||
#include <QString>
|
||||
#include <QCoreApplication>
|
||||
|
||||
|
||||
class QPixmap;
|
||||
class QMimeType;
|
||||
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
# This need for corect working file translations.pro
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/utils.h \
|
||||
$$PWD/vabstractconverter.h \
|
||||
$$PWD/vbackgroundpatternimage.h \
|
||||
$$PWD/vdomdocument.h \
|
||||
$$PWD/vlayoutconverter.h \
|
||||
$$PWD/vpatternconverter.h \
|
||||
|
@ -16,7 +18,9 @@ HEADERS += \
|
|||
$$PWD/vwatermarkconverter.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/utils.cpp \
|
||||
$$PWD/vabstractconverter.cpp \
|
||||
$$PWD/vbackgroundpatternimage.cpp \
|
||||
$$PWD/vdomdocument.cpp \
|
||||
$$PWD/vlayoutconverter.cpp \
|
||||
$$PWD/vpatternconverter.cpp \
|
||||
|
|
|
@ -299,7 +299,7 @@ QDomElement VPatternRecipe::Draft(const QDomElement &draft)
|
|||
QDomElement VPatternRecipe::Step(const VToolRecord &tool, const VContainer &data)
|
||||
{
|
||||
// This check helps to find missed tools in the switch
|
||||
Q_STATIC_ASSERT_X(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 55, "Not all tools were used in history.");
|
||||
Q_STATIC_ASSERT_X(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 59, "Not all tools were used in history.");
|
||||
|
||||
const QDomElement domElem = m_pattern->elementById(tool.getId());
|
||||
if (not domElem.isElement() && tool.IsMandatory())
|
||||
|
@ -320,6 +320,10 @@ QT_WARNING_DISABLE_GCC("-Wswitch-default")
|
|||
case Tool::Cut:
|
||||
case Tool::Midpoint:// Same as Tool::AlongLine, but tool will never has such type
|
||||
case Tool::ArcIntersectAxis:// Same as Tool::CurveIntersectAxis, but tool will never has such type
|
||||
case Tool::BackgroundImage:
|
||||
case Tool::BackgroundImageControls:
|
||||
case Tool::BackgroundPixmapImage:
|
||||
case Tool::BackgroundSVGImage:
|
||||
case Tool::LAST_ONE_DO_NOT_USE:
|
||||
Q_UNREACHABLE(); //-V501
|
||||
break;
|
||||
|
|
|
@ -205,6 +205,10 @@ enum class Tool : ToolVisHolderType
|
|||
InsertNode,
|
||||
PlaceLabel,
|
||||
DuplicateDetail,
|
||||
BackgroundImage,
|
||||
BackgroundImageControls,
|
||||
BackgroundPixmapImage,
|
||||
BackgroundSVGImage,
|
||||
LAST_ONE_DO_NOT_USE //add new stuffs above this, this constant must be last and never used
|
||||
};
|
||||
|
||||
|
|
|
@ -48,4 +48,13 @@ void qAsConst(const T &&) Q_DECL_EQ_DELETE;
|
|||
Class &operator=(const Class &) Q_DECL_EQ_DELETE;
|
||||
#endif
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 13, 0)
|
||||
#define Q_DISABLE_MOVE(Class) \
|
||||
Class(Class &&) = delete; \
|
||||
Class &operator=(Class &&) = delete;
|
||||
#define Q_DISABLE_COPY_MOVE(Class) \
|
||||
Q_DISABLE_COPY(Class) \
|
||||
Q_DISABLE_MOVE(Class)
|
||||
#endif
|
||||
|
||||
#endif // DEFGLOBAL_H
|
||||
|
|
|
@ -94,5 +94,58 @@
|
|||
<file>icon/24x24/close.png</file>
|
||||
<file>icon/24x24/close@2x.png</file>
|
||||
<file>icon/layout.png</file>
|
||||
<file>icon/32x32/rotate-top-left-hover@2x.png</file>
|
||||
<file>icon/32x32/rotate-top-left-hover.png</file>
|
||||
<file>icon/32x32/rotate-top-left@2x.png</file>
|
||||
<file>icon/32x32/rotate-top-left.png</file>
|
||||
<file>icon/32x32/rotate-top-right-hover@2x.png</file>
|
||||
<file>icon/32x32/rotate-top-right-hover.png</file>
|
||||
<file>icon/32x32/rotate-top-right@2x.png</file>
|
||||
<file>icon/32x32/rotate-top-right.png</file>
|
||||
<file>icon/32x32/rotate-bottom-right-hover@2x.png</file>
|
||||
<file>icon/32x32/rotate-bottom-right-hover.png</file>
|
||||
<file>icon/32x32/rotate-bottom-right@2x.png</file>
|
||||
<file>icon/32x32/rotate-bottom-right.png</file>
|
||||
<file>icon/32x32/rotate-bottom-left-hover@2x.png</file>
|
||||
<file>icon/32x32/rotate-bottom-left-hover.png</file>
|
||||
<file>icon/32x32/rotate-bottom-left@2x.png</file>
|
||||
<file>icon/32x32/rotate-bottom-left.png</file>
|
||||
<file>icon/32x32/expand2-hover@2x.png</file>
|
||||
<file>icon/32x32/expand2-hover.png</file>
|
||||
<file>icon/32x32/expand2@2x.png</file>
|
||||
<file>icon/32x32/expand2.png</file>
|
||||
<file>icon/32x32/expand1-hover@2x.png</file>
|
||||
<file>icon/32x32/expand1-hover.png</file>
|
||||
<file>icon/32x32/expand1@2x.png</file>
|
||||
<file>icon/32x32/expand1.png</file>
|
||||
<file>icon/32x32/double-arrow-vertical-hover@2x.png</file>
|
||||
<file>icon/32x32/double-arrow-vertical-hover.png</file>
|
||||
<file>icon/32x32/double-arrow-vertical@2x.png</file>
|
||||
<file>icon/32x32/double-arrow-vertical.png</file>
|
||||
<file>icon/32x32/double-arrow-horizontal-hover@2x.png</file>
|
||||
<file>icon/32x32/double-arrow-horizontal@2x.png</file>
|
||||
<file>icon/32x32/double-arrow-horizontal-hover.png</file>
|
||||
<file>icon/32x32/double-arrow-horizontal.png</file>
|
||||
<file>icon/svg/broken_path.svg</file>
|
||||
<file>icon/16x16/not_hold_image@2x.png</file>
|
||||
<file>icon/16x16/not_hold_image.png</file>
|
||||
<file>icon/16x16/hold_image@2x.png</file>
|
||||
<file>icon/16x16/hold_image.png</file>
|
||||
<file>icon/32x32/rotate-top-right-disabled@2x.png</file>
|
||||
<file>icon/32x32/rotate-top-right-disabled.png</file>
|
||||
<file>icon/32x32/rotate-top-left-disabled@2x.png</file>
|
||||
<file>icon/32x32/rotate-top-left-disabled.png</file>
|
||||
<file>icon/32x32/rotate-bottom-right-disabled@2x.png</file>
|
||||
<file>icon/32x32/rotate-bottom-right-disabled.png</file>
|
||||
<file>icon/32x32/rotate-bottom-left-disabled@2x.png</file>
|
||||
<file>icon/32x32/rotate-bottom-left-disabled.png</file>
|
||||
<file>icon/32x32/expand2-disabled@2x.png</file>
|
||||
<file>icon/32x32/expand2-disabled.png</file>
|
||||
<file>icon/32x32/expand1-disabled@2x.png</file>
|
||||
<file>icon/32x32/expand1-disabled.png</file>
|
||||
<file>icon/32x32/double-arrow-vertical-disabled@2x.png</file>
|
||||
<file>icon/32x32/double-arrow-vertical-disabled.png</file>
|
||||
<file>icon/32x32/double-arrow-horizontal-disabled@2x.png</file>
|
||||
<file>icon/32x32/double-arrow-horizontal-disabled.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
BIN
src/libs/vmisc/share/resources/icon/16x16/hold_image.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
src/libs/vmisc/share/resources/icon/16x16/hold_image@2x.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
src/libs/vmisc/share/resources/icon/16x16/not_hold_image.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
src/libs/vmisc/share/resources/icon/16x16/not_hold_image@2x.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 5.0 KiB |
After Width: | Height: | Size: 634 B |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 310 B |
After Width: | Height: | Size: 501 B |
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 5.5 KiB |
After Width: | Height: | Size: 758 B |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 316 B |
After Width: | Height: | Size: 575 B |
BIN
src/libs/vmisc/share/resources/icon/32x32/expand1-disabled.png
Normal file
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 7.1 KiB |
BIN
src/libs/vmisc/share/resources/icon/32x32/expand1-hover.png
Normal file
After Width: | Height: | Size: 3.8 KiB |
BIN
src/libs/vmisc/share/resources/icon/32x32/expand1-hover@2x.png
Normal file
After Width: | Height: | Size: 7.2 KiB |
BIN
src/libs/vmisc/share/resources/icon/32x32/expand1.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
src/libs/vmisc/share/resources/icon/32x32/expand1@2x.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
src/libs/vmisc/share/resources/icon/32x32/expand2-disabled.png
Normal file
After Width: | Height: | Size: 3.7 KiB |
After Width: | Height: | Size: 7.2 KiB |
BIN
src/libs/vmisc/share/resources/icon/32x32/expand2-hover.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
src/libs/vmisc/share/resources/icon/32x32/expand2-hover@2x.png
Normal file
After Width: | Height: | Size: 3.2 KiB |
BIN
src/libs/vmisc/share/resources/icon/32x32/expand2.png
Normal file
After Width: | Height: | Size: 484 B |
BIN
src/libs/vmisc/share/resources/icon/32x32/expand2@2x.png
Normal file
After Width: | Height: | Size: 899 B |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 6.2 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 2.5 KiB |
BIN
src/libs/vmisc/share/resources/icon/32x32/rotate-bottom-left.png
Normal file
After Width: | Height: | Size: 609 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 6.2 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 599 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 6.0 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 2.3 KiB |
BIN
src/libs/vmisc/share/resources/icon/32x32/rotate-top-left.png
Normal file
After Width: | Height: | Size: 612 B |
BIN
src/libs/vmisc/share/resources/icon/32x32/rotate-top-left@2x.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 6.2 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 2.5 KiB |
BIN
src/libs/vmisc/share/resources/icon/32x32/rotate-top-right.png
Normal file
After Width: | Height: | Size: 606 B |
After Width: | Height: | Size: 1.2 KiB |
1
src/libs/vmisc/share/resources/icon/svg/broken_path.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg id="Capa_1" enable-background="new 0 0 512 512" height="512" viewBox="0 0 512 512" width="512" xmlns="http://www.w3.org/2000/svg"><g><g><path d="m502.681 198.27v68.85l-2.48 1.68-24.29 16.48-58.97-40-58.97 40-58.97-40-58.97 40-58.96-40-58.97 40-26.76-18.15v-219.75c0-22.03 17.85-39.88 39.87-39.88h176.7c15.88 0 67.31 43.85 112.77 90.03 41.48 42.15 78 86.24 78 100.74z" fill="#ddeafb"/><path d="m475.911 332.15 26.77-18.16v150.63c0 22.03-17.85 39.88-39.87 39.88h-327.6c-18.82 0-34.59-13.04-38.78-30.58l-.16-22.8-.93-135.78v-1.34l26.76 18.15 58.97-40 58.96 40 58.97-40 58.97 40 58.97-40z" fill="#ddeafb"/><path d="m502.681 198.27v68.85l-2.48 1.68c-15.77-94.08-100.61-101.12-129.94-130.45l54.42-40.82c41.48 42.15 78 86.24 78 100.74z" fill="#cbe2ff"/><path d="m311.906 7.5h-97.57c.11 0 .22.01.34.01 119.72 3 125.26 100.52 157.15 132.41l40.82-54.42c-42.15-41.48-86.24-78-100.74-78z" fill="#cbe2ff"/><path d="m502.681 198.276v16.868c0-35.514-28.798-64.312-64.312-64.312h-39.143c-22.019 0-39.877-17.858-39.877-39.877v-39.143c0-35.514-28.798-64.312-64.312-64.312h16.868c30.373 0 59.512 12.068 80.989 33.545l76.242 76.242c21.476 21.476 33.545 50.615 33.545 80.989z" fill="#bed8fb"/><circle cx="96.445" cy="141.864" fill="#dd636e" r="87.126"/><path d="m107.749 228.264c-3.7.48-7.48.73-11.31.73-48.12 0-87.12-39.01-87.12-87.13 0-48.11 39-87.12 87.12-87.12 3.83 0 7.61.25 11.31.73-42.78 5.54-75.82 42.11-75.82 86.39 0 44.29 33.04 80.86 75.82 86.4z" fill="#da4a54"/></g><g><path d="m510.181 198.276c0-32.598-12.693-63.244-35.741-86.292l-76.242-76.242c-23.05-23.049-53.695-35.742-86.293-35.742h-.006-176.7c-26.12 0-47.37 21.255-47.37 47.38v.257c-48.153 4.369-86.01 44.956-86.01 94.223 0 49.273 37.856 89.864 86.01 94.233v31.027c0 2.486 1.232 4.811 3.29 6.207l26.769 18.16c2.543 1.725 5.88 1.724 8.421 0l54.761-37.144 54.749 37.144c2.543 1.725 5.88 1.724 8.421 0l54.76-37.144 54.76 37.144c2.541 1.725 5.879 1.724 8.42 0l54.761-37.144 54.76 37.144c1.271.862 2.74 1.293 4.21 1.293s2.939-.431 4.21-1.293l26.76-18.15c2.058-1.396 3.29-3.721 3.29-6.207zm-122.591-151.928 76.242 76.242c12.185 12.184 21.069 26.788 26.205 42.729-13.069-13.549-31.401-21.988-51.669-21.988h-39.143c-17.853 0-32.377-14.524-32.377-32.377v-39.142c0-20.268-8.438-38.599-21.987-51.669 15.942 5.137 30.545 14.021 42.729 26.205zm88.319 229.87-54.76-37.144c-2.541-1.724-5.879-1.724-8.42 0l-54.761 37.144-54.76-37.144c-2.541-1.724-5.879-1.724-8.42 0l-54.76 37.144-54.749-37.144c-2.543-1.725-5.88-1.724-8.421 0l-54.761 37.144-19.27-13.072v-26.876c49.21-3.293 88.24-44.375 88.24-94.41 0-29.062-13.078-56.098-35.881-74.177-3.244-2.573-7.963-2.029-10.536 1.218-2.573 3.246-2.028 7.963 1.218 10.536 19.191 15.217 30.199 37.969 30.199 62.423 0 43.908-35.718 79.63-79.62 79.63-43.908 0-79.63-35.722-79.63-79.63 0-43.903 35.722-79.62 79.63-79.62 7.619 0 15.133 1.069 22.331 3.177 3.979 1.166 8.142-1.115 9.306-5.089 1.165-3.975-1.114-8.141-5.089-9.306-6.547-1.918-13.307-3.107-20.168-3.564v-.078c0-17.854 14.521-32.38 32.37-32.38h159.838c31.326 0 56.812 25.486 56.812 56.812v39.143c0 26.124 21.253 47.377 47.377 47.377h39.143c31.171 0 56.551 25.237 56.801 56.35v48.472z"/><path d="m507.608 308.351c-2.641-2.287-6.383-2.434-9.149-.558l-22.55 15.294-54.76-37.144c-2.541-1.725-5.878-1.724-8.421 0l-19.519 13.243c-3.399 2.306-4.586 6.937-2.382 10.403 2.279 3.586 7.05 4.555 10.543 2.187l15.569-10.563 54.76 37.144c2.541 1.725 5.879 1.724 8.42 0l15.05-10.208v136.471c0 17.883-14.497 32.38-32.38 32.38h-327.59c-.462 0-.921-.01-1.379-.029-16.775-.699-29.846-14.883-29.961-31.673l-.941-137.098 14.97 10.156c2.543 1.725 5.88 1.724 8.421 0l54.761-37.144 54.749 37.144c2.543 1.725 5.88 1.724 8.421 0l54.76-37.144 54.76 37.144c2.54 1.724 5.877 1.724 8.419.001l11.172-7.575c3.399-2.304 4.586-6.933 2.384-10.399-2.279-3.587-7.052-4.559-10.543-2.192l-7.221 4.896-54.761-37.145c-2.541-1.724-5.879-1.724-8.42 0l-54.76 37.144-54.749-37.144c-2.543-1.725-5.88-1.724-8.421 0l-54.761 37.144-22.379-15.18c-1.84-1.248-4.138-1.747-6.287-1.175-3.377.899-5.604 3.914-5.604 7.259v1.402l1.09 154.58c0 17.853 14.019 42.029 46.28 42.029h327.6c26.162 0 47.37-21.208 47.37-47.37v-150.416c0-2.225-.879-4.407-2.561-5.864z"/><path d="m131.2 96.501-34.755 34.755-34.756-34.755c-2.93-2.929-7.678-2.929-10.607 0s-2.929 7.677 0 10.606l34.756 34.756-34.756 34.757c-2.929 2.929-2.929 7.677 0 10.606 1.465 1.465 3.385 2.197 5.304 2.197s3.839-.732 5.304-2.197l34.755-34.755 34.755 34.755c1.465 1.465 3.385 2.197 5.304 2.197s3.839-.732 5.304-2.197c2.929-2.929 2.929-7.677 0-10.606l-34.756-34.756 34.756-34.756c2.929-2.929 2.929-7.677 0-10.606-2.93-2.93-7.678-2.93-10.608-.001z"/></g></g></svg>
|
After Width: | Height: | Size: 4.5 KiB |
|
@ -92,6 +92,8 @@ Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingDockWidgetToolOptionsActive,
|
|||
(QLatin1String("dockWidget/toolOptionsActive")))
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingDockWidgetPatternMessagesActive,
|
||||
(QLatin1String("dockWidget/patternMessagesActive")))
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingDockWidgetBackgroundImagesActive,
|
||||
(QLatin1String("dockWidget/backgroundImagesActive")))
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingPatternMessagesFontSize, (QLatin1String("font/patternMessagesSize")))
|
||||
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingSearchHistoryHistory, (QLatin1String("searchHistory/history")))
|
||||
|
@ -621,6 +623,24 @@ void VValentinaSettings::SetDockWidgetPatternMessagesActive(bool value)
|
|||
setValue(*settingDockWidgetPatternMessagesActive, value);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
bool VValentinaSettings::IsDockWidgetBackgroundImagesActive() const
|
||||
{
|
||||
return value(*settingDockWidgetBackgroundImagesActive, GetDefDockWidgetBackgroundImagesActive()).toBool();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
bool VValentinaSettings::GetDefDockWidgetBackgroundImagesActive()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VValentinaSettings::SetDockWidgetBackgroundImagesActive(bool value)
|
||||
{
|
||||
setValue(*settingDockWidgetBackgroundImagesActive, value);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
int VValentinaSettings::GetPatternMessageFontSize(int fontSizeDef) const
|
||||
{
|
||||
|
|
|
@ -153,6 +153,10 @@ public:
|
|||
static bool GetDefDockWidgetPatternMessagesActive();
|
||||
void SetDockWidgetPatternMessagesActive(bool value);
|
||||
|
||||
bool IsDockWidgetBackgroundImagesActive() const;
|
||||
static bool GetDefDockWidgetBackgroundImagesActive();
|
||||
void SetDockWidgetBackgroundImagesActive(bool value);
|
||||
|
||||
int GetPatternMessageFontSize(int fontSizeDef) const;
|
||||
static int GetDefMinPatternMessageFontSize();
|
||||
static int GetDefMaxPatternMessageFontSize();
|
||||
|
|
|
@ -20,61 +20,95 @@
|
|||
|
||||
#include "vboolproperty.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QCoreApplication>
|
||||
#include <QFlags>
|
||||
#include <QObject>
|
||||
|
||||
#include "../vproperty_p.h"
|
||||
|
||||
|
||||
QVariant VPE::VBoolProperty::TrueText;
|
||||
QVariant VPE::VBoolProperty::FalseText;
|
||||
|
||||
VPE::VBoolProperty::VBoolProperty(const QString& name) :
|
||||
VProperty(name, QVariant::Bool)
|
||||
{
|
||||
d_ptr->VariantValue.setValue(false);
|
||||
d_ptr->VariantValue.convert(QVariant::Bool);
|
||||
|
||||
// I'm not sure, how Qt handles the translations...
|
||||
if (TrueText.isNull())
|
||||
{
|
||||
TrueText = tr("True");
|
||||
}
|
||||
if (FalseText.isNull())
|
||||
{
|
||||
FalseText = tr("False");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//! Get the data how it should be displayed
|
||||
QVariant VPE::VBoolProperty::data (int column, int role) const
|
||||
auto VPE::VBoolProperty::data (int column, int role) const -> QVariant
|
||||
{
|
||||
if (column == DPC_Data && (Qt::DisplayRole == role || Qt::EditRole == role))
|
||||
auto* tmpEditor = qobject_cast<QCheckBox*>(VProperty::d_ptr->editor);
|
||||
|
||||
if (column == DPC_Data && Qt::DisplayRole == role)
|
||||
{
|
||||
return d_ptr->VariantValue.toBool() ? TrueText : FalseText;
|
||||
return tmpEditor->checkState();
|
||||
}
|
||||
if (column == DPC_Data && Qt::CheckStateRole == role)
|
||||
|
||||
if (column == DPC_Data && Qt::EditRole == role)
|
||||
{
|
||||
return d_ptr->VariantValue.toBool() ? Qt::Checked : Qt::Unchecked;
|
||||
return VProperty::d_ptr->VariantValue;
|
||||
}
|
||||
else
|
||||
return VProperty::data(column, role);
|
||||
|
||||
return VProperty::data(column, role);
|
||||
}
|
||||
|
||||
bool VPE::VBoolProperty::setData(const QVariant &data, int role)
|
||||
auto VPE::VBoolProperty::createEditor(QWidget *parent, const QStyleOptionViewItem &options,
|
||||
const QAbstractItemDelegate *delegate) -> QWidget *
|
||||
{
|
||||
if (Qt::CheckStateRole == role)
|
||||
Q_UNUSED(options)
|
||||
Q_UNUSED(delegate)
|
||||
auto* tmpEditor = new QCheckBox(parent);
|
||||
tmpEditor->setCheckState(d_ptr->VariantValue.toBool() ? Qt::Checked : Qt::Unchecked);
|
||||
connect(tmpEditor, &QCheckBox::stateChanged, this, &VBoolProperty::StateChanged);
|
||||
|
||||
VProperty::d_ptr->editor = tmpEditor;
|
||||
return VProperty::d_ptr->editor;
|
||||
}
|
||||
|
||||
auto VPE::VBoolProperty::setEditorData(QWidget *editor) -> bool
|
||||
{
|
||||
if (!editor)
|
||||
{
|
||||
d_ptr->VariantValue = (Qt::Checked == static_cast<Qt::CheckState>(data.toInt()));
|
||||
return false;
|
||||
}
|
||||
|
||||
auto* tmpEditor = qobject_cast<QCheckBox*>(editor);
|
||||
if (tmpEditor)
|
||||
{
|
||||
tmpEditor->blockSignals(true);
|
||||
tmpEditor->setCheckState(d_ptr->VariantValue.toBool() ? Qt::Checked : Qt::Unchecked);
|
||||
tmpEditor->blockSignals(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
auto VPE::VBoolProperty::getEditorData(const QWidget *editor) const -> QVariant
|
||||
{
|
||||
const auto* tmpEditor = qobject_cast<const QCheckBox*>(editor);
|
||||
if (tmpEditor)
|
||||
{
|
||||
return tmpEditor->checkState() == Qt::Checked ? Qt::Checked : Qt::Unchecked;
|
||||
}
|
||||
|
||||
return {0};
|
||||
}
|
||||
|
||||
void VPE::VBoolProperty::setValue(const QVariant &value)
|
||||
{
|
||||
VProperty::d_ptr->VariantValue = value;
|
||||
VProperty::d_ptr->VariantValue.convert(QVariant::Bool);
|
||||
|
||||
if (VProperty::d_ptr->editor != nullptr)
|
||||
{
|
||||
setEditorData(VProperty::d_ptr->editor);
|
||||
}
|
||||
}
|
||||
|
||||
//! Returns item flags
|
||||
Qt::ItemFlags VPE::VBoolProperty::flags(int column) const
|
||||
auto VPE::VBoolProperty::flags(int column) const -> Qt::ItemFlags
|
||||
{
|
||||
if (column == DPC_Data)
|
||||
{
|
||||
|
@ -84,12 +118,18 @@ Qt::ItemFlags VPE::VBoolProperty::flags(int column) const
|
|||
return VProperty::flags(column);
|
||||
}
|
||||
|
||||
QString VPE::VBoolProperty::type() const
|
||||
auto VPE::VBoolProperty::type() const -> QString
|
||||
{
|
||||
return "bool";
|
||||
}
|
||||
|
||||
VPE::VProperty *VPE::VBoolProperty::clone(bool include_children, VProperty *container) const
|
||||
auto VPE::VBoolProperty::clone(bool include_children, VProperty *container) const -> VPE::VProperty *
|
||||
{
|
||||
return VProperty::clone(include_children, container ? container : new VBoolProperty(getName()));
|
||||
}
|
||||
|
||||
void VPE::VBoolProperty::StateChanged()
|
||||
{
|
||||
auto *event = new UserChangeEvent();
|
||||
QCoreApplication::postEvent ( VProperty::d_ptr->editor, event );
|
||||
}
|
||||
|
|
|
@ -48,36 +48,43 @@ public:
|
|||
explicit VBoolProperty(const QString& name);
|
||||
|
||||
//! Destructor
|
||||
virtual ~VBoolProperty() override {}
|
||||
~VBoolProperty() override = default;
|
||||
|
||||
//! Get the data how it should be displayed
|
||||
virtual QVariant data (int column = DPC_Name, int role = Qt::DisplayRole) const override;
|
||||
auto data(int column = DPC_Name, int role = Qt::DisplayRole) const -> QVariant override;
|
||||
|
||||
//! This is used by the model to set the data
|
||||
//! \param data The data to set
|
||||
//! \param role The role. Default is Qt::EditRole
|
||||
//! \return Returns true, if the data was changed, false if not.
|
||||
virtual bool setData (const QVariant& data, int role = Qt::EditRole) override;
|
||||
//! Returns an editor widget, or NULL if it doesn't supply one
|
||||
//! \param parent The widget to which the editor will be added as a child
|
||||
//! \options Render options
|
||||
//! \delegate A pointer to the QAbstractItemDelegate requesting the editor. This can be used to connect signals and
|
||||
//! slots.
|
||||
auto createEditor(QWidget* parent, const QStyleOptionViewItem& options,
|
||||
const QAbstractItemDelegate* delegate) -> QWidget* override;
|
||||
|
||||
//! Sets the property's data to the editor (returns false, if the standard delegate should do that)
|
||||
auto setEditorData(QWidget* editor) -> bool override;
|
||||
|
||||
//! Gets the data from the widget
|
||||
auto getEditorData(const QWidget* editor) const -> QVariant override;
|
||||
|
||||
//! Sets the value of the property
|
||||
void setValue(const QVariant& value) override;
|
||||
|
||||
//! Returns item flags
|
||||
virtual Qt::ItemFlags flags(int column = DPC_Name) const override;
|
||||
auto flags(int column = DPC_Name) const -> Qt::ItemFlags override;
|
||||
|
||||
//! Returns a string containing the type of the property
|
||||
virtual QString type() const override;
|
||||
auto type() const -> QString override;
|
||||
|
||||
//! Clones this property
|
||||
//! \param include_children Indicates whether to also clone the children
|
||||
//! \param container If a property is being passed here, no new VProperty is being created but instead it is tried
|
||||
//! to fill all the data into container. This can also be used when subclassing this function.
|
||||
//! \return Returns the newly created property (or container, if it was not NULL)
|
||||
virtual VProperty* clone(bool include_children = true, VProperty* container = NULL) const override;
|
||||
auto clone(bool include_children = true, VProperty* container = NULL) const -> VProperty* override;
|
||||
|
||||
protected:
|
||||
//! The (translatable) text displayed when the property is set to true (default: "True")
|
||||
static QVariant TrueText;
|
||||
|
||||
//! The (translatable) text displayed when the property is set to false (default: "False")
|
||||
static QVariant FalseText;
|
||||
public slots:
|
||||
void StateChanged();
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(VBoolProperty)
|
||||
|
@ -85,6 +92,6 @@ private:
|
|||
|
||||
QT_WARNING_POP
|
||||
|
||||
}
|
||||
} // namespace VPE
|
||||
|
||||
#endif // VBOOLPROPERTY_H
|
||||
|
|
1895
src/libs/vtools/tools/backgroundimage/vbackgroundimagecontrols.cpp
Normal file
185
src/libs/vtools/tools/backgroundimage/vbackgroundimagecontrols.h
Normal file
|
@ -0,0 +1,185 @@
|
|||
/************************************************************************
|
||||
**
|
||||
** @file vbackgroundimagecontrols.h
|
||||
** @author Roman Telezhynskyi <dismine(at)gmail.com>
|
||||
** @date 17 1, 2022
|
||||
**
|
||||
** @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) 2022 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 VBACKGROUNDIMAGECONTROLS_H
|
||||
#define VBACKGROUNDIMAGECONTROLS_H
|
||||
|
||||
#include <QGraphicsObject>
|
||||
#include <QUuid>
|
||||
|
||||
#include "../vmisc/def.h"
|
||||
#include "../ifc/xml/vbackgroundpatternimage.h"
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 13, 0)
|
||||
#include "../vmisc/defglobal.h"
|
||||
#endif // QT_VERSION < QT_VERSION_CHECK(5, 13, 0)
|
||||
|
||||
class VAbstractPattern;
|
||||
class QScreen;
|
||||
|
||||
enum class BITransformationType {Scale, Rotate, Unknown};
|
||||
|
||||
enum class BIHandleCorner : int
|
||||
{
|
||||
Invalid,
|
||||
TopLeft,
|
||||
Top,
|
||||
TopRight,
|
||||
Right,
|
||||
BottomRight,
|
||||
Bottom,
|
||||
BottomLeft,
|
||||
Left
|
||||
};
|
||||
|
||||
enum class BIHandleCornerType
|
||||
{
|
||||
ScaleTopLeftBottomRight,
|
||||
ScaleTopBottom,
|
||||
ScaleTopRightBottomLeft,
|
||||
ScaleRightLeft,
|
||||
RotateTopLeft,
|
||||
RotateTopRight,
|
||||
RotateBottomRight,
|
||||
RotateBottomLeft
|
||||
};
|
||||
|
||||
class VBackgroundImageControls : public QGraphicsObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit VBackgroundImageControls(VAbstractPattern *doc, QGraphicsItem * parent = nullptr);
|
||||
~VBackgroundImageControls() override = default;
|
||||
|
||||
auto type() const -> int override {return Type;}
|
||||
enum { Type = UserType + static_cast<int>(Tool::BackgroundImageControls)};
|
||||
|
||||
auto Id() const -> const QUuid &;
|
||||
|
||||
signals:
|
||||
void ActiveImageChanged(const QUuid &id);
|
||||
|
||||
public slots:
|
||||
void ActivateControls(const QUuid &id);
|
||||
void DeactivateControls(QGraphicsItem* pItem);
|
||||
void UpdateControls();
|
||||
|
||||
protected:
|
||||
auto boundingRect() const -> QRectF override;
|
||||
auto shape() const -> QPainterPath override;
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
|
||||
|
||||
void mousePressEvent(QGraphicsSceneMouseEvent * event) override;
|
||||
void mouseMoveEvent(QGraphicsSceneMouseEvent * event) override;
|
||||
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
|
||||
void hoverEnterEvent(QGraphicsSceneHoverEvent *event) override;
|
||||
void hoverMoveEvent(QGraphicsSceneHoverEvent *event) override;
|
||||
void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) override;
|
||||
|
||||
private slots:
|
||||
void ScreenChanged();
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY_MOVE(VBackgroundImageControls)
|
||||
|
||||
QUuid m_id{};
|
||||
VAbstractPattern *m_doc;
|
||||
VBackgroundPatternImage m_image{};
|
||||
BITransformationType m_tranformationType{BITransformationType::Unknown};
|
||||
|
||||
QMap<BIHandleCornerType, QPixmap> m_handlePixmaps{};
|
||||
QMap<BIHandleCornerType, QPixmap> m_handleHoverPixmaps{};
|
||||
QMap<BIHandleCornerType, QPixmap> m_handleDisabledPixmaps{};
|
||||
QMap<BIHandleCornerType, QPainterPath> m_handlePaths{};
|
||||
|
||||
BIHandleCorner m_handleCornerHover{BIHandleCorner::Invalid};
|
||||
|
||||
bool m_controlsVisible{true};
|
||||
bool m_allowChangeMerge{false};
|
||||
bool m_transformationApplied{false};
|
||||
|
||||
QPointF m_scaleDiff{};
|
||||
QTransform m_originalMatrix{};
|
||||
QRectF m_imageBoundingRect{};
|
||||
QRectF m_imageScreenBoundingRect{};
|
||||
QPointF m_rotationStartPoint{};
|
||||
|
||||
bool m_showOrigin{false};
|
||||
QPointF m_originPos{};
|
||||
|
||||
void InitPixmaps();
|
||||
|
||||
auto TopLeftHandlerPosition() const -> QPointF;
|
||||
auto TopHandlerPosition() const -> QPointF;
|
||||
auto TopRightHandlerPosition() const -> QPointF;
|
||||
auto RightHandlerPosition() const -> QPointF;
|
||||
auto BottomRightHandlerPosition() const -> QPointF;
|
||||
auto BottomHandlerPosition() const -> QPointF;
|
||||
auto BottomLeftHandlerPosition() const -> QPointF;
|
||||
auto LeftHandlerPosition() const -> QPointF;
|
||||
|
||||
auto ControllerPath(BIHandleCornerType type, QPointF pos) const -> QPainterPath;
|
||||
auto ScaleTopLeftControl() const -> QPainterPath;
|
||||
auto ScaleTopControl() const -> QPainterPath;
|
||||
auto ScaleTopRightControl() const -> QPainterPath;
|
||||
auto ScaleRightControl() const -> QPainterPath;
|
||||
auto ScaleBottomRightControl() const -> QPainterPath;
|
||||
auto ScaleBottomControl() const -> QPainterPath;
|
||||
auto ScaleBottomLeftControl() const -> QPainterPath;
|
||||
auto ScaleLeftControl() const -> QPainterPath;
|
||||
|
||||
auto RotateTopLeftControl() const -> QPainterPath;
|
||||
auto RotateTopRightControl() const -> QPainterPath;
|
||||
auto RotateBottomRightControl() const -> QPainterPath;
|
||||
auto RotateBottomLeftControl() const -> QPainterPath;
|
||||
|
||||
auto ScaleByTopLeft(QGraphicsSceneMouseEvent * event) const -> QTransform;
|
||||
auto ScaleByTop(QGraphicsSceneMouseEvent * event) const -> QTransform;
|
||||
auto ScaleByTopRight(QGraphicsSceneMouseEvent * event) const -> QTransform;
|
||||
auto ScaleByRight(QGraphicsSceneMouseEvent * event) const -> QTransform;
|
||||
auto ScaleByBottomRight(QGraphicsSceneMouseEvent * event) const -> QTransform;
|
||||
auto ScaleByBottom(QGraphicsSceneMouseEvent * event) const -> QTransform;
|
||||
auto ScaleByBottomLeft(QGraphicsSceneMouseEvent * event) const -> QTransform;
|
||||
auto ScaleByLeft(QGraphicsSceneMouseEvent * event) const -> QTransform;
|
||||
|
||||
auto Handles() const -> QPainterPath;
|
||||
auto ControllersRect() const -> QRectF;
|
||||
|
||||
auto SelectedHandleCorner(const QPointF &pos) const -> BIHandleCorner;
|
||||
|
||||
auto HandlerPixmap(bool hover, BIHandleCornerType type) const -> QPixmap;
|
||||
|
||||
void ShowOrigin(const QPointF &pos);
|
||||
auto OriginCircle1() const -> QPainterPath;
|
||||
auto OriginCircle2() const -> QPainterPath;
|
||||
auto OriginPath() const -> QPainterPath;
|
||||
|
||||
void ScaleImage(QGraphicsSceneMouseEvent * event);
|
||||
void RotateImage(QGraphicsSceneMouseEvent * event);
|
||||
};
|
||||
|
||||
#endif // VBACKGROUNDIMAGECONTROLS_H
|
734
src/libs/vtools/tools/backgroundimage/vbackgroundimageitem.cpp
Normal file
|
@ -0,0 +1,734 @@
|
|||
/************************************************************************
|
||||
**
|
||||
** @file vbackgroundimageitem.cpp
|
||||
** @author Roman Telezhynskyi <dismine(at)gmail.com>
|
||||
** @date 13 1, 2022
|
||||
**
|
||||
** @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) 2022 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 "vbackgroundimageitem.h"
|
||||
#include "../vwidgets/global.h"
|
||||
#include "../vmisc/vabstractvalapplication.h"
|
||||
#include "../vwidgets/vmaingraphicsview.h"
|
||||
#include "../ifc/xml/vabstractpattern.h"
|
||||
#include "../../undocommands/image/movebackgroundimage.h"
|
||||
#include "../../undocommands/image/holdbackgroundimage.h"
|
||||
#include "../../undocommands/image/rotatebackgroundimage.h"
|
||||
#include "../../undocommands/image/scalebackgroundimage.h"
|
||||
#include "../../undocommands/image/renamebackgroundimage.h"
|
||||
#include "../../undocommands/image/hidebackgroundimage.h"
|
||||
#include "../../undocommands/image/resetbackgroundimage.h"
|
||||
#include "../toolsdef.h"
|
||||
|
||||
#include <QUndoStack>
|
||||
#include <QGraphicsView>
|
||||
#include <QGraphicsSceneMouseEvent>
|
||||
#include <QMenu>
|
||||
#include <QGraphicsDropShadowEffect>
|
||||
#include <QMessageBox>
|
||||
#include <QKeyEvent>
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VBackgroundImageItem::VBackgroundImageItem(const VBackgroundPatternImage &image, VAbstractPattern *doc,
|
||||
QGraphicsItem *parent)
|
||||
: QGraphicsObject{parent},
|
||||
m_image(image),
|
||||
m_doc(doc)
|
||||
{
|
||||
SCASSERT(doc != nullptr)
|
||||
|
||||
setAcceptHoverEvents(true);
|
||||
|
||||
connect(doc, &VAbstractPattern::BackgroundImageTransformationChanged, this,
|
||||
&VBackgroundImageItem::ImageTransformationChanged);
|
||||
connect(doc, &VAbstractPattern::BackgroundImageHoldChanged, this, &VBackgroundImageItem::HoldChanged);
|
||||
connect(doc, &VAbstractPattern::BackgroundImageVisibilityChanged, this, &VBackgroundImageItem::VisibilityChanged);
|
||||
connect(doc, &VAbstractPattern::BackgroundImageNameChanged, this, &VBackgroundImageItem::NameChanged);
|
||||
connect(doc, &VAbstractPattern::BackgroundImagesHoldChanged, this, &VBackgroundImageItem::UpdateHoldState);
|
||||
connect(doc, &VAbstractPattern::BackgroundImagesVisibilityChanged, this,
|
||||
&VBackgroundImageItem::UpdateVisibilityState);
|
||||
connect(doc, &VAbstractPattern::BackgroundImagesZValueChanged, this, &VBackgroundImageItem::ZValueChanged);
|
||||
connect(doc, &VAbstractPattern::BackgroundImagePositionChanged, this, &VBackgroundImageItem::PositionChanged);
|
||||
|
||||
InitImage();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VBackgroundImageItem::Image() const -> const VBackgroundPatternImage &
|
||||
{
|
||||
return m_image;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VBackgroundImageItem::SetImage(const VBackgroundPatternImage &newImage)
|
||||
{
|
||||
prepareGeometryChange();
|
||||
m_image = newImage;
|
||||
InitImage();
|
||||
m_stale = true;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VBackgroundImageItem::pen() -> QPen
|
||||
{
|
||||
return {QBrush(), 1.0};
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VBackgroundImageItem::name() const -> QString
|
||||
{
|
||||
return m_image.Name();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VBackgroundImageItem::setName(const QString &newName)
|
||||
{
|
||||
VAbstractApplication::VApp()->getUndoStack()->push(new RenameBackgroundImage(m_image.Id(), newName, m_doc));
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VBackgroundImageItem::IsHold() const -> bool
|
||||
{
|
||||
return m_image.Hold();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VBackgroundImageItem::SetHold(bool hold)
|
||||
{
|
||||
VAbstractApplication::VApp()->getUndoStack()->push(new HoldBackgroundImage(m_image.Id(), hold, m_doc));
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VBackgroundImageItem::IsVisible() const -> bool
|
||||
{
|
||||
return m_image.Visible();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VBackgroundImageItem::SetVisible(bool visible)
|
||||
{
|
||||
VAbstractApplication::VApp()->getUndoStack()->push(new HideBackgroundImage(m_image.Id(), not visible, m_doc));
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VBackgroundImageItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
||||
{
|
||||
Q_UNUSED(option)
|
||||
Q_UNUSED(widget)
|
||||
|
||||
if (m_showHover)
|
||||
{
|
||||
painter->save();
|
||||
|
||||
QBrush brush(QColor(177, 216, 250, 25));
|
||||
painter->setBrush(brush);
|
||||
|
||||
painter->drawRect(boundingRect());
|
||||
|
||||
painter->restore();
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VBackgroundImageItem::PositionChanged(QUuid id)
|
||||
{
|
||||
if (m_image.Id() != id)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QTransform oldMatrix = m_image.Matrix();
|
||||
m_image = m_doc->GetBackgroundImage(id);
|
||||
QTransform newMatrix = m_image.Matrix();
|
||||
|
||||
if (not VFuzzyComparePossibleNulls(oldMatrix.m31(), newMatrix.m31()) ||
|
||||
not VFuzzyComparePossibleNulls(oldMatrix.m32(), newMatrix.m32()))
|
||||
{
|
||||
prepareGeometryChange();
|
||||
update();
|
||||
}
|
||||
|
||||
emit UpdateControls();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VBackgroundImageItem::ImageTransformationChanged(QUuid id)
|
||||
{
|
||||
if (m_image.Id() != id)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
prepareGeometryChange();
|
||||
m_image = m_doc->GetBackgroundImage(id);
|
||||
|
||||
emit UpdateControls();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VBackgroundImageItem::HoldChanged(QUuid id)
|
||||
{
|
||||
if (m_image.Id() != id)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateHoldState();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VBackgroundImageItem::VisibilityChanged(QUuid id)
|
||||
{
|
||||
if (m_image.Id() != id)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateVisibilityState();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VBackgroundImageItem::NameChanged(QUuid id)
|
||||
{
|
||||
if (m_image.Id() != id)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_image = m_doc->GetBackgroundImage(id);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VBackgroundImageItem::EnableSelection(bool enable)
|
||||
{
|
||||
m_selectable = enable;
|
||||
setFlag(QGraphicsItem::ItemSendsGeometryChanges, m_selectable && not m_image.Hold());
|
||||
setFlag(QGraphicsItem::ItemIsFocusable, m_selectable && not m_image.Hold());
|
||||
|
||||
if (not m_selectable)
|
||||
{
|
||||
emit ActivateControls(QUuid());
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VBackgroundImageItem::DeleteFromMenu()
|
||||
{
|
||||
DeleteToolWithConfirm();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VBackgroundImageItem::itemChange(GraphicsItemChange change, const QVariant &value) -> QVariant
|
||||
{
|
||||
if (change == ItemPositionChange && (scene() != nullptr))
|
||||
{
|
||||
// Each time we move something we call recalculation scene rect. In some cases this can cause moving
|
||||
// objects positions. And this cause infinite redrawing. That's why we wait the finish of saving the last move.
|
||||
static bool changeFinished = true;
|
||||
if (changeFinished)
|
||||
{
|
||||
changeFinished = false;
|
||||
|
||||
// value - this is new position.
|
||||
const QPointF newPos = value.toPointF();
|
||||
const QPointF diff = newPos - m_lastMoveDistance;
|
||||
|
||||
auto *command = new MoveBackgroundImage(m_image.Id(), diff.x(), diff.y(), m_doc, m_allowChangeMerge);
|
||||
VAbstractApplication::VApp()->getUndoStack()->push(command);
|
||||
|
||||
const QList<QGraphicsView *> viewList = scene()->views();
|
||||
if (not viewList.isEmpty())
|
||||
{
|
||||
if (auto *view = qobject_cast<VMainGraphicsView *>(viewList.at(0)))
|
||||
{
|
||||
view->EnsureItemVisibleWithDelay(this, VMainGraphicsView::scrollDelay);
|
||||
}
|
||||
}
|
||||
|
||||
changeFinished = true;
|
||||
m_lastMoveDistance = newPos;
|
||||
}
|
||||
return pos();
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VBackgroundImageItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
if (not m_selectable)
|
||||
{
|
||||
event->ignore();
|
||||
return;
|
||||
}
|
||||
|
||||
if (not Image().Hold())
|
||||
{
|
||||
if (flags() & QGraphicsItem::ItemIsMovable)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton && event->type() != QEvent::GraphicsSceneMouseDoubleClick)
|
||||
{
|
||||
SetItemOverrideCursor(this, cursorArrowCloseHand, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (event->button() == Qt::LeftButton && event->type() != QEvent::GraphicsSceneMouseDoubleClick)
|
||||
{
|
||||
m_lastMoveDistance = QPointF();
|
||||
emit Selected(m_image.Id());
|
||||
event->accept();
|
||||
}
|
||||
else
|
||||
{
|
||||
QGraphicsObject::mousePressEvent(event);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (event->button() == Qt::LeftButton && event->type() != QEvent::GraphicsSceneMouseDoubleClick)
|
||||
{
|
||||
emit ActivateControls(m_image.Id());
|
||||
}
|
||||
QGraphicsObject::mousePressEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VBackgroundImageItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
QGraphicsObject::mouseMoveEvent(event);
|
||||
m_allowChangeMerge = true;
|
||||
m_wasMoved = true;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VBackgroundImageItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton && event->type() != QEvent::GraphicsSceneMouseDoubleClick &&
|
||||
(flags() & QGraphicsItem::ItemIsMovable))
|
||||
{
|
||||
m_lastMoveDistance = QPointF();
|
||||
SetItemOverrideCursor(this, cursorArrowOpenHand, 1, 1);
|
||||
m_allowChangeMerge = false;
|
||||
if (not m_wasMoved && m_selectable)
|
||||
{
|
||||
emit ActivateControls(m_image.Id());
|
||||
}
|
||||
m_wasMoved = false;
|
||||
}
|
||||
|
||||
QGraphicsObject::mouseReleaseEvent(event);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VBackgroundImageItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
|
||||
{
|
||||
if (m_selectable && flags() & QGraphicsItem::ItemIsMovable)
|
||||
{
|
||||
m_showHover = true;
|
||||
SetItemOverrideCursor(this, cursorArrowOpenHand, 1, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
setCursor(VAbstractValApplication::VApp()->getSceneView()->viewport()->cursor());
|
||||
}
|
||||
QGraphicsObject::hoverEnterEvent(event);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VBackgroundImageItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
|
||||
{
|
||||
if (m_selectable && flags() & QGraphicsItem::ItemIsMovable)
|
||||
{
|
||||
SetItemOverrideCursor(this, cursorArrowOpenHand, 1, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
setCursor(VAbstractValApplication::VApp()->getSceneView()->viewport()->cursor());
|
||||
}
|
||||
QGraphicsObject::hoverMoveEvent(event);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VBackgroundImageItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
|
||||
{
|
||||
m_showHover = false;
|
||||
setCursor(VAbstractValApplication::VApp()->getSceneView()->viewport()->cursor());
|
||||
QGraphicsObject::hoverLeaveEvent(event);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VBackgroundImageItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
|
||||
{
|
||||
if (not m_selectable)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QMenu menu;
|
||||
|
||||
QAction *holdOption = menu.addAction(tr("Hold"));
|
||||
holdOption->setCheckable(true);
|
||||
holdOption->setChecked(m_image.Hold());
|
||||
|
||||
QAction *actionVisible = menu.addAction(tr("Visible"));
|
||||
actionVisible->setCheckable(true);
|
||||
actionVisible->setChecked(m_image.Visible());
|
||||
|
||||
#if defined(Q_OS_MAC)
|
||||
const QString actionShowTitle = tr("Show in Finder");
|
||||
#else
|
||||
const QString actionShowTitle = tr("Show in Explorer");
|
||||
#endif
|
||||
QAction *actionShow = menu.addAction(QIcon::fromTheme(QStringLiteral("system-search")), actionShowTitle);
|
||||
actionShow->setVisible(false);
|
||||
actionShow->setEnabled(QFileInfo::exists(m_image.FilePath()));
|
||||
|
||||
QAction *actionSaveAs = menu.addAction(QIcon::fromTheme(QStringLiteral("document-save-as")), tr("Save as …"));
|
||||
actionSaveAs->setVisible(false);
|
||||
|
||||
if (not m_image.FilePath().isEmpty())
|
||||
{
|
||||
actionShow->setVisible(true);
|
||||
}
|
||||
else if (not m_image.ContentData().isEmpty())
|
||||
{
|
||||
actionSaveAs->setVisible(true);
|
||||
}
|
||||
|
||||
QAction *actionReset = menu.addAction(tr("Reset transformation"));
|
||||
actionReset->setEnabled(not m_image.Hold());
|
||||
|
||||
QAction *actionRemove = menu.addAction(QIcon::fromTheme(QStringLiteral("edit-delete")), tr("Delete"));
|
||||
|
||||
QAction *selectedAction = menu.exec(event->screenPos());
|
||||
if (selectedAction == holdOption)
|
||||
{
|
||||
SetHold(selectedAction->isChecked());
|
||||
}
|
||||
else if (selectedAction == actionVisible)
|
||||
{
|
||||
SetVisible(selectedAction->isChecked());
|
||||
}
|
||||
else if (selectedAction == actionShow)
|
||||
{
|
||||
emit ShowImageInExplorer(m_image.Id());
|
||||
}
|
||||
else if (selectedAction == actionSaveAs)
|
||||
{
|
||||
emit SaveImage(m_image.Id());
|
||||
}
|
||||
else if (selectedAction == actionReset)
|
||||
{
|
||||
VAbstractApplication::VApp()->getUndoStack()->push(new ResetBackgroundImage(m_image.Id(), m_doc));
|
||||
}
|
||||
else if (selectedAction == actionRemove)
|
||||
{
|
||||
DeleteFromMenu();
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VBackgroundImageItem::keyPressEvent(QKeyEvent *event)
|
||||
{
|
||||
const int move = event->modifiers() & Qt::ShiftModifier ? 10 : 1;
|
||||
if (event->key() == Qt::Key_Left)
|
||||
{
|
||||
TranslateImageOn(-move, 0);
|
||||
event->accept();
|
||||
return;
|
||||
}
|
||||
|
||||
if (event->key() == Qt::Key_Right)
|
||||
{
|
||||
TranslateImageOn(move, 0);
|
||||
event->accept();
|
||||
return;
|
||||
}
|
||||
|
||||
if (event->key() == Qt::Key_Up)
|
||||
{
|
||||
TranslateImageOn(0, -move);
|
||||
event->accept();
|
||||
return;
|
||||
}
|
||||
|
||||
if (event->key() == Qt::Key_Down)
|
||||
{
|
||||
TranslateImageOn(0, move);
|
||||
event->accept();
|
||||
return;
|
||||
}
|
||||
|
||||
int angle = 15;
|
||||
if(event->modifiers() & Qt::ControlModifier)
|
||||
{
|
||||
angle = 90;
|
||||
}
|
||||
else if(event->modifiers() & Qt::AltModifier)
|
||||
{
|
||||
angle = 1;
|
||||
}
|
||||
|
||||
if (event->key() == Qt::Key_BracketLeft)
|
||||
{
|
||||
RotateImageByAngle(angle);
|
||||
event->accept();
|
||||
return;
|
||||
}
|
||||
|
||||
if (event->key() == Qt::Key_BracketRight)
|
||||
{
|
||||
RotateImageByAngle(-angle);
|
||||
event->accept();
|
||||
return;
|
||||
}
|
||||
|
||||
if (event->key() == Qt::Key_Period || event->key() == Qt::Key_Greater)
|
||||
{
|
||||
if (event->modifiers() & Qt::ControlModifier)
|
||||
{
|
||||
ScaleImageByFactor(2);
|
||||
}
|
||||
else
|
||||
{
|
||||
ScaleImageByAdjustSize(2);
|
||||
}
|
||||
}
|
||||
|
||||
if (event->key() == Qt::Key_Comma || event->key() == Qt::Key_Less)
|
||||
{
|
||||
if (event->modifiers() & Qt::ControlModifier)
|
||||
{
|
||||
ScaleImageByFactor(0.5);
|
||||
}
|
||||
else
|
||||
{
|
||||
ScaleImageByAdjustSize(-2);
|
||||
}
|
||||
}
|
||||
|
||||
QGraphicsObject::keyPressEvent(event);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VBackgroundImageItem::keyReleaseEvent(QKeyEvent *event)
|
||||
{
|
||||
if (not Image().Hold())
|
||||
{
|
||||
if (event->key() == Qt::Key_Delete)
|
||||
{
|
||||
if (ConfirmDeletion() == QMessageBox::Yes)
|
||||
{
|
||||
DeleteToolWithConfirm(false);
|
||||
event->accept();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (event->key() == Qt::Key_Left ||
|
||||
event->key() == Qt::Key_Right ||
|
||||
event->key() == Qt::Key_Up ||
|
||||
event->key() == Qt::Key_Down ||
|
||||
event->key() == Qt::Key_BracketLeft ||
|
||||
event->key() == Qt::Key_BracketRight ||
|
||||
event->key() == Qt::Key_Period ||
|
||||
event->key() == Qt::Key_Greater ||
|
||||
event->key() == Qt::Key_Comma ||
|
||||
event->key() == Qt::Key_Less)
|
||||
{
|
||||
if (not event->isAutoRepeat())
|
||||
{
|
||||
m_allowChangeMerge = false;
|
||||
}
|
||||
event->accept();
|
||||
return;
|
||||
}
|
||||
}
|
||||
QGraphicsObject::keyReleaseEvent(event);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VBackgroundImageItem::Stale() const -> bool
|
||||
{
|
||||
return m_stale;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VBackgroundImageItem::MakeFresh() const
|
||||
{
|
||||
m_stale = false;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VBackgroundImageItem::DeleteToolWithConfirm(bool ask)
|
||||
{
|
||||
if (ask)
|
||||
{
|
||||
if (ConfirmDeletion() == QMessageBox::No)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
emit ActivateControls(QUuid());
|
||||
emit DeleteImage(m_image.Id());
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VBackgroundImageItem::UpdateHoldState()
|
||||
{
|
||||
m_image = m_doc->GetBackgroundImage(m_image.Id());
|
||||
setFlag(QGraphicsItem::ItemIsMovable, not m_image.Hold());
|
||||
setFlag(QGraphicsItem::ItemSendsGeometryChanges, not m_image.Hold());
|
||||
setFlag(QGraphicsItem::ItemIsFocusable, not m_image.Hold());// For keyboard input focus
|
||||
emit UpdateControls();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VBackgroundImageItem::UpdateVisibilityState()
|
||||
{
|
||||
m_image = m_doc->GetBackgroundImage(m_image.Id());
|
||||
|
||||
setVisible(m_image.Visible());
|
||||
|
||||
if (not m_image.Visible())
|
||||
{
|
||||
emit ActivateControls(QUuid());
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VBackgroundImageItem::ZValueChanged()
|
||||
{
|
||||
m_image = m_doc->GetBackgroundImage(m_image.Id());
|
||||
|
||||
SetupZValue();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VBackgroundImageItem::InitImage()
|
||||
{
|
||||
SetupZValue();
|
||||
|
||||
setFlag(QGraphicsItem::ItemIsMovable, not m_image.Hold());
|
||||
setFlag(QGraphicsItem::ItemSendsGeometryChanges, not m_image.Hold());
|
||||
setFlag(QGraphicsItem::ItemIsFocusable, not m_image.Hold());// For keyboard input focus
|
||||
|
||||
setVisible(m_image.Visible());
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VBackgroundImageItem::TranslateImageOn(qreal dx, qreal dy)
|
||||
{
|
||||
auto *command = new MoveBackgroundImage(m_image.Id(), dx, dy, m_doc, m_allowChangeMerge);
|
||||
VAbstractApplication::VApp()->getUndoStack()->push(command);
|
||||
|
||||
UpdateSceneRect();
|
||||
|
||||
m_allowChangeMerge = true;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VBackgroundImageItem::RotateImageByAngle(qreal angle)
|
||||
{
|
||||
QTransform imageMatrix = m_image.Matrix();
|
||||
|
||||
QPointF originPos = m_image.BoundingRect().center();
|
||||
|
||||
QTransform m;
|
||||
m.translate(originPos.x(), originPos.y());
|
||||
m.rotate(-angle);
|
||||
m.translate(-originPos.x(), -originPos.y());
|
||||
imageMatrix *= m;
|
||||
|
||||
auto *command = new RotateBackgroundImage(m_image.Id(), imageMatrix, m_doc, m_allowChangeMerge);
|
||||
VAbstractApplication::VApp()->getUndoStack()->push(command);
|
||||
|
||||
UpdateSceneRect();
|
||||
|
||||
m_allowChangeMerge = true;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VBackgroundImageItem::ScaleImageByAdjustSize(qreal value)
|
||||
{
|
||||
QRectF rect = m_image.BoundingRect();
|
||||
QRectF adjusted = rect;
|
||||
adjusted.adjust(-value, -value, value, value);
|
||||
|
||||
qreal factor = adjusted.width() / rect.width();
|
||||
ScaleImageByFactor(factor);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VBackgroundImageItem::ScaleImageByFactor(qreal factor)
|
||||
{
|
||||
QTransform imageMatrix = m_image.Matrix();
|
||||
QPointF originPos = m_image.BoundingRect().center();
|
||||
|
||||
QTransform m;
|
||||
m.translate(originPos.x(), originPos.y());
|
||||
m.scale(factor, factor);
|
||||
m.translate(-originPos.x(), -originPos.y());
|
||||
imageMatrix *= m;
|
||||
|
||||
auto *command = new ScaleBackgroundImage(m_image.Id(), imageMatrix, m_doc, m_allowChangeMerge);
|
||||
VAbstractApplication::VApp()->getUndoStack()->push(command);
|
||||
|
||||
UpdateSceneRect();
|
||||
|
||||
m_allowChangeMerge = true;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VBackgroundImageItem::UpdateSceneRect()
|
||||
{
|
||||
const QList<QGraphicsView *> viewList = scene()->views();
|
||||
if (not viewList.isEmpty())
|
||||
{
|
||||
if (auto *view = qobject_cast<VMainGraphicsView *>(viewList.at(0)))
|
||||
{
|
||||
setFlag(QGraphicsItem::ItemSendsGeometryChanges, false);
|
||||
VMainGraphicsView::NewSceneRect(scene(), view);
|
||||
setFlag(QGraphicsItem::ItemSendsGeometryChanges, not m_image.Hold());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VBackgroundImageItem::SetupZValue()
|
||||
{
|
||||
if (qFuzzyIsNull(m_image.ZValue()))
|
||||
{
|
||||
setZValue(-1);
|
||||
}
|
||||
else if (m_image.ZValue() > 0)
|
||||
{
|
||||
setZValue(-1 * m_image.ZValue() - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
setZValue(m_image.ZValue() - 1);
|
||||
}
|
||||
}
|
133
src/libs/vtools/tools/backgroundimage/vbackgroundimageitem.h
Normal file
|
@ -0,0 +1,133 @@
|
|||
/************************************************************************
|
||||
**
|
||||
** @file vbackgroundimageitem.h
|
||||
** @author Roman Telezhynskyi <dismine(at)gmail.com>
|
||||
** @date 13 1, 2022
|
||||
**
|
||||
** @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) 2022 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 VBACKGROUNDIMAGEITEM_H
|
||||
#define VBACKGROUNDIMAGEITEM_H
|
||||
|
||||
#include <QGraphicsObject>
|
||||
|
||||
#include "../ifc/xml/vbackgroundpatternimage.h"
|
||||
#include "../vmisc/def.h"
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 13, 0)
|
||||
#include "../vmisc/defglobal.h"
|
||||
#endif // QT_VERSION < QT_VERSION_CHECK(5, 13, 0)
|
||||
|
||||
class VAbstractPattern;
|
||||
|
||||
class VBackgroundImageItem : public QGraphicsObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
VBackgroundImageItem(const VBackgroundPatternImage &image, VAbstractPattern *doc, QGraphicsItem *parent = nullptr);
|
||||
~VBackgroundImageItem() override = default;
|
||||
|
||||
auto type() const -> int override {return Type;}
|
||||
enum {Type = UserType + static_cast<int>(Tool::BackgroundImage)};
|
||||
|
||||
auto Image() const -> const VBackgroundPatternImage &;
|
||||
void SetImage(const VBackgroundPatternImage &newImage);
|
||||
|
||||
static auto pen() -> QPen;
|
||||
|
||||
auto name() const -> QString;
|
||||
void setName(const QString &newName);
|
||||
|
||||
auto IsHold() const -> bool;
|
||||
void SetHold(bool hold);
|
||||
|
||||
auto IsVisible() const -> bool;
|
||||
void SetVisible(bool visible);
|
||||
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
|
||||
|
||||
signals:
|
||||
void Selected(const QUuid &id);
|
||||
void UpdateControls();
|
||||
void ActivateControls(const QUuid &id);
|
||||
void DeleteImage(const QUuid &id);
|
||||
void ShowImageInExplorer(const QUuid &id);
|
||||
void SaveImage(const QUuid &id);
|
||||
|
||||
public slots:
|
||||
void PositionChanged(QUuid id);
|
||||
void ImageTransformationChanged(QUuid id);
|
||||
void HoldChanged(QUuid id);
|
||||
void VisibilityChanged(QUuid id);
|
||||
void NameChanged(QUuid id);
|
||||
void EnableSelection(bool enable);
|
||||
void DeleteFromMenu();
|
||||
|
||||
protected:
|
||||
auto itemChange(GraphicsItemChange change, const QVariant &value) -> QVariant override;
|
||||
void mousePressEvent( QGraphicsSceneMouseEvent * event) override;
|
||||
void mouseMoveEvent ( QGraphicsSceneMouseEvent * event ) override;
|
||||
void mouseReleaseEvent ( QGraphicsSceneMouseEvent * event ) override;
|
||||
void hoverEnterEvent ( QGraphicsSceneHoverEvent * event ) override;
|
||||
void hoverMoveEvent ( QGraphicsSceneHoverEvent * event ) override;
|
||||
void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) override;
|
||||
void contextMenuEvent ( QGraphicsSceneContextMenuEvent * event ) override;
|
||||
void keyPressEvent(QKeyEvent *event) override;
|
||||
void keyReleaseEvent(QKeyEvent * event) override;
|
||||
|
||||
auto Stale() const -> bool;
|
||||
void MakeFresh() const;
|
||||
void DeleteToolWithConfirm(bool ask = true);
|
||||
|
||||
auto Invalid() const -> bool;
|
||||
void SetInvalid(bool newInvalid);
|
||||
|
||||
private slots:
|
||||
void UpdateHoldState();
|
||||
void UpdateVisibilityState();
|
||||
void ZValueChanged();
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY_MOVE(VBackgroundImageItem)
|
||||
|
||||
VBackgroundPatternImage m_image;
|
||||
VAbstractPattern *m_doc;
|
||||
mutable bool m_stale{true};
|
||||
bool m_allowChangeMerge{false};
|
||||
QPointF m_lastMoveDistance{};
|
||||
bool m_wasMoved{false};
|
||||
bool m_showHover{false};
|
||||
bool m_selectable{true};
|
||||
|
||||
void InitImage();
|
||||
|
||||
void TranslateImageOn(qreal dx, qreal dy);
|
||||
void RotateImageByAngle(qreal angle);
|
||||
void ScaleImageByAdjustSize(qreal value);
|
||||
void ScaleImageByFactor(qreal factor);
|
||||
|
||||
void UpdateSceneRect();
|
||||
|
||||
void SetupZValue();
|
||||
};
|
||||
|
||||
#endif // VBACKGROUNDIMAGEITEM_H
|
245
src/libs/vtools/tools/backgroundimage/vbackgroundpixmapitem.cpp
Normal file
|
@ -0,0 +1,245 @@
|
|||
/************************************************************************
|
||||
**
|
||||
** @file vbackgroundpixmapitem.cpp
|
||||
** @author Roman Telezhynskyi <dismine(at)gmail.com>
|
||||
** @date 15 1, 2022
|
||||
**
|
||||
** @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) 2022 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 "vbackgroundpixmapitem.h"
|
||||
|
||||
#include <QBitmap>
|
||||
#include <QBuffer>
|
||||
#include <QImageReader>
|
||||
#include <QPainter>
|
||||
#include <QStyleOptionGraphicsItem>
|
||||
|
||||
extern auto qt_regionToPath(const QRegion ®ion) -> QPainterPath;
|
||||
|
||||
namespace
|
||||
{
|
||||
auto InvalidImage() -> QPixmap
|
||||
{
|
||||
QImageReader imageReader(QStringLiteral("://icon/svg/broken_path.svg"));
|
||||
return std::move(QPixmap::fromImageReader(&imageReader));
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VBackgroundPixmapItem::VBackgroundPixmapItem(const VBackgroundPatternImage &image, VAbstractPattern *doc,
|
||||
QGraphicsItem *parent)
|
||||
: VBackgroundImageItem(image, doc, parent)
|
||||
{}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VBackgroundPixmapItem::SetTransformationMode(Qt::TransformationMode mode)
|
||||
{
|
||||
m_transformationMode = mode;
|
||||
update();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VBackgroundPixmapItem::boundingRect() const -> QRectF
|
||||
{
|
||||
QPixmap pixmap = Pixmap();
|
||||
if (pixmap.isNull())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
return Image().Matrix().mapRect(QRectF(QPointF(0, 0), pixmap.size() / pixmap.devicePixelRatio()));
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VBackgroundPixmapItem::shape() const -> QPainterPath
|
||||
{
|
||||
if (!m_hasShape)
|
||||
{
|
||||
UpdateShape();
|
||||
m_hasShape = true;
|
||||
}
|
||||
return Image().Matrix().map(m_shape);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VBackgroundPixmapItem::contains(const QPointF &point) const -> bool
|
||||
{
|
||||
return QGraphicsItem::contains(point);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VBackgroundPixmapItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
||||
{
|
||||
painter->setRenderHint(QPainter::SmoothPixmapTransform, (m_transformationMode == Qt::SmoothTransformation));
|
||||
|
||||
painter->save();
|
||||
painter->setTransform(Image().Matrix(), true);
|
||||
|
||||
painter->drawPixmap(QPointF(), Pixmap());
|
||||
|
||||
painter->restore();
|
||||
|
||||
VBackgroundImageItem::paint(painter, option, widget);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VBackgroundPixmapItem::isObscuredBy(const QGraphicsItem *item) const -> bool
|
||||
{
|
||||
return QGraphicsItem::isObscuredBy(item);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VBackgroundPixmapItem::opaqueArea() const -> QPainterPath
|
||||
{
|
||||
return shape();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VBackgroundPixmapItem::ShapeMode() const -> enum ShapeMode
|
||||
{
|
||||
return m_shapeMode;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VBackgroundPixmapItem::SetShapeMode(enum ShapeMode mode)
|
||||
{
|
||||
if (m_shapeMode == mode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_shapeMode = mode;
|
||||
m_hasShape = false;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VBackgroundPixmapItem::supportsExtension(Extension extension) const -> bool
|
||||
{
|
||||
Q_UNUSED(extension);
|
||||
return false;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VBackgroundPixmapItem::setExtension(Extension extension, const QVariant &variant)
|
||||
{
|
||||
Q_UNUSED(extension);
|
||||
Q_UNUSED(variant);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VBackgroundPixmapItem::extension(const QVariant &variant) const -> QVariant
|
||||
{
|
||||
Q_UNUSED(variant);
|
||||
return {};
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VBackgroundPixmapItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
SetTransformationMode(Qt::FastTransformation);
|
||||
VBackgroundImageItem::mouseMoveEvent(event);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VBackgroundPixmapItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
SetTransformationMode(Qt::SmoothTransformation);
|
||||
VBackgroundImageItem::mouseReleaseEvent(event);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VBackgroundPixmapItem::UpdateShape() const
|
||||
{
|
||||
QPixmap pixmap = Pixmap();
|
||||
m_shape = QPainterPath();
|
||||
switch (m_shapeMode)
|
||||
{
|
||||
case ShapeMode::MaskShape:
|
||||
{
|
||||
QBitmap mask = pixmap.mask();
|
||||
if (!mask.isNull())
|
||||
{
|
||||
m_shape = qt_regionToPath(QRegion(mask));
|
||||
break;
|
||||
}
|
||||
Q_FALLTHROUGH();
|
||||
}
|
||||
case ShapeMode::BoundingRectShape:
|
||||
m_shape.addRect(QRectF(0, 0, pixmap.width(), pixmap.height()));
|
||||
break;
|
||||
case ShapeMode::HeuristicMaskShape:
|
||||
#ifndef QT_NO_IMAGE_HEURISTIC_MASK
|
||||
m_shape = qt_regionToPath(QRegion(pixmap.createHeuristicMask()));
|
||||
#else
|
||||
m_shape.addRect(QRectF(0, 0, m_shape.width(), m_shape.height()));
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VBackgroundPixmapItem::Pixmap() const -> QPixmap
|
||||
{
|
||||
if (Stale())
|
||||
{
|
||||
m_pixmap = QPixmap();
|
||||
|
||||
VBackgroundPatternImage image = Image();
|
||||
if (not image.IsValid())
|
||||
{
|
||||
m_pixmap = InvalidImage();
|
||||
MakeFresh();
|
||||
return m_pixmap;
|
||||
}
|
||||
|
||||
if (not image.FilePath().isEmpty())
|
||||
{
|
||||
QImageReader imageReader(image.FilePath());
|
||||
m_pixmap = QPixmap::fromImageReader(&imageReader);
|
||||
if (m_pixmap.isNull())
|
||||
{
|
||||
m_pixmap = InvalidImage();
|
||||
}
|
||||
MakeFresh();
|
||||
return m_pixmap;
|
||||
}
|
||||
|
||||
if (not image.ContentData().isEmpty())
|
||||
{
|
||||
QByteArray array = QByteArray::fromBase64(image.ContentData());
|
||||
QBuffer buffer(&array);
|
||||
buffer.open(QIODevice::ReadOnly);
|
||||
|
||||
QImageReader imageReader(&buffer);
|
||||
m_pixmap = QPixmap::fromImageReader(&imageReader);
|
||||
if (m_pixmap.isNull())
|
||||
{
|
||||
m_pixmap = InvalidImage();
|
||||
}
|
||||
MakeFresh();
|
||||
return m_pixmap;
|
||||
}
|
||||
}
|
||||
|
||||
return m_pixmap;
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
/************************************************************************
|
||||
**
|
||||
** @file vbackgroundpixmapitem.h
|
||||
** @author Roman Telezhynskyi <dismine(at)gmail.com>
|
||||
** @date 15 1, 2022
|
||||
**
|
||||
** @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) 2022 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 VBACKGROUNDPIXMAPITEM_H
|
||||
#define VBACKGROUNDPIXMAPITEM_H
|
||||
|
||||
#include "vbackgroundimageitem.h"
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 13, 0)
|
||||
#include "../vmisc/defglobal.h"
|
||||
#endif // QT_VERSION < QT_VERSION_CHECK(5, 13, 0)
|
||||
|
||||
enum class ShapeMode
|
||||
{
|
||||
MaskShape,
|
||||
BoundingRectShape,
|
||||
HeuristicMaskShape
|
||||
};
|
||||
|
||||
class VBackgroundPixmapItem : public VBackgroundImageItem
|
||||
{
|
||||
public:
|
||||
VBackgroundPixmapItem(const VBackgroundPatternImage &image, VAbstractPattern *doc, QGraphicsItem *parent = nullptr);
|
||||
~VBackgroundPixmapItem() override = default;
|
||||
|
||||
auto type() const -> int override {return Type;}
|
||||
enum {Type = UserType + static_cast<int>(Tool::BackgroundPixmapImage)};
|
||||
|
||||
auto boundingRect() const -> QRectF override;
|
||||
auto shape() const -> QPainterPath override;
|
||||
auto contains(const QPointF &point) const -> bool override;
|
||||
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
|
||||
|
||||
auto isObscuredBy(const QGraphicsItem *item) const -> bool override;
|
||||
auto opaqueArea() const -> QPainterPath override;
|
||||
|
||||
auto ShapeMode() const -> ShapeMode;
|
||||
void SetShapeMode(enum ShapeMode mode);
|
||||
|
||||
protected:
|
||||
auto supportsExtension(Extension extension) const -> bool override;
|
||||
void setExtension(Extension extension, const QVariant &variant) override;
|
||||
auto extension(const QVariant &variant) const -> QVariant override;
|
||||
void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
|
||||
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY_MOVE(VBackgroundPixmapItem)
|
||||
|
||||
mutable QPixmap m_pixmap{};
|
||||
Qt::TransformationMode m_transformationMode{Qt::SmoothTransformation};
|
||||
enum ShapeMode m_shapeMode{ShapeMode::MaskShape};
|
||||
mutable QPainterPath m_shape{};
|
||||
mutable bool m_hasShape{false};
|
||||
|
||||
void SetTransformationMode(Qt::TransformationMode mode);
|
||||
|
||||
void UpdateShape() const;
|
||||
|
||||
auto Pixmap() const -> QPixmap;
|
||||
};
|
||||
|
||||
#endif // VBACKGROUNDPIXMAPITEM_H
|
123
src/libs/vtools/tools/backgroundimage/vbackgroundsvgitem.cpp
Normal file
|
@ -0,0 +1,123 @@
|
|||
/************************************************************************
|
||||
**
|
||||
** @file vbackgroundsvgitem.cpp
|
||||
** @author Roman Telezhynskyi <dismine(at)gmail.com>
|
||||
** @date 15 1, 2022
|
||||
**
|
||||
** @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) 2022 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 "vbackgroundsvgitem.h"
|
||||
|
||||
#include <QStyleOptionGraphicsItem>
|
||||
#include <QSvgRenderer>
|
||||
#include <QPen>
|
||||
#include <QPainter>
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VBackgroundSVGItem::VBackgroundSVGItem(const VBackgroundPatternImage &image, VAbstractPattern *doc,
|
||||
QGraphicsItem *parent)
|
||||
: VBackgroundImageItem(image, doc, parent),
|
||||
m_renderer(new QSvgRenderer())
|
||||
{
|
||||
setCacheMode(QGraphicsItem::DeviceCoordinateCache);
|
||||
|
||||
QObject::connect(m_renderer, &QSvgRenderer::repaintNeeded, this, &VBackgroundSVGItem::RepaintItem);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VBackgroundSVGItem::~VBackgroundSVGItem()
|
||||
{
|
||||
delete m_renderer;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VBackgroundSVGItem::boundingRect() const -> QRectF
|
||||
{
|
||||
return Image().Matrix().mapRect(QRectF(QPointF(0, 0), Renderer()->defaultSize()));
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VBackgroundSVGItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
||||
{
|
||||
QSvgRenderer *renderer = Renderer();
|
||||
|
||||
if (not renderer->isValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
painter->save();
|
||||
painter->setTransform(Image().Matrix(), true);
|
||||
|
||||
renderer->render(painter, QRectF(QPointF(0, 0), renderer->defaultSize()));
|
||||
|
||||
painter->restore();
|
||||
|
||||
VBackgroundImageItem::paint(painter, option, widget);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VBackgroundSVGItem::RepaintItem()
|
||||
{
|
||||
update();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VBackgroundSVGItem::Renderer() const -> QSvgRenderer *
|
||||
{
|
||||
if (Stale())
|
||||
{
|
||||
const QString brokenImage = QStringLiteral("://icon/svg/broken_path.svg");
|
||||
m_renderer->load(brokenImage);
|
||||
|
||||
VBackgroundPatternImage image = Image();
|
||||
if (not image.IsValid())
|
||||
{
|
||||
MakeFresh();
|
||||
return m_renderer;
|
||||
}
|
||||
|
||||
if (not image.FilePath().isEmpty())
|
||||
{
|
||||
m_renderer->load(image.FilePath());
|
||||
if (not m_renderer->isValid())
|
||||
{
|
||||
m_renderer->load(brokenImage);
|
||||
}
|
||||
MakeFresh();
|
||||
return m_renderer;
|
||||
}
|
||||
|
||||
if (not image.ContentData().isEmpty())
|
||||
{
|
||||
m_renderer->load(QByteArray::fromBase64(image.ContentData()));
|
||||
if (not m_renderer->isValid())
|
||||
{
|
||||
m_renderer->load(brokenImage);
|
||||
}
|
||||
MakeFresh();
|
||||
return m_renderer;
|
||||
}
|
||||
}
|
||||
|
||||
return m_renderer;
|
||||
}
|
63
src/libs/vtools/tools/backgroundimage/vbackgroundsvgitem.h
Normal file
|
@ -0,0 +1,63 @@
|
|||
/************************************************************************
|
||||
**
|
||||
** @file vbackgroundsvgitem.h
|
||||
** @author Roman Telezhynskyi <dismine(at)gmail.com>
|
||||
** @date 15 1, 2022
|
||||
**
|
||||
** @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) 2022 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 VBACKGROUNDSVGITEM_H
|
||||
#define VBACKGROUNDSVGITEM_H
|
||||
|
||||
#include "vbackgroundimageitem.h"
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 13, 0)
|
||||
#include "../vmisc/defglobal.h"
|
||||
#endif // QT_VERSION < QT_VERSION_CHECK(5, 13, 0)
|
||||
|
||||
class QSvgRenderer;
|
||||
|
||||
class VBackgroundSVGItem : public VBackgroundImageItem
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
VBackgroundSVGItem(const VBackgroundPatternImage &image, VAbstractPattern *doc, QGraphicsItem *parent = nullptr);
|
||||
~VBackgroundSVGItem() override;
|
||||
|
||||
auto type() const -> int override {return Type;}
|
||||
enum {Type = UserType + static_cast<int>(Tool::BackgroundSVGImage)};
|
||||
|
||||
auto boundingRect() const -> QRectF override;
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
|
||||
|
||||
private slots:
|
||||
void RepaintItem();
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY_MOVE(VBackgroundSVGItem)
|
||||
|
||||
QSvgRenderer *m_renderer{nullptr};
|
||||
|
||||
auto Renderer() const -> QSvgRenderer *;
|
||||
};
|
||||
|
||||
#endif // VBACKGROUNDSVGITEM_H
|
|
@ -2,7 +2,11 @@
|
|||
# This need for corect working file translations.pro
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/backgroundimage/vbackgroundimagecontrols.h \
|
||||
$$PWD/backgroundimage/vbackgroundpixmapitem.h \
|
||||
$$PWD/backgroundimage/vbackgroundsvgitem.h \
|
||||
$$PWD/toolsdef.h \
|
||||
$$PWD/backgroundimage/vbackgroundimageitem.h \
|
||||
$$PWD/vdatatool.h \
|
||||
$$PWD/vabstracttool.h \
|
||||
$$PWD/tools.h \
|
||||
|
@ -65,7 +69,11 @@ HEADERS += \
|
|||
$$PWD/nodeDetails/vtoolplacelabel.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/backgroundimage/vbackgroundimagecontrols.cpp \
|
||||
$$PWD/backgroundimage/vbackgroundpixmapitem.cpp \
|
||||
$$PWD/backgroundimage/vbackgroundsvgitem.cpp \
|
||||
$$PWD/toolsdef.cpp \
|
||||
$$PWD/backgroundimage/vbackgroundimageitem.cpp \
|
||||
$$PWD/vdatatool.cpp \
|
||||
$$PWD/vabstracttool.cpp \
|
||||
$$PWD/drawTools/toolpoint/toolsinglepoint/vtooltriangle.cpp \
|
||||
|
|
|
@ -29,16 +29,21 @@
|
|||
#include "toolsdef.h"
|
||||
|
||||
#include <QBrush>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QIcon>
|
||||
#include <QMessageBox>
|
||||
#include <QPainter>
|
||||
#include <QPen>
|
||||
#include <QPixmap>
|
||||
#include <QRegularExpression>
|
||||
#include <QVector>
|
||||
#include <QStyle>
|
||||
|
||||
#include "../vgeometry/vgobject.h"
|
||||
#include "../qmuparser/qmudef.h"
|
||||
#include "../vpatterndb/vcontainer.h"
|
||||
#include "../vpropertyexplorer/checkablemessagebox.h"
|
||||
#include "../vmisc/vabstractvalapplication.h"
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
QVector<quint32> SourceToObjects(const QVector<SourceItem> &source)
|
||||
|
@ -116,3 +121,28 @@ QMap<QString, QIcon> OperationLineStylesPics()
|
|||
map.insert(TypeLineDefault, QIcon());
|
||||
return map;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto ConfirmDeletion() -> int
|
||||
{
|
||||
if (not VAbstractApplication::VApp()->Settings()->GetConfirmItemDelete())
|
||||
{
|
||||
return QMessageBox::Yes;
|
||||
}
|
||||
|
||||
Utils::CheckableMessageBox msgBox(VAbstractValApplication::VApp()->getMainWindow());
|
||||
msgBox.setWindowTitle(QObject::tr("Confirm deletion"));
|
||||
msgBox.setText(QObject::tr("Do you really want to delete?"));
|
||||
msgBox.setStandardButtons(QDialogButtonBox::Yes | QDialogButtonBox::No);
|
||||
msgBox.setDefaultButton(QDialogButtonBox::No);
|
||||
msgBox.setIconPixmap(QApplication::style()->standardIcon(QStyle::SP_MessageBoxQuestion).pixmap(32, 32) );
|
||||
|
||||
int dialogResult = msgBox.exec();
|
||||
|
||||
if (dialogResult == QDialog::Accepted)
|
||||
{
|
||||
VAbstractApplication::VApp()->Settings()->SetConfirmItemDelete(not msgBox.isChecked());
|
||||
}
|
||||
|
||||
return dialogResult == QDialog::Accepted ? QMessageBox::Yes : QMessageBox::No;
|
||||
}
|
||||
|
|
|
@ -60,4 +60,6 @@ bool SourceAliasValid(const SourceItem &item, const QSharedPointer<VGObject> &ob
|
|||
|
||||
QMap<QString, QIcon> OperationLineStylesPics();
|
||||
|
||||
int ConfirmDeletion();
|
||||
|
||||
#endif // TOOLSDEF_H
|
||||
|
|