summaryrefslogtreecommitdiffstats
path: root/sc/source/ui/dbgui/tpsort.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sc/source/ui/dbgui/tpsort.cxx')
-rw-r--r--sc/source/ui/dbgui/tpsort.cxx855
1 files changed, 855 insertions, 0 deletions
diff --git a/sc/source/ui/dbgui/tpsort.cxx b/sc/source/ui/dbgui/tpsort.cxx
new file mode 100644
index 000000000..35a24e633
--- /dev/null
+++ b/sc/source/ui/dbgui/tpsort.cxx
@@ -0,0 +1,855 @@
+/* -*- 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 <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <i18nlangtag/languagetag.hxx>
+#include <svtools/collatorres.hxx>
+#include <unotools/collatorwrapper.hxx>
+#include <comphelper/processfactory.hxx>
+#include <osl/diagnose.h>
+
+#include <scitems.hxx>
+#include <uiitems.hxx>
+#include <viewdata.hxx>
+#include <document.hxx>
+#include <global.hxx>
+#include <dbdata.hxx>
+#include <userlist.hxx>
+#include <rangeutl.hxx>
+#include <scresid.hxx>
+#include <sc.hrc>
+#include <strings.hrc>
+#include <globstr.hrc>
+
+#include <sortkeydlg.hxx>
+
+#include <sortdlg.hxx>
+
+#include <tpsort.hxx>
+
+using namespace com::sun::star;
+
+/*
+ * Since the settings on the second Tab Page (Options) effects
+ * the first Tab Page, there must be a way for it to communicate with the
+ * other Page.
+ *
+ * At the moment this problem is solved through using two data members of the
+ * Tab Pages. If a page is enabled / disabled, it compares this data member
+ * with its own state (-> Activate() / Deactivate()).
+ *
+ * In the meantime the class SfxTabPage offers the following method:
+ *
+ * virtual sal_Bool HasExchangeSupport() const; -> return sal_True;
+ * virtual void ActivatePage(const SfxItemSet &);
+ * virtual int DeactivatePage(SfxItemSet * = 0);
+ *
+ * This still needs to be changed!
+ */
+
+// Sort Criteria Tab page
+
+ScTabPageSortFields::ScTabPageSortFields(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rArgSet)
+ : SfxTabPage(pPage, pController, "modules/scalc/ui/sortcriteriapage.ui", "SortCriteriaPage", &rArgSet)
+ ,
+
+ m_aIdle("ScTabPageSortFields Scroll To End Idle"),
+ aStrUndefined ( ScResId( SCSTR_UNDEFINED ) ),
+ aStrColumn ( ScResId( SCSTR_COLUMN ) ),
+ aStrRow ( ScResId( SCSTR_ROW ) ),
+ aStrRowLabel ( ScResId( SCSTR_ROW_LABEL ) ),
+ aStrColLabel ( ScResId( SCSTR_COL_LABEL ) ),
+
+ nWhichSort ( rArgSet.GetPool()->GetWhich( SID_SORT ) ),
+ pViewData ( nullptr ),
+ aSortData ( rArgSet.Get( nWhichSort ).GetSortData() ),
+ nFieldCount ( 0 ),
+ // show actual size of the sorting keys without limiting them to the default size
+ nSortKeyCount(std::max(aSortData.GetSortKeyCount(), static_cast<sal_uInt16>(DEFSORT)))
+
+ , m_xTop(m_xBuilder->weld_container("TopWindow"))
+ , m_xBtnHeader(m_xBuilder->weld_check_button("cbHeader"))
+ , m_xBtnTopDown(m_xBuilder->weld_radio_button("rbTopDown"))
+ , m_xBtnLeftRight(m_xBuilder->weld_radio_button("rbLeftRight"))
+ , m_xScrolledWindow(m_xBuilder->weld_scrolled_window("SortCriteriaPage"))
+ , m_xBox(m_xBuilder->weld_container("SortKeyWindow"))
+ , m_aSortWin(m_xBox.get())
+{
+ // tdf#147722 set some nominal small default height so the height adapts
+ // to all the other contents and the natural height of this widget isn't
+ // an input into the overall size
+ m_xScrolledWindow->set_size_request(-1, 42);
+
+ Init();
+
+ m_aIdle.SetInvokeHandler(LINK(this, ScTabPageSortFields, ScrollToEndHdl));
+
+ SetExchangeSupport();
+}
+
+ScTabPageSortFields::~ScTabPageSortFields()
+{
+ m_aSortWin.m_aSortKeyItems.clear();
+ m_xBox.reset();
+ m_xScrolledWindow.reset();
+}
+
+void ScTabPageSortFields::Init()
+{
+ // Check whether the field that is passed on is a database field:
+ ScDocument* pDoc = pViewData ? &pViewData->GetDocument() : nullptr;
+ if ( pDoc )
+ {
+ ScDBCollection* pDBColl = pDoc->GetDBCollection();
+ const SCTAB nCurTab = pViewData->GetTabNo();
+ if ( pDBColl )
+ {
+ ScDBData* pDBData
+ = pDBColl->GetDBAtArea( nCurTab,
+ aSortData.nCol1, aSortData.nRow1,
+ aSortData.nCol2, aSortData.nRow2 );
+ if ( pDBData )
+ {
+ m_xBtnHeader->set_active(pDBData->HasHeader());
+ }
+ }
+ }
+ m_xBtnHeader->set_label(aStrColLabel);
+
+ Link<weld::Toggleable&,void> aLink = LINK(this, ScTabPageSortFields, SortDirHdl );
+ m_xBtnTopDown->connect_toggled( aLink );
+ m_xBtnLeftRight->connect_toggled( aLink );
+ m_xBtnHeader->connect_toggled( aLink );
+
+ const ScSortItem& rSortItem = GetItemSet().Get( nWhichSort );
+
+ pViewData = rSortItem.GetViewData();
+ OSL_ENSURE( pViewData, "ViewData not found!" );
+
+ nFieldArr.push_back( 0 );
+
+ // Create three sort key dialogs by default
+ for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
+ {
+ AddSortKey(i+1);
+ m_aSortWin.m_aSortKeyItems[i]->m_xLbSort->connect_changed(LINK(this, ScTabPageSortFields, SelectHdl));
+ }
+}
+
+std::unique_ptr<SfxTabPage> ScTabPageSortFields::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* pArgSet)
+{
+ return std::make_unique<ScTabPageSortFields>(pPage, pController, *pArgSet);
+}
+
+void ScTabPageSortFields::Reset( const SfxItemSet* /* rArgSet */ )
+{
+ m_xBtnHeader->set_active( aSortData.bHasHeader );
+ m_xBtnTopDown->set_active( aSortData.bByRow );
+ m_xBtnLeftRight->set_active( !aSortData.bByRow );
+
+ if (m_aSortWin.m_aSortKeyItems[0]->m_xLbSort->get_count() == 0)
+ FillFieldLists(0);
+
+ // ListBox selection:
+ if (!aSortData.maKeyState.empty() && aSortData.maKeyState[0].bDoSort)
+ {
+ // Make sure that the all sort keys are reset
+ for ( sal_uInt16 i=nSortKeyCount; i<aSortData.GetSortKeyCount(); i++ )
+ {
+ AddSortKey(i+1);
+ m_aSortWin.m_aSortKeyItems[i]->m_xLbSort->connect_changed( LINK( this,
+ ScTabPageSortFields, SelectHdl ) );
+ }
+ nSortKeyCount = aSortData.GetSortKeyCount();
+ FillFieldLists(0);
+
+ for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
+ {
+ if (aSortData.maKeyState[i].bDoSort )
+ {
+ m_aSortWin.m_aSortKeyItems[i]->m_xLbSort->set_active( GetFieldSelPos(
+ aSortData.maKeyState[i].nField ) );
+ (aSortData.maKeyState[i].bAscending)
+ ? m_aSortWin.m_aSortKeyItems[i]->m_xBtnUp->set_active(true)
+ : m_aSortWin.m_aSortKeyItems[i]->m_xBtnDown->set_active(true);
+ }
+ else
+ {
+ m_aSortWin.m_aSortKeyItems[i]->m_xLbSort->set_active(0); // Select none
+ m_aSortWin.m_aSortKeyItems[i]->m_xBtnUp->set_active(true);
+ }
+ }
+
+ // Enable or disable field depending on preceding Listbox selection
+ m_aSortWin.m_aSortKeyItems[0]->EnableField();
+ for ( sal_uInt16 i=1; i<nSortKeyCount; i++ )
+ if ( m_aSortWin.m_aSortKeyItems[i - 1]->m_xLbSort->get_active() == 0 )
+ m_aSortWin.m_aSortKeyItems[i]->DisableField();
+ else
+ m_aSortWin.m_aSortKeyItems[i]->EnableField();
+ }
+ else
+ {
+ SCCOL nCol = pViewData->GetCurX();
+
+ if( nCol < aSortData.nCol1 )
+ nCol = aSortData.nCol1;
+ else if( nCol > aSortData.nCol2 )
+ nCol = aSortData.nCol2;
+
+ sal_uInt16 nSort1Pos = nCol - aSortData.nCol1+1;
+
+ m_aSortWin.m_aSortKeyItems[0]->m_xLbSort->set_active(nSort1Pos);
+ for ( sal_uInt16 i=1; i<nSortKeyCount; i++ )
+ m_aSortWin.m_aSortKeyItems[i]->m_xLbSort->set_active(0);
+
+ for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
+ m_aSortWin.m_aSortKeyItems[i]->m_xBtnUp->set_active(true);
+
+ m_aSortWin.m_aSortKeyItems[0]->EnableField();
+ m_aSortWin.m_aSortKeyItems[1]->EnableField();
+ for ( sal_uInt16 i=2; i<nSortKeyCount; i++ )
+ m_aSortWin.m_aSortKeyItems[i]->DisableField();
+ }
+
+ // Make sure that there is always a last undefined sort key
+ if (m_aSortWin.m_aSortKeyItems[nSortKeyCount - 1]->m_xLbSort->get_active() > 0)
+ SetLastSortKey( nSortKeyCount );
+}
+
+bool ScTabPageSortFields::FillItemSet( SfxItemSet* rArgSet )
+{
+ ScSortParam aNewSortData = aSortData;
+
+ const SfxItemSet* pExample = GetDialogExampleSet();
+ if (pExample)
+ {
+ if (const ScSortItem* pItem = pExample->GetItemIfSet(nWhichSort))
+ {
+ ScSortParam aTempData = pItem->GetSortData();
+ aTempData.maKeyState = aNewSortData.maKeyState;
+ aNewSortData = aTempData;
+ }
+ }
+ aNewSortData.bByRow = m_xBtnTopDown->get_active();
+ aNewSortData.bHasHeader = m_xBtnHeader->get_active();
+
+ std::vector<sal_Int32> nSortPos;
+
+ for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
+ {
+ nSortPos.push_back(m_aSortWin.m_aSortKeyItems[i]->m_xLbSort->get_active());
+ if (nSortPos[i] == -1) nSortPos[i] = 0;
+ }
+
+ if( nSortKeyCount >= aNewSortData.GetSortKeyCount() )
+ aNewSortData.maKeyState.resize(nSortKeyCount);
+
+ if ( nSortPos[0] > 0 )
+ {
+ for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
+ {
+ aNewSortData.maKeyState[i].bDoSort = (nSortPos[i] > 0);
+ aNewSortData.maKeyState[i].nField = nFieldArr[nSortPos[i]];
+ aNewSortData.maKeyState[i].bAscending = m_aSortWin.m_aSortKeyItems[i]->m_xBtnUp->get_active();
+ }
+ }
+ else
+ {
+ for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
+ aNewSortData.maKeyState[i].bDoSort = false;
+ }
+
+ rArgSet->Put( ScSortItem( SCITEM_SORTDATA, nullptr, &aNewSortData ) );
+
+ return true;
+}
+
+// for data exchange without dialogue detour:
+void ScTabPageSortFields::ActivatePage( const SfxItemSet& rSet )
+{
+ // Refresh local copy with shared data
+ aSortData = rSet.Get( SCITEM_SORTDATA ).GetSortData();
+
+ m_xBtnHeader->set_active( aSortData.bHasHeader );
+ m_xBtnTopDown->set_active( aSortData.bByRow );
+ m_xBtnLeftRight->set_active( !aSortData.bByRow );
+}
+
+DeactivateRC ScTabPageSortFields::DeactivatePage( SfxItemSet* pSetP )
+{
+ if ( pSetP )
+ FillItemSet( pSetP );
+
+ return DeactivateRC::LeavePage;
+}
+
+void ScTabPageSortFields::FillFieldLists( sal_uInt16 nStartField )
+{
+ if ( !pViewData )
+ return;
+
+ ScDocument& rDoc = pViewData->GetDocument();
+
+ for (sal_uInt16 j = nStartField; j < nSortKeyCount; ++j)
+ {
+ m_aSortWin.m_aSortKeyItems[j]->m_xLabel->set_label(aSortData.bByRow ? aStrColumn : aStrRow);
+ m_aSortWin.m_aSortKeyItems[j]->m_xLbSort->clear();
+ m_aSortWin.m_aSortKeyItems[j]->m_xLbSort->freeze();
+ m_aSortWin.m_aSortKeyItems[j]->m_xLbSort->append_text(aStrUndefined);
+ }
+
+ SCCOL nFirstSortCol = aSortData.nCol1;
+ SCROW nFirstSortRow = aSortData.nRow1;
+ SCTAB nTab = pViewData->GetTabNo();
+ sal_uInt16 i = 1;
+ nFieldArr.clear();
+ nFieldArr.push_back(0);
+
+ if ( aSortData.bByRow )
+ {
+ OUString aFieldName;
+ SCCOL nMaxCol = rDoc.ClampToAllocatedColumns(nTab, aSortData.nCol2);
+ SCCOL col;
+
+ for ( col=nFirstSortCol; col<=nMaxCol && i<SC_MAXFIELDS(rDoc.GetSheetLimits()); col++ )
+ {
+ aFieldName = rDoc.GetString(col, nFirstSortRow, nTab);
+ if ( !aSortData.bHasHeader || aFieldName.isEmpty() )
+ aFieldName = ScColToAlpha( col );
+ nFieldArr.push_back( col );
+
+ for ( sal_uInt16 j=nStartField; j<nSortKeyCount; j++ )
+ m_aSortWin.m_aSortKeyItems[j]->m_xLbSort->insert_text(i, aFieldName);
+
+ i++;
+ }
+ }
+ else
+ {
+ OUString aFieldName;
+ SCROW nMaxRow = aSortData.nRow2;
+ SCROW row;
+
+ for ( row=nFirstSortRow; row<=nMaxRow && i<SC_MAXFIELDS(rDoc.GetSheetLimits()); row++ )
+ {
+ aFieldName = rDoc.GetString(nFirstSortCol, row, nTab);
+ if ( !aSortData.bHasHeader || aFieldName.isEmpty() )
+ aFieldName = OUString::number( row+1);
+ nFieldArr.push_back( row );
+
+ for ( sal_uInt16 j=nStartField; j<nSortKeyCount; j++ )
+ m_aSortWin.m_aSortKeyItems[j]->m_xLbSort->insert_text(i, aFieldName);
+
+ i++;
+ }
+ }
+
+ for (sal_uInt16 j=nStartField; j < nSortKeyCount; ++j)
+ {
+ m_aSortWin.m_aSortKeyItems[j]->m_xLbSort->thaw();
+ }
+
+ nFieldCount = i;
+}
+
+sal_uInt16 ScTabPageSortFields::GetFieldSelPos( SCCOLROW nField )
+{
+ sal_uInt16 nFieldPos = 0;
+ bool bFound = false;
+
+ for ( sal_uInt16 n=1; n<nFieldCount && !bFound; n++ )
+ {
+ if ( nFieldArr[n] == nField )
+ {
+ nFieldPos = n;
+ bFound = true;
+ }
+ }
+
+ return nFieldPos;
+}
+
+void ScTabPageSortFields::SetLastSortKey( sal_uInt16 nItem )
+{
+ // Extend local SortParam copy
+ const ScSortKeyState atempKeyState = { 0, false, true };
+ aSortData.maKeyState.push_back( atempKeyState );
+
+ // Add Sort Key Item
+ ++nSortKeyCount;
+ AddSortKey( nSortKeyCount );
+ m_aSortWin.m_aSortKeyItems[nItem]->m_xLbSort->connect_changed(
+ LINK( this, ScTabPageSortFields, SelectHdl ) );
+
+ FillFieldLists( nItem );
+
+ // Set Status
+ m_aSortWin.m_aSortKeyItems[nItem]->m_xBtnUp->set_active(true);
+ m_aSortWin.m_aSortKeyItems[nItem]->m_xLbSort->set_active(0);
+}
+
+// Handler:
+
+IMPL_LINK_NOARG(ScTabPageSortFields, SortDirHdl, weld::Toggleable&, void)
+{
+ if ( (m_xBtnTopDown->get_active() != aSortData.bByRow) || (m_xBtnHeader->get_active() != aSortData.bHasHeader))
+ {
+ if (m_xBtnTopDown->get_active())
+ m_xBtnHeader->set_label(aStrColLabel);
+ else
+ m_xBtnHeader->set_label(aStrRowLabel);
+
+ aSortData.bByRow = m_xBtnTopDown->get_active();
+ aSortData.bHasHeader = m_xBtnHeader->get_active();
+
+ // remember selection
+ std::vector<sal_uInt16> nCurSel;
+ for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
+ nCurSel.push_back( m_aSortWin.m_aSortKeyItems[i]->m_xLbSort->get_active() );
+
+ FillFieldLists(0);
+
+ for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
+ m_aSortWin.m_aSortKeyItems[i]->m_xLbSort->set_active(nCurSel[i]);
+ }
+}
+
+IMPL_LINK( ScTabPageSortFields, SelectHdl, weld::ComboBox&, rLb, void )
+{
+ OUString aSelEntry = rLb.get_active_text();
+ ScSortKeyItems::iterator pIter;
+
+ // If last listbox is enabled add one item
+ if (m_aSortWin.m_aSortKeyItems.back()->m_xLbSort.get() == &rLb)
+ {
+ if ( aSelEntry != aStrUndefined )
+ {
+ SetLastSortKey( nSortKeyCount );
+ return;
+ }
+ }
+
+ // Find selected listbox
+ pIter = std::find_if(m_aSortWin.m_aSortKeyItems.begin(), m_aSortWin.m_aSortKeyItems.end(),
+ [&rLb](const ScSortKeyItems::value_type& rItem) { return rItem->m_xLbSort.get() == &rLb; });
+
+ if (pIter == m_aSortWin.m_aSortKeyItems.end())
+ return;
+
+ // If not selecting the last Listbox, modify the succeeding ones
+ ++pIter;
+ if ( std::distance(m_aSortWin.m_aSortKeyItems.begin(), pIter) >= nSortKeyCount )
+ return;
+
+ if ( aSelEntry == aStrUndefined )
+ {
+ for ( ; pIter != m_aSortWin.m_aSortKeyItems.end(); ++pIter )
+ {
+ (*pIter)->m_xLbSort->set_active(0);
+
+ (*pIter)->DisableField();
+ }
+ }
+ else
+ {
+ (*pIter)->EnableField();
+ }
+}
+
+IMPL_LINK_NOARG(ScTabPageSortFields, ScrollToEndHdl, Timer*, void)
+{
+ m_xScrolledWindow->vadjustment_set_value(m_xScrolledWindow->vadjustment_get_upper());
+}
+
+void ScTabPageSortFields::AddSortKey( sal_uInt16 nItem )
+{
+ m_aSortWin.AddSortKey(nItem);
+ m_aIdle.Start();
+}
+
+// Sort option Tab Page:
+
+ScTabPageSortOptions::ScTabPageSortOptions(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rArgSet)
+ : SfxTabPage(pPage, pController, "modules/scalc/ui/sortoptionspage.ui", "SortOptionsPage", &rArgSet)
+ , aStrUndefined(ScResId(SCSTR_UNDEFINED))
+ , nWhichSort(rArgSet.GetPool()->GetWhich(SID_SORT))
+ , aSortData(rArgSet.Get(nWhichSort).GetSortData())
+ , pViewData(nullptr)
+ , pDoc(nullptr)
+ , m_xBtnCase(m_xBuilder->weld_check_button("case"))
+ , m_xBtnFormats(m_xBuilder->weld_check_button("formats"))
+ , m_xBtnNaturalSort(m_xBuilder->weld_check_button("naturalsort"))
+ , m_xBtnCopyResult(m_xBuilder->weld_check_button("copyresult"))
+ , m_xLbOutPos(m_xBuilder->weld_combo_box("outarealb"))
+ , m_xEdOutPos(m_xBuilder->weld_entry("outareaed"))
+ , m_xBtnSortUser(m_xBuilder->weld_check_button("sortuser"))
+ , m_xLbSortUser(m_xBuilder->weld_combo_box("sortuserlb"))
+ , m_xLbLanguage(new SvxLanguageBox(m_xBuilder->weld_combo_box("language")))
+ , m_xFtAlgorithm(m_xBuilder->weld_label("algorithmft"))
+ , m_xLbAlgorithm(m_xBuilder->weld_combo_box("algorithmlb"))
+ , m_xBtnIncComments(m_xBuilder->weld_check_button("includenotes"))
+ , m_xBtnIncImages(m_xBuilder->weld_check_button("includeimages"))
+{
+ m_xLbSortUser->set_size_request(m_xLbSortUser->get_approximate_digit_width() * 50, -1);
+ m_xLbSortUser->set_accessible_description(ScResId(STR_A11Y_DESC_SORTUSER));
+ Init();
+ SetExchangeSupport();
+}
+
+void ScTabPageSortOptions::Init()
+{
+ // CollatorResource has user-visible names for sort algorithms
+ m_xColRes.reset(new CollatorResource);
+
+ //! use CollatorWrapper from document?
+ m_xColWrap.reset(new CollatorWrapper(comphelper::getProcessComponentContext()));
+
+ const ScSortItem& rSortItem = GetItemSet().Get( nWhichSort );
+
+ m_xLbOutPos->connect_changed( LINK( this, ScTabPageSortOptions, SelOutPosHdl ) );
+ m_xBtnCopyResult->connect_toggled( LINK( this, ScTabPageSortOptions, EnableHdl ) );
+ m_xBtnSortUser->connect_toggled( LINK( this, ScTabPageSortOptions, EnableHdl ) );
+ m_xLbLanguage->connect_changed( LINK( this, ScTabPageSortOptions, FillAlgorHdl ) );
+
+ pViewData = rSortItem.GetViewData();
+ pDoc = pViewData ? &pViewData->GetDocument() : nullptr;
+
+ OSL_ENSURE( pViewData, "ViewData not found! :-/" );
+
+ if ( pViewData && pDoc )
+ {
+ const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
+
+ m_xLbOutPos->clear();
+ m_xLbOutPos->append_text(aStrUndefined);
+ m_xLbOutPos->set_sensitive(false);
+
+ ScAreaNameIterator aIter( *pDoc );
+ OUString aName;
+ ScRange aRange;
+ while ( aIter.Next( aName, aRange ) )
+ {
+ OUString aRefStr(aRange.aStart.Format(ScRefFlags::ADDR_ABS_3D, pDoc, eConv));
+ m_xLbOutPos->append(aRefStr, aName);
+ }
+
+ m_xLbOutPos->set_active(0);
+ m_xEdOutPos->set_text(OUString());
+ }
+
+ FillUserSortListBox();
+
+ // get available languages
+
+ m_xLbLanguage->SetLanguageList( SvxLanguageListFlags::ALL | SvxLanguageListFlags::ONLY_KNOWN, false );
+ m_xLbLanguage->InsertLanguage( LANGUAGE_SYSTEM );
+}
+
+std::unique_ptr<SfxTabPage> ScTabPageSortOptions::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rArgSet)
+{
+ return std::make_unique<ScTabPageSortOptions>(pPage, pController, *rArgSet);
+}
+
+void ScTabPageSortOptions::Reset( const SfxItemSet* /* rArgSet */ )
+{
+ if ( aSortData.bUserDef )
+ {
+ m_xBtnSortUser->set_active(true);
+ m_xLbSortUser->set_sensitive(true);
+ m_xLbSortUser->set_active(aSortData.nUserIndex);
+ }
+ else
+ {
+ m_xBtnSortUser->set_active(false);
+ m_xLbSortUser->set_sensitive(false);
+ m_xLbSortUser->set_active(0);
+ }
+
+ m_xBtnCase->set_active( aSortData.bCaseSens );
+ m_xBtnFormats->set_active( aSortData.aDataAreaExtras.mbCellFormats );
+ m_xBtnNaturalSort->set_active( aSortData.bNaturalSort );
+ m_xBtnIncComments->set_active( aSortData.aDataAreaExtras.mbCellNotes );
+ m_xBtnIncImages->set_active( aSortData.aDataAreaExtras.mbCellDrawObjects );
+
+ LanguageType eLang = LanguageTag::convertToLanguageType( aSortData.aCollatorLocale, false);
+ if ( eLang == LANGUAGE_DONTKNOW )
+ eLang = LANGUAGE_SYSTEM;
+ m_xLbLanguage->set_active_id(eLang);
+ FillAlgor(); // get algorithms, select default
+ if ( !aSortData.aCollatorAlgorithm.isEmpty() )
+ m_xLbAlgorithm->set_active_text(m_xColRes->GetTranslation(aSortData.aCollatorAlgorithm));
+
+ if ( pDoc && !aSortData.bInplace )
+ {
+ ScRefFlags nFormat = (aSortData.nDestTab != pViewData->GetTabNo())
+ ? ScRefFlags::RANGE_ABS_3D
+ : ScRefFlags::RANGE_ABS;
+
+ theOutPos.Set( aSortData.nDestCol,
+ aSortData.nDestRow,
+ aSortData.nDestTab );
+
+ OUString aStr(theOutPos.Format(nFormat, pDoc, pDoc->GetAddressConvention()));
+ m_xBtnCopyResult->set_active(true);
+ m_xLbOutPos->set_sensitive(true);
+ m_xEdOutPos->set_sensitive(true);
+ m_xEdOutPos->set_text( aStr );
+ EdOutPosModHdl();
+ m_xEdOutPos->grab_focus();
+ m_xEdOutPos->select_region(0, -1);
+ }
+ else
+ {
+ m_xBtnCopyResult->set_active( false );
+ m_xLbOutPos->set_sensitive(false);
+ m_xEdOutPos->set_sensitive(false);
+ m_xEdOutPos->set_text( OUString() );
+ }
+}
+
+bool ScTabPageSortOptions::FillItemSet( SfxItemSet* rArgSet )
+{
+ // Create local copy of ScParam
+ ScSortParam aNewSortData = aSortData;
+
+ const SfxItemSet* pExample = GetDialogExampleSet();
+ if (pExample)
+ {
+ if (const ScSortItem* pSortItem = pExample->GetItemIfSet(nWhichSort))
+ aNewSortData = pSortItem->GetSortData();
+ }
+ aNewSortData.bCaseSens = m_xBtnCase->get_active();
+ aNewSortData.bNaturalSort = m_xBtnNaturalSort->get_active();
+ aNewSortData.aDataAreaExtras.mbCellNotes = m_xBtnIncComments->get_active();
+ aNewSortData.aDataAreaExtras.mbCellDrawObjects = m_xBtnIncImages->get_active();
+ aNewSortData.aDataAreaExtras.mbCellFormats = m_xBtnFormats->get_active();
+ aNewSortData.bInplace = !m_xBtnCopyResult->get_active();
+ aNewSortData.nDestCol = theOutPos.Col();
+ aNewSortData.nDestRow = theOutPos.Row();
+ aNewSortData.nDestTab = theOutPos.Tab();
+ aNewSortData.bUserDef = m_xBtnSortUser->get_active();
+ aNewSortData.nUserIndex = (m_xBtnSortUser->get_active())
+ ? m_xLbSortUser->get_active()
+ : 0;
+
+ // get locale
+ LanguageType eLang = m_xLbLanguage->get_active_id();
+ aNewSortData.aCollatorLocale = LanguageTag::convertToLocale( eLang, false);
+
+ // get algorithm
+ OUString sAlg;
+ if ( eLang != LANGUAGE_SYSTEM )
+ {
+ uno::Sequence<OUString> aAlgos = m_xColWrap->listCollatorAlgorithms(
+ aNewSortData.aCollatorLocale );
+ const int nSel = m_xLbAlgorithm->get_active();
+ if ( nSel < aAlgos.getLength() )
+ sAlg = aAlgos[nSel];
+ }
+ aNewSortData.aCollatorAlgorithm = sAlg;
+
+ rArgSet->Put( ScSortItem( SCITEM_SORTDATA, &aNewSortData ) );
+
+ return true;
+}
+
+// for data exchange without dialogue detour:
+void ScTabPageSortOptions::ActivatePage( const SfxItemSet& rSet )
+{
+ // Refresh local copy with shared data
+ aSortData = rSet.Get( SCITEM_SORTDATA ).GetSortData();
+ ScSortDlg* pDlg = static_cast<ScSortDlg*>(GetDialogController());
+ if (!pDlg)
+ return;
+}
+
+DeactivateRC ScTabPageSortOptions::DeactivatePage( SfxItemSet* pSetP )
+{
+ bool bPosInputOk = true;
+
+ if ( m_xBtnCopyResult->get_active() )
+ {
+ OUString thePosStr = m_xEdOutPos->get_text();
+ ScAddress thePos;
+ sal_Int32 nColonPos = thePosStr.indexOf( ':' );
+
+ if ( -1 != nColonPos )
+ thePosStr = thePosStr.copy( 0, nColonPos );
+
+ if ( pViewData )
+ {
+ // visible table is default for input without table
+ // must be changed to GetRefTabNo when sorting has RefInput!
+ thePos.SetTab( pViewData->GetTabNo() );
+ }
+
+ ScRefFlags nResult = thePos.Parse( thePosStr, *pDoc, pDoc->GetAddressConvention() );
+
+ bPosInputOk = (nResult & ScRefFlags::VALID) == ScRefFlags::VALID;
+
+ if ( !bPosInputOk )
+ {
+ std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(GetFrameWeld(),
+ VclMessageType::Warning, VclButtonsType::Ok,
+ ScResId(STR_INVALID_TABREF)));
+ xBox->run();
+ m_xEdOutPos->grab_focus();
+ m_xEdOutPos->select_region(0, -1);
+ theOutPos.Set(0,0,0);
+ }
+ else
+ {
+ m_xEdOutPos->set_text(thePosStr);
+ theOutPos = thePos;
+ }
+ }
+
+ if ( pSetP && bPosInputOk )
+ FillItemSet( pSetP );
+
+ return bPosInputOk ? DeactivateRC::LeavePage : DeactivateRC::KeepPage;
+}
+
+void ScTabPageSortOptions::FillUserSortListBox()
+{
+ ScUserList* pUserLists = ScGlobal::GetUserList();
+
+ m_xLbSortUser->clear();
+ if ( pUserLists )
+ {
+ size_t nCount = pUserLists->size();
+ for (size_t i=0; i<nCount; ++i)
+ m_xLbSortUser->append_text((*pUserLists)[i].GetString());
+ }
+}
+
+// Handler:
+
+IMPL_LINK( ScTabPageSortOptions, EnableHdl, weld::Toggleable&, rButton, void )
+{
+ if (&rButton == m_xBtnCopyResult.get())
+ {
+ if (rButton.get_active())
+ {
+ m_xLbOutPos->set_sensitive(true);
+ m_xEdOutPos->set_sensitive(true);
+ m_xEdOutPos->grab_focus();
+ }
+ else
+ {
+ m_xLbOutPos->set_sensitive(false);
+ m_xEdOutPos->set_sensitive(false);
+ }
+ }
+ else if (&rButton == m_xBtnSortUser.get())
+ {
+ if (rButton.get_active())
+ {
+ m_xLbSortUser->set_sensitive(true);
+ m_xLbSortUser->grab_focus();
+ }
+ else
+ m_xLbSortUser->set_sensitive(false);
+ }
+}
+
+IMPL_LINK(ScTabPageSortOptions, SelOutPosHdl, weld::ComboBox&, rLb, void)
+{
+ if (&rLb == m_xLbOutPos.get())
+ {
+ OUString aString;
+ const int nSelPos = m_xLbOutPos->get_active();
+
+ if (nSelPos > 0)
+ aString = m_xLbOutPos->get_id(nSelPos);
+
+ m_xEdOutPos->set_text(aString);
+ }
+}
+
+void ScTabPageSortOptions::EdOutPosModHdl()
+{
+ OUString theCurPosStr = m_xEdOutPos->get_text();
+ ScRefFlags nResult = ScAddress().Parse( theCurPosStr, *pDoc, pDoc->GetAddressConvention() );
+
+ if ( (nResult & ScRefFlags::VALID) != ScRefFlags::VALID )
+ return;
+
+ bool bFound = false;
+ sal_Int32 i = 0;
+ const int nCount = m_xLbOutPos->get_count();
+
+ for ( i=2; i<nCount && !bFound; i++ )
+ {
+ OUString aStr = m_xLbOutPos->get_id(i);
+ bFound = (theCurPosStr == aStr);
+ }
+
+ if ( bFound )
+ m_xLbOutPos->set_active(--i);
+ else
+ m_xLbOutPos->set_active(0);
+}
+
+void ScTabPageSortOptions::FillAlgor()
+{
+ tools::Long nCount = 0;
+
+ m_xLbAlgorithm->freeze();
+ m_xLbAlgorithm->clear();
+
+ LanguageType eLang = m_xLbLanguage->get_active_id();
+ if ( eLang == LANGUAGE_SYSTEM )
+ {
+ // for LANGUAGE_SYSTEM no algorithm can be selected because
+ // it wouldn't necessarily exist for other languages
+ // -> leave list box empty if LANGUAGE_SYSTEM is selected
+ m_xFtAlgorithm->set_sensitive( false ); // nothing to select
+ m_xLbAlgorithm->set_sensitive( false ); // nothing to select
+ }
+ else
+ {
+ lang::Locale aLocale( LanguageTag::convertToLocale( eLang ));
+ const uno::Sequence<OUString> aAlgos = m_xColWrap->listCollatorAlgorithms( aLocale );
+
+ nCount = aAlgos.getLength();
+ for (const OUString& sAlg : aAlgos)
+ {
+ OUString sUser = m_xColRes->GetTranslation( sAlg );
+ m_xLbAlgorithm->append_text(sUser);
+ }
+ }
+
+ m_xLbAlgorithm->thaw();
+
+ m_xLbAlgorithm->set_active(nCount ? 0 : -1); // first entry is default
+ m_xFtAlgorithm->set_sensitive(nCount > 1); // enable only if there is a choice
+ m_xLbAlgorithm->set_sensitive(nCount > 1); // enable only if there is a choice
+}
+
+IMPL_LINK_NOARG(ScTabPageSortOptions, FillAlgorHdl, weld::ComboBox&, void)
+{
+ FillAlgor();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */