[Libreoffice-commits] core.git: Branch 'feature/unitver' - 2 commits - officecfg/registry sc/inc sc/Library_sc.mk sc/sdi sc/source sc/uiconfig sc/UIConfig_scalc.mk

Andrzej Hunt andrzej at ahunt.org
Sun May 31 12:38:00 PDT 2015


 officecfg/registry/data/org/openoffice/Office/UI/CalcCommands.xcu |    5 
 sc/Library_sc.mk                                                  |    1 
 sc/UIConfig_scalc.mk                                              |    1 
 sc/inc/sc.hrc                                                     |    1 
 sc/inc/sccommands.h                                               |    1 
 sc/inc/units.hxx                                                  |    2 
 sc/sdi/cellsh.sdi                                                 |    1 
 sc/sdi/drawsh.sdi                                                 |    1 
 sc/sdi/drtxtob.sdi                                                |    1 
 sc/sdi/scalc.sdi                                                  |   24 
 sc/source/core/units/unitsimpl.cxx                                |    6 
 sc/source/core/units/unitsimpl.hxx                                |    2 
 sc/source/ui/app/scdll.cxx                                        |    1 
 sc/source/ui/inc/reffact.hxx                                      |    7 
 sc/source/ui/inc/unitsconversiondlg.hxx                           |   97 ++
 sc/source/ui/miscdlgs/unitsconversiondlg.cxx                      |  272 +++++++
 sc/source/ui/view/cellsh1.cxx                                     |   12 
 sc/source/ui/view/tabvwsh.cxx                                     |    1 
 sc/source/ui/view/tabvwshc.cxx                                    |    7 
 sc/uiconfig/scalc/menubar/menubar.xml                             |    2 
 sc/uiconfig/scalc/ui/unitsconversiondialog.ui                     |  347 ++++++++++
 21 files changed, 792 insertions(+)

New commits:
commit ad52aa65a5cd9eeaea4cb001a02074fda5736215
Author: Andrzej Hunt <andrzej at ahunt.org>
Date:   Sun May 31 20:37:14 2015 +0100

    Implement units conversion dialog.
    
    Change-Id: Iea99d0c86de970e185bfc03e548be47f5235be5f

diff --git a/officecfg/registry/data/org/openoffice/Office/UI/CalcCommands.xcu b/officecfg/registry/data/org/openoffice/Office/UI/CalcCommands.xcu
index 433c723..a57d7e2 100644
--- a/officecfg/registry/data/org/openoffice/Office/UI/CalcCommands.xcu
+++ b/officecfg/registry/data/org/openoffice/Office/UI/CalcCommands.xcu
@@ -1413,6 +1413,11 @@
           <value xml:lang="en-US">~XML Source...</value>
         </prop>
       </node>
+      <node oor:name=".uno:ConvertUnits" oor:op="replace">
+        <prop oor:name="Label" oor:type="xs:string">
+          <value xml:lang="en-US">Convert ~Units</value>
+        </prop>
+      </node>
       <node oor:name=".uno:DataSort" oor:op="replace">
         <prop oor:name="Label" oor:type="xs:string">
           <value xml:lang="en-US">~Sort...</value>
diff --git a/sc/Library_sc.mk b/sc/Library_sc.mk
index 04052c6..82a5237 100644
--- a/sc/Library_sc.mk
+++ b/sc/Library_sc.mk
@@ -488,6 +488,7 @@ $(eval $(call gb_Library_add_exception_objects,sc,\
     sc/source/ui/miscdlgs/solverutil \
     sc/source/ui/miscdlgs/solvrdlg \
     sc/source/ui/miscdlgs/tabopdlg \
+    sc/source/ui/miscdlgs/unitsconversiondlg \
     sc/source/ui/miscdlgs/warnbox \
     sc/source/ui/namedlg/namedefdlg \
     sc/source/ui/namedlg/namedlg \
diff --git a/sc/UIConfig_scalc.mk b/sc/UIConfig_scalc.mk
index 5e4be53..77c821c 100644
--- a/sc/UIConfig_scalc.mk
+++ b/sc/UIConfig_scalc.mk
@@ -181,6 +181,7 @@ $(eval $(call gb_UIConfig_add_uifiles,modules/scalc,\
 	sc/uiconfig/scalc/ui/tpviewpage \
 	sc/uiconfig/scalc/ui/ttestdialog \
 	sc/uiconfig/scalc/ui/ungroupdialog \
+	sc/uiconfig/scalc/ui/unitsconversiondialog \
 	sc/uiconfig/scalc/ui/validationdialog \
 	sc/uiconfig/scalc/ui/validationcriteriapage \
 	sc/uiconfig/scalc/ui/validationhelptabpage \
diff --git a/sc/inc/sc.hrc b/sc/inc/sc.hrc
index 255dc71..bac863f 100644
--- a/sc/inc/sc.hrc
+++ b/sc/inc/sc.hrc
@@ -274,6 +274,7 @@
 #define SID_ZTEST_DIALOG                    (SC_MESSAGE_START + 80)
 #define SID_CHI_SQUARE_TEST_DIALOG          (SC_MESSAGE_START + 81)
 #define SID_SEARCH_RESULTS_DIALOG           (SC_MESSAGE_START + 82)
+#define SID_UNITSCONVERSION_DIALOG          (SC_MESSAGE_START + 83)
 
 // functions
 
diff --git a/sc/inc/sccommands.h b/sc/inc/sccommands.h
index 93a770e..9cc002e 100644
--- a/sc/inc/sccommands.h
+++ b/sc/inc/sccommands.h
@@ -24,6 +24,7 @@
 #define CMD_FID_COL_WIDTH                           ".uno:ColumnWidth"
 #define CMD_SID_CREATE_SW_DRAWVIEW                  ".uno:CreateSWDrawView"
 #define CMD_SID_OPENDLG_PIVOTTABLE                  ".uno:DataDataPilotRun"
+#define CMD_SID_UNITSONVERSION_DIALOG               ".uno:ConvertUnits"
 #define CMD_SID_DATA_SELECT                         ".uno:DataSelect"
 #define CMD_SID_DEFINE_PRINTAREA                    ".uno:DefinePrintArea"
 #define CMD_FID_DELETE_CELL                         ".uno:DeleteCell"
diff --git a/sc/sdi/cellsh.sdi b/sc/sdi/cellsh.sdi
index 6da3c75..162447a 100644
--- a/sc/sdi/cellsh.sdi
+++ b/sc/sdi/cellsh.sdi
@@ -31,6 +31,7 @@ interface CellSelection
     SID_DEFINE_COLROWNAMERANGES [ ExecMethod = ExecuteEdit; StateMethod = GetState; ]
     SID_OPENDLG_SOLVE           [ ExecMethod = Execute; StateMethod = GetState; ]
     SID_OPENDLG_OPTSOLVER       [ ExecMethod = Execute; StateMethod = GetState; ]
+    SID_UNITSCONVERSION_DIALOG  [ ExecMethod = ExecuteEdit; StateMethod = GetState; ]
     SID_OPENDLG_PIVOTTABLE      [ ExecMethod = ExecuteDB; StateMethod = GetDBState; ]
     SID_OPENDLG_TABOP           [ ExecMethod = Execute; StateMethod = GetBlockState; ]
     SID_FILTER                  [ ExecMethod = ExecuteDB; StateMethod = GetDBState; ]
diff --git a/sc/sdi/drawsh.sdi b/sc/sdi/drawsh.sdi
index d4a1eec..50853d4 100644
--- a/sc/sdi/drawsh.sdi
+++ b/sc/sdi/drawsh.sdi
@@ -27,6 +27,7 @@ interface TableDraw
     SID_DEFINE_COLROWNAMERANGES [ StateMethod = StateDisableItems; Export = FALSE; ]
     SID_OPENDLG_SOLVE           [ StateMethod = StateDisableItems; Export = FALSE; ]
     SID_OPENDLG_OPTSOLVER       [ StateMethod = StateDisableItems; Export = FALSE; ]
+    SID_UNITSCONVERSION_DIALOG  [ StateMethod = StateDisableItems; Export = FALSE; ]
     SID_OPENDLG_PIVOTTABLE      [ StateMethod = StateDisableItems; Export = FALSE; ]
     SID_OPENDLG_TABOP           [ StateMethod = StateDisableItems; Export = FALSE; ]
     SID_FILTER                  [ StateMethod = StateDisableItems; Export = FALSE; ]
diff --git a/sc/sdi/drtxtob.sdi b/sc/sdi/drtxtob.sdi
index 9a77b17..3c969f7 100644
--- a/sc/sdi/drtxtob.sdi
+++ b/sc/sdi/drtxtob.sdi
@@ -25,6 +25,7 @@ interface TableDrawText
     SID_DEFINE_COLROWNAMERANGES [ StateMethod = StateDisableItems; Export = FALSE; ]
     SID_OPENDLG_SOLVE           [ StateMethod = StateDisableItems; Export = FALSE; ]
     SID_OPENDLG_OPTSOLVER       [ StateMethod = StateDisableItems; Export = FALSE; ]
+    SID_UNITSCONVERSION_DIALOG  [ StateMethod = StateDisableItems; Export = FALSE; ]
     SID_OPENDLG_PIVOTTABLE      [ StateMethod = StateDisableItems; Export = FALSE; ]
     SID_OPENDLG_TABOP           [ StateMethod = StateDisableItems; Export = FALSE; ]
     SID_FILTER                  [ StateMethod = StateDisableItems; Export = FALSE; ]
diff --git a/sc/sdi/scalc.sdi b/sc/sdi/scalc.sdi
index 2fbf373..0d03cc9 100644
--- a/sc/sdi/scalc.sdi
+++ b/sc/sdi/scalc.sdi
@@ -3279,6 +3279,30 @@ SfxVoidItem SolverDialog SID_OPENDLG_OPTSOLVER
     GroupId = GID_OPTIONS;
 ]
 
+SfxVoidItem ConvertUnits SID_UNITSCONVERSION_DIALOG
+()
+[
+    /* flags: */
+    AutoUpdate = FALSE,
+    Cachable = Cachable,
+    FastCall = FALSE,
+    HasCoreId = FALSE,
+    HasDialog = TRUE,
+    ReadOnlyDoc = TRUE,
+    Toggle = FALSE,
+    Container = FALSE,
+    RecordAbsolute = FALSE,
+    RecordPerSet;
+    Synchron;
+
+    /* config: */
+    AccelConfig = TRUE,
+    MenuConfig = TRUE,
+    StatusBarConfig = FALSE,
+    ToolBoxConfig = TRUE,
+    GroupId = GID_DATA;
+]
+
 SfxVoidItem SearchResultsDialog SID_SEARCH_RESULTS_DIALOG
 ()
 [
diff --git a/sc/source/ui/app/scdll.cxx b/sc/source/ui/app/scdll.cxx
index 384ae4c..242b0b7 100644
--- a/sc/source/ui/app/scdll.cxx
+++ b/sc/source/ui/app/scdll.cxx
@@ -250,6 +250,7 @@ void ScDLL::Init()
     ScFormulaDlgWrapper         ::RegisterChildWindow(false, pMod);
 
     ScRandomNumberGeneratorDialogWrapper::RegisterChildWindow(false, pMod);
+    ScUnitsConversionDialogWrapper      ::RegisterChildWindow(false, pMod);
     ScSamplingDialogWrapper             ::RegisterChildWindow(false, pMod);
     ScDescriptiveStatisticsDialogWrapper::RegisterChildWindow(false, pMod);
     ScAnalysisOfVarianceDialogWrapper   ::RegisterChildWindow(false, pMod);
diff --git a/sc/source/ui/inc/reffact.hxx b/sc/source/ui/inc/reffact.hxx
index 4dee934..22ae265 100644
--- a/sc/source/ui/inc/reffact.hxx
+++ b/sc/source/ui/inc/reffact.hxx
@@ -73,6 +73,13 @@ private:
     ScRandomNumberGeneratorDialogWrapper() SAL_DELETED_FUNCTION;
 };
 
+class ScUnitsConversionDialogWrapper :
+    public ChildWindowWrapper<SID_UNITSCONVERSION_DIALOG>
+{
+private:
+    ScUnitsConversionDialogWrapper() SAL_DELETED_FUNCTION;
+};
+
 class ScAnalysisOfVarianceDialogWrapper :
     public ChildWindowWrapper<SID_ANALYSIS_OF_VARIANCE_DIALOG>
 {
diff --git a/sc/source/ui/inc/unitsconversiondlg.hxx b/sc/source/ui/inc/unitsconversiondlg.hxx
new file mode 100644
index 0000000..01116d2
--- /dev/null
+++ b/sc/source/ui/inc/unitsconversiondlg.hxx
@@ -0,0 +1,97 @@
+/* -*- 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/.
+ */
+#ifndef INCLUDED_SC_SOURCE_UI_INC_UNITSCONVERSIONDLG_HXX
+#define INCLUDED_SC_SOURCE_UI_INC_UNITSCONVERSIONDLG_HXX
+
+#include <formula/funcutl.hxx>
+#include <vcl/combobox.hxx>
+#include <vcl/fixed.hxx>
+#include <vcl/vclptr.hxx>
+
+#include "anyrefdg.hxx"
+#include "rangelst.hxx"
+#include "units.hxx"
+
+class ScDocument;
+class ScViewData;
+
+class ScUnitsConversionDialog : public ScAnyRefDlg
+{
+public:
+    ScUnitsConversionDialog(SfxBindings* pB,
+                            SfxChildWindow* pCW,
+                            vcl::Window* pParent,
+                            ScViewData* pViewData);
+    virtual ~ScUnitsConversionDialog();
+
+    virtual void dispose() SAL_OVERRIDE;
+
+    virtual void SetReference(const ScRange& rRef, ScDocument* pDoc) SAL_OVERRIDE;
+
+    virtual void SetActive() SAL_OVERRIDE;
+
+    virtual bool Close() SAL_OVERRIDE;
+
+private:
+    ScViewData* mpViewData;
+    ScDocument* mpDoc;
+
+    ScRangeListRef mInputRange;
+
+    bool mbDialogLostFocus;
+
+    boost::shared_ptr< sc::units::Units > mpUnits;
+
+    VclPtr<SelectableFixedText> mpLabelInputUnits;
+    OUString msNone;
+
+    VclPtr<PushButton> mpButtonOk;
+
+    /*
+     * Cache the list of units so that we can quickly
+     * check the compatibility of the desired output
+     * units. (Otherwise we would have to reload the
+     * input units everytime the desired output units
+     * are changed, and this is likely to be the most
+     * common operation in the (probably rare) case
+     * that the desired output units aren't compatible.)
+     */
+    sc::units::RangeUnits mUnits;
+
+    VclPtr<FixedText> mpInputRangeLabel;
+    VclPtr<formula::RefEdit> mpInputRangeEdit;
+    VclPtr<formula::RefButton> mpInputRangeButton;
+
+    VclPtr<VclBox> mpIncompatibleInputsBox;
+
+    VclPtr<ComboBox> mpOutputUnitsEdit;
+    VclPtr<VclBox> mpIncompatibleOutputBox;
+
+    void Init();
+    void GetRangeFromSelection();
+    void UpdateInputUnits();
+
+    // Verify that at least one of the input units
+    // can be converted to the desired output units.
+    // If false, a conversion will not change any data
+    // in the sheet.
+    bool CheckUnitsAreConvertible();
+    void PerformConversion();
+
+    DECL_LINK( OkClicked,                   PushButton* );
+    DECL_LINK( GetFocusHandler,             Control* );
+    DECL_LINK( LoseFocusHandler,            void* );
+    DECL_LINK( OutputUnitsModified,         void* );
+    DECL_LINK( OutputUnitsGetFocusHandler,  void* );
+    DECL_LINK( OutputUnitsLoseFocusHandler, void* );
+};
+
+#endif // INCLUDED_SC_SOURCE_UI_INC_UNITSCONVERSIONDLG_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/miscdlgs/unitsconversiondlg.cxx b/sc/source/ui/miscdlgs/unitsconversiondlg.cxx
new file mode 100644
index 0000000..edd611e
--- /dev/null
+++ b/sc/source/ui/miscdlgs/unitsconversiondlg.cxx
@@ -0,0 +1,272 @@
+/* -*- 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/.
+ */
+
+#include "unitsconversiondlg.hxx"
+
+#include "document.hxx"
+#include "reffact.hxx"
+#include "units.hxx"
+#include "viewdata.hxx"
+
+using namespace sc::units;
+
+ScUnitsConversionDialog::ScUnitsConversionDialog( SfxBindings* pB,
+                                                  SfxChildWindow* pCW,
+                                                  vcl::Window* pParent,
+                                                  ScViewData* pViewData)
+    : ScAnyRefDlg( pB, pCW, pParent, "UnitsConversionDialog",
+                   "modules/scalc/ui/unitsconversiondialog.ui" )
+    , mpViewData( pViewData )
+    , mpDoc( pViewData->GetDocument() )
+    , mInputRange( new ScRangeList )
+    , mbDialogLostFocus( false )
+{
+    mpUnits = Units::GetUnits();
+
+    get( mpButtonOk, "ok" );
+
+    get( mpInputRangeLabel, "cell-range-label" );
+    get( mpInputRangeEdit, "cell-range-edit" );
+    get( mpInputRangeButton, "cell-range-button" );
+    mpInputRangeEdit->SetReferences( this, mpInputRangeLabel );
+    mpInputRangeButton->SetReferences( this, mpInputRangeEdit );
+
+    get( mpLabelInputUnits, "inputunits" );
+    get( mpIncompatibleInputsBox, "incompatible-inputs-box" );
+
+    get( mpOutputUnitsEdit, "output-units-edit" );
+    get( mpIncompatibleOutputBox, "incompatible-output-box" );
+
+    Init();
+
+    msNone = mpLabelInputUnits->GetText();
+    GetRangeFromSelection();
+    UpdateInputUnits();
+}
+
+ScUnitsConversionDialog::~ScUnitsConversionDialog()
+{
+    disposeOnce();
+}
+
+void ScUnitsConversionDialog::dispose()
+{
+    mpButtonOk.clear();
+
+    mpInputRangeLabel.clear();
+    mpInputRangeEdit.clear();
+    mpInputRangeButton.clear();
+
+    mpLabelInputUnits.clear();
+    mpIncompatibleInputsBox.clear();
+
+    mpOutputUnitsEdit.clear();
+    mpIncompatibleOutputBox.clear();
+
+    ScAnyRefDlg::dispose();
+}
+
+void ScUnitsConversionDialog::Init()
+{
+    Link<> aLink = LINK( this, ScUnitsConversionDialog, GetFocusHandler );
+    mpInputRangeEdit->SetGetFocusHdl( aLink );
+    mpInputRangeButton->SetGetFocusHdl( aLink );
+
+    aLink = LINK( this, ScUnitsConversionDialog, LoseFocusHandler );
+    mpInputRangeEdit->SetLoseFocusHdl ( aLink );
+    mpInputRangeButton->SetLoseFocusHdl ( aLink );
+
+    mpOutputUnitsEdit->SetModifyHdl( LINK( this, ScUnitsConversionDialog, OutputUnitsModified ) );
+
+    mpOutputUnitsEdit->SetGetFocusHdl( LINK( this, ScUnitsConversionDialog, OutputUnitsGetFocusHandler ) );
+    mpOutputUnitsEdit->SetLoseFocusHdl( LINK( this, ScUnitsConversionDialog, OutputUnitsLoseFocusHandler ) );
+
+    mpButtonOk->SetClickHdl( LINK( this, ScUnitsConversionDialog, OkClicked ) );
+}
+
+void ScUnitsConversionDialog::GetRangeFromSelection()
+{
+    mpViewData->GetMultiArea( mInputRange );
+    OUString sCurrentString;
+    mInputRange->Format( sCurrentString, SCA_VALID, mpDoc, mpDoc->GetAddressConvention() );
+    mpInputRangeEdit->SetText( sCurrentString );
+}
+
+void ScUnitsConversionDialog::UpdateInputUnits()
+{
+    mUnits = mpUnits->getUnitsForRange( *mInputRange, mpDoc );
+
+    if ( mUnits.units.size() > 0 )
+    {
+        OUStringBuffer mUnitsBuf;
+
+        for ( OUString sUnit : mUnits.units )
+        {
+            // Test that the buffer has already got a unit, so that
+            // we only add the separator after units (but not at the
+            // beginnning).
+            if ( !mUnitsBuf.isEmpty() )
+            {
+                mUnitsBuf.append( ", " );
+            }
+            mUnitsBuf.append( sUnit );
+        }
+        mpLabelInputUnits->SetText( mUnitsBuf.makeStringAndClear() );
+    }
+    else
+    {
+        mpLabelInputUnits->SetText( msNone );
+    }
+
+    mpIncompatibleInputsBox->Show( !mUnits.compatible );
+}
+
+void ScUnitsConversionDialog::SetReference( const ScRange& rRange, ScDocument* pDoc )
+{
+    if ( mpInputRangeEdit->IsEnabled() )
+    {
+        if ( rRange.aStart != rRange.aEnd )
+        {
+            RefInputStart( mpInputRangeEdit );
+        }
+
+        mInputRange->RemoveAll();
+        mInputRange->Append(rRange);
+
+        OUString aRangeString = rRange.Format( SCA_VALID, pDoc, pDoc->GetAddressConvention() );
+        mpInputRangeEdit->SetRefString( aRangeString );
+
+        UpdateInputUnits();
+    }
+}
+
+void ScUnitsConversionDialog::SetActive()
+{
+    if ( mbDialogLostFocus )
+    {
+        mbDialogLostFocus = false;
+        if( mpInputRangeEdit )
+        {
+            mpInputRangeEdit->GrabFocus();
+        }
+    }
+    else
+    {
+        GrabFocus();
+    }
+    RefInputDone();
+}
+
+bool ScUnitsConversionDialog::Close()
+{
+    return DoClose( ScUnitsConversionDialogWrapper::GetChildWindowId() );
+}
+
+bool ScUnitsConversionDialog::CheckUnitsAreConvertible()
+{
+    OUString sOutputUnit = mpOutputUnitsEdit->GetText();
+
+    bool bCompatibleInputFound = false;
+    for ( auto aIt = mUnits.units.cbegin(); aIt < mUnits.units.cend(); aIt++ )
+    {
+        if ( mpUnits->areUnitsCompatible( *aIt, sOutputUnit ) ) {
+            bCompatibleInputFound = true;
+            break;
+        }
+
+        // Optimisation: break after first unit if all input units are compatible, since
+        // the output will either be compatible with all or none of the inputs.
+        if ( mUnits.compatible )
+        {
+            break;
+        }
+    }
+
+    return bCompatibleInputFound;
+}
+
+IMPL_LINK( ScUnitsConversionDialog, OkClicked, PushButton*, /*pButton*/ )
+{
+    if (!CheckUnitsAreConvertible())
+    {
+        // As we have now clicked on this button, the output units entry
+        // box has lost focus, so the "no conversion possible" warning
+        // will already be shown by the OutputUnitsComplete handler.
+        return 0;
+    }
+
+    PerformConversion();
+    Close();
+    return 0;
+}
+
+IMPL_LINK( ScUnitsConversionDialog, GetFocusHandler, Control*, pCtrl )
+{
+    Edit* pEdit = NULL;
+
+    if( (pCtrl == (Control*) mpInputRangeEdit) || (pCtrl == (Control*) mpInputRangeButton) ) {
+        pEdit = mpInputRangeEdit;
+    }
+
+    if( pEdit ) {
+        pEdit->SetSelection( Selection( 0, SELECTION_MAX ) );
+    }
+
+    return 0;
+}
+
+IMPL_LINK_NOARG( ScUnitsConversionDialog, LoseFocusHandler )
+{
+    mbDialogLostFocus = !IsActive();
+    return 0;
+}
+
+IMPL_LINK_NOARG( ScUnitsConversionDialog, OutputUnitsGetFocusHandler )
+{
+    // The warning box may have been enabled because of an incompatible unit,
+    // however we should disable it during editing (it will then be reenabled
+    // if needed once the user completes editing their desired output unit).
+    mpIncompatibleOutputBox->Show( false );
+
+    return 0;
+}
+
+IMPL_LINK_NOARG( ScUnitsConversionDialog, OutputUnitsModified )
+{
+    OUString sOutputUnit = mpOutputUnitsEdit->GetText();
+
+    if (!mpUnits->isValidUnit(sOutputUnit))
+    {
+        mpOutputUnitsEdit->SetControlForeground( Color( COL_LIGHTRED ) );
+        mpOutputUnitsEdit->set_font_attribute( "underline", "true" );
+    }
+    else
+    {
+        mpOutputUnitsEdit->SetControlForeground( Color( COL_BLACK ) );
+        mpOutputUnitsEdit->set_font_attribute( "underline", "false" );
+    }
+
+    return 0;
+}
+
+IMPL_LINK_NOARG( ScUnitsConversionDialog, OutputUnitsLoseFocusHandler )
+{
+    mpIncompatibleOutputBox->Show( !CheckUnitsAreConvertible() );
+
+    return 0;
+}
+
+void ScUnitsConversionDialog::PerformConversion()
+{
+    OUString sOutputUnit = mpOutputUnitsEdit->GetText();
+
+    mpUnits->convertCellUnits( *mInputRange, mpDoc, sOutputUnit );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/view/cellsh1.cxx b/sc/source/ui/view/cellsh1.cxx
index 6fd0e50..c8efa14 100644
--- a/sc/source/ui/view/cellsh1.cxx
+++ b/sc/source/ui/view/cellsh1.cxx
@@ -76,6 +76,7 @@
 #include "markdata.hxx"
 #include "docpool.hxx"
 #include "condformatdlg.hxx"
+#include "unitsconversiondlg.hxx"
 #include "attrib.hxx"
 
 #include "globstr.hrc"
@@ -127,6 +128,7 @@ void ScCellShell::ExecuteEdit( SfxRequest& rReq )
             case SID_OPENDLG_CONDFRMT:
             case SID_OPENDLG_COLORSCALE:
             case SID_OPENDLG_DATABAR:
+            case SID_UNITSCONVERSION_DIALOG:
 
             pScMod->InputEnterHandler();
             pTabViewShell->UpdateInputHandler();
@@ -1903,6 +1905,16 @@ void ScCellShell::ExecuteEdit( SfxRequest& rReq )
             }
             break;
 
+        case SID_UNITSCONVERSION_DIALOG:
+            {
+                sal_uInt16 nId  = ScUnitsConversionDialogWrapper::GetChildWindowId();
+                SfxViewFrame* pViewFrm = pTabViewShell->GetViewFrame();
+                SfxChildWindow* pWnd = pViewFrm->GetChildWindow( nId );
+
+                pScMod->SetRefDialog( nId, pWnd == nullptr );
+            }
+            break;
+
         case SID_OPENDLG_CONDFRMT:
         case SID_OPENDLG_COLORSCALE:
         case SID_OPENDLG_DATABAR:
diff --git a/sc/source/ui/view/tabvwsh.cxx b/sc/source/ui/view/tabvwsh.cxx
index 632757d..033b1a0 100644
--- a/sc/source/ui/view/tabvwsh.cxx
+++ b/sc/source/ui/view/tabvwsh.cxx
@@ -88,6 +88,7 @@ void ScTabViewShell::InitInterface_Impl()
     GetStaticInterface()->RegisterChildWindow(ScValidityRefChildWin::GetChildWindowId());
     GetStaticInterface()->RegisterChildWindow(sc::SearchResultsDlgWrapper::GetChildWindowId());
 
+    GetStaticInterface()->RegisterChildWindow(ScUnitsConversionDialogWrapper::GetChildWindowId());
     GetStaticInterface()->RegisterChildWindow(ScRandomNumberGeneratorDialogWrapper::GetChildWindowId());
     GetStaticInterface()->RegisterChildWindow(ScSamplingDialogWrapper::GetChildWindowId());
     GetStaticInterface()->RegisterChildWindow(ScDescriptiveStatisticsDialogWrapper::GetChildWindowId());
diff --git a/sc/source/ui/view/tabvwshc.cxx b/sc/source/ui/view/tabvwshc.cxx
index 38502d2..900165a 100644
--- a/sc/source/ui/view/tabvwshc.cxx
+++ b/sc/source/ui/view/tabvwshc.cxx
@@ -56,6 +56,7 @@
 #include "markdata.hxx"
 #include "reffact.hxx"
 #include "condformatdlg.hxx"
+#include "unitsconversiondlg.hxx"
 #include "xmlsourcedlg.hxx"
 
 #include "RandomNumberGeneratorDialog.hxx"
@@ -324,6 +325,12 @@ VclPtr<SfxModelessDialog> ScTabViewShell::CreateRefDialog(
         }
         break;
 
+        case SID_UNITSCONVERSION_DIALOG:
+        {
+            pResult = VclPtr<ScUnitsConversionDialog>::Create( pB, pCW, pParent, &GetViewData() );
+        }
+        break;
+
         case SID_RANDOM_NUMBER_GENERATOR_DIALOG:
         {
             pResult = VclPtr<ScRandomNumberGeneratorDialog>::Create( pB, pCW, pParent, &GetViewData() );
diff --git a/sc/uiconfig/scalc/menubar/menubar.xml b/sc/uiconfig/scalc/menubar/menubar.xml
index 46d3da4..2fbf187 100644
--- a/sc/uiconfig/scalc/menubar/menubar.xml
+++ b/sc/uiconfig/scalc/menubar/menubar.xml
@@ -481,6 +481,8 @@
             <menu:menuitem menu:id=".uno:DataStreams"/>
             <menu:menuitem menu:id=".uno:ManageXMLSource"/>
             <menu:menuseparator/>
+            <menu:menuitem menu:id=".uno:ConvertUnits"/>
+            <menu:menuseparator/>
             <menu:menuitem menu:id=".uno:DataSort"/>
             <menu:menu menu:id=".uno:FilterMenu">
                 <menu:menupopup>
diff --git a/sc/uiconfig/scalc/ui/unitsconversiondialog.ui b/sc/uiconfig/scalc/ui/unitsconversiondialog.ui
new file mode 100644
index 0000000..3549282
--- /dev/null
+++ b/sc/uiconfig/scalc/ui/unitsconversiondialog.ui
@@ -0,0 +1,347 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.18.3 -->
+<interface>
+  <requires lib="gtk+" version="3.0"/>
+  <requires lib="LibreOffice" version="1.0"/>
+  <object class="GtkDialog" id="UnitsConversionDialog">
+    <property name="can_focus">False</property>
+    <property name="border_width">5</property>
+    <property name="title" translatable="yes">Convert Units</property>
+    <property name="type_hint">dialog</property>
+    <child internal-child="vbox">
+      <object class="GtkBox" id="dialog-vbox1">
+        <property name="can_focus">False</property>
+        <property name="orientation">vertical</property>
+        <property name="spacing">2</property>
+        <child internal-child="action_area">
+          <object class="GtkButtonBox" id="dialog-action_area1">
+            <property name="can_focus">False</property>
+            <property name="layout_style">end</property>
+            <child>
+              <object class="GtkButton" id="ok">
+                <property name="label">gtk-ok</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="has_default">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="cancel">
+                <property name="label">gtk-cancel</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="pack_type">end</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkBox" id="box1">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="orientation">vertical</property>
+            <property name="spacing">12</property>
+            <child>
+              <object class="GtkFrame" id="framerange">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="valign">center</property>
+                <property name="label_xalign">0</property>
+                <property name="shadow_type">none</property>
+                <child>
+                  <object class="GtkAlignment" id="alignment2">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="top_padding">6</property>
+                    <property name="bottom_padding">6</property>
+                    <property name="left_padding">12</property>
+                    <property name="right_padding">12</property>
+                    <child>
+                      <object class="GtkGrid" id="grid1">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="row_spacing">6</property>
+                        <property name="column_spacing">6</property>
+                        <child>
+                          <object class="GtkLabel" id="cell-range-label">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="halign">start</property>
+                            <property name="valign">center</property>
+                            <property name="label" translatable="yes">Range:</property>
+                            <property name="use_underline">True</property>
+                            <property name="mnemonic_widget">cell-range-edit</property>
+                          </object>
+                          <packing>
+                            <property name="left_attach">0</property>
+                            <property name="top_attach">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="label5">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="double_buffered">False</property>
+                            <property name="halign">start</property>
+                            <property name="label" translatable="yes">Units in input:</property>
+                          </object>
+                          <packing>
+                            <property name="left_attach">0</property>
+                            <property name="top_attach">1</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="foruilo-RefEdit" id="cell-range-edit">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="valign">center</property>
+                            <property name="hexpand">True</property>
+                            <property name="invisible_char">●</property>
+                            <property name="width_chars">30</property>
+                          </object>
+                          <packing>
+                            <property name="left_attach">1</property>
+                            <property name="top_attach">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="inputunits">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="xalign">0</property>
+                            <property name="label" translatable="yes">none</property>
+                            <property name="selectable">True</property>
+                            <attributes>
+                              <attribute name="style" value="italic"/>
+                              <attribute name="weight" value="bold"/>
+                            </attributes>
+                          </object>
+                          <packing>
+                            <property name="left_attach">1</property>
+                            <property name="top_attach">1</property>
+                            <property name="width">2</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="foruilo-RefButton" id="cell-range-button">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="receives_default">True</property>
+                            <property name="valign">center</property>
+                          </object>
+                          <packing>
+                            <property name="left_attach">2</property>
+                            <property name="top_attach">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkBox" id="incompatible-inputs-box">
+                            <property name="can_focus">False</property>
+                            <child>
+                              <object class="GtkImage" id="incompatible-inputs-icon">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="valign">center</property>
+                                <property name="pixbuf">svx/res/caution_11x16.png</property>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">0</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkLabel" id="incompatible-inputs-label">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="tooltip_text" translatable="yes">Not all units will be converted.</property>
+                                <property name="valign">center</property>
+                                <property name="label" translatable="yes">Warning: Input area contains mixed incompatible units!</property>
+                                <attributes>
+                                  <attribute name="weight" value="bold"/>
+                                </attributes>
+                              </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">2</property>
+                            <property name="width">3</property>
+                          </packing>
+                        </child>
+                      </object>
+                    </child>
+                  </object>
+                </child>
+                <child type="label">
+                  <object class="GtkLabel" id="label2">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">Cell Range</property>
+                    <property name="justify">right</property>
+                    <attributes>
+                      <attribute name="weight" value="bold"/>
+                    </attributes>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkFrame" id="frameoutputunit">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label_xalign">0</property>
+                <property name="shadow_type">none</property>
+                <child>
+                  <object class="GtkAlignment" id="alignment1">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="top_padding">6</property>
+                    <property name="bottom_padding">6</property>
+                    <property name="left_padding">12</property>
+                    <child>
+                      <object class="GtkBox" id="box5">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="orientation">vertical</property>
+                        <property name="spacing">6</property>
+                        <child>
+                          <object class="VclComboBoxText" id="output-units-edit">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="has_entry">True</property>
+                            <child internal-child="entry">
+                              <object class="GtkEntry" id="foo">
+                                <property name="can_focus">False</property>
+                              </object>
+                            </child>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkBox" id="incompatible-output-box">
+                            <property name="can_focus">False</property>
+                            <child>
+                              <object class="GtkImage" id="incompatible-output-icon">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="valign">center</property>
+                                <property name="pixbuf">svx/res/caution_11x16.png</property>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">0</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkLabel" id="incompatible-output-label">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="tooltip_text" translatable="yes">None of the input units can be converted to the desired output unit.</property>
+                                <property name="valign">center</property>
+                                <property name="label" translatable="yes">Warning: Incompatible output units used!</property>
+                                <attributes>
+                                  <attribute name="weight" value="bold"/>
+                                </attributes>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">2</property>
+                              </packing>
+                            </child>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="position">2</property>
+                          </packing>
+                        </child>
+                      </object>
+                    </child>
+                  </object>
+                </child>
+                <child type="label">
+                  <object class="GtkLabel" id="label1">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">Output Units</property>
+                    <attributes>
+                      <attribute name="weight" value="bold"/>
+                    </attributes>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkCheckButton" id="checkbutton1">
+                <property name="label" translatable="yes">Store original unit data in cell annotation</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">False</property>
+                <property name="tooltip_text" translatable="yes">The original data prior to conversion will be stored as a cell annotation, meaning it can be retrieved in future if needed.</property>
+                <property name="xalign">0</property>
+                <property name="draw_indicator">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="pack_type">end</property>
+                <property name="position">2</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+    <action-widgets>
+      <action-widget response="0">ok</action-widget>
+      <action-widget response="0">cancel</action-widget>
+    </action-widgets>
+  </object>
+</interface>
commit 890988f2518e52d4074c6ae5cf257ca95f41452b
Author: Andrzej Hunt <andrzej at ahunt.org>
Date:   Sun May 31 20:33:09 2015 +0100

    Add Units::isValidUnit
    
    Change-Id: Ibb9c6e0d713ceeaa4fc4c67467d76da2f6183502

diff --git a/sc/inc/units.hxx b/sc/inc/units.hxx
index 8e15af4..b428d40 100644
--- a/sc/inc/units.hxx
+++ b/sc/inc/units.hxx
@@ -117,6 +117,8 @@ public:
     virtual RangeUnits getUnitsForRange(const ScRangeList& rRangeList,
                                         ScDocument* pDoc) = 0;
 
+    virtual bool isValidUnit(const OUString& rsUnit) = 0;
+
     virtual ~Units() {}
 };
 
diff --git a/sc/source/core/units/unitsimpl.cxx b/sc/source/core/units/unitsimpl.cxx
index fc4e899..e764aad 100644
--- a/sc/source/core/units/unitsimpl.cxx
+++ b/sc/source/core/units/unitsimpl.cxx
@@ -883,4 +883,10 @@ RangeUnits UnitsImpl::getUnitsForRange(const ScRangeList& rRangeList, ScDocument
     return { aUnitsList, bCompatible };
 }
 
+bool UnitsImpl::isValidUnit(const OUString& rsUnit) {
+    UtUnit aUnit;
+
+    return UtUnit::createUnit(rsUnit, aUnit, mpUnitSystem);
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/units/unitsimpl.hxx b/sc/source/core/units/unitsimpl.hxx
index 58e0971..176a34d 100644
--- a/sc/source/core/units/unitsimpl.hxx
+++ b/sc/source/core/units/unitsimpl.hxx
@@ -113,6 +113,8 @@ public:
     virtual RangeUnits getUnitsForRange(const ScRangeList& rRangeList,
                                         ScDocument* pDoc) SAL_OVERRIDE;
 
+    virtual bool isValidUnit(const OUString& rsUnit) SAL_OVERRIDE;
+
 private:
     UnitsResult getOutputUnitsForOpCode(std::stack< RAUSItem >& rStack, const formula::FormulaToken* pToken, ScDocument* pDoc);
 


More information about the Libreoffice-commits mailing list