Hi, I have submitted a patch for review:
https://gerrit.libreoffice.org/2577 To pull it, you can do: git pull ssh://gerrit.libreoffice.org:29418/core refs/changes/77/2577/1 Changes to enable display of comments annotations in pptx files Change-Id: I752f97dddd7f85cf7481f738d8a94df056adcb4a --- M oox/inc/oox/core/fragmenthandler2.hxx A oox/inc/oox/ppt/comments.hxx M oox/inc/oox/ppt/slidepersist.hxx M oox/source/core/fragmenthandler2.cxx M oox/source/ppt/presentationfragmenthandler.cxx M oox/source/ppt/slidefragmenthandler.cxx 6 files changed, 295 insertions(+), 3 deletions(-) diff --git a/oox/inc/oox/core/fragmenthandler2.hxx b/oox/inc/oox/core/fragmenthandler2.hxx index 5be5b62..86f7ea8 100644 --- a/oox/inc/oox/core/fragmenthandler2.hxx +++ b/oox/inc/oox/core/fragmenthandler2.hxx @@ -50,6 +50,11 @@ const ::rtl::OUString& rFragmentPath, bool bEnableTrimSpace = true ); virtual ~FragmentHandler2(); +private: + ::std::vector< rtl::OUString> charVector; // handle char in OnCharacters + +public: + ::std::vector< rtl::OUString> getCharVector(void) { return charVector; } // resolve ambiguity from base classes virtual void SAL_CALL acquire() throw() { FragmentHandler::acquire(); } diff --git a/oox/inc/oox/ppt/comments.hxx b/oox/inc/oox/ppt/comments.hxx new file mode 100644 index 0000000..ffd6a41 --- /dev/null +++ b/oox/inc/oox/ppt/comments.hxx @@ -0,0 +1,193 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +#ifndef OOX_PPT_COMMENTS_HXX +#define OOX_PPT_COMMENTS_HXX + +#define ELEMENT_NOT_FOUND 0 + +using rtl::OUString; +#include <vector> +#include <boost/algorithm/string.hpp> //split function to tokenize for date time + +#include <com/sun/star/util/DateTime.hpp> + + +struct commentAuthor +{ + ::rtl::OUString clrIdx; + ::rtl::OUString id; + ::rtl::OUString initials; + ::rtl::OUString lastIdx; + ::rtl::OUString name; +}; + +class commentAuthorList +{ + public: + std::vector<commentAuthor> cmAuthorLst; + void setValues( commentAuthorList list) + { + std::vector<commentAuthor>::iterator it; + for(it=list.cmAuthorLst.begin();it!=list.cmAuthorLst.end();it++) + { + commentAuthor temp; + cmAuthorLst.push_back(temp); + cmAuthorLst.back().clrIdx = it->clrIdx; + cmAuthorLst.back().id = it->id; + cmAuthorLst.back().initials = it->initials; + cmAuthorLst.back().lastIdx = it->lastIdx; + cmAuthorLst.back().name = it->name; + } + } +}; + +class comment +{ + private: + ::rtl::OUString authorId; + ::rtl::OUString dt; + ::rtl::OUString idx; + ::rtl::OUString x; + ::rtl::OUString y; + ::rtl::OUString text; + ::com::sun::star::util::DateTime aDateTime; + + public: + void setAuthorId(::rtl::OUString _aId) + { + authorId = _aId; + } + void setdt(::rtl::OUString _dt) + { + dt=_dt; + setDateTime(_dt); + } + void setidx(::rtl::OUString _idx) + { + idx=_idx; + } + void set_X(::rtl::OUString _x) + { + x=_x; + } + void set_Y(::rtl::OUString _y) + { + y=_y; + } + void set_text(std::string _text) + { + text = rtl::OUString::createFromAscii ( _text.c_str() ); + } + void set_text(rtl::OUString _text) + { + text = _text; + } + + private: + //DateTime is saved as : 2013-01-10T15:53:26.000 + + void setDateTime (::rtl::OUString datetime) + { + std::string _datetime = rtl::OUStringToOString(datetime, RTL_TEXTENCODING_UTF8).getStr(); + std::vector<std::string> _dt; + boost::split( _dt, _datetime, boost::is_any_of( "-:T" ) ); + aDateTime.Year = atoi(_dt.at(0).c_str()); + aDateTime.Month = atoi(_dt.at(1).c_str()); + aDateTime.Day = atoi(_dt.at(2).c_str()); + aDateTime.Hours = atoi(_dt.at(3).c_str()); + aDateTime.Minutes = atoi(_dt.at(4).c_str()); + aDateTime.HundredthSeconds = atoi(_dt.at(5).c_str()); + std::vector<std::string>::iterator i; + } + + public: + ::rtl::OUString getAuthorId() + { + return authorId; + } + ::rtl::OUString getdt() + { + return dt; + } + ::rtl::OUString getidx() + { + return idx; + } + ::rtl::OUString get_X() + { + return x; + } + ::rtl::OUString get_Y() + { + return y; + } + ::rtl::OUString get_text() + { + return text; + } + ::com::sun::star::util::DateTime getDateTime() + { + return aDateTime; + } + int get_int_X() + { + std::string temp = rtl::OUStringToOString(get_X(), RTL_TEXTENCODING_UTF8).getStr(); + return atoi(temp.c_str()); + } + int get_int_Y() + { + std::string temp = rtl::OUStringToOString(get_Y(), RTL_TEXTENCODING_UTF8).getStr(); + return atoi(temp.c_str()); + } + commentAuthor getAuthor ( commentAuthorList list ) + { + std::string temp = rtl::OUStringToOString(authorId, RTL_TEXTENCODING_UTF8).getStr(); + int aId = atoi(temp.c_str()); + std::vector<commentAuthor>::iterator it; + for(it = list.cmAuthorLst.begin(); it != list.cmAuthorLst.end(); it++) + { + temp = rtl::OUStringToOString(it->id, RTL_TEXTENCODING_UTF8).getStr(); + int list_aId = atoi(temp.c_str()); + if(list_aId == aId) + return *(it); + } + throw ELEMENT_NOT_FOUND; + } +}; + +class commentList +{ + public: + std::vector<comment> cmLst; + int getSize () + { + return (int)cmLst.size(); + } + comment getCommentAtIndex (int index) + { + if(index < (int)cmLst.size() && index >= 0) + return cmLst.at(index); + else + throw ELEMENT_NOT_FOUND; + } +}; + +#endif \ No newline at end of file diff --git a/oox/inc/oox/ppt/slidepersist.hxx b/oox/inc/oox/ppt/slidepersist.hxx index 3c8bf33..68caa18 100644 --- a/oox/inc/oox/ppt/slidepersist.hxx +++ b/oox/inc/oox/ppt/slidepersist.hxx @@ -32,6 +32,8 @@ #include <com/sun/star/animations/XAnimationNode.hpp> #include "oox/core/fragmenthandler.hxx" +#include "oox/ppt/comments.hxx" + #include <list> namespace oox { namespace vml { class Drawing; } } @@ -116,6 +118,15 @@ ::oox::drawingml::ShapePtr getShape( const ::rtl::OUString & id ) { return maShapeMap[ id ]; } ::oox::drawingml::ShapeIdMap& getShapeMap() { return maShapeMap; } + //comments +private: + commentList commentsList; + commentAuthorList commentAuthors; + +public: + commentList* getCommentsList() { return &commentsList; } + commentAuthorList* getCommentAuthors() { return &commentAuthors; } + private: rtl::OUString maPath; rtl::OUString maLayoutPath; diff --git a/oox/source/core/fragmenthandler2.cxx b/oox/source/core/fragmenthandler2.cxx index bfc6834..f3138db 100644 --- a/oox/source/core/fragmenthandler2.cxx +++ b/oox/source/core/fragmenthandler2.cxx @@ -132,7 +132,6 @@ aMceState.pop_back(); break; } - implEndElement( nElement ); } @@ -164,8 +163,9 @@ { } -void FragmentHandler2::onCharacters( const OUString& ) +void FragmentHandler2::onCharacters( const OUString& rChars) { + charVector.push_back(rChars); } void FragmentHandler2::onEndElement() diff --git a/oox/source/ppt/presentationfragmenthandler.cxx b/oox/source/ppt/presentationfragmenthandler.cxx index 6d077e7..000976d 100644 --- a/oox/source/ppt/presentationfragmenthandler.cxx +++ b/oox/source/ppt/presentationfragmenthandler.cxx @@ -31,6 +31,9 @@ #include <com/sun/star/presentation/XPresentationPage.hpp> #include <com/sun/star/task/XStatusIndicator.hpp> +#include <com/sun/star/office/XAnnotation.hpp> +#include <com/sun/star/office/XAnnotationAccess.hpp> //for comments +#include <com/sun/star/awt/Point.hpp> #include "oox/drawingml/theme.hxx" #include "oox/drawingml/drawingmltypes.hxx" #include "oox/drawingml/themefragmenthandler.hxx" @@ -41,6 +44,9 @@ #include "oox/ppt/layoutfragmenthandler.hxx" #include "oox/ppt/pptimport.hxx" +#include "oox/ppt/comments.hxx" + +using rtl::OUString; using namespace ::com::sun::star; using namespace ::oox::core; using namespace ::oox::drawingml; @@ -132,6 +138,8 @@ void PresentationFragmentHandler::finalizeImport() { + commentAuthorList AuthorList; + int readCommentAuthors; // read commentAuthors.xml only once // todo: localized progress bar text const Reference< task::XStatusIndicator >& rxStatusIndicator( getFilter().getStatusIndicator() ); if ( rxStatusIndicator.is() ) @@ -149,6 +157,7 @@ Reference< drawing::XDrawPagesSupplier > xDPS( xModel, uno::UNO_QUERY_THROW ); Reference< drawing::XDrawPages > xDrawPages( xDPS->getDrawPages(), uno::UNO_QUERY_THROW ); + readCommentAuthors = 0; // as commentAuthors.xml has not been read still for( nSlide = 0; nSlide < maSlidesVector.size(); nSlide++ ) { if ( rxStatusIndicator.is() ) @@ -162,7 +171,7 @@ OUString aSlideFragmentPath = getFragmentPathFromRelId( maSlidesVector[ nSlide ] ); if( !aSlideFragmentPath.isEmpty() ) { - OUString aMasterFragmentPath; + OUString aMasterFragmentPath; SlidePersistPtr pMasterPersistPtr; SlidePersistPtr pSlidePersistPtr( new SlidePersist( rFilter, sal_False, sal_False, xSlide, ShapePtr( new PPTShape( Slide, "com.sun.star.drawing.GroupShape" ) ), mpTextListStyle ) ); @@ -171,6 +180,7 @@ // importing the corresponding masterpage/layout OUString aLayoutFragmentPath = xSlideFragmentHandler->getFragmentPathFromFirstType( CREATE_OFFICEDOC_RELATION_TYPE( "slideLayout" ) ); + OUString aCommentFragmentPath = xSlideFragmentHandler->getFragmentPathFromFirstType( CREATE_OFFICEDOC_RELATION_TYPE( "comments" ) ); if ( !aLayoutFragmentPath.isEmpty() ) { // importing layout @@ -279,6 +289,50 @@ } } } + + if( !aCommentFragmentPath.isEmpty() && readCommentAuthors == 0 ) + {// Comments are present and commentAuthors.xml has still not been read + readCommentAuthors = 1; //set to true + rtl::OUString aCommentAuthorsFragmentPath = "ppt/commentAuthors.xml"; + Reference< XPresentationPage > xPresentationPage( xSlide, UNO_QUERY ); + Reference< XDrawPage > xCommentAuthorsPage( xPresentationPage->getNotesPage() ); + SlidePersistPtr pCommentAuthorsPersistPtr( new SlidePersist( rFilter, sal_False, sal_True, xCommentAuthorsPage, + ShapePtr( new PPTShape( Slide, "com.sun.star.drawing.GroupShape" ) ), mpTextListStyle ) ); + FragmentHandlerRef xCommentAuthorsFragmentHandler( new SlideFragmentHandler( getFilter(), aCommentAuthorsFragmentPath, pCommentAuthorsPersistPtr, Slide ) ); + + pCommentAuthorsPersistPtr->getCommentAuthors()->cmAuthorLst.clear(); + importSlide( xCommentAuthorsFragmentHandler, pCommentAuthorsPersistPtr ); + AuthorList.cmAuthorLst.clear(); + AuthorList.setValues(*(pCommentAuthorsPersistPtr->getCommentAuthors())); + } + if( !aCommentFragmentPath.isEmpty() ) + { Reference< XPresentationPage > xPresentationPage( xSlide, UNO_QUERY ); + Reference< XDrawPage > xCommentsPage( xPresentationPage->getNotesPage() ); + SlidePersistPtr pCommentsPersistPtr( new SlidePersist( rFilter, sal_False, sal_True, xCommentsPage, + ShapePtr( new PPTShape( Slide, "com.sun.star.drawing.GroupShape" ) ), mpTextListStyle ) ); + FragmentHandlerRef xCommentsFragmentHandler( new SlideFragmentHandler( getFilter(), aCommentFragmentPath, pCommentsPersistPtr, Slide ) ); + pCommentsPersistPtr->getCommentsList()->cmLst.clear(); + importSlide( xCommentsFragmentHandler, pCommentsPersistPtr ); + FragmentHandler2 *comment_handler = dynamic_cast<FragmentHandler2*>(xCommentsFragmentHandler.get()); + pCommentsPersistPtr->getCommentsList()->cmLst.back().set_text( comment_handler->getCharVector().back() );//set comment chars for last comment on slide + + pCommentsPersistPtr->getCommentAuthors()->setValues(AuthorList); + //insert all comments from commentsList + for(int i=0; i<pCommentsPersistPtr->getCommentsList()->getSize(); i++) + { + uno::Reference< office::XAnnotationAccess > xAnnotationAccess( xSlide, UNO_QUERY_THROW ); + uno::Reference< office::XAnnotation > xAnnotation( xAnnotationAccess->createAndInsertAnnotation() ); + int nPosX = pCommentsPersistPtr->getCommentsList()->getCommentAtIndex(i).get_int_X(); + int nPosY = pCommentsPersistPtr->getCommentsList()->getCommentAtIndex(i).get_int_Y(); + xAnnotation->setPosition( geometry::RealPoint2D( ::oox::drawingml::convertEmuToHmm( nPosX ) * 15.87 , ::oox::drawingml::convertEmuToHmm( nPosY ) * 15.87 ) ); + xAnnotation->setAuthor( pCommentsPersistPtr->getCommentsList()->getCommentAtIndex(i).getAuthor(*(pCommentsPersistPtr->getCommentAuthors())).name ); + xAnnotation->setDateTime( pCommentsPersistPtr->getCommentsList()->getCommentAtIndex(i).getDateTime() ); + uno::Reference< text::XText > xText( xAnnotation->getTextRange() ); + xText->setString( pCommentsPersistPtr->getCommentsList()->getCommentAtIndex(i).get_text()); + } + + } + } } ResolveTextFields( rFilter ); diff --git a/oox/source/ppt/slidefragmenthandler.cxx b/oox/source/ppt/slidefragmenthandler.cxx index 12b0ebb..97947b6 100644 --- a/oox/source/ppt/slidefragmenthandler.cxx +++ b/oox/source/ppt/slidefragmenthandler.cxx @@ -39,6 +39,7 @@ #include "oox/ppt/pptimport.hxx" +using rtl::OUString; using namespace ::com::sun::star; using namespace ::oox::core; using namespace ::oox::drawingml; @@ -188,6 +189,34 @@ case PPT_TOKEN( custDataLst ): // CT_CustomerDataList case PPT_TOKEN( tagLst ): // CT_TagList return this; + + //for Comments + case PPT_TOKEN( cmLst ): + break; + case PPT_TOKEN( cm ): + + if(!mpSlidePersistPtr->getCommentsList()->cmLst.empty()) + { mpSlidePersistPtr->getCommentsList()->cmLst.back().set_text( getCharVector().back() ); // set comment text for earlier comment + } + mpSlidePersistPtr->getCommentsList()->cmLst.push_back(comment()); // insert a new comment in vector commentsList + mpSlidePersistPtr->getCommentsList()->cmLst.back().setAuthorId(rAttribs.getString(XML_authorId, OUString())); //set AuthorId + mpSlidePersistPtr->getCommentsList()->cmLst.back().setdt(rAttribs.getString(XML_dt, OUString())); //set dt + mpSlidePersistPtr->getCommentsList()->cmLst.back().setidx(rAttribs.getString(XML_idx, OUString())); //set idx + break; + + case PPT_TOKEN( pos ): + mpSlidePersistPtr->getCommentsList()->cmLst.back().set_X(rAttribs.getString(XML_x, OUString())); //set x + mpSlidePersistPtr->getCommentsList()->cmLst.back().set_Y(rAttribs.getString(XML_y, OUString())); //set y + break; + //case PPT_TOKEN( text ): + + case PPT_TOKEN( cmAuthor ): + mpSlidePersistPtr->getCommentAuthors()->cmAuthorLst.push_back(commentAuthor()); // insert a new comment Author in cmAuthorList + mpSlidePersistPtr->getCommentAuthors()->cmAuthorLst.back().clrIdx = rAttribs.getString(XML_clrIdx, OUString()); //set clrIdx + mpSlidePersistPtr->getCommentAuthors()->cmAuthorLst.back().id = rAttribs.getString(XML_id, OUString()); // set id + mpSlidePersistPtr->getCommentAuthors()->cmAuthorLst.back().initials = rAttribs.getString(XML_initials, OUString()); // set initials + mpSlidePersistPtr->getCommentAuthors()->cmAuthorLst.back().lastIdx = rAttribs.getString(XML_lastIdx, OUString()); // set lastIdx + mpSlidePersistPtr->getCommentAuthors()->cmAuthorLst.back().name = rAttribs.getString(XML_name, OUString()); //set name } return this; -- To view, visit https://gerrit.libreoffice.org/2577 To unsubscribe, visit https://gerrit.libreoffice.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I752f97dddd7f85cf7481f738d8a94df056adcb4a Gerrit-PatchSet: 1 Gerrit-Project: core Gerrit-Branch: master Gerrit-Owner: vinaya mandke <vinaya.man...@synerzip.com> _______________________________________________ LibreOffice mailing list LibreOffice@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice