From b848a2eb7ff2d58251d1f83356c6e6e7a74f23ea Mon Sep 17 00:00:00 2001 From: Luboš Luňák Date: Fri, 23 Sep 2011 17:51:41 +0200 Subject: debug support for dumping writer nodes structure Similarly to the layout debug support. F12 -> layout, Shift+F12 -> nodes. --- sw/Library_sw.mk | 1 + sw/inc/doc.hxx | 8 ++ sw/inc/ndarr.hxx | 11 ++ sw/inc/ndtxt.hxx | 4 + sw/inc/node.hxx | 12 +++ sw/source/core/docnode/nodedump.cxx | 199 ++++++++++++++++++++++++++++++++++++ sw/source/ui/docvw/edtwin.cxx | 16 ++- 7 files changed, 247 insertions(+), 4 deletions(-) create mode 100644 sw/source/core/docnode/nodedump.cxx diff --git a/sw/Library_sw.mk b/sw/Library_sw.mk index f1e7d5c72425..a486d5c4d2ff 100644 --- a/sw/Library_sw.mk +++ b/sw/Library_sw.mk @@ -215,6 +215,7 @@ $(eval $(call gb_Library_add_exception_objects,sw,\ sw/source/core/docnode/ndtbl \ sw/source/core/docnode/ndtbl1 \ sw/source/core/docnode/node \ + sw/source/core/docnode/nodedump \ sw/source/core/docnode/node2lay \ sw/source/core/docnode/nodes \ sw/source/core/docnode/observablethread \ diff --git a/sw/inc/doc.hxx b/sw/inc/doc.hxx index be85f2cd706f..3461e6d10b43 100644 --- a/sw/inc/doc.hxx +++ b/sw/inc/doc.hxx @@ -2033,6 +2033,14 @@ public: ::sw::UndoManager & GetUndoManager(); ::sw::UndoManager const& GetUndoManager() const; SfxObjectShell* CreateCopy(bool bCallInitNew) const; + +#if OSL_DEBUG_LEVEL > 0 + /** + * Dumps the entire nodes structure to the given destination (file nodes.xml in the current directory by default) + * @since 3.5 + */ + void dumpAsXml( xmlTextWriterPtr writer = NULL ); +#endif }; // This method is called in Dtor of SwDoc and deletes cache of ContourObjects. diff --git a/sw/inc/ndarr.hxx b/sw/inc/ndarr.hxx index 71c447ab7c0b..019ccb6a0f9a 100644 --- a/sw/inc/ndarr.hxx +++ b/sw/inc/ndarr.hxx @@ -41,6 +41,9 @@ #include #include +#include +#include + class Graphic; class GraphicObject; class String; @@ -333,6 +336,14 @@ public: SwNode * DocumentSectionStartNode(SwNode * pNode) const; SwNode * DocumentSectionEndNode(SwNode * pNode) const; + +#if OSL_DEBUG_LEVEL > 0 + /** + * Dumps the entire nodes structure to the given destination (file nodes.xml in the current directory by default) + * @since 3.5 + */ + void dumpAsXml( xmlTextWriterPtr writer = NULL ); +#endif }; #endif diff --git a/sw/inc/ndtxt.hxx b/sw/inc/ndtxt.hxx index 7fb3b552aaf1..fc60c194c4ec 100644 --- a/sw/inc/ndtxt.hxx +++ b/sw/inc/ndtxt.hxx @@ -801,6 +801,10 @@ public: bool IsCollapse() const; +#if OSL_DEBUG_LEVEL > 0 + virtual void dumpAsXml( xmlTextWriterPtr writer = NULL ); +#endif + DECL_FIXEDMEMPOOL_NEWDEL(SwTxtNode) }; diff --git a/sw/inc/node.hxx b/sw/inc/node.hxx index 5860f25a9712..583b8e6ce617 100644 --- a/sw/inc/node.hxx +++ b/sw/inc/node.hxx @@ -297,6 +297,14 @@ public: sal_uInt8 HasPrevNextLayNode() const; +#if OSL_DEBUG_LEVEL > 0 + /** + * Dumps the node structure to the given destination (file nodes.xml in the current directory by default) + * @since 3.5 + */ + virtual void dumpAsXml( xmlTextWriterPtr writer = NULL ); +#endif + private: // Private constructor because copying is never allowed!! SwNode( const SwNode & rNodes ); @@ -330,6 +338,10 @@ public: // Call ChkCondcoll to all ContentNodes of section. void CheckSectionCondColl() const; +#if OSL_DEBUG_LEVEL > 0 + virtual void dumpAsXml( xmlTextWriterPtr writer = NULL ); +#endif + private: // Private constructor because copying is never allowed!! SwStartNode( const SwStartNode & rNode ); diff --git a/sw/source/core/docnode/nodedump.cxx b/sw/source/core/docnode/nodedump.cxx new file mode 100644 index 000000000000..17d6c8793a51 --- /dev/null +++ b/sw/source/core/docnode/nodedump.cxx @@ -0,0 +1,199 @@ +/* + * Version: MPL 1.1 / GPLv3+ / LGPLv3+ + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License or as specified alternatively below. You may obtain a copy of + * the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * Major Contributor(s): + * [ Copyright (C) 2011 Lubos Lunak (initial developer) ] + * + * All Rights Reserved. + * + * For minor contributions see the git repository. + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 3 or later (the "GPLv3+"), or + * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"), + * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable + * instead of those above. + */ + +#include "doc.hxx" +#include "ndtxt.hxx" + +#if OSL_DEBUG_LEVEL > 0 + +namespace +{ + +// Small helper class to ensure that we write to nodes.xml if nothing +// has been explicitly specified. +// Always use at the beginning of dumpAsXml(). +// Also, there are some functions to save typing. +class WriterHelper +{ +public: + WriterHelper( xmlTextWriterPtr ); + ~WriterHelper(); + operator xmlTextWriterPtr(); + xmlTextWriterPtr operator->(); + void startElement( const char* element ); + void endElement(); + void writeFormatAttribute( const char* attribute, const char* format, ... ) LIBXML_ATTR_FORMAT(3,4); +private: + xmlTextWriterPtr writer; + bool owns; +}; + +WriterHelper::WriterHelper( xmlTextWriterPtr w ) + : writer( w ) + , owns( false ) +{ + if( writer == NULL ) + { + writer = xmlNewTextWriterFilename( "nodes.xml", 0 ); + xmlTextWriterStartDocument( writer, NULL, NULL, NULL ); + owns = true; + } +} + +WriterHelper::~WriterHelper() +{ + if( owns ) + { + xmlTextWriterEndDocument( writer ); + xmlFreeTextWriter( writer ); + } +} + +WriterHelper::operator xmlTextWriterPtr() +{ + return writer; +} + +xmlTextWriterPtr WriterHelper::operator->() +{ + return writer; +} + +void WriterHelper::startElement( const char* element ) +{ + xmlTextWriterStartElement( writer, BAD_CAST( element )); +} + +void WriterHelper::endElement() +{ + xmlTextWriterEndElement( writer ); +} + +void WriterHelper::writeFormatAttribute( const char* attribute, const char* format, ... ) +{ + va_list va; + va_start( va, format ); + xmlTextWriterWriteVFormatAttribute( writer, BAD_CAST( attribute ), format, va ); + va_end( va ); +} + +} + +void SwDoc::dumpAsXml( xmlTextWriterPtr w ) +{ + WriterHelper writer( w ); + writer.startElement( "doc" ); + writer.writeFormatAttribute( "ptr", "%p", this ); + m_pNodes->dumpAsXml( writer ); + writer.endElement(); +} + +void SwNodes::dumpAsXml( xmlTextWriterPtr w ) +{ + WriterHelper writer( w ); + writer.startElement( "swnodes" ); + writer.writeFormatAttribute( "ptr", "%p", this ); + for( unsigned int i = 0; i < Count(); ++i ) + { + ( *this )[ i ]->dumpAsXml( writer ); + } + writer.endElement(); +} + +void SwNode::dumpAsXml( xmlTextWriterPtr w ) +{ + WriterHelper writer( w ); + const char* name = "???"; + switch( GetNodeType()) + { + case ND_ENDNODE: + name = "end"; + break; + case ND_STARTNODE: + case ND_TEXTNODE: + abort(); // overriden + case ND_TABLENODE: + name = "table"; + break; + case ND_GRFNODE: + name = "grf"; + break; + case ND_OLENODE: + name = "ole"; + break; + } + writer.startElement( name ); + writer.writeFormatAttribute( "ptr", "%p", this ); + writer.endElement(); + if( GetNodeType() == ND_ENDNODE ) + writer.endElement(); // end start node +} + +void SwStartNode::dumpAsXml( xmlTextWriterPtr w ) +{ + WriterHelper writer( w ); + const char* name = "???"; + switch( GetStartNodeType()) + { + case SwNormalStartNode: + name = "start"; + break; + case SwTableBoxStartNode: + name = "tablebox"; + break; + case SwFlyStartNode: + name = "fly"; + break; + case SwFootnoteStartNode: + name = "footnote"; + break; + case SwHeaderStartNode: + name = "header"; + break; + case SwFooterStartNode: + name = "footer"; + break; + } + writer.startElement( name ); + writer.writeFormatAttribute( "ptr", "%p", this ); + // writer.endElement(); - it is a start node, so don't end, will make xml better nested +} + +void SwTxtNode::dumpAsXml( xmlTextWriterPtr w ) +{ + WriterHelper writer( w ); + writer.startElement( "text" ); + writer.writeFormatAttribute( "ptr", "%p", this ); + rtl::OUString txt = GetTxt(); + for( int i = 0; i < 32; ++i ) + txt = txt.replace( i, '*' ); + rtl::OString txt8 = ::rtl::OUStringToOString( txt, RTL_TEXTENCODING_UTF8 ); + xmlTextWriterWriteString( writer, BAD_CAST( txt8.getStr())); + writer.endElement(); +} + +#endif // OSL_DEBUG_LEVEL diff --git a/sw/source/ui/docvw/edtwin.cxx b/sw/source/ui/docvw/edtwin.cxx index cac527739ce7..bc1e4b8774f0 100644 --- a/sw/source/ui/docvw/edtwin.cxx +++ b/sw/source/ui/docvw/edtwin.cxx @@ -1363,12 +1363,20 @@ void SwEditWin::KeyInput(const KeyEvent &rKEvt) sal_Bool bChkInsBlank = pQuickHlpData->bChkInsBlank; pQuickHlpData->bChkInsBlank = sal_False; -#if OSL_DEBUG_LEVEL > 1 +#if OSL_DEBUG_LEVEL > 0 if (rKEvt.GetKeyCode().GetCode() == KEY_F12) { - SwRootFrm* pLayout = GetView().GetDocShell()->GetWrtShell()->GetLayout(); - pLayout->dumpAsXml( ); - return; + if( rKEvt.GetKeyCode().IsShift()) + { + GetView().GetDocShell()->GetDoc()->dumpAsXml(); + return; + } + else + { + SwRootFrm* pLayout = GetView().GetDocShell()->GetWrtShell()->GetLayout(); + pLayout->dumpAsXml( ); + return; + } } #endif -- cgit