diff --git a/src/app/valentina/xml/vpattern.cpp b/src/app/valentina/xml/vpattern.cpp index 8db3a299a..9fbb0dc24 100644 --- a/src/app/valentina/xml/vpattern.cpp +++ b/src/app/valentina/xml/vpattern.cpp @@ -1279,11 +1279,10 @@ void VPattern::ParseNodePoint(const QDomElement &domElement, const Document &par PointsCommonAttributes(domElement, id, mx, my); const quint32 idObject = GetParametrUInt(domElement, VAbstractNode::AttrIdObject, NULL_ID_STR); const quint32 idTool = GetParametrUInt(domElement, VAbstractNode::AttrIdTool, NULL_ID_STR); - const NodeUsage inUse = GetParametrUsage(domElement, VAbstractNode::AttrInUse); const QSharedPointer point = data->GeometricObject(idObject ); data->UpdateGObject(id, new VPointF(point->toQPointF(), point->name(), mx, my, idObject, Draw::Modeling)); - VNodePoint::Create(this, data, sceneDetail, id, idObject, parse, Source::FromFile, inUse, idTool); + VNodePoint::Create(this, data, sceneDetail, id, idObject, parse, Source::FromFile, idTool); } catch (const VExceptionBadId &e) { @@ -1900,12 +1899,11 @@ void VPattern::ParseNodeSpline(const QDomElement &domElement, const Document &pa quint32 idTool = 0; SplinesCommonAttributes(domElement, id, idObject, idTool); - const NodeUsage inUse = GetParametrUsage(domElement, VAbstractNode::AttrInUse); VSpline *spl = new VSpline(*data->GeometricObject(idObject)); spl->setIdObject(idObject); spl->setMode(Draw::Modeling); data->UpdateGObject(id, spl); - VNodeSpline::Create(this, data, sceneDetail, id, idObject, parse, Source::FromFile, inUse, idTool); + VNodeSpline::Create(this, data, sceneDetail, id, idObject, parse, Source::FromFile, idTool); } catch (const VExceptionBadId &e) { @@ -1927,12 +1925,11 @@ void VPattern::ParseNodeSplinePath(const QDomElement &domElement, const Document quint32 idTool = 0; SplinesCommonAttributes(domElement, id, idObject, idTool); - const NodeUsage inUse = GetParametrUsage(domElement, VAbstractNode::AttrInUse); VSplinePath *path = new VSplinePath(*data->GeometricObject(idObject)); path->setIdObject(idObject); path->setMode(Draw::Modeling); data->UpdateGObject(id, path); - VNodeSplinePath::Create(this, data, sceneDetail, id, idObject, parse, Source::FromFile, inUse, idTool); + VNodeSplinePath::Create(this, data, sceneDetail, id, idObject, parse, Source::FromFile, idTool); } catch (const VExceptionBadId &e) { @@ -1999,12 +1996,11 @@ void VPattern::ParseNodeArc(const QDomElement &domElement, const Document &parse ToolsCommonAttributes(domElement, id); const quint32 idObject = GetParametrUInt(domElement, VAbstractNode::AttrIdObject, NULL_ID_STR); const quint32 idTool = GetParametrUInt(domElement, VAbstractNode::AttrIdTool, NULL_ID_STR); - const NodeUsage inUse = GetParametrUsage(domElement, VAbstractNode::AttrInUse); VArc *arc = new VArc(*data->GeometricObject(idObject)); arc->setIdObject(idObject); arc->setMode(Draw::Modeling); data->UpdateGObject(id, arc); - VNodeArc::Create(this, data, sceneDetail, id, idObject, parse, Source::FromFile, inUse, idTool); + VNodeArc::Create(this, data, sceneDetail, id, idObject, parse, Source::FromFile, idTool); } catch (const VExceptionBadId &e) { diff --git a/src/libs/ifc/schema/pattern/v0.2.3.xsd b/src/libs/ifc/schema/pattern/v0.2.3.xsd index b1905a2ab..b12c45bcf 100644 --- a/src/libs/ifc/schema/pattern/v0.2.3.xsd +++ b/src/libs/ifc/schema/pattern/v0.2.3.xsd @@ -256,6 +256,7 @@ + diff --git a/src/libs/vtools/tools/nodeDetails/vabstractnode.cpp b/src/libs/vtools/tools/nodeDetails/vabstractnode.cpp index aaa754692..f75fe4330 100644 --- a/src/libs/vtools/tools/nodeDetails/vabstractnode.cpp +++ b/src/libs/vtools/tools/nodeDetails/vabstractnode.cpp @@ -33,7 +33,6 @@ const QString VAbstractNode::AttrIdObject = QStringLiteral("idObject"); const QString VAbstractNode::AttrIdTool = QStringLiteral("idTool"); -const QString VAbstractNode::AttrInUse = QStringLiteral("inUse"); //--------------------------------------------------------------------------------------------------------------------- /** @@ -61,11 +60,8 @@ void VAbstractNode::ShowVisualization(bool show) //--------------------------------------------------------------------------------------------------------------------- void VAbstractNode::incrementReferens() { - if (_referens <= 0) - { - ++_referens; - } - if (_referens > 0) + ++_referens; + if (_referens == 1) { idTool != NULL_ID ? doc->IncrementReferens(idTool) : doc->IncrementReferens(idNode); ShowNode(); @@ -87,7 +83,7 @@ void VAbstractNode::decrementReferens() { --_referens; } - if (_referens <= 0) + if (_referens == 0) { idTool != NULL_ID ? doc->DecrementReferens(idTool) : doc->DecrementReferens(idNode); HideNode(); diff --git a/src/libs/vtools/tools/nodeDetails/vabstractnode.h b/src/libs/vtools/tools/nodeDetails/vabstractnode.h index 6c55136c0..09532ca05 100644 --- a/src/libs/vtools/tools/nodeDetails/vabstractnode.h +++ b/src/libs/vtools/tools/nodeDetails/vabstractnode.h @@ -45,7 +45,6 @@ public: virtual ~VAbstractNode() Q_DECL_OVERRIDE {} static const QString AttrIdObject; static const QString AttrIdTool; - static const QString AttrInUse; virtual void ShowVisualization(bool show) Q_DECL_OVERRIDE; virtual void incrementReferens() Q_DECL_OVERRIDE; virtual void decrementReferens() Q_DECL_OVERRIDE; diff --git a/src/libs/vtools/tools/nodeDetails/vnodearc.cpp b/src/libs/vtools/tools/nodeDetails/vnodearc.cpp index 4366d9d55..092c051bf 100644 --- a/src/libs/vtools/tools/nodeDetails/vnodearc.cpp +++ b/src/libs/vtools/tools/nodeDetails/vnodearc.cpp @@ -69,8 +69,7 @@ VNodeArc::VNodeArc(VAbstractPattern *doc, VContainer *data, quint32 id, quint32 * @param parent QObject parent */ void VNodeArc::Create(VAbstractPattern *doc, VContainer *data, VMainGraphicsScene *scene, quint32 id, quint32 idArc, - const Document &parse, - const Source &typeCreation, const NodeUsage &inUse, const quint32 &idTool, QObject *parent) + const Document &parse, const Source &typeCreation, const quint32 &idTool, QObject *parent) { VAbstractTool::AddRecord(id, Tool::NodeArc, doc); if (parse == Document::FullParse) @@ -84,22 +83,11 @@ void VNodeArc::Create(VAbstractPattern *doc, VContainer *data, VMainGraphicsScen doc->AddTool(id, arc); if (idTool != NULL_ID) { - if (inUse == NodeUsage::InUse) - { - doc->IncrementReferens(idTool); - } //Some nodes we don't show on scene. Tool that create this nodes must free memory. VDataTool *tool = doc->getTool(idTool); SCASSERT(tool != nullptr); arc->setParent(tool);// Adopted by a tool } - else - { - if (inUse == NodeUsage::InUse) - { - doc->IncrementReferens(idArc); - } - } } else { diff --git a/src/libs/vtools/tools/nodeDetails/vnodearc.h b/src/libs/vtools/tools/nodeDetails/vnodearc.h index a19208f13..1e87f74f0 100644 --- a/src/libs/vtools/tools/nodeDetails/vnodearc.h +++ b/src/libs/vtools/tools/nodeDetails/vnodearc.h @@ -44,8 +44,7 @@ public: static void Create(VAbstractPattern *doc, VContainer *data, VMainGraphicsScene *scene, quint32 id, quint32 idArc, const Document &parse, - const Source &typeCreation, const NodeUsage &inUse, const quint32 &idTool = 0, - QObject *parent = nullptr); + const Source &typeCreation, const quint32 &idTool = 0, QObject *parent = nullptr); static const QString TagName; static const QString ToolType; virtual int type() const Q_DECL_OVERRIDE {return Type;} diff --git a/src/libs/vtools/tools/nodeDetails/vnodepoint.cpp b/src/libs/vtools/tools/nodeDetails/vnodepoint.cpp index c45ca6cad..a87dc7afd 100644 --- a/src/libs/vtools/tools/nodeDetails/vnodepoint.cpp +++ b/src/libs/vtools/tools/nodeDetails/vnodepoint.cpp @@ -81,7 +81,7 @@ VNodePoint::VNodePoint(VAbstractPattern *doc, VContainer *data, quint32 id, quin */ void VNodePoint::Create(VAbstractPattern *doc, VContainer *data, VMainGraphicsScene *scene, quint32 id, quint32 idPoint, const Document &parse, - const Source &typeCreation, const NodeUsage &inUse, const quint32 &idTool, QObject *parent) + const Source &typeCreation, const quint32 &idTool, QObject *parent) { VAbstractTool::AddRecord(id, Tool::NodePoint, doc); if (parse == Document::FullParse) @@ -98,22 +98,11 @@ void VNodePoint::Create(VAbstractPattern *doc, VContainer *data, VMainGraphicsSc doc->AddTool(id, point); if (idTool != NULL_ID) { - if (inUse == NodeUsage::InUse) - { - doc->IncrementReferens(idTool); - } //Some nodes we don't show on scene. Tool that create this nodes must free memory. VDataTool *tool = doc->getTool(idTool); SCASSERT(tool != nullptr); point->setParent(tool);// Adopted by a tool } - else - { - if (inUse == NodeUsage::InUse) - { - doc->IncrementReferens(idPoint); - } - } } else { diff --git a/src/libs/vtools/tools/nodeDetails/vnodepoint.h b/src/libs/vtools/tools/nodeDetails/vnodepoint.h index 93aa46dc0..7a015e239 100644 --- a/src/libs/vtools/tools/nodeDetails/vnodepoint.h +++ b/src/libs/vtools/tools/nodeDetails/vnodepoint.h @@ -50,8 +50,7 @@ public: static void Create(VAbstractPattern *doc, VContainer *data, VMainGraphicsScene *scene, quint32 id, quint32 idPoint, const Document &parse, - const Source &typeCreation, const NodeUsage &inUse, const quint32 &idTool = 0, - QObject *parent = nullptr); + const Source &typeCreation, const quint32 &idTool = 0, QObject *parent = nullptr); static const QString TagName; static const QString ToolType; virtual int type() const Q_DECL_OVERRIDE {return Type;} diff --git a/src/libs/vtools/tools/nodeDetails/vnodespline.cpp b/src/libs/vtools/tools/nodeDetails/vnodespline.cpp index bbf122f4c..9b3c4afe0 100644 --- a/src/libs/vtools/tools/nodeDetails/vnodespline.cpp +++ b/src/libs/vtools/tools/nodeDetails/vnodespline.cpp @@ -71,8 +71,7 @@ VNodeSpline::VNodeSpline(VAbstractPattern *doc, VContainer *data, quint32 id, qu */ VNodeSpline *VNodeSpline::Create(VAbstractPattern *doc, VContainer *data, VMainGraphicsScene *scene, quint32 id, quint32 idSpline, const Document &parse, - const Source &typeCreation, const NodeUsage &inUse, const quint32 &idTool, - QObject *parent) + const Source &typeCreation, const quint32 &idTool, QObject *parent) { VAbstractTool::AddRecord(id, Tool::NodeSpline, doc); VNodeSpline *spl = nullptr; @@ -87,22 +86,11 @@ VNodeSpline *VNodeSpline::Create(VAbstractPattern *doc, VContainer *data, VMainG doc->AddTool(id, spl); if (idTool != NULL_ID) { - if (inUse == NodeUsage::InUse) - { - doc->IncrementReferens(idTool); - } //Some nodes we don't show on scene. Tool that create this nodes must free memory. VDataTool *tool = doc->getTool(idTool); SCASSERT(tool != nullptr); spl->setParent(tool);// Adopted by a tool } - else - { - if (inUse == NodeUsage::InUse) - { - doc->IncrementReferens(idSpline); - } - } } else { diff --git a/src/libs/vtools/tools/nodeDetails/vnodespline.h b/src/libs/vtools/tools/nodeDetails/vnodespline.h index 69abfe3ec..d04ba33d6 100644 --- a/src/libs/vtools/tools/nodeDetails/vnodespline.h +++ b/src/libs/vtools/tools/nodeDetails/vnodespline.h @@ -44,8 +44,7 @@ public: static VNodeSpline *Create(VAbstractPattern *doc, VContainer *data, VMainGraphicsScene *scene, quint32 id, quint32 idSpline, const Document &parse, - const Source &typeCreation, const NodeUsage &inUse, const quint32 &idTool = 0, - QObject *parent = nullptr); + const Source &typeCreation, const quint32 &idTool = 0, QObject *parent = nullptr); static const QString TagName; static const QString ToolType; virtual int type() const Q_DECL_OVERRIDE {return Type;} diff --git a/src/libs/vtools/tools/nodeDetails/vnodesplinepath.cpp b/src/libs/vtools/tools/nodeDetails/vnodesplinepath.cpp index 0e1ce01c5..3d3780a11 100644 --- a/src/libs/vtools/tools/nodeDetails/vnodesplinepath.cpp +++ b/src/libs/vtools/tools/nodeDetails/vnodesplinepath.cpp @@ -72,7 +72,7 @@ VNodeSplinePath::VNodeSplinePath(VAbstractPattern *doc, VContainer *data, quint3 */ void VNodeSplinePath::Create(VAbstractPattern *doc, VContainer *data, VMainGraphicsScene *scene, quint32 id, quint32 idSpline, const Document &parse, - const Source &typeCreation, const NodeUsage &inUse, const quint32 &idTool, QObject *parent) + const Source &typeCreation, const quint32 &idTool, QObject *parent) { VAbstractTool::AddRecord(id, Tool::NodeSplinePath, doc); if (parse == Document::FullParse) @@ -90,22 +90,11 @@ void VNodeSplinePath::Create(VAbstractPattern *doc, VContainer *data, VMainGraph { if (idTool != NULL_ID) { - if (inUse == NodeUsage::InUse) - { - doc->IncrementReferens(idTool); - } //Some nodes we don't show on scene. Tool that create this nodes must free memory. VDataTool *tool = doc->getTool(idTool); SCASSERT(tool != nullptr); splPath->setParent(tool);// Adopted by a tool } - else - { - if (inUse == NodeUsage::InUse) - { - doc->IncrementReferens(points->at(i).P().id()); - } - } } } else diff --git a/src/libs/vtools/tools/nodeDetails/vnodesplinepath.h b/src/libs/vtools/tools/nodeDetails/vnodesplinepath.h index d039db98c..c82d3787d 100644 --- a/src/libs/vtools/tools/nodeDetails/vnodesplinepath.h +++ b/src/libs/vtools/tools/nodeDetails/vnodesplinepath.h @@ -43,8 +43,7 @@ public: const quint32 &idTool = 0, QObject *qoParent = nullptr, QGraphicsItem * parent = nullptr); static void Create(VAbstractPattern *doc, VContainer *data, VMainGraphicsScene *scene, quint32 id, quint32 idSpline, const Document &parse, - const Source &typeCreation, const NodeUsage &inUse, const quint32 &idTool = 0, - QObject *parent = 0); + const Source &typeCreation, const quint32 &idTool = 0, QObject *parent = 0); static const QString TagName; static const QString ToolType; virtual int type() const Q_DECL_OVERRIDE {return Type;} diff --git a/src/libs/vtools/tools/vabstracttool.cpp b/src/libs/vtools/tools/vabstracttool.cpp index dff63b2b1..a65cb5fe5 100644 --- a/src/libs/vtools/tools/vabstracttool.cpp +++ b/src/libs/vtools/tools/vabstracttool.cpp @@ -41,6 +41,8 @@ #include #include +const QString VAbstractTool::AttrInUse = QStringLiteral("inUse"); + //--------------------------------------------------------------------------------------------------------------------- /** * @brief VAbstractTool container. diff --git a/src/libs/vtools/tools/vabstracttool.h b/src/libs/vtools/tools/vabstracttool.h index 062eb5bdd..4c1513c87 100644 --- a/src/libs/vtools/tools/vabstracttool.h +++ b/src/libs/vtools/tools/vabstracttool.h @@ -56,6 +56,8 @@ public: virtual ~VAbstractTool() Q_DECL_OVERRIDE; quint32 getId() const; + static const QString AttrInUse; + static const QStringList StylesList(); static Qt::PenStyle LineStyleToPenStyle(const QString &typeLine); static QMap LineStylesPics(); diff --git a/src/libs/vtools/tools/vtooldetail.cpp b/src/libs/vtools/tools/vtooldetail.cpp index 262e419c2..669f6a570 100644 --- a/src/libs/vtools/tools/vtooldetail.cpp +++ b/src/libs/vtools/tools/vtooldetail.cpp @@ -98,7 +98,6 @@ VToolDetail::VToolDetail(VAbstractPattern *doc, VContainer *data, const quint32 qDebug()<<"Get wrong tool type. Ignore."; break; } - doc->IncrementReferens(detail.at(i).getId()); } this->setFlag(QGraphicsItem::ItemIsMovable, true); this->setFlag(QGraphicsItem::ItemIsSelectable, true); @@ -162,29 +161,25 @@ void VToolDetail::Create(DialogTool *dialog, VMainGraphicsScene *scene, VAbstrac case (Tool::NodePoint): { id = CreateNode(data, nodeD.getId()); - VNodePoint::Create(doc, data, scene, id, nodeD.getId(), Document::FullParse, Source::FromGui, - NodeUsage::InUse); + VNodePoint::Create(doc, data, scene, id, nodeD.getId(), Document::FullParse, Source::FromGui); } break; case (Tool::NodeArc): { id = CreateNode(data, nodeD.getId()); - VNodeArc::Create(doc, data, scene, id, nodeD.getId(), Document::FullParse, Source::FromGui, - NodeUsage::InUse); + VNodeArc::Create(doc, data, scene, id, nodeD.getId(), Document::FullParse, Source::FromGui); } break; case (Tool::NodeSpline): { id = CreateNode(data, nodeD.getId()); - VNodeSpline::Create(doc, data, scene, id, nodeD.getId(), Document::FullParse, Source::FromGui, - NodeUsage::InUse); + VNodeSpline::Create(doc, data, scene, id, nodeD.getId(), Document::FullParse, Source::FromGui); } break; case (Tool::NodeSplinePath): { id = CreateNode(data, nodeD.getId()); - VNodeSplinePath::Create(doc, data, scene, id, nodeD.getId(), Document::FullParse, Source::FromGui, - NodeUsage::InUse); + VNodeSplinePath::Create(doc, data, scene, id, nodeD.getId(), Document::FullParse, Source::FromGui); } break; default: diff --git a/src/libs/vtools/tools/vtooluniondetails.cpp b/src/libs/vtools/tools/vtooluniondetails.cpp index 80e538758..3b5b8568b 100644 --- a/src/libs/vtools/tools/vtooluniondetails.cpp +++ b/src/libs/vtools/tools/vtooluniondetails.cpp @@ -64,6 +64,7 @@ VToolUnionDetails::VToolUnionDetails(VAbstractPattern *doc, VContainer *data, co const Source &typeCreation, QObject *parent) :VAbstractTool(doc, data, id, parent), d1(d1), d2(d2), indexD1(indexD1), indexD2(indexD2) { + _referens = 0; ToolCreation(typeCreation); } @@ -105,8 +106,7 @@ void VToolUnionDetails::AddToNewDetail(QObject *tool, VMainGraphicsScene *scene, VPointF *point1 = new VPointF(*point); point1->setMode(Draw::Modeling); id = data->AddGObject(point1); - VNodePoint::Create(doc, data, scene, id, idObject, Document::FullParse, Source::FromGui, - NodeUsage::InUse, idTool, tool); + VNodePoint::Create(doc, data, scene, id, idObject, Document::FullParse, Source::FromGui, idTool, tool); } } break; @@ -142,8 +142,7 @@ void VToolUnionDetails::AddToNewDetail(QObject *tool, VMainGraphicsScene *scene, arc2->setMode(Draw::Modeling); id = data->AddGObject(arc2); - VNodeArc::Create(doc, data, scene, id, idObject, Document::FullParse, Source::FromGui, NodeUsage::InUse, - idTool, tool); + VNodeArc::Create(doc, data, scene, id, idObject, Document::FullParse, Source::FromGui, idTool, tool); } } break; @@ -177,8 +176,7 @@ void VToolUnionDetails::AddToNewDetail(QObject *tool, VMainGraphicsScene *scene, VSpline *spl1 = new VSpline(*spl); spl1->setMode(Draw::Modeling); id = data->AddGObject(spl1); - VNodeSpline::Create(doc, data, scene, id, idObject, Document::FullParse, Source::FromGui, - NodeUsage::InUse, idTool, tool); + VNodeSpline::Create(doc, data, scene, id, idObject, Document::FullParse, Source::FromGui, idTool, tool); delete p4; delete p1; @@ -233,8 +231,8 @@ void VToolUnionDetails::AddToNewDetail(QObject *tool, VMainGraphicsScene *scene, VSplinePath *path1 = new VSplinePath(*path); path1->setMode(Draw::Modeling); id = data->AddGObject(path1); - VNodeSplinePath::Create(doc, data, scene, id, idObject, Document::FullParse, Source::FromGui, - NodeUsage::InUse, idTool, tool); + VNodeSplinePath::Create(doc, data, scene, id, idObject, Document::FullParse, Source::FromGui, idTool, + tool); } } break; @@ -424,6 +422,57 @@ void VToolUnionDetails::ShowVisualization(bool show) Q_UNUSED(show) } +//--------------------------------------------------------------------------------------------------------------------- +void VToolUnionDetails::incrementReferens() +{ + ++_referens; + if (_referens == 1) + { + for (int i = 0; i < d1.CountNode(); ++i) + { + doc->IncrementReferens(d1.at(i).getId()); + } + + for (int i = 0; i < d2.CountNode(); ++i) + { + doc->IncrementReferens(d2.at(i).getId()); + } + + QDomElement domElement = doc->elementById(id); + if (domElement.isElement()) + { + doc->SetParametrUsage(domElement, AttrInUse, NodeUsage::InUse); + } + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolUnionDetails::decrementReferens() +{ + if (_referens > 0) + { + --_referens; + } + if (_referens == 0) + { + for (int i = 0; i < d1.CountNode(); ++i) + { + doc->DecrementReferens(d1.at(i).getId()); + } + + for (int i = 0; i < d2.CountNode(); ++i) + { + doc->DecrementReferens(d2.at(i).getId()); + } + + QDomElement domElement = doc->elementById(id); + if (domElement.isElement()) + { + doc->SetParametrUsage(domElement, AttrInUse, NodeUsage::NotInUse); + } + } +} + //--------------------------------------------------------------------------------------------------------------------- /** * @brief Create help create tool from GUI. @@ -490,15 +539,6 @@ VToolUnionDetails* VToolUnionDetails::Create(const quint32 _id, const VDetail &d unionDetails = new VToolUnionDetails(doc, data, id, d1, d2, indexD1, indexD2, typeCreation, doc); QHash* tools = doc->getTools(); tools->insert(id, unionDetails); - for (int i = 0; i < d1.CountNode(); ++i) - { - doc->IncrementReferens(d1.at(i).getId()); - } - for (int i = 0; i < d2.CountNode(); ++i) - { - doc->IncrementReferens(d2.at(i).getId()); - } - } //Then create new details VNodeDetail det1p1; diff --git a/src/libs/vtools/tools/vtooluniondetails.h b/src/libs/vtools/tools/vtooluniondetails.h index 29251b1eb..e5cb984d2 100644 --- a/src/libs/vtools/tools/vtooluniondetails.h +++ b/src/libs/vtools/tools/vtooluniondetails.h @@ -79,6 +79,8 @@ public: const qreal &angle); virtual QString getTagName() const Q_DECL_OVERRIDE; virtual void ShowVisualization(bool show) Q_DECL_OVERRIDE; + virtual void incrementReferens() Q_DECL_OVERRIDE; + virtual void decrementReferens() Q_DECL_OVERRIDE; public slots: /** * @brief FullUpdateFromFile update tool data form file.