LibreOffice Module sc (master) 1
docsh3.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
21#include <com/sun/star/document/XDocumentProperties.hpp>
22
23#include <scitems.hxx>
24#include <rangelst.hxx>
25#include <editeng/flstitem.hxx>
26#include <editeng/paperinf.hxx>
27#include <editeng/sizeitem.hxx>
29#include <officecfg/Office/Common.hxx>
30#include <sal/log.hxx>
31#include <sfx2/viewfrm.hxx>
32#include <sfx2/app.hxx>
33#include <sfx2/docfile.hxx>
34#include <sfx2/printer.hxx>
35#include <svl/numformat.hxx>
36#include <svx/pageitem.hxx>
37#include <svx/postattr.hxx>
38#include <svx/svxids.hrc>
40#include <vcl/svapp.hxx>
41#include <vcl/virdev.hxx>
42#include <vcl/weld.hxx>
43#include <osl/diagnose.h>
44
45#include <docsh.hxx>
46#include "docshimp.hxx"
47#include <scmod.hxx>
48#include <tabvwsh.hxx>
49#include <viewdata.hxx>
50#include <docpool.hxx>
51#include <stlpool.hxx>
52#include <patattr.hxx>
53#include <uiitems.hxx>
54#include <hints.hxx>
55#include <docoptio.hxx>
56#include <viewopti.hxx>
57#include <pntlock.hxx>
58#include <chgtrack.hxx>
59#include <docfunc.hxx>
60#include <formulacell.hxx>
61#include <chgviset.hxx>
62#include <progress.hxx>
63#include <redcom.hxx>
64#include <inputopt.hxx>
65#include <drwlayer.hxx>
66#include <inputhdl.hxx>
67#include <conflictsdlg.hxx>
68#include <globstr.hrc>
69#include <scresid.hxx>
70#include <markdata.hxx>
71#include <memory>
72#include <formulaopt.hxx>
73
74#include <comphelper/lok.hxx>
75#include <sfx2/lokhelper.hxx>
76
77// Redraw - Notifications
78
79void ScDocShell::PostEditView( ScEditEngineDefaulter* pEditEngine, const ScAddress& rCursorPos )
80{
81// Broadcast( ScEditViewHint( pEditEngine, rCursorPos ) );
82
83 // Test: only active ViewShell
84
86 if (pViewSh && pViewSh->GetViewData().GetDocShell() == this)
87 {
88 ScEditViewHint aHint( pEditEngine, rCursorPos );
89 pViewSh->Notify( *this, aHint );
90 }
91}
92
94{
95 Broadcast( SfxHint( SfxHintId::ScDataChanged ) );
96 SfxGetpApp()->Broadcast(SfxHint( SfxHintId::ScAnyDataChanged )); // Navigator
97 m_pDocument->PrepareFormulaCalc();
99}
100
101void ScDocShell::PostPaint( SCCOL nStartCol, SCROW nStartRow, SCTAB nStartTab,
102 SCCOL nEndCol, SCROW nEndRow, SCTAB nEndTab, PaintPartFlags nPart,
103 sal_uInt16 nExtFlags )
104{
105 ScRange aRange(nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab);
106 PostPaint(aRange, nPart, nExtFlags);
107}
108
109void ScDocShell::PostPaint( const ScRangeList& rRanges, PaintPartFlags nPart, sal_uInt16 nExtFlags )
110{
111 ScRangeList aPaintRanges;
112 for (size_t i = 0, n = rRanges.size(); i < n; ++i)
113 {
114 const ScRange& rRange = rRanges[i];
115 SCCOL nCol1 = rRange.aStart.Col(), nCol2 = rRange.aEnd.Col();
116 SCROW nRow1 = rRange.aStart.Row(), nRow2 = rRange.aEnd.Row();
117 SCTAB nTab1 = rRange.aStart.Tab(), nTab2 = rRange.aEnd.Tab();
118
119 if (!m_pDocument->ValidCol(nCol1)) nCol1 = m_pDocument->MaxCol();
120 if (!m_pDocument->ValidRow(nRow1)) nRow1 = m_pDocument->MaxRow();
121 if (!m_pDocument->ValidCol(nCol2)) nCol2 = m_pDocument->MaxCol();
122 if (!m_pDocument->ValidRow(nRow2)) nRow2 = m_pDocument->MaxRow();
123
124 if ( m_pPaintLockData )
125 {
126 // #i54081# PaintPartFlags::Extras still has to be broadcast because it changes the
127 // current sheet if it's invalid. All other flags added to pPaintLockData.
128 PaintPartFlags nLockPart = nPart & ~PaintPartFlags::Extras;
129 if ( nLockPart != PaintPartFlags::NONE )
130 {
132 m_pPaintLockData->AddRange( ScRange( nCol1, nRow1, nTab1,
133 nCol2, nRow2, nTab2 ), nLockPart );
134 }
135
136 nPart &= PaintPartFlags::Extras; // for broadcasting
137 if (nPart == PaintPartFlags::NONE)
138 continue;
139 }
140
141 if (nExtFlags & SC_PF_LINES) // respect space for lines
142 {
144 if (nCol1>0) --nCol1;
145 if (nCol2<m_pDocument->MaxCol()) ++nCol2;
146 if (nRow1>0) --nRow1;
147 if (nRow2<m_pDocument->MaxRow()) ++nRow2;
148 }
149
150 // expand for the merged ones
151 if (nExtFlags & SC_PF_TESTMERGE)
152 m_pDocument->ExtendMerge( nCol1, nRow1, nCol2, nRow2, nTab1 );
153
154 if ( nCol1 != 0 || nCol2 != m_pDocument->MaxCol() )
155 {
156 // Extend to whole rows if SC_PF_WHOLEROWS is set, or rotated or non-left
157 // aligned cells are contained (see UpdatePaintExt).
158 // Special handling for RTL text (#i9731#) is unnecessary now with full
159 // support of right-aligned text.
160
161 if ( ( nExtFlags & SC_PF_WHOLEROWS ) ||
162 m_pDocument->HasAttrib( nCol1,nRow1,nTab1,
164 {
165 nCol1 = 0;
166 nCol2 = m_pDocument->MaxCol();
167 }
168 }
169 aPaintRanges.push_back(ScRange(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2));
170 }
171
172 Broadcast(ScPaintHint(aPaintRanges.Combine(), nPart));
173
174 // LOK: we are supposed to update the row / columns headers (and actually
175 // the document size too - cell size affects that, obviously)
177 {
178 ScModelObj* pModel = GetModel();
180 }
181}
182
184{
185 PostPaint( 0,0,0, m_pDocument->MaxCol(),m_pDocument->MaxRow(),MAXTAB, PaintPartFlags::Grid );
186}
187
189{
190 PostPaint( nCol,nRow,nTab, nCol,nRow,nTab, PaintPartFlags::Grid, SC_PF_TESTMERGE );
191}
192
194{
195 PostPaintCell( rPos.Col(), rPos.Row(), rPos.Tab() );
196}
197
199{
200 PostPaint( 0,0,0, m_pDocument->MaxCol(),m_pDocument->MaxRow(),MAXTAB, PaintPartFlags::Extras );
201}
202
203void ScDocShell::UpdatePaintExt( sal_uInt16& rExtFlags, const ScRange& rRange )
204{
205 if ( ( rExtFlags & SC_PF_LINES ) == 0 &&
207 {
208 // If the range contains lines, shadow or conditional formats,
209 // set SC_PF_LINES to include one extra cell in all directions.
210
211 rExtFlags |= SC_PF_LINES;
212 }
213
214 if ( ( rExtFlags & SC_PF_WHOLEROWS ) == 0 &&
215 ( rRange.aStart.Col() != 0 || rRange.aEnd.Col() != m_pDocument->MaxCol() ) &&
217 {
218 // If the range contains (logically) right- or center-aligned cells,
219 // or rotated cells, set SC_PF_WHOLEROWS to paint the whole rows.
220 // This test isn't needed after the cell changes, because it's also
221 // tested in PostPaint. UpdatePaintExt may later be changed to do this
222 // only if called before the changes.
223
224 rExtFlags |= SC_PF_WHOLEROWS;
225 }
226}
227
228void ScDocShell::UpdatePaintExt( sal_uInt16& rExtFlags, SCCOL nStartCol, SCROW nStartRow, SCTAB nStartTab,
229 SCCOL nEndCol, SCROW nEndRow, SCTAB nEndTab )
230{
231 UpdatePaintExt( rExtFlags, ScRange( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab ) );
232}
233
235{
236 if ( !m_pPaintLockData )
238 m_pPaintLockData->IncLevel(bDoc);
239}
240
242{
243 if ( m_pPaintLockData )
244 {
245 if ( m_pPaintLockData->GetLevel(bDoc) )
246 m_pPaintLockData->DecLevel(bDoc);
247 if (!m_pPaintLockData->GetLevel(!bDoc) && !m_pPaintLockData->GetLevel(bDoc))
248 {
249 // Execute Paint now
250
251 // don't continue collecting
252 std::unique_ptr<ScPaintLockData> pPaint = std::move(m_pPaintLockData);
253
254 ScRangeListRef xRangeList = pPaint->GetRangeList();
255 if ( xRangeList.is() )
256 {
257 PaintPartFlags nParts = pPaint->GetParts();
258 for ( size_t i = 0, nCount = xRangeList->size(); i < nCount; i++ )
259 {
261 ScRange const & rRange = (*xRangeList)[i];
262 PostPaint( rRange.aStart.Col(), rRange.aStart.Row(), rRange.aStart.Tab(),
263 rRange.aEnd.Col(), rRange.aEnd.Row(), rRange.aEnd.Tab(),
264 nParts );
265 }
266 }
267
268 if ( pPaint->GetModified() )
270 }
271 }
272 else
273 {
274 OSL_FAIL("UnlockPaint without LockPaint");
275 }
276}
277
278void ScDocShell::LockDocument_Impl(sal_uInt16 nNew)
279{
280 if (!m_nDocumentLock)
281 {
282 ScDrawLayer* pDrawLayer = m_pDocument->GetDrawLayer();
283 if (pDrawLayer)
284 pDrawLayer->setLock(true);
285 }
286 m_nDocumentLock = nNew;
287}
288
290{
291 m_nDocumentLock = nNew;
292 if (!m_nDocumentLock)
293 {
294 ScDrawLayer* pDrawLayer = m_pDocument->GetDrawLayer();
295 if (pDrawLayer)
296 pDrawLayer->setLock(false);
297 }
298}
299
300void ScDocShell::SetLockCount(sal_uInt16 nNew)
301{
302 if (nNew) // set
303 {
304 if ( !m_pPaintLockData )
306 m_pPaintLockData->SetDocLevel(nNew-1);
307 LockDocument_Impl(nNew);
308 }
309 else if (m_pPaintLockData) // delete
310 {
311 m_pPaintLockData->SetDocLevel(0); // at unlock, execute immediately
312 UnlockPaint_Impl(true); // now
314 }
315}
316
318{
319 LockPaint_Impl(false);
320}
321
323{
324 UnlockPaint_Impl(false);
325}
326
328{
329 LockPaint_Impl(true);
331}
332
334{
335 if (m_nDocumentLock)
336 {
337 UnlockPaint_Impl(true);
339 }
340 else
341 {
342 OSL_FAIL("UnlockDocument without LockDocument");
343 }
344}
345
346void ScDocShell::SetInplace( bool bInplace )
347{
348 if (m_bIsInplace != bInplace)
349 {
350 m_bIsInplace = bInplace;
352 }
353}
354
356{
357 if (m_bIsInplace)
358 {
359 m_nPrtToScreenFactor = 1.0; // otherwise it does not match the inactive display
360 return;
361 }
362
363 bool bTextWysiwyg = SC_MOD()->GetInputOptions().GetTextWysiwyg();
364 if (bTextWysiwyg)
365 {
367 return;
368 }
369
370 OUString aTestString(
371 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890123456789");
372 tools::Long nPrinterWidth = 0;
373 const ScPatternAttr* pPattern = &m_pDocument->GetPool()->GetDefaultItem(ATTR_PATTERN);
374
375 vcl::Font aDefFont;
376 OutputDevice* pRefDev = GetRefDevice();
377 MapMode aOldMode = pRefDev->GetMapMode();
378 vcl::Font aOldFont = pRefDev->GetFont();
379
380 pRefDev->SetMapMode(MapMode(MapUnit::MapPixel));
381 pPattern->fillFontOnly(aDefFont, pRefDev); // font color doesn't matter here
382 pRefDev->SetFont(aDefFont);
383 nPrinterWidth = pRefDev->PixelToLogic(Size(pRefDev->GetTextWidth(aTestString), 0), MapMode(MapUnit::Map100thMM)).Width();
384 pRefDev->SetFont(aOldFont);
385 pRefDev->SetMapMode(aOldMode);
386
388 pVirtWindow->SetMapMode(MapMode(MapUnit::MapPixel));
389 pPattern->fillFontOnly(aDefFont, pVirtWindow); // font color doesn't matter here
390 pVirtWindow->SetFont(aDefFont);
391 double nWindowWidth = pVirtWindow->GetTextWidth(aTestString) / ScGlobal::nScreenPPTX;
392 nWindowWidth = o3tl::convert(nWindowWidth, o3tl::Length::twip, o3tl::Length::mm100);
393
394 if (nPrinterWidth && nWindowWidth)
395 m_nPrtToScreenFactor = nPrinterWidth / nWindowWidth;
396 else
397 {
398 OSL_FAIL("GetTextSize returns 0 ??");
400 }
401}
402
403void ScDocShell::InitOptions(bool bForLoading) // called from InitNew and Load
404{
405 // Settings from the SpellCheckCfg get into Doc- and ViewOptions
406
407 LanguageType nDefLang, nCjkLang, nCtlLang;
408 bool bAutoSpell;
409 ScModule::GetSpellSettings( nDefLang, nCjkLang, nCtlLang, bAutoSpell );
410 ScModule* pScMod = SC_MOD();
411
412 ScDocOptions aDocOpt = pScMod->GetDocOptions();
413 ScFormulaOptions aFormulaOpt = pScMod->GetFormulaOptions();
414 ScViewOptions aViewOpt = pScMod->GetViewOptions();
415 aDocOpt.SetAutoSpell( bAutoSpell );
416
418 {
419 // two-digit year entry from Tools->Options->General
420 aDocOpt.SetYear2000(officecfg::Office::Common::DateFormat::TwoDigitYear::get());
421 }
422
423 if (bForLoading)
424 {
425 // #i112123# No style:decimal-places attribute means automatic decimals, not the configured default,
426 // so it must not be taken from the global options.
427 // Calculation settings are handled separately in ScXMLBodyContext::EndElement.
429
430 // fdo#78294 The default null-date if
431 // <table:null-date table:date-value='...' />
432 // is absent is 1899-12-30 regardless what the configuration is set to.
433 // Import filters may override this value.
434 aDocOpt.SetDate( 30, 12, 1899);
435 }
436
437 m_pDocument->SetDocOptions( aDocOpt );
438 m_pDocument->SetViewOptions( aViewOpt );
439 SetFormulaOptions( aFormulaOpt, bForLoading );
440
441 // print options are now set directly before the printing
442
443 m_pDocument->SetLanguage( nDefLang, nCjkLang, nCtlLang );
444}
445
447{
448 return m_pDocument->GetPrinter();
449}
450
451SfxPrinter* ScDocShell::GetPrinter(bool bCreateIfNotExist)
452{
453 return m_pDocument->GetPrinter(bCreateIfNotExist);
454}
455
457{
458 // pImpl->pFontList = new FontList( GetPrinter(), Application::GetDefaultDevice() );
459 m_pImpl->pFontList.reset(new FontList(GetRefDevice(), nullptr));
460 SvxFontListItem aFontListItem( m_pImpl->pFontList.get(), SID_ATTR_CHAR_FONTLIST );
461 PutItem( aFontListItem );
462
464}
465
467{
468 return m_pDocument->GetRefDevice();
469}
470
471sal_uInt16 ScDocShell::SetPrinter( VclPtr<SfxPrinter> const & pNewPrinter, SfxPrinterChangeFlags nDiffFlags )
472{
473 SfxPrinter *pOld = m_pDocument->GetPrinter( false );
474 if ( pOld && pOld->IsPrinting() )
475 return SFX_PRINTERROR_BUSY;
476
477 if (nDiffFlags & SfxPrinterChangeFlags::PRINTER)
478 {
479 if ( m_pDocument->GetPrinter() != pNewPrinter )
480 {
481 m_pDocument->SetPrinter( pNewPrinter );
482 m_pDocument->SetPrintOptions();
483
484 // MT: Use UpdateFontList: Will use Printer fonts only if needed!
485 /*
486 delete pImpl->pFontList;
487 pImpl->pFontList = new FontList( pNewPrinter, Application::GetDefaultDevice() );
488 SvxFontListItem aFontListItem( pImpl->pFontList, SID_ATTR_CHAR_FONTLIST );
489 PutItem( aFontListItem );
490
491 CalcOutputFactor();
492 */
493 if ( SC_MOD()->GetInputOptions().GetTextWysiwyg() )
495
496 ScModule* pScMod = SC_MOD();
497 SfxViewFrame *pFrame = SfxViewFrame::GetFirst( this );
498 while (pFrame)
499 {
500 SfxViewShell* pSh = pFrame->GetViewShell();
501 if (ScTabViewShell* pViewSh = dynamic_cast<ScTabViewShell*>(pSh))
502 {
503 ScInputHandler* pInputHdl = pScMod->GetInputHdl(pViewSh);
504 if (pInputHdl)
505 pInputHdl->UpdateRefDevice();
506 }
507 pFrame = SfxViewFrame::GetNext( *pFrame, this );
508 }
509 }
510 }
511 else if (nDiffFlags & SfxPrinterChangeFlags::JOBSETUP)
512 {
513 SfxPrinter* pOldPrinter = m_pDocument->GetPrinter();
514 if (pOldPrinter)
515 {
516 pOldPrinter->SetJobSetup( pNewPrinter->GetJobSetup() );
517
518 // #i6706# Call SetPrinter with the old printer again, so the drawing layer
519 // RefDevice is set (calling ReformatAllTextObjects and rebuilding charts),
520 // because the JobSetup (printer device settings) may affect text layout.
521 m_pDocument->SetPrinter( pOldPrinter );
522 CalcOutputFactor(); // also with the new settings
523 }
524 }
525
526 if (nDiffFlags & SfxPrinterChangeFlags::OPTIONS)
527 {
528 m_pDocument->SetPrintOptions();
529 }
530
531 if (nDiffFlags & (SfxPrinterChangeFlags::CHG_ORIENTATION | SfxPrinterChangeFlags::CHG_SIZE))
532 {
533 OUString aStyle = m_pDocument->GetPageStyle( GetCurTab() );
534 ScStyleSheetPool* pStPl = m_pDocument->GetStyleSheetPool();
535 SfxStyleSheet* pStyleSheet = static_cast<SfxStyleSheet*>(pStPl->Find(aStyle, SfxStyleFamily::Page));
536 if (pStyleSheet)
537 {
538 SfxItemSet& rSet = pStyleSheet->GetItemSet();
539
540 if (nDiffFlags & SfxPrinterChangeFlags::CHG_ORIENTATION)
541 {
542 const SvxPageItem& rOldItem = rSet.Get(ATTR_PAGE);
543 bool bWasLand = rOldItem.IsLandscape();
544 bool bNewLand = ( pNewPrinter->GetOrientation() == Orientation::Landscape );
545 if (bNewLand != bWasLand)
546 {
547 SvxPageItem aNewItem( rOldItem );
548 aNewItem.SetLandscape( bNewLand );
549 rSet.Put( aNewItem );
550
551 // flip size
552 Size aOldSize = rSet.Get(ATTR_PAGE_SIZE).GetSize();
553 // coverity[swapped_arguments : FALSE] - this is in the correct order
554 Size aNewSize(aOldSize.Height(),aOldSize.Width());
555 SvxSizeItem aNewSItem(ATTR_PAGE_SIZE,aNewSize);
556 rSet.Put( aNewSItem );
557 }
558 }
559 if (nDiffFlags & SfxPrinterChangeFlags::CHG_SIZE)
560 {
561 SvxSizeItem aPaperSizeItem( ATTR_PAGE_SIZE, SvxPaperInfo::GetPaperSize(pNewPrinter) );
562 rSet.Put( aPaperSizeItem );
563 }
564 }
565 }
566
568
569 return 0;
570}
571
573{
575 if (!pTrack)
576 return nullptr;
577
578 SCTAB nTab = rPos.Tab();
579
580 const ScChangeAction* pFound = nullptr;
581 const ScChangeAction* pAction = pTrack->GetFirst();
582 while (pAction)
583 {
584 ScChangeActionType eType = pAction->GetType();
586 if ( pAction->IsVisible() && eType != SC_CAT_DELETE_TABS )
587 {
588 const ScBigRange& rBig = pAction->GetBigRange();
589 if ( rBig.aStart.Tab() == nTab )
590 {
591 ScRange aRange = rBig.MakeRange( GetDocument() );
592
593 if ( eType == SC_CAT_DELETE_ROWS )
594 aRange.aEnd.SetRow( aRange.aStart.Row() );
595 else if ( eType == SC_CAT_DELETE_COLS )
596 aRange.aEnd.SetCol( aRange.aStart.Col() );
597
598 if ( aRange.Contains( rPos ) )
599 {
600 pFound = pAction; // the last one wins
601 }
602 }
603 if ( pAction->GetType() == SC_CAT_MOVE )
604 {
605 ScRange aRange =
606 static_cast<const ScChangeActionMove*>(pAction)->
607 GetFromRange().MakeRange( GetDocument() );
608 if ( aRange.Contains( rPos ) )
609 {
610 pFound = pAction;
611 }
612 }
613 }
614 pAction = pAction->GetNext();
615 }
616
617 return const_cast<ScChangeAction*>(pFound);
618}
619
620void ScDocShell::SetChangeComment( ScChangeAction* pAction, const OUString& rComment )
621{
622 if (!pAction)
623 return;
624
625 pAction->SetComment( rComment );
628
629 // Dialog-Notify
631 if (pTrack)
632 {
633 sal_uLong nNumber = pAction->GetActionNumber();
634 pTrack->NotifyModified( ScChangeTrackMsgType::Change, nNumber, nNumber );
635 }
636}
637
639{
640 if (!pAction) return; // without action is nothing...
641
642 OUString aComment = pAction->GetComment();
643 OUString aAuthor = pAction->GetUser();
644
645 DateTime aDT = pAction->GetDateTime();
646 OUString aDate = ScGlobal::getLocaleData().getDate( aDT ) + " " +
647 ScGlobal::getLocaleData().getTime( aDT, false );
648
650
651 aSet.Put( SvxPostItTextItem ( aComment, SID_ATTR_POSTIT_TEXT ) );
652 aSet.Put( SvxPostItAuthorItem( aAuthor, SID_ATTR_POSTIT_AUTHOR ) );
653 aSet.Put( SvxPostItDateItem ( aDate, SID_ATTR_POSTIT_DATE ) );
654
655 std::unique_ptr<ScRedComDialog> pDlg(new ScRedComDialog( pParent, aSet,this,pAction,bPrevNext));
656
657 pDlg->Execute();
658}
659
661{
662 ScChangeTrack* pTrack = m_pDocument->GetChangeTrack();
663 if ( pTrack && pTrack->GetFirst() )
664 {
666 }
667
668 m_pDocument->EndChangeTracking();
669 m_pDocument->StartChangeTracking();
670
671 OUString aOldUser;
672 pTrack = m_pDocument->GetChangeTrack();
673 if ( pTrack )
674 {
675 aOldUser = pTrack->GetUser();
676
677 // check if comparing to same document
678
679 OUString aThisFile;
680 const SfxMedium* pThisMed = GetMedium();
681 if (pThisMed)
682 aThisFile = pThisMed->GetName();
683 OUString aOtherFile;
684 SfxObjectShell* pOtherSh = rOtherDoc.GetDocumentShell();
685 if (pOtherSh)
686 {
687 const SfxMedium* pOtherMed = pOtherSh->GetMedium();
688 if (pOtherMed)
689 aOtherFile = pOtherMed->GetName();
690 }
691 bool bSameDoc = ( aThisFile == aOtherFile && !aThisFile.isEmpty() );
692 if ( !bSameDoc )
693 {
694 // create change actions from comparing with the name of the user
695 // who last saved the document
696 // (only if comparing different documents)
697
698 using namespace ::com::sun::star;
699 uno::Reference<document::XDocumentProperties> xDocProps(
700 GetModel()->getDocumentProperties());
701 OSL_ENSURE(xDocProps.is(), "no DocumentProperties");
702 OUString aDocUser = xDocProps->getModifiedBy();
703
704 if ( !aDocUser.isEmpty() )
705 pTrack->SetUser( aDocUser );
706 }
707 }
708
709 m_pDocument->CompareDocument( rOtherDoc );
710
711 pTrack = m_pDocument->GetChangeTrack();
712 if ( pTrack )
713 pTrack->SetUser( aOldUser );
714
717}
718
719// Merge (combine documents)
720
721static bool lcl_Equal( const ScChangeAction* pA, const ScChangeAction* pB, bool bIgnore100Sec )
722{
723 return pA && pB &&
724 pA->GetActionNumber() == pB->GetActionNumber() &&
725 pA->GetType() == pB->GetType() &&
726 pA->GetUser() == pB->GetUser() &&
727 (bIgnore100Sec ?
729 pA->GetDateTimeUTC() == pB->GetDateTimeUTC());
730 // don't compare state if an old change has been accepted
731}
732
733static bool lcl_FindAction( ScDocument& rDoc, const ScChangeAction* pAction, ScDocument& rSearchDoc, const ScChangeAction* pFirstSearchAction, const ScChangeAction* pLastSearchAction, bool bIgnore100Sec )
734{
735 if ( !pAction || !pFirstSearchAction || !pLastSearchAction )
736 {
737 return false;
738 }
739
740 sal_uLong nLastSearchAction = pLastSearchAction->GetActionNumber();
741 const ScChangeAction* pA = pFirstSearchAction;
742 while ( pA && pA->GetActionNumber() <= nLastSearchAction )
743 {
744 if ( pAction->GetType() == pA->GetType() &&
745 pAction->GetUser() == pA->GetUser() &&
746 (bIgnore100Sec ?
748 pAction->GetDateTimeUTC() == pA->GetDateTimeUTC() ) &&
749 pAction->GetBigRange() == pA->GetBigRange() )
750 {
751 OUString aActionDesc = pAction->GetDescription(rDoc, true);
752 OUString aADesc = pA->GetDescription(rSearchDoc, true);
753 if (aActionDesc == aADesc)
754 {
755 OSL_FAIL( "lcl_FindAction(): found equal action!" );
756 return true;
757 }
758 }
759 pA = pA->GetNext();
760 }
761
762 return false;
763}
764
765void ScDocShell::MergeDocument( ScDocument& rOtherDoc, bool bShared, bool bCheckDuplicates, sal_uLong nOffset, ScChangeActionMergeMap* pMergeMap, bool bInverseMap )
766{
767 ScTabViewShell* pViewSh = GetBestViewShell( false );
768 if (!pViewSh)
769 return;
770
771 ScChangeTrack* pSourceTrack = rOtherDoc.GetChangeTrack();
772 if (!pSourceTrack)
773 return;
774
775 ScChangeTrack* pThisTrack = m_pDocument->GetChangeTrack();
776 if ( !pThisTrack )
777 { // turn on
778 m_pDocument->StartChangeTracking();
779 pThisTrack = m_pDocument->GetChangeTrack();
780 OSL_ENSURE(pThisTrack,"ChangeTracking not enabled?");
781 if ( !bShared )
782 {
783 // turn on visual RedLining
784 ScChangeViewSettings aChangeViewSet;
785 aChangeViewSet.SetShowChanges(true);
786 m_pDocument->SetChangeViewSettings(aChangeViewSet);
787 }
788 }
789
790 // include Nano seconds in compare?
791 bool bIgnore100Sec = !pSourceTrack->IsTimeNanoSeconds() ||
792 !pThisTrack->IsTimeNanoSeconds();
793
794 // find common initial position
795 sal_uLong nFirstNewNumber = 0;
796 const ScChangeAction* pSourceAction = pSourceTrack->GetFirst();
797 const ScChangeAction* pThisAction = pThisTrack->GetFirst();
798 // skip identical actions
799 while ( lcl_Equal( pSourceAction, pThisAction, bIgnore100Sec ) )
800 {
801 nFirstNewNumber = pSourceAction->GetActionNumber() + 1;
802 pSourceAction = pSourceAction->GetNext();
803 pThisAction = pThisAction->GetNext();
804 }
805 // pSourceAction and pThisAction now point to the first "own" actions
806 // The common actions before don't interest at all
807
809
810 const ScChangeAction* pFirstMergeAction = pSourceAction;
811 const ScChangeAction* pFirstSearchAction = pThisAction;
812
813 // #i94841# [Collaboration] When deleting rows is rejected, the content is sometimes wrong
814 const ScChangeAction* pLastSearchAction = pThisTrack->GetLast();
815
816 // Create MergeChangeData from the following actions
817 sal_uLong nNewActionCount = 0;
818 const ScChangeAction* pCount = pSourceAction;
819 while ( pCount )
820 {
821 if ( bShared || !ScChangeTrack::MergeIgnore( *pCount, nFirstNewNumber ) )
822 ++nNewActionCount;
823 pCount = pCount->GetNext();
824 }
825 if (!nNewActionCount)
826 return;
827 // from here on no return
828
829 ScProgress aProgress( this, "...", nNewActionCount, true );
830
831 sal_uLong nLastMergeAction = pSourceTrack->GetLast()->GetActionNumber();
832 // UpdateReference-Undo, valid references for the last common state
833 pSourceTrack->MergePrepare( pFirstMergeAction, bShared );
834
835 // adjust MergeChangeData to all yet following actions in this document
836 // -> references valid for this document
837 while ( pThisAction )
838 {
839 // #i87049# [Collaboration] Conflict between delete row and insert content is not merged correctly
840 if ( !bShared || !ScChangeTrack::MergeIgnore( *pThisAction, nFirstNewNumber ) )
841 {
842 ScChangeActionType eType = pThisAction->GetType();
843 switch ( eType )
844 {
845 case SC_CAT_INSERT_COLS :
846 case SC_CAT_INSERT_ROWS :
847 case SC_CAT_INSERT_TABS :
848 pSourceTrack->AppendInsert( pThisAction->GetBigRange().MakeRange( GetDocument() ) );
849 break;
850 case SC_CAT_DELETE_COLS :
851 case SC_CAT_DELETE_ROWS :
852 case SC_CAT_DELETE_TABS :
853 {
854 const ScChangeActionDel* pDel = static_cast<const ScChangeActionDel*>(pThisAction);
855 if ( pDel->IsTopDelete() && !pDel->IsTabDeleteCol() )
856 { // deleted table contains deleted cols, which are not
857 sal_uLong nStart, nEnd;
858 pSourceTrack->AppendDeleteRange(
859 pDel->GetOverAllRange().MakeRange( GetDocument() ), nullptr, nStart, nEnd );
860 }
861 }
862 break;
863 case SC_CAT_MOVE :
864 {
865 const ScChangeActionMove* pMove = static_cast<const ScChangeActionMove*>(pThisAction);
866 pSourceTrack->AppendMove( pMove->GetFromRange().MakeRange( GetDocument() ),
867 pMove->GetBigRange().MakeRange( GetDocument() ), nullptr );
868 }
869 break;
870 default:
871 {
872 // added to avoid warnings
873 }
874 }
875 }
876 pThisAction = pThisAction->GetNext();
877 }
878
879 LockPaint(); // #i73877# no repainting after each action
880
881 // take over MergeChangeData into the current document
882 bool bHasRejected = false;
883 OUString aOldUser = pThisTrack->GetUser();
884 pThisTrack->SetUseFixDateTime( true );
885 ScMarkData& rMarkData = pViewSh->GetViewData().GetMarkData();
886 ScMarkData aOldMarkData( rMarkData );
887 pSourceAction = pFirstMergeAction;
888 while ( pSourceAction && pSourceAction->GetActionNumber() <= nLastMergeAction )
889 {
890 bool bMergeAction = false;
891 if ( bShared )
892 {
893 if ( !bCheckDuplicates || !lcl_FindAction( rOtherDoc, pSourceAction, *m_pDocument, pFirstSearchAction, pLastSearchAction, bIgnore100Sec ) )
894 {
895 bMergeAction = true;
896 }
897 }
898 else
899 {
900 if ( !ScChangeTrack::MergeIgnore( *pSourceAction, nFirstNewNumber ) )
901 {
902 bMergeAction = true;
903 }
904 }
905
906 if ( bMergeAction )
907 {
908 ScChangeActionType eSourceType = pSourceAction->GetType();
909 if ( !bShared && pSourceAction->IsDeletedIn() )
910 {
913
914 // lies in a range, which was deleted in this document
915 // -> is omitted
918#if OSL_DEBUG_LEVEL > 0
919 OUString aValue;
920 if ( eSourceType == SC_CAT_CONTENT )
921 aValue = static_cast<const ScChangeActionContent*>(pSourceAction)->GetNewString( m_pDocument.get() );
922 SAL_WARN( "sc", aValue << " omitted");
923#endif
924 }
925 else
926 {
928
929 pThisTrack->SetUser( pSourceAction->GetUser() );
930 pThisTrack->SetFixDateTimeUTC( pSourceAction->GetDateTimeUTC() );
931 sal_uLong nOldActionMax = pThisTrack->GetActionMax();
932
933 bool bExecute = true;
934 sal_uLong nReject = pSourceAction->GetRejectAction();
935 if ( nReject )
936 {
937 if ( bShared )
938 {
939 if ( nReject >= nFirstNewNumber )
940 {
941 nReject += nOffset;
942 }
943 ScChangeAction* pOldAction = pThisTrack->GetAction( nReject );
944 if ( pOldAction && pOldAction->IsVirgin() )
945 {
946 pThisTrack->Reject( pOldAction );
947 bHasRejected = true;
948 bExecute = false;
949 }
950 }
951 else
952 {
953 // decline old action (of the common ones)
954 ScChangeAction* pOldAction = pThisTrack->GetAction( nReject );
955 if (pOldAction && pOldAction->GetState() == SC_CAS_VIRGIN)
956 {
960
961 pThisTrack->Reject(pOldAction);
962 bHasRejected = true; // for Paint
963 }
964 bExecute = false;
965 }
966 }
967
968 if ( bExecute )
969 {
970 // execute normally
971 ScRange aSourceRange = pSourceAction->GetBigRange().MakeRange( GetDocument() );
972 rMarkData.SelectOneTable( aSourceRange.aStart.Tab() );
973 switch ( eSourceType )
974 {
975 case SC_CAT_CONTENT:
976 {
979
980 OSL_ENSURE( aSourceRange.aStart == aSourceRange.aEnd, "huch?" );
981 ScAddress aPos = aSourceRange.aStart;
982 OUString aValue = static_cast<const ScChangeActionContent*>(pSourceAction)->GetNewString( m_pDocument.get() );
984 const ScCellValue& rCell = static_cast<const ScChangeActionContent*>(pSourceAction)->GetNewCell();
985 if (rCell.getType() == CELLTYPE_FORMULA)
986 eMatrix = rCell.getFormula()->GetMatrixFlag();
987 switch ( eMatrix )
988 {
989 case ScMatrixMode::NONE :
990 pViewSh->EnterData( aPos.Col(), aPos.Row(), aPos.Tab(), aValue );
991 break;
993 {
994 SCCOL nCols;
995 SCROW nRows;
996 rCell.getFormula()->GetMatColsRows(nCols, nRows);
997 aSourceRange.aEnd.SetCol( aPos.Col() + nCols - 1 );
998 aSourceRange.aEnd.SetRow( aPos.Row() + nRows - 1 );
999 aValue = aValue.copy(1, aValue.getLength()-2); // remove the 1st and last characters.
1000 GetDocFunc().EnterMatrix( aSourceRange,
1001 nullptr, nullptr, aValue, false, false,
1003 }
1004 break;
1005 case ScMatrixMode::Reference : // do nothing
1006 break;
1007 }
1008 }
1009 break;
1010 case SC_CAT_INSERT_TABS :
1011 {
1012 OUString aName;
1013 m_pDocument->CreateValidTabName( aName );
1014 (void)GetDocFunc().InsertTable( aSourceRange.aStart.Tab(), aName, true, false );
1015 }
1016 break;
1017 case SC_CAT_INSERT_ROWS:
1018 (void)GetDocFunc().InsertCells( aSourceRange, nullptr, INS_INSROWS_BEFORE, true, false );
1019 break;
1020 case SC_CAT_INSERT_COLS:
1021 (void)GetDocFunc().InsertCells( aSourceRange, nullptr, INS_INSCOLS_BEFORE, true, false );
1022 break;
1023 case SC_CAT_DELETE_TABS :
1024 (void)GetDocFunc().DeleteTable( aSourceRange.aStart.Tab(), true );
1025 break;
1026 case SC_CAT_DELETE_ROWS:
1027 {
1028 const ScChangeActionDel* pDel = static_cast<const ScChangeActionDel*>(pSourceAction);
1029 if ( pDel->IsTopDelete() )
1030 {
1031 aSourceRange = pDel->GetOverAllRange().MakeRange( GetDocument() );
1032 (void)GetDocFunc().DeleteCells( aSourceRange, nullptr, DelCellCmd::Rows, false );
1033
1034 // #i101099# [Collaboration] Changes are not correctly shown
1035 if ( bShared )
1036 {
1037 ScChangeAction* pAct = pThisTrack->GetLast();
1038 if ( pAct && pAct->GetType() == eSourceType && pAct->IsDeletedIn() && !pSourceAction->IsDeletedIn() )
1039 {
1040 pAct->RemoveAllDeletedIn();
1041 }
1042 }
1043 }
1044 }
1045 break;
1046 case SC_CAT_DELETE_COLS:
1047 {
1048 const ScChangeActionDel* pDel = static_cast<const ScChangeActionDel*>(pSourceAction);
1049 if ( pDel->IsTopDelete() && !pDel->IsTabDeleteCol() )
1050 { // deleted table contains deleted cols, which are not
1051 aSourceRange = pDel->GetOverAllRange().MakeRange( GetDocument() );
1052 (void)GetDocFunc().DeleteCells( aSourceRange, nullptr, DelCellCmd::Cols, false );
1053 }
1054 }
1055 break;
1056 case SC_CAT_MOVE :
1057 {
1058 const ScChangeActionMove* pMove = static_cast<const ScChangeActionMove*>(pSourceAction);
1059 ScRange aFromRange( pMove->GetFromRange().MakeRange( GetDocument() ) );
1060 (void)GetDocFunc().MoveBlock( aFromRange,
1061 aSourceRange.aStart, true, true, false, false );
1062 }
1063 break;
1064 default:
1065 {
1066 // added to avoid warnings
1067 }
1068 }
1069 }
1070 const OUString& rComment = pSourceAction->GetComment();
1071 if ( !rComment.isEmpty() )
1072 {
1073 ScChangeAction* pAct = pThisTrack->GetLast();
1074 if ( pAct && pAct->GetActionNumber() > nOldActionMax )
1075 pAct->SetComment( rComment );
1076 else
1077 OSL_FAIL( "MergeDocument: what to do with the comment?!?" );
1078 }
1079
1080 // adjust references
1081 pSourceTrack->MergeOwn( const_cast<ScChangeAction*>(pSourceAction), nFirstNewNumber, bShared );
1082
1083 // merge action state
1084 if ( bShared && !pSourceAction->IsRejected() )
1085 {
1086 ScChangeAction* pAct = pThisTrack->GetLast();
1087 if ( pAct && pAct->GetActionNumber() > nOldActionMax )
1088 {
1089 ScChangeTrack::MergeActionState( pAct, pSourceAction );
1090 }
1091 }
1092
1093 // fill merge map
1094 if ( bShared && pMergeMap )
1095 {
1096 ScChangeAction* pAct = pThisTrack->GetLast();
1097 if ( pAct && pAct->GetActionNumber() > nOldActionMax )
1098 {
1099 sal_uLong nActionMax = pAct->GetActionNumber();
1100 sal_uLong nActionCount = nActionMax - nOldActionMax;
1101 sal_uLong nAction = nActionMax - nActionCount + 1;
1102 sal_uLong nSourceAction = pSourceAction->GetActionNumber() - nActionCount + 1;
1103 while ( nAction <= nActionMax )
1104 {
1105 if ( bInverseMap )
1106 {
1107 (*pMergeMap)[ nAction++ ] = nSourceAction++;
1108 }
1109 else
1110 {
1111 (*pMergeMap)[ nSourceAction++ ] = nAction++;
1112 }
1113 }
1114 }
1115 }
1116 }
1117 aProgress.SetStateCountDown( --nNewActionCount );
1118 }
1119 pSourceAction = pSourceAction->GetNext();
1120 }
1121
1122 rMarkData = std::move(aOldMarkData);
1123 pThisTrack->SetUser(aOldUser);
1124 pThisTrack->SetUseFixDateTime( false );
1125
1126 pSourceTrack->Clear();
1127
1128 if (bHasRejected)
1129 PostPaintGridAll(); // Reject() doesn't paint itself
1130
1131 UnlockPaint();
1132}
1133
1135{
1136 if ( !pSharedDocShell )
1137 {
1138 return false;
1139 }
1140
1141 ScChangeTrack* pThisTrack = m_pDocument->GetChangeTrack();
1142 if ( !pThisTrack )
1143 {
1144 return false;
1145 }
1146
1147 ScDocument& rSharedDoc = pSharedDocShell->GetDocument();
1148 ScChangeTrack* pSharedTrack = rSharedDoc.GetChangeTrack();
1149 if ( !pSharedTrack )
1150 {
1151 return false;
1152 }
1153
1154 // reset show changes
1155 ScChangeViewSettings aChangeViewSet;
1156 aChangeViewSet.SetShowChanges( false );
1157 m_pDocument->SetChangeViewSettings( aChangeViewSet );
1158
1159 // find first merge action in this document
1160 bool bIgnore100Sec = !pThisTrack->IsTimeNanoSeconds() || !pSharedTrack->IsTimeNanoSeconds();
1161 ScChangeAction* pThisAction = pThisTrack->GetFirst();
1162 ScChangeAction* pSharedAction = pSharedTrack->GetFirst();
1163 while ( lcl_Equal( pThisAction, pSharedAction, bIgnore100Sec ) )
1164 {
1165 pThisAction = pThisAction->GetNext();
1166 pSharedAction = pSharedAction->GetNext();
1167 }
1168
1169 if ( pSharedAction )
1170 {
1171 if ( pThisAction )
1172 {
1173 // merge own changes into shared document
1174 sal_uLong nActStartShared = pSharedAction->GetActionNumber();
1175 sal_uLong nActEndShared = pSharedTrack->GetActionMax();
1176 std::optional<ScDocument> pTmpDoc(std::in_place);
1177 for ( sal_Int32 nIndex = 0; nIndex < m_pDocument->GetTableCount(); ++nIndex )
1178 {
1179 OUString sTabName;
1180 pTmpDoc->CreateValidTabName( sTabName );
1181 pTmpDoc->InsertTab( SC_TAB_APPEND, sTabName );
1182 }
1183 m_pDocument->GetChangeTrack()->Clone( &*pTmpDoc );
1184 ScChangeActionMergeMap aOwnInverseMergeMap;
1185 pSharedDocShell->MergeDocument( *pTmpDoc, true, true, 0, &aOwnInverseMergeMap, true );
1186 pTmpDoc.reset();
1187 sal_uLong nActStartOwn = nActEndShared + 1;
1188 sal_uLong nActEndOwn = pSharedTrack->GetActionMax();
1189
1190 // find conflicts
1191 ScConflictsList aConflictsList;
1192 ScConflictsFinder aFinder( pSharedTrack, nActStartShared, nActEndShared, nActStartOwn, nActEndOwn, aConflictsList );
1193 if ( aFinder.Find() )
1194 {
1195 ScConflictsListHelper::TransformConflictsList( aConflictsList, nullptr, &aOwnInverseMergeMap );
1196 bool bLoop = true;
1197 while ( bLoop )
1198 {
1199 bLoop = false;
1201 ScConflictsDlg aDlg(pWin, GetViewData(), &rSharedDoc, aConflictsList);
1202 if (aDlg.run() == RET_CANCEL)
1203 {
1204 std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(pWin,
1205 VclMessageType::Question, VclButtonsType::YesNo,
1206 ScResId(STR_DOC_WILLNOTBESAVED)));
1207 xQueryBox->set_default_response(RET_YES);
1208 if (xQueryBox->run() == RET_YES)
1209 {
1210 return false;
1211 }
1212 else
1213 {
1214 bLoop = true;
1215 }
1216 }
1217 }
1218 }
1219
1220 // undo own changes in shared document
1221 pSharedTrack->Undo( nActStartOwn, nActEndOwn );
1222
1223 // clone change track for merging into own document
1224 pTmpDoc.emplace();
1225 for ( sal_Int32 nIndex = 0; nIndex < m_pDocument->GetTableCount(); ++nIndex )
1226 {
1227 OUString sTabName;
1228 pTmpDoc->CreateValidTabName( sTabName );
1229 pTmpDoc->InsertTab( SC_TAB_APPEND, sTabName );
1230 }
1231 pThisTrack->Clone( &*pTmpDoc );
1232
1233 // undo own changes since last save in own document
1234 sal_uLong nStartShared = pThisAction->GetActionNumber();
1235 ScChangeAction* pAction = pThisTrack->GetLast();
1236 while ( pAction && pAction->GetActionNumber() >= nStartShared )
1237 {
1238 pThisTrack->Reject( pAction, true );
1239 pAction = pAction->GetPrev();
1240 }
1241
1242 // #i94841# [Collaboration] When deleting rows is rejected, the content is sometimes wrong
1243 pThisTrack->Undo( nStartShared, pThisTrack->GetActionMax(), true );
1244
1245 // merge shared changes into own document
1246 ScChangeActionMergeMap aSharedMergeMap;
1247 MergeDocument( rSharedDoc, true, true, 0, &aSharedMergeMap );
1248 sal_uLong nEndShared = pThisTrack->GetActionMax();
1249
1250 // resolve conflicts for shared non-content actions
1251 if ( !aConflictsList.empty() )
1252 {
1253 ScConflictsListHelper::TransformConflictsList( aConflictsList, &aSharedMergeMap, nullptr );
1254 ScConflictsResolver aResolver( pThisTrack, aConflictsList );
1255 pAction = pThisTrack->GetAction( nEndShared );
1256 while ( pAction && pAction->GetActionNumber() >= nStartShared )
1257 {
1258 aResolver.HandleAction( pAction, true /*bIsSharedAction*/,
1259 false /*bHandleContentAction*/, true /*bHandleNonContentAction*/ );
1260 pAction = pAction->GetPrev();
1261 }
1262 }
1263 nEndShared = pThisTrack->GetActionMax();
1264
1265 // only show changes from shared document
1266 aChangeViewSet.SetShowChanges( true );
1267 aChangeViewSet.SetShowAccepted( true );
1268 aChangeViewSet.SetHasActionRange();
1269 aChangeViewSet.SetTheActionRange( nStartShared, nEndShared );
1270 m_pDocument->SetChangeViewSettings( aChangeViewSet );
1271
1272 // merge own changes back into own document
1273 sal_uLong nStartOwn = nEndShared + 1;
1274 ScChangeActionMergeMap aOwnMergeMap;
1275 MergeDocument( *pTmpDoc, true, true, nEndShared - nStartShared + 1, &aOwnMergeMap );
1276 pTmpDoc.reset();
1277 sal_uLong nEndOwn = pThisTrack->GetActionMax();
1278
1279 // resolve conflicts for shared content actions and own actions
1280 if ( !aConflictsList.empty() )
1281 {
1282 ScConflictsListHelper::TransformConflictsList( aConflictsList, nullptr, &aOwnMergeMap );
1283 ScConflictsResolver aResolver( pThisTrack, aConflictsList );
1284 pAction = pThisTrack->GetAction( nEndShared );
1285 while ( pAction && pAction->GetActionNumber() >= nStartShared )
1286 {
1287 aResolver.HandleAction( pAction, true /*bIsSharedAction*/,
1288 true /*bHandleContentAction*/, false /*bHandleNonContentAction*/ );
1289 pAction = pAction->GetPrev();
1290 }
1291
1292 pAction = pThisTrack->GetAction( nEndOwn );
1293 while ( pAction && pAction->GetActionNumber() >= nStartOwn )
1294 {
1295 aResolver.HandleAction( pAction, false /*bIsSharedAction*/,
1296 true /*bHandleContentAction*/, true /*bHandleNonContentAction*/ );
1297 pAction = pAction->GetPrev();
1298 }
1299 }
1300 }
1301 else
1302 {
1303 // merge shared changes into own document
1304 sal_uLong nStartShared = pThisTrack->GetActionMax() + 1;
1305 MergeDocument( rSharedDoc, true, true );
1306 sal_uLong nEndShared = pThisTrack->GetActionMax();
1307
1308 // only show changes from shared document
1309 aChangeViewSet.SetShowChanges( true );
1310 aChangeViewSet.SetShowAccepted( true );
1311 aChangeViewSet.SetHasActionRange();
1312 aChangeViewSet.SetTheActionRange( nStartShared, nEndShared );
1313 m_pDocument->SetChangeViewSettings( aChangeViewSet );
1314 }
1315
1316 // update view
1319
1320 std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(GetActiveDialogParent(),
1321 VclMessageType::Info, VclButtonsType::Ok,
1322 ScResId(STR_DOC_UPDATED)));
1323 xInfoBox->run();
1324 }
1325
1326 return ( pThisAction != nullptr );
1327}
1328
1329/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const SCTAB MAXTAB
Definition: address.hxx:70
const SCTAB SC_TAB_APPEND
Definition: address.hxx:90
SfxApplication * SfxGetpApp()
ScChangeActionType
Definition: chgtrack.hxx:63
@ SC_CAT_MOVE
Definition: chgtrack.hxx:71
@ SC_CAT_DELETE_TABS
Definition: chgtrack.hxx:70
@ SC_CAT_INSERT_TABS
Definition: chgtrack.hxx:67
@ SC_CAT_DELETE_ROWS
Definition: chgtrack.hxx:69
@ SC_CAT_CONTENT
Definition: chgtrack.hxx:72
@ SC_CAT_DELETE_COLS
Definition: chgtrack.hxx:68
@ SC_CAT_INSERT_ROWS
Definition: chgtrack.hxx:66
@ SC_CAT_INSERT_COLS
Definition: chgtrack.hxx:65
@ SC_CAS_VIRGIN
Definition: chgtrack.hxx:78
static OutputDevice * GetDefaultDevice()
static weld::MessageDialog * CreateMessageDialog(weld::Widget *pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage, const ILibreOfficeKitNotifier *pNotifier=nullptr)
bool IsEqualIgnoreNanoSec(const DateTime &rDateTime) const
OUString getDate(const Date &rDate) const
OUString getTime(const tools::Time &rTime, bool bSec=true, bool b100Sec=false) const
const vcl::Font & GetFont() const
void SetFont(const vcl::Font &rNewFont)
SAL_WARN_UNUSED_RESULT Point PixelToLogic(const Point &rDevicePt) const
void SetMapMode()
tools::Long GetTextWidth(const OUString &rStr, sal_Int32 nIndex=0, sal_Int32 nLen=-1, vcl::text::TextLayoutCache const *=nullptr, SalLayoutGlyphs const *const pLayoutCache=nullptr) const
const MapMode & GetMapMode() const
SCTAB Tab() const
Definition: address.hxx:283
void SetCol(SCCOL nColP)
Definition: address.hxx:291
SCROW Row() const
Definition: address.hxx:274
void SetRow(SCROW nRowP)
Definition: address.hxx:287
SCCOL Col() const
Definition: address.hxx:279
sal_Int64 Tab() const
Definition: bigrange.hxx:46
ScBigAddress aStart
Definition: bigrange.hxx:108
ScRange MakeRange(const ScDocument &rDoc) const
Definition: bigrange.hxx:134
bool IsTabDeleteCol() const
Definition: chgtrack.cxx:831
ScBigRange GetOverAllRange() const
Definition: chgtrack.cxx:887
bool IsTopDelete() const
Definition: chgtrack.cxx:811
ScBigRange & GetFromRange()
Definition: chgtrack.hxx:524
const OUString & GetComment() const
Definition: chgtrack.hxx:348
void SetComment(const OUString &rStr)
Definition: chgtrack.cxx:533
ScBigRange & GetBigRange()
Definition: chgtrack.hxx:229
bool IsDeletedIn() const
Definition: chgtrack.cxx:318
bool IsRejected() const
Definition: chgtrack.cxx:133
bool IsVisible() const
Definition: chgtrack.cxx:143
sal_uLong GetRejectAction() const
Definition: chgtrack.hxx:318
sal_uLong GetActionNumber() const
Definition: chgtrack.hxx:317
const DateTime & GetDateTimeUTC() const
Definition: chgtrack.hxx:313
ScChangeActionType GetType() const
Definition: chgtrack.hxx:315
virtual OUString GetDescription(ScDocument &rDoc, bool bSplitRange=false, bool bWarning=true) const
Definition: chgtrack.cxx:421
ScChangeAction * GetNext() const
Definition: chgtrack.hxx:320
ScChangeAction * GetPrev() const
Definition: chgtrack.hxx:321
bool IsVirgin() const
Definition: chgtrack.cxx:123
SC_DLLPUBLIC DateTime GetDateTime() const
Definition: chgtrack.cxx:407
ScChangeActionState GetState() const
Definition: chgtrack.hxx:316
const OUString & GetUser() const
Definition: chgtrack.hxx:347
void RemoveAllDeletedIn()
Definition: chgtrack.cxx:335
ScChangeAction * GetLast() const
Definition: chgtrack.hxx:952
SC_DLLPUBLIC void AppendInsert(const ScRange &rRange, bool bEndOfList=false)
Definition: chgtrack.cxx:2763
SC_DLLPUBLIC ScChangeTrack * Clone(ScDocument *pDocument) const
Definition: chgtrack.cxx:4361
void MergePrepare(const ScChangeAction *pFirstMerge, bool bShared)
may only be used in a temporary opened document.
Definition: chgtrack.cxx:3147
SC_DLLPUBLIC ScChangeAction * GetAction(sal_uLong nAction) const
Definition: chgtrack.cxx:2110
SC_DLLPUBLIC void SetUser(const OUString &rUser)
Definition: chgtrack.cxx:2191
SC_DLLPUBLIC void AppendMove(const ScRange &rFromRange, const ScRange &rToRange, ScDocument *pRefDoc)
Definition: chgtrack.cxx:2535
sal_uLong GetActionMax() const
Definition: chgtrack.hxx:953
void MergeOwn(ScChangeAction *pAct, sal_uLong nFirstMerge, bool bShared)
Definition: chgtrack.cxx:3179
void NotifyModified(ScChangeTrackMsgType eMsgType, sal_uLong nStartAction, sal_uLong nEndAction)
Definition: chgtrack.cxx:2250
static bool MergeIgnore(const ScChangeAction &, sal_uLong nFirstMerge)
Definition: chgtrack.cxx:3136
void SetFixDateTimeUTC(const DateTime &rDT)
Definition: chgtrack.hxx:983
SC_DLLPUBLIC void Undo(sal_uLong nStartAction, sal_uLong nEndAction, bool bMerge=false)
Definition: chgtrack.cxx:3044
bool Reject(ScChangeAction *, ScChangeActionMap *, bool bRecursion)
Definition: chgtrack.cxx:4139
bool IsTimeNanoSeconds() const
Definition: chgtrack.hxx:1132
SC_DLLPUBLIC void AppendDeleteRange(const ScRange &, ScDocument *pRefDoc, SCTAB nDz, sal_uLong nRejectingInsert)
Definition: chgtrack.cxx:2399
void SetUseFixDateTime(bool bVal)
Definition: chgtrack.hxx:980
static void MergeActionState(ScChangeAction *pAct, const ScChangeAction *pOtherAct)
Definition: chgtrack.cxx:4622
const OUString & GetUser() const
Definition: chgtrack.hxx:971
ScChangeAction * GetFirst() const
Definition: chgtrack.hxx:951
void SetShowChanges(bool bFlag)
Definition: chgviset.hxx:78
void SetTheActionRange(sal_uLong nFirst, sal_uLong nLast)
Definition: chgviset.hxx:126
void SetShowAccepted(bool bVal)
Definition: chgviset.hxx:113
static void TransformConflictsList(ScConflictsList &rConflictsList, ScChangeActionMergeMap *pSharedMap, ScChangeActionMergeMap *pOwnMap)
void HandleAction(ScChangeAction *pAction, bool bIsSharedAction, bool bHandleContentAction, bool bHandleNonContentAction)
bool MoveBlock(const ScRange &rSource, const ScAddress &rDestPos, bool bCut, bool bRecord, bool bPaint, bool bApi)
Definition: docfunc.cxx:2852
bool InsertCells(const ScRange &rRange, const ScMarkData *pTabMark, InsCellCmd eCmd, bool bRecord, bool bApi, bool bPartOfPaste=false)
Definition: docfunc.cxx:1736
bool DeleteCells(const ScRange &rRange, const ScMarkData *pTabMark, DelCellCmd eCmd, bool bApi)
Definition: docfunc.cxx:2271
SC_DLLPUBLIC bool InsertTable(SCTAB nTab, const OUString &rName, bool bRecord, bool bApi)
Definition: docfunc.cxx:3269
bool DeleteTable(SCTAB nTab, bool bRecord)
Definition: docfunc.cxx:3321
SC_DLLPUBLIC bool EnterMatrix(const ScRange &rRange, const ScMarkData *pTabMark, const ScTokenArray *pTokenArray, const OUString &rString, bool bApi, bool bEnglish, const OUString &rFormulaNmsp, const formula::FormulaGrammar::Grammar)
Definition: docfunc.cxx:4317
void SetYear2000(sal_uInt16 nVal)
Definition: docoptio.hxx:84
void SetAutoSpell(bool bVal)
Definition: docoptio.hxx:54
void SetStdPrecision(sal_uInt16 n)
Definition: docoptio.hxx:79
void SetDate(sal_uInt16 nD, sal_uInt16 nM, sal_Int16 nY)
Definition: docoptio.hxx:68
void UnlockPaint()
Definition: docsh3.cxx:322
void LockPaint()
Definition: docsh3.cxx:317
ScChangeAction * GetChangeAction(const ScAddress &rPos)
Definition: docsh3.cxx:572
void PostPaintCell(SCCOL nCol, SCROW nRow, SCTAB nTab)
Definition: docsh3.cxx:188
static weld::Window * GetActiveDialogParent()
Definition: docsh.cxx:3112
SAL_DLLPRIVATE void UnlockPaint_Impl(bool bDoc)
Definition: docsh3.cxx:241
OutputDevice * GetRefDevice()
Definition: docsh3.cxx:466
void PostPaintGridAll()
Definition: docsh3.cxx:183
double m_nPrtToScreenFactor
Definition: docsh.hxx:86
void UpdateFontList()
Definition: docsh3.cxx:456
bool m_bIsInplace
Definition: docsh.hxx:92
bool MergeSharedDocument(ScDocShell *pSharedDocShell)
Definition: docsh3.cxx:1134
void SetDocumentModified()
Definition: docsh.cxx:2982
sal_uInt16 m_nDocumentLock
Definition: docsh.hxx:98
SAL_DLLPRIVATE void LockPaint_Impl(bool bDoc)
Definition: docsh3.cxx:234
virtual Printer * GetDocumentPrinter() override
Definition: docsh3.cxx:446
SAL_DLLPRIVATE void LockDocument_Impl(sal_uInt16 nNew)
Definition: docsh3.cxx:278
sal_uInt16 SetPrinter(VclPtr< SfxPrinter > const &pNewPrinter, SfxPrinterChangeFlags nDiffFlags=SFX_PRINTER_ALL)
Definition: docsh3.cxx:471
SAL_DLLPRIVATE void UnlockDocument_Impl(sal_uInt16 nNew)
Definition: docsh3.cxx:289
void CompareDocument(ScDocument &rOtherDoc)
Definition: docsh3.cxx:660
const ScDocument & GetDocument() const
Definition: docsh.hxx:219
void UpdatePaintExt(sal_uInt16 &rExtFlags, SCCOL nStartCol, SCROW nStartRow, SCTAB nStartTab, SCCOL nEndCol, SCROW nEndRow, SCTAB nEndTab)
Definition: docsh3.cxx:228
void ExecuteChangeCommentDialog(ScChangeAction *pAction, weld::Window *pParent, bool bPrevNext=true)
Definition: docsh3.cxx:638
void PostDataChanged()
Definition: docsh3.cxx:93
std::shared_ptr< ScDocument > m_pDocument
Definition: docsh.hxx:82
void SetChangeComment(ScChangeAction *pAction, const OUString &rComment)
Definition: docsh3.cxx:620
std::unique_ptr< ScPaintLockData > m_pPaintLockData
Definition: docsh.hxx:104
std::unique_ptr< DocShell_Impl > m_pImpl
Definition: docsh.hxx:87
void PostEditView(ScEditEngineDefaulter *pEditEngine, const ScAddress &rCursorPos)
Definition: docsh3.cxx:79
ScTabViewShell * GetBestViewShell(bool bOnlyVisible=true)
Definition: docsh4.cxx:2623
void PostPaintExtras()
Definition: docsh3.cxx:198
void PostPaint(SCCOL nStartCol, SCROW nStartRow, SCTAB nStartTab, SCCOL nEndCol, SCROW nEndRow, SCTAB nEndTab, PaintPartFlags nPart, sal_uInt16 nExtFlags=0)
Definition: docsh3.cxx:101
void MergeDocument(ScDocument &rOtherDoc, bool bShared=false, bool bCheckDuplicates=false, sal_uLong nOffset=0, ScChangeActionMergeMap *pMergeMap=nullptr, bool bInverseMap=false)
Definition: docsh3.cxx:765
SAL_DLLPRIVATE void InitOptions(bool bForLoading)
Definition: docsh3.cxx:403
SfxPrinter * GetPrinter(bool bCreateIfNotExist=true)
Definition: docsh3.cxx:451
void CalcOutputFactor()
Definition: docsh3.cxx:355
static ScViewData * GetViewData()
Definition: docsh4.cxx:2607
void SetLockCount(sal_uInt16 nNew)
Definition: docsh3.cxx:300
void LockDocument()
Definition: docsh3.cxx:327
void SetFormulaOptions(const ScFormulaOptions &rOpt, bool bForLoading=false)
Definition: docsh6.cxx:419
ScModelObj * GetModel() const
Definition: docsh.hxx:432
ScDocFunc & GetDocFunc()
Definition: docsh.hxx:221
static SCTAB GetCurTab()
Definition: docsh4.cxx:2614
void SetInplace(bool bInplace)
Definition: docsh3.cxx:346
void UnlockDocument()
Definition: docsh3.cxx:333
SfxObjectShell * GetDocumentShell() const
Definition: document.hxx:1083
ScChangeTrack * GetChangeTrack() const
Definition: document.hxx:2494
void GetMatColsRows(SCCOL &nCols, SCROW &nRows) const
ScMatrixMode GetMatrixFlag() const
static SC_DLLPUBLIC double nScreenPPTX
Horizontal pixel per twips factor.
Definition: global.hxx:589
static SC_DLLPUBLIC const LocaleDataWrapper & getLocaleData()
Definition: global.cxx:1055
void UpdateRefDevice()
Definition: inputhdl.cxx:897
todo: It should be possible to have MarkArrays for each table, in order to enable "search all" across...
Definition: markdata.hxx:43
void SelectOneTable(SCTAB nTab)
Definition: markdata.cxx:174
ScInputHandler * GetInputHdl(ScTabViewShell *pViewSh=nullptr, bool bUseRef=true)
Input-Handler.
Definition: scmod.cxx:1355
SC_DLLPUBLIC const ScFormulaOptions & GetFormulaOptions()
Definition: scmod.cxx:831
SC_DLLPUBLIC const ScDocOptions & GetDocOptions()
Definition: scmod.cxx:746
static void GetSpellSettings(LanguageType &rDefLang, LanguageType &rCjkLang, LanguageType &rCtlLang, bool &rAutoSpell)
Definition: scmod.cxx:2255
const ScViewOptions & GetViewOptions()
Definition: scmod.cxx:730
static void fillFontOnly(vcl::Font &rFont, const SfxItemSet &rItemSet, const OutputDevice *pOutDev=nullptr, const Fraction *pScale=nullptr, const SfxItemSet *pCondSet=nullptr, SvtScriptType nScript=SvtScriptType::NONE)
Static helper function to fill a font object from the passed item set.
Definition: patattr.cxx:266
void SetStateCountDown(sal_uInt64 nVal)
Definition: progress.hxx:88
ScRange Combine() const
Definition: rangelst.cxx:1107
void push_back(const ScRange &rRange)
Definition: rangelst.cxx:1137
size_t size() const
Definition: rangelst.hxx:89
ScAddress aEnd
Definition: address.hxx:498
bool Contains(const ScAddress &) const
is Address& fully in Range?
Definition: address.hxx:718
ScAddress aStart
Definition: address.hxx:497
virtual void Notify(SfxBroadcaster &rBC, const SfxHint &rHint) override
Definition: tabvwsh5.cxx:42
static ScTabViewShell * GetActiveViewShell()
Definition: tabvwsh4.cxx:1076
ScViewData & GetViewData()
Definition: tabview.hxx:344
ScMarkData & GetMarkData()
Definition: viewdata.cxx:3146
ScDocShell * GetDocShell() const
Definition: viewdata.hxx:354
void EnterData(SCCOL nCol, SCROW nRow, SCTAB nTab, const OUString &rString, const EditTextObject *pData=nullptr, bool bMatrixExpand=false)
Definition: viewfunc.cxx:384
void setLock(bool bLock)
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
const SfxPoolItem & Get(sal_uInt16 nWhich, bool bSrchInParent=true) const
static void notifyDocumentSizeChangedAllViews(vcl::ITiledRenderable *pDoc, bool bInvalidateAll=true)
const OUString & GetName() const
SfxMedium * GetMedium() const
void PutItem(const SfxPoolItem &rItem)
SfxItemPool & GetPool() const
SfxViewShell * GetViewShell() const
virtual SfxStyleSheetBase * Find(const OUString &, SfxStyleFamily eFam, SfxStyleSearchBits n=SfxStyleSearchBits::All)
virtual SfxItemSet & GetItemSet()
static SAL_WARN_UNUSED_RESULT SfxViewFrame * GetNext(const SfxViewFrame &rPrev, const SfxObjectShell *pDoc=nullptr, bool bOnlyVisible=true)
static SAL_WARN_UNUSED_RESULT SfxViewFrame * GetFirst(const SfxObjectShell *pDoc=nullptr, bool bOnlyVisible=true)
constexpr tools::Long Height() const
constexpr tools::Long Width() const
static const sal_uInt16 UNLIMITED_PRECISION
void SetLandscape(bool bL)
bool IsLandscape() const
static Size GetPaperSize(Paper ePaper, MapUnit eUnit=MapUnit::MapTwip)
bool is() const
static bool IsFuzzing()
virtual short run()
::std::vector< ScConflictsListEntry > ScConflictsList
int nCount
static bool lcl_FindAction(ScDocument &rDoc, const ScChangeAction *pAction, ScDocument &rSearchDoc, const ScChangeAction *pFirstSearchAction, const ScChangeAction *pLastSearchAction, bool bIgnore100Sec)
Definition: docsh3.cxx:733
static bool lcl_Equal(const ScChangeAction *pA, const ScChangeAction *pB, bool bIgnore100Sec)
Definition: docsh3.cxx:721
#define SC_PF_WHOLEROWS
Definition: docsh.hxx:78
std::unordered_map< sal_uLong, sal_uLong > ScChangeActionMergeMap
Definition: docsh.hxx:65
#define SC_PF_TESTMERGE
Definition: docsh.hxx:77
#define SC_PF_LINES
Definition: docsh.hxx:76
DocumentType eType
ScMatrixMode
@ CELLTYPE_FORMULA
Definition: global.hxx:276
@ INS_INSCOLS_BEFORE
Definition: global.hxx:294
@ INS_INSROWS_BEFORE
Definition: global.hxx:293
PaintPartFlags
Definition: global.hxx:109
sal_Int32 nIndex
OUString aName
sal_Int64 n
#define SAL_WARN(area, stream)
int i
constexpr Point convert(const Point &rPoint, o3tl::Length eFrom, o3tl::Length eTo)
long Long
OUString ScResId(TranslateId aId)
Definition: scdll.cxx:90
constexpr TypedWhichId< SvxSizeItem > ATTR_PAGE_SIZE(161)
constexpr TypedWhichId< ScPatternAttr > ATTR_PATTERN(156)
constexpr TypedWhichId< SvxPageItem > ATTR_PAGE(159)
#define SC_MOD()
Definition: scmod.hxx:247
static SfxItemSet & rSet
sal_uIntPtr sal_uLong
Store arbitrary cell value of any kind.
Definition: cellvalue.hxx:32
CellType getType() const
Definition: cellvalue.cxx:296
ScFormulaCell * getFormula() const
Definition: cellvalue.hxx:59
sal_Int16 SCTAB
Definition: types.hxx:22
sal_Int16 SCCOL
Definition: types.hxx:21
sal_Int32 SCROW
Definition: types.hxx:17
RET_CANCEL
RET_YES
#define SFX_PRINTERROR_BUSY
SfxPrinterChangeFlags