800 lines
28 KiB
C++
800 lines
28 KiB
C++
/* -*- 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 <reffact.hxx>
|
|
#include <document.hxx>
|
|
#include <globstr.hrc>
|
|
#include <scresid.hxx>
|
|
#include <docsh.hxx>
|
|
#include <crnrdlg.hxx>
|
|
#include <vcl/svapp.hxx>
|
|
#include <vcl/weld.hxx>
|
|
#include <o3tl/string_view.hxx>
|
|
#include <memory>
|
|
|
|
namespace
|
|
{
|
|
void ERRORBOX(weld::Window* pParent, const OUString& rString)
|
|
{
|
|
std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(pParent,
|
|
VclMessageType::Warning, VclButtonsType::Ok,
|
|
rString));
|
|
xBox->run();
|
|
}
|
|
|
|
int QUERYBOX(weld::Window* pParent, const OUString& rString)
|
|
{
|
|
std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(pParent,
|
|
VclMessageType::Question, VclButtonsType::YesNo,
|
|
rString));
|
|
xBox->set_default_response(RET_YES);
|
|
return xBox->run();
|
|
}
|
|
|
|
}
|
|
|
|
const sal_uLong nEntryDataCol = 0;
|
|
const sal_uLong nEntryDataRow = 1;
|
|
const sal_uLong nEntryDataDelim = 2;
|
|
|
|
|
|
// note: some of the initialisation is done in Init
|
|
ScColRowNameRangesDlg::ScColRowNameRangesDlg( SfxBindings* pB,
|
|
SfxChildWindow* pCW,
|
|
weld::Window* pParent,
|
|
ScViewData& rViewData )
|
|
|
|
: ScAnyRefDlgController(pB, pCW, pParent, u"modules/scalc/ui/namerangesdialog.ui"_ustr, u"NameRangesDialog"_ustr)
|
|
, m_rViewData(rViewData)
|
|
, rDoc(rViewData.GetDocument())
|
|
, bDlgLostFocus(false)
|
|
, m_pEdActive(nullptr)
|
|
, m_xLbRange(m_xBuilder->weld_tree_view(u"range"_ustr))
|
|
, m_xEdAssign(new formula::RefEdit(m_xBuilder->weld_entry(u"edassign"_ustr)))
|
|
, m_xRbAssign(new formula::RefButton(m_xBuilder->weld_button(u"rbassign"_ustr)))
|
|
, m_xBtnColHead(m_xBuilder->weld_radio_button(u"colhead"_ustr))
|
|
, m_xBtnRowHead(m_xBuilder->weld_radio_button(u"rowhead"_ustr))
|
|
, m_xEdAssign2(new formula::RefEdit(m_xBuilder->weld_entry(u"edassign2"_ustr)))
|
|
, m_xRbAssign2(new formula::RefButton(m_xBuilder->weld_button(u"rbassign2"_ustr)))
|
|
, m_xBtnOk(m_xBuilder->weld_button(u"ok"_ustr))
|
|
, m_xBtnCancel(m_xBuilder->weld_button(u"cancel"_ustr))
|
|
, m_xBtnAdd(m_xBuilder->weld_button(u"add"_ustr))
|
|
, m_xBtnRemove(m_xBuilder->weld_button(u"delete"_ustr))
|
|
, m_xRangeFrame(m_xBuilder->weld_frame(u"rangeframe"_ustr))
|
|
, m_xRangeFT(m_xRangeFrame->weld_label_widget())
|
|
, m_xDataFT(m_xBuilder->weld_label(u"datarange"_ustr))
|
|
{
|
|
m_xRbAssign->SetReferences(this, m_xEdAssign.get());
|
|
m_xEdAssign->SetReferences(this, m_xRangeFT.get());
|
|
m_xRbAssign2->SetReferences(this, m_xEdAssign2.get());
|
|
m_xEdAssign2->SetReferences(this, m_xDataFT.get());
|
|
|
|
xColNameRanges = rDoc.GetColNameRanges()->Clone();
|
|
xRowNameRanges = rDoc.GetRowNameRanges()->Clone();
|
|
Init();
|
|
}
|
|
|
|
ScColRowNameRangesDlg::~ScColRowNameRangesDlg()
|
|
{
|
|
}
|
|
|
|
// initialises event handlers and start parameters in the dialog
|
|
void ScColRowNameRangesDlg::Init()
|
|
{
|
|
m_xBtnOk->connect_clicked ( LINK( this, ScColRowNameRangesDlg, OkBtnHdl ) );
|
|
m_xBtnCancel->connect_clicked ( LINK( this, ScColRowNameRangesDlg, CancelBtnHdl ) );
|
|
m_xBtnAdd->connect_clicked ( LINK( this, ScColRowNameRangesDlg, AddBtnHdl ) );
|
|
m_xBtnRemove->connect_clicked ( LINK( this, ScColRowNameRangesDlg, RemoveBtnHdl ) );
|
|
m_xLbRange->connect_changed( LINK( this, ScColRowNameRangesDlg, Range1SelectHdl ) );
|
|
m_xEdAssign->SetModifyHdl ( LINK( this, ScColRowNameRangesDlg, Range1DataModifyHdl ) );
|
|
m_xBtnColHead->connect_toggled ( LINK( this, ScColRowNameRangesDlg, ColRowToggleHdl ) );
|
|
m_xEdAssign2->SetModifyHdl ( LINK( this, ScColRowNameRangesDlg, Range2DataModifyHdl ) );
|
|
|
|
Link<formula::RefEdit&,void> aEditLink = LINK( this, ScColRowNameRangesDlg, GetEditFocusHdl );
|
|
m_xEdAssign->SetGetFocusHdl( aEditLink );
|
|
m_xEdAssign2->SetGetFocusHdl( aEditLink );
|
|
|
|
Link<formula::RefButton&,void> aButtonLink = LINK( this, ScColRowNameRangesDlg, GetButtonFocusHdl );
|
|
m_xRbAssign->SetGetFocusHdl( aButtonLink );
|
|
m_xRbAssign2->SetGetFocusHdl( aButtonLink );
|
|
|
|
aEditLink = LINK( this, ScColRowNameRangesDlg, LoseEditFocusHdl );
|
|
m_xEdAssign->SetLoseFocusHdl( aEditLink );
|
|
m_xEdAssign2->SetLoseFocusHdl( aEditLink );
|
|
|
|
aButtonLink = LINK( this, ScColRowNameRangesDlg, LoseButtonFocusHdl );
|
|
m_xRbAssign2->SetLoseFocusHdl( aButtonLink );
|
|
m_xRbAssign->SetLoseFocusHdl( aButtonLink );
|
|
|
|
m_pEdActive = m_xEdAssign.get();
|
|
|
|
UpdateNames();
|
|
|
|
SCCOL nStartCol = 0;
|
|
SCROW nStartRow = 0;
|
|
SCTAB nStartTab = 0;
|
|
SCCOL nEndCol = 0;
|
|
SCROW nEndRow = 0;
|
|
SCTAB nEndTab = 0;
|
|
m_rViewData.GetSimpleArea(nStartCol, nStartRow, nStartTab,
|
|
nEndCol, nEndRow, nEndTab );
|
|
SetColRowData( ScRange( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab));
|
|
|
|
m_xBtnColHead->set_sensitive(true);
|
|
m_xBtnRowHead->set_sensitive(true);
|
|
m_xEdAssign->GetWidget()->set_sensitive(true);
|
|
m_xEdAssign->GrabFocus();
|
|
m_xRbAssign->GetWidget()->set_sensitive(true);
|
|
|
|
Range1SelectHdl( *m_xLbRange );
|
|
}
|
|
|
|
// set data range of a labeled range to default values and set the
|
|
// form elements for the reference
|
|
void ScColRowNameRangesDlg::SetColRowData( const ScRange& rLabelRange, bool bRef)
|
|
{
|
|
theCurData = theCurArea = rLabelRange;
|
|
bool bValid = true;
|
|
SCCOL nCol1 = theCurArea.aStart.Col();
|
|
SCCOL nCol2 = theCurArea.aEnd.Col();
|
|
SCROW nRow1 = theCurArea.aStart.Row();
|
|
SCROW nRow2 = theCurArea.aEnd.Row();
|
|
if ( (static_cast<SCCOLROW>(nCol2 - nCol1) >= nRow2 - nRow1) || (nCol1 == 0 && nCol2 == rDoc.MaxCol()) )
|
|
{ // Column headers and the limiting case of the whole sheet
|
|
m_xBtnColHead->set_active(true);
|
|
m_xBtnRowHead->set_active(false);
|
|
if ( nRow2 == rDoc.MaxRow() )
|
|
{
|
|
if ( nRow1 == 0 )
|
|
bValid = false; // limiting case of the whole sheet
|
|
else
|
|
{ // Header at bottom, data above
|
|
theCurData.aStart.SetRow( 0 );
|
|
theCurData.aEnd.SetRow( nRow1 - 1 );
|
|
}
|
|
}
|
|
else
|
|
{ // Header at top, data below
|
|
theCurData.aStart.SetRow( nRow2 + 1 );
|
|
theCurData.aEnd.SetRow( rDoc.MaxRow() );
|
|
}
|
|
}
|
|
else
|
|
{ // Column headers
|
|
m_xBtnRowHead->set_active(true);
|
|
m_xBtnColHead->set_active(false);
|
|
if ( nCol2 == rDoc.MaxCol() )
|
|
{ // Header at the right, data to the left
|
|
theCurData.aStart.SetCol( 0 );
|
|
theCurData.aEnd.SetCol( nCol2 - 1 );
|
|
}
|
|
else
|
|
{ // Header at the left, data to the right
|
|
theCurData.aStart.SetCol( nCol2 + 1 );
|
|
theCurData.aEnd.SetCol( rDoc.MaxCol() );
|
|
}
|
|
}
|
|
if ( bValid )
|
|
{
|
|
const formula::FormulaGrammar::AddressConvention eConv = rDoc.GetAddressConvention();
|
|
OUString aStr(theCurArea.Format(rDoc, ScRefFlags::RANGE_ABS_3D, eConv));
|
|
|
|
if(bRef)
|
|
m_xEdAssign->SetRefString( aStr );
|
|
else
|
|
m_xEdAssign->SetText( aStr );
|
|
|
|
m_xEdAssign->SetCursorAtLast();
|
|
aStr = theCurData.Format(rDoc, ScRefFlags::RANGE_ABS_3D, eConv);
|
|
|
|
if(bRef)
|
|
m_xEdAssign2->SetRefString( aStr );
|
|
else
|
|
m_xEdAssign2->SetText( aStr );
|
|
}
|
|
else
|
|
{
|
|
theCurData = theCurArea = ScRange();
|
|
|
|
if(bRef)
|
|
{
|
|
m_xEdAssign->SetRefString( OUString() );
|
|
m_xEdAssign2->SetRefString( OUString() );
|
|
}
|
|
else
|
|
{
|
|
m_xEdAssign->SetText( OUString() );
|
|
m_xEdAssign2->SetText( OUString() );
|
|
}
|
|
|
|
m_xBtnColHead->set_sensitive(false);
|
|
m_xBtnRowHead->set_sensitive(false);
|
|
m_xEdAssign2->GetWidget()->set_sensitive(false);
|
|
m_xRbAssign2->GetWidget()->set_sensitive(false);
|
|
}
|
|
}
|
|
|
|
// adjust label range and set the data reference form element
|
|
void ScColRowNameRangesDlg::AdjustColRowData( const ScRange& rDataRange, bool bRef)
|
|
{
|
|
theCurData = rDataRange;
|
|
if ( m_xBtnColHead->get_active() )
|
|
{ // Data range is the same columns as the header
|
|
theCurData.aStart.SetCol( theCurArea.aStart.Col() );
|
|
theCurData.aEnd.SetCol( theCurArea.aEnd.Col() );
|
|
if ( theCurData.Intersects( theCurArea ) )
|
|
{
|
|
SCROW nRow1 = theCurArea.aStart.Row();
|
|
SCROW nRow2 = theCurArea.aEnd.Row();
|
|
if ( nRow1 > 0
|
|
&& (theCurData.aEnd.Row() < nRow2 || nRow2 == rDoc.MaxRow()) )
|
|
{ // Data above header
|
|
theCurData.aEnd.SetRow( nRow1 - 1 );
|
|
if ( theCurData.aStart.Row() > theCurData.aEnd.Row() )
|
|
theCurData.aStart.SetRow( theCurData.aEnd.Row() );
|
|
}
|
|
else
|
|
{ // Data below header
|
|
theCurData.aStart.SetRow( nRow2 + 1 );
|
|
if ( theCurData.aStart.Row() > theCurData.aEnd.Row() )
|
|
theCurData.aEnd.SetRow( theCurData.aStart.Row() );
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{ // Data range in the same rows as header
|
|
theCurData.aStart.SetRow( theCurArea.aStart.Row() );
|
|
theCurData.aEnd.SetRow( theCurArea.aEnd.Row() );
|
|
if ( theCurData.Intersects( theCurArea ) )
|
|
{
|
|
SCCOL nCol1 = theCurArea.aStart.Col();
|
|
SCCOL nCol2 = theCurArea.aEnd.Col();
|
|
if ( nCol1 > 0
|
|
&& (theCurData.aEnd.Col() < nCol2 || nCol2 == rDoc.MaxCol()) )
|
|
{ // Data left of header
|
|
theCurData.aEnd.SetCol( nCol1 - 1 );
|
|
if ( theCurData.aStart.Col() > theCurData.aEnd.Col() )
|
|
theCurData.aStart.SetCol( theCurData.aEnd.Col() );
|
|
}
|
|
else
|
|
{ // Data right of header
|
|
theCurData.aStart.SetCol( nCol2 + 1 );
|
|
if ( theCurData.aStart.Col() > theCurData.aEnd.Col() )
|
|
theCurData.aEnd.SetCol( theCurData.aStart.Col() );
|
|
}
|
|
}
|
|
}
|
|
OUString aStr(theCurData.Format(rDoc, ScRefFlags::RANGE_ABS_3D, rDoc.GetAddressConvention()));
|
|
|
|
if(bRef)
|
|
m_xEdAssign2->SetRefString( aStr );
|
|
else
|
|
m_xEdAssign2->SetText( aStr );
|
|
|
|
m_xEdAssign2->SetCursorAtLast();
|
|
}
|
|
|
|
// Set the reference to a cell range selected with the mouse and update
|
|
// the selection form element
|
|
void ScColRowNameRangesDlg::SetReference( const ScRange& rRef, ScDocument& /* rDoc */ )
|
|
{
|
|
if ( !m_pEdActive )
|
|
return;
|
|
|
|
if ( rRef.aStart != rRef.aEnd )
|
|
RefInputStart( m_pEdActive );
|
|
|
|
if (m_pEdActive == m_xEdAssign.get())
|
|
SetColRowData( rRef, true );
|
|
else
|
|
AdjustColRowData( rRef, true );
|
|
m_xBtnColHead->set_sensitive(true);
|
|
m_xBtnRowHead->set_sensitive(true);
|
|
m_xBtnAdd->set_sensitive(true);
|
|
m_xBtnRemove->set_sensitive(false);
|
|
}
|
|
|
|
void ScColRowNameRangesDlg::Close()
|
|
{
|
|
DoClose( ScColRowNameRangesDlgWrapper::GetChildWindowId() );
|
|
}
|
|
|
|
void ScColRowNameRangesDlg::SetActive()
|
|
{
|
|
if ( bDlgLostFocus )
|
|
{
|
|
bDlgLostFocus = false;
|
|
if( m_pEdActive )
|
|
m_pEdActive->GrabFocus();
|
|
}
|
|
else
|
|
m_xDialog->grab_focus();
|
|
|
|
if( m_pEdActive == m_xEdAssign.get() )
|
|
Range1DataModifyHdl( *m_xEdAssign );
|
|
else if( m_pEdActive == m_xEdAssign2.get() )
|
|
Range2DataModifyHdl( *m_xEdAssign2 );
|
|
|
|
RefInputDone();
|
|
}
|
|
|
|
void ScColRowNameRangesDlg::UpdateNames()
|
|
{
|
|
m_xLbRange->freeze();
|
|
|
|
m_xLbRange->clear();
|
|
aRangeMap.clear();
|
|
m_xEdAssign->SetText( OUString() );
|
|
|
|
size_t nCount, j;
|
|
|
|
SCCOL nCol1;
|
|
SCROW nRow1; //Extension for range names
|
|
SCTAB nTab1;
|
|
SCCOL nCol2;
|
|
SCROW nRow2;
|
|
SCTAB nTab2;
|
|
OUString rString;
|
|
const ScAddress::Details aDetails(rDoc.GetAddressConvention());
|
|
|
|
OUString strDelim(u" --- "_ustr);
|
|
OUString aString = strDelim + ScResId( STR_COLUMN ) + strDelim;
|
|
m_xLbRange->append(OUString::number(nEntryDataDelim), aString);
|
|
if ( xColNameRanges->size() > 0 )
|
|
{
|
|
std::vector<const ScRangePair*> aSortArray(xColNameRanges->CreateNameSortedArray(
|
|
rDoc ));
|
|
nCount = aSortArray.size();
|
|
for ( j=0; j < nCount; j++ )
|
|
{
|
|
const ScRange aRange(aSortArray[j]->GetRange(0));
|
|
aString = aRange.Format(rDoc, ScRefFlags::RANGE_ABS_3D, aDetails);
|
|
|
|
//@008 get range parameters from document
|
|
aSortArray[j]->GetRange(0).GetVars( nCol1, nRow1, nTab1,
|
|
nCol2, nRow2, nTab2 );
|
|
SCCOL q=nCol1+3;
|
|
if(q>nCol2) q=nCol2;
|
|
//@008 construct string
|
|
OUStringBuffer strShow = " [";
|
|
rString = rDoc.GetString(nCol1, nRow1, nTab1);
|
|
strShow.append(rString);
|
|
for(SCCOL i=nCol1+1;i<=q;i++)
|
|
{
|
|
strShow.append(", ");
|
|
rString = rDoc.GetString(i, nRow1, nTab1);
|
|
strShow.append(rString);
|
|
}
|
|
if(q<nCol2) // Too long? Add ",..."
|
|
{
|
|
strShow.append(", ...");
|
|
}
|
|
strShow.append("]");
|
|
|
|
//@008 Add string to listbox
|
|
OUString aInsStr = aString + strShow;
|
|
aRangeMap.emplace( aInsStr, aRange );
|
|
m_xLbRange->append(OUString::number(nEntryDataCol), aInsStr);
|
|
}
|
|
}
|
|
aString = strDelim + ScResId( STR_ROW ) + strDelim;
|
|
m_xLbRange->append(OUString::number(nEntryDataDelim), aString);
|
|
if ( xRowNameRanges->size() > 0 )
|
|
{
|
|
std::vector<const ScRangePair*> aSortArray(xRowNameRanges->CreateNameSortedArray(
|
|
rDoc ));
|
|
nCount = aSortArray.size();
|
|
for ( j=0; j < nCount; j++ )
|
|
{
|
|
const ScRange aRange(aSortArray[j]->GetRange(0));
|
|
aString = aRange.Format(rDoc, ScRefFlags::RANGE_ABS_3D, aDetails);
|
|
|
|
//@008 Build string for rows below
|
|
aSortArray[j]->GetRange(0).GetVars( nCol1, nRow1, nTab1,
|
|
nCol2, nRow2, nTab2 );
|
|
SCROW q=nRow1+3;
|
|
if(q>nRow2) q=nRow2;
|
|
OUStringBuffer strShow = " [";
|
|
rString = rDoc.GetString(nCol1, nRow1, nTab1);
|
|
strShow.append(rString);
|
|
for(SCROW i=nRow1+1;i<=q;i++)
|
|
{
|
|
strShow.append(", ");
|
|
rString = rDoc.GetString(nCol1, i, nTab1);
|
|
strShow.append(rString);
|
|
}
|
|
if(q<nRow2)
|
|
{
|
|
strShow.append(", ...");
|
|
}
|
|
strShow.append("]");
|
|
|
|
OUString aInsStr = aString + strShow;
|
|
aRangeMap.emplace( aInsStr, aRange );
|
|
m_xLbRange->append(OUString::number(nEntryDataRow), aInsStr);
|
|
}
|
|
}
|
|
|
|
m_xLbRange->thaw();
|
|
}
|
|
|
|
void ScColRowNameRangesDlg::UpdateRangeData( const ScRange& rRange, bool bColName )
|
|
{
|
|
ScRangePair* pPair = nullptr;
|
|
bool bFound = false;
|
|
if ( bColName && (pPair = xColNameRanges->Find( rRange )) != nullptr )
|
|
bFound = true;
|
|
else if ( !bColName && (pPair = xRowNameRanges->Find( rRange )) != nullptr )
|
|
bFound = true;
|
|
|
|
if ( bFound )
|
|
{
|
|
const formula::FormulaGrammar::AddressConvention eConv = rDoc.GetAddressConvention();
|
|
theCurArea = rRange;
|
|
OUString aStr(theCurArea.Format(rDoc, ScRefFlags::RANGE_ABS_3D, eConv));
|
|
m_xEdAssign->SetText( aStr );
|
|
m_xBtnAdd->set_sensitive(false);
|
|
m_xBtnRemove->set_sensitive(true);
|
|
m_xBtnColHead->set_active(bColName);
|
|
m_xBtnRowHead->set_active(!bColName);
|
|
theCurData = pPair->GetRange(1);
|
|
aStr = theCurData.Format(rDoc, ScRefFlags::RANGE_ABS_3D, eConv);
|
|
m_xEdAssign2->SetText( aStr );
|
|
}
|
|
else
|
|
{
|
|
m_xBtnAdd->set_sensitive(true);
|
|
m_xBtnRemove->set_sensitive(false);
|
|
}
|
|
m_xBtnColHead->set_sensitive(true);
|
|
m_xBtnRowHead->set_sensitive(true);
|
|
m_xEdAssign2->GetWidget()->set_sensitive(true);
|
|
m_xRbAssign2->GetWidget()->set_sensitive(true);
|
|
}
|
|
|
|
bool ScColRowNameRangesDlg::IsRefInputMode() const
|
|
{
|
|
return (m_pEdActive != nullptr);
|
|
}
|
|
|
|
// Handler:
|
|
|
|
// handler called when OK is clicked, calls the add button handler before
|
|
// passing the range lists to the document
|
|
IMPL_LINK_NOARG(ScColRowNameRangesDlg, OkBtnHdl, weld::Button&, void)
|
|
{
|
|
AddBtnHdl(*m_xBtnAdd);
|
|
|
|
// assign RangeLists to the references in the document
|
|
rDoc.GetColNameRangesRef() = xColNameRanges;
|
|
rDoc.GetRowNameRangesRef() = xRowNameRanges;
|
|
// changed ranges need to take effect
|
|
rDoc.CompileColRowNameFormula();
|
|
ScDocShell* pDocShell = m_rViewData.GetDocShell();
|
|
pDocShell->PostPaint(ScRange(0, 0, 0, rDoc.MaxCol(), rDoc.MaxRow(), MAXTAB), PaintPartFlags::Grid);
|
|
pDocShell->SetDocumentModified();
|
|
|
|
response(RET_OK);
|
|
}
|
|
|
|
IMPL_LINK_NOARG(ScColRowNameRangesDlg, CancelBtnHdl, weld::Button&, void)
|
|
{
|
|
response(RET_CANCEL);
|
|
}
|
|
|
|
// handler called when add button clicked: set ranges and add to listbox
|
|
IMPL_LINK_NOARG(ScColRowNameRangesDlg, AddBtnHdl, weld::Button&, void)
|
|
{
|
|
OUString aNewArea( m_xEdAssign->GetText() );
|
|
OUString aNewData( m_xEdAssign2->GetText() );
|
|
|
|
if (aNewArea.isEmpty() || aNewData.isEmpty())
|
|
return;
|
|
|
|
const formula::FormulaGrammar::AddressConvention eConv = rDoc.GetAddressConvention();
|
|
ScRange aRange1, aRange2;
|
|
bool bOk1 = (aRange1.ParseAny( aNewArea, rDoc, eConv ) & ScRefFlags::VALID) == ScRefFlags::VALID;
|
|
if ( bOk1 && (aRange2.ParseAny( aNewData, rDoc, eConv ) & ScRefFlags::VALID) == ScRefFlags::VALID)
|
|
{
|
|
theCurArea = aRange1;
|
|
AdjustColRowData( aRange2 );
|
|
ScRangePair* pPair;
|
|
if ( ( pPair = xColNameRanges->Find( theCurArea ) ) != nullptr )
|
|
{
|
|
xColNameRanges->Remove( *pPair );
|
|
}
|
|
if ( ( pPair = xRowNameRanges->Find( theCurArea ) ) != nullptr )
|
|
{
|
|
xRowNameRanges->Remove( *pPair );
|
|
}
|
|
if ( m_xBtnColHead->get_active() )
|
|
xColNameRanges->Join( ScRangePair( theCurArea, theCurData ) );
|
|
else
|
|
xRowNameRanges->Join( ScRangePair( theCurArea, theCurData ) );
|
|
|
|
UpdateNames();
|
|
|
|
m_xEdAssign->GrabFocus();
|
|
m_xBtnAdd->set_sensitive(false);
|
|
m_xBtnRemove->set_sensitive(false);
|
|
m_xEdAssign->SetText( OUString() );
|
|
m_xBtnColHead->set_active(true);
|
|
m_xBtnRowHead->set_active(false);
|
|
m_xEdAssign2->SetText( OUString() );
|
|
theCurArea = ScRange();
|
|
theCurData = theCurArea;
|
|
Range1SelectHdl( *m_xLbRange );
|
|
}
|
|
else
|
|
{
|
|
ERRORBOX(m_xDialog.get(), ScResId(STR_INVALIDTABNAME));
|
|
if ( !bOk1 )
|
|
m_xEdAssign->GrabFocus();
|
|
else
|
|
m_xEdAssign2->GrabFocus();
|
|
}
|
|
}
|
|
|
|
IMPL_LINK_NOARG(ScColRowNameRangesDlg, RemoveBtnHdl, weld::Button&, void)
|
|
{
|
|
OUString aRangeStr = m_xLbRange->get_selected_text();
|
|
sal_Int32 nSelectPos = m_xLbRange->get_selected_index();
|
|
bool bColName = nSelectPos != -1 && m_xLbRange->get_id(nSelectPos).toInt32() == nEntryDataCol;
|
|
NameRangeMap::const_iterator itr = aRangeMap.find(aRangeStr);
|
|
if (itr == aRangeMap.end())
|
|
return;
|
|
const ScRange& rRange = itr->second;
|
|
|
|
ScRangePair* pPair = nullptr;
|
|
bool bFound = false;
|
|
if ( bColName && (pPair = xColNameRanges->Find( rRange )) != nullptr )
|
|
bFound = true;
|
|
else if ( !bColName && (pPair = xRowNameRanges->Find( rRange )) != nullptr )
|
|
bFound = true;
|
|
if ( !bFound )
|
|
return;
|
|
|
|
OUString aStrDelMsg = ScResId( STR_QUERY_DELENTRY );
|
|
OUString aMsg = o3tl::getToken(aStrDelMsg, 0, '#' )
|
|
+ aRangeStr
|
|
+ o3tl::getToken(aStrDelMsg, 1, '#' );
|
|
|
|
if (RET_YES != QUERYBOX(m_xDialog.get(), aMsg))
|
|
return;
|
|
|
|
if ( bColName )
|
|
xColNameRanges->Remove( *pPair );
|
|
else
|
|
xRowNameRanges->Remove( *pPair );
|
|
|
|
UpdateNames();
|
|
const sal_Int32 nCnt = m_xLbRange->n_children();
|
|
if ( nSelectPos >= nCnt )
|
|
{
|
|
if ( nCnt )
|
|
nSelectPos = nCnt - 1;
|
|
else
|
|
nSelectPos = 0;
|
|
}
|
|
m_xLbRange->select(nSelectPos);
|
|
if (nSelectPos && m_xLbRange->get_id(nSelectPos).toInt32() == nEntryDataDelim)
|
|
m_xLbRange->select( --nSelectPos ); // ---Row---
|
|
|
|
m_xLbRange->grab_focus();
|
|
m_xBtnAdd->set_sensitive(false);
|
|
m_xBtnRemove->set_sensitive(false);
|
|
m_xEdAssign->SetText( OUString() );
|
|
theCurArea = theCurData = ScRange();
|
|
m_xBtnColHead->set_active(true);
|
|
m_xBtnRowHead->set_active(false);
|
|
m_xEdAssign2->SetText( OUString() );
|
|
Range1SelectHdl( *m_xLbRange );
|
|
}
|
|
|
|
// handler called when a row in the listbox is selected, updates form input fields
|
|
IMPL_LINK_NOARG(ScColRowNameRangesDlg, Range1SelectHdl, weld::TreeView&, void)
|
|
{
|
|
sal_Int32 nSelectPos = m_xLbRange->get_selected_index();
|
|
const sal_Int32 nCnt = m_xLbRange->n_children();
|
|
sal_uInt16 nMoves = 0;
|
|
while (nSelectPos != -1 && nSelectPos < nCnt && m_xLbRange->get_id(nSelectPos).toInt32() == nEntryDataDelim)
|
|
{ // skip Delimiter
|
|
++nMoves;
|
|
++nSelectPos;
|
|
}
|
|
OUString aRangeStr = m_xLbRange->get_selected_text();
|
|
if ( nMoves )
|
|
{
|
|
if ( nSelectPos > 1 && nSelectPos >= nCnt )
|
|
{ // if entries exist before the " --- Row --- " Delimiter then
|
|
// do not stop at the delimiter
|
|
nSelectPos = nCnt - 2;
|
|
m_xLbRange->select(nSelectPos);
|
|
aRangeStr = m_xLbRange->get_selected_text();
|
|
}
|
|
else if ( nSelectPos > 2 && nSelectPos < nCnt && !aRangeStr.isEmpty()
|
|
&& aRangeStr == m_xEdAssign->GetText() )
|
|
{ // move upwards instead of below to the previous position
|
|
nSelectPos -= 2;
|
|
m_xLbRange->select( nSelectPos );
|
|
aRangeStr = m_xLbRange->get_selected_text();
|
|
}
|
|
else
|
|
m_xLbRange->select(nSelectPos);
|
|
}
|
|
NameRangeMap::const_iterator itr = aRangeMap.find(aRangeStr);
|
|
if ( itr != aRangeMap.end() )
|
|
{
|
|
bool bColName = m_xLbRange->get_id(nSelectPos).toInt32() == nEntryDataCol;
|
|
UpdateRangeData( itr->second, bColName );
|
|
m_xBtnAdd->set_sensitive(false);
|
|
m_xBtnRemove->set_sensitive(true);
|
|
}
|
|
else
|
|
{
|
|
if ( !m_xEdAssign->GetText().isEmpty() )
|
|
{
|
|
if ( !m_xEdAssign2->GetText().isEmpty() )
|
|
m_xBtnAdd->set_sensitive(true);
|
|
else
|
|
m_xBtnAdd->set_sensitive(false);
|
|
m_xBtnColHead->set_sensitive(true);
|
|
m_xBtnRowHead->set_sensitive(true);
|
|
m_xEdAssign2->GetWidget()->set_sensitive(true);
|
|
m_xRbAssign2->GetWidget()->set_sensitive(true);
|
|
}
|
|
else
|
|
{
|
|
m_xBtnAdd->set_sensitive(false);
|
|
m_xBtnColHead->set_sensitive(false);
|
|
m_xBtnRowHead->set_sensitive(false);
|
|
m_xEdAssign2->GetWidget()->set_sensitive(false);
|
|
m_xRbAssign2->GetWidget()->set_sensitive(false);
|
|
}
|
|
m_xBtnRemove->set_sensitive(false);
|
|
m_xEdAssign->GrabFocus();
|
|
}
|
|
|
|
m_xEdAssign->GetWidget()->set_sensitive(true);
|
|
m_xRbAssign->GetWidget()->set_sensitive(true);
|
|
}
|
|
|
|
// handler called when the label range has changed
|
|
IMPL_LINK_NOARG(ScColRowNameRangesDlg, Range1DataModifyHdl, formula::RefEdit&, void)
|
|
{
|
|
OUString aNewArea( m_xEdAssign->GetText() );
|
|
bool bValid = false;
|
|
if (!aNewArea.isEmpty())
|
|
{
|
|
ScRange aRange;
|
|
if ( (aRange.ParseAny(aNewArea, rDoc, rDoc.GetAddressConvention() ) & ScRefFlags::VALID) == ScRefFlags::VALID)
|
|
{
|
|
SetColRowData( aRange );
|
|
bValid = true;
|
|
}
|
|
}
|
|
if ( bValid )
|
|
{
|
|
m_xBtnAdd->set_sensitive(true);
|
|
m_xBtnColHead->set_sensitive(true);
|
|
m_xBtnRowHead->set_sensitive(true);
|
|
m_xEdAssign2->GetWidget()->set_sensitive(true);
|
|
m_xRbAssign2->GetWidget()->set_sensitive(true);
|
|
}
|
|
else
|
|
{
|
|
m_xBtnAdd->set_sensitive(false);
|
|
m_xBtnColHead->set_sensitive(false);
|
|
m_xBtnRowHead->set_sensitive(false);
|
|
m_xEdAssign2->GetWidget()->set_sensitive(false);
|
|
m_xRbAssign2->GetWidget()->set_sensitive(false);
|
|
}
|
|
m_xBtnRemove->set_sensitive(false);
|
|
}
|
|
|
|
// handler called when the data range has changed
|
|
IMPL_LINK_NOARG(ScColRowNameRangesDlg, Range2DataModifyHdl, formula::RefEdit&, void)
|
|
{
|
|
OUString aNewData( m_xEdAssign2->GetText() );
|
|
if ( !aNewData.isEmpty() )
|
|
{
|
|
ScRange aRange;
|
|
if ( (aRange.ParseAny(aNewData, rDoc, rDoc.GetAddressConvention() ) & ScRefFlags::VALID) == ScRefFlags::VALID)
|
|
{
|
|
AdjustColRowData( aRange );
|
|
m_xBtnAdd->set_sensitive(true);
|
|
}
|
|
else
|
|
m_xBtnAdd->set_sensitive(false);
|
|
}
|
|
else
|
|
{
|
|
m_xBtnAdd->set_sensitive(false);
|
|
}
|
|
}
|
|
|
|
IMPL_LINK_NOARG(ScColRowNameRangesDlg, ColRowToggleHdl, weld::Toggleable&, void)
|
|
{
|
|
if (m_xBtnColHead->get_active())
|
|
{
|
|
// handler for the radio button for columns, adjust ranges
|
|
if ( theCurArea.aStart.Row() == 0 && theCurArea.aEnd.Row() == rDoc.MaxRow() )
|
|
{
|
|
theCurArea.aEnd.SetRow( rDoc.MaxRow() - 1 );
|
|
OUString aStr(theCurArea.Format(rDoc, ScRefFlags::RANGE_ABS_3D, rDoc.GetAddressConvention()));
|
|
m_xEdAssign->SetText( aStr );
|
|
}
|
|
ScRange aRange( theCurData );
|
|
aRange.aStart.SetRow( std::min( static_cast<tools::Long>(theCurArea.aEnd.Row() + 1), static_cast<tools::Long>(rDoc.MaxRow()) ) );
|
|
aRange.aEnd.SetRow( rDoc.MaxRow() );
|
|
AdjustColRowData( aRange );
|
|
}
|
|
else if (m_xBtnRowHead->get_active())
|
|
{
|
|
// handler for the radio button for columns, adjust range
|
|
if ( theCurArea.aStart.Col() == 0 && theCurArea.aEnd.Col() == rDoc.MaxCol() )
|
|
{
|
|
theCurArea.aEnd.SetCol( rDoc.MaxCol() - 1 );
|
|
OUString aStr(theCurArea.Format(rDoc, ScRefFlags::RANGE_ABS_3D, rDoc.GetAddressConvention()));
|
|
m_xEdAssign->SetText( aStr );
|
|
}
|
|
ScRange aRange( theCurData );
|
|
aRange.aStart.SetCol( static_cast<SCCOL>(std::min( static_cast<tools::Long>(theCurArea.aEnd.Col() + 1), static_cast<tools::Long>(rDoc.MaxCol()) )) );
|
|
aRange.aEnd.SetCol( rDoc.MaxCol() );
|
|
AdjustColRowData( aRange );
|
|
}
|
|
}
|
|
|
|
IMPL_LINK( ScColRowNameRangesDlg, GetEditFocusHdl, formula::RefEdit&, rCtrl, void )
|
|
{
|
|
if (&rCtrl == m_xEdAssign.get())
|
|
m_pEdActive = m_xEdAssign.get();
|
|
else if (&rCtrl == m_xEdAssign2.get())
|
|
m_pEdActive = m_xEdAssign2.get();
|
|
else
|
|
m_pEdActive = nullptr;
|
|
|
|
if( m_pEdActive )
|
|
m_pEdActive->SelectAll();
|
|
}
|
|
|
|
IMPL_LINK( ScColRowNameRangesDlg, GetButtonFocusHdl, formula::RefButton&, rCtrl, void )
|
|
{
|
|
if (&rCtrl == m_xRbAssign.get())
|
|
m_pEdActive = m_xEdAssign.get();
|
|
else if (&rCtrl == m_xRbAssign2.get())
|
|
m_pEdActive = m_xEdAssign2.get();
|
|
else
|
|
m_pEdActive = nullptr;
|
|
|
|
if( m_pEdActive )
|
|
m_pEdActive->SelectAll();
|
|
}
|
|
|
|
IMPL_LINK_NOARG(ScColRowNameRangesDlg, LoseEditFocusHdl, formula::RefEdit&, void)
|
|
{
|
|
bDlgLostFocus = !m_xDialog->has_toplevel_focus();
|
|
}
|
|
|
|
IMPL_LINK_NOARG(ScColRowNameRangesDlg, LoseButtonFocusHdl, formula::RefButton&, void)
|
|
{
|
|
bDlgLostFocus = !m_xDialog->has_toplevel_focus();
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|