summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@suse.com>2012-01-04 15:45:09 -0500
committerKohei Yoshida <kohei.yoshida@suse.com>2012-01-04 21:19:39 -0500
commit578292d707077c18079de050c928afaae268a25d (patch)
tree6924d920095d58773ca59e87896a472a47077281 /sc
parent39042cce6685fc9db5ee20957bcc7ac584c28554 (diff)
Register chart data ranges via tokens rather than string.
Doing it this way avoids having to re-generate the data ranges in Calc A1 before passing it to the chart backend in Calc. We need this in order to remove the silly restriction that forces us to always pass data range strings in Calc A1 format, which is error-prone. This is also necessary in order to fix the bug that prevents editing data ranges of an existing chart when the formula syntax is something other than Calc A1.
Diffstat (limited to 'sc')
-rw-r--r--sc/inc/chart2uno.hxx18
-rw-r--r--sc/source/ui/unoobj/chart2uno.cxx131
2 files changed, 146 insertions, 3 deletions
diff --git a/sc/inc/chart2uno.hxx b/sc/inc/chart2uno.hxx
index 544ab9b09a32..86b14b2c4b0c 100644
--- a/sc/inc/chart2uno.hxx
+++ b/sc/inc/chart2uno.hxx
@@ -38,6 +38,7 @@
#include <svl/lstner.hxx>
#include <com/sun/star/chart/ChartDataRowSource.hpp>
#include <com/sun/star/chart2/data/XDataProvider.hpp>
+#include <com/sun/star/chart2/data/XSheetDataProvider.hpp>
#include <com/sun/star/chart2/data/XRangeXMLConversion.hpp>
#include <com/sun/star/chart2/data/XDataSource.hpp>
#include <com/sun/star/chart2/data/XDataSequence.hpp>
@@ -50,8 +51,7 @@
#include <com/sun/star/util/XCloneable.hpp>
#include <com/sun/star/util/XModifyBroadcaster.hpp>
#include <cppuhelper/implbase2.hxx>
-#include <cppuhelper/implbase4.hxx>
-#include <cppuhelper/implbase6.hxx>
+#include <cppuhelper/implbase5.hxx>
#include <cppuhelper/implbase7.hxx>
#include <rtl/ustring.hxx>
#include <svl/itemprop.hxx>
@@ -69,8 +69,9 @@ class ScDocument;
// DataProvider ==============================================================
class ScChart2DataProvider : public
- ::cppu::WeakImplHelper4<
+ ::cppu::WeakImplHelper5<
::com::sun::star::chart2::data::XDataProvider,
+ ::com::sun::star::chart2::data::XSheetDataProvider,
::com::sun::star::chart2::data::XRangeXMLConversion,
::com::sun::star::beans::XPropertySet,
::com::sun::star::lang::XServiceInfo>,
@@ -110,6 +111,17 @@ public:
virtual ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XRangeSelection > SAL_CALL getRangeSelection()
throw (::com::sun::star::uno::RuntimeException);
+ // XSheetDataProvider ----------------------------------------------------
+
+ virtual sal_Bool SAL_CALL createDataSequenceByFormulaTokensPossible(
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::sheet::FormulaToken >& aTokens )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XDataSequence >
+ SAL_CALL createDataSequenceByFormulaTokens(
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::sheet::FormulaToken >& aTokens )
+ throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+
// XRangeXMLConversion ---------------------------------------------------
virtual ::rtl::OUString SAL_CALL convertRangeToXML( const ::rtl::OUString& sRangeRepresentation )
diff --git a/sc/source/ui/unoobj/chart2uno.cxx b/sc/source/ui/unoobj/chart2uno.cxx
index 48651281d6f2..c9a1aad89110 100644
--- a/sc/source/ui/unoobj/chart2uno.cxx
+++ b/sc/source/ui/unoobj/chart2uno.cxx
@@ -42,6 +42,9 @@
#include "reftokenhelper.hxx"
#include "chartlis.hxx"
#include "stlalgorithm.hxx"
+#include "tokenuno.hxx"
+
+#include "formula/opcode.hxx"
#include <sfx2/objsh.hxx>
#include <tools/table.hxx>
@@ -2103,6 +2106,134 @@ uno::Reference< sheet::XRangeSelection > SAL_CALL ScChart2DataProvider::getRange
return xResult;
}
+sal_Bool SAL_CALL ScChart2DataProvider::createDataSequenceByFormulaTokensPossible(
+ const Sequence<sheet::FormulaToken>& aTokens )
+ throw (uno::RuntimeException)
+{
+ if (aTokens.getLength() <= 0)
+ return false;
+
+ ScTokenArray aCode;
+ if (!ScTokenConversion::ConvertToTokenArray(*m_pDocument, aCode, aTokens))
+ return false;
+
+ sal_uInt16 n = aCode.GetLen();
+ if (!n)
+ return false;
+
+ const formula::FormulaToken* pFirst = aCode.First();
+ const formula::FormulaToken* pLast = aCode.GetArray()[n-1];
+ for (const formula::FormulaToken* p = aCode.First(); p; p = aCode.Next())
+ {
+ switch (p->GetType())
+ {
+ case svSep:
+ {
+ switch (p->GetOpCode())
+ {
+ case ocSep:
+ // separators are allowed.
+ break;
+ case ocOpen:
+ if (p != pFirst)
+ // open paran is allowed only as the first token.
+ return false;
+ break;
+ case ocClose:
+ if (p != pLast)
+ // close paren is allowed only as the last token.
+ return false;
+ break;
+ default:
+ return false;
+ }
+ }
+ break;
+ case svSingleRef:
+ case svDoubleRef:
+ case svExternalSingleRef:
+ case svExternalDoubleRef:
+ break;
+ default:
+ return false;
+ }
+ }
+
+ return true;
+}
+
+Reference<chart2::data::XDataSequence> SAL_CALL
+ScChart2DataProvider::createDataSequenceByFormulaTokens(
+ const Sequence<sheet::FormulaToken>& aTokens )
+ throw (lang::IllegalArgumentException, uno::RuntimeException)
+{
+ Reference<chart2::data::XDataSequence> xResult;
+ if (aTokens.getLength() <= 0)
+ return xResult;
+
+ ScTokenArray aCode;
+ if (!ScTokenConversion::ConvertToTokenArray(*m_pDocument, aCode, aTokens))
+ return xResult;
+
+ sal_uInt16 n = aCode.GetLen();
+ if (!n)
+ return xResult;
+
+ vector<ScTokenRef> aRefTokens;
+ const formula::FormulaToken* pFirst = aCode.First();
+ const formula::FormulaToken* pLast = aCode.GetArray()[n-1];
+ for (const formula::FormulaToken* p = aCode.First(); p; p = aCode.Next())
+ {
+ switch (p->GetType())
+ {
+ case svSep:
+ {
+ switch (p->GetOpCode())
+ {
+ case ocSep:
+ // separators are allowed.
+ break;
+ case ocOpen:
+ if (p != pFirst)
+ // open paran is allowed only as the first token.
+ throw lang::IllegalArgumentException();
+ break;
+ case ocClose:
+ if (p != pLast)
+ // close paren is allowed only as the last token.
+ throw lang::IllegalArgumentException();
+ break;
+ default:
+ throw lang::IllegalArgumentException();
+ }
+ }
+ break;
+ case svSingleRef:
+ case svDoubleRef:
+ case svExternalSingleRef:
+ case svExternalDoubleRef:
+ {
+ ScTokenRef pNew(static_cast<const ScToken*>(p->Clone()));
+ aRefTokens.push_back(pNew);
+ }
+ break;
+ default:
+ throw lang::IllegalArgumentException();
+ }
+ }
+
+ if (aRefTokens.empty())
+ return xResult;
+
+ shrinkToDataRange(m_pDocument, aRefTokens);
+
+ // ScChart2DataSequence manages the life cycle of pRefTokens.
+ vector<ScTokenRef>* pRefTokens = new vector<ScTokenRef>();
+ pRefTokens->swap(aRefTokens);
+ xResult.set(new ScChart2DataSequence(m_pDocument, this, pRefTokens, m_bIncludeHiddenCells));
+ return xResult;
+}
+
// XRangeXMLConversion ---------------------------------------------------
rtl::OUString SAL_CALL ScChart2DataProvider::convertRangeToXML( const rtl::OUString& sRangeRepresentation )