summaryrefslogtreecommitdiff
path: root/oox/source
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@suse.cz>2012-12-14 18:16:56 +0100
committerMiklos Vajna <vmiklos@suse.cz>2012-12-17 11:25:31 +0100
commitd5c934d150cb6cea5f96cbbee4fb5e8312bf027e (patch)
treeabc28f93d2a11ed40976ae36032b9c1b296e0e6d /oox/source
parent2bbb4b9c5bf9c61c5b0b7fdfcce5b97e04a63a8a (diff)
n#792778 DOCX import: parse group shapes in oox only
Previously textframes inside groupshapes were tried to be imported as TextFrames, but then their addition to a GroupShape failed, so the text simply ended up as a normal paragraph. Fix this by importing members of groupshapes as drawinglayer objects, just like how the WW8 import does. Also fix two testcases, which implicitely tested that the groupshape VML element is ignored on import. Change-Id: I1a9fba8a5fd532203a825e55b1d5996277ea12fa
Diffstat (limited to 'oox/source')
-rw-r--r--oox/source/vml/vmlshape.cxx15
-rw-r--r--oox/source/vml/vmlshapecontext.cxx11
-rw-r--r--oox/source/vml/vmltextbox.cxx36
-rw-r--r--oox/source/vml/vmltextboxcontext.cxx45
4 files changed, 97 insertions, 10 deletions
diff --git a/oox/source/vml/vmlshape.cxx b/oox/source/vml/vmlshape.cxx
index df6d3b5b02ca..6b280b4d1842 100644
--- a/oox/source/vml/vmlshape.cxx
+++ b/oox/source/vml/vmlshape.cxx
@@ -233,9 +233,9 @@ ShapeModel::~ShapeModel()
{
}
-TextBox& ShapeModel::createTextBox()
+TextBox& ShapeModel::createTextBox(ShapeTypeModel& rModel)
{
- mxTextBox.reset( new TextBox );
+ mxTextBox.reset( new TextBox(rModel) );
return *mxTextBox;
}
@@ -486,6 +486,9 @@ Reference< XShape > SimpleShape::implConvertAndInsert( const Reference< XShapes
PropertySet( xShape ).setAnyProperty(PROP_RelativeHeight, makeAny( nHeight ) );
}
}
+
+ if (getTextBox())
+ getTextBox()->convert(xShape);
}
// Import Legacy Fragments (if any)
@@ -522,8 +525,9 @@ Reference< XShape > SimpleShape::createPictureObject( const Reference< XShapes >
{
aPropSet.setProperty( PROP_GraphicURL, aGraphicUrl );
}
- // If the shape has an absolute position, set the properties accordingly.
- if ( maTypeModel.maPosition == "absolute" )
+ uno::Reference< lang::XServiceInfo > xServiceInfo(rxShapes, uno::UNO_QUERY);
+ // If the shape has an absolute position, set the properties accordingly, unless we're inside a group shape.
+ if ( maTypeModel.maPosition == "absolute" && !xServiceInfo->supportsService("com.sun.star.drawing.GroupShape"))
{
aPropSet.setProperty(PROP_HoriOrientPosition, rShapeRect.X);
aPropSet.setProperty(PROP_VertOrientPosition, rShapeRect.Y);
@@ -866,6 +870,9 @@ Reference< XShape > GroupShape::implConvertAndInsert( const Reference< XShapes >
catch( Exception& )
{
}
+ // Make sure group shapes are inline as well, unless there is an explicit different style.
+ PropertySet aPropertySet(xGroupShape);
+ lcl_SetAnchorType(aPropertySet, maTypeModel);
return xGroupShape;
}
diff --git a/oox/source/vml/vmlshapecontext.cxx b/oox/source/vml/vmlshapecontext.cxx
index 165b7358ac7c..cb3daa6dbd03 100644
--- a/oox/source/vml/vmlshapecontext.cxx
+++ b/oox/source/vml/vmlshapecontext.cxx
@@ -404,10 +404,13 @@ ContextHandlerRef ShapeContext::onCreateContext( sal_Int32 nElement, const Attri
if( isRootElement() ) switch( nElement )
{
case VML_TOKEN( textbox ):
- // Custom shape in Writer with a textbox are transformed into a frame
- dynamic_cast<SimpleShape&>( mrShape ).setService(
- "com.sun.star.text.TextFrame");
- return new TextBoxContext( *this, mrShapeModel.createTextBox(), rAttribs,
+ if (getParentElement() != VML_TOKEN( group ))
+ {
+ // Custom shape in Writer with a textbox are transformed into a frame
+ dynamic_cast<SimpleShape&>( mrShape ).setService(
+ "com.sun.star.text.TextFrame");
+ }
+ return new TextBoxContext( *this, mrShapeModel.createTextBox(mrShape.getTypeModel()), rAttribs,
mrShape.getDrawing().getFilter().getGraphicHelper());
case VMLX_TOKEN( ClientData ):
return new ClientDataContext( *this, mrShapeModel.createClientData(), rAttribs );
diff --git a/oox/source/vml/vmltextbox.cxx b/oox/source/vml/vmltextbox.cxx
index 03c4eff90e9d..4af0a9d67cc0 100644
--- a/oox/source/vml/vmltextbox.cxx
+++ b/oox/source/vml/vmltextbox.cxx
@@ -20,12 +20,15 @@
#include "oox/vml/vmltextbox.hxx"
#include <rtl/ustrbuf.hxx>
+#include <com/sun/star/awt/FontWeight.hpp>
+#include <com/sun/star/text/XTextAppend.hpp>
namespace oox {
namespace vml {
using ::rtl::OUString;
using ::rtl::OUStringBuffer;
+using namespace com::sun::star;
TextFontModel::TextFontModel()
{
@@ -37,8 +40,9 @@ TextPortionModel::TextPortionModel( const TextFontModel& rFont, const OUString&
{
}
-TextBox::TextBox()
- : borderDistanceSet( false )
+TextBox::TextBox(ShapeTypeModel& rTypeModel)
+ : mrTypeModel(rTypeModel),
+ borderDistanceSet( false )
{
}
@@ -60,6 +64,34 @@ OUString TextBox::getText() const
return aBuffer.makeStringAndClear();
}
+void TextBox::convert(uno::Reference<drawing::XShape> xShape) const
+{
+ uno::Reference<text::XTextAppend> xTextAppend(xShape, uno::UNO_QUERY);
+ for (PortionVector::const_iterator aIt = maPortions.begin(), aEnd = maPortions.end(); aIt != aEnd; ++aIt)
+ {
+ beans::PropertyValue aPropertyValue;
+ std::vector<beans::PropertyValue> aPropVec;
+ const TextFontModel& rFont = aIt->maFont;
+ if (rFont.mobBold.has())
+ {
+ aPropertyValue.Name = "CharWeight";
+ aPropertyValue.Value = uno::makeAny(rFont.mobBold.get() ? awt::FontWeight::BOLD : awt::FontWeight::NORMAL);
+ aPropVec.push_back(aPropertyValue);
+ }
+ if (rFont.monSize.has())
+ {
+ aPropertyValue.Name = "CharHeight";
+ aPropertyValue.Value = uno::makeAny(double(rFont.monSize.get()) / 2.);
+ aPropVec.push_back(aPropertyValue);
+ }
+ uno::Sequence<beans::PropertyValue> aPropSeq(aPropVec.size());
+ beans::PropertyValue* pValues = aPropSeq.getArray();
+ for (std::vector<beans::PropertyValue>::iterator i = aPropVec.begin(); i != aPropVec.end(); ++i)
+ *pValues++ = *i;
+ xTextAppend->appendTextPortion(aIt->maText, aPropSeq);
+ }
+}
+
} // namespace vml
} // namespace oox
diff --git a/oox/source/vml/vmltextboxcontext.cxx b/oox/source/vml/vmltextboxcontext.cxx
index 2724a1f70d10..3755cc7efd5b 100644
--- a/oox/source/vml/vmltextboxcontext.cxx
+++ b/oox/source/vml/vmltextboxcontext.cxx
@@ -19,6 +19,8 @@
#include "oox/vml/vmlformatting.hxx"
#include "oox/vml/vmltextboxcontext.hxx"
+#include "oox/vml/vmlshape.hxx"
+#include <com/sun/star/drawing/XShape.hpp>
namespace oox {
namespace vml {
@@ -68,7 +70,22 @@ TextPortionContext::TextPortionContext( ContextHandler2Helper& rParent,
OSL_ENSURE( !maFont.mobStrikeout, "TextPortionContext::TextPortionContext - nested <s> elements" );
maFont.mobStrikeout = true;
break;
+ case OOX_TOKEN(dml, blip):
+ {
+ OptValue<OUString> oRelId = rAttribs.getString(R_TOKEN(embed));
+ if (oRelId.has())
+ mrTextBox.mrTypeModel.moGraphicPath = getFragmentPathFromRelId(oRelId.get());
+ }
+ break;
+ case VML_TOKEN(imagedata):
+ {
+ OptValue<OUString> oRelId = rAttribs.getString(R_TOKEN(id));
+ if (oRelId.has())
+ mrTextBox.mrTypeModel.moGraphicPath = getFragmentPathFromRelId(oRelId.get());
+ }
+ break;
case XML_span:
+ case OOX_TOKEN(doc, r):
break;
default:
OSL_ENSURE( false, "TextPortionContext::TextPortionContext - unknown element" );
@@ -78,11 +95,16 @@ TextPortionContext::TextPortionContext( ContextHandler2Helper& rParent,
ContextHandlerRef TextPortionContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
{
OSL_ENSURE( nElement != XML_font, "TextPortionContext::onCreateContext - nested <font> elements" );
+ if (getNamespace(getCurrentElement()) == NMSP_doc)
+ return this;
return new TextPortionContext( *this, mrTextBox, maFont, nElement, rAttribs );
}
void TextPortionContext::onCharacters( const OUString& rChars )
{
+ if (getNamespace(getCurrentElement()) == NMSP_doc && getCurrentElement() != OOX_TOKEN(doc, t))
+ return;
+
switch( getCurrentElement() )
{
case XML_span:
@@ -94,8 +116,24 @@ void TextPortionContext::onCharacters( const OUString& rChars )
}
}
+void TextPortionContext::onStartElement(const AttributeList& rAttribs)
+{
+ switch (getCurrentElement())
+ {
+ case OOX_TOKEN(doc, b):
+ maFont.mobBold = true;
+ break;
+ case OOX_TOKEN(doc, sz):
+ maFont.monSize = rAttribs.getInteger( OOX_TOKEN(doc, val) );
+ break;
+ }
+}
+
void TextPortionContext::onEndElement()
{
+ if (getNamespace(getCurrentElement()) == NMSP_doc && getCurrentElement() != OOX_TOKEN(doc, t))
+ return;
+
/* A child element without own child elements may contain a single space
character, for example:
@@ -149,10 +187,17 @@ ContextHandlerRef TextBoxContext::onCreateContext( sal_Int32 nElement, const Att
{
case VML_TOKEN( textbox ):
if( nElement == XML_div ) return this;
+ else if (nElement == OOX_TOKEN(doc, txbxContent)) return this;
break;
case XML_div:
if( nElement == XML_font ) return new TextPortionContext( *this, mrTextBox, TextFontModel(), nElement, rAttribs );
break;
+ case OOX_TOKEN(doc, txbxContent):
+ if (nElement == OOX_TOKEN(doc, p)) return this;
+ break;
+ case OOX_TOKEN(doc, p):
+ if (nElement == OOX_TOKEN(doc, r)) return new TextPortionContext( *this, mrTextBox, TextFontModel(), nElement, rAttribs );
+ break;
}
return 0;
}