[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    branches/work/koffice-ko/kchart/shape
From:       Johannes Simon <johannes.simon () gmail ! com>
Date:       2010-04-17 16:11:00
Message-ID: 20100417161100.0D873AC89B () svn ! kde ! org
[Download RAW message or body]

SVN commit 1115828 by jsimon:

When the container size changes, scale those layout items whose position or size was \
loaded from ODF (or later maybe repositioned manually be the user) - instead of doing \
nothing with them. It makes sense, and it mimics OOo. More comments inline.

 M  +59 -5     Layout.cpp  
 M  +34 -0     Layout.h  
 M  +1 -1      Legend.cpp  
 M  +1 -1      PlotArea.cpp  


--- branches/work/koffice-ko/kchart/shape/Layout.cpp #1115827:1115828
@@ -42,11 +42,13 @@
     Position pos;
     int weight;
     bool clipped;
+    bool scaleOnly;
 
     LayoutData( Position _pos, int _weight )
-        : pos( _pos ),
-          weight( _weight ),
-          clipped( true ) {};
+        : pos( _pos )
+        , weight( _weight )
+        , clipped( true )
+        , scaleOnly( false ) {};
 };
 
 Layout::Layout()
@@ -85,6 +87,18 @@
     }
 }
 
+void Layout::setScaleOnly( const KoShape *shape, bool scaleOnly )
+{
+    Q_ASSERT( m_layoutItems.contains( const_cast<KoShape*>(shape) ) );
+    m_layoutItems.value( const_cast<KoShape*>(shape) )->scaleOnly = scaleOnly;
+}
+
+bool Layout::scaleOnly( const KoShape *shape ) const
+{
+    Q_ASSERT( m_layoutItems.contains( const_cast<KoShape*>(shape) ) );
+    return m_layoutItems.value( const_cast<KoShape*>(shape) )->scaleOnly;
+}
+
 void Layout::setClipping( const KoShape *shape, bool clipping )
 {
     Q_ASSERT( m_layoutItems.contains( const_cast<KoShape*>(shape) ) );
@@ -113,6 +127,8 @@
     if ( container->size() != m_containerSize ) {
         QSizeF oldSize = m_containerSize;
         m_containerSize = container->size();
+        if ( oldSize.isValid() )
+            scaleLayout( oldSize, container->size() );
         scheduleRelayout();
     }
     // Container was moved
@@ -186,9 +202,9 @@
     while ( it.hasNext() ) {
         it.next();
         KoShape *shape = it.key();
-        if ( !shape->isVisible() )
+        LayoutData *data = it.value();
+        if ( !shape->isVisible() || data->scaleOnly )
             continue;
-        LayoutData *data = it.value();
         switch ( data->pos ) {
         case TopPosition:
             top.insert( data->weight, shape );
@@ -247,6 +263,44 @@
 
 
 
+void Layout::scaleLayout( const QSizeF &oldSize, const QSizeF &newSize )
+{
+    Q_ASSERT( !m_doingLayout );
+    m_doingLayout = true;
+
+    const QSizeF diff = newSize - oldSize;
+    const qreal dx = diff.width();
+    const qreal dy = diff.height();
+    QMapIterator<KoShape*, LayoutData*> it( m_layoutItems );
+    while ( it.hasNext() )
+    {
+        it.next();
+        KoShape *shape = it.key();
+        LayoutData *data = it.value();
+        // If scaleOnly is not set for this layout item, it will be laid out as \
usual by layout(). +        if ( !data->scaleOnly )
+            continue;
+        switch( data->pos ) {
+        case TopPosition:
+            setItemPosition( shape, itemPosition( shape ) + QPointF( dx / 2.0, 0.0 ) \
); +            break;
+        case BottomPosition:
+            setItemPosition( shape, itemPosition( shape ) + QPointF( dx / 2.0, dy ) \
); +            break;
+        case StartPosition:
+            setItemPosition( shape, itemPosition( shape ) + QPointF( 0.0, dy / 2.0 ) \
); +            break;
+        case EndPosition:
+            setItemPosition( shape, itemPosition( shape ) + QPointF( dx, dy / 2.0 ) \
); +            break;
+        case CenterPosition:
+            shape->setSize( itemSize( shape ) + diff );
+        }
+    }
+
+    m_doingLayout = false;
+}
+
 qreal Layout::layoutTop( const QMap<int, KoShape*>& shapes )
 {
     qreal top = 0.0;
--- branches/work/koffice-ko/kchart/shape/Layout.h #1115827:1115828
@@ -92,6 +92,32 @@
     void remove( KoShape *shape );
 
     /**
+     * If \a scaleOnly is true, \a shape will not be laid out as usual but its \
position +     * and size will only be adjusted if the container's size changes (in \
other words, +     * the item will only be scaled with the container).
+     * Thus it will not make room for other shapes that are added (e.g. by making \
them +     * visible) to this layout.
+     *
+     * This is useful for loading from ODF: At one point, we set the pos/size of a \
shape A +     * as specfied in ODF. Later we set another position and size of a \
different shape B in the same +     * layout as specified for it in ODF. We do not, \
however, want B to effect the size or position +     * of the previous shape A. Then, \
why not just remove them from the layout? The point is: When the +     * container's \
size changes, we still want the layout items to have a resonable position in this \
layout. +     * In that case, we set this property for these shapes.
+     *
+     * In short, the layout will still obey the layout position of \a shape, but \a \
shape won't effect +     * other shapes in this layout and the other way around.
+     */
+    void setScaleOnly( const KoShape *shape, bool scaleOnly );
+
+    /**
+     * Returns whether this \a shape will only be scaled with the layout.
+     *
+     * \see setScaleOnly
+     */
+    bool scaleOnly( const KoShape *shape ) const;
+
+    /**
      * Turns clipping of a shape on or off.
      */
     void setClipping( const KoShape *shape, bool clipping );
@@ -154,6 +180,14 @@
 
 private:
     /**
+     * Scales the relative position (and size of center item) of all items
+     * in this layout for which the scaleOnly property is set.
+     *
+     * \see setScaleOnly
+     */
+    void scaleLayout( const QSizeF &oldSize, const QSizeF &newSize );
+
+    /**
      * Lays out all items in TopPosition, and returns the y value of
      * the bottom-most item's bottom.
      */
--- branches/work/koffice-ko/kchart/shape/Legend.cpp #1115827:1115828
@@ -453,7 +453,7 @@
              legendElement.hasAttributeNS( KoXmlNS::svg, "y" ) ||
              legendElement.hasAttributeNS( KoXmlNS::svg, "width" ) ||
              legendElement.hasAttributeNS( KoXmlNS::svg, "height" ) )
-            d->shape->layout()->setPosition( this, FloatingPosition );
+            d->shape->layout()->setScaleOnly( this, true );
 
         loadOdfAttributes( legendElement, context, attributesToLoad );
 
--- branches/work/koffice-ko/kchart/shape/PlotArea.cpp #1115827:1115828
@@ -673,7 +673,7 @@
          plotAreaElement.hasAttributeNS( KoXmlNS::svg, "y" ) ||
          plotAreaElement.hasAttributeNS( KoXmlNS::svg, "width" ) ||
          plotAreaElement.hasAttributeNS( KoXmlNS::svg, "height" ) )
-        parent()->layout()->setPosition( this, FloatingPosition );
+        parent()->layout()->setScaleOnly( this, true );
 
     loadOdfAttributes( plotAreaElement, context, OdfAllAttributes );
     


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic