Commit 15af8f56 authored by ElenaSubbotina's avatar ElenaSubbotina

OdfFormatWriter - fix picture size from placeholder

parent 58f8d13d
...@@ -42,6 +42,8 @@ ...@@ -42,6 +42,8 @@
#include "../../../ASCOfficePPTXFile/PPTXFormat/Logic/Timing/Seq.h" #include "../../../ASCOfficePPTXFile/PPTXFormat/Logic/Timing/Seq.h"
#include "../../../ASCOfficePPTXFile/PPTXFormat/Logic/Timing/CTn.h" #include "../../../ASCOfficePPTXFile/PPTXFormat/Logic/Timing/CTn.h"
#include "../../../ASCOfficePPTXFile/PPTXFormat/Logic/CxnSp.h"
#include "../../../ASCOfficePPTXFile/PPTXFormat/Logic/Transitions/EmptyTransition.h" #include "../../../ASCOfficePPTXFile/PPTXFormat/Logic/Transitions/EmptyTransition.h"
#include "../../../ASCOfficePPTXFile/PPTXFormat/Logic/Transitions/OrientationTransition.h" #include "../../../ASCOfficePPTXFile/PPTXFormat/Logic/Transitions/OrientationTransition.h"
#include "../../../ASCOfficePPTXFile/PPTXFormat/Logic/Transitions/EightDirectionTransition.h" #include "../../../ASCOfficePPTXFile/PPTXFormat/Logic/Transitions/EightDirectionTransition.h"
...@@ -1338,24 +1340,35 @@ void PptxConverter::convert_slide(PPTX::Logic::CSld *oox_slide, PPTX::Logic::TxS ...@@ -1338,24 +1340,35 @@ void PptxConverter::convert_slide(PPTX::Logic::CSld *oox_slide, PPTX::Logic::TxS
for (size_t i = 0 ; i < oox_slide->spTree.SpTreeElems.size(); i++) for (size_t i = 0 ; i < oox_slide->spTree.SpTreeElems.size(); i++)
{ {
smart_ptr<PPTX::WrapperWritingElement> pElem = oox_slide->spTree.SpTreeElems[i].GetElem(); smart_ptr<PPTX::WrapperWritingElement> pElem = oox_slide->spTree.SpTreeElems[i].GetElem();
smart_ptr<PPTX::Logic::Shape> pShape = pElem.smart_dynamic_cast<PPTX::Logic::Shape>(); smart_ptr<PPTX::Logic::Shape> pShape = pElem.smart_dynamic_cast<PPTX::Logic::Shape>();
smart_ptr<PPTX::Logic::Pic> pPic = pElem.smart_dynamic_cast<PPTX::Logic::Pic>();
odf_context()->drawing_context()->start_drawing(); odf_context()->drawing_context()->start_drawing();
if (pShape.IsInit()) PPTX::Logic::NvPr *pNvPr = NULL;
{
if (pShape->nvSpPr.nvPr.ph.is_init()) if (pShape.IsInit()) pNvPr = &pShape->nvSpPr.nvPr;
if (pPic.IsInit()) pNvPr = &pPic->nvPicPr.nvPr;
bool bConvert = false;
if ((pNvPr) && (pNvPr->ph.is_init()))
{ {
if (type == Notes || type == NotesMaster) if (type == Notes || type == NotesMaster)
{ {
pShape->nvSpPr.nvPr.ph->idx.reset(); if (pShape.IsInit()) pShape->nvSpPr.nvPr.ph->idx.reset();
if (pPic.IsInit()) pPic->nvPicPr.nvPr.ph->idx.reset();
} }
if (bFillUp) if (bFillUp)
pShape->FillLevelUp(); {
if (pShape.IsInit()) pShape->FillLevelUp();
if (pPic.IsInit()) pPic->FillLevelUp();
}
if (pShape->nvSpPr.nvPr.ph->type.IsInit()) if (pNvPr->ph->type.IsInit())
{ {
int ph_type = pShape->nvSpPr.nvPr.ph->type->GetBYTECode(); int ph_type = pNvPr->ph->type->GetBYTECode();
if (type == Layout && (ph_type == 5 || ph_type == 6 || ph_type == 7 || ph_type == 12)) if (type == Layout && (ph_type == 5 || ph_type == 6 || ph_type == 7 || ph_type == 12))
continue; continue;
...@@ -1365,8 +1378,8 @@ void PptxConverter::convert_slide(PPTX::Logic::CSld *oox_slide, PPTX::Logic::TxS ...@@ -1365,8 +1378,8 @@ void PptxConverter::convert_slide(PPTX::Logic::CSld *oox_slide, PPTX::Logic::TxS
else else
odf_context()->drawing_context()->set_placeholder_type(0); odf_context()->drawing_context()->set_placeholder_type(0);
if (pShape->nvSpPr.nvPr.ph->idx.IsInit()) if (pNvPr->ph->idx.IsInit())
odf_context()->drawing_context()->set_placeholder_id(pShape->nvSpPr.nvPr.ph->idx.get()); odf_context()->drawing_context()->set_placeholder_id(pNvPr->ph->idx.get());
if (!bPlaceholders) if (!bPlaceholders)
continue; continue;
...@@ -1375,7 +1388,8 @@ void PptxConverter::convert_slide(PPTX::Logic::CSld *oox_slide, PPTX::Logic::TxS ...@@ -1375,7 +1388,8 @@ void PptxConverter::convert_slide(PPTX::Logic::CSld *oox_slide, PPTX::Logic::TxS
if (txStyles) if (txStyles)
{ {
std::wstring type = pShape->nvSpPr.nvPr.ph->type.get_value_or(_T("body")); std::wstring type = pNvPr->ph->type.get_value_or(_T("body"));
if ((type == L"title") || (type == L"ctrTitle")) if ((type == L"title") || (type == L"ctrTitle"))
listMasterStyle = txStyles->titleStyle.GetPointer(); listMasterStyle = txStyles->titleStyle.GetPointer();
else if ((type == L"body") || (type == L"subTitle") || (type == L"obj")) else if ((type == L"body") || (type == L"subTitle") || (type == L"obj"))
...@@ -1383,6 +1397,9 @@ void PptxConverter::convert_slide(PPTX::Logic::CSld *oox_slide, PPTX::Logic::TxS ...@@ -1383,6 +1397,9 @@ void PptxConverter::convert_slide(PPTX::Logic::CSld *oox_slide, PPTX::Logic::TxS
else if (type != L"") else if (type != L"")
listMasterStyle = txStyles->otherStyle.GetPointer(); listMasterStyle = txStyles->otherStyle.GetPointer();
} }
if (pShape.IsInit())
{
PPTX::Logic::Shape update_shape; PPTX::Logic::Shape update_shape;
if (listMasterStyle) if (listMasterStyle)
...@@ -1401,7 +1418,17 @@ void PptxConverter::convert_slide(PPTX::Logic::CSld *oox_slide, PPTX::Logic::TxS ...@@ -1401,7 +1418,17 @@ void PptxConverter::convert_slide(PPTX::Logic::CSld *oox_slide, PPTX::Logic::TxS
pShape->Merge(update_shape); pShape->Merge(update_shape);
OoxConverter::convert(&update_shape); OoxConverter::convert(&update_shape);
} }
else if (pShape->txBody.IsInit() && presentation->defaultTextStyle.IsInit()) if (pPic.IsInit())
{
PPTX::Logic::Pic update_shape;
pPic->Merge(update_shape);
OoxConverter::convert(&update_shape);
}
bConvert = true;
}
if (!bConvert && (pShape.IsInit()) && (pShape->txBody.IsInit() && presentation->defaultTextStyle.IsInit()))
{//default text style with master clrScheme {//default text style with master clrScheme
PPTX::Logic::Shape update_shape; PPTX::Logic::Shape update_shape;
...@@ -1411,14 +1438,16 @@ void PptxConverter::convert_slide(PPTX::Logic::CSld *oox_slide, PPTX::Logic::TxS ...@@ -1411,14 +1438,16 @@ void PptxConverter::convert_slide(PPTX::Logic::CSld *oox_slide, PPTX::Logic::TxS
pShape->Merge(update_shape); pShape->Merge(update_shape);
OoxConverter::convert(&update_shape); OoxConverter::convert(&update_shape);
bConvert = true;
} }
else
OoxConverter::convert(pShape.operator->());
} if (!bConvert)
else
{ {
OoxConverter::convert(pElem.operator->()); OoxConverter::convert(pElem.operator->());
} }
odf_context()->drawing_context()->end_drawing(); odf_context()->drawing_context()->end_drawing();
} }
convert(oox_slide->controls.GetPointer()); convert(oox_slide->controls.GetPointer());
......
...@@ -69,6 +69,11 @@ namespace PPTX ...@@ -69,6 +69,11 @@ namespace PPTX
DWORD GetLine(Ln& line)const; DWORD GetLine(Ln& line)const;
DWORD GetFill(UniFill& fill)const; DWORD GetFill(UniFill& fill)const;
//void FillLevelUp();
//void Merge(CxnSp& cxnSp, bool bIsSlidePlaceholder = false);
//void SetLevelUpElement( CxnSp* p){m_pLevelUp = p;};
virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const
{ {
pWriter->StartRecord(SPTREE_TYPE_CXNSP); pWriter->StartRecord(SPTREE_TYPE_CXNSP);
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include "Pic.h" #include "Pic.h"
#include "SpTree.h" #include "SpTree.h"
#include "Shape.h"
#include "./../SlideLayout.h" #include "./../SlideLayout.h"
#include "./../SlideMaster.h" #include "./../SlideMaster.h"
...@@ -530,23 +531,27 @@ namespace PPTX ...@@ -530,23 +531,27 @@ namespace PPTX
Pic::Pic(std::wstring ns) Pic::Pic(std::wstring ns)
{ {
m_namespace = ns; m_namespace = ns;
m_pLevelUp = NULL;
} }
Pic::~Pic() Pic::~Pic()
{ {
} }
Pic::Pic(XmlUtils::CXmlNode& node) Pic::Pic(XmlUtils::CXmlNode& node)
{ {
m_pLevelUp = NULL;
fromXML(node); fromXML(node);
} }
Pic::Pic(XmlUtils::CXmlLiteReader& oReader)
{
m_pLevelUp = NULL;
fromXML(oReader);
}
const Pic& Pic::operator =(XmlUtils::CXmlNode& node) const Pic& Pic::operator =(XmlUtils::CXmlNode& node)
{ {
fromXML(node); fromXML(node);
return *this; return *this;
} }
Pic::Pic(XmlUtils::CXmlLiteReader& oReader)
{
fromXML(oReader);
}
const Pic& Pic::operator =(XmlUtils::CXmlLiteReader& oReader) const Pic& Pic::operator =(XmlUtils::CXmlLiteReader& oReader)
{ {
fromXML(oReader); fromXML(oReader);
...@@ -991,6 +996,45 @@ namespace PPTX ...@@ -991,6 +996,45 @@ namespace PPTX
pReader->Seek(_end_rec); pReader->Seek(_end_rec);
} }
void Pic::FillLevelUp()
{
if ((m_pLevelUp == NULL) && (nvPicPr.nvPr.ph.IsInit()))
{
if ((nvPicPr.nvPr.ph->type.IsInit()) || (nvPicPr.nvPr.ph->idx.IsInit()))
{
if (parentFileIs<Slide>())
{
parentFileAs<Slide>().Layout->GetLevelUp(this);
}
else if(parentFileIs<SlideLayout>())
{
parentFileAs<SlideLayout>().Master->GetLevelUp(this);
}
else if(parentFileIs<NotesSlide>())
{
parentFileAs<NotesSlide>().master_->GetLevelUp(this);
}
}
}
}
void Pic::Merge(Pic& pic, bool bIsSlidePlaceholder)
{
if (m_pLevelUp)
m_pLevelUp->Merge(pic, true);
pic.nvPicPr = nvPicPr;
pic.blipFill = blipFill;
pic.oleObject = oleObject;
spPr.Merge(pic.spPr);
if (style.is_init())
{
pic.style = style;
pic.style->SetParentFilePointer(parentFile);
}
}
void Pic::FillParentPointersForChilds() void Pic::FillParentPointersForChilds()
{ {
......
...@@ -179,6 +179,7 @@ namespace PPTX ...@@ -179,6 +179,7 @@ namespace PPTX
{ {
namespace Logic namespace Logic
{ {
class Shape;
class COLEObject : public WrapperWritingElement class COLEObject : public WrapperWritingElement
{ {
public: public:
...@@ -251,6 +252,11 @@ namespace PPTX ...@@ -251,6 +252,11 @@ namespace PPTX
double GetEndTrim () const; double GetEndTrim () const;
long GetRefId() const; long GetRefId() const;
void FillLevelUp();
void Merge(Pic& pic, bool bIsSlidePlaceholder = false);
void SetLevelUpElement( Shape* p){m_pLevelUp = p;};
virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader);
virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const;
...@@ -258,6 +264,7 @@ namespace PPTX ...@@ -258,6 +264,7 @@ namespace PPTX
virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const;
void toXmlWriterVML(NSBinPptxRW::CXmlWriter* pWriter, smart_ptr<PPTX::Theme>& oTheme, smart_ptr<PPTX::Logic::ClrMap>& oClrMap, bool in_group = false); void toXmlWriterVML(NSBinPptxRW::CXmlWriter* pWriter, smart_ptr<PPTX::Theme>& oTheme, smart_ptr<PPTX::Logic::ClrMap>& oClrMap, bool in_group = false);
//---------------------------------------------------------------------- //----------------------------------------------------------------------
Shape* m_pLevelUp;
NvPicPr nvPicPr; NvPicPr nvPicPr;
mutable BlipFill blipFill; mutable BlipFill blipFill;
SpPr spPr; SpPr spPr;
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include "../SlideMaster.h" #include "../SlideMaster.h"
#include "../Slide.h" #include "../Slide.h"
#include "SpTree.h" #include "SpTree.h"
#include "Pic.h"
namespace PPTX namespace PPTX
{ {
...@@ -493,7 +494,22 @@ namespace PPTX ...@@ -493,7 +494,22 @@ namespace PPTX
return txBody->lstStyle->IsListStyleEmpty(); return txBody->lstStyle->IsListStyleEmpty();
} }
void Shape::Merge(Pic& pic, bool bIsSlidePlaceholder)
{
if (m_pLevelUp)
m_pLevelUp->Merge(pic, true);
pic.nvPicPr.cNvPr = nvSpPr.cNvPr;
pic.nvPicPr.nvPr = nvSpPr.nvPr;
spPr.Merge(pic.spPr);
if (style.is_init())
{
pic.style = style;
pic.style->SetParentFilePointer(parentFile);
}
}
void Shape::Merge(Shape& shape, bool bIsSlidePlaceholder) void Shape::Merge(Shape& shape, bool bIsSlidePlaceholder)
{ {
if (m_pLevelUp) if (m_pLevelUp)
......
...@@ -272,6 +272,7 @@ namespace PPTX ...@@ -272,6 +272,7 @@ namespace PPTX
{ {
namespace Logic namespace Logic
{ {
class Pic;
class Shape : public WrapperWritingElement class Shape : public WrapperWritingElement
{ {
public: public:
...@@ -304,6 +305,7 @@ namespace PPTX ...@@ -304,6 +305,7 @@ namespace PPTX
void FillLevelUp(); void FillLevelUp();
void Merge(Shape& shape, bool bIsSlidePlaceholder = false); void Merge(Shape& shape, bool bIsSlidePlaceholder = false);
void Merge(Pic& pic, bool bIsSlidePlaceholder = false);
bool IsListStyleEmpty(); bool IsListStyleEmpty();
void SetLevelUpElement( Shape* p){m_pLevelUp = p;}; void SetLevelUpElement( Shape* p){m_pLevelUp = p;};
......
...@@ -183,14 +183,23 @@ namespace PPTX ...@@ -183,14 +183,23 @@ namespace PPTX
pReader->Seek(end); pReader->Seek(end);
} }
virtual void GetLevelUp(Logic::Shape* pShape) virtual void GetLevelUp(WrapperWritingElement* pElem)
{ {
if (!pShape) return; Logic::Shape *pShape = dynamic_cast<PPTX::Logic::Shape*>(pElem);
Logic::Pic *pPic = dynamic_cast<PPTX::Logic::Pic*>(pElem);
if (pShape->nvSpPr.nvPr.ph.is_init()) if (!pShape && !pPic) return;
{
std::wstring idx = pShape->nvSpPr.nvPr.ph->idx.get_value_or(L""); Logic::NvPr *pNvPr = NULL;
std::wstring type = pShape->nvSpPr.nvPr.ph->type.get_value_or(L"body");
if (pShape) pNvPr = &pShape->nvSpPr.nvPr;
if (pPic) pNvPr = &pPic->nvPicPr.nvPr;
if (!pNvPr) return;
if (pNvPr->ph.is_init() == false) return;
std::wstring idx = pNvPr->ph->idx.get_value_or(L"");
std::wstring type = pNvPr->ph->type.get_value_or(L"body");
if (type == L"ctrTitle") type = L"title"; if (type == L"ctrTitle") type = L"title";
...@@ -209,19 +218,20 @@ namespace PPTX ...@@ -209,19 +218,20 @@ namespace PPTX
if ((type == lType) && (idx == lIdx) && !idx.empty()) if ((type == lType) && (idx == lIdx) && !idx.empty())
{ {
pShape->SetLevelUpElement(pMasterShape.operator->()); if (pShape) pShape->SetLevelUpElement(pMasterShape.operator->());
if (pPic) pPic->SetLevelUpElement(pMasterShape.operator->());
return; return;
} }
else if ((type == lType) && idx.empty() && lIdx.empty()) else if ((type == lType) && idx.empty() && lIdx.empty())
{ {
pShape->SetLevelUpElement(pMasterShape.operator->()); if (pShape) pShape->SetLevelUpElement(pMasterShape.operator->());
if (pPic) pPic->SetLevelUpElement(pMasterShape.operator->());
return; return;
} }
} }
} }
} }
} }
}
smart_ptr<Theme> theme_; smart_ptr<Theme> theme_;
smart_ptr<TableStyles> tableStyles_; smart_ptr<TableStyles> tableStyles_;
......
...@@ -124,14 +124,23 @@ namespace PPTX ...@@ -124,14 +124,23 @@ namespace PPTX
return type().DefaultFileName(); return type().DefaultFileName();
} }
virtual void GetLevelUp(Logic::Shape* pShape) virtual void GetLevelUp(WrapperWritingElement* pElem)
{ {
if (!pShape) return; Logic::Shape *pShape = dynamic_cast<PPTX::Logic::Shape*>(pElem);
Logic::Pic *pPic = dynamic_cast<PPTX::Logic::Pic*>(pElem);
if (pShape->nvSpPr.nvPr.ph.is_init()) if (!pShape && !pPic) return;
{
std::wstring idx = pShape->nvSpPr.nvPr.ph->idx.get_value_or(L""); Logic::NvPr *pNvPr = NULL;
std::wstring type = pShape->nvSpPr.nvPr.ph->type.get_value_or(L"body");
if (pShape) pNvPr = &pShape->nvSpPr.nvPr;
if (pPic) pNvPr = &pPic->nvPicPr.nvPr;
if (!pNvPr) return;
if (pNvPr->ph.is_init() == false) return;
std::wstring idx = pNvPr->ph->idx.get_value_or(L"");
std::wstring type = pNvPr->ph->type.get_value_or(L"body");
if (type == L"ctrTitle") type = L"title"; if (type == L"ctrTitle") type = L"title";
...@@ -150,26 +159,29 @@ namespace PPTX ...@@ -150,26 +159,29 @@ namespace PPTX
if ((type == lType) && (idx == lIdx) && !idx.empty()) if ((type == lType) && (idx == lIdx) && !idx.empty())
{ {
pShape->SetLevelUpElement(pLayoutShape.operator->()); if (pShape) pShape->SetLevelUpElement(pLayoutShape.operator->());
if (pPic) pPic->SetLevelUpElement(pLayoutShape.operator->());
return; return;
} }
else if ((type == lType) && idx.empty() && lIdx.empty()) else if ((type == lType) && idx.empty() && lIdx.empty())
{ {
pShape->SetLevelUpElement(pLayoutShape.operator->()); if (pShape) pShape->SetLevelUpElement(pLayoutShape.operator->());
if (pPic) pPic->SetLevelUpElement(pLayoutShape.operator->());
return; return;
} }
} }
} }
} }
if (pShape->nvSpPr.nvPr.ph->idx.IsInit()) if (pNvPr->ph->idx.IsInit())
{ {
//not found in layout !! 100818_건강보험과_보건의료_김용익_최종.pptx //not found in layout !! 100818_건강보험과_보건의료_김용익_최종.pptx
bool bShapeMaster = showMasterSp.get_value_or(true); bool bShapeMaster = showMasterSp.get_value_or(true);
if (Master.IsInit() && bShapeMaster) if (Master.IsInit() && bShapeMaster)
{ {
Master->GetLevelUp(pShape); Master->GetLevelUp(pElem);
}
} }
} }
} }
......
...@@ -130,14 +130,23 @@ namespace PPTX ...@@ -130,14 +130,23 @@ namespace PPTX
{ {
return type().DefaultFileName(); return type().DefaultFileName();
} }
void GetLevelUp(Logic::Shape* pShape) void GetLevelUp(WrapperWritingElement* pElem)
{ {
if (!pShape) return; Logic::Shape *pShape = dynamic_cast<PPTX::Logic::Shape*>(pElem);
Logic::Pic *pPic = dynamic_cast<PPTX::Logic::Pic*>(pElem);
if(pShape->nvSpPr.nvPr.ph.is_init()) if (!pShape && !pPic) return;
{
std::wstring idx = pShape->nvSpPr.nvPr.ph->idx.get_value_or(_T("0")); Logic::NvPr *pNvPr = NULL;
std::wstring type = pShape->nvSpPr.nvPr.ph->type.get_value_or(_T("body"));
if (pShape) pNvPr = &pShape->nvSpPr.nvPr;
if (pPic) pNvPr = &pPic->nvPicPr.nvPr;
if (!pNvPr) return;
if (pNvPr->ph.is_init() == false) return;
std::wstring idx = pNvPr->ph->idx.get_value_or(_T("0"));
std::wstring type = pNvPr->ph->type.get_value_or(_T("body"));
if (type == _T("ctrTitle")) type = _T("title"); if (type == _T("ctrTitle")) type = _T("title");
...@@ -154,14 +163,15 @@ namespace PPTX ...@@ -154,14 +163,15 @@ namespace PPTX
if (lType == L"ctrTitle") lType = L"title"; if (lType == L"ctrTitle") lType = L"title";
if (type == lType) if (type == lType)
{ {
pShape->SetLevelUpElement(pMasterShape.operator->()); if (pShape) pShape->SetLevelUpElement(pMasterShape.operator->());
if (pPic) pPic->SetLevelUpElement(pMasterShape.operator->());
return; return;
} }
} }
} }
} }
} }
}
virtual std::wstring GetImagePathNameFromRId(const OOX::RId& rid)const virtual std::wstring GetImagePathNameFromRId(const OOX::RId& rid)const
{ {
smart_ptr<OOX::Image> p = Get<OOX::Image>(rid); smart_ptr<OOX::Image> p = Get<OOX::Image>(rid);
......
...@@ -893,6 +893,8 @@ namespace BinXlsxRW ...@@ -893,6 +893,8 @@ namespace BinXlsxRW
} }
else if(c_oserct_chartspaceCLRMAPOVR == type) else if(c_oserct_chartspaceCLRMAPOVR == type)
{ {
BYTE typeRec1 = m_oBufferedStream.GetUChar();
poVal->m_oClrMapOvr = new PPTX::Logic::ClrMap(); poVal->m_oClrMapOvr = new PPTX::Logic::ClrMap();
poVal->m_oClrMapOvr->m_name = L"c:clrMapOvr"; poVal->m_oClrMapOvr->m_name = L"c:clrMapOvr";
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment