summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenry Castro <hcastro@collabora.com>2016-10-04 11:28:27 -0400
committerHenry Castro <hcastro@collabora.com>2016-10-05 17:12:18 +0000
commitaf239f5affe82d0c6449e0e8f9828fe587033f02 (patch)
treecc8749c911aa1b0007047fe38b26d34184cc804c
parent306add13e1d9f70e1111acde8362aea6c169a97d (diff)
sc lok: add .uno:AutoSum
Change-Id: Id2bc0200734308aae1c2e39814c22c6b76664c59 Reviewed-on: https://gerrit.libreoffice.org/29525 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Henry Castro <hcastro@collabora.com>
-rw-r--r--sc/inc/sc.hrc1
-rw-r--r--sc/qa/unit/tiledrendering/tiledrendering.cxx26
-rw-r--r--sc/sdi/cellsh.sdi1
-rw-r--r--sc/sdi/scalc.sdi18
-rw-r--r--sc/source/ui/app/inputwin.cxx151
-rw-r--r--sc/source/ui/inc/inputwin.hxx1
-rw-r--r--sc/source/ui/inc/tabvwsh.hxx2
-rw-r--r--sc/source/ui/view/cellsh1.cxx33
-rw-r--r--sc/source/ui/view/tabvwshc.cxx153
9 files changed, 236 insertions, 150 deletions
diff --git a/sc/inc/sc.hrc b/sc/inc/sc.hrc
index 26a39ca4b072..26b55cb78442 100644
--- a/sc/inc/sc.hrc
+++ b/sc/inc/sc.hrc
@@ -243,6 +243,7 @@
#define SC_HINT_FORCESETTAB (SC_MESSAGE_START + 36)
#define SID_ENTER_STRING (SC_MESSAGE_START + 37)
#define SID_ROWCOL_SELCOUNT (SC_MESSAGE_START + 38)
+#define SID_AUTO_SUM (SC_MESSAGE_START + 39)
// messages for opening dialogs:
#define SID_OPENDLG_CONSOLIDATE (SC_MESSAGE_START + 50)
diff --git a/sc/qa/unit/tiledrendering/tiledrendering.cxx b/sc/qa/unit/tiledrendering/tiledrendering.cxx
index 83c56d13ce3f..dac54bf3852e 100644
--- a/sc/qa/unit/tiledrendering/tiledrendering.cxx
+++ b/sc/qa/unit/tiledrendering/tiledrendering.cxx
@@ -66,6 +66,7 @@ public:
void testTextEditViews();
void testTextEditViewInvalidations();
void testGraphicInvalidate();
+ void testAutoSum();
CPPUNIT_TEST_SUITE(ScTiledRenderingTest);
CPPUNIT_TEST(testRowColumnSelections);
@@ -83,6 +84,7 @@ public:
CPPUNIT_TEST(testTextEditViews);
CPPUNIT_TEST(testTextEditViewInvalidations);
CPPUNIT_TEST(testGraphicInvalidate);
+ CPPUNIT_TEST(testAutoSum);
CPPUNIT_TEST_SUITE_END();
private:
@@ -390,6 +392,7 @@ public:
bool m_bFullInvalidateTiles;
bool m_bInvalidateTiles;
bool m_bViewLock;
+ OString m_sCellFormula;
ViewCallback()
: m_bOwnCursorInvalidated(false),
@@ -457,6 +460,11 @@ public:
m_bInvalidateTiles = true;
}
}
+ break;
+ case LOK_CALLBACK_CELL_FORMULA:
+ {
+ m_sCellFormula = pPayload;
+ }
}
}
};
@@ -820,6 +828,24 @@ void ScTiledRenderingTest::testGraphicInvalidate()
comphelper::LibreOfficeKit::setActive(false);
}
+void ScTiledRenderingTest::testAutoSum()
+{
+ // Load a document
+ comphelper::LibreOfficeKit::setActive();
+ createDoc("small.ods");
+
+ ViewCallback aView;
+ SfxViewShell::Current()->registerLibreOfficeKitViewCallback(&ViewCallback::callback, &aView);
+
+ uno::Sequence<beans::PropertyValue> aArgs;
+ comphelper::dispatchCommand(".uno:AutoSum", aArgs);
+ Scheduler::ProcessEventsToIdle();
+ CPPUNIT_ASSERT(aView.m_sCellFormula.startsWith("=SUM("));
+
+ mxComponent->dispose();
+ mxComponent.clear();
+ comphelper::LibreOfficeKit::setActive(false);
+}
}
CPPUNIT_TEST_SUITE_REGISTRATION(ScTiledRenderingTest);
diff --git a/sc/sdi/cellsh.sdi b/sc/sdi/cellsh.sdi
index 0e8f0a823d3e..32230be961ab 100644
--- a/sc/sdi/cellsh.sdi
+++ b/sc/sdi/cellsh.sdi
@@ -235,6 +235,7 @@ interface CellSelection
SID_TRANSLITERATE_FULLWIDTH [ ExecMethod = ExecuteTrans; StateMethod = GetBlockState; ]
SID_TRANSLITERATE_HIRAGANA [ ExecMethod = ExecuteTrans; StateMethod = GetBlockState; ]
SID_TRANSLITERATE_KATAGANA [ ExecMethod = ExecuteTrans; StateMethod = GetBlockState; ]
+ SID_AUTO_SUM [ ExecMethod = ExecuteEdit; ]
}
diff --git a/sc/sdi/scalc.sdi b/sc/sdi/scalc.sdi
index c371c283bb35..fee950c176a7 100644
--- a/sc/sdi/scalc.sdi
+++ b/sc/sdi/scalc.sdi
@@ -6632,3 +6632,21 @@ SfxUInt16Item NumberFormatType SID_NUMBER_TYPE_FORMAT
ToolBoxConfig = TRUE,
GroupId = GID_FORMAT;
]
+
+
+SfxVoidItem AutoSum SID_AUTO_SUM
+[
+ AutoUpdate = FALSE,
+ FastCall = FALSE,
+ ReadOnlyDoc = TRUE,
+ Toggle = FALSE,
+ Container = FALSE,
+ RecordAbsolute = FALSE,
+ RecordPerSet;
+
+
+ AccelConfig = FALSE,
+ MenuConfig = FALSE,
+ ToolBoxConfig = TRUE,
+ GroupId = GID_INTERN;
+]
diff --git a/sc/source/ui/app/inputwin.cxx b/sc/source/ui/app/inputwin.cxx
index e779989951d8..1f20584d7274 100644
--- a/sc/source/ui/app/inputwin.cxx
+++ b/sc/source/ui/app/inputwin.cxx
@@ -292,65 +292,6 @@ void ScInputWindow::SetInputHandler( ScInputHandler* pNew )
}
}
-bool ScInputWindow::UseSubTotal(ScRangeList* pRangeList)
-{
- bool bSubTotal = false;
- ScTabViewShell* pViewSh = dynamic_cast<ScTabViewShell*>( SfxViewShell::Current() );
- if ( pViewSh )
- {
- ScDocument* pDoc = pViewSh->GetViewData().GetDocument();
- size_t nRangeCount (pRangeList->size());
- size_t nRangeIndex (0);
- while (!bSubTotal && nRangeIndex < nRangeCount)
- {
- const ScRange* pRange = (*pRangeList)[nRangeIndex];
- if( pRange )
- {
- SCTAB nTabEnd(pRange->aEnd.Tab());
- SCTAB nTab(pRange->aStart.Tab());
- while (!bSubTotal && nTab <= nTabEnd)
- {
- SCROW nRowEnd(pRange->aEnd.Row());
- SCROW nRow(pRange->aStart.Row());
- while (!bSubTotal && nRow <= nRowEnd)
- {
- if (pDoc->RowFiltered(nRow, nTab))
- bSubTotal = true;
- else
- ++nRow;
- }
- ++nTab;
- }
- }
- ++nRangeIndex;
- }
-
- const ScDBCollection::NamedDBs& rDBs = pDoc->GetDBCollection()->getNamedDBs();
- ScDBCollection::NamedDBs::const_iterator itr = rDBs.begin(), itrEnd = rDBs.end();
- for (; !bSubTotal && itr != itrEnd; ++itr)
- {
- const ScDBData& rDB = **itr;
- if (!rDB.HasAutoFilter())
- continue;
-
- nRangeIndex = 0;
- while (!bSubTotal && nRangeIndex < nRangeCount)
- {
- const ScRange* pRange = (*pRangeList)[nRangeIndex];
- if( pRange )
- {
- ScRange aDBArea;
- rDB.GetArea(aDBArea);
- if (aDBArea.Intersects(*pRange))
- bSubTotal = true;
- }
- ++nRangeIndex;
- }
- }
- }
- return bSubTotal;
-}
-
void ScInputWindow::Select()
{
ScModule* pScMod = SC_MOD();
@@ -390,98 +331,10 @@ void ScInputWindow::Select()
ScTabViewShell* pViewSh = dynamic_cast<ScTabViewShell*>( SfxViewShell::Current() );
if ( pViewSh )
{
- const ScMarkData& rMark = pViewSh->GetViewData().GetMarkData();
- if ( rMark.IsMarked() || rMark.IsMultiMarked() )
+ const OUString aFormula = pViewSh->DoAutoSum();
+ if (!aFormula.isEmpty())
{
- ScRangeList aMarkRangeList;
- rMark.FillRangeListWithMarks( &aMarkRangeList, false );
- ScDocument* pDoc = pViewSh->GetViewData().GetDocument();
-
- // check if one of the marked ranges is empty
- bool bEmpty = false;
- const size_t nCount = aMarkRangeList.size();
- for ( size_t i = 0; i < nCount; ++i )
- {
- const ScRange aRange( *aMarkRangeList[i] );
- if ( pDoc->IsBlockEmpty( aRange.aStart.Tab(),
- aRange.aStart.Col(), aRange.aStart.Row(),
- aRange.aEnd.Col(), aRange.aEnd.Row() ) )
- {
- bEmpty = true;
- break;
- }
- }
-
- if ( bEmpty )
- {
- ScRangeList aRangeList;
- const bool bDataFound = pViewSh->GetAutoSumArea( aRangeList );
- if ( bDataFound )
- {
- ScAddress aAddr = aRangeList.back()->aEnd;
- aAddr.IncRow();
- const bool bSubTotal( UseSubTotal( &aRangeList ) );
- pViewSh->EnterAutoSum( aRangeList, bSubTotal, aAddr );
- }
- }
- else
- {
- const bool bSubTotal( UseSubTotal( &aMarkRangeList ) );
- for ( size_t i = 0; i < nCount; ++i )
- {
- const ScRange aRange( *aMarkRangeList[i] );
- const bool bSetCursor = ( i == nCount - 1 );
- const bool bContinue = ( i != 0 );
- if ( !pViewSh->AutoSum( aRange, bSubTotal, bSetCursor, bContinue ) )
- {
- pViewSh->MarkRange( aRange, false );
- pViewSh->SetCursor( aRange.aEnd.Col(), aRange.aEnd.Row() );
- const ScRangeList aRangeList;
- ScAddress aAddr = aRange.aEnd;
- aAddr.IncRow();
- const OUString aFormula = pViewSh->GetAutoSumFormula(
- aRangeList, bSubTotal, aAddr );
- SetFuncString( aFormula );
- break;
- }
- }
- }
- }
- else // Only insert into input row
- {
- ScRangeList aRangeList;
- const bool bDataFound = pViewSh->GetAutoSumArea( aRangeList );
- const bool bSubTotal( UseSubTotal( &aRangeList ) );
- ScAddress aAddr = pViewSh->GetViewData().GetCurPos();
- const OUString aFormula = pViewSh->GetAutoSumFormula( aRangeList, bSubTotal, aAddr );
SetFuncString( aFormula );
-
- if ( bDataFound && pScMod->IsEditMode() )
- {
- ScInputHandler* pHdl = pScMod->GetInputHdl( pViewSh );
- if ( pHdl )
- {
- pHdl->InitRangeFinder( aFormula );
-
- //! SetSelection at the InputHandler?
- //! Set bSelIsRef?
- const sal_Int32 nOpen = aFormula.indexOf('(');
- const sal_Int32 nLen = aFormula.getLength();
- if ( nOpen != -1 && nLen > nOpen )
- {
- sal_uInt8 nAdd(1);
- if (bSubTotal)
- nAdd = 3;
- ESelection aSel(0,nOpen+nAdd,0,nLen-1);
- EditView* pTableView = pHdl->GetTableView();
- if (pTableView)
- pTableView->SetSelection(aSel);
- EditView* pTopView = pHdl->GetTopView();
- if (pTopView)
- pTopView->SetSelection(aSel);
- }
- }
- }
}
}
}
diff --git a/sc/source/ui/inc/inputwin.hxx b/sc/source/ui/inc/inputwin.hxx
index a48d4fec87f8..6e557460f8c4 100644
--- a/sc/source/ui/inc/inputwin.hxx
+++ b/sc/source/ui/inc/inputwin.hxx
@@ -265,7 +265,6 @@ public:
virtual void MouseMove( const MouseEvent& rMEvt ) override;
protected:
- static bool UseSubTotal( ScRangeList* pRangeList );
bool IsPointerAtResizePos();
private:
diff --git a/sc/source/ui/inc/tabvwsh.hxx b/sc/source/ui/inc/tabvwsh.hxx
index 392a133a4256..7e29d9c8152c 100644
--- a/sc/source/ui/inc/tabvwsh.hxx
+++ b/sc/source/ui/inc/tabvwsh.hxx
@@ -382,6 +382,8 @@ public:
bool IsActive() const { return bIsActive; }
OUString GetFormula(ScAddress& rAddress);
+ bool UseSubTotal(ScRangeList* pRangeList);
+ const OUString DoAutoSum();
// ugly hack to call Define Names from Manage Names
void SwitchBetweenRefDialogs(SfxModelessDialog* pDialog);
diff --git a/sc/source/ui/view/cellsh1.cxx b/sc/source/ui/view/cellsh1.cxx
index 777bcd76ea00..0fc688c4ae91 100644
--- a/sc/source/ui/view/cellsh1.cxx
+++ b/sc/source/ui/view/cellsh1.cxx
@@ -44,6 +44,7 @@
#include <vcl/waitobj.hxx>
#include <vcl/builderfactory.hxx>
#include <unotools/localedatawrapper.hxx>
+#include <editeng/editview.hxx>
#include "cellsh.hxx"
#include "sc.hrc"
@@ -2535,6 +2536,38 @@ void ScCellShell::ExecuteEdit( SfxRequest& rReq )
}
break;
+ case SID_AUTO_SUM:
+ {
+ const OUString aFormula = pTabViewShell->DoAutoSum();
+ if (!aFormula.isEmpty())
+ {
+ ScInputHandler* pHdl = pScMod->GetInputHdl(pTabViewShell);
+ if (pHdl)
+ {
+ if (!pScMod->IsEditMode())
+ {
+ pScMod->SetInputMode(SC_INPUT_TABLE);
+ }
+
+ EditView *pEditView=pHdl->GetActiveView();
+ if (pEditView)
+ {
+ ESelection aTextSel = pEditView->GetSelection();
+ aTextSel.nStartPos = 0;
+ aTextSel.nEndPos = EE_TEXTPOS_ALL;
+ pHdl->DataChanging();
+ pEditView->SetSelection(aTextSel);
+ pEditView->InsertText(aFormula);
+ aTextSel.nStartPos = aFormula.getLength() - 1;
+ aTextSel.nEndPos = aFormula.getLength() - 1;
+ pEditView->SetSelection(aTextSel);
+ pHdl->DataChanged();
+ }
+ }
+ }
+ }
+ break;
+
default:
OSL_FAIL("incorrect slot in ExecuteEdit");
break;
diff --git a/sc/source/ui/view/tabvwshc.cxx b/sc/source/ui/view/tabvwshc.cxx
index 3b65d6951a90..8cdfcac650a3 100644
--- a/sc/source/ui/view/tabvwshc.cxx
+++ b/sc/source/ui/view/tabvwshc.cxx
@@ -24,6 +24,7 @@
#include <sfx2/childwin.hxx>
#include <sfx2/dispatch.hxx>
#include <editeng/editview.hxx>
+#include <inputhdl.hxx>
#include "tabvwsh.hxx"
#include "sc.hrc"
@@ -542,4 +543,156 @@ void ScTabViewShell::NotifyCursor(SfxViewShell* pOtherShell) const
pWin->updateLibreOfficeKitCellCursor(pOtherShell);
}
+bool ScTabViewShell::UseSubTotal(ScRangeList* pRangeList)
+{
+ bool bSubTotal = false;
+ ScDocument* pDoc = GetViewData().GetDocument();
+ size_t nRangeCount (pRangeList->size());
+ size_t nRangeIndex (0);
+ while (!bSubTotal && nRangeIndex < nRangeCount)
+ {
+ const ScRange* pRange = (*pRangeList)[nRangeIndex];
+ if( pRange )
+ {
+ SCTAB nTabEnd(pRange->aEnd.Tab());
+ SCTAB nTab(pRange->aStart.Tab());
+ while (!bSubTotal && nTab <= nTabEnd)
+ {
+ SCROW nRowEnd(pRange->aEnd.Row());
+ SCROW nRow(pRange->aStart.Row());
+ while (!bSubTotal && nRow <= nRowEnd)
+ {
+ if (pDoc->RowFiltered(nRow, nTab))
+ bSubTotal = true;
+ else
+ ++nRow;
+ }
+ ++nTab;
+ }
+ }
+ ++nRangeIndex;
+ }
+
+ const ScDBCollection::NamedDBs& rDBs = pDoc->GetDBCollection()->getNamedDBs();
+ ScDBCollection::NamedDBs::const_iterator itr = rDBs.begin(), itrEnd = rDBs.end();
+ for (; !bSubTotal && itr != itrEnd; ++itr)
+ {
+ const ScDBData& rDB = **itr;
+ if (!rDB.HasAutoFilter())
+ continue;
+
+ nRangeIndex = 0;
+ while (!bSubTotal && nRangeIndex < nRangeCount)
+ {
+ const ScRange* pRange = (*pRangeList)[nRangeIndex];
+ if( pRange )
+ {
+ ScRange aDBArea;
+ rDB.GetArea(aDBArea);
+ if (aDBArea.Intersects(*pRange))
+ bSubTotal = true;
+ }
+ ++nRangeIndex;
+ }
+ }
+ return bSubTotal;
+}
+
+const OUString ScTabViewShell::DoAutoSum()
+{
+ OUString aFormula;
+ ScModule* pScMod = SC_MOD();
+ const ScMarkData& rMark = GetViewData().GetMarkData();
+ if ( rMark.IsMarked() || rMark.IsMultiMarked() )
+ {
+ ScRangeList aMarkRangeList;
+ rMark.FillRangeListWithMarks( &aMarkRangeList, false );
+ ScDocument* pDoc = GetViewData().GetDocument();
+
+ // check if one of the marked ranges is empty
+ bool bEmpty = false;
+ const size_t nCount = aMarkRangeList.size();
+ for ( size_t i = 0; i < nCount; ++i )
+ {
+ const ScRange aRange( *aMarkRangeList[i] );
+ if ( pDoc->IsBlockEmpty( aRange.aStart.Tab(),
+ aRange.aStart.Col(), aRange.aStart.Row(),
+ aRange.aEnd.Col(), aRange.aEnd.Row() ) )
+ {
+ bEmpty = true;
+ break;
+ }
+ }
+
+ if ( bEmpty )
+ {
+ ScRangeList aRangeList;
+ const bool bDataFound = GetAutoSumArea( aRangeList );
+ if ( bDataFound )
+ {
+ ScAddress aAddr = aRangeList.back()->aEnd;
+ aAddr.IncRow();
+ const bool bSubTotal( UseSubTotal( &aRangeList ) );
+ EnterAutoSum( aRangeList, bSubTotal, aAddr );
+ }
+ }
+ else
+ {
+ const bool bSubTotal( UseSubTotal( &aMarkRangeList ) );
+ for ( size_t i = 0; i < nCount; ++i )
+ {
+ const ScRange aRange( *aMarkRangeList[i] );
+ const bool bSetCursor = ( i == nCount - 1 );
+ const bool bContinue = ( i != 0 );
+ if ( !AutoSum( aRange, bSubTotal, bSetCursor, bContinue ) )
+ {
+ MarkRange( aRange, false );
+ SetCursor( aRange.aEnd.Col(), aRange.aEnd.Row() );
+ const ScRangeList aRangeList;
+ ScAddress aAddr = aRange.aEnd;
+ aAddr.IncRow();
+ aFormula = GetAutoSumFormula( aRangeList, bSubTotal, aAddr );
+ break;
+ }
+ }
+ }
+ }
+ else // Only insert into input row
+ {
+ ScRangeList aRangeList;
+ const bool bDataFound = GetAutoSumArea( aRangeList );
+ const bool bSubTotal( UseSubTotal( &aRangeList ) );
+ ScAddress aAddr = GetViewData().GetCurPos();
+ aFormula = GetAutoSumFormula( aRangeList, bSubTotal, aAddr );
+
+ if ( bDataFound && pScMod->IsEditMode() )
+ {
+ ScInputHandler* pHdl = pScMod->GetInputHdl( this );
+ if ( pHdl )
+ {
+ pHdl->InitRangeFinder( aFormula );
+
+ //! SetSelection at the InputHandler?
+ //! Set bSelIsRef?
+ const sal_Int32 nOpen = aFormula.indexOf('(');
+ const sal_Int32 nLen = aFormula.getLength();
+ if ( nOpen != -1 && nLen > nOpen )
+ {
+ sal_uInt8 nAdd(1);
+ if (bSubTotal)
+ nAdd = 3;
+ ESelection aSel(0,nOpen+nAdd,0,nLen-1);
+ EditView* pTableView = pHdl->GetTableView();
+ if (pTableView)
+ pTableView->SetSelection(aSel);
+ EditView* pTopView = pHdl->GetTopView();
+ if (pTopView)
+ pTopView->SetSelection(aSel);
+ }
+ }
+ }
+ }
+ return aFormula;
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */