/* -*- 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/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ #undef SC_DLLIMPLEMENTATION #include #include #include #include #include #include #include #include #include #include #include #include #include // Subtotals group tabpage: ScTpSubTotalGroup::ScTpSubTotalGroup( vcl::Window* pParent, const SfxItemSet& rArgSet ) : SfxTabPage ( pParent, "SubTotalGrpPage", "modules/scalc/ui/subtotalgrppage.ui", &rArgSet ), aStrNone ( ScResId( SCSTR_NONE ) ), aStrColumn ( ScResId( SCSTR_COLUMN ) ), pViewData ( nullptr ), pDoc ( nullptr ), nWhichSubTotals ( rArgSet.GetPool()->GetWhich( SID_SUBTOTALS ) ), rSubTotalData ( static_cast( rArgSet.Get( nWhichSubTotals )). GetSubTotalData() ), nFieldCount ( 0 ) { get(mpLbGroup, "group_by"); get(mpLbColumns, "columns"); get(mpLbFunctions, "functions"); for (size_t i = 0; i < SAL_N_ELEMENTS(SCSTR_SUBTOTALS); ++i) mpLbFunctions->InsertEntry(ScResId(SCSTR_SUBTOTALS[i])); long nHeight = mpLbColumns->GetTextHeight() * 14; mpLbColumns->set_height_request(nHeight); mpLbFunctions->set_height_request(nHeight); // Font is correctly initialized by SvTreeListBox ctor mpLbColumns->SetSelectionMode( SelectionMode::Single ); mpLbColumns->SetDragDropMode( DragDropMode::NONE ); mpLbColumns->SetSpaceBetweenEntries( 0 ); Init (); } ScTpSubTotalGroup::~ScTpSubTotalGroup() { disposeOnce(); } void ScTpSubTotalGroup::dispose() { sal_uLong nCount = mpLbColumns->GetEntryCount(); if ( nCount > 0 ) { for ( sal_uLong i=0; i(mpLbColumns->GetEntryData( i )); OSL_ENSURE( pData, "EntryData not found" ); delete pData; } } mpLbGroup.clear(); mpLbColumns.clear(); mpLbFunctions.clear(); SfxTabPage::dispose(); } void ScTpSubTotalGroup::Init() { const ScSubTotalItem& rSubTotalItem = static_cast( GetItemSet().Get( nWhichSubTotals )); pViewData = rSubTotalItem.GetViewData(); pDoc = ( pViewData ) ? pViewData->GetDocument() : nullptr; OSL_ENSURE( pViewData && pDoc, "ViewData or Document not found :-(" ); mpLbGroup->SetSelectHdl ( LINK( this, ScTpSubTotalGroup, SelectListBoxHdl ) ); mpLbColumns->SetSelectHdl ( LINK( this, ScTpSubTotalGroup, SelectTreeListBoxHdl ) ); mpLbColumns->SetCheckButtonHdl( LINK( this, ScTpSubTotalGroup, CheckHdl ) ); mpLbFunctions->SetSelectHdl ( LINK( this, ScTpSubTotalGroup, SelectListBoxHdl ) ); nFieldArr[0] = 0; FillListBoxes(); } bool ScTpSubTotalGroup::DoReset( sal_uInt16 nGroupNo, const SfxItemSet& rArgSet ) { sal_uInt16 nGroupIdx = 0; OSL_ENSURE( (nGroupNo<=3) && (nGroupNo>0), "Invalid group" ); if ( (nGroupNo > 3) || (nGroupNo == 0) ) return false; else nGroupIdx = nGroupNo-1; // first we have to clear the listboxes... for ( sal_uLong nLbEntry = 0; nLbEntry < mpLbColumns->GetEntryCount(); ++nLbEntry ) { mpLbColumns->CheckEntryPos( nLbEntry, false ); *static_cast(mpLbColumns->GetEntryData( nLbEntry )) = 0; } mpLbFunctions->SelectEntryPos( 0 ); ScSubTotalParam theSubTotalData( static_cast( rArgSet.Get( nWhichSubTotals )). GetSubTotalData() ); if ( theSubTotalData.bGroupActive[nGroupIdx] ) { SCCOL nField = theSubTotalData.nField[nGroupIdx]; SCCOL nSubTotals = theSubTotalData.nSubTotals[nGroupIdx]; SCCOL* pSubTotals = theSubTotalData.pSubTotals[nGroupIdx]; ScSubTotalFunc* pFunctions = theSubTotalData.pFunctions[nGroupIdx]; mpLbGroup->SelectEntryPos( GetFieldSelPos( nField )+1 ); sal_uInt16 nFirstChecked = 0; for ( sal_uInt16 i=0; i(mpLbColumns->GetEntryData( nCheckPos )); mpLbColumns->CheckEntryPos( nCheckPos ); *pFunction = FuncToLbPos( pFunctions[i] ); if (i == 0 || nCheckPos < nFirstChecked) nFirstChecked = nCheckPos; } // Select the first checked field from the top. mpLbColumns->SelectEntryPos(nFirstChecked); } else { mpLbGroup->SelectEntryPos( (nGroupNo == 1) ? 1 : 0 ); mpLbColumns->SelectEntryPos( 0 ); mpLbFunctions->SelectEntryPos( 0 ); } return true; } bool ScTpSubTotalGroup::DoFillItemSet( sal_uInt16 nGroupNo, SfxItemSet& rArgSet ) { sal_uInt16 nGroupIdx = 0; OSL_ENSURE( (nGroupNo<=3) && (nGroupNo>0), "Invalid group" ); OSL_ENSURE( (mpLbGroup->GetEntryCount() > 0) && (mpLbColumns->GetEntryCount() > 0) && (mpLbFunctions->GetEntryCount() > 0), "Non-initialized Lists" ); if ( (nGroupNo > 3) || (nGroupNo == 0) || (mpLbGroup->GetEntryCount() == 0) || (mpLbColumns->GetEntryCount() == 0) || (mpLbFunctions->GetEntryCount() == 0) ) return false; else nGroupIdx = nGroupNo-1; ScSubTotalParam theSubTotalData; // read out, if already partly filled const SfxItemSet* pExample = GetDialogExampleSet(); if (pExample) { const SfxPoolItem* pItem; if (pExample->GetItemState(nWhichSubTotals, true, &pItem) == SfxItemState::SET) theSubTotalData = static_cast(pItem)->GetSubTotalData(); } std::unique_ptr pFunctions; std::unique_ptr pSubTotals; const sal_Int32 nGroup = mpLbGroup->GetSelectedEntryPos(); const sal_Int32 nEntryCount = mpLbColumns->GetEntryCount(); const sal_Int32 nCheckCount = mpLbColumns->GetCheckedEntryCount(); theSubTotalData.nCol1 = rSubTotalData.nCol1; theSubTotalData.nRow1 = rSubTotalData.nRow1; theSubTotalData.nCol2 = rSubTotalData.nCol2; theSubTotalData.nRow2 = rSubTotalData.nRow2; theSubTotalData.bGroupActive[nGroupIdx] = (nGroup != 0); theSubTotalData.nField[nGroupIdx] = (nGroup != 0) ? nFieldArr[nGroup-1] : static_cast(0); if ( nEntryCount>0 && nCheckCount>0 && nGroup!=0 ) { sal_uInt16 nFunction = 0; pSubTotals.reset(new SCCOL [nCheckCount]); pFunctions.reset(new ScSubTotalFunc [nCheckCount]); for ( sal_Int32 i=0, nCheck=0; iIsChecked( i ) ) { OSL_ENSURE( nCheck <= nCheckCount, "Range error :-(" ); nFunction = *static_cast(mpLbColumns->GetEntryData( i )); pSubTotals[nCheck] = nFieldArr[i]; pFunctions[nCheck] = LbPosToFunc( nFunction ); nCheck++; } } theSubTotalData.SetSubTotals( nGroupNo, // group number pSubTotals.get(), pFunctions.get(), nCheckCount ); // number of array elements } rArgSet.Put( ScSubTotalItem( SCITEM_SUBTDATA, &theSubTotalData ) ); return true; } void ScTpSubTotalGroup::FillListBoxes() { OSL_ENSURE( pViewData && pDoc, "ViewData or Document not found :-/" ); if ( pViewData && pDoc ) { SCCOL nFirstCol = rSubTotalData.nCol1; SCROW nFirstRow = rSubTotalData.nRow1; SCTAB nTab = pViewData->GetTabNo(); SCCOL nMaxCol = rSubTotalData.nCol2; SCCOL col; OUString aFieldName; mpLbGroup->Clear(); mpLbColumns->Clear(); mpLbGroup->InsertEntry( aStrNone, 0 ); sal_uInt16 i=0; for ( col=nFirstCol; col<=nMaxCol && iGetString(col, nFirstRow, nTab); if ( aFieldName.isEmpty() ) { aFieldName = ScGlobal::ReplaceOrAppend( aStrColumn, "%1", ScColToAlpha( col )); } nFieldArr[i] = col; mpLbGroup->InsertEntry( aFieldName, i+1 ); mpLbColumns->InsertEntry( aFieldName, i ); mpLbColumns->SetEntryData( i, new sal_uInt16(0) ); i++; } // subsequent initialization of the constant: nFieldCount = i; } } sal_uInt16 ScTpSubTotalGroup::GetFieldSelPos( SCCOL nField ) { sal_uInt16 nFieldPos = 0; bool bFound = false; for ( sal_uInt16 n=0; nGetEntryCount() > 0) && (mpLbColumns->GetSelectionCount() > 0) ) { const sal_Int32 nFunction = mpLbFunctions->GetSelectedEntryPos(); const sal_Int32 nColumn = mpLbColumns->GetSelectedEntryPos(); sal_uInt16* pFunction = static_cast(mpLbColumns->GetEntryData( nColumn )); OSL_ENSURE( pFunction, "EntryData not found!" ); if ( !pFunction ) return; if ( pLb == mpLbColumns ) { mpLbFunctions->SelectEntryPos( *pFunction ); } else if ( pLb == mpLbFunctions ) { *pFunction = static_cast(nFunction); mpLbColumns->CheckEntryPos( nColumn ); } } } IMPL_LINK( ScTpSubTotalGroup, CheckHdl, SvTreeListBox*, pLb, void ) { if ( pLb == mpLbColumns ) { SvTreeListEntry* pEntry = mpLbColumns->GetHdlEntry(); if ( pEntry ) { mpLbColumns->SelectEntryPos( static_cast(mpLbColumns->GetModel()->GetAbsPos( pEntry )) ); SelectHdl( pLb ); } } } // Derived Group TabPages: VclPtr ScTpSubTotalGroup1::Create( TabPageParent pParent, const SfxItemSet* rArgSet ) { return VclPtr::Create( pParent.pParent, *rArgSet ); } VclPtr ScTpSubTotalGroup2::Create( TabPageParent pParent, const SfxItemSet* rArgSet ) { return VclPtr::Create( pParent.pParent, *rArgSet ); } VclPtr ScTpSubTotalGroup3::Create( TabPageParent pParent, const SfxItemSet* rArgSet ) { return VclPtr::Create( pParent.pParent, *rArgSet ); } ScTpSubTotalGroup1::ScTpSubTotalGroup1( vcl::Window* pParent, const SfxItemSet& rArgSet ) : ScTpSubTotalGroup( pParent, rArgSet ) {} ScTpSubTotalGroup2::ScTpSubTotalGroup2( vcl::Window* pParent, const SfxItemSet& rArgSet ) : ScTpSubTotalGroup( pParent, rArgSet ) {} ScTpSubTotalGroup3::ScTpSubTotalGroup3( vcl::Window* pParent, const SfxItemSet& rArgSet ) : ScTpSubTotalGroup( pParent, rArgSet ) {} #define RESET(i) (ScTpSubTotalGroup::DoReset( (i), *rArgSet )) void ScTpSubTotalGroup1::Reset( const SfxItemSet* rArgSet ) { RESET(1); } void ScTpSubTotalGroup2::Reset( const SfxItemSet* rArgSet ) { RESET(2); } void ScTpSubTotalGroup3::Reset( const SfxItemSet* rArgSet ) { RESET(3); } #undef RESET #define FILLSET(i) (ScTpSubTotalGroup::DoFillItemSet( (i), *rArgSet )) bool ScTpSubTotalGroup1::FillItemSet( SfxItemSet* rArgSet ) { return FILLSET(1); } bool ScTpSubTotalGroup2::FillItemSet( SfxItemSet* rArgSet ) { return FILLSET(2); } bool ScTpSubTotalGroup3::FillItemSet( SfxItemSet* rArgSet ) { return FILLSET(3); } #undef FILL // options tab page: ScTpSubTotalOptions::ScTpSubTotalOptions(TabPageParent pParent, const SfxItemSet& rArgSet) : SfxTabPage ( pParent, "modules/scalc/ui/subtotaloptionspage.ui", "SubTotalOptionsPage", &rArgSet ), pViewData ( nullptr ), pDoc ( nullptr ), nWhichSubTotals ( rArgSet.GetPool()->GetWhich( SID_SUBTOTALS ) ), rSubTotalData ( static_cast( rArgSet.Get( nWhichSubTotals )). GetSubTotalData() ) , m_xBtnPagebreak(m_xBuilder->weld_check_button("pagebreak")) , m_xBtnCase(m_xBuilder->weld_check_button("case")) , m_xBtnSort(m_xBuilder->weld_check_button("sort")) , m_xFlSort(m_xBuilder->weld_label("label2")) , m_xBtnAscending(m_xBuilder->weld_radio_button("ascending")) , m_xBtnDescending(m_xBuilder->weld_radio_button("descending")) , m_xBtnFormats(m_xBuilder->weld_check_button("formats")) , m_xBtnUserDef(m_xBuilder->weld_check_button("btnuserdef")) , m_xLbUserDef(m_xBuilder->weld_combo_box("lbuserdef")) { Init(); } ScTpSubTotalOptions::~ScTpSubTotalOptions() { disposeOnce(); } void ScTpSubTotalOptions::Init() { const ScSubTotalItem& rSubTotalItem = static_cast( GetItemSet().Get( nWhichSubTotals )); pViewData = rSubTotalItem.GetViewData(); pDoc = ( pViewData ) ? pViewData->GetDocument() : nullptr; OSL_ENSURE( pViewData && pDoc, "ViewData or Document not found!" ); m_xBtnSort->connect_clicked( LINK( this, ScTpSubTotalOptions, CheckHdl ) ); m_xBtnUserDef->connect_clicked( LINK( this, ScTpSubTotalOptions, CheckHdl ) ); FillUserSortListBox(); } VclPtr ScTpSubTotalOptions::Create(TabPageParent pParent, const SfxItemSet* rArgSet) { return VclPtr::Create(pParent, *rArgSet); } void ScTpSubTotalOptions::Reset( const SfxItemSet* /* rArgSet */ ) { m_xBtnPagebreak->set_active( rSubTotalData.bPagebreak ); m_xBtnCase->set_active( rSubTotalData.bCaseSens ); m_xBtnFormats->set_active( rSubTotalData.bIncludePattern ); m_xBtnSort->set_active( rSubTotalData.bDoSort ); m_xBtnAscending->set_active( rSubTotalData.bAscending ); m_xBtnDescending->set_active( !rSubTotalData.bAscending ); if ( rSubTotalData.bUserDef ) { m_xBtnUserDef->set_active(true); m_xLbUserDef->set_sensitive(true); m_xLbUserDef->set_active(rSubTotalData.nUserIndex); } else { m_xBtnUserDef->set_active( false ); m_xLbUserDef->set_sensitive(false); m_xLbUserDef->set_active(0); } CheckHdl(*m_xBtnSort); } bool ScTpSubTotalOptions::FillItemSet( SfxItemSet* rArgSet ) { ScSubTotalParam theSubTotalData; // read out, if already partly filled const SfxItemSet* pExample = GetDialogExampleSet(); if (pExample) { const SfxPoolItem* pItem; if (pExample->GetItemState(nWhichSubTotals, true, &pItem) == SfxItemState::SET) theSubTotalData = static_cast(pItem)->GetSubTotalData(); } theSubTotalData.bPagebreak = m_xBtnPagebreak->get_active(); theSubTotalData.bReplace = true; theSubTotalData.bCaseSens = m_xBtnCase->get_active(); theSubTotalData.bIncludePattern = m_xBtnFormats->get_active(); theSubTotalData.bDoSort = m_xBtnSort->get_active(); theSubTotalData.bAscending = m_xBtnAscending->get_active(); theSubTotalData.bUserDef = m_xBtnUserDef->get_active(); theSubTotalData.nUserIndex = (m_xBtnUserDef->get_active()) ? m_xLbUserDef->get_active() : 0; rArgSet->Put( ScSubTotalItem( nWhichSubTotals, &theSubTotalData ) ); return true; } void ScTpSubTotalOptions::FillUserSortListBox() { ScUserList* pUserLists = ScGlobal::GetUserList(); m_xLbUserDef->freeze(); m_xLbUserDef->clear(); if ( pUserLists ) { size_t nCount = pUserLists->size(); for ( size_t i=0; iappend_text((*pUserLists)[i].GetString() ); } m_xLbUserDef->thaw(); } // Handler: IMPL_LINK(ScTpSubTotalOptions, CheckHdl, weld::Button&, rBox, void) { if (&rBox == m_xBtnSort.get()) { if ( m_xBtnSort->get_active() ) { m_xFlSort->set_sensitive(true); m_xBtnFormats->set_sensitive(true); m_xBtnUserDef->set_sensitive(true); m_xBtnAscending->set_sensitive(true); m_xBtnDescending->set_sensitive(true); if ( m_xBtnUserDef->get_active() ) m_xLbUserDef->set_sensitive(true); } else { m_xFlSort->set_sensitive(false); m_xBtnFormats->set_sensitive(false); m_xBtnUserDef->set_sensitive(false); m_xBtnAscending->set_sensitive(false); m_xBtnDescending->set_sensitive(false); m_xLbUserDef->set_sensitive(false); } } else if (&rBox == m_xBtnUserDef.get()) { if ( m_xBtnUserDef->get_active() ) { m_xLbUserDef->set_sensitive(true); m_xLbUserDef->grab_focus(); } else m_xLbUserDef->set_sensitive(false); } } ScTpSubTotalGroup1::~ScTpSubTotalGroup1() { } ScTpSubTotalGroup2::~ScTpSubTotalGroup2() { } ScTpSubTotalGroup3::~ScTpSubTotalGroup3() { } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */