summaryrefslogtreecommitdiff
path: root/sc/source/ui
diff options
context:
space:
mode:
Diffstat (limited to 'sc/source/ui')
-rw-r--r--sc/source/ui/app/inputhdl.cxx50
-rw-r--r--sc/source/ui/app/inputwin.cxx6
-rw-r--r--sc/source/ui/app/scmod.cxx4
-rw-r--r--sc/source/ui/cctrl/checklistmenu.cxx17
-rw-r--r--sc/source/ui/dbgui/PivotLayoutDialog.cxx3
-rw-r--r--sc/source/ui/docshell/docfunc.cxx3
-rw-r--r--sc/source/ui/docshell/docsh.cxx14
-rw-r--r--sc/source/ui/docshell/externalrefmgr.cxx8
-rw-r--r--sc/source/ui/docshell/impex.cxx112
-rw-r--r--sc/source/ui/inc/checklistmenu.hxx2
-rw-r--r--sc/source/ui/inc/inputhdl.hxx4
-rw-r--r--sc/source/ui/inc/undoblk.hxx4
-rw-r--r--sc/source/ui/inc/viewfunc.hxx30
-rw-r--r--sc/source/ui/miscdlgs/sharedocdlg.cxx6
-rw-r--r--sc/source/ui/undo/undoblk.cxx2
-rw-r--r--sc/source/ui/undo/undotab.cxx7
-rw-r--r--sc/source/ui/unoobj/cellsuno.cxx4
-rw-r--r--sc/source/ui/unoobj/chart2uno.cxx3
-rw-r--r--sc/source/ui/unoobj/listenercalls.cxx2
-rw-r--r--sc/source/ui/vba/excelvbahelper.cxx25
-rw-r--r--sc/source/ui/vba/vbarange.cxx94
-rw-r--r--sc/source/ui/vba/vbarange.hxx3
-rw-r--r--sc/source/ui/vba/vbaworkbooks.cxx11
-rw-r--r--sc/source/ui/view/cellsh2.cxx49
-rw-r--r--sc/source/ui/view/editsh.cxx1
-rw-r--r--sc/source/ui/view/gridwin.cxx19
-rw-r--r--sc/source/ui/view/gridwin4.cxx4
-rw-r--r--sc/source/ui/view/output2.cxx12
-rw-r--r--sc/source/ui/view/printfun.cxx4
-rw-r--r--sc/source/ui/view/spellcheckcontext.cxx4
-rw-r--r--sc/source/ui/view/tabvwsh2.cxx11
-rw-r--r--sc/source/ui/view/tabvwsha.cxx23
-rw-r--r--sc/source/ui/view/viewdata.cxx31
-rw-r--r--sc/source/ui/view/viewfun2.cxx1
-rw-r--r--sc/source/ui/view/viewfun3.cxx38
-rw-r--r--sc/source/ui/view/viewfunc.cxx51
36 files changed, 483 insertions, 179 deletions
diff --git a/sc/source/ui/app/inputhdl.cxx b/sc/source/ui/app/inputhdl.cxx
index 8b4d8bde90b3..e69b06b9abca 100644
--- a/sc/source/ui/app/inputhdl.cxx
+++ b/sc/source/ui/app/inputhdl.cxx
@@ -830,6 +830,7 @@ ScInputHandler::ScInputHandler()
bLastIsSymbol( false ),
mbDocumentDisposing(false),
mbPartialPrefix(false),
+ mbEditingExistingContent(false),
nValidation( 0 ),
eAttrAdjust( SvxCellHorJustify::Standard ),
aScaleX( 1,1 ),
@@ -1079,14 +1080,14 @@ void ScInputHandler::GetFormulaData()
IMPL_LINK( ScInputHandler, ShowHideTipVisibleParentListener, VclWindowEvent&, rEvent, void )
{
if (rEvent.GetId() == VclEventId::ObjectDying || rEvent.GetId() == VclEventId::WindowHide
- || rEvent.GetId() == VclEventId::WindowLoseFocus)
+ || rEvent.GetId() == VclEventId::WindowLoseFocus || rEvent.GetId() == VclEventId::ControlLoseFocus)
HideTip();
}
IMPL_LINK( ScInputHandler, ShowHideTipVisibleSecParentListener, VclWindowEvent&, rEvent, void )
{
if (rEvent.GetId() == VclEventId::ObjectDying || rEvent.GetId() == VclEventId::WindowHide
- || rEvent.GetId() == VclEventId::WindowLoseFocus)
+ || rEvent.GetId() == VclEventId::WindowLoseFocus || rEvent.GetId() == VclEventId::ControlLoseFocus)
HideTipBelow();
}
@@ -1287,6 +1288,7 @@ void ScInputHandler::ShowTipCursor()
HideTipBelow();
EditView* pActiveView = pTopView ? pTopView : pTableView;
+ /* TODO: MLFORMULA: this should work also with multi-line formulas. */
if ( !(bFormulaMode && pActiveView && pFormulaDataPara && mpEditEngine->GetParagraphCount() == 1) )
return;
@@ -1534,7 +1536,7 @@ void ScInputHandler::UseFormulaData()
{
EditView* pActiveView = pTopView ? pTopView : pTableView;
- // Formulas may only have 1 paragraph
+ /* TODO: MLFORMULA: this should work also with multi-line formulas. */
if ( !(pActiveView && pFormulaData && mpEditEngine->GetParagraphCount() == 1) )
return;
@@ -1767,6 +1769,9 @@ void ScInputHandler::LOKPasteFunctionData(const OUString& rFunctionName)
if (pEditEngine)
{
aFormula = pEditEngine->GetText(0);
+ /* TODO: LOK: are you sure you want '+' and '-' let start formulas with
+ * function names? That was meant for "data typist" numeric keyboard
+ * input. */
bEdit = aFormula.getLength() > 1 && (aFormula[0] == '=' || aFormula[0] == '+' || aFormula[0] == '-');
}
@@ -2166,10 +2171,11 @@ void ScInputHandler::UpdateParenthesis()
{
// Examine character left to the cursor
sal_Int32 nPos = aSel.nStartPos - 1;
- OUString aFormula = mpEditEngine->GetText(0);
+ OUString aFormula = mpEditEngine->GetText(aSel.nStartPara);
sal_Unicode c = aFormula[nPos];
if ( c == '(' || c == ')' )
{
+ // Note this matches only within one paragraph.
sal_Int32 nOther = lcl_MatchParenthesis( aFormula, nPos );
if ( nOther != -1 )
{
@@ -2185,9 +2191,9 @@ void ScInputHandler::UpdateParenthesis()
mpEditEngine->RemoveCharAttribs( i, EE_CHAR_WEIGHT );
}
- ESelection aSelThis( 0,nPos, 0,nPos+1 );
+ ESelection aSelThis( aSel.nStartPara, nPos, aSel.nStartPara, nPos+1);
mpEditEngine->QuickSetAttribs( aSet, aSelThis );
- ESelection aSelOther( 0,nOther, 0,nOther+1 );
+ ESelection aSelOther( aSel.nStartPara, nOther, aSel.nStartPara, nOther+1);
mpEditEngine->QuickSetAttribs( aSet, aSelOther );
// Dummy InsertText for Update and Paint (selection is empty)
@@ -2556,6 +2562,9 @@ bool ScInputHandler::StartTable( sal_Unicode cTyped, bool bFromCommand, bool bIn
else
aStr = GetEditText(mpEditEngine.get());
+ // cTyped!=0 is overtyping, not editing.
+ mbEditingExistingContent = !cTyped && !aStr.isEmpty();
+
if (aStr.startsWith("{=") && aStr.endsWith("}") ) // Matrix formula?
{
aStr = aStr.copy(1, aStr.getLength() -2);
@@ -2569,8 +2578,7 @@ bool ScInputHandler::StartTable( sal_Unicode cTyped, bool bFromCommand, bool bIn
if ( bAutoComplete )
GetColData();
- if ( !aStr.isEmpty() && ( aStr[0] == '=' || aStr[0] == '+' || aStr[0] == '-' ) &&
- !cTyped && !bCreatingFuncView )
+ if (!cTyped && !bCreatingFuncView && StartsLikeFormula(aStr))
InitRangeFinder(aStr); // Formula is being edited -> RangeFinder
bNewTable = true; // -> PostEditView Call
@@ -2761,16 +2769,22 @@ void ScInputHandler::DataChanged( bool bFromTopNotify, bool bSetModified )
bInOwnChange = false;
}
+bool ScInputHandler::StartsLikeFormula( std::u16string_view rStr ) const
+{
+ // For new input '+' and '-' may start the dreaded "lazy data typist"
+ // formula input, editing existing formula content can only start with '='.
+ return !rStr.empty() && (rStr[0] == '=' || (!mbEditingExistingContent && (rStr[0] == '+' || rStr[0] == '-')));
+}
+
void ScInputHandler::UpdateFormulaMode()
{
SfxApplication* pSfxApp = SfxGetpApp();
- bool bIsFormula = !bProtected && mpEditEngine->GetParagraphCount() == 1;
+ bool bIsFormula = !bProtected;
if (bIsFormula)
{
const OUString& rText = mpEditEngine->GetText(0);
- bIsFormula = !rText.isEmpty() &&
- (rText[0] == '=' || rText[0] == '+' || rText[0] == '-');
+ bIsFormula = StartsLikeFormula(rText);
}
if ( bIsFormula )
@@ -3001,7 +3015,7 @@ static void lcl_SelectionToEnd( EditView* pView )
}
}
-void ScInputHandler::EnterHandler( ScEnterMode nBlockMode )
+void ScInputHandler::EnterHandler( ScEnterMode nBlockMode, bool bBeforeSavingInLOK )
{
if (!mbDocumentDisposing && comphelper::LibreOfficeKit::isActive()
&& pActiveViewSh != SfxViewShell::Current())
@@ -3081,6 +3095,16 @@ void ScInputHandler::EnterHandler( ScEnterMode nBlockMode )
pSelEngine->ReleaseMouse();
}
+ if (bBeforeSavingInLOK)
+ {
+ // Invalid entry but not applied to the document model.
+ // Exit to complete the "save", leaving the edit view as it is
+ // for the user to continue after save.
+ bInOwnChange = false;
+ bInEnterHandler = false;
+ return;
+ }
+
if (pData->DoError(pActiveViewSh->GetFrameWeld(), aString, aCursorPos))
bForget = true; // Do not take over input
}
@@ -3366,6 +3390,7 @@ void ScInputHandler::EnterHandler( ScEnterMode nBlockMode )
nFormSelStart = nFormSelEnd = 0;
aFormText.clear();
+ mbEditingExistingContent = false;
bInOwnChange = false;
bInEnterHandler = false;
}
@@ -3378,6 +3403,7 @@ void ScInputHandler::CancelHandler()
bModified = false;
mbPartialPrefix = false;
+ mbEditingExistingContent = false;
// Don't rely on ShowRefFrame switching the active view synchronously
// execute the function directly on the correct view's bindings instead
diff --git a/sc/source/ui/app/inputwin.cxx b/sc/source/ui/app/inputwin.cxx
index b601fc4d5c34..d44ee9769bf9 100644
--- a/sc/source/ui/app/inputwin.cxx
+++ b/sc/source/ui/app/inputwin.cxx
@@ -1798,7 +1798,8 @@ bool ScTextWnd::Command( const CommandEvent& rCEvt )
bool ScTextWnd::StartDrag()
{
- if (m_xEditView)
+ // tdf#145248 don't start a drag if actively selecting
+ if (m_xEditView && !m_xEditEngine->IsInSelectionMode())
{
OUString sSelection = m_xEditView->GetSelected();
m_xHelper->SetData(sSelection);
@@ -2362,8 +2363,7 @@ void ScPosWnd::Notify( SfxBroadcaster&, const SfxHint& rHint )
else
{
const SfxHintId nHintId = rHint.GetId();
- if (nHintId == SfxHintId::ScAreasChanged || nHintId == SfxHintId::ScNavigatorUpdateAll
- || nHintId == SfxHintId::ScTablesRenamed)
+ if (nHintId == SfxHintId::ScAreasChanged || nHintId == SfxHintId::ScNavigatorUpdateAll)
FillRangeNames();
}
}
diff --git a/sc/source/ui/app/scmod.cxx b/sc/source/ui/app/scmod.cxx
index dee33b48a509..3534ecdb69e3 100644
--- a/sc/source/ui/app/scmod.cxx
+++ b/sc/source/ui/app/scmod.cxx
@@ -1356,13 +1356,13 @@ bool ScModule::InputKeyEvent( const KeyEvent& rKEvt, bool bStartEdit )
return pHdl && pHdl->KeyInput( rKEvt, bStartEdit );
}
-void ScModule::InputEnterHandler( ScEnterMode nBlockMode )
+void ScModule::InputEnterHandler( ScEnterMode nBlockMode, bool bBeforeSavingInLOK )
{
if ( !SfxGetpApp()->IsDowning() ) // Not when quitting the program
{
ScInputHandler* pHdl = GetInputHdl();
if (pHdl)
- pHdl->EnterHandler( nBlockMode );
+ pHdl->EnterHandler( nBlockMode, bBeforeSavingInLOK );
}
}
diff --git a/sc/source/ui/cctrl/checklistmenu.cxx b/sc/source/ui/cctrl/checklistmenu.cxx
index f62b2369da27..88366b2ff0ac 100644
--- a/sc/source/ui/cctrl/checklistmenu.cxx
+++ b/sc/source/ui/cctrl/checklistmenu.cxx
@@ -283,6 +283,8 @@ void ScCheckListMenuControl::queueCloseSubMenu()
maCloseTimer.mpSubMenu = maOpenTimer.mpSubMenu;
maCloseTimer.mnMenuPos = maOpenTimer.mnMenuPos;
+ maOpenTimer.mpSubMenu = nullptr;
+ maOpenTimer.mnMenuPos = MENU_NOT_SELECTED;
maCloseTimer.maTimer.Start();
}
@@ -570,11 +572,8 @@ void ScCheckListMenuControl::GrabFocus()
}
}
-ScCheckListMenuControl::~ScCheckListMenuControl()
+void ScCheckListMenuControl::DropPendingEvents()
{
- EndPopupMode();
- for (auto& rMenuItem : maMenuItems)
- rMenuItem.mxSubMenuWin.reset();
if (mnAsyncPostPopdownId)
{
Application::RemoveUserEvent(mnAsyncPostPopdownId);
@@ -587,6 +586,14 @@ ScCheckListMenuControl::~ScCheckListMenuControl()
}
}
+ScCheckListMenuControl::~ScCheckListMenuControl()
+{
+ EndPopupMode();
+ for (auto& rMenuItem : maMenuItems)
+ rMenuItem.mxSubMenuWin.reset();
+ DropPendingEvents();
+}
+
void ScCheckListMenuControl::prepWindow()
{
mxMenu->set_size_request(-1, mxMenu->get_preferred_size().Height() + 2);
@@ -1427,6 +1434,8 @@ IMPL_LINK_NOARG(ScCheckListMenuControl, PopupModeEndHdl, weld::Popover&, void)
if (mxPopupEndAction)
mxPopupEndAction->execute();
+ DropPendingEvents();
+
if (comphelper::LibreOfficeKit::isActive())
NotifyCloseLOK();
}
diff --git a/sc/source/ui/dbgui/PivotLayoutDialog.cxx b/sc/source/ui/dbgui/PivotLayoutDialog.cxx
index 05a9428eda5e..3ea7e0121eb0 100644
--- a/sc/source/ui/dbgui/PivotLayoutDialog.cxx
+++ b/sc/source/ui/dbgui/PivotLayoutDialog.cxx
@@ -627,7 +627,8 @@ void ScPivotLayoutDialog::PushDataFieldNames(std::vector<ScDPName>& rDataFieldNa
void ScPivotLayoutDialog::Close()
{
- DoClose( ScPivotLayoutWrapper::GetChildWindowId() );
+ DoClose(ScPivotLayoutWrapper::GetChildWindowId());
+ SfxDialogController::Close();
}
IMPL_LINK_NOARG( ScPivotLayoutDialog, OKClicked, weld::Button&, void )
diff --git a/sc/source/ui/docshell/docfunc.cxx b/sc/source/ui/docshell/docfunc.cxx
index a126b0b9330b..2e1a62070511 100644
--- a/sc/source/ui/docshell/docfunc.cxx
+++ b/sc/source/ui/docshell/docfunc.cxx
@@ -3400,6 +3400,7 @@ bool ScDocFunc::DeleteTable( SCTAB nTab, bool bRecord )
SfxApplication* pSfxApp = SfxGetpApp(); // Navigator
pSfxApp->Broadcast( SfxHint( SfxHintId::ScTablesChanged ) );
+ pSfxApp->Broadcast( SfxHint( SfxHintId::ScAreasChanged ) );
pSfxApp->Broadcast( SfxHint( SfxHintId::ScDbAreasChanged ) );
pSfxApp->Broadcast( SfxHint( SfxHintId::ScAreaLinksChanged ) );
@@ -3516,7 +3517,7 @@ bool ScDocFunc::RenameTable( SCTAB nTab, const OUString& rName, bool bRecord, bo
rDocShell.PostPaintExtras();
aModificator.SetDocumentModified();
SfxGetpApp()->Broadcast( SfxHint( SfxHintId::ScTablesChanged ) );
- SfxGetpApp()->Broadcast( SfxHint( SfxHintId::ScTablesRenamed ) );
+ SfxGetpApp()->Broadcast( SfxHint( SfxHintId::ScAreasChanged ) );
bSuccess = true;
}
diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx
index 4a13484c82cf..19992e3641d5 100644
--- a/sc/source/ui/docshell/docsh.cxx
+++ b/sc/source/ui/docshell/docsh.cxx
@@ -136,6 +136,9 @@
#include <memory>
#include <vector>
+#include <svtools/sfxecode.hxx>
+#include <unotools/pathoptions.hxx>
+
using namespace com::sun::star;
using ::com::sun::star::uno::Reference;
using ::com::sun::star::lang::XMultiServiceFactory;
@@ -1789,6 +1792,17 @@ bool ScDocShell::SaveAs( SfxMedium& rMedium )
bNeedsRehash = ScPassHashHelper::needsPassHashRegen(m_aDocument, PASSHASH_SHA256);
}
+ // skip saving recovery file instead of showing re-type password dialog window
+ if ( bNeedsRehash && rMedium.GetFilter()->GetFilterName() == "calc8" &&
+ // it seems, utl::MediaDescriptor::PROP_AUTOSAVEEVENT is true at Save As, too,
+ // so check the backup path
+ rMedium.GetName().startsWith( SvtPathOptions().GetBackupPath() ) )
+ {
+ SAL_WARN("sc.filter", "Should re-type password for own format, won't export recovery file");
+ rMedium.SetError(ERRCODE_SFX_WRONGPASSWORD);
+ return false;
+ }
+
if (pViewShell && bNeedsRehash)
{
if (!pViewShell->ExecuteRetypePassDlg(PASSHASH_SHA1))
diff --git a/sc/source/ui/docshell/externalrefmgr.cxx b/sc/source/ui/docshell/externalrefmgr.cxx
index 472872db7359..2e3df2f54a23 100644
--- a/sc/source/ui/docshell/externalrefmgr.cxx
+++ b/sc/source/ui/docshell/externalrefmgr.cxx
@@ -3080,6 +3080,14 @@ void ScExternalRefManager::setFilterData(sal_uInt16 nFileId, const OUString& rFi
void ScExternalRefManager::clear()
{
+ for (auto& rEntry : maLinkListeners)
+ {
+ for (auto& it : rEntry.second)
+ {
+ it->notify(0, OH_NO_WE_ARE_GOING_TO_DIE);
+ }
+ }
+
for (auto& rEntry : maDocShells)
rEntry.second.maShell->DoClose();
diff --git a/sc/source/ui/docshell/impex.cxx b/sc/source/ui/docshell/impex.cxx
index 5d8e755c18f6..5bd8052e0bec 100644
--- a/sc/source/ui/docshell/impex.cxx
+++ b/sc/source/ui/docshell/impex.cxx
@@ -1616,40 +1616,55 @@ bool ScImportExport::ExtText2Doc( SvStream& rStrm )
bool bMultiLine = false;
if ( bFixed ) // Fixed line length
{
- sal_Int32 nStartIdx = 0;
- // Yes, the check is nCol<=rDoc.MaxCol()+1, +1 because it is only an
- // overflow if there is really data following to be put behind
- // the last column, which doesn't happen if info is
- // SC_COL_SKIP.
- for ( i=0; i<nInfoCount && nCol <= rDoc.MaxCol()+1; i++ )
+ if (bDetermineRange)
{
- sal_uInt8 nFmt = pColFormat[i];
- if (nFmt != SC_COL_SKIP) // otherwise don't increment nCol either
+ // Yes, the check is nCol<=rDoc.MaxCol()+1, +1 because it
+ // is only an overflow if there is really data following to
+ // be put behind the last column, which doesn't happen if
+ // info is SC_COL_SKIP.
+ for (i=0; i < nInfoCount && nCol <= rDoc.MaxCol()+1; ++i)
{
- if (nCol > rDoc.MaxCol())
- bOverflowCol = true; // display warning on import
- else if (!bDetermineRange)
+ const sal_uInt8 nFmt = pColFormat[i];
+ if (nFmt != SC_COL_SKIP) // otherwise don't increment nCol either
{
- sal_Int32 nNextIdx = nStartIdx;
- if ( i + 1 < nInfoCount )
- CountVisualWidth( aLine, nNextIdx, pColStart[i+1] - pColStart[i] );
+ if (nCol > rDoc.MaxCol())
+ bOverflowCol = true; // display warning on import
+ ++nCol;
+ }
+ }
+ }
+ else
+ {
+ sal_Int32 nStartIdx = 0;
+ // Same maxcol+1 check reason as above.
+ for (i=0; i < nInfoCount && nCol <= rDoc.MaxCol()+1; ++i)
+ {
+ sal_Int32 nNextIdx = nStartIdx;
+ if (i + 1 < nInfoCount)
+ CountVisualWidth( aLine, nNextIdx, pColStart[i+1] - pColStart[i] );
+ else
+ nNextIdx = nLineLen;
+ sal_uInt8 nFmt = pColFormat[i];
+ if (nFmt != SC_COL_SKIP) // otherwise don't increment nCol either
+ {
+ if (nCol > rDoc.MaxCol())
+ bOverflowCol = true; // display warning on import
else
- nNextIdx = nLineLen;
-
- bool bIsQuoted = false;
- aCell = lcl_GetFixed( aLine, nStartIdx, nNextIdx, bIsQuoted, bOverflowCell );
- if (bIsQuoted && bQuotedAsText)
- nFmt = SC_COL_TEXT;
-
- bMultiLine |= lcl_PutString(
- aDocImport, !mbOverwriting, nCol, nRow, nTab, aCell, nFmt,
- &aNumFormatter, bDetectNumFormat, bEvaluateFormulas, bSkipEmptyCells,
- aTransliteration, aCalendar,
- pEnglishTransliteration.get(), pEnglishCalendar.get());
-
- nStartIdx = nNextIdx;
+ {
+ bool bIsQuoted = false;
+ aCell = lcl_GetFixed( aLine, nStartIdx, nNextIdx, bIsQuoted, bOverflowCell );
+ if (bIsQuoted && bQuotedAsText)
+ nFmt = SC_COL_TEXT;
+
+ bMultiLine |= lcl_PutString(
+ aDocImport, !mbOverwriting, nCol, nRow, nTab, aCell, nFmt,
+ &aNumFormatter, bDetectNumFormat, bEvaluateFormulas, bSkipEmptyCells,
+ aTransliteration, aCalendar,
+ pEnglishTransliteration.get(), pEnglishCalendar.get());
+ }
+ ++nCol;
}
- ++nCol;
+ nStartIdx = nNextIdx;
}
}
}
@@ -1766,10 +1781,41 @@ void ScImportExport::EmbeddedNullTreatment( OUString & rStr )
// The normal case is no embedded NULL, check first before de-/allocating
// ustring stuff.
- sal_Unicode cNull = 0;
- if (rStr.indexOf( cNull) >= 0)
+ const sal_Unicode cNull = 0;
+ sal_Int32 i;
+ if ((i = rStr.indexOf( cNull)) >= 0)
{
- rStr = rStr.replaceAll( std::u16string_view( &cNull, 1), "");
+ // Do not use OUString::replaceAll(...,""), in case of repeated null
+ // bytes that reallocates for each and for massive amounts takes
+ // ~endless. See tdf#147421 with 3577016 trailing null-bytes.
+ const sal_Int32 nLen = rStr.getLength();
+ OUStringBuffer aBuf( nLen);
+ sal_Int32 s = 0;
+ sal_Unicode const * const p = rStr.getStr();
+ do
+ {
+ // Append good substring.
+ aBuf.append( p + s, i - s);
+ // Skip all cNull.
+ while (++i < nLen && *(p+i) == cNull)
+ ;
+ // Find next cNull after good if characters left, else end.
+ if (i < nLen)
+ {
+ s = i;
+ i = rStr.indexOf( cNull, i);
+ }
+ else
+ {
+ s = nLen;
+ }
+ }
+ while (0 <= i && i < nLen);
+ // Append good trailing substring, if any.
+ if (s < nLen)
+ aBuf.append( p + s, nLen - s);
+
+ rStr = aBuf.makeStringAndClear();
}
}
@@ -2294,7 +2340,7 @@ bool ScImportExport::Sylk2Doc( SvStream& rStrm )
aFormats.push_back( nKey );
}
}
- else if( cTag == 'I' && *p == 'D' )
+ else if (cTag == 'I' && *p == 'D' && aLine.getLength() > 4)
{
aLine = aLine.copy(4);
if (aLine == "CALCOOO32")
diff --git a/sc/source/ui/inc/checklistmenu.hxx b/sc/source/ui/inc/checklistmenu.hxx
index 961fddceac58..8d135870d871 100644
--- a/sc/source/ui/inc/checklistmenu.hxx
+++ b/sc/source/ui/inc/checklistmenu.hxx
@@ -254,6 +254,8 @@ private:
DECL_LINK(SetDropdownPosHdl, void*, void);
+ void DropPendingEvents();
+
private:
std::unique_ptr<weld::Builder> mxBuilder;
std::unique_ptr<weld::Popover> mxPopover;
diff --git a/sc/source/ui/inc/inputhdl.hxx b/sc/source/ui/inc/inputhdl.hxx
index fb3880e97a69..88ec1dd81adc 100644
--- a/sc/source/ui/inc/inputhdl.hxx
+++ b/sc/source/ui/inc/inputhdl.hxx
@@ -105,6 +105,7 @@ private:
bool mbDocumentDisposing:1;
/// To indicate if there is a partial prefix completion.
bool mbPartialPrefix:1;
+ bool mbEditingExistingContent:1;
sal_uLong nValidation;
SvxCellHorJustify eAttrAdjust;
@@ -146,6 +147,7 @@ private:
bool StartTable( sal_Unicode cTyped, bool bFromCommand, bool bInputActivated,
ScEditEngineDefaulter* pTopEngine );
void RemoveSelection();
+ bool StartsLikeFormula( std::u16string_view rStr ) const;
void UpdateFormulaMode();
static void InvalidateAttribs();
void ImplCreateEditEngine();
@@ -198,7 +200,7 @@ public:
void MergeLanguageAttributes( ScEditEngineDefaulter& rDestEngine ) const;
bool KeyInput( const KeyEvent& rKEvt, bool bStartEdit );
- void EnterHandler( ScEnterMode nBlockMode = ScEnterMode::NORMAL );
+ void EnterHandler( ScEnterMode nBlockMode = ScEnterMode::NORMAL, bool bBeforeSavingInLOK = false );
void CancelHandler();
void SetReference( const ScRange& rRef, const ScDocument& rDoc );
void AddRefEntry();
diff --git a/sc/source/ui/inc/undoblk.hxx b/sc/source/ui/inc/undoblk.hxx
index 39dba0afa20d..a0de06cb698d 100644
--- a/sc/source/ui/inc/undoblk.hxx
+++ b/sc/source/ui/inc/undoblk.hxx
@@ -163,14 +163,14 @@ private:
struct ScUndoPasteOptions
{
ScPasteFunc nFunction;
- bool bSkipEmpty;
+ bool bSkipEmptyCells;
bool bTranspose;
bool bAsLink;
InsCellCmd eMoveMode;
ScUndoPasteOptions() :
nFunction( ScPasteFunc::NONE ),
- bSkipEmpty( false ),
+ bSkipEmptyCells( false ),
bTranspose( false ),
bAsLink( false ),
eMoveMode( INS_NONE )
diff --git a/sc/source/ui/inc/viewfunc.hxx b/sc/source/ui/inc/viewfunc.hxx
index ec037cc18e71..80b9b090bcad 100644
--- a/sc/source/ui/inc/viewfunc.hxx
+++ b/sc/source/ui/inc/viewfunc.hxx
@@ -116,12 +116,14 @@ public:
bool CopyToClipMultiRange( const ScDocument* pClipDoc, const ScRangeList& rRanges, bool bCut,
bool bApi, bool bIncludeObjects );
rtl::Reference<ScTransferObj> CopyToTransferable();
- SC_DLLPUBLIC bool PasteFromClip( InsertDeleteFlags nFlags, ScDocument* pClipDoc,
- ScPasteFunc nFunction = ScPasteFunc::NONE, bool bSkipEmpty = false,
- bool bTranspose = false, bool bAsLink = false,
- InsCellCmd eMoveMode = INS_NONE,
- InsertDeleteFlags nUndoExtraFlags = InsertDeleteFlags::NONE,
- bool bAllowDialogs = false );
+
+ SC_DLLPUBLIC bool PasteFromClip(
+ InsertDeleteFlags nFlags, ScDocument* pClipDoc,
+ ScPasteFunc nFunction = ScPasteFunc::NONE, bool bSkipEmptyCells = false,
+ bool bTranspose = false, bool bAsLink = false,
+ InsCellCmd eMoveMode = INS_NONE,
+ InsertDeleteFlags nUndoExtraFlags = InsertDeleteFlags::NONE,
+ bool bAllowDialogs = false );
void FillTab( InsertDeleteFlags nFlags, ScPasteFunc nFunction, bool bSkipEmpty, bool bAsLink );
@@ -352,14 +354,16 @@ private:
void PasteRTF( SCCOL nCol, SCROW nStartRow,
const css::uno::Reference< css::datatransfer::XTransferable >& rxTransferable );
- bool PasteMultiRangesFromClip(InsertDeleteFlags nFlags, ScDocument* pClipDoc,
- ScPasteFunc nFunction, bool bSkipEmpty, bool bIncludeFiltered,
- bool bTranspose, bool bAsLink, bool bAllowDialogs,
- InsCellCmd eMoveMode, InsertDeleteFlags nUndoFlags);
+ bool PasteMultiRangesFromClip(
+ InsertDeleteFlags nFlags, ScDocument* pClipDoc,
+ ScPasteFunc nFunction, bool bSkipEmptyCells, bool bIncludeFiltered,
+ bool bTranspose, bool bAsLink, bool bAllowDialogs,
+ InsCellCmd eMoveMode, InsertDeleteFlags nUndoFlags );
- bool PasteFromClipToMultiRanges( InsertDeleteFlags nFlags, ScDocument* pClipDoc, ScPasteFunc nFunction,
- bool bSkipEmpty, bool bTranspose, bool bAsLink, bool bAllowDialogs,
- InsCellCmd eMoveMode, InsertDeleteFlags nUndoFlags );
+ bool PasteFromClipToMultiRanges(
+ InsertDeleteFlags nFlags, ScDocument* pClipDoc, ScPasteFunc nFunction,
+ bool bSkipEmptyCells, bool bTranspose, bool bAsLink, bool bAllowDialogs,
+ InsCellCmd eMoveMode, InsertDeleteFlags nUndoFlags );
void PostPasteFromClip(const ScRangeList& rPasteRanges, const ScMarkData& rMark);
diff --git a/sc/source/ui/miscdlgs/sharedocdlg.cxx b/sc/source/ui/miscdlgs/sharedocdlg.cxx
index ec019fb70655..294a69e93c2b 100644
--- a/sc/source/ui/miscdlgs/sharedocdlg.cxx
+++ b/sc/source/ui/miscdlgs/sharedocdlg.cxx
@@ -39,7 +39,7 @@ using namespace ::com::sun::star;
IMPL_LINK(ScShareDocumentDlg, SizeAllocated, const Size&, rSize, void)
{
- OUString sWidestAccessString = getWidestTime(ScGlobal::getLocaleData());
+ OUString sWidestAccessString = getWidestDateTime(ScGlobal::getLocaleData(), false);
const int nAccessWidth = m_xLbUsers->get_pixel_size(sWidestAccessString).Width() * 2;
std::vector<int> aWidths
{
@@ -151,7 +151,7 @@ void ScShareDocumentDlg::UpdateView()
tools::Time aTime( nHours, nMinutes );
DateTime aDateTime( aDate, aTime );
- OUString aString = formatTime(aDateTime, ScGlobal::getLocaleData());
+ OUString aString = formatDateTime(aDateTime, ScGlobal::getLocaleData(), false);
m_xLbUsers->append_text(aUser);
m_xLbUsers->set_text(m_xLbUsers->n_children() - 1, aString, 1);
@@ -201,7 +201,7 @@ void ScShareDocumentDlg::UpdateView()
util::DateTime uDT(xDocProps->getModificationDate());
DateTime aDateTime(uDT);
- OUString aString = formatTime(aDateTime, ScGlobal::getLocaleData()) + " " +
+ OUString aString = formatDateTime(aDateTime, ScGlobal::getLocaleData(), false) + " " +
ScGlobal::getLocaleData().getTime( aDateTime, false );
m_xLbUsers->append_text(aUser);
diff --git a/sc/source/ui/undo/undoblk.cxx b/sc/source/ui/undo/undoblk.cxx
index 26841c009eb2..be93e37bd35f 100644
--- a/sc/source/ui/undo/undoblk.cxx
+++ b/sc/source/ui/undo/undoblk.cxx
@@ -1177,7 +1177,7 @@ void ScUndoPaste::Repeat(SfxRepeatTarget& rTarget)
if (pOwnClip)
{
pViewSh->PasteFromClip( nFlags, pOwnClip->GetDocument(),
- aPasteOptions.nFunction, aPasteOptions.bSkipEmpty, aPasteOptions.bTranspose,
+ aPasteOptions.nFunction, aPasteOptions.bSkipEmptyCells, aPasteOptions.bTranspose,
aPasteOptions.bAsLink, aPasteOptions.eMoveMode, InsertDeleteFlags::NONE,
true ); // allow warning dialog
}
diff --git a/sc/source/ui/undo/undotab.cxx b/sc/source/ui/undo/undotab.cxx
index 467e93cb7145..a4000a12863a 100644
--- a/sc/source/ui/undo/undotab.cxx
+++ b/sc/source/ui/undo/undotab.cxx
@@ -363,6 +363,7 @@ void ScUndoDeleteTab::Undo()
}
SfxApplication* pSfxApp = SfxGetpApp(); // Navigator
pSfxApp->Broadcast( SfxHint( SfxHintId::ScTablesChanged ) );
+ pSfxApp->Broadcast( SfxHint( SfxHintId::ScAreasChanged ) );
pSfxApp->Broadcast( SfxHint( SfxHintId::ScDbAreasChanged ) );
pSfxApp->Broadcast( SfxHint( SfxHintId::ScAreaLinksChanged ) );
@@ -433,7 +434,7 @@ void ScUndoRenameTab::DoChange( SCTAB nTabP, const OUString& rName ) const
rDoc.RenameTab( nTabP, rName );
SfxGetpApp()->Broadcast( SfxHint( SfxHintId::ScTablesChanged ) ); // Navigator
- SfxGetpApp()->Broadcast( SfxHint( SfxHintId::ScTablesRenamed ) ); // Name Box
+ SfxGetpApp()->Broadcast( SfxHint( SfxHintId::ScAreasChanged ) ); // Also Name Box
pDocShell->PostPaintGridAll();
pDocShell->PostPaintExtras();
@@ -597,7 +598,9 @@ void ScUndoCopyTab::DoChange() const
if (pViewShell)
pViewShell->SetTabNo((*mpOldTabs)[0],true);
- SfxGetpApp()->Broadcast( SfxHint( SfxHintId::ScTablesChanged ) ); // Navigator
+ SfxApplication* pSfxApp = SfxGetpApp(); // Navigator
+ pSfxApp->Broadcast( SfxHint( SfxHintId::ScTablesChanged ) );
+ pSfxApp->Broadcast( SfxHint( SfxHintId::ScAreasChanged ) );
pDocShell->PostPaintGridAll();
pDocShell->PostPaintExtras();
diff --git a/sc/source/ui/unoobj/cellsuno.cxx b/sc/source/ui/unoobj/cellsuno.cxx
index 622307974a75..566a989ecafc 100644
--- a/sc/source/ui/unoobj/cellsuno.cxx
+++ b/sc/source/ui/unoobj/cellsuno.cxx
@@ -6721,7 +6721,9 @@ uno::Reference<sheet::XSheetCellCursor> SAL_CALL ScTableSheetObj::createCursorBy
if (pRangesImp)
{
const ScRangeList& rRanges = pRangesImp->GetRangeList();
- OSL_ENSURE( rRanges.size() == 1, "Range? Ranges?" );
+ SAL_WARN_IF( rRanges.size() != 1, "sc", "ScTableSheetObj::createCursorByRange: Range? Ranges?");
+ if (rRanges.empty())
+ return nullptr;
return new ScCellCursorObj( pDocSh, rRanges[ 0 ] );
}
}
diff --git a/sc/source/ui/unoobj/chart2uno.cxx b/sc/source/ui/unoobj/chart2uno.cxx
index 40e72bbfc8d9..f15ceb2722a2 100644
--- a/sc/source/ui/unoobj/chart2uno.cxx
+++ b/sc/source/ui/unoobj/chart2uno.cxx
@@ -2915,6 +2915,9 @@ void ScChart2DataSequence::ExternalRefListener::notify(sal_uInt16 nFileId, ScExt
case ScExternalRefManager::LINK_BROKEN:
maFileIds.erase(nFileId);
break;
+ case ScExternalRefManager::OH_NO_WE_ARE_GOING_TO_DIE:
+ mpDoc = nullptr;
+ break;
}
}
diff --git a/sc/source/ui/unoobj/listenercalls.cxx b/sc/source/ui/unoobj/listenercalls.cxx
index 2d9a23083ca8..7ff7c7df0956 100644
--- a/sc/source/ui/unoobj/listenercalls.cxx
+++ b/sc/source/ui/unoobj/listenercalls.cxx
@@ -44,7 +44,7 @@ void ScUnoListenerCalls::ExecuteAndClear()
// During each modified() call, Add may be called again.
// These new calls are executed here, too.
- std::vector<ScUnoListenerEntry>::iterator aItr(aEntries.begin());
+ std::list<ScUnoListenerEntry>::iterator aItr(aEntries.begin());
while (aItr != aEntries.end())
{
ScUnoListenerEntry aEntry = *aItr;
diff --git a/sc/source/ui/vba/excelvbahelper.cxx b/sc/source/ui/vba/excelvbahelper.cxx
index d337a0f6836e..37d3a5fcf1de 100644
--- a/sc/source/ui/vba/excelvbahelper.cxx
+++ b/sc/source/ui/vba/excelvbahelper.cxx
@@ -210,25 +210,28 @@ void implnPasteSpecial( const uno::Reference< frame::XModel>& xModel, InsertDele
{
PasteCellsWarningReseter resetWarningBox;
- ScTabViewShell* pTabViewShell = getBestViewShell( xModel );
- ScDocShell* pDocShell = getDocShell( xModel );
- if ( !(pTabViewShell && pDocShell) )
+ ScTabViewShell* pTabViewShell = getBestViewShell(xModel);
+ if (!pTabViewShell)
+ return;
+
+ ScDocShell* pDocShell = getDocShell(xModel);
+ if (!pDocShell)
return;
ScViewData& rView = pTabViewShell->GetViewData();
vcl::Window* pWin = rView.GetActiveWin();
- if (pWin)
+ if (!pWin)
+ return;
+
+ const ScTransferObj* pOwnClip = ScTransferObj::GetOwnClipboard(ScTabViewShell::GetClipData(pWin));
+ if (pOwnClip)
{
- const ScTransferObj* pOwnClip = ScTransferObj::GetOwnClipboard(pDocShell->GetClipData());
- ScDocument* pDoc = nullptr;
- if ( pOwnClip )
- pDoc = pOwnClip->GetDocument();
- pTabViewShell->PasteFromClip( nFlags, pDoc,
+ pTabViewShell->PasteFromClip(nFlags, pOwnClip->GetDocument(),
nFunction, bSkipEmpty, bTranspose, false,
- INS_NONE, InsertDeleteFlags::NONE, true );
+ INS_NONE, InsertDeleteFlags::NONE, true);
+
pTabViewShell->CellContentChanged();
}
-
}
ScDocShell*
diff --git a/sc/source/ui/vba/vbarange.cxx b/sc/source/ui/vba/vbarange.cxx
index 1cb307133cf7..351cbdc60a75 100644
--- a/sc/source/ui/vba/vbarange.cxx
+++ b/sc/source/ui/vba/vbarange.cxx
@@ -871,15 +871,18 @@ protected:
ScCellRangesBase* pUnoRangesBase = dynamic_cast< ScCellRangesBase* >( xIf.get() );
if ( pUnoRangesBase )
{
- ScRangeList aCellRanges = pUnoRangesBase->GetRangeList();
- ScCompiler aCompiler( m_rDoc, aCellRanges.front().aStart, m_eGrammar );
- // compile the string in the format passed in
- std::unique_ptr<ScTokenArray> pArray(aCompiler.CompileString(sFormula));
- // convert to API grammar
- aCompiler.SetGrammar( formula::FormulaGrammar::GRAM_API );
- OUString sConverted;
- aCompiler.CreateStringFromTokenArray(sConverted);
- sFormula = EQUALS + sConverted;
+ const ScRangeList& rCellRanges = pUnoRangesBase->GetRangeList();
+ if (!rCellRanges.empty())
+ {
+ ScCompiler aCompiler( m_rDoc, rCellRanges.front().aStart, m_eGrammar );
+ // compile the string in the format passed in
+ std::unique_ptr<ScTokenArray> pArray(aCompiler.CompileString(sFormula));
+ // convert to API grammar
+ aCompiler.SetGrammar( formula::FormulaGrammar::GRAM_API );
+ OUString sConverted;
+ aCompiler.CreateStringFromTokenArray(sConverted);
+ sFormula = EQUALS + sConverted;
+ }
}
}
@@ -917,16 +920,19 @@ public:
{
OUString sVal;
aValue >>= sVal;
- ScRangeList aCellRanges = pUnoRangesBase->GetRangeList();
- // Compile string from API grammar.
- ScCompiler aCompiler( m_rDoc, aCellRanges.front().aStart, formula::FormulaGrammar::GRAM_API );
- std::unique_ptr<ScTokenArray> pArray(aCompiler.CompileString(sVal));
- // Convert to desired grammar.
- aCompiler.SetGrammar( m_eGrammar );
- OUString sConverted;
- aCompiler.CreateStringFromTokenArray(sConverted);
- sVal = EQUALS + sConverted;
- aValue <<= sVal;
+ const ScRangeList& rCellRanges = pUnoRangesBase->GetRangeList();
+ if (!rCellRanges.empty())
+ {
+ // Compile string from API grammar.
+ ScCompiler aCompiler( m_rDoc, rCellRanges.front().aStart, formula::FormulaGrammar::GRAM_API );
+ std::unique_ptr<ScTokenArray> pArray(aCompiler.CompileString(sVal));
+ // Convert to desired grammar.
+ aCompiler.SetGrammar( m_eGrammar );
+ OUString sConverted;
+ aCompiler.CreateStringFromTokenArray(sConverted);
+ sVal = EQUALS + sConverted;
+ aValue <<= sVal;
+ }
}
}
@@ -1279,9 +1285,12 @@ uno::Reference< sheet::XSheetCellRange > lclExpandToMerged( const uno::Reference
{
aOldAddress = aNewAddress;
uno::Reference< sheet::XSheetCellCursor > xCursor( xSheet->createCursorByRange( xNewCellRange ), uno::UNO_SET_THROW );
- xCursor->collapseToMergedArea();
- xNewCellRange.set( xCursor, uno::UNO_QUERY_THROW );
- aNewAddress = lclGetRangeAddress( xNewCellRange );
+ if (xCursor.is())
+ {
+ xCursor->collapseToMergedArea();
+ xNewCellRange.set( xCursor, uno::UNO_QUERY_THROW );
+ aNewAddress = lclGetRangeAddress( xNewCellRange );
+ }
}
while( bRecursive && (aOldAddress != aNewAddress) );
return xNewCellRange;
@@ -1913,7 +1922,8 @@ ScVbaRange::Offset( const ::uno::Any &nRowOff, const uno::Any &nColOff )
return new ScVbaRange( mxParent, mxContext, xRanges );
}
// normal range
- uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( pUnoRangesBase->GetDocShell(), aCellRanges.front() ) );
+ const ScRange aRange( obtainRangeEvenIfRangeListIsEmpty( aCellRanges));
+ uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( pUnoRangesBase->GetDocShell(), aRange));
return new ScVbaRange( mxParent, mxContext, xRange );
}
@@ -2364,17 +2374,28 @@ ScVbaRange::Activate()
}
+ScRange ScVbaRange::obtainRangeEvenIfRangeListIsEmpty( const ScRangeList& rCellRanges ) const
+{
+ // XXX It may be that using the current range list was never correct, but
+ // always the initial sheet range would be instead, history is unclear.
+
+ if (!rCellRanges.empty())
+ return rCellRanges.front();
+
+ table::CellRangeAddress aRA( lclGetRangeAddress( mxRange ));
+ return ScRange( aRA.StartColumn, aRA.StartRow, aRA.Sheet, aRA.EndColumn, aRA.EndRow, aRA.Sheet);
+}
+
uno::Reference< excel::XRange >
ScVbaRange::Rows(const uno::Any& aIndex )
{
if ( aIndex.hasValue() )
{
- sal_Int32 nValue = 0;
ScCellRangesBase* pUnoRangesBase = getCellRangesBase();
- ScRangeList aCellRanges = pUnoRangesBase->GetRangeList();
- OUString sAddress;
+ ScRange aRange( obtainRangeEvenIfRangeListIsEmpty( pUnoRangesBase->GetRangeList()));
- ScRange aRange = aCellRanges.front();
+ sal_Int32 nValue = 0;
+ OUString sAddress;
if( aIndex >>= nValue )
{
aRange.aStart.SetRow( aRange.aStart.Row() + --nValue );
@@ -2410,9 +2431,8 @@ uno::Reference< excel::XRange >
ScVbaRange::Columns(const uno::Any& aIndex )
{
ScCellRangesBase* pUnoRangesBase = getCellRangesBase();
- ScRangeList aCellRanges = pUnoRangesBase->GetRangeList();
+ ScRange aRange( obtainRangeEvenIfRangeListIsEmpty( pUnoRangesBase->GetRangeList()));
- ScRange aRange = aCellRanges.front();
if ( aIndex.hasValue() )
{
OUString sAddress;
@@ -2534,7 +2554,9 @@ ScVbaRange::Copy(const ::uno::Any& Destination)
}
else
{
- excel::implnCopy( getUnoModel() );
+ uno::Reference<frame::XModel> xModel = getModelFromRange(mxRange);
+ Select();
+ excel::implnCopy(getUnoModel());
}
}
@@ -2892,7 +2914,8 @@ ScVbaRange::PasteSpecial( const uno::Any& Paste, const uno::Any& Operation, cons
InsertDeleteFlags nFlags = getPasteFlags(nPaste);
ScPasteFunc nFormulaBits = getPasteFormulaBits(nOperation);
- excel::implnPasteSpecial(pShell->GetModel(), nFlags,nFormulaBits,bSkipBlanks,bTranspose);
+
+ excel::implnPasteSpecial(xModel, nFlags, nFormulaBits, bSkipBlanks, bTranspose);
}
uno::Reference< excel::XRange >
@@ -2923,7 +2946,8 @@ ScVbaRange::getEntireColumnOrRow( bool bColumn )
return new ScVbaRange( mxParent, mxContext, xRanges, !bColumn, bColumn );
}
- uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( pUnoRangesBase->GetDocShell(), aCellRanges.front() ) );
+ const ScRange aRange( obtainRangeEvenIfRangeListIsEmpty( aCellRanges));
+ uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( pUnoRangesBase->GetDocShell(), aRange));
return new ScVbaRange( mxParent, mxContext, xRange, !bColumn, bColumn );
}
@@ -3409,9 +3433,9 @@ ScVbaRange::Sort( const uno::Any& Key1, const uno::Any& Order1, const uno::Any&
// set up defaults
- sal_Int16 nOrder1 = aSortParam.maKeyState[1].bAscending ? excel::XlSortOrder::xlAscending : excel::XlSortOrder::xlDescending;
- sal_Int16 nOrder2 = aSortParam.maKeyState[2].bAscending ? excel::XlSortOrder::xlAscending : excel::XlSortOrder::xlDescending;
- sal_Int16 nOrder3 = aSortParam.maKeyState[3].bAscending ? excel::XlSortOrder::xlAscending : excel::XlSortOrder::xlDescending;
+ sal_Int16 nOrder1 = aSortParam.maKeyState[0].bAscending ? excel::XlSortOrder::xlAscending : excel::XlSortOrder::xlDescending;
+ sal_Int16 nOrder2 = aSortParam.maKeyState[1].bAscending ? excel::XlSortOrder::xlAscending : excel::XlSortOrder::xlDescending;
+ sal_Int16 nOrder3 = aSortParam.maKeyState[2].bAscending ? excel::XlSortOrder::xlAscending : excel::XlSortOrder::xlDescending;
sal_Int16 nCustom = aSortParam.nUserIndex;
sal_Int16 nSortMethod = excel::XlSortMethod::xlPinYin;
diff --git a/sc/source/ui/vba/vbarange.hxx b/sc/source/ui/vba/vbarange.hxx
index 2e9b71746879..cdeab983fa6d 100644
--- a/sc/source/ui/vba/vbarange.hxx
+++ b/sc/source/ui/vba/vbarange.hxx
@@ -119,6 +119,9 @@ class ScVbaRange : public ScVbaRange_BASE
/** Fires a Worksheet_Change event for this range or range list. */
void fireChangeEvent();
+ /// @throws css::uno::RuntimeException
+ ScRange obtainRangeEvenIfRangeListIsEmpty( const ScRangeList& rCellRanges ) const;
+
protected:
virtual ScCellRangesBase* getCellRangesBase() override;
/// @throws css::uno::RuntimeException
diff --git a/sc/source/ui/vba/vbaworkbooks.cxx b/sc/source/ui/vba/vbaworkbooks.cxx
index bd52292cfa5a..e3b608b33942 100644
--- a/sc/source/ui/vba/vbaworkbooks.cxx
+++ b/sc/source/ui/vba/vbaworkbooks.cxx
@@ -144,9 +144,14 @@ ScVbaWorkbooks::Add( const uno::Any& Template )
// need to set up the document modules ( and vba mode ) here
excel::setUpDocumentModules( xSpreadDoc );
- if( xSpreadDoc.is() )
- return getWorkbook( mxContext, xSpreadDoc, mxParent );
- return uno::Any();
+ if (!xSpreadDoc.is())
+ return uno::Any();
+
+ uno::Any aRet = getWorkbook( mxContext, xSpreadDoc, mxParent );
+ uno::Reference< excel::XWorkbook > xWBook( aRet, uno::UNO_QUERY );
+ if (xWBook.is())
+ xWBook->Activate();
+ return aRet;
}
void SAL_CALL
diff --git a/sc/source/ui/view/cellsh2.cxx b/sc/source/ui/view/cellsh2.cxx
index 0bed3b16141f..8ff829326597 100644
--- a/sc/source/ui/view/cellsh2.cxx
+++ b/sc/source/ui/view/cellsh2.cxx
@@ -526,6 +526,55 @@ void ScCellShell::ExecuteDB( SfxRequest& rReq )
// subtotal when needed new
pTabViewShell->UISort( rOutParam );
+
+ SfxViewFrame* pViewFrm = pTabViewShell->GetViewFrame();
+ if (pViewFrm)
+ {
+ SfxRequest aRequest(pViewFrm, SID_SORT);
+
+ if ( rOutParam.bInplace )
+ {
+ aRequest.AppendItem( SfxBoolItem( SID_SORT_BYROW,
+ rOutParam.bByRow ) );
+ aRequest.AppendItem( SfxBoolItem( SID_SORT_HASHEADER,
+ rOutParam.bHasHeader ) );
+ aRequest.AppendItem( SfxBoolItem( SID_SORT_CASESENS,
+ rOutParam.bCaseSens ) );
+ aRequest.AppendItem( SfxBoolItem( SID_SORT_NATURALSORT,
+ rOutParam.bNaturalSort ) );
+ aRequest.AppendItem( SfxBoolItem( SID_SORT_INCCOMMENTS,
+ rOutParam.aDataAreaExtras.mbCellNotes ) );
+ aRequest.AppendItem( SfxBoolItem( SID_SORT_INCIMAGES,
+ rOutParam.aDataAreaExtras.mbCellDrawObjects ) );
+ aRequest.AppendItem( SfxBoolItem( SID_SORT_ATTRIBS,
+ rOutParam.aDataAreaExtras.mbCellFormats ) );
+ sal_uInt16 nUser = rOutParam.bUserDef ? ( rOutParam.nUserIndex + 1 ) : 0;
+ aRequest.AppendItem( SfxUInt16Item( SID_SORT_USERDEF, nUser ) );
+ if ( rOutParam.maKeyState[0].bDoSort )
+ {
+ aRequest.AppendItem( SfxInt32Item( FN_PARAM_1,
+ rOutParam.maKeyState[0].nField + 1 ) );
+ aRequest.AppendItem( SfxBoolItem( FN_PARAM_2,
+ rOutParam.maKeyState[0].bAscending ) );
+ }
+ if ( rOutParam.maKeyState[1].bDoSort )
+ {
+ aRequest.AppendItem( SfxInt32Item( FN_PARAM_3,
+ rOutParam.maKeyState[1].nField + 1 ) );
+ aRequest.AppendItem( SfxBoolItem( FN_PARAM_4,
+ rOutParam.maKeyState[1].bAscending ) );
+ }
+ if ( rOutParam.maKeyState[2].bDoSort )
+ {
+ aRequest.AppendItem( SfxInt32Item( FN_PARAM_5,
+ rOutParam.maKeyState[2].nField + 1 ) );
+ aRequest.AppendItem( SfxBoolItem( FN_PARAM_6,
+ rOutParam.maKeyState[2].bAscending ) );
+ }
+ }
+
+ aRequest.Done();
+ }
}
else
{
diff --git a/sc/source/ui/view/editsh.cxx b/sc/source/ui/view/editsh.cxx
index c7e7dabd1ee5..ba0abdc433c4 100644
--- a/sc/source/ui/view/editsh.cxx
+++ b/sc/source/ui/view/editsh.cxx
@@ -526,6 +526,7 @@ void ScEditShell::Execute( SfxRequest& rReq )
case SID_TOGGLE_REL:
{
+ /* TODO: MLFORMULA: this should work also with multi-line formulas. */
if (pEngine->GetParagraphCount() == 1)
{
OUString aText = pEngine->GetText();
diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx
index 42b02d4b9743..f41d7b580a01 100644
--- a/sc/source/ui/view/gridwin.cxx
+++ b/sc/source/ui/view/gridwin.cxx
@@ -475,6 +475,7 @@ IMPL_LINK_NOARG(ScGridWindow, PopupModeEndHdl, weld::Popover&, void)
mpFilterBox->SetCancelled(); // cancel select
// restore the mouse capture state of the GridWindow to
// what it was at initial popup time
+ SAL_WARN_IF(bMouseWasCaptured, "sc.ui", "Is there a scenario where the mouse was captured before mouse down?");
if (bMouseWasCaptured)
CaptureMouse();
}
@@ -524,6 +525,7 @@ public:
virtual bool execute() override
{
mpWindow->RefreshAutoFilterButton(maPos);
+ mpWindow->GrabFocus();
return false; // this is called after the popup has been closed
}
};
@@ -1796,6 +1798,9 @@ void ScGridWindow::HandleMouseButtonDown( const MouseEvent& rMEvt, MouseEventSta
if (pScMod->IsModalMode(mrViewData.GetSfxDocShell()))
return;
+ const bool bWasMouseCaptured = IsMouseCaptured();
+ SAL_WARN_IF(bWasMouseCaptured, "sc.ui", "Is there a scenario where the mouse is captured before mouse down?");
+
pScActiveViewShell = mrViewData.GetViewShell(); // if left is clicked
nScClickMouseModifier = rMEvt.GetModifier(); // to always catch a control click
@@ -2052,9 +2057,11 @@ void ScGridWindow::HandleMouseButtonDown( const MouseEvent& rMEvt, MouseEventSta
tools::Rectangle aButtonRect = GetListValButtonRect( aListValPos );
if ( aButtonRect.Contains( aPos ) )
{
- // tdf#125917 typically we have the mouse captured already, except if are editing the cell.
- // Ensure its captured before the menu is launched even in the cell editing case
- CaptureMouse();
+ // tdf#149609 if we captured the mouse in the course of this function
+ // release it before showing the data select menu to undo any unhelpful
+ // seleng capture
+ if (!bWasMouseCaptured && IsMouseCaptured())
+ ReleaseMouse();
LaunchDataSelectMenu( aListValPos.Col(), aListValPos.Row() );
@@ -2070,7 +2077,11 @@ void ScGridWindow::HandleMouseButtonDown( const MouseEvent& rMEvt, MouseEventSta
ScRange aScenRange;
if ( rMEvt.IsLeft() && HasScenarioButton( aPos, aScenRange ) )
{
- CaptureMouse();
+ // tdf#149609 if we captured the mouse in the course of this function
+ // release it before showing the data scenario menu to undo any unhelpful
+ // seleng capture
+ if (!bWasMouseCaptured && IsMouseCaptured())
+ ReleaseMouse();
DoScenarioMenu( aScenRange );
diff --git a/sc/source/ui/view/gridwin4.cxx b/sc/source/ui/view/gridwin4.cxx
index 5da4a54508d2..d1aa33f4c847 100644
--- a/sc/source/ui/view/gridwin4.cxx
+++ b/sc/source/ui/view/gridwin4.cxx
@@ -1355,7 +1355,9 @@ namespace
if (!pPageView)
return;
- SdrPageWindow* pSdrPageWindow = pPageView->GetPageWindow(0);
+ SdrPageWindow* pSdrPageWindow = nullptr;
+ if (pPageView->PageWindowCount() > 0)
+ pSdrPageWindow = pPageView->GetPageWindow(0);
if (!pSdrPageWindow)
return;
diff --git a/sc/source/ui/view/output2.cxx b/sc/source/ui/view/output2.cxx
index ba4a1b13a795..56e428d557a2 100644
--- a/sc/source/ui/view/output2.cxx
+++ b/sc/source/ui/view/output2.cxx
@@ -74,6 +74,7 @@
#include <scopetools.hxx>
#include <com/sun/star/i18n/DirectionProperty.hpp>
+#include <comphelper/scopeguard.hxx>
#include <comphelper/string.hxx>
#include <memory>
@@ -1518,6 +1519,12 @@ void ScOutputData::DrawStrings( bool bPixelToLogic )
tools::Rectangle ScOutputData::LayoutStrings(bool bPixelToLogic, bool bPaint, const ScAddress &rAddress)
{
+ bool bOrigIsInLayoutStrings = mpDoc->IsInLayoutStrings();
+ mpDoc->SetLayoutStrings(true);
+ comphelper::ScopeGuard g([this, bOrigIsInLayoutStrings] {
+ mpDoc->SetLayoutStrings(bOrigIsInLayoutStrings);
+ });
+
OSL_ENSURE( mpDev == mpRefDevice ||
mpDev->GetMapMode().GetMapUnit() == mpRefDevice->GetMapMode().GetMapUnit(),
"LayoutStrings: different MapUnits ?!?!" );
@@ -1552,6 +1559,11 @@ tools::Rectangle ScOutputData::LayoutStrings(bool bPixelToLogic, bool bPaint, co
const SfxItemSet* pOldCondSet = nullptr;
SvtScriptType nOldScript = SvtScriptType::NONE;
+ // Try to limit interpreting to only visible cells. Calling e.g. IsValue()
+ // on a formula cell that needs interpreting would call Interpret()
+ // for the entire formula group, which could be large.
+ mpDoc->InterpretCellsIfNeeded( ScRange( nX1, nY1, nTab, nX2, nY2, nTab ));
+
// alternative pattern instances in case we need to modify the pattern
// before processing the cell value.
std::vector<std::unique_ptr<ScPatternAttr> > aAltPatterns;
diff --git a/sc/source/ui/view/printfun.cxx b/sc/source/ui/view/printfun.cxx
index ccd015552074..b5d2da8b96c6 100644
--- a/sc/source/ui/view/printfun.cxx
+++ b/sc/source/ui/view/printfun.cxx
@@ -3091,6 +3091,10 @@ void PrintPageRanges::calculate(ScDocument& rDoc,
rDoc.SetPageSize(nPrintTab, rDocSize);
+ // Clear the map to prevent any outdated values to "survive" when
+ // we have to recalculate the new values anyway
+ m_xPageRows->clear();
+
// #i123672# use dynamic mem to react on size changes
if (m_xPageEndX->size() < static_cast<size_t>(rDoc.MaxCol()) + 1)
{
diff --git a/sc/source/ui/view/spellcheckcontext.cxx b/sc/source/ui/view/spellcheckcontext.cxx
index 224af6859f59..a1358dcd647a 100644
--- a/sc/source/ui/view/spellcheckcontext.cxx
+++ b/sc/source/ui/view/spellcheckcontext.cxx
@@ -327,12 +327,14 @@ void SpellCheckContext::ensureResults(SCCOL nCol, SCROW nRow)
}
// Cache miss, the cell needs spell-check..
- mpEngine->SetDefaultItem(SvxLanguageItem(eCellLang, EE_CHAR_LANGUAGE));
if (eType == CELLTYPE_STRING)
mpEngine->SetText(aCell.mpString->getString());
else
mpEngine->SetText(*aCell.mpEditText);
+ // it has to happen after we set text
+ mpEngine->SetDefaultItem(SvxLanguageItem(eCellLang, EE_CHAR_LANGUAGE));
+
mpStatus->mbModified = false;
mpEngine->CompleteOnlineSpelling();
std::unique_ptr<MisspellType> pRanges;
diff --git a/sc/source/ui/view/tabvwsh2.cxx b/sc/source/ui/view/tabvwsh2.cxx
index a096a766ea7d..9060fa98e65c 100644
--- a/sc/source/ui/view/tabvwsh2.cxx
+++ b/sc/source/ui/view/tabvwsh2.cxx
@@ -265,6 +265,7 @@ void ScTabViewShell::ExecDraw(SfxRequest& rReq)
case SID_DRAW_TEXT_MARQUEE:
case SID_DRAW_NOTEEDIT:
pTabView->SetDrawFuncPtr(new FuText(*this, pWin, pView, pDoc, aNewReq));
+ bCreateDirectly = comphelper::LibreOfficeKit::isActive();
break;
case SID_FM_CREATE_CONTROL:
@@ -335,7 +336,6 @@ void ScTabViewShell::ExecDraw(SfxRequest& rReq)
}
else
{
- GetViewFrame()->GetDispatcher()->Execute(SID_OBJECT_SELECT, SfxCallMode::ASYNCHRON);
ScViewData& rViewData = GetViewData();
aInsertPos = rViewData.getLOKVisibleArea().Center();
if (comphelper::LibreOfficeKit::isCompatFlagSet(
@@ -370,13 +370,20 @@ void ScTabViewShell::ExecDraw(SfxRequest& rReq)
// insert into page
pView->InsertObjectAtView(pObj.release(), *pPageView);
- if ( nNewId == SID_DRAW_CAPTION || nNewId == SID_DRAW_CAPTION_VERTICAL )
+ switch ( nNewId )
{
+ case SID_DRAW_CAPTION:
+ case SID_DRAW_CAPTION_VERTICAL:
+ case SID_DRAW_TEXT:
+ case SID_DRAW_TEXT_VERTICAL:
// use KeyInput to start edit mode (FuText is created).
// For FuText objects, edit mode is handled within CreateDefaultObject.
// KEY_F2 is handled in FuDraw::KeyInput.
pFuActual->KeyInput( KeyEvent( 0, vcl::KeyCode( KEY_F2 ) ) );
+ break;
+ default:
+ break;
}
}
diff --git a/sc/source/ui/view/tabvwsha.cxx b/sc/source/ui/view/tabvwsha.cxx
index 414a293d854d..39910e32cc39 100644
--- a/sc/source/ui/view/tabvwsha.cxx
+++ b/sc/source/ui/view/tabvwsha.cxx
@@ -29,6 +29,7 @@
#include <sfx2/viewfrm.hxx>
#include <svl/ilstitem.hxx>
#include <svl/numformat.hxx>
+#include <svl/zformat.hxx>
#include <svl/int64item.hxx>
#include <svl/srchitem.hxx>
#include <svl/srchdefs.hxx>
@@ -127,6 +128,17 @@ bool ScTabViewShell::GetFunction( OUString& rFuncStr, FormulaError nErrCode )
{
// number format from attributes or formula
nNumFmt = rDoc.GetNumberFormat( nPosX, nPosY, nTab );
+ // If the number format is time (without date) and the
+ // result is not within 24 hours, use a duration
+ // format. Summing date+time doesn't make much sense
+ // otherwise but we also don't want to display duration
+ // for a single date+time value.
+ if (nVal < 0.0 || nVal >= 1.0)
+ {
+ const SvNumberformat* pFormat = pFormatter->GetEntry(nNumFmt);
+ if (pFormat && (pFormat->GetType() == SvNumFormatType::TIME))
+ nNumFmt = pFormatter->GetTimeFormat( nVal, pFormat->GetLanguage(), true);
+ }
}
OUString aValStr;
@@ -757,9 +769,16 @@ void ScTabViewShell::ExecuteSave( SfxRequest& rReq )
// Finish entering unless 'DontTerminateEdit' is specified, even if a formula is being processed
if (bCommitChanges)
{
- SC_MOD()->InputEnterHandler();
+ bool bLOKActive = comphelper::LibreOfficeKit::isActive();
+
+ // Disable error dialog box when about to save in lok mode as
+ // this ultimately invokes SvpSalInstance::DoYield() when we want
+ // to save immediately without committing any erroneous input in possibly
+ // a cell with validation rules. After save is complete the user
+ // can continue editing.
+ SC_MOD()->InputEnterHandler(ScEnterMode::NORMAL, bLOKActive /* bBeforeSavingInLOK */);
- if (comphelper::LibreOfficeKit::isActive())
+ if (bLOKActive)
{
// Normally this isn't needed, but in Calc when editing a cell formula
// and manually saving (without changing cells or hitting enter), while
diff --git a/sc/source/ui/view/viewdata.cxx b/sc/source/ui/view/viewdata.cxx
index 6ac95430a84e..f712d23ae0e6 100644
--- a/sc/source/ui/view/viewdata.cxx
+++ b/sc/source/ui/view/viewdata.cxx
@@ -1153,7 +1153,7 @@ ScMarkType ScViewData::GetSimpleArea( ScRange & rRange, ScMarkData & rNewMark )
if (eMarkType == SC_MARK_NONE)
eMarkType = SC_MARK_SIMPLE;
const ScPatternAttr* pMarkPattern = mrDoc.GetPattern(GetCurX(), GetCurY(), GetTabNo());
- if (pMarkPattern->GetItemSet().GetItemState(ATTR_MERGE, false) == SfxItemState::SET)
+ if (pMarkPattern && pMarkPattern->GetItemSet().GetItemState(ATTR_MERGE, false) == SfxItemState::SET)
{
SCROW nRow = pMarkPattern->GetItem(ATTR_MERGE).GetRowMerge();
SCCOL nCol = pMarkPattern->GetItem(ATTR_MERGE).GetColMerge();
@@ -2416,7 +2416,7 @@ Point ScViewData::GetScrPos( SCCOL nWhereX, SCROW nWhereY, ScSplitPos eWhich,
const_cast<ScViewData*>(this)->aScrSize.setHeight( pView->GetGridHeight(eWhichY) );
}
- sal_uLong nTSize;
+ sal_uInt16 nTSize;
bool bIsTiledRendering = comphelper::LibreOfficeKit::isActive();
@@ -2484,20 +2484,27 @@ Point ScViewData::GetScrPos( SCCOL nWhereX, SCROW nWhereY, ScSplitPos eWhich,
if (nWhereY >= nStartPosY)
{
- if (bAllowNeg || bIsTiledRendering || nScrPosY <= aScrSize.Height())
+ for (SCROW nY = nStartPosY; nY < nWhereY && (bAllowNeg || bIsTiledRendering || nScrPosY <= aScrSize.Height()); nY++)
{
- if (nWhereY - 1 > mrDoc.MaxRow())
+ if ( nY > mrDoc.MaxRow() )
nScrPosY = 0x7FFFFFFF;
- else if (bAllowNeg || bIsTiledRendering)
- {
- sal_uLong nSizeYPix = mrDoc.GetScaledRowHeight(nStartPosY, nWhereY - 1, nForTab, nPPTY);
- nScrPosY += nSizeYPix;
- }
else
{
- sal_uLong nMaxHeight = aScrSize.getHeight() - nScrPosY;
- sal_uLong nSizeYPix = mrDoc.GetScaledRowHeight(nStartPosY, nWhereY - 1, nForTab, nPPTY, &nMaxHeight);
- nScrPosY += nSizeYPix;
+ nTSize = mrDoc.GetRowHeight( nY, nTabNo );
+ if (nTSize)
+ {
+ tools::Long nSizeYPix = ToPixel( nTSize, nPPTY );
+ nScrPosY += nSizeYPix;
+ }
+ else if ( nY < mrDoc.MaxRow() )
+ {
+ // skip multiple hidden rows (forward only for now)
+ SCROW nNext = mrDoc.FirstVisibleRow(nY + 1, mrDoc.MaxRow(), nTabNo);
+ if ( nNext > mrDoc.MaxRow() )
+ nY = mrDoc.MaxRow();
+ else
+ nY = nNext - 1; // +=nDir advances to next visible row
+ }
}
}
}
diff --git a/sc/source/ui/view/viewfun2.cxx b/sc/source/ui/view/viewfun2.cxx
index f5c79f583efb..fe8536918164 100644
--- a/sc/source/ui/view/viewfun2.cxx
+++ b/sc/source/ui/view/viewfun2.cxx
@@ -2591,6 +2591,7 @@ bool ScViewFunc::DeleteTables(const vector<SCTAB> &TheTabs, bool bRecord )
SfxApplication* pSfxApp = SfxGetpApp(); // Navigator
pSfxApp->Broadcast( SfxHint( SfxHintId::ScTablesChanged ) );
+ pSfxApp->Broadcast( SfxHint( SfxHintId::ScAreasChanged ) );
pSfxApp->Broadcast( SfxHint( SfxHintId::ScDbAreasChanged ) );
pSfxApp->Broadcast( SfxHint( SfxHintId::ScAreaLinksChanged ) );
}
diff --git a/sc/source/ui/view/viewfun3.cxx b/sc/source/ui/view/viewfun3.cxx
index 5397d2dec352..679557d020b4 100644
--- a/sc/source/ui/view/viewfun3.cxx
+++ b/sc/source/ui/view/viewfun3.cxx
@@ -869,7 +869,7 @@ bool checkDestRangeForOverwrite(const ScRangeList& rDestRanges, const ScDocument
}
bool ScViewFunc::PasteFromClip( InsertDeleteFlags nFlags, ScDocument* pClipDoc,
- ScPasteFunc nFunction, bool bSkipEmpty,
+ ScPasteFunc nFunction, bool bSkipEmptyCells,
bool bTranspose, bool bAsLink,
InsCellCmd eMoveMode, InsertDeleteFlags nUndoExtraFlags,
bool bAllowDialogs )
@@ -900,7 +900,7 @@ bool ScViewFunc::PasteFromClip( InsertDeleteFlags nFlags, ScDocument* pClipDoc,
if (rClipParam.isMultiRange())
{
// Source data is multi-range.
- return PasteMultiRangesFromClip(nFlags, pClipDoc, nFunction, bSkipEmpty, false, bTranspose,
+ return PasteMultiRangesFromClip(nFlags, pClipDoc, nFunction, bSkipEmptyCells, false, bTranspose,
bAsLink, bAllowDialogs, eMoveMode, nUndoFlags);
}
@@ -909,7 +909,7 @@ bool ScViewFunc::PasteFromClip( InsertDeleteFlags nFlags, ScDocument* pClipDoc,
{
// Source data is single-range but destination is multi-range.
return PasteFromClipToMultiRanges(
- nFlags, pClipDoc, nFunction, bSkipEmpty, bTranspose, bAsLink, bAllowDialogs,
+ nFlags, pClipDoc, nFunction, bSkipEmptyCells, bTranspose, bAsLink, bAllowDialogs,
eMoveMode, nUndoFlags);
}
@@ -1281,7 +1281,7 @@ bool ScViewFunc::PasteFromClip( InsertDeleteFlags nFlags, ScDocument* pClipDoc,
ScDocumentUniquePtr pMixDoc;
if (nFunction != ScPasteFunc::NONE)
{
- bSkipEmpty = false;
+ bSkipEmptyCells = false;
if ( nFlags & InsertDeleteFlags::CONTENTS )
{
pMixDoc.reset(new ScDocument( SCDOCMODE_UNDO ));
@@ -1306,7 +1306,7 @@ bool ScViewFunc::PasteFromClip( InsertDeleteFlags nFlags, ScDocument* pClipDoc,
// copy normally (original range)
rDoc.CopyFromClip( aUserRange, aFilteredMark, nNoObjFlags,
pRefUndoDoc.get(), pClipDoc, true, false, bIncludeFiltered,
- bSkipEmpty, (bMarkIsFiltered ? &aRangeList : nullptr) );
+ bSkipEmptyCells, (bMarkIsFiltered ? &aRangeList : nullptr) );
// adapt refs manually in case of transpose
if ( bTranspose && bCutMode && (nFlags & InsertDeleteFlags::CONTENTS) )
@@ -1316,7 +1316,7 @@ bool ScViewFunc::PasteFromClip( InsertDeleteFlags nFlags, ScDocument* pClipDoc,
{
// copy with bAsLink=TRUE
rDoc.CopyFromClip( aUserRange, aFilteredMark, nNoObjFlags, pRefUndoDoc.get(), pClipDoc,
- true, true, bIncludeFiltered, bSkipEmpty );
+ true, true, bIncludeFiltered, bSkipEmptyCells );
}
else
{
@@ -1333,7 +1333,7 @@ bool ScViewFunc::PasteFromClip( InsertDeleteFlags nFlags, ScDocument* pClipDoc,
if ( pMixDoc ) // calculate with original data?
{
- rDoc.MixDocument( aUserRange, nFunction, bSkipEmpty, *pMixDoc );
+ rDoc.MixDocument( aUserRange, nFunction, bSkipEmptyCells, *pMixDoc );
}
pMixDoc.reset();
@@ -1405,7 +1405,7 @@ bool ScViewFunc::PasteFromClip( InsertDeleteFlags nFlags, ScDocument* pClipDoc,
ScUndoPasteOptions aOptions; // store options for repeat
aOptions.nFunction = nFunction;
- aOptions.bSkipEmpty = bSkipEmpty;
+ aOptions.bSkipEmptyCells = bSkipEmptyCells;
aOptions.bTranspose = bTranspose;
aOptions.bAsLink = bAsLink;
aOptions.eMoveMode = eMoveMode;
@@ -1464,7 +1464,7 @@ bool ScViewFunc::PasteFromClip( InsertDeleteFlags nFlags, ScDocument* pClipDoc,
}
bool ScViewFunc::PasteMultiRangesFromClip(InsertDeleteFlags nFlags, ScDocument* pClipDoc,
- ScPasteFunc nFunction, bool bSkipEmpty,
+ ScPasteFunc nFunction, bool bSkipEmptyCells,
bool bIncludeFiltered, bool bTranspose, bool bAsLink,
bool bAllowDialogs, InsCellCmd eMoveMode,
InsertDeleteFlags nUndoFlags)
@@ -1554,7 +1554,7 @@ bool ScViewFunc::PasteMultiRangesFromClip(InsertDeleteFlags nFlags, ScDocument*
}
ScDocumentUniquePtr pMixDoc;
- if ( bSkipEmpty || nFunction != ScPasteFunc::NONE)
+ if ( bSkipEmptyCells || nFunction != ScPasteFunc::NONE)
{
if ( nFlags & InsertDeleteFlags::CONTENTS )
{
@@ -1578,10 +1578,10 @@ bool ScViewFunc::PasteMultiRangesFromClip(InsertDeleteFlags nFlags, ScDocument*
if (bAsLink && bTranspose)
nCopyFlags |= InsertDeleteFlags::FORMULA;
rDoc.CopyMultiRangeFromClip(rCurPos, aMark, nCopyFlags, pClipDoc, true, bAsLink && !bTranspose,
- bIncludeFiltered, bSkipEmpty);
+ bIncludeFiltered, bSkipEmptyCells);
if (pMixDoc)
- rDoc.MixDocument(aMarkedRange, nFunction, bSkipEmpty, *pMixDoc);
+ rDoc.MixDocument(aMarkedRange, nFunction, bSkipEmptyCells, *pMixDoc);
AdjustBlockHeight(); // update row heights before pasting objects
@@ -1611,7 +1611,7 @@ bool ScViewFunc::PasteMultiRangesFromClip(InsertDeleteFlags nFlags, ScDocument*
ScUndoPasteOptions aOptions; // store options for repeat
aOptions.nFunction = nFunction;
- aOptions.bSkipEmpty = bSkipEmpty;
+ aOptions.bSkipEmptyCells = bSkipEmptyCells;
aOptions.bTranspose = bTranspose;
aOptions.bAsLink = bAsLink;
aOptions.eMoveMode = eMoveMode;
@@ -1634,7 +1634,7 @@ bool ScViewFunc::PasteMultiRangesFromClip(InsertDeleteFlags nFlags, ScDocument*
bool ScViewFunc::PasteFromClipToMultiRanges(
InsertDeleteFlags nFlags, ScDocument* pClipDoc, ScPasteFunc nFunction,
- bool bSkipEmpty, bool bTranspose, bool bAsLink, bool bAllowDialogs,
+ bool bSkipEmptyCells, bool bTranspose, bool bAsLink, bool bAllowDialogs,
InsCellCmd eMoveMode, InsertDeleteFlags nUndoFlags )
{
if (bTranspose)
@@ -1714,7 +1714,7 @@ bool ScViewFunc::PasteFromClipToMultiRanges(
}
ScDocumentUniquePtr pMixDoc;
- if (bSkipEmpty || nFunction != ScPasteFunc::NONE)
+ if (bSkipEmptyCells || nFunction != ScPasteFunc::NONE)
{
if (nFlags & InsertDeleteFlags::CONTENTS)
{
@@ -1738,13 +1738,13 @@ bool ScViewFunc::PasteFromClipToMultiRanges(
{
rDoc.CopyFromClip(
aRanges[i], aMark, (nFlags & ~InsertDeleteFlags::OBJECTS), nullptr, pClipDoc,
- false, false, true, bSkipEmpty);
+ false, false, true, bSkipEmptyCells);
}
if (pMixDoc)
{
for (size_t i = 0, n = aRanges.size(); i < n; ++i)
- rDoc.MixDocument(aRanges[i], nFunction, bSkipEmpty, *pMixDoc);
+ rDoc.MixDocument(aRanges[i], nFunction, bSkipEmptyCells, *pMixDoc);
}
AdjustBlockHeight(); // update row heights before pasting objects
@@ -1756,7 +1756,7 @@ bool ScViewFunc::PasteFromClipToMultiRanges(
{
rDoc.CopyFromClip(
aRanges[i], aMark, InsertDeleteFlags::OBJECTS, nullptr, pClipDoc,
- false, false, true, bSkipEmpty);
+ false, false, true, bSkipEmptyCells);
}
}
@@ -1777,7 +1777,7 @@ bool ScViewFunc::PasteFromClipToMultiRanges(
ScUndoPasteOptions aOptions; // store options for repeat
aOptions.nFunction = nFunction;
- aOptions.bSkipEmpty = bSkipEmpty;
+ aOptions.bSkipEmptyCells = bSkipEmptyCells;
aOptions.bTranspose = bTranspose;
aOptions.bAsLink = bAsLink;
aOptions.eMoveMode = eMoveMode;
diff --git a/sc/source/ui/view/viewfunc.cxx b/sc/source/ui/view/viewfunc.cxx
index af151534c018..95020795aceb 100644
--- a/sc/source/ui/view/viewfunc.cxx
+++ b/sc/source/ui/view/viewfunc.cxx
@@ -77,6 +77,7 @@
#include <comphelper/lok.hxx>
#include <conditio.hxx>
#include <columnspanset.hxx>
+#include <stringutil.hxx>
#include <memory>
@@ -337,6 +338,29 @@ namespace HelperNotifyChanges
}
}
+namespace
+{
+ class AutoCorrectQuery : public weld::MessageDialogController
+ {
+ private:
+ std::unique_ptr<weld::TextView> m_xError;
+ public:
+ AutoCorrectQuery(weld::Window* pParent, const OUString& rFormula)
+ : weld::MessageDialogController(pParent, "modules/scalc/ui/warnautocorrect.ui", "WarnAutoCorrect", "grid")
+ , m_xError(m_xBuilder->weld_text_view("error"))
+ {
+ m_xDialog->set_primary_text(ScResId(SCSTR_FORMULA_AUTOCORRECTION).trim());
+ m_xDialog->set_default_response(RET_YES);
+
+ const int nMaxWidth = m_xError->get_approximate_digit_width() * 65;
+ const int nMaxHeight = m_xError->get_height_rows(6);
+ m_xError->set_size_request(nMaxWidth, nMaxHeight);
+
+ m_xError->set_text(rFormula);
+ }
+ };
+}
+
// actual functions
// input - undo OK
@@ -447,13 +471,8 @@ void ScViewFunc::EnterData( SCCOL nCol, SCROW nRow, SCTAB nTab,
nResult = RET_NO; // empty formula, just '='
else
{
- OUString aMessage = ScResId( SCSTR_FORMULA_AUTOCORRECTION ) + aCorrectedFormula;
-
- std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(GetViewData().GetDialogParent(),
- VclMessageType::Question, VclButtonsType::YesNo,
- aMessage));
- xQueryBox->set_default_response(RET_YES);
- nResult = xQueryBox->run();
+ AutoCorrectQuery aQueryBox(GetViewData().GetDialogParent(), aCorrectedFormula);
+ nResult = aQueryBox.run();
}
if ( nResult == RET_YES )
{
@@ -560,10 +579,24 @@ void ScViewFunc::EnterData( SCCOL nCol, SCROW nRow, SCTAB nTab,
}
else
{
+ ScFieldEditEngine& rEngine = rDoc.GetEditEngine();
for (const auto& rTab : rMark)
{
bool bNumFmtSet = false;
- rFunc.SetNormalString( bNumFmtSet, ScAddress( nCol, nRow, rTab ), rString, false );
+ const ScAddress aScAddress(nCol, nRow, rTab);
+
+ // tdf#104902 - handle embedded newline
+ if (ScStringUtil::isMultiline(rString))
+ {
+ rEngine.SetTextCurrentDefaults(rString);
+ rDoc.SetEditText(aScAddress, rEngine.CreateTextObject());
+ pDocSh->AdjustRowHeight(nRow, nRow, rTab);
+ }
+ else
+ {
+ rFunc.SetNormalString(bNumFmtSet, aScAddress, rString, false);
+ }
+
if (bNumFmtSet)
{
/* FIXME: if set on any sheet results in changed only on
@@ -661,7 +694,7 @@ void ScViewFunc::EnterData( SCCOL nCol, SCROW nRow, SCTAB nTab,
// formulas have to be recognized even if they're formatted
// (but common attributes are still collected)
- if ( !bSimple && aEngine.GetParagraphCount() == 1 )
+ if (!bSimple)
{
OUString aParStr(aEngine.GetText( 0 ));
if ( aParStr[0] == '=' )