diff options
author | Henry Castro <hcastro@collabora.com> | 2016-10-04 11:28:27 -0400 |
---|---|---|
committer | Henry Castro <hcastro@collabora.com> | 2016-10-05 17:12:18 +0000 |
commit | af239f5affe82d0c6449e0e8f9828fe587033f02 (patch) | |
tree | cc8749c911aa1b0007047fe38b26d34184cc804c | |
parent | 306add13e1d9f70e1111acde8362aea6c169a97d (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.hrc | 1 | ||||
-rw-r--r-- | sc/qa/unit/tiledrendering/tiledrendering.cxx | 26 | ||||
-rw-r--r-- | sc/sdi/cellsh.sdi | 1 | ||||
-rw-r--r-- | sc/sdi/scalc.sdi | 18 | ||||
-rw-r--r-- | sc/source/ui/app/inputwin.cxx | 151 | ||||
-rw-r--r-- | sc/source/ui/inc/inputwin.hxx | 1 | ||||
-rw-r--r-- | sc/source/ui/inc/tabvwsh.hxx | 2 | ||||
-rw-r--r-- | sc/source/ui/view/cellsh1.cxx | 33 | ||||
-rw-r--r-- | sc/source/ui/view/tabvwshc.cxx | 153 |
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: */ |