Blob Blame History Raw
From e5faac4ef25728509d23d028bbc32cf3a9a281b1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= <caolanm@redhat.com>
Date: Tue, 13 Oct 2015 13:16:31 +0100
Subject: [PATCH] implement dialog control over enhanced shape control points

use case is a desire to enable viewing and setting rounded rectangle radiuses
to an exact known value

(cherry picked from commit b859d84e471fdb70b61607d2d919a7907d074bd0)

Change-Id: I7e6a4db0699076950adf5869a61825159766c46a
---
 cui/source/inc/transfrm.hxx           |   6 +
 cui/source/tabpages/transfrm.cxx      | 129 ++++++++++++++-
 cui/uiconfig/ui/slantcornertabpage.ui | 302 ++++++++++++++++++++++++++++++----
 include/svx/EnhancedCustomShape2d.hxx |   1 +
 4 files changed, 400 insertions(+), 38 deletions(-)

diff --git a/cui/source/inc/transfrm.hxx b/cui/source/inc/transfrm.hxx
index f4f6925..6aa3935 100644
--- a/cui/source/inc/transfrm.hxx
+++ b/cui/source/inc/transfrm.hxx
@@ -233,6 +233,12 @@ private:
     VclFrame*            m_pFlAngle;
     MetricField*         m_pMtrAngle;
 
+    VclFrame*            m_aControlGroups[2];
+    VclContainer*        m_aControlGroupX[2];
+    MetricField*         m_aControlX[2];
+    VclContainer*        m_aControlGroupY[2];
+    MetricField*         m_aControlY[2];
+
     const SfxItemSet&   rOutAttrs;
 
     const SdrView*      pView;
diff --git a/cui/source/tabpages/transfrm.cxx b/cui/source/tabpages/transfrm.cxx
index e1193c1..4716ed6 100644
--- a/cui/source/tabpages/transfrm.cxx
+++ b/cui/source/tabpages/transfrm.cxx
@@ -18,6 +18,8 @@
  */
 
 #include <sfx2/app.hxx>
+#include <svx/EnhancedCustomShape2d.hxx>
+#include <svx/svdundo.hxx>
 #include <svx/svdview.hxx>
 #include <svx/svdobj.hxx>
 #include <svx/svdpagv.hxx>
@@ -443,6 +445,15 @@ SvxSlantTabPage::SvxSlantTabPage(vcl::Window* pParent, const SfxItemSet& rInAttr
     get(m_pFlAngle, "FL_SLANT");
     get(m_pMtrAngle, "MTR_FLD_ANGLE");
 
+    for (int i = 0; i < 2; ++i)
+    {
+        get(m_aControlGroups[i], "controlgroups" + OString::number(i+1));
+        get(m_aControlGroupX[i], "controlgroupx" + OString::number(i+1));
+        get(m_aControlX[i], "controlx" + OString::number(i+1));
+        get(m_aControlGroupY[i], "controlgroupy" + OString::number(i+1));
+        get(m_aControlY[i], "controly" + OString::number(i+1));
+    }
+
     // this page needs ExchangeSupport
     SetExchangeSupport();
 
@@ -505,10 +516,56 @@ bool SvxSlantTabPage::FillItemSet(SfxItemSet* rAttrs)
         rAttrs->Put( SfxBoolItem( SID_ATTR_TRANSFORM_SHEAR_VERTICAL, false ) );
     }
 
-    return( bModified );
-}
+    bool bControlPointsChanged = false;
+    for (int i = 0; i < 2; ++i)
+    {
+        bControlPointsChanged |= (m_aControlX[i]->IsValueChangedFromSaved() ||
+                                  m_aControlY[i]->IsValueChangedFromSaved());
+    }
 
+    if (!bControlPointsChanged)
+        return bModified;
 
+    SdrObject* pObj = pView->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj();
+    SdrModel* pModel = pObj->GetModel();
+    SdrUndoAction* pUndo = pModel->IsUndoEnabled() ?
+                pModel->GetSdrUndoFactory().CreateUndoAttrObject(*pObj) :
+                nullptr;
+
+    if (pUndo)
+        pModel->BegUndo(pUndo->GetComment());
+
+    EnhancedCustomShape2d aShape(pObj);
+    Rectangle aLogicRect = aShape.GetLogicRect();
+
+    for (int i = 0; i < 2; ++i)
+    {
+        if (m_aControlX[i]->IsValueChangedFromSaved() || m_aControlY[i]->IsValueChangedFromSaved())
+        {
+            Point aNewPosition(GetCoreValue(*m_aControlX[i], ePoolUnit),
+                               GetCoreValue(*m_aControlY[i], ePoolUnit));
+            aNewPosition.Move(aLogicRect.Left(), aLogicRect.Top());
+
+            css::awt::Point aPosition;
+            aPosition.X = aNewPosition.X();
+            aPosition.Y = aNewPosition.Y();
+
+            aShape.SetHandleControllerPosition(i, aPosition);
+        }
+    }
+
+    pObj->SetChanged();
+    pObj->BroadcastObjectChange();
+    bModified = true;
+
+    if (pUndo)
+    {
+        pModel->AddUndo(pUndo);
+        pModel->EndUndo();
+    }
+
+    return bModified;
+}
 
 void SvxSlantTabPage::Reset(const SfxItemSet* rAttrs)
 {
@@ -560,9 +617,70 @@ void SvxSlantTabPage::Reset(const SfxItemSet* rAttrs)
     }
 
     m_pMtrAngle->SaveValue();
-}
-
 
+    const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
+    if (rMarkList.GetMarkCount() == 1)
+    {
+        SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+        SdrObjKind eKind = (SdrObjKind) pObj->GetObjIdentifier();
+        if (eKind == OBJ_CUSTOMSHAPE)
+        {
+            EnhancedCustomShape2d aShape(pObj);
+            Point aInitialPosition;
+            for (int i = 0; i < 2; ++i)
+            {
+                if (!aShape.GetHandlePosition(i, aInitialPosition))
+                    break;
+                m_aControlGroups[i]->Enable();
+                css::awt::Point aPosition;
+
+                aPosition.X = SAL_MAX_INT32;
+                aPosition.Y = SAL_MAX_INT32;
+                aShape.SetHandleControllerPosition(i, aPosition);
+                Point aMaxPosition;
+                aShape.GetHandlePosition(i, aMaxPosition);
+
+                aPosition.X = SAL_MIN_INT32;
+                aPosition.Y = SAL_MIN_INT32;
+                aShape.SetHandleControllerPosition(i, aPosition);
+                Point aMinPosition;
+                aShape.GetHandlePosition(i, aMinPosition);
+
+                Rectangle aLogicRect = aShape.GetLogicRect();
+                aMaxPosition.Move(-aLogicRect.Left(), -aLogicRect.Top());
+                aMinPosition.Move(-aLogicRect.Left(), -aLogicRect.Top());
+
+                aPosition.X = aInitialPosition.X();
+                aPosition.Y = aInitialPosition.Y();
+                aInitialPosition.Move(-aLogicRect.Left(), -aLogicRect.Top());
+                aShape.SetHandleControllerPosition(i, aPosition);
+
+                SetMetricValue(*m_aControlX[i], aInitialPosition.X(), ePoolUnit);
+                SetMetricValue(*m_aControlY[i], aInitialPosition.Y(), ePoolUnit);
+
+                if (aMaxPosition.X() == aMinPosition.X())
+                    m_aControlGroupX[i]->Disable();
+                else
+                {
+                    m_aControlX[i]->SetMin(aMinPosition.X(), FUNIT_MM);
+                    m_aControlX[i]->SetMax(aMaxPosition.X(), FUNIT_MM);
+                }
+                if (aMaxPosition.Y() == aMinPosition.Y())
+                    m_aControlGroupY[i]->Disable();
+                else
+                {
+                    m_aControlY[i]->SetMin(aMinPosition.Y(), FUNIT_MM);
+                    m_aControlY[i]->SetMax(aMaxPosition.Y(), FUNIT_MM);
+                }
+            }
+        }
+    }
+    for (int i = 0; i < 2; ++i)
+    {
+        m_aControlX[i]->SaveValue();
+        m_aControlY[i]->SaveValue();
+    }
+}
 
 SfxTabPage* SvxSlantTabPage::Create( vcl::Window* pWindow, const SfxItemSet* rOutAttrs )
 {
@@ -576,8 +694,6 @@ const sal_uInt16* SvxSlantTabPage::GetRanges()
     return( pSlantRanges );
 }
 
-
-
 void SvxSlantTabPage::ActivatePage( const SfxItemSet& rSet )
 {
     SfxRectangleItem* pRectItem = NULL;
@@ -626,7 +742,6 @@ SvxPositionSizeTabPage::SvxPositionSizeTabPage(vcl::Window* pParent, const SfxIt
     , mfOldWidth(0.0)
     , mfOldHeight(0.0)
 {
-
     get(m_pFlPosition, "FL_POSITION");
     get(m_pMtrPosX, "MTR_FLD_POS_X");
     get(m_pMtrPosY, "MTR_FLD_POS_Y");
diff --git a/cui/uiconfig/ui/slantcornertabpage.ui b/cui/uiconfig/ui/slantcornertabpage.ui
index 37b7b0e..7e365d8 100644
--- a/cui/uiconfig/ui/slantcornertabpage.ui
+++ b/cui/uiconfig/ui/slantcornertabpage.ui
@@ -13,12 +13,132 @@
     <property name="step_increment">1</property>
     <property name="page_increment">10</property>
   </object>
-  <object class="GtkBox" id="SlantAndCornerRadius">
+  <object class="GtkGrid" id="SlantAndCornerRadius">
     <property name="visible">True</property>
     <property name="can_focus">False</property>
     <property name="border_width">6</property>
-    <property name="orientation">vertical</property>
-    <property name="spacing">12</property>
+    <property name="row_spacing">24</property>
+    <property name="column_spacing">12</property>
+    <child>
+      <object class="GtkFrame" id="controlgroups1">
+        <property name="visible">True</property>
+        <property name="sensitive">False</property>
+        <property name="can_focus">False</property>
+        <property name="label_xalign">0</property>
+        <property name="shadow_type">none</property>
+        <child>
+          <object class="GtkAlignment" id="alignment3">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="top_padding">6</property>
+            <property name="left_padding">12</property>
+            <child>
+              <object class="GtkGrid" id="grid1">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="row_spacing">12</property>
+                <property name="column_spacing">6</property>
+                <child>
+                  <object class="GtkBox" id="controlgroupx1">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="spacing">12</property>
+                    <child>
+                      <object class="GtkLabel" id="label5">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="label" translatable="yes">_X:</property>
+                        <property name="use_underline">True</property>
+                        <property name="mnemonic_widget">controlx1:0.00cm</property>
+                        <property name="xalign">0</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkSpinButton" id="controlx1:0.00cm">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="invisible_char">•</property>
+                        <property name="text" translatable="yes">0.00</property>
+                        <property name="digits">2</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkBox" id="controlgroupy1">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="spacing">12</property>
+                    <child>
+                      <object class="GtkLabel" id="label6">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="label" translatable="yes">_Y:</property>
+                        <property name="use_underline">True</property>
+                        <property name="mnemonic_widget">controly1:0.00cm</property>
+                        <property name="xalign">0</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkSpinButton" id="controly1:0.00cm">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="invisible_char">•</property>
+                        <property name="text" translatable="yes">0.00</property>
+                        <property name="digits">2</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">1</property>
+                  </packing>
+                </child>
+              </object>
+            </child>
+          </object>
+        </child>
+        <child type="label">
+          <object class="GtkLabel" id="label3">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="label" translatable="yes">Control Point 1</property>
+            <property name="xalign">0</property>
+            <attributes>
+              <attribute name="weight" value="bold"/>
+            </attributes>
+          </object>
+        </child>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">1</property>
+      </packing>
+    </child>
     <child>
       <object class="GtkFrame" id="FL_RADIUS">
         <property name="visible">True</property>
@@ -32,37 +152,36 @@
             <property name="top_padding">6</property>
             <property name="left_padding">12</property>
             <child>
-              <object class="GtkBox" id="box2">
+              <object class="GtkGrid" id="grid2">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
-                <property name="spacing">12</property>
+                <property name="column_spacing">12</property>
                 <child>
                   <object class="GtkLabel" id="FT_RADIUS">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="xalign">0</property>
                     <property name="label" translatable="yes">_Radius:</property>
                     <property name="use_underline">True</property>
                     <property name="mnemonic_widget">MTR_FLD_RADIUS:0.00cm</property>
+                    <property name="xalign">0</property>
                   </object>
                   <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">0</property>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">0</property>
                   </packing>
                 </child>
                 <child>
                   <object class="GtkSpinButton" id="MTR_FLD_RADIUS:0.00cm">
                     <property name="visible">True</property>
-                    <property name="can_focus">False</property>
+                    <property name="can_focus">True</property>
                     <property name="invisible_char">•</property>
+                    <property name="text" translatable="yes">0.00</property>
                     <property name="adjustment">adjustmentRADIUS</property>
                     <property name="digits">2</property>
                   </object>
                   <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">1</property>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">0</property>
                   </packing>
                 </child>
               </object>
@@ -73,8 +192,8 @@
           <object class="GtkLabel" id="label1">
             <property name="visible">True</property>
             <property name="can_focus">False</property>
-            <property name="xalign">0</property>
             <property name="label" translatable="yes">Corner Radius</property>
+            <property name="xalign">0</property>
             <attributes>
               <attribute name="weight" value="bold"/>
             </attributes>
@@ -82,9 +201,8 @@
         </child>
       </object>
       <packing>
-        <property name="expand">False</property>
-        <property name="fill">True</property>
-        <property name="position">0</property>
+        <property name="left_attach">0</property>
+        <property name="top_attach">0</property>
       </packing>
     </child>
     <child>
@@ -100,37 +218,36 @@
             <property name="top_padding">6</property>
             <property name="left_padding">12</property>
             <child>
-              <object class="GtkBox" id="box3">
+              <object class="GtkGrid" id="grid3">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
-                <property name="spacing">12</property>
+                <property name="column_spacing">12</property>
                 <child>
                   <object class="GtkLabel" id="FT_ANGLE">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="xalign">0</property>
                     <property name="label" translatable="yes">_Angle:</property>
                     <property name="use_underline">True</property>
                     <property name="mnemonic_widget">MTR_FLD_ANGLE:0.00degrees</property>
+                    <property name="xalign">0</property>
                   </object>
                   <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">0</property>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">0</property>
                   </packing>
                 </child>
                 <child>
                   <object class="GtkSpinButton" id="MTR_FLD_ANGLE:0.00degrees">
                     <property name="visible">True</property>
-                    <property name="can_focus">False</property>
+                    <property name="can_focus">True</property>
                     <property name="invisible_char">•</property>
+                    <property name="text" translatable="yes">0.00</property>
                     <property name="adjustment">adjustmentSLANT</property>
                     <property name="digits">2</property>
                   </object>
                   <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">1</property>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">0</property>
                   </packing>
                 </child>
               </object>
@@ -141,8 +258,128 @@
           <object class="GtkLabel" id="label2">
             <property name="visible">True</property>
             <property name="can_focus">False</property>
-            <property name="xalign">0</property>
             <property name="label" translatable="yes">Slant</property>
+            <property name="xalign">0</property>
+            <attributes>
+              <attribute name="weight" value="bold"/>
+            </attributes>
+          </object>
+        </child>
+      </object>
+      <packing>
+        <property name="left_attach">1</property>
+        <property name="top_attach">0</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkFrame" id="controlgroups2">
+        <property name="visible">True</property>
+        <property name="sensitive">False</property>
+        <property name="can_focus">False</property>
+        <property name="label_xalign">0</property>
+        <property name="shadow_type">none</property>
+        <child>
+          <object class="GtkAlignment" id="alignment4">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="top_padding">6</property>
+            <property name="left_padding">12</property>
+            <child>
+              <object class="GtkGrid" id="grid4">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="row_spacing">12</property>
+                <property name="column_spacing">6</property>
+                <child>
+                  <object class="GtkBox" id="controlgroupx2">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="spacing">12</property>
+                    <child>
+                      <object class="GtkLabel" id="label4">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="label" translatable="yes">_X:</property>
+                        <property name="use_underline">True</property>
+                        <property name="mnemonic_widget">controlx2:0.00cm</property>
+                        <property name="xalign">0</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkSpinButton" id="controlx2:0.00cm">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="invisible_char">•</property>
+                        <property name="text" translatable="yes">0.00</property>
+                        <property name="digits">2</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkBox" id="controlgroupy2">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="spacing">12</property>
+                    <child>
+                      <object class="GtkLabel" id="label7">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="label" translatable="yes">_Y:</property>
+                        <property name="use_underline">True</property>
+                        <property name="mnemonic_widget">controly2:0.00cm</property>
+                        <property name="xalign">0</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkSpinButton" id="controly2:0.00cm">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="invisible_char">•</property>
+                        <property name="text" translatable="yes">0.00</property>
+                        <property name="digits">2</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">1</property>
+                  </packing>
+                </child>
+              </object>
+            </child>
+          </object>
+        </child>
+        <child type="label">
+          <object class="GtkLabel" id="label8">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="label" translatable="yes">Control Point 2</property>
+            <property name="xalign">0</property>
             <attributes>
               <attribute name="weight" value="bold"/>
             </attributes>
@@ -150,16 +387,19 @@
         </child>
       </object>
       <packing>
-        <property name="expand">False</property>
-        <property name="fill">True</property>
-        <property name="position">1</property>
+        <property name="left_attach">1</property>
+        <property name="top_attach">1</property>
       </packing>
     </child>
   </object>
   <object class="GtkSizeGroup" id="sizegroup1">
     <widgets>
+      <widget name="label5"/>
+      <widget name="label6"/>
       <widget name="FT_RADIUS"/>
       <widget name="FT_ANGLE"/>
+      <widget name="label4"/>
+      <widget name="label7"/>
     </widgets>
   </object>
   <object class="GtkSizeGroup" id="sizegroup2">
diff --git a/include/svx/EnhancedCustomShape2d.hxx b/include/svx/EnhancedCustomShape2d.hxx
index 8ab32cf..58bf76d 100644
--- a/include/svx/EnhancedCustomShape2d.hxx
+++ b/include/svx/EnhancedCustomShape2d.hxx
@@ -188,6 +188,7 @@ class SVX_DLLPUBLIC EnhancedCustomShape2d : public SfxItemSet
         SdrObject*              CreateObject( bool bLineGeometryNeededOnly );
         void                    ApplyGluePoints( SdrObject* pObj );
         Rectangle               GetTextRect() const;
+        Rectangle               GetLogicRect() const { return aLogicRect; }
 
         sal_uInt32              GetHdlCount() const;
         bool                    GetHandlePosition( const sal_uInt32 nIndex, Point& rReturnPosition ) const;
-- 
2.4.3