/* -*- 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 . */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define QUERY_ENTRY_COUNT 4 #define INVALID_HEADER_POS std::numeric_limits::max() ScFilterDlg::EntryList::EntryList() : mnHeaderPos(INVALID_HEADER_POS) {} ScFilterDlg::ScFilterDlg(SfxBindings* pB, SfxChildWindow* pCW, weld::Window* pParent, const SfxItemSet& rArgSet) : ScAnyRefDlgController(pB, pCW, pParent, "modules/scalc/ui/standardfilterdialog.ui", "StandardFilterDialog") , aStrUndefined(ScResId(SCSTR_UNDEFINED)) , aStrNone(ScResId(SCSTR_NONE)) , aStrEmpty(ScResId(SCSTR_FILTER_EMPTY)) , aStrNotEmpty(ScResId(SCSTR_FILTER_NOTEMPTY)) , aStrColumn(ScResId(SCSTR_COLUMN)) , aStrTextColor(ScResId(SCSTR_FILTER_TEXT_COLOR_COND)) , aStrBackgroundColor(ScResId(SCSTR_FILTER_BACKGROUND_COLOR_COND)) , nWhichQuery(rArgSet.GetPool()->GetWhich(SID_QUERY)) , theQueryData(static_cast(rArgSet.Get(nWhichQuery)).GetQueryData()) , pViewData(nullptr) , pDoc(nullptr) , nSrcTab(0) , bRefInputMode(false) , m_xLbConnect1(m_xBuilder->weld_combo_box("connect1")) , m_xLbField1(m_xBuilder->weld_combo_box("field1")) , m_xLbCond1(m_xBuilder->weld_combo_box("cond1")) , m_xEdVal1(m_xBuilder->weld_combo_box("val1")) , m_xLbColor1(m_xBuilder->weld_combo_box("color1")) , m_xBtnRemove1(m_xBuilder->weld_button("remove1")) , m_xLbConnect2(m_xBuilder->weld_combo_box("connect2")) , m_xLbField2(m_xBuilder->weld_combo_box("field2")) , m_xLbCond2(m_xBuilder->weld_combo_box("cond2")) , m_xEdVal2(m_xBuilder->weld_combo_box("val2")) , m_xLbColor2(m_xBuilder->weld_combo_box("color2")) , m_xBtnRemove2(m_xBuilder->weld_button("remove2")) , m_xLbConnect3(m_xBuilder->weld_combo_box("connect3")) , m_xLbField3(m_xBuilder->weld_combo_box("field3")) , m_xLbCond3(m_xBuilder->weld_combo_box("cond3")) , m_xEdVal3(m_xBuilder->weld_combo_box("val3")) , m_xLbColor3(m_xBuilder->weld_combo_box("color3")) , m_xBtnRemove3(m_xBuilder->weld_button("remove3")) , m_xLbConnect4(m_xBuilder->weld_combo_box("connect4")) , m_xLbField4(m_xBuilder->weld_combo_box("field4")) , m_xLbCond4(m_xBuilder->weld_combo_box("cond4")) , m_xEdVal4(m_xBuilder->weld_combo_box("val4")) , m_xLbColor4(m_xBuilder->weld_combo_box("color4")) , m_xBtnRemove4(m_xBuilder->weld_button("remove4")) , m_xContents(m_xBuilder->weld_widget("grid")) , m_xScrollBar(m_xBuilder->weld_scrolled_window("scrollbar", true)) , m_xExpander(m_xBuilder->weld_expander("more")) , m_xBtnClear(m_xBuilder->weld_button("clear")) , m_xBtnOk(m_xBuilder->weld_button("ok")) , m_xBtnCancel(m_xBuilder->weld_button("cancel")) , m_xBtnCase(m_xBuilder->weld_check_button("case")) , m_xBtnRegExp(m_xBuilder->weld_check_button("regexp")) , m_xBtnHeader(m_xBuilder->weld_check_button("header")) , m_xBtnUnique(m_xBuilder->weld_check_button("unique")) , m_xBtnCopyResult(m_xBuilder->weld_check_button("copyresult")) , m_xLbCopyArea(m_xBuilder->weld_combo_box("lbcopyarea")) , m_xEdCopyArea(new formula::RefEdit(m_xBuilder->weld_entry("edcopyarea"))) , m_xRbCopyArea(new formula::RefButton(m_xBuilder->weld_button("rbcopyarea"))) , m_xBtnDestPers(m_xBuilder->weld_check_button("destpers")) , m_xFtDbAreaLabel(m_xBuilder->weld_label("dbarealabel")) , m_xFtDbArea(m_xBuilder->weld_label("dbarea")) { m_xExpander->connect_expanded(LINK(this, ScFilterDlg, MoreExpandedHdl)); m_xEdCopyArea->SetReferences(this, m_xFtDbAreaLabel.get()); m_xRbCopyArea->SetReferences(this, m_xEdCopyArea.get()); assert(m_xLbCond1->find_text(aStrTextColor) != -1); assert(m_xLbCond1->find_text(aStrBackgroundColor) != -1); Init( rArgSet ); // Hack: RefInput control pTimer.reset( new Timer("ScFilterTimer") ); pTimer->SetTimeout( 50 ); // Wait 50ms pTimer->SetInvokeHandler( LINK( this, ScFilterDlg, TimeOutHdl ) ); } ScFilterDlg::~ScFilterDlg() { pOptionsMgr.reset(); pOutItem.reset(); // Hack: RefInput control pTimer->Stop(); pTimer.reset(); } namespace { VirtualDevice* lcl_getColorImage(const Color &rColor) { const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings(); Size aImageSize(rStyleSettings.GetListBoxPreviewDefaultPixelSize()); VclPtrInstance xDevice; xDevice->SetOutputSize(aImageSize); const tools::Rectangle aRect(Point(0, 0), aImageSize); if (rColor == COL_NONE_COLOR) { const Color aW(COL_WHITE); const Color aG(0xef, 0xef, 0xef); xDevice->DrawCheckered(aRect.TopLeft(), aRect.GetSize(), 8, aW, aG); xDevice->SetFillColor(); } else { xDevice->SetFillColor(rColor); } xDevice->DrawRect(aRect); return xDevice.get(); } } void ScFilterDlg::Init( const SfxItemSet& rArgSet ) { const ScQueryItem& rQueryItem = static_cast( rArgSet.Get( nWhichQuery )); m_xBtnClear->connect_clicked ( LINK( this, ScFilterDlg, BtnClearHdl ) ); m_xBtnOk->connect_clicked ( LINK( this, ScFilterDlg, EndDlgHdl ) ); m_xBtnCancel->connect_clicked ( LINK( this, ScFilterDlg, EndDlgHdl ) ); m_xBtnHeader->connect_toggled ( LINK( this, ScFilterDlg, CheckBoxHdl ) ); m_xBtnCase->connect_toggled ( LINK( this, ScFilterDlg, CheckBoxHdl ) ); m_xLbField1->connect_changed ( LINK( this, ScFilterDlg, LbSelectHdl ) ); m_xLbField2->connect_changed ( LINK( this, ScFilterDlg, LbSelectHdl ) ); m_xLbField3->connect_changed ( LINK( this, ScFilterDlg, LbSelectHdl ) ); m_xLbField4->connect_changed ( LINK( this, ScFilterDlg, LbSelectHdl ) ); m_xLbConnect1->connect_changed( LINK( this, ScFilterDlg, LbSelectHdl ) ); m_xLbConnect2->connect_changed( LINK( this, ScFilterDlg, LbSelectHdl ) ); m_xLbConnect3->connect_changed( LINK( this, ScFilterDlg, LbSelectHdl ) ); m_xLbConnect4->connect_changed( LINK( this, ScFilterDlg, LbSelectHdl ) ); m_xLbField1->append_text("0000000000"); m_xLbField1->set_active(0); auto nPrefWidth = m_xLbField1->get_preferred_size().Width(); m_xLbField1->clear(); m_xLbField1->set_size_request(nPrefWidth, -1); m_xLbField2->set_size_request(nPrefWidth, -1); m_xLbField3->set_size_request(nPrefWidth, -1); m_xLbField4->set_size_request(nPrefWidth, -1); m_xLbCond1->connect_changed( LINK( this, ScFilterDlg, LbSelectHdl ) ); m_xLbCond2->connect_changed( LINK( this, ScFilterDlg, LbSelectHdl ) ); m_xLbCond3->connect_changed( LINK( this, ScFilterDlg, LbSelectHdl ) ); m_xLbCond4->connect_changed( LINK( this, ScFilterDlg, LbSelectHdl ) ); m_xLbColor1->connect_changed( LINK( this, ScFilterDlg, LbSelectHdl ) ); m_xLbColor2->connect_changed( LINK( this, ScFilterDlg, LbSelectHdl ) ); m_xLbColor3->connect_changed( LINK( this, ScFilterDlg, LbSelectHdl ) ); m_xLbColor4->connect_changed( LINK( this, ScFilterDlg, LbSelectHdl ) ); m_xBtnRemove1->connect_clicked( LINK( this, ScFilterDlg, BtnRemoveHdl ) ); m_xBtnRemove2->connect_clicked( LINK( this, ScFilterDlg, BtnRemoveHdl ) ); m_xBtnRemove3->connect_clicked( LINK( this, ScFilterDlg, BtnRemoveHdl ) ); m_xBtnRemove4->connect_clicked( LINK( this, ScFilterDlg, BtnRemoveHdl ) ); pViewData = rQueryItem.GetViewData(); pDoc = pViewData ? &pViewData->GetDocument() : nullptr; nSrcTab = pViewData ? pViewData->GetTabNo() : static_cast(0); // for easier access: maFieldLbArr.reserve(QUERY_ENTRY_COUNT); maFieldLbArr.push_back(m_xLbField1.get()); maFieldLbArr.push_back(m_xLbField2.get()); maFieldLbArr.push_back(m_xLbField3.get()); maFieldLbArr.push_back(m_xLbField4.get()); maValueEdArr.reserve(QUERY_ENTRY_COUNT); maValueEdArr.push_back(m_xEdVal1.get()); maValueEdArr.push_back(m_xEdVal2.get()); maValueEdArr.push_back(m_xEdVal3.get()); maValueEdArr.push_back(m_xEdVal4.get()); maCondLbArr.reserve(QUERY_ENTRY_COUNT); maCondLbArr.push_back(m_xLbCond1.get()); maCondLbArr.push_back(m_xLbCond2.get()); maCondLbArr.push_back(m_xLbCond3.get()); maCondLbArr.push_back(m_xLbCond4.get()); maConnLbArr.reserve(QUERY_ENTRY_COUNT); maConnLbArr.push_back(m_xLbConnect1.get()); maConnLbArr.push_back(m_xLbConnect2.get()); maConnLbArr.push_back(m_xLbConnect3.get()); maConnLbArr.push_back(m_xLbConnect4.get()); maColorLbArr.reserve(QUERY_ENTRY_COUNT); maColorLbArr.push_back(m_xLbColor1.get()); maColorLbArr.push_back(m_xLbColor2.get()); maColorLbArr.push_back(m_xLbColor3.get()); maColorLbArr.push_back(m_xLbColor4.get()); maRemoveBtnArr.reserve(QUERY_ENTRY_COUNT); maRemoveBtnArr.push_back(m_xBtnRemove1.get()); maRemoveBtnArr.push_back(m_xBtnRemove2.get()); maRemoveBtnArr.push_back(m_xBtnRemove3.get()); maRemoveBtnArr.push_back(m_xBtnRemove4.get()); // Option initialization: pOptionsMgr.reset( new ScFilterOptionsMgr( pViewData, theQueryData, m_xBtnCase.get(), m_xBtnRegExp.get(), m_xBtnHeader.get(), m_xBtnUnique.get(), m_xBtnCopyResult.get(), m_xBtnDestPers.get(), m_xLbCopyArea.get(), m_xEdCopyArea.get(), m_xRbCopyArea.get(), m_xFtDbAreaLabel.get(), m_xFtDbArea.get(), aStrUndefined ) ); // Read in field lists and select entries FillFieldLists(); for (size_t i = 0; i < QUERY_ENTRY_COUNT; ++i) { OUString aValStr; size_t nCondPos = 0; size_t nFieldSelPos = 0; maColorLbArr[i]->set_visible(false); ScQueryEntry& rEntry = theQueryData.GetEntry(i); if ( rEntry.bDoQuery ) { nCondPos = static_cast(rEntry.eOp); nFieldSelPos = GetFieldSelPos( static_cast(rEntry.nField) ); if (rEntry.IsQueryByEmpty()) { aValStr = aStrEmpty; maCondLbArr[i]->set_sensitive(false); } else if (rEntry.IsQueryByNonEmpty()) { aValStr = aStrNotEmpty; maCondLbArr[i]->set_sensitive(false); } else if (rEntry.IsQueryByTextColor() || rEntry.IsQueryByBackgroundColor()) { nCondPos = maCondLbArr[i]->find_text( rEntry.IsQueryByTextColor() ? aStrTextColor : aStrBackgroundColor); maValueEdArr[i]->set_visible(false); maColorLbArr[i]->set_visible(true); maColorLbArr[i]->set_sensitive(true); } else { const ScQueryEntry::Item& rItem = rEntry.GetQueryItem(); OUString aQueryStr = rItem.maString.getString(); SetValString(aQueryStr, rItem, aValStr); } } else if ( i == 0 ) { nFieldSelPos = pViewData ? GetFieldSelPos(pViewData->GetCurX()) : 0; rEntry.nField = nFieldSelPos ? (theQueryData.nCol1 + static_cast(nFieldSelPos) - 1) : static_cast(0); rEntry.bDoQuery=true; if (maRefreshExceptQuery.size() < i + 1) maRefreshExceptQuery.resize(i + 1, false); maRefreshExceptQuery[i] = true; } maFieldLbArr[i]->set_active( nFieldSelPos ); maCondLbArr [i]->set_active( nCondPos ); maValueEdArr[i]->set_entry_text( aValStr ); maValueEdArr[i]->set_entry_completion(false); maValueEdArr[i]->connect_changed( LINK( this, ScFilterDlg, ValModifyHdl ) ); UpdateValueList(i+1); UpdateColorList(i+1); } m_xScrollBar->connect_vadjustment_changed( LINK( this, ScFilterDlg, ScrollHdl ) ); m_xScrollBar->vadjustment_configure(0, 0, 8, 1, 3, 4); Size aSize(m_xContents->get_preferred_size()); m_xContents->set_size_request(aSize.Width(), aSize.Height()); m_xLbConnect1->hide(); // Disable/Enable Logic: (m_xLbField1->get_active() != 0) && (m_xLbField2->get_active() != 0) ? m_xLbConnect2->set_active( static_cast(theQueryData.GetEntry(1).eConnect) ) : m_xLbConnect2->set_active(-1); (m_xLbField2->get_active() != 0) && (m_xLbField3->get_active() != 0) ? m_xLbConnect3->set_active( static_cast(theQueryData.GetEntry(2).eConnect) ) : m_xLbConnect3->set_active(-1); (m_xLbField3->get_active() != 0) && (m_xLbField4->get_active() != 0) ? m_xLbConnect4->set_active( static_cast(theQueryData.GetEntry(3).eConnect) ) : m_xLbConnect4->set_active(-1); if ( m_xLbField1->get_active() == 0 ) { m_xLbConnect2->set_sensitive(false); m_xLbField2->set_sensitive(false); m_xLbCond2->set_sensitive(false); m_xEdVal2->set_sensitive(false); m_xLbColor2->set_sensitive(false); m_xBtnRemove2->set_sensitive(false); } else if ( m_xLbConnect2->get_active() == -1 ) { m_xLbField2->set_sensitive(false); m_xLbCond2->set_sensitive(false); m_xEdVal2->set_sensitive(false); m_xLbColor2->set_sensitive(false); m_xBtnRemove2->set_sensitive(false); } if ( m_xLbField2->get_active() == 0 ) { m_xLbConnect3->set_sensitive(false); m_xLbField3->set_sensitive(false); m_xLbCond3->set_sensitive(false); m_xEdVal3->set_sensitive(false); m_xLbColor3->set_sensitive(false); m_xBtnRemove3->set_sensitive(false); } else if ( m_xLbConnect3->get_active() == -1 ) { m_xLbField3->set_sensitive(false); m_xLbCond3->set_sensitive(false); m_xEdVal3->set_sensitive(false); m_xLbColor3->set_sensitive(false); m_xBtnRemove3->set_sensitive(false); } if ( m_xLbField3->get_active() == 0 ) { m_xLbConnect4->set_sensitive(false); m_xLbField4->set_sensitive(false); m_xLbCond4->set_sensitive(false); m_xEdVal4->set_sensitive(false); m_xLbColor4->set_sensitive(false); m_xBtnRemove4->set_sensitive(false); } else if ( m_xLbConnect4->get_active() == -1 ) { m_xLbField4->set_sensitive(false); m_xLbCond4->set_sensitive(false); m_xEdVal4->set_sensitive(false); m_xLbColor4->set_sensitive(false); m_xBtnRemove4->set_sensitive(false); } m_xEdVal1->set_entry_width_chars(10); m_xEdVal2->set_entry_width_chars(10); m_xEdVal3->set_entry_width_chars(10); m_xEdVal4->set_entry_width_chars(10); if (pDoc != nullptr && pDoc->GetChangeTrack() != nullptr) m_xBtnCopyResult->set_sensitive(false); } void ScFilterDlg::Close() { if (pViewData) pViewData->GetDocShell()->CancelAutoDBRange(); DoClose( ScFilterDlgWrapper::GetChildWindowId() ); } // Mouse-selected cell area becomes the new selection and is shown in the // reference text box void ScFilterDlg::SetReference( const ScRange& rRef, ScDocument& rDocP ) { if ( bRefInputMode ) // Only possible if in reference edit mode { if ( rRef.aStart != rRef.aEnd ) RefInputStart( m_xEdCopyArea.get() ); OUString aRefStr(rRef.aStart.Format(ScRefFlags::ADDR_ABS_3D, &rDocP, rDocP.GetAddressConvention())); m_xEdCopyArea->SetRefString( aRefStr ); } } void ScFilterDlg::SetActive() { if ( bRefInputMode ) { m_xEdCopyArea->GrabFocus(); m_xEdCopyArea->GetModifyHdl().Call( *m_xEdCopyArea ); } else m_xDialog->grab_focus(); RefInputDone(); } void ScFilterDlg::FillFieldLists() { m_xLbField1->freeze(); m_xLbField2->freeze(); m_xLbField3->freeze(); m_xLbField4->freeze(); m_xLbField1->clear(); m_xLbField2->clear(); m_xLbField3->clear(); m_xLbField4->clear(); m_xLbField1->append_text( aStrNone ); m_xLbField2->append_text( aStrNone ); m_xLbField3->append_text( aStrNone ); m_xLbField4->append_text( aStrNone ); if ( pDoc ) { OUString aFieldName; SCTAB nTab = nSrcTab; SCCOL nFirstCol = theQueryData.nCol1; SCROW nFirstRow = theQueryData.nRow1; SCCOL nMaxCol = theQueryData.nCol2; SCCOL col = 0; for ( col=nFirstCol; col<=nMaxCol; col++ ) { aFieldName = pDoc->GetString(col, nFirstRow, nTab); if (!m_xBtnHeader->get_active() || aFieldName.isEmpty()) { aFieldName = ScGlobal::ReplaceOrAppend( aStrColumn, u"%1", ScColToAlpha( col )); } m_xLbField1->append_text( aFieldName ); m_xLbField2->append_text( aFieldName ); m_xLbField3->append_text( aFieldName ); m_xLbField4->append_text( aFieldName ); } } m_xLbField4->thaw(); m_xLbField3->thaw(); m_xLbField2->thaw(); m_xLbField1->thaw(); } void ScFilterDlg::UpdateValueList( size_t nList ) { bool bCaseSens = m_xBtnCase->get_active(); if (pDoc && nList > 0 && nList <= QUERY_ENTRY_COUNT) { weld::ComboBox* pValList = maValueEdArr[nList-1]; const sal_Int32 nFieldSelPos = maFieldLbArr[nList-1]->get_active(); OUString aCurValue = pValList->get_active_text(); std::unique_ptr xWaiter; std::vector aEntries; aEntries.emplace_back(aStrNotEmpty); aEntries.emplace_back(aStrEmpty); if (nFieldSelPos) { xWaiter.reset(new weld::WaitObject(m_xDialog.get())); // even if only the list box has content SCCOL nColumn = theQueryData.nCol1 + static_cast(nFieldSelPos) - 1; EntryList* pList = nullptr; if (!m_EntryLists.count(nColumn)) { size_t nOffset = GetSliderPos(); SCTAB nTab = nSrcTab; SCROW nFirstRow = theQueryData.nRow1; SCROW nLastRow = theQueryData.nRow2; if (maHasDates.size() < nOffset+nList) maHasDates.resize(nOffset+nList, false); maHasDates[nOffset+nList-1] = false; // first without the first line std::pair r = m_EntryLists.insert(std::make_pair(nColumn, std::make_unique())); if (!r.second) // insertion failed. return; pList = r.first->second.get(); pDoc->GetFilterEntriesArea( nColumn, nFirstRow+1, nLastRow, nTab, bCaseSens, pList->maFilterEntries); maHasDates[nOffset+nList-1] = pList->maFilterEntries.mbHasDates; // Entry for the first line //! Entry (pHdrEntry) doesn't generate collection? pList->mnHeaderPos = INVALID_HEADER_POS; ScFilterEntries aHdrColl; pDoc->GetFilterEntriesArea( nColumn, nFirstRow, nFirstRow, nTab, true, aHdrColl ); if (!aHdrColl.empty()) { // See if the header value is already in the list. std::vector::iterator itBeg = pList->maFilterEntries.begin(), itEnd = pList->maFilterEntries.end(); if (std::none_of(itBeg, itEnd, FindTypedStrData(aHdrColl.front(), bCaseSens))) { // Not in the list. Insert it. pList->maFilterEntries.push_back(aHdrColl.front()); if (bCaseSens) std::sort(pList->maFilterEntries.begin(), pList->maFilterEntries.end(), ScTypedStrData::LessCaseSensitive()); else std::sort(pList->maFilterEntries.begin(), pList->maFilterEntries.end(), ScTypedStrData::LessCaseInsensitive()); // Record its position. itBeg = pList->maFilterEntries.begin(); itEnd = pList->maFilterEntries.end(); auto it = std::find_if(itBeg, itEnd, FindTypedStrData(aHdrColl.front(), bCaseSens)); pList->mnHeaderPos = std::distance(itBeg, it); } } } else pList = m_EntryLists[nColumn].get(); assert(pList); for (const auto& rEntry : pList->maFilterEntries) aEntries.emplace_back(rEntry.GetString()); } pValList->insert_vector(aEntries, false); pValList->set_entry_text(aCurValue); } UpdateHdrInValueList( nList ); } void ScFilterDlg::UpdateHdrInValueList( size_t nList ) { //! GetText / SetText ?? if (!pDoc) return; if (nList == 0 || nList > QUERY_ENTRY_COUNT) return; size_t nFieldSelPos = maFieldLbArr[nList-1]->get_active(); if (!nFieldSelPos) return; SCCOL nColumn = theQueryData.nCol1 + static_cast(nFieldSelPos) - 1; if (!m_EntryLists.count(nColumn)) { OSL_FAIL("column not yet initialized"); return; } size_t const nPos = m_EntryLists[nColumn]->mnHeaderPos; if (nPos == INVALID_HEADER_POS) return; weld::ComboBox* pValList = maValueEdArr[nList-1]; int nListPos = nPos + 2; // for "empty" and "non-empty" const ScTypedStrData& rHdrEntry = m_EntryLists[nColumn]->maFilterEntries.maStrData[nPos]; const OUString& aHdrStr = rHdrEntry.GetString(); bool bWasThere = nListPos < pValList->get_count() && aHdrStr == pValList->get_text(nListPos); bool bInclude = !m_xBtnHeader->get_active(); if (bInclude) // Include entry { if (!bWasThere) pValList->insert_text(nListPos, aHdrStr); } else // Omit entry { if (bWasThere) pValList->remove(nListPos); } } void ScFilterDlg::ClearValueList( size_t nList ) { if (nList > 0 && nList <= QUERY_ENTRY_COUNT) { weld::ComboBox* pValList = maValueEdArr[nList-1]; pValList->clear(); pValList->append_text( aStrNotEmpty ); pValList->append_text( aStrEmpty ); pValList->set_entry_text( OUString() ); } } void ScFilterDlg::UpdateColorList(size_t nList) { if (!pDoc || nList <= 0 || nList > QUERY_ENTRY_COUNT) return; size_t nPos = nList - 1; ScQueryEntry& rEntry = theQueryData.GetEntry(nPos); const sal_Int32 nFieldSelPos = maFieldLbArr[nPos]->get_active(); if (!nFieldSelPos) return; SCCOL nColumn = theQueryData.nCol1 + static_cast(nFieldSelPos) - 1; EntryList* pList = m_EntryLists[nColumn].get(); if (!pList) return; std::set aColors; OUString sSelectedCondition = maCondLbArr[nPos]->get_active_text(); if (sSelectedCondition == aStrTextColor) aColors = pList->maFilterEntries.getTextColors(); else if (sSelectedCondition == aStrBackgroundColor) aColors = pList->maFilterEntries.getBackgroundColors(); else return; sal_Int32 i = 1; maColorLbArr[nPos]->clear(); for (const auto& rColor : aColors) { OUString sId = rColor.AsRGBHexString(); if (rColor == COL_AUTO) { OUString sText = sSelectedCondition == aStrTextColor ? ScResId(SCSTR_FILTER_AUTOMATIC_COLOR) : ScResId(SCSTR_FILTER_NO_FILL); maColorLbArr[nPos]->append(sId, sText); } else { VirtualDevice* pDev = lcl_getColorImage(rColor); maColorLbArr[nPos]->append(sId, OUString(), *pDev); } auto aItem = rEntry.GetQueryItem(); if (aItem.maColor == rColor && ((sSelectedCondition == aStrTextColor && aItem.meType == ScQueryEntry::ByTextColor) || (sSelectedCondition == aStrBackgroundColor && aItem.meType == ScQueryEntry::ByBackgroundColor))) { maColorLbArr[nPos]->set_active_id(sId); } i++; } } size_t ScFilterDlg::GetFieldSelPos( SCCOL nField ) { if ( nField >= theQueryData.nCol1 && nField <= theQueryData.nCol2 ) return static_cast(nField - theQueryData.nCol1 + 1); else return 0; } ScQueryItem* ScFilterDlg::GetOutputItem() { ScAddress theCopyPos; ScQueryParam theParam( theQueryData ); bool bCopyPosOk = false; if ( m_xBtnCopyResult->get_active() ) { ScRefFlags nResult = theCopyPos.Parse( m_xEdCopyArea->GetText(), *pDoc, pDoc->GetAddressConvention()); bCopyPosOk = (nResult & ScRefFlags::VALID) == ScRefFlags::VALID; } if ( m_xBtnCopyResult->get_active() && bCopyPosOk ) { theParam.bInplace = false; theParam.nDestTab = theCopyPos.Tab(); theParam.nDestCol = theCopyPos.Col(); theParam.nDestRow = theCopyPos.Row(); } else { theParam.bInplace = true; theParam.nDestTab = 0; theParam.nDestCol = 0; theParam.nDestRow = 0; } theParam.bHasHeader = m_xBtnHeader->get_active(); theParam.bByRow = true; theParam.bDuplicate = !m_xBtnUnique->get_active(); theParam.bCaseSens = m_xBtnCase->get_active(); theParam.eSearchType = m_xBtnRegExp->get_active() ? utl::SearchParam::SearchType::Regexp : utl::SearchParam::SearchType::Normal; theParam.bDestPers = m_xBtnDestPers->get_active(); // only set the three - reset everything else pOutItem.reset( new ScQueryItem( nWhichQuery, &theParam ) ); return pOutItem.get(); } bool ScFilterDlg::IsRefInputMode() const { return bRefInputMode; } // Handler: IMPL_LINK( ScFilterDlg, BtnClearHdl, weld::Button&, rBtn, void ) { if ( &rBtn != m_xBtnClear.get() ) return; // scroll to the top m_xScrollBar->vadjustment_set_value(0); size_t nOffset = 0; RefreshEditRow( nOffset); // clear all conditions m_xLbConnect1->set_active(-1); m_xLbConnect2->set_active(-1); m_xLbConnect3->set_active(-1); m_xLbConnect4->set_active(-1); m_xLbField1->set_active(0); m_xLbField2->set_active(0); m_xLbField3->set_active(0); m_xLbField4->set_active(0); m_xLbCond1->set_active(0); m_xLbCond2->set_active(0); m_xLbCond3->set_active(0); m_xLbCond4->set_active(0); ClearValueList( 1 ); ClearValueList( 2 ); ClearValueList( 3 ); ClearValueList( 4 ); // disable fields for second row onward m_xLbConnect2->set_sensitive(false); m_xLbConnect3->set_sensitive(false); m_xLbConnect4->set_sensitive(false); m_xLbField2->set_sensitive(false); m_xLbField3->set_sensitive(false); m_xLbField4->set_sensitive(false); m_xLbCond2->set_sensitive(false); m_xLbCond3->set_sensitive(false); m_xLbCond4->set_sensitive(false); m_xEdVal2->set_sensitive(false); m_xEdVal3->set_sensitive(false); m_xEdVal4->set_sensitive(false); m_xLbColor2->set_sensitive(false); m_xLbColor3->set_sensitive(false); m_xLbColor4->set_sensitive(false); m_xBtnRemove2->set_sensitive(false); m_xBtnRemove3->set_sensitive(false); m_xBtnRemove4->set_sensitive(false); // clear query data objects SCSIZE nCount = theQueryData.GetEntryCount(); if (maRefreshExceptQuery.size() < nCount + 1) maRefreshExceptQuery.resize(nCount + 1, false); for (SCSIZE i = 0; i < nCount; ++i) { theQueryData.GetEntry(i).bDoQuery = false; maRefreshExceptQuery[i] = false; theQueryData.GetEntry(i).nField = static_cast(0); } maRefreshExceptQuery[0] = true; } IMPL_LINK( ScFilterDlg, EndDlgHdl, weld::Button&, rBtn, void ) { if ( &rBtn == m_xBtnOk.get() ) { bool bAreaInputOk = true; if ( m_xBtnCopyResult->get_active() ) { if ( !pOptionsMgr->VerifyPosStr( m_xEdCopyArea->GetText() ) ) { if (!m_xExpander->get_expanded()) m_xExpander->set_expanded(true); std::unique_ptr xBox(Application::CreateMessageDialog(m_xDialog.get(), VclMessageType::Warning, VclButtonsType::Ok, ScResId(STR_INVALID_TABREF))); xBox->run(); m_xEdCopyArea->GrabFocus(); bAreaInputOk = false; } } if ( bAreaInputOk ) { SetDispatcherLock( false ); SwitchToDocument(); GetBindings().GetDispatcher()->ExecuteList(FID_FILTER_OK, SfxCallMode::SLOT | SfxCallMode::RECORD, { GetOutputItem() }); response(RET_OK); } } else if ( &rBtn == m_xBtnCancel.get() ) { response(RET_CANCEL); } } IMPL_LINK_NOARG(ScFilterDlg, MoreExpandedHdl, weld::Expander&, void) { if ( m_xExpander->get_expanded() ) pTimer->Start(); else { pTimer->Stop(); bRefInputMode = false; //@BugID 54702 Enable/disable only in Basic class //SFX_APPWINDOW->Disable(FALSE); //! general method in ScAnyRefDlg } } IMPL_LINK( ScFilterDlg, TimeOutHdl, Timer*, _pTimer, void ) { // Check if RefInputMode is still true every 50ms if (_pTimer == pTimer.get() && m_xDialog->has_toplevel_focus()) bRefInputMode = (m_xEdCopyArea->GetWidget()->has_focus() || m_xRbCopyArea->GetWidget()->has_focus()); if ( m_xExpander->get_expanded() ) pTimer->Start(); } IMPL_LINK(ScFilterDlg, LbSelectHdl, weld::ComboBox&, rLb, void) { /* * Handle enable/disable logic depending on which ListBox was selected */ sal_uInt16 nOffset = GetSliderPos(); if ( &rLb == m_xLbConnect1.get() ) { m_xLbField1->set_sensitive(true); m_xLbCond1->set_sensitive(true); m_xEdVal1->set_sensitive(true); m_xBtnRemove1->set_sensitive(true); const sal_Int32 nConnect1 = m_xLbConnect1->get_active(); size_t nQE = nOffset; theQueryData.GetEntry(nQE).eConnect =static_cast(nConnect1); if (maRefreshExceptQuery.size() < nQE + 1) maRefreshExceptQuery.resize(nQE + 1, false); maRefreshExceptQuery[nQE] = true; } else if ( &rLb == m_xLbConnect2.get() ) { m_xLbField2->set_sensitive(true); m_xLbCond2->set_sensitive(true); m_xEdVal2->set_sensitive(true); m_xBtnRemove2->set_sensitive(true); const sal_Int32 nConnect2 = m_xLbConnect2->get_active(); size_t nQE = 1+nOffset; theQueryData.GetEntry(nQE).eConnect =static_cast(nConnect2); if (maRefreshExceptQuery.size() < nQE + 1) maRefreshExceptQuery.resize(nQE + 1, false); maRefreshExceptQuery[nQE]=true; } else if ( &rLb == m_xLbConnect3.get() ) { m_xLbField3->set_sensitive(true); m_xLbCond3->set_sensitive(true); m_xEdVal3->set_sensitive(true); m_xBtnRemove3->set_sensitive(true); const sal_Int32 nConnect3 = m_xLbConnect3->get_active(); size_t nQE = 2 + nOffset; theQueryData.GetEntry(nQE).eConnect = static_cast(nConnect3); if (maRefreshExceptQuery.size() < nQE + 1) maRefreshExceptQuery.resize(nQE + 1, false); maRefreshExceptQuery[nQE] = true; } else if ( &rLb == m_xLbConnect4.get() ) { m_xLbField4->set_sensitive(true); m_xLbCond4->set_sensitive(true); m_xEdVal4->set_sensitive(true); m_xLbColor4->set_sensitive(true); m_xBtnRemove4->set_sensitive(true); const sal_Int32 nConnect4 = m_xLbConnect4->get_active(); size_t nQE = 3 + nOffset; theQueryData.GetEntry(nQE).eConnect = static_cast(nConnect4); if (maRefreshExceptQuery.size() < nQE + 1) maRefreshExceptQuery.resize(nQE + 1, false); maRefreshExceptQuery[nQE] = true; } else if ( &rLb == m_xLbField1.get() ) { if ( m_xLbField1->get_active() == 0 ) { m_xLbConnect2->set_active(-1); m_xLbConnect3->set_active(-1); m_xLbConnect4->set_active(-1); m_xLbField2->set_active( 0 ); m_xLbField3->set_active( 0 ); m_xLbField4->set_active( 0 ); m_xLbCond2->set_active( 0 ); m_xLbCond3->set_active( 0 ); m_xLbCond4->set_active( 0 ); ClearValueList( 1 ); ClearValueList( 2 ); ClearValueList( 3 ); ClearValueList( 4 ); m_xLbConnect2->set_sensitive(false); m_xLbConnect3->set_sensitive(false); m_xLbConnect4->set_sensitive(false); m_xLbField2->set_sensitive(false); m_xLbField3->set_sensitive(false); m_xLbField4->set_sensitive(false); m_xLbCond2->set_sensitive(false); m_xLbCond3->set_sensitive(false); m_xLbCond4->set_sensitive(false); m_xEdVal2->set_sensitive(false); m_xEdVal3->set_sensitive(false); m_xEdVal4->set_sensitive(false); m_xLbColor2->set_sensitive(false); m_xLbColor3->set_sensitive(false); m_xLbColor4->set_sensitive(false); m_xBtnRemove2->set_sensitive(false); m_xBtnRemove3->set_sensitive(false); m_xBtnRemove4->set_sensitive(false); SCSIZE nCount = theQueryData.GetEntryCount(); if (maRefreshExceptQuery.size() < nCount + 1) maRefreshExceptQuery.resize(nCount + 1, false); for (SCSIZE i = nOffset; i < nCount; ++i) { theQueryData.GetEntry(i).bDoQuery = false; maRefreshExceptQuery[i] = false; theQueryData.GetEntry(i).nField = static_cast(0); } maRefreshExceptQuery[nOffset] = true; } else { UpdateValueList( 1 ); UpdateColorList( 1 ); if ( !m_xLbConnect2->get_sensitive() ) { m_xLbConnect2->set_sensitive(true); } theQueryData.GetEntry(nOffset).bDoQuery = true; const sal_Int32 nField = rLb.get_active(); theQueryData.GetEntry(nOffset).nField = theQueryData.nCol1 + static_cast(nField) - 1 ; } } else if ( &rLb == m_xLbField2.get() ) { if ( m_xLbField2->get_active() == 0 ) { m_xLbConnect3->set_active(-1); m_xLbConnect4->set_active(-1); m_xLbField3->set_active( 0 ); m_xLbField4->set_active( 0 ); m_xLbCond3->set_active( 0 ); m_xLbCond4->set_active( 0 ); ClearValueList( 2 ); ClearValueList( 3 ); ClearValueList( 4 ); m_xLbConnect3->set_sensitive(false); m_xLbConnect4->set_sensitive(false); m_xLbField3->set_sensitive(false); m_xLbField4->set_sensitive(false); m_xLbCond3->set_sensitive(false); m_xLbCond4->set_sensitive(false); m_xEdVal3->set_sensitive(false); m_xEdVal4->set_sensitive(false); m_xLbColor3->set_sensitive(false); m_xLbColor4->set_sensitive(false); m_xBtnRemove3->set_sensitive(false); m_xBtnRemove4->set_sensitive(false); sal_uInt16 nTemp=nOffset+1; SCSIZE nCount = theQueryData.GetEntryCount(); if (maRefreshExceptQuery.size() < nCount) maRefreshExceptQuery.resize(nCount, false); for (SCSIZE i= nTemp; i< nCount; i++) { theQueryData.GetEntry(i).bDoQuery = false; maRefreshExceptQuery[i] = false; theQueryData.GetEntry(i).nField = static_cast(0); } maRefreshExceptQuery[nTemp] = true; } else { UpdateValueList( 2 ); UpdateColorList( 2 ); if ( !m_xLbConnect3->get_sensitive() ) { m_xLbConnect3->set_sensitive(true); } const sal_Int32 nField = rLb.get_active(); sal_uInt16 nQ=1+nOffset; theQueryData.GetEntry(nQ).bDoQuery = true; theQueryData.GetEntry(nQ).nField = theQueryData.nCol1 + static_cast(nField) - 1 ; } } else if ( &rLb == m_xLbField3.get() ) { if ( m_xLbField3->get_active() == 0 ) { m_xLbConnect4->set_active(-1); m_xLbField4->set_active( 0 ); m_xLbCond4->set_active( 0 ); ClearValueList( 3 ); ClearValueList( 4 ); m_xLbConnect4->set_sensitive(false); m_xLbField4->set_sensitive(false); m_xLbCond4->set_sensitive(false); m_xEdVal4->set_sensitive(false); m_xLbColor4->set_sensitive(false); m_xBtnRemove4->set_sensitive(false); sal_uInt16 nTemp=nOffset+2; SCSIZE nCount = theQueryData.GetEntryCount(); if (maRefreshExceptQuery.size() < nCount) maRefreshExceptQuery.resize(nCount, false); for (SCSIZE i = nTemp; i < nCount; ++i) { theQueryData.GetEntry(i).bDoQuery = false; maRefreshExceptQuery[i] = false; theQueryData.GetEntry(i).nField = static_cast(0); } maRefreshExceptQuery[nTemp] = true; } else { UpdateValueList( 3 ); UpdateColorList( 3 ); if ( !m_xLbConnect4->get_sensitive() ) { m_xLbConnect4->set_sensitive(true); } const sal_Int32 nField = rLb.get_active(); sal_uInt16 nQ=2+nOffset; theQueryData.GetEntry(nQ).bDoQuery = true; theQueryData.GetEntry(nQ).nField = theQueryData.nCol1 + static_cast(nField) - 1 ; } } else if ( &rLb == m_xLbField4.get() ) { if ( m_xLbField4->get_active() == 0 ) { ClearValueList( 4 ); sal_uInt16 nTemp=nOffset+3; SCSIZE nCount = theQueryData.GetEntryCount(); if (maRefreshExceptQuery.size() < nCount) maRefreshExceptQuery.resize(nCount, false); for (SCSIZE i = nTemp; i < nCount; ++i) { theQueryData.GetEntry(i).bDoQuery = false; maRefreshExceptQuery[i] = false; theQueryData.GetEntry(i).nField = static_cast(0); } maRefreshExceptQuery[nTemp] = true; } else { UpdateValueList( 4 ); UpdateColorList( 4 ); const sal_Int32 nField = rLb.get_active(); sal_uInt16 nQ=3+nOffset; theQueryData.GetEntry(nQ).bDoQuery = true; theQueryData.GetEntry(nQ).nField = theQueryData.nCol1 + static_cast(nField) - 1 ; } } else if (&rLb == m_xLbCond1.get() || &rLb == m_xLbCond2.get() || &rLb == m_xLbCond3.get() || &rLb == m_xLbCond4.get()) { ScQueryOp op; sal_uInt16 nQ = 0; bool bEnableColorLb = false; if (rLb.get_active_text() == aStrTextColor || rLb.get_active_text() == aStrBackgroundColor) { bEnableColorLb = true; op = SC_EQUAL; } else { op = static_cast(rLb.get_active()); } if (&rLb == m_xLbCond1.get()) { nQ = nOffset; m_xLbColor1->set_visible(bEnableColorLb); m_xLbColor1->set_sensitive(bEnableColorLb); m_xEdVal1->set_visible(!bEnableColorLb); UpdateColorList(1); } else if (&rLb == m_xLbCond2.get()) { nQ = 1 + nOffset; m_xLbColor2->set_visible(bEnableColorLb); m_xLbColor2->set_sensitive(bEnableColorLb); m_xEdVal2->set_visible(!bEnableColorLb); UpdateColorList(2); } else if (&rLb == m_xLbCond3.get()) { nQ = 2 + nOffset; m_xLbColor3->set_visible(bEnableColorLb); m_xLbColor3->set_sensitive(bEnableColorLb); m_xEdVal3->set_visible(!bEnableColorLb); UpdateColorList(3); } else if (&rLb == m_xLbCond4.get()) { nQ = 3 + nOffset; m_xLbColor4->set_visible(bEnableColorLb); m_xLbColor4->set_sensitive(bEnableColorLb); m_xEdVal4->set_visible(!bEnableColorLb); UpdateColorList(4); } auto aEntry = theQueryData.GetEntry(nQ); aEntry.eOp = op; } else if (&rLb == m_xLbColor1.get() || &rLb == m_xLbColor2.get() || &rLb == m_xLbColor3.get() || &rLb == m_xLbColor4.get()) { sal_uInt16 nQ = 0; if (&rLb == m_xLbColor1.get()) { nQ = nOffset; } else if (&rLb == m_xLbColor2.get()) { nQ = 1 + nOffset; } else if (&rLb == m_xLbColor3.get()) { nQ = 2 + nOffset; } else if (&rLb == m_xLbColor4.get()) { nQ = 3 + nOffset; } ScQueryEntry& aEntry = theQueryData.GetEntry(nQ); Color aColor = Color::STRtoRGB(maColorLbArr[nQ]->get_active_id()); if (maCondLbArr[nQ]->get_active_text() == aStrTextColor) { aEntry.SetQueryByTextColor(aColor); } else if (maCondLbArr[nQ]->get_active_text() == aStrBackgroundColor) { aEntry.SetQueryByBackgroundColor(aColor); } } } IMPL_LINK( ScFilterDlg, CheckBoxHdl, weld::Toggleable&, rBox, void ) { // Column headers: // Field list: Columnxx <-> column header string // Value list: Column header value not applicable. // Upper/lower case: // Value list: completely new if ( &rBox == m_xBtnHeader.get() ) // Field list and value list { const sal_Int32 nCurSel1 = m_xLbField1->get_active(); const sal_Int32 nCurSel2 = m_xLbField2->get_active(); const sal_Int32 nCurSel3 = m_xLbField3->get_active(); const sal_Int32 nCurSel4 = m_xLbField4->get_active(); FillFieldLists(); m_xLbField1->set_active( nCurSel1 ); m_xLbField2->set_active( nCurSel2 ); m_xLbField3->set_active( nCurSel3 ); m_xLbField4->set_active( nCurSel4 ); UpdateHdrInValueList( 1 ); UpdateHdrInValueList( 2 ); UpdateHdrInValueList( 3 ); UpdateHdrInValueList( 4 ); } if ( &rBox != m_xBtnCase.get() ) // Complete value list return; m_EntryLists.clear(); UpdateValueList( 1 ); // current text is recorded UpdateValueList( 2 ); UpdateValueList( 3 ); UpdateValueList( 4 ); UpdateColorList( 1 ); UpdateColorList( 2 ); UpdateColorList( 3 ); UpdateColorList( 4 ); } IMPL_LINK( ScFilterDlg, ValModifyHdl, weld::ComboBox&, rEd, void ) { size_t nOffset = GetSliderPos(); size_t i = 0; size_t nQE = i + nOffset; OUString aStrVal = rEd.get_active_text(); weld::ComboBox* pLbCond = m_xLbCond1.get(); weld::ComboBox* pLbField = m_xLbField1.get(); if ( &rEd == m_xEdVal2.get() ) { pLbCond = m_xLbCond2.get(); pLbField = m_xLbField2.get(); i=1; nQE=i+nOffset; } if ( &rEd == m_xEdVal3.get() ) { pLbCond = m_xLbCond3.get(); pLbField = m_xLbField3.get(); i=2; nQE=i+nOffset; } if ( &rEd == m_xEdVal4.get() ) { pLbCond = m_xLbCond4.get(); pLbField = m_xLbField4.get(); i=3; nQE=i+nOffset; } if ( aStrEmpty == aStrVal || aStrNotEmpty == aStrVal ) { pLbCond->set_active_text(OUString('=')); pLbCond->set_sensitive(false); } else pLbCond->set_sensitive(true); if (maHasDates.size() < nQE + 1) maHasDates.resize(nQE + 1, false); if (maRefreshExceptQuery.size() < nQE + 1) maRefreshExceptQuery.resize(nQE + 1, false); ScQueryEntry& rEntry = theQueryData.GetEntry( nQE ); ScQueryEntry::Item& rItem = rEntry.GetQueryItem(); bool bDoThis = (pLbField->get_active() != 0); rEntry.bDoQuery = bDoThis; if ( !(rEntry.bDoQuery || maRefreshExceptQuery[nQE]) ) return; bool bByEmptyOrNotByEmpty = false; if ( aStrEmpty == aStrVal ) { bByEmptyOrNotByEmpty = true; rEntry.SetQueryByEmpty(); } else if ( aStrNotEmpty == aStrVal ) { bByEmptyOrNotByEmpty = true; rEntry.SetQueryByNonEmpty(); } else { rItem.maString = pDoc->GetSharedStringPool().intern(aStrVal); rItem.mfVal = 0.0; rItem.meType = ScQueryEntry::ByString; } const sal_Int32 nField = pLbField->get_active(); rEntry.nField = nField ? (theQueryData.nCol1 + static_cast(nField) - 1) : static_cast(0); ScQueryOp eOp = static_cast(pLbCond->get_active()); rEntry.eOp = eOp; if (maHasDates[nQE] && !bByEmptyOrNotByEmpty) rItem.meType = ScQueryEntry::ByDate; } IMPL_LINK( ScFilterDlg, BtnRemoveHdl, weld::Button&, rBtn, void ) { // Calculate the row to delete sal_uInt16 nOffset = GetSliderPos(); int nButtonIndex = 0; if ( &rBtn == m_xBtnRemove2.get() ) nButtonIndex = 1; if ( &rBtn == m_xBtnRemove3.get() ) nButtonIndex = 2; if ( &rBtn == m_xBtnRemove4.get() ) nButtonIndex = 3; SCSIZE nRowToDelete = nOffset + nButtonIndex; // Check that the index is sensible SCSIZE nCount = theQueryData.GetEntryCount(); if (nRowToDelete >= nCount) { SAL_WARN( "sc", "ScFilterDlg::BtnRemoveHdl: could not delete row - invalid index."); return; } // Resize maRefreshExceptQuery if (maRefreshExceptQuery.size() < nCount + 1) maRefreshExceptQuery.resize(nCount + 1, false); // Move all the subsequent rows back one position; // also find the last row, which we will delete SCSIZE nRowToClear = nCount-1; for (SCSIZE i = nRowToDelete; i < nCount-1; ++i) { if (theQueryData.GetEntry(i+1).bDoQuery) { theQueryData.GetEntry(i) = theQueryData.GetEntry(i+1); } else { nRowToClear = i; break; } } // If the next row is being edited, but not confirmed, move it back // one position if (nRowToClear < nCount-1 && maRefreshExceptQuery[nRowToClear+1]) { theQueryData.GetEntry(nRowToClear) = theQueryData.GetEntry(nRowToClear+1); maRefreshExceptQuery[nRowToClear] = true; maRefreshExceptQuery[nRowToClear+1] = false; } else { // Remove the very last one, since everything has moved back theQueryData.GetEntry(nRowToClear).bDoQuery = false; theQueryData.GetEntry(nRowToClear).nField = static_cast(0); maRefreshExceptQuery[nRowToClear] = false; } // Always enable the very first row if (!theQueryData.GetEntry(0).bDoQuery) { maRefreshExceptQuery[0] = true; } // Refresh the UI RefreshEditRow( nOffset ); // Special handling if the very first row was cleared if (!theQueryData.GetEntry(0).bDoQuery) { m_xLbConnect1->set_active(-1); m_xLbField1->set_active(0); m_xLbField1->set_sensitive(true); m_xLbCond1->set_active(0); m_xLbCond1->set_sensitive(true); ClearValueList(1); } } IMPL_LINK_NOARG(ScFilterDlg, ScrollHdl, weld::ScrolledWindow&, void) { SliderMoved(); } void ScFilterDlg::SliderMoved() { size_t nOffset = GetSliderPos(); RefreshEditRow( nOffset); } size_t ScFilterDlg::GetSliderPos() const { return static_cast(m_xScrollBar->vadjustment_get_value()); } void ScFilterDlg::RefreshEditRow( size_t nOffset ) { if (nOffset==0) maConnLbArr[0]->hide(); else maConnLbArr[0]->show(); for (size_t i = 0; i < QUERY_ENTRY_COUNT; ++i) { OUString aValStr; size_t nCondPos = 0; size_t nFieldSelPos = 0; size_t nQE = i + nOffset; maColorLbArr[i]->set_visible(false); if (maRefreshExceptQuery.size() < nQE + 1) maRefreshExceptQuery.resize(nQE + 1, false); ScQueryEntry& rEntry = theQueryData.GetEntry( nQE); if ( rEntry.bDoQuery || maRefreshExceptQuery[nQE] ) { nCondPos = static_cast(rEntry.eOp); if(rEntry.bDoQuery) nFieldSelPos = GetFieldSelPos( static_cast(rEntry.nField) ); const ScQueryEntry::Item& rItem = rEntry.GetQueryItem(); OUString aQueryStr = rItem.maString.getString(); if (rEntry.IsQueryByEmpty()) { aValStr = aStrEmpty; maCondLbArr[i]->set_sensitive(false); } else if (rEntry.IsQueryByNonEmpty()) { aValStr = aStrNotEmpty; maCondLbArr[i]->set_sensitive(false); } else if (rEntry.IsQueryByTextColor() || rEntry.IsQueryByBackgroundColor()) { nCondPos = maCondLbArr[i]->find_text( rEntry.IsQueryByTextColor() ? aStrTextColor : aStrBackgroundColor); maValueEdArr[i]->set_visible(false); maColorLbArr[i]->set_visible(true); maColorLbArr[i]->set_sensitive(true); } else { SetValString(aQueryStr, rItem, aValStr); maCondLbArr[i]->set_sensitive(true); } maFieldLbArr[i]->set_sensitive(true); maValueEdArr[i]->set_sensitive(true); maRemoveBtnArr[i]->set_sensitive(true); if (nOffset==0) { if (i<3) { if(rEntry.bDoQuery) maConnLbArr[i+1]->set_sensitive(true); else maConnLbArr[i+1]->set_sensitive(false); size_t nQENext = nQE + 1; if (maRefreshExceptQuery.size() < nQENext + 1) maRefreshExceptQuery.resize(nQENext + 1, false); if (theQueryData.GetEntry(nQENext).bDoQuery || maRefreshExceptQuery[nQENext]) maConnLbArr[i+1]->set_active( static_cast(theQueryData.GetEntry(nQENext).eConnect) ); else maConnLbArr[i+1]->set_active(-1); } } else { if(theQueryData.GetEntry( nQE-1).bDoQuery) maConnLbArr[i]->set_sensitive(true); else maConnLbArr[i]->set_sensitive(false); if (maRefreshExceptQuery.size() < nQE + 1) maRefreshExceptQuery.resize(nQE + 1, false); if(rEntry.bDoQuery || maRefreshExceptQuery[nQE]) maConnLbArr[i]->set_active( static_cast(rEntry.eConnect) ); else maConnLbArr[i]->set_active(-1); } } else { if (nOffset==0) { if(i<3) { maConnLbArr[i+1]->set_active(-1); maConnLbArr[i+1]->set_sensitive(false); } } else { if(theQueryData.GetEntry( nQE-1).bDoQuery) maConnLbArr[i]->set_sensitive(true); else maConnLbArr[i]->set_sensitive(false); maConnLbArr[i]->set_active(-1); } maFieldLbArr[i]->set_sensitive(false); maCondLbArr[i]->set_sensitive(false); maValueEdArr[i]->set_sensitive(false); maRemoveBtnArr[i]->set_sensitive(false); } maFieldLbArr[i]->set_active( nFieldSelPos ); maCondLbArr [i]->set_active( nCondPos ); maValueEdArr[i]->set_entry_text( aValStr ); UpdateValueList(i+1); UpdateColorList(i+1); } } void ScFilterDlg::SetValString( const OUString& rQueryStr, const ScQueryEntry::Item& rItem, OUString& rValStr ) { if (rQueryStr.isEmpty()) { pDoc = pViewData ? &pViewData->GetDocument() : nullptr; if (rItem.meType == ScQueryEntry::ByValue) { if (pDoc) { pDoc->GetFormatTable()->GetInputLineString(rItem.mfVal, 0, rValStr); } } else if (rItem.meType == ScQueryEntry::ByDate) { if (pDoc) { SvNumberFormatter* pFormatter = pDoc->GetFormatTable(); pFormatter->GetInputLineString(rItem.mfVal, pFormatter->GetStandardFormat( SvNumFormatType::DATE), rValStr); } } else { SAL_WARN( "sc", "ScFilterDlg::SetValString: empty query string, really?"); rValStr = rQueryStr; } } else { // XXX NOTE: if not ByString we just assume this has been // set to a proper string corresponding to the numeric // value earlier! rValStr = rQueryStr; } } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */