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