summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--oovbaapi/ooo/vba/excel/XName.idl2
-rw-r--r--sc/inc/nameuno.hxx3
-rw-r--r--sc/source/ui/vba/vbaname.cxx115
-rw-r--r--sc/source/ui/vba/vbaname.hxx5
-rw-r--r--sc/source/ui/vba/vbanames.cxx100
5 files changed, 145 insertions, 80 deletions
diff --git a/oovbaapi/ooo/vba/excel/XName.idl b/oovbaapi/ooo/vba/excel/XName.idl
index 379095b0c0c1..dc6ba1c1ee09 100644
--- a/oovbaapi/ooo/vba/excel/XName.idl
+++ b/oovbaapi/ooo/vba/excel/XName.idl
@@ -36,7 +36,7 @@ interface XName
[attribute] string Name;
[attribute] string NameLocal;
[attribute] boolean Visible;
- [attribute, readonly] string Value;
+ [attribute] string Value;
[attribute, readonly] string RefersTo;
[attribute, readonly] string RefersToLocal;
[attribute, readonly] string RefersToR1C1;
diff --git a/sc/inc/nameuno.hxx b/sc/inc/nameuno.hxx
index 61be7bb7b0e9..053627130cbf 100644
--- a/sc/inc/nameuno.hxx
+++ b/sc/inc/nameuno.hxx
@@ -48,7 +48,7 @@ class ScRangeData;
class ScTokenArray;
class ScNamedRangesObj;
-class ScNamedRangeObj : public ::cppu::WeakImplHelper6<
+class SC_DLLPUBLIC ScNamedRangeObj : public ::cppu::WeakImplHelper6<
::com::sun::star::sheet::XNamedRange,
::com::sun::star::sheet::XFormulaTokens,
::com::sun::star::sheet::XCellRangeReferrer,
@@ -64,6 +64,7 @@ private:
com::sun::star::uno::Reference< com::sun::star::container::XNamed > mxSheet;
private:
+friend class ScVbaName;
ScRangeData* GetRangeData_Impl();
void Modify_Impl( const String* pNewName,
const ScTokenArray* pNewTokens, const String* pNewContent,
diff --git a/sc/source/ui/vba/vbaname.cxx b/sc/source/ui/vba/vbaname.cxx
index 815b8b7bb9b9..9721b73ed5d2 100644
--- a/sc/source/ui/vba/vbaname.cxx
+++ b/sc/source/ui/vba/vbaname.cxx
@@ -30,6 +30,9 @@
#include <vcl/msgbox.hxx>
#include "tabvwsh.hxx"
#include "viewdata.hxx"
+#include "nameuno.hxx"
+#include "compiler.hxx"
+#include "tokenarray.hxx"
using namespace ::ooo::vba;
using namespace ::com::sun::star;
@@ -92,81 +95,64 @@ ScVbaName::setVisible( sal_Bool /*bVisible*/ ) throw (css::uno::RuntimeException
{
}
-OUString
-ScVbaName::getValue() throw (css::uno::RuntimeException)
+OUString ScVbaName::getContent( const formula::FormulaGrammar::Grammar eGrammar, bool bPrependEquals )
{
- OUString sValue = mxNamedRange->getContent();
- OUString sSheetName = getWorkSheet()->getName();
- OUString sSegmentation = OUString::createFromAscii( ";" );
- OUString sNewSegmentation = OUString::createFromAscii( "," );
- OUString sResult;
- sal_Int32 nFrom = 0;
- sal_Int32 nTo = 0;
- nTo = sValue.indexOf( sSegmentation, nFrom );
- while ( nTo != -1 )
+ ScNamedRangeObj* pNamedRange = dynamic_cast< ScNamedRangeObj* >( mxNamedRange.get() );
+ OUString aContent;
+ if ( pNamedRange )
{
- OUString sTmpValue = sValue.copy( nFrom, nTo - nFrom );
- if ( sTmpValue.toChar() == '$' )
- {
- OUString sTmp = sTmpValue.copy( 1 );
- sTmp = sTmp.replaceAt(0, OUString(sSheetName + OUString::createFromAscii(".")).getLength(), sSheetName + OUString::createFromAscii("!"));
- sResult += sTmp;
- sResult += sNewSegmentation;
- }
- nFrom = nTo + 1;
- nTo = sValue.indexOf( sSegmentation, nFrom );
+ ScRangeData* pData = pNamedRange->GetRangeData_Impl();
+ if (pData)
+ pData->GetSymbol( aContent, eGrammar );
}
- OUString sTmpValue = sValue.copy( nFrom );
- if ( sTmpValue.toChar() == '$' )
+ if ( bPrependEquals )
{
- OUString sTmp = sTmpValue.copy(1);
- sTmp = sTmp.replaceAt(0, OUString(sSheetName + OUString::createFromAscii(".")).getLength(), sSheetName + OUString::createFromAscii("!"));
- sResult += sTmp;
+ if (aContent.indexOf('=') != 0)
+ aContent = OUString::createFromAscii("=") + aContent;
}
- if (sResult.indexOf('=') != 0)
- {
- sResult = OUString::createFromAscii("=") + sResult;
- }
- return sResult;
+ return aContent;
}
-void
-ScVbaName::setValue( const OUString & rValue ) throw (css::uno::RuntimeException)
+void ScVbaName::setContent( const OUString& rContent, const formula::FormulaGrammar::Grammar eGrammar, bool bRemoveEquals )
{
- OUString sSheetName = getWorkSheet()->getName();
- OUString sValue = rValue;
- OUString sSegmentation = OUString::createFromAscii( "," );
- OUString sNewSegmentation = OUString::createFromAscii( ";" );
- OUString sResult;
- sal_Int32 nFrom = 0;
- sal_Int32 nTo = 0;
- if (sValue.indexOf('=') == 0)
+ OUString sContent( rContent );
+ if ( bRemoveEquals )
{
- OUString sTmp = sValue.copy(1);
- sValue = sTmp;
+ if (sContent.indexOf('=') == 0)
+ sContent = sContent.copy(1);
}
- nTo = sValue.indexOf( sSegmentation, nFrom );
- while ( nTo != -1 )
+ ScNamedRangeObj* pNamedRange = dynamic_cast< ScNamedRangeObj* >( mxNamedRange.get() );
+
+ // We should be able to do the below by just setting calling SetCode on pNamedRange
+ // right?
+ if ( pNamedRange && pNamedRange->pDocShell )
{
- OUString sTmpValue = sValue.copy( nFrom, nTo - nFrom );
- sTmpValue = sTmpValue.replaceAt(0, OUString(sSheetName + OUString::createFromAscii("!")).getLength(), sSheetName + OUString::createFromAscii("."));
- if (sTmpValue.copy(0, sSheetName.getLength()).equals(sSheetName))
+
+ ScDocument* pDoc = pNamedRange->pDocShell->GetDocument();
+ ScRangeData* pOldData = pNamedRange->GetRangeData_Impl();
+ if (pOldData)
{
- sTmpValue = OUString::createFromAscii("$") + sTmpValue;
+ // Shorter way of doing this ?
+ ScCompiler aComp( pDoc, pOldData->GetPos() );
+ aComp.SetGrammar( eGrammar );
+ ScTokenArray aArray(*aComp.CompileString( sContent ) );
+ pOldData->SetCode( aArray );
}
- sTmpValue += sNewSegmentation;
- sResult += sTmpValue;
- nFrom = nTo + 1;
- nTo = sValue.indexOf( sSegmentation, nFrom );
}
- OUString sTmpValue = sValue.copy( nFrom );
- sTmpValue = sTmpValue.replaceAt(0, OUString(sSheetName + OUString::createFromAscii("!")).getLength(), sSheetName + OUString::createFromAscii("."));
- if (sTmpValue.copy(0, sSheetName.getLength()).equals(sSheetName))
- {
- sTmpValue = OUString::createFromAscii("$") + sTmpValue;
- }
- sResult += sTmpValue;
- mxNamedRange->setContent(sResult);
+}
+
+OUString
+ScVbaName::getValue() throw (css::uno::RuntimeException)
+{
+ rtl::OUString sResult = getContent( formula::FormulaGrammar::GRAM_NATIVE_XL_A1, true );
+
+ return sResult;
+}
+
+void
+ScVbaName::setValue( const OUString & rValue ) throw (css::uno::RuntimeException)
+{
+ setContent( rValue, formula::FormulaGrammar::GRAM_NATIVE_XL_A1, true );
}
OUString
@@ -196,19 +182,20 @@ ScVbaName::setRefersToLocal( const OUString & rRefersTo ) throw (css::uno::Runti
OUString
ScVbaName::getRefersToR1C1() throw (css::uno::RuntimeException)
{
- return getRefersTo();
+ rtl::OUString sResult = getContent( formula::FormulaGrammar::GRAM_NATIVE_XL_R1C1, true );
+ return sResult;
}
void
ScVbaName::setRefersToR1C1( const OUString & rRefersTo ) throw (css::uno::RuntimeException)
{
- setRefersTo( rRefersTo );
+ setContent( rRefersTo, formula::FormulaGrammar::GRAM_NATIVE_XL_R1C1, true );
}
OUString
ScVbaName::getRefersToR1C1Local() throw (css::uno::RuntimeException)
{
- return getRefersTo();
+ return getRefersToR1C1();
}
void
diff --git a/sc/source/ui/vba/vbaname.hxx b/sc/source/ui/vba/vbaname.hxx
index 971c91fb7d7d..505f825f4cb8 100644
--- a/sc/source/ui/vba/vbaname.hxx
+++ b/sc/source/ui/vba/vbaname.hxx
@@ -24,7 +24,7 @@
#include <com/sun/star/sheet/XNamedRanges.hpp>
#include <vbahelper/vbahelperinterface.hxx>
-
+#include <formula/grammar.hxx>
class ScDocument;
typedef InheritedHelperInterfaceImpl1< ov::excel::XName > NameImpl_BASE;
@@ -34,7 +34,8 @@ class ScVbaName : public NameImpl_BASE
css::uno::Reference< css::frame::XModel > mxModel;
css::uno::Reference< css::sheet::XNamedRange > mxNamedRange;
css::uno::Reference< css::sheet::XNamedRanges > mxNames;
-
+ OUString getContent( const formula::FormulaGrammar::Grammar eGrammar, bool prependEquals = true );
+ void setContent( const OUString& sContent, const formula::FormulaGrammar::Grammar eGrammar, bool removeEquals = true );
protected:
virtual css::uno::Reference< css::frame::XModel > getModel() { return mxModel; }
virtual css::uno::Reference< ov::excel::XWorksheet > getWorkSheet() throw (css::uno::RuntimeException);
diff --git a/sc/source/ui/vba/vbanames.cxx b/sc/source/ui/vba/vbanames.cxx
index 5c44fbb9fd03..9cf542bbbaab 100644
--- a/sc/source/ui/vba/vbanames.cxx
+++ b/sc/source/ui/vba/vbanames.cxx
@@ -30,6 +30,9 @@
#include <vcl/msgbox.hxx>
#include "tabvwsh.hxx"
#include "viewdata.hxx"
+#include "compiler.hxx"
+#include "tokenarray.hxx"
+#include "cellsuno.hxx"
using namespace ::ooo::vba;
using namespace ::com::sun::star;
@@ -117,36 +120,109 @@ ScVbaNames::Add( const css::uno::Any& Name ,
uno::Reference< uno::XInterface >() );
}
}
+ uno::Reference< table::XCellRange > xUnoRange;
if ( RefersTo.hasValue() || RefersToR1C1.hasValue() || RefersToR1C1Local.hasValue() )
{
+ OUString sFormula;
+
+ formula::FormulaGrammar::Grammar eGram = formula::FormulaGrammar::GRAM_NATIVE_XL_A1;
if ( RefersTo.hasValue() )
- RefersTo >>= xRange;
+ {
+ if ( RefersTo.getValueTypeClass() == uno::TypeClass_STRING )
+ RefersTo >>= sFormula;
+ else
+ RefersTo >>= xRange;
+ }
if ( RefersToR1C1.hasValue() )
- RefersToR1C1 >>= xRange;
+ {
+ if ( RefersToR1C1.getValueTypeClass() == uno::TypeClass_STRING )
+ {
+ RefersToR1C1 >>= sFormula;
+ eGram = formula::FormulaGrammar::GRAM_NATIVE_XL_R1C1;
+ }
+ else
+ RefersToR1C1 >>= xRange;
+ }
if ( RefersToR1C1Local.hasValue() )
- RefersToR1C1Local >>= xRange;
+ {
+ if ( RefersToR1C1Local.getValueTypeClass() == uno::TypeClass_STRING )
+ {
+ RefersToR1C1Local >>= sFormula;
+ eGram = formula::FormulaGrammar::GRAM_NATIVE_XL_R1C1;
+ }
+ else
+ RefersToR1C1Local >>= xRange;
+ }
+ if ( !xRange.is() && !sFormula.isEmpty() )
+ {
+ ScAddress aBlank;
+ ScCompiler aComp( getScDocument(), aBlank );
+ aComp.SetGrammar( eGram );
+ ScTokenArray* pTokens = aComp.CompileString( sFormula );
+ if ( pTokens )
+ {
+ ScRange aRange;
+ ScDocShell* pDocSh = excel::getDocShell(getModel());
+ if ( pTokens->IsValidReference( aRange ) )
+ xUnoRange = new ScCellRangeObj( pDocSh, aRange );
+ else
+ {
+ // assume it's an address try strip the '=' if it's there
+ // and try and create a range ( must be a better way )
+ if ( sFormula.startsWith("=") )
+ sFormula = sFormula.copy(1);
+ ScRangeList aCellRanges;
+ sal_uInt16 nFlags = 0;
+
+ formula::FormulaGrammar::AddressConvention eConv = ( eGram == formula::FormulaGrammar::GRAM_NATIVE_XL_A1 ) ? formula::FormulaGrammar::CONV_XL_A1 : formula::FormulaGrammar::CONV_XL_R1C1;
+ if ( ScVbaRange::getCellRangesForAddress( nFlags, sFormula, pDocSh, aCellRanges, eConv , ',' ) )
+ {
+ if ( aCellRanges.size() == 1 )
+ xUnoRange = new ScCellRangeObj( pDocSh, *aCellRanges.front() );
+ else
+ {
+ uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( pDocSh, aCellRanges ) );
+ xRange = new ScVbaRange( mxParent, mxContext, xRanges );
+ }
+ }
+
+ }
+ }
+ }
}
- if ( xRange.is() )
+ if ( xRange.is() || xUnoRange.is() )
{
- ScVbaRange* pRange = dynamic_cast< ScVbaRange* >( xRange.get() );
- uno::Reference< table::XCellRange > thisRange ;
- uno::Any xAny = pRange->getCellRange() ;
- if ( xAny.hasValue() )
- xAny >>= thisRange;
- uno::Reference< sheet::XCellRangeAddressable > thisRangeAdd( thisRange, ::uno::UNO_QUERY_THROW);
+ if ( !xRange.is() )
+ xRange = new ScVbaRange( mxParent, mxContext, xUnoRange );
+
+ uno::Reference< excel::XRange > xArea( xRange->Areas( uno::makeAny( 1 ) ), uno::UNO_QUERY );
+ uno::Any xAny = xArea->getCellRange() ;
+
+ uno::Reference< sheet::XCellRangeAddressable > thisRangeAdd( xAny, ::uno::UNO_QUERY_THROW);
+
table::CellRangeAddress aAddr = thisRangeAdd->getRangeAddress();
ScAddress aPos( static_cast< SCCOL >( aAddr.StartColumn ) , static_cast< SCROW >( aAddr.StartRow ) , static_cast< SCTAB >(aAddr.Sheet ) );
uno::Any xAny2 ;
- String sRangeAdd = xRange->Address( xAny2, xAny2 , xAny2 , xAny2, xAny2 );
if ( mxNames.is() )
{
RangeType nType = RT_NAME;
table::CellAddress aCellAddr( aAddr.Sheet , aAddr.StartColumn , aAddr.StartRow );
if ( mxNames->hasByName( sName ) )
mxNames->removeByName(sName);
- OUString sTmp = "$" + xRange->getWorksheet()->getName() + "." + sRangeAdd;
+ OUString sTmp = "$";
+ uno::Reference< ov::XCollection > xCol( xRange->Areas( uno::Any() ), uno::UNO_QUERY );
+ for ( sal_Int32 nArea = 1; nArea <= xCol->getCount(); ++nArea )
+ {
+ xArea.set( xRange->Areas( uno::makeAny( nArea ) ), uno::UNO_QUERY_THROW );
+
+ String sRangeAdd = xArea->Address( xAny2, xAny2 , xAny2 , xAny2, xAny2 );
+ if ( nArea > 1 )
+ sTmp += ",";
+ sTmp = sTmp + "'" + xRange->getWorksheet()->getName() + "'." + sRangeAdd;
+ }
mxNames->addNewByName( sName , sTmp , aCellAddr , (sal_Int32)nType);
+ return Item( uno::makeAny( sName ), uno::Any() );
}
}
return css::uno::Any();