Commit 32302282 authored by Thomas Zander's avatar Thomas Zander

Further refactoring to allow better separation of concerns.

This fixes the problem that 'draw:frame' and a nested 'draw:' previously both
added attributes for size/position/etc.

svn path=/trunk/koffice/; revision=652528
parent 08792720
......@@ -22,6 +22,7 @@
#include "KoShape.h"
#include "KoShapeContainer.h"
#include "KoShapeLayer.h"
#include "KoShapeContainerModel.h"
#include "KoSelection.h"
#include "KoPointerEvent.h"
......@@ -609,6 +610,9 @@ void KoShape::setName( const QString & name ) {
}
// loading & saving methods
void KoShape::saveOdfConnections(KoShapeSavingContext *context) const {
// TODO save "draw-glue-point" elements (9.2.19)
}
QString KoShape::style( KoShapeSavingContext *context ) const
{
......@@ -644,85 +648,88 @@ QString KoShape::style( KoShapeSavingContext *context ) const
return context->mainStyles().lookup( style, context->isSet( KoShapeSavingContext::PresentationShape ) ? "pr" : "gr" );
}
void KoShape::saveOdfTransformationAttributes(KoShapeSavingContext *context) const {
// just like in shapes; ODF allows you to manipulate the 'matrix' after setting an
// ofset on the shape (using the x and y positions). Lets save them here.
bool rotate = qAbs(d->angle) > 1E-6;
bool skew = qAbs(d->shearX) > 1E-6 || qAbs(d->shearY) > 1E-6;
bool scale = qAbs(d->scaleX - 1) > 1E-6 || qAbs(d->scaleY -1) > 1E-6;
void KoShape::saveOdfFrameAttributes(KoShapeSavingContext *context) {
saveOdfAttributes(context, FrameAttributes);
context->addOption(KoShapeSavingContext::FrameOpened);
}
void KoShape::saveOdfAttributes(KoShapeSavingContext *context, int attributes) const {
if(attributes & OdfMandatories) {
// all items that should be written to 'draw:frame' and any other 'draw:' object that inherits this shape
context->xmlWriter().addAttribute( context->isSet( KoShapeSavingContext::PresentationShape ) ?
"presentation:style-name": "draw:style-name",
style( context ) );
if(rotate && (skew || scale)) {
QMatrix matrix; // can't use transformationMatrix() as that includes transformation of the container as well.
QSizeF size(this->size());
if ( d->angle != 0 )
if ( context->isSet( KoShapeSavingContext::DrawId ) )
{
matrix.translate( size.width() / 2.0 * d->scaleX, size.height() / 2.0 * d->scaleY );
matrix.translate( size.height() / 2.0 * d->shearX, size.width() / 2.0 * d->shearY );
matrix.rotate( d->angle );
matrix.translate( -size.width() / 2.0 * d->scaleX, -size.height() / 2.0 * d->scaleY );
matrix.translate( -size.height() / 2.0 * d->shearX, -size.width() / 2.0 * d->shearY );
context->xmlWriter().addAttribute( "draw:id", context->drawId( this ) );
}
matrix.shear( d->shearX, d->shearY );
matrix.scale( d->scaleX, d->scaleY );
QString m = QString( "matrix(0 0 %3 %4 %5pt %6pt)" ).arg( matrix.m11() ).arg( matrix.m12() )
.arg( matrix.m21() ).arg( matrix.m22() )
.arg( matrix.dx() ) .arg( matrix.dy() );
context->xmlWriter().addAttribute( "draw:transform", m );
if(d->parent && dynamic_cast<KoShapeLayer*> (d->parent))
context->xmlWriter().addAttribute("draw:layer", d->parent->name());
}
else {
QString transform;
if(rotate)
transform = "rotate("+ QString::number(d->angle) +')';
if(skew)
transform = "skewX("+ QString::number(d->shearX) +") skewY("+ QString::number(d->shearY) +')';
if(scale) {
transform += "scale("+ QString::number(d->scaleX);
if(d->scaleX != d->scaleY)
transform += ','+ QString::number(d->scaleY);
transform += ')';
}
context->xmlWriter().addAttribute( "draw:transform", transform );
// all items after this should not be written out when they have already be written in
// a 'draw:frame' attribute.
if(context->isSet(KoShapeSavingContext::FrameOpened)) {
context->removeOption(KoShapeSavingContext::FrameOpened);
return;
}
}
void KoShape::saveOdfMandatoryAttributes(KoShapeSavingContext *context) const {
context->xmlWriter().addAttribute( context->isSet( KoShapeSavingContext::PresentationShape ) ?
"presentation:style-name": "draw:style-name",
style( context ) );
if ( context->isSet( KoShapeSavingContext::DrawId ) )
{
context->xmlWriter().addAttribute( "draw:id", context->drawId( this ) );
if(attributes & OdfSize) {
QSizeF s( size() );
context->xmlWriter().addAttributePt( "svg:width", s.width() );
context->xmlWriter().addAttributePt( "svg:height", s.height() );
context->xmlWriter().addAttributePt( "svg:x", d->pos.x() );
context->xmlWriter().addAttributePt( "svg:y", d->pos.y() );
}
QList<const char*> tags = context->xmlWriter().tagHierarchy();
tags.removeAt(tags.count()-1); // remove the last; as its the current open tag.
foreach(const char* tag, tags) {
if(QString(tag) == QString("draw:frame"))
return; // we don't store those.
if(attributes & OdfMandatories) {
context->xmlWriter().addAttribute("draw:z-index", zIndex());
}
context->xmlWriter().addAttribute("draw:z-index", zIndex());
}
void KoShape::saveOdfSizePositionAttributes(KoShapeSavingContext *context) const {
QList<const char*> tags = context->xmlWriter().tagHierarchy();
tags.removeAt(tags.count()-1); // remove the last; as its the current open tag.
foreach(const char* tag, tags) {
if(QString(tag) == QString("draw:frame"))
return; // we don't store those.
if(attributes & OdfTransformation) {
// just like in shapes; ODF allows you to manipulate the 'matrix' after setting an
// ofset on the shape (using the x and y positions). Lets save them here.
bool rotate = qAbs(d->angle) > 1E-6;
bool skew = qAbs(d->shearX) > 1E-6 || qAbs(d->shearY) > 1E-6;
bool scale = qAbs(d->scaleX - 1) > 1E-6 || qAbs(d->scaleY -1) > 1E-6;
if(rotate && (skew || scale)) {
QMatrix matrix; // can't use transformationMatrix() as that includes transformation of the container as well.
QSizeF size(this->size());
if ( d->angle != 0 )
{
matrix.translate( size.width() / 2.0 * d->scaleX, size.height() / 2.0 * d->scaleY );
matrix.translate( size.height() / 2.0 * d->shearX, size.width() / 2.0 * d->shearY );
matrix.rotate( d->angle );
matrix.translate( -size.width() / 2.0 * d->scaleX, -size.height() / 2.0 * d->scaleY );
matrix.translate( -size.height() / 2.0 * d->shearX, -size.width() / 2.0 * d->shearY );
}
matrix.shear( d->shearX, d->shearY );
matrix.scale( d->scaleX, d->scaleY );
QString m = QString( "matrix(0 0 %3 %4 %5pt %6pt)" ).arg( matrix.m11() ).arg( matrix.m12() )
.arg( matrix.m21() ).arg( matrix.m22() )
.arg( matrix.dx() ) .arg( matrix.dy() );
context->xmlWriter().addAttribute( "draw:transform", m );
}
else if(rotate || skew || scale) {
QString transform;
if(rotate)
transform = "rotate("+ QString::number(d->angle) +')';
if(skew)
transform = "skewX("+ QString::number(d->shearX) +") skewY("+ QString::number(d->shearY) +')';
if(scale) {
transform += "scale("+ QString::number(d->scaleX);
if(d->scaleX != d->scaleY)
transform += ','+ QString::number(d->scaleY);
transform += ')';
}
context->xmlWriter().addAttribute( "draw:transform", transform );
}
}
QSizeF s( size() );
context->xmlWriter().addAttributePt( "svg:width", s.width() );
context->xmlWriter().addAttributePt( "svg:height", s.height() );
context->xmlWriter().addAttributePt( "svg:x", d->pos.x() );
context->xmlWriter().addAttributePt( "svg:y", d->pos.y() );
}
void KoShape::saveOdfConnections(KoShapeSavingContext *context) const {
// TODO save "draw-glue-point" elements (9.2.19)
}
// end loading & saving methods
......
......@@ -141,15 +141,11 @@ public:
virtual void saveOdf( KoShapeSavingContext * context ) { Q_UNUSED(context); } ; // = 0;
/**
* This method can be used while saving the shape as ODF to add the size and
* the position of a shape attributes to the current element.
*
* This also takes the transformation into account. Use in shapes which have
* Size, Position and transformation as defined in ODF 9.2.15 Common Drawing
* Shape Attributes.
* @see saveOdf()
* When saving this shape to ODF, you may nest it in a 'draw:frame' and shape properties should be
* saved as attributes on that element instead of on the normal shape. After starting to write such
* an element you can call this method to write all relevant properties.
*/
void saveOdfSizePositionAttributes(KoShapeSavingContext *context) const;
void saveOdfFrameAttributes(KoShapeSavingContext *context);
/**
* @brief Scale the shape using the zero-point which is the top-left corner.
......@@ -567,26 +563,25 @@ public:
protected:
/* ** loading saving helper methods */
/**
* This method can be used while saving the shape as ODF to add the size and
* the position of a shape attributes to the current element.
*
* This also takes the transformation into account. Use in shapes which have
* Size & Position as defined in ODF 9.2.15 Common Drawing
* Shape Attributes.
* @see saveOdf, saveOdfMandatoryAttributes(), style(), saveOdfSizePositionAttributes()
*/
void saveOdfTransformationAttributes(KoShapeSavingContext *context) const;
/// attributes from ODF 1.1 chapter 9.2.15 Common Drawing Shape Attributes
enum OdfAttribute {
OdfTransformation = 1, ///< Store transformation information
OdfSize = 2, ///< Store size information
OdfPosition = 4, ///< Store position of shape
OdfMandatories = 8, ///< Id, z-index, layer and style
FrameAttributes = OdfMandatories | OdfSize | OdfPosition | OdfTransformation
};
/**
* This method can be used while saving the shape as ODF to add the mandatory
* attributes to the current element.
* This method can be used while saving the shape as ODF to add the data
* stored on this shape to the current element.
*
* The following attributes will be added; ID, Z-Index, Layer and Style
* as defined in ODF 9.2.15 Common Drawing Shape Attributes.
* @see saveOdf, saveOdfTransformationAttributes(), style(), saveOdfSizePositionAttributes()
* @param context the context for the current save.
* @param attributes a number of OdfAttribute items to state which attributes to save.
* @see saveOdf
*/
void saveOdfMandatoryAttributes(KoShapeSavingContext *context) const;
void saveOdfAttributes(KoShapeSavingContext *context, int attributes) const;
/**
* Add a new draw-glue-point element for each connections() present on this shape.
......@@ -604,7 +599,6 @@ protected:
*/
QString style( KoShapeSavingContext *context ) const;
/* ** end loading saving */
......
......@@ -46,7 +46,7 @@ void KoShapeGroup::childCountChanged() {
void KoShapeGroup::saveOdf( KoShapeSavingContext * context ) {
context->xmlWriter().startElement( "draw:g" );
saveOdfMandatoryAttributes(context);
saveOdfAttributes(context, OdfMandatories);
context->xmlWriter().addAttributePt( "svg:y", position().y() );
foreach(KoShape* shape, iterator()) // store children.
......
......@@ -51,7 +51,7 @@ KoGenStyles & KoShapeSavingContext::mainStyles()
return m_context.mainStyles();
}
bool KoShapeSavingContext::isSet( KoShapeSavingOption option ) const
bool KoShapeSavingContext::isSet( ShapeSavingOption option ) const
{
return m_savingOptions & option;
}
......@@ -60,11 +60,21 @@ void KoShapeSavingContext::setOptions( KoShapeSavingOptions options )
{
m_savingOptions = options;
}
KoShapeSavingContext::KoShapeSavingOptions KoShapeSavingContext::options() const
{
return m_savingOptions;
}
void KoShapeSavingContext::addOption( ShapeSavingOption option) {
m_savingOptions = m_savingOptions | option;
}
void KoShapeSavingContext::removeOption( ShapeSavingOption option) {
if(isSet(option))
m_savingOptions = m_savingOptions ^ option; // xor to remove it.
}
const QString KoShapeSavingContext::drawId( const KoShape * shape, bool insert )
{
QMap<const KoShape *, QString>::const_iterator it( m_drawIds.find( shape ) );
......
......@@ -39,7 +39,7 @@ class FLAKE_EXPORT KoShapeSavingContext
{
public:
/// The Style used for saving the shape
enum KoShapeSavingOption
enum ShapeSavingOption
{
/**
* If set the style of family presentation is used, when not set the
......@@ -55,9 +55,10 @@ public:
/**
* If set the automatic style will be marked as being needed in styles.xml
*/
AutoStyleInStyleXml = 4
AutoStyleInStyleXml = 4,
FrameOpened = 8 ///< If a 'draw:frame' tag has been openened shape properties should be saved differently
};
Q_DECLARE_FLAGS( KoShapeSavingOptions, KoShapeSavingOption )
Q_DECLARE_FLAGS( KoShapeSavingOptions, ShapeSavingOption )
/**
* @brief Constructor
......@@ -96,7 +97,7 @@ public:
*
* @return ture if the option is set, false otherwise
*/
bool isSet( KoShapeSavingOption option ) const;
bool isSet( ShapeSavingOption option ) const;
/**
* @brief Set the options to use
......@@ -105,6 +106,10 @@ public:
*/
void setOptions( KoShapeSavingOptions options );
void addOption( ShapeSavingOption option);
void removeOption( ShapeSavingOption option);
/**
* @brief Get the options used
*
......
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