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 = comphelper::getFromUnoTunnel<ScModelObj>(this->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->GetFont(aDefFont, SC_AUTOCOL_BLACK, 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->GetFont(aDefFont, SC_AUTOCOL_BLACK, 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::XDocumentPropertiesSupplier> xDPS(
700 GetModel(), uno::UNO_QUERY_THROW);
701 uno::Reference<document::XDocumentProperties> xDocProps(
702 xDPS->getDocumentProperties());
703 OSL_ENSURE(xDocProps.is(), "no DocumentProperties");
704 OUString aDocUser = xDocProps->getModifiedBy();
705
706 if ( !aDocUser.isEmpty() )
707 pTrack->SetUser( aDocUser );
708 }
709 }
710
711 m_pDocument->CompareDocument( rOtherDoc );
712
713 pTrack = m_pDocument->GetChangeTrack();
714 if ( pTrack )
715 pTrack->SetUser( aOldUser );
716
719}
720
721// Merge (combine documents)
722
723static bool lcl_Equal( const ScChangeAction* pA, const ScChangeAction* pB, bool bIgnore100Sec )
724{
725 return pA && pB &&
726 pA->GetActionNumber() == pB->GetActionNumber() &&
727 pA->GetType() == pB->GetType() &&
728 pA->GetUser() == pB->GetUser() &&
729 (bIgnore100Sec ?
731 pA->GetDateTimeUTC() == pB->GetDateTimeUTC());
732 // don't compare state if an old change has been accepted
733}
734
735static bool lcl_FindAction( ScDocument& rDoc, const ScChangeAction* pAction, ScDocument& rSearchDoc, const ScChangeAction* pFirstSearchAction, const ScChangeAction* pLastSearchAction, bool bIgnore100Sec )
736{
737 if ( !pAction || !pFirstSearchAction || !pLastSearchAction )
738 {
739 return false;
740 }
741
742 sal_uLong nLastSearchAction = pLastSearchAction->GetActionNumber();
743 const ScChangeAction* pA = pFirstSearchAction;
744 while ( pA && pA->GetActionNumber() <= nLastSearchAction )
745 {
746 if ( pAction->GetType() == pA->GetType() &&
747 pAction->GetUser() == pA->GetUser() &&
748 (bIgnore100Sec ?
750 pAction->GetDateTimeUTC() == pA->GetDateTimeUTC() ) &&
751 pAction->GetBigRange() == pA->GetBigRange() )
752 {
753 OUString aActionDesc = pAction->GetDescription(rDoc, true);
754 OUString aADesc = pA->GetDescription(rSearchDoc, true);
755 if (aActionDesc == aADesc)
756 {
757 OSL_FAIL( "lcl_FindAction(): found equal action!" );
758 return true;
759 }
760 }
761 pA = pA->GetNext();
762 }
763
764 return false;
765}
766
767void ScDocShell::MergeDocument( ScDocument& rOtherDoc, bool bShared, bool bCheckDuplicates, sal_uLong nOffset, ScChangeActionMergeMap* pMergeMap, bool bInverseMap )
768{
769 ScTabViewShell* pViewSh = GetBestViewShell( false );
770 if (!pViewSh)
771 return;
772
773 ScChangeTrack* pSourceTrack = rOtherDoc.GetChangeTrack();
774 if (!pSourceTrack)
775 return;
776
777 ScChangeTrack* pThisTrack = m_pDocument->GetChangeTrack();
778 if ( !pThisTrack )
779 { // turn on
780 m_pDocument->StartChangeTracking();
781 pThisTrack = m_pDocument->GetChangeTrack();
782 OSL_ENSURE(pThisTrack,"ChangeTracking not enabled?");
783 if ( !bShared )
784 {
785 // turn on visual RedLining
786 ScChangeViewSettings aChangeViewSet;
787 aChangeViewSet.SetShowChanges(true);
788 m_pDocument->SetChangeViewSettings(aChangeViewSet);
789 }
790 }
791
792 // include Nano seconds in compare?
793 bool bIgnore100Sec = !pSourceTrack->IsTimeNanoSeconds() ||
794 !pThisTrack->IsTimeNanoSeconds();
795
796 // find common initial position
797 sal_uLong nFirstNewNumber = 0;
798 const ScChangeAction* pSourceAction = pSourceTrack->GetFirst();
799 const ScChangeAction* pThisAction = pThisTrack->GetFirst();
800 // skip identical actions
801 while ( lcl_Equal( pSourceAction, pThisAction, bIgnore100Sec ) )
802 {
803 nFirstNewNumber = pSourceAction->GetActionNumber() + 1;
804 pSourceAction = pSourceAction->GetNext();
805 pThisAction = pThisAction->GetNext();
806 }
807 // pSourceAction and pThisAction now point to the first "own" actions
808 // The common actions before don't interest at all
809
811
812 const ScChangeAction* pFirstMergeAction = pSourceAction;
813 const ScChangeAction* pFirstSearchAction = pThisAction;
814
815 // #i94841# [Collaboration] When deleting rows is rejected, the content is sometimes wrong
816 const ScChangeAction* pLastSearchAction = pThisTrack->GetLast();
817
818 // Create MergeChangeData from the following actions
819 sal_uLong nNewActionCount = 0;
820 const ScChangeAction* pCount = pSourceAction;
821 while ( pCount )
822 {
823 if ( bShared || !ScChangeTrack::MergeIgnore( *pCount, nFirstNewNumber ) )
824 ++nNewActionCount;
825 pCount = pCount->GetNext();
826 }
827 if (!nNewActionCount)
828 return;
829 // from here on no return
830
831 ScProgress aProgress( this, "...", nNewActionCount, true );
832
833 sal_uLong nLastMergeAction = pSourceTrack->GetLast()->GetActionNumber();
834 // UpdateReference-Undo, valid references for the last common state
835 pSourceTrack->MergePrepare( pFirstMergeAction, bShared );
836
837 // adjust MergeChangeData to all yet following actions in this document
838 // -> references valid for this document
839 while ( pThisAction )
840 {
841 // #i87049# [Collaboration] Conflict between delete row and insert content is not merged correctly
842 if ( !bShared || !ScChangeTrack::MergeIgnore( *pThisAction, nFirstNewNumber ) )
843 {
844 ScChangeActionType eType = pThisAction->GetType();
845 switch ( eType )
846 {
847 case SC_CAT_INSERT_COLS :
848 case SC_CAT_INSERT_ROWS :
849 case SC_CAT_INSERT_TABS :
850 pSourceTrack->AppendInsert( pThisAction->GetBigRange().MakeRange( GetDocument() ) );
851 break;
852 case SC_CAT_DELETE_COLS :
853 case SC_CAT_DELETE_ROWS :
854 case SC_CAT_DELETE_TABS :
855 {
856 const ScChangeActionDel* pDel = static_cast<const ScChangeActionDel*>(pThisAction);
857 if ( pDel->IsTopDelete() && !pDel->IsTabDeleteCol() )
858 { // deleted table contains deleted cols, which are not
859 sal_uLong nStart, nEnd;
860 pSourceTrack->AppendDeleteRange(
861 pDel->GetOverAllRange().MakeRange( GetDocument() ), nullptr, nStart, nEnd );
862 }
863 }
864 break;
865 case SC_CAT_MOVE :
866 {
867 const ScChangeActionMove* pMove = static_cast<const ScChangeActionMove*>(pThisAction);
868 pSourceTrack->AppendMove( pMove->GetFromRange().MakeRange( GetDocument() ),
869 pMove->GetBigRange().MakeRange( GetDocument() ), nullptr );
870 }
871 break;
872 default:
873 {
874 // added to avoid warnings
875 }
876 }
877 }
878 pThisAction = pThisAction->GetNext();
879 }
880
881 LockPaint(); // #i73877# no repainting after each action
882
883 // take over MergeChangeData into the current document
884 bool bHasRejected = false;
885 OUString aOldUser = pThisTrack->GetUser();
886 pThisTrack->SetUseFixDateTime( true );
887 ScMarkData& rMarkData = pViewSh->GetViewData().GetMarkData();
888 ScMarkData aOldMarkData( rMarkData );
889 pSourceAction = pFirstMergeAction;
890 while ( pSourceAction && pSourceAction->GetActionNumber() <= nLastMergeAction )
891 {
892 bool bMergeAction = false;
893 if ( bShared )
894 {
895 if ( !bCheckDuplicates || !lcl_FindAction( rOtherDoc, pSourceAction, *m_pDocument, pFirstSearchAction, pLastSearchAction, bIgnore100Sec ) )
896 {
897 bMergeAction = true;
898 }
899 }
900 else
901 {
902 if ( !ScChangeTrack::MergeIgnore( *pSourceAction, nFirstNewNumber ) )
903 {
904 bMergeAction = true;
905 }
906 }
907
908 if ( bMergeAction )
909 {
910 ScChangeActionType eSourceType = pSourceAction->GetType();
911 if ( !bShared && pSourceAction->IsDeletedIn() )
912 {
915
916 // lies in a range, which was deleted in this document
917 // -> is omitted
920#if OSL_DEBUG_LEVEL > 0
921 OUString aValue;
922 if ( eSourceType == SC_CAT_CONTENT )
923 aValue = static_cast<const ScChangeActionContent*>(pSourceAction)->GetNewString( m_pDocument.get() );
924 SAL_WARN( "sc", aValue << " omitted");
925#endif
926 }
927 else
928 {
930
931 pThisTrack->SetUser( pSourceAction->GetUser() );
932 pThisTrack->SetFixDateTimeUTC( pSourceAction->GetDateTimeUTC() );
933 sal_uLong nOldActionMax = pThisTrack->GetActionMax();
934
935 bool bExecute = true;
936 sal_uLong nReject = pSourceAction->GetRejectAction();
937 if ( nReject )
938 {
939 if ( bShared )
940 {
941 if ( nReject >= nFirstNewNumber )
942 {
943 nReject += nOffset;
944 }
945 ScChangeAction* pOldAction = pThisTrack->GetAction( nReject );
946 if ( pOldAction && pOldAction->IsVirgin() )
947 {
948 pThisTrack->Reject( pOldAction );
949 bHasRejected = true;
950 bExecute = false;
951 }
952 }
953 else
954 {
955 // decline old action (of the common ones)
956 ScChangeAction* pOldAction = pThisTrack->GetAction( nReject );
957 if (pOldAction && pOldAction->GetState() == SC_CAS_VIRGIN)
958 {
962
963 pThisTrack->Reject(pOldAction);
964 bHasRejected = true; // for Paint
965 }
966 bExecute = false;
967 }
968 }
969
970 if ( bExecute )
971 {
972 // execute normally
973 ScRange aSourceRange = pSourceAction->GetBigRange().MakeRange( GetDocument() );
974 rMarkData.SelectOneTable( aSourceRange.aStart.Tab() );
975 switch ( eSourceType )
976 {
977 case SC_CAT_CONTENT:
978 {
981
982 OSL_ENSURE( aSourceRange.aStart == aSourceRange.aEnd, "huch?" );
983 ScAddress aPos = aSourceRange.aStart;
984 OUString aValue = static_cast<const ScChangeActionContent*>(pSourceAction)->GetNewString( m_pDocument.get() );
986 const ScCellValue& rCell = static_cast<const ScChangeActionContent*>(pSourceAction)->GetNewCell();
987 if (rCell.getType() == CELLTYPE_FORMULA)
988 eMatrix = rCell.getFormula()->GetMatrixFlag();
989 switch ( eMatrix )
990 {
991 case ScMatrixMode::NONE :
992 pViewSh->EnterData( aPos.Col(), aPos.Row(), aPos.Tab(), aValue );
993 break;
995 {
996 SCCOL nCols;
997 SCROW nRows;
998 rCell.getFormula()->GetMatColsRows(nCols, nRows);
999 aSourceRange.aEnd.SetCol( aPos.Col() + nCols - 1 );
1000 aSourceRange.aEnd.SetRow( aPos.Row() + nRows - 1 );
1001 aValue = aValue.copy(1, aValue.getLength()-2); // remove the 1st and last characters.
1002 GetDocFunc().EnterMatrix( aSourceRange,
1003 nullptr, nullptr, aValue, false, false,
1005 }
1006 break;
1007 case ScMatrixMode::Reference : // do nothing
1008 break;
1009 }
1010 }
1011 break;
1012 case SC_CAT_INSERT_TABS :
1013 {
1014 OUString aName;
1015 m_pDocument->CreateValidTabName( aName );
1016 (void)GetDocFunc().InsertTable( aSourceRange.aStart.Tab(), aName, true, false );
1017 }
1018 break;
1019 case SC_CAT_INSERT_ROWS:
1020 (void)GetDocFunc().InsertCells( aSourceRange, nullptr, INS_INSROWS_BEFORE, true, false );
1021 break;
1022 case SC_CAT_INSERT_COLS:
1023 (void)GetDocFunc().InsertCells( aSourceRange, nullptr, INS_INSCOLS_BEFORE, true, false );
1024 break;
1025 case SC_CAT_DELETE_TABS :
1026 (void)GetDocFunc().DeleteTable( aSourceRange.aStart.Tab(), true );
1027 break;
1028 case SC_CAT_DELETE_ROWS:
1029 {
1030 const ScChangeActionDel* pDel = static_cast<const ScChangeActionDel*>(pSourceAction);
1031 if ( pDel->IsTopDelete() )
1032 {
1033 aSourceRange = pDel->GetOverAllRange().MakeRange( GetDocument() );
1034 (void)GetDocFunc().DeleteCells( aSourceRange, nullptr, DelCellCmd::Rows, false );
1035
1036 // #i101099# [Collaboration] Changes are not correctly shown
1037 if ( bShared )
1038 {
1039 ScChangeAction* pAct = pThisTrack->GetLast();
1040 if ( pAct && pAct->GetType() == eSourceType && pAct->IsDeletedIn() && !pSourceAction->IsDeletedIn() )
1041 {
1042 pAct->RemoveAllDeletedIn();
1043 }
1044 }
1045 }
1046 }
1047 break;
1048 case SC_CAT_DELETE_COLS:
1049 {
1050 const ScChangeActionDel* pDel = static_cast<const ScChangeActionDel*>(pSourceAction);
1051 if ( pDel->IsTopDelete() && !pDel->IsTabDeleteCol() )
1052 { // deleted table contains deleted cols, which are not
1053 aSourceRange = pDel->GetOverAllRange().MakeRange( GetDocument() );
1054 (void)GetDocFunc().DeleteCells( aSourceRange, nullptr, DelCellCmd::Cols, false );
1055 }
1056 }
1057 break;
1058 case SC_CAT_MOVE :
1059 {
1060 const ScChangeActionMove* pMove = static_cast<const ScChangeActionMove*>(pSourceAction);
1061 ScRange aFromRange( pMove->GetFromRange().MakeRange( GetDocument() ) );
1062 (void)GetDocFunc().MoveBlock( aFromRange,
1063 aSourceRange.aStart, true, true, false, false );
1064 }
1065 break;
1066 default:
1067 {
1068 // added to avoid warnings
1069 }
1070 }
1071 }
1072 const OUString& rComment = pSourceAction->GetComment();
1073 if ( !rComment.isEmpty() )
1074 {
1075 ScChangeAction* pAct = pThisTrack->GetLast();
1076 if ( pAct && pAct->GetActionNumber() > nOldActionMax )
1077 pAct->SetComment( rComment );
1078 else
1079 OSL_FAIL( "MergeDocument: what to do with the comment?!?" );
1080 }
1081
1082 // adjust references
1083 pSourceTrack->MergeOwn( const_cast<ScChangeAction*>(pSourceAction), nFirstNewNumber, bShared );
1084
1085 // merge action state
1086 if ( bShared && !pSourceAction->IsRejected() )
1087 {
1088 ScChangeAction* pAct = pThisTrack->GetLast();
1089 if ( pAct && pAct->GetActionNumber() > nOldActionMax )
1090 {
1091 ScChangeTrack::MergeActionState( pAct, pSourceAction );
1092 }
1093 }
1094
1095 // fill merge map
1096 if ( bShared && pMergeMap )
1097 {
1098 ScChangeAction* pAct = pThisTrack->GetLast();
1099 if ( pAct && pAct->GetActionNumber() > nOldActionMax )
1100 {
1101 sal_uLong nActionMax = pAct->GetActionNumber();
1102 sal_uLong nActionCount = nActionMax - nOldActionMax;
1103 sal_uLong nAction = nActionMax - nActionCount + 1;
1104 sal_uLong nSourceAction = pSourceAction->GetActionNumber() - nActionCount + 1;
1105 while ( nAction <= nActionMax )
1106 {
1107 if ( bInverseMap )
1108 {
1109 (*pMergeMap)[ nAction++ ] = nSourceAction++;
1110 }
1111 else
1112 {
1113 (*pMergeMap)[ nSourceAction++ ] = nAction++;
1114 }
1115 }
1116 }
1117 }
1118 }
1119 aProgress.SetStateCountDown( --nNewActionCount );
1120 }
1121 pSourceAction = pSourceAction->GetNext();
1122 }
1123
1124 rMarkData = std::move(aOldMarkData);
1125 pThisTrack->SetUser(aOldUser);
1126 pThisTrack->SetUseFixDateTime( false );
1127
1128 pSourceTrack->Clear();
1129
1130 if (bHasRejected)
1131 PostPaintGridAll(); // Reject() doesn't paint itself
1132
1133 UnlockPaint();
1134}
1135
1137{
1138 if ( !pSharedDocShell )
1139 {
1140 return false;
1141 }
1142
1143 ScChangeTrack* pThisTrack = m_pDocument->GetChangeTrack();
1144 if ( !pThisTrack )
1145 {
1146 return false;
1147 }
1148
1149 ScDocument& rSharedDoc = pSharedDocShell->GetDocument();
1150 ScChangeTrack* pSharedTrack = rSharedDoc.GetChangeTrack();
1151 if ( !pSharedTrack )
1152 {
1153 return false;
1154 }
1155
1156 // reset show changes
1157 ScChangeViewSettings aChangeViewSet;
1158 aChangeViewSet.SetShowChanges( false );
1159 m_pDocument->SetChangeViewSettings( aChangeViewSet );
1160
1161 // find first merge action in this document
1162 bool bIgnore100Sec = !pThisTrack->IsTimeNanoSeconds() || !pSharedTrack->IsTimeNanoSeconds();
1163 ScChangeAction* pThisAction = pThisTrack->GetFirst();
1164 ScChangeAction* pSharedAction = pSharedTrack->GetFirst();
1165 while ( lcl_Equal( pThisAction, pSharedAction, bIgnore100Sec ) )
1166 {
1167 pThisAction = pThisAction->GetNext();
1168 pSharedAction = pSharedAction->GetNext();
1169 }
1170
1171 if ( pSharedAction )
1172 {
1173 if ( pThisAction )
1174 {
1175 // merge own changes into shared document
1176 sal_uLong nActStartShared = pSharedAction->GetActionNumber();
1177 sal_uLong nActEndShared = pSharedTrack->GetActionMax();
1178 std::optional<ScDocument> pTmpDoc(std::in_place);
1179 for ( sal_Int32 nIndex = 0; nIndex < m_pDocument->GetTableCount(); ++nIndex )
1180 {
1181 OUString sTabName;
1182 pTmpDoc->CreateValidTabName( sTabName );
1183 pTmpDoc->InsertTab( SC_TAB_APPEND, sTabName );
1184 }
1185 m_pDocument->GetChangeTrack()->Clone( &*pTmpDoc );
1186 ScChangeActionMergeMap aOwnInverseMergeMap;
1187 pSharedDocShell->MergeDocument( *pTmpDoc, true, true, 0, &aOwnInverseMergeMap, true );
1188 pTmpDoc.reset();
1189 sal_uLong nActStartOwn = nActEndShared + 1;
1190 sal_uLong nActEndOwn = pSharedTrack->GetActionMax();
1191
1192 // find conflicts
1193 ScConflictsList aConflictsList;
1194 ScConflictsFinder aFinder( pSharedTrack, nActStartShared, nActEndShared, nActStartOwn, nActEndOwn, aConflictsList );
1195 if ( aFinder.Find() )
1196 {
1197 ScConflictsListHelper::TransformConflictsList( aConflictsList, nullptr, &aOwnInverseMergeMap );
1198 bool bLoop = true;
1199 while ( bLoop )
1200 {
1201 bLoop = false;
1203 ScConflictsDlg aDlg(pWin, GetViewData(), &rSharedDoc, aConflictsList);
1204 if (aDlg.run() == RET_CANCEL)
1205 {
1206 std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(pWin,
1207 VclMessageType::Question, VclButtonsType::YesNo,
1208 ScResId(STR_DOC_WILLNOTBESAVED)));
1209 xQueryBox->set_default_response(RET_YES);
1210 if (xQueryBox->run() == RET_YES)
1211 {
1212 return false;
1213 }
1214 else
1215 {
1216 bLoop = true;
1217 }
1218 }
1219 }
1220 }
1221
1222 // undo own changes in shared document
1223 pSharedTrack->Undo( nActStartOwn, nActEndOwn );
1224
1225 // clone change track for merging into own document
1226 pTmpDoc.emplace();
1227 for ( sal_Int32 nIndex = 0; nIndex < m_pDocument->GetTableCount(); ++nIndex )
1228 {
1229 OUString sTabName;
1230 pTmpDoc->CreateValidTabName( sTabName );
1231 pTmpDoc->InsertTab( SC_TAB_APPEND, sTabName );
1232 }
1233 pThisTrack->Clone( &*pTmpDoc );
1234
1235 // undo own changes since last save in own document
1236 sal_uLong nStartShared = pThisAction->GetActionNumber();
1237 ScChangeAction* pAction = pThisTrack->GetLast();
1238 while ( pAction && pAction->GetActionNumber() >= nStartShared )
1239 {
1240 pThisTrack->Reject( pAction, true );
1241 pAction = pAction->GetPrev();
1242 }
1243
1244 // #i94841# [Collaboration] When deleting rows is rejected, the content is sometimes wrong
1245 pThisTrack->Undo( nStartShared, pThisTrack->GetActionMax(), true );
1246
1247 // merge shared changes into own document
1248 ScChangeActionMergeMap aSharedMergeMap;
1249 MergeDocument( rSharedDoc, true, true, 0, &aSharedMergeMap );
1250 sal_uLong nEndShared = pThisTrack->GetActionMax();
1251
1252 // resolve conflicts for shared non-content actions
1253 if ( !aConflictsList.empty() )
1254 {
1255 ScConflictsListHelper::TransformConflictsList( aConflictsList, &aSharedMergeMap, nullptr );
1256 ScConflictsResolver aResolver( pThisTrack, aConflictsList );
1257 pAction = pThisTrack->GetAction( nEndShared );
1258 while ( pAction && pAction->GetActionNumber() >= nStartShared )
1259 {
1260 aResolver.HandleAction( pAction, true /*bIsSharedAction*/,
1261 false /*bHandleContentAction*/, true /*bHandleNonContentAction*/ );
1262 pAction = pAction->GetPrev();
1263 }
1264 }
1265 nEndShared = pThisTrack->GetActionMax();
1266
1267 // only show changes from shared document
1268 aChangeViewSet.SetShowChanges( true );
1269 aChangeViewSet.SetShowAccepted( true );
1270 aChangeViewSet.SetHasActionRange();
1271 aChangeViewSet.SetTheActionRange( nStartShared, nEndShared );
1272 m_pDocument->SetChangeViewSettings( aChangeViewSet );
1273
1274 // merge own changes back into own document
1275 sal_uLong nStartOwn = nEndShared + 1;
1276 ScChangeActionMergeMap aOwnMergeMap;
1277 MergeDocument( *pTmpDoc, true, true, nEndShared - nStartShared + 1, &aOwnMergeMap );
1278 pTmpDoc.reset();
1279 sal_uLong nEndOwn = pThisTrack->GetActionMax();
1280
1281 // resolve conflicts for shared content actions and own actions
1282 if ( !aConflictsList.empty() )
1283 {
1284 ScConflictsListHelper::TransformConflictsList( aConflictsList, nullptr, &aOwnMergeMap );
1285 ScConflictsResolver aResolver( pThisTrack, aConflictsList );
1286 pAction = pThisTrack->GetAction( nEndShared );
1287 while ( pAction && pAction->GetActionNumber() >= nStartShared )
1288 {
1289 aResolver.HandleAction( pAction, true /*bIsSharedAction*/,
1290 true /*bHandleContentAction*/, false /*bHandleNonContentAction*/ );
1291 pAction = pAction->GetPrev();
1292 }
1293
1294 pAction = pThisTrack->GetAction( nEndOwn );
1295 while ( pAction && pAction->GetActionNumber() >= nStartOwn )
1296 {
1297 aResolver.HandleAction( pAction, false /*bIsSharedAction*/,
1298 true /*bHandleContentAction*/, true /*bHandleNonContentAction*/ );
1299 pAction = pAction->GetPrev();
1300 }
1301 }
1302 }
1303 else
1304 {
1305 // merge shared changes into own document
1306 sal_uLong nStartShared = pThisTrack->GetActionMax() + 1;
1307 MergeDocument( rSharedDoc, true, true );
1308 sal_uLong nEndShared = pThisTrack->GetActionMax();
1309
1310 // only show changes from shared document
1311 aChangeViewSet.SetShowChanges( true );
1312 aChangeViewSet.SetShowAccepted( true );
1313 aChangeViewSet.SetHasActionRange();
1314 aChangeViewSet.SetTheActionRange( nStartShared, nEndShared );
1315 m_pDocument->SetChangeViewSettings( aChangeViewSet );
1316 }
1317
1318 // update view
1321
1322 std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(GetActiveDialogParent(),
1323 VclMessageType::Info, VclButtonsType::Ok,
1324 ScResId(STR_DOC_UPDATED)));
1325 xInfoBox->run();
1326 }
1327
1328 return ( pThisAction != nullptr );
1329}
1330
1331/* 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, bool bMobile=false)
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:834
ScBigRange GetOverAllRange() const
Definition: chgtrack.cxx:890
bool IsTopDelete() const
Definition: chgtrack.cxx:814
ScBigRange & GetFromRange()
Definition: chgtrack.hxx:526
const OUString & GetComment() const
Definition: chgtrack.hxx:350
void SetComment(const OUString &rStr)
Definition: chgtrack.cxx:536
ScBigRange & GetBigRange()
Definition: chgtrack.hxx:231
bool IsDeletedIn() const
Definition: chgtrack.cxx:317
bool IsRejected() const
Definition: chgtrack.cxx:132
bool IsVisible() const
Definition: chgtrack.cxx:142
sal_uLong GetRejectAction() const
Definition: chgtrack.hxx:320
sal_uLong GetActionNumber() const
Definition: chgtrack.hxx:319
const DateTime & GetDateTimeUTC() const
Definition: chgtrack.hxx:315
ScChangeActionType GetType() const
Definition: chgtrack.hxx:317
virtual OUString GetDescription(ScDocument &rDoc, bool bSplitRange=false, bool bWarning=true) const
Definition: chgtrack.cxx:420
ScChangeAction * GetNext() const
Definition: chgtrack.hxx:322
ScChangeAction * GetPrev() const
Definition: chgtrack.hxx:323
bool IsVirgin() const
Definition: chgtrack.cxx:122
SC_DLLPUBLIC DateTime GetDateTime() const
Definition: chgtrack.cxx:406
ScChangeActionState GetState() const
Definition: chgtrack.hxx:318
const OUString & GetUser() const
Definition: chgtrack.hxx:349
void RemoveAllDeletedIn()
Definition: chgtrack.cxx:334
ScChangeAction * GetLast() const
Definition: chgtrack.hxx:954
SC_DLLPUBLIC void AppendInsert(const ScRange &rRange, bool bEndOfList=false)
Definition: chgtrack.cxx:2753
SC_DLLPUBLIC ScChangeTrack * Clone(ScDocument *pDocument) const
Definition: chgtrack.cxx:4351
void MergePrepare(const ScChangeAction *pFirstMerge, bool bShared)
may only be used in a temporary opened document.
Definition: chgtrack.cxx:3137
SC_DLLPUBLIC ScChangeAction * GetAction(sal_uLong nAction) const
Definition: chgtrack.cxx:2115
SC_DLLPUBLIC void SetUser(const OUString &rUser)
Definition: chgtrack.cxx:2181
SC_DLLPUBLIC void AppendMove(const ScRange &rFromRange, const ScRange &rToRange, ScDocument *pRefDoc)
Definition: chgtrack.cxx:2525
sal_uLong GetActionMax() const
Definition: chgtrack.hxx:955
void MergeOwn(ScChangeAction *pAct, sal_uLong nFirstMerge, bool bShared)
Definition: chgtrack.cxx:3169
void NotifyModified(ScChangeTrackMsgType eMsgType, sal_uLong nStartAction, sal_uLong nEndAction)
Definition: chgtrack.cxx:2240
static bool MergeIgnore(const ScChangeAction &, sal_uLong nFirstMerge)
Definition: chgtrack.cxx:3126
void SetFixDateTimeUTC(const DateTime &rDT)
Definition: chgtrack.hxx:984
SC_DLLPUBLIC void Undo(sal_uLong nStartAction, sal_uLong nEndAction, bool bMerge=false)
Definition: chgtrack.cxx:3034
bool Reject(ScChangeAction *, ScChangeActionMap *, bool bRecursion)
Definition: chgtrack.cxx:4129
bool IsTimeNanoSeconds() const
Definition: chgtrack.hxx:1133
SC_DLLPUBLIC void AppendDeleteRange(const ScRange &, ScDocument *pRefDoc, SCTAB nDz, sal_uLong nRejectingInsert)
Definition: chgtrack.cxx:2389
void SetUseFixDateTime(bool bVal)
Definition: chgtrack.hxx:981
static void MergeActionState(ScChangeAction *pAct, const ScChangeAction *pOtherAct)
Definition: chgtrack.cxx:4612
const OUString & GetUser() const
Definition: chgtrack.hxx:972
ScChangeAction * GetFirst() const
Definition: chgtrack.hxx:953
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:3091
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:1136
void SetDocumentModified()
Definition: docsh.cxx:2961
sal_uInt16 m_nDocumentLock
Definition: docsh.hxx:99
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:220
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:105
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:2608
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:767
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:2592
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
ScDocFunc & GetDocFunc()
Definition: docsh.hxx:222
static SCTAB GetCurTab()
Definition: docsh4.cxx:2599
void SetInplace(bool bInplace)
Definition: docsh3.cxx:346
void UnlockDocument()
Definition: docsh3.cxx:333
SfxObjectShell * GetDocumentShell() const
Definition: document.hxx:1081
ScChangeTrack * GetChangeTrack() const
Definition: document.hxx:2487
void GetMatColsRows(SCCOL &nCols, SCROW &nRows) const
ScMatrixMode GetMatrixFlag() const
static SC_DLLPUBLIC double nScreenPPTX
Horizontal pixel per twips factor.
Definition: global.hxx:588
static SC_DLLPUBLIC const LocaleDataWrapper & getLocaleData()
Definition: global.cxx:1053
void UpdateRefDevice()
Definition: inputhdl.cxx:875
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:1352
SC_DLLPUBLIC const ScFormulaOptions & GetFormulaOptions()
Definition: scmod.cxx:806
SC_DLLPUBLIC const ScDocOptions & GetDocOptions()
Definition: scmod.cxx:721
static void GetSpellSettings(LanguageType &rDefLang, LanguageType &rCjkLang, LanguageType &rCtlLang, bool &rAutoSpell)
Definition: scmod.cxx:2252
const ScViewOptions & GetViewOptions()
Definition: scmod.cxx:705
static void GetFont(vcl::Font &rFont, const SfxItemSet &rItemSet, ScAutoFontColorMode eAutoMode, const OutputDevice *pOutDev=nullptr, const Fraction *pScale=nullptr, const SfxItemSet *pCondSet=nullptr, SvtScriptType nScript=SvtScriptType::NONE, const Color *pBackConfigColor=nullptr, const Color *pTextConfigColor=nullptr)
Static helper function to fill a font object from the passed item set.
Definition: patattr.cxx:251
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:335
ScMarkData & GetMarkData()
Definition: viewdata.cxx:3141
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:365
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
css::uno::Reference< css::frame::XModel3 > GetModel() const
void PutItem(const SfxPoolItem &rItem)
SfxItemPool & GetPool() const
SfxViewShell * GetViewShell() const
virtual SfxStyleSheetBase * Find(const OUString &, SfxStyleFamily eFam, SfxStyleSearchBits n=SfxStyleSearchBits::All) const
virtual SfxItemSet & GetItemSet()
static SfxViewFrame * GetNext(const SfxViewFrame &rPrev, const SfxObjectShell *pDoc=nullptr, bool bOnlyVisible=true)
static 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:735
static bool lcl_Equal(const ScChangeAction *pA, const ScChangeAction *pB, bool bIgnore100Sec)
Definition: docsh3.cxx:723
#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:275
@ INS_INSCOLS_BEFORE
Definition: global.hxx:293
@ INS_INSROWS_BEFORE
Definition: global.hxx:292
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
@ SC_AUTOCOL_BLACK
always use black
Definition: patattr.hxx:45
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:249
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