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