LibreOffice Module sc (master)  1
content.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 <sal/config.h>
21 
22 #include <string_view>
23 
24 #include <svx/svditer.hxx>
25 #include <svx/svdobj.hxx>
26 #include <svx/svdview.hxx>
27 #include <sfx2/linkmgr.hxx>
28 #include <sfx2/docfile.hxx>
29 #include <sfx2/viewfrm.hxx>
30 #include <vcl/commandevent.hxx>
31 #include <vcl/svapp.hxx>
32 #include <osl/diagnose.h>
33 #include <tools/urlobj.hxx>
34 #include <sal/log.hxx>
35 #include <unotools/charclass.hxx>
36 
37 #include <content.hxx>
38 #include <navipi.hxx>
39 #include <global.hxx>
40 #include <docsh.hxx>
41 #include <scmod.hxx>
42 #include <rangenam.hxx>
43 #include <dbdata.hxx>
44 #include <tablink.hxx>
45 #include <drwlayer.hxx>
46 #include <transobj.hxx>
47 #include <drwtrans.hxx>
48 #include <lnktrans.hxx>
49 #include <strings.hrc>
50 #include <scresid.hxx>
51 #include <bitmaps.hlst>
52 #include <arealink.hxx>
53 #include <navicfg.hxx>
54 #include <navsett.hxx>
55 #include <postit.hxx>
56 #include <tabvwsh.hxx>
57 #include <drawview.hxx>
58 #include <clipparam.hxx>
59 #include <markdata.hxx>
60 
61 using namespace com::sun::star;
62 
63 // order of the categories in navigator -------------------------------------
64 
66 {
67  ScContentId::ROOT, // ROOT (0) has to be at the front
76 };
77 
78 constexpr rtl::OUStringConstExpr aContentBmps[]=
79 {
80  RID_BMP_CONTENT_TABLE,
81  RID_BMP_CONTENT_RANGENAME,
82  RID_BMP_CONTENT_DBAREA,
83  RID_BMP_CONTENT_GRAPHIC,
84  RID_BMP_CONTENT_OLEOBJECT,
85  RID_BMP_CONTENT_NOTE,
86  RID_BMP_CONTENT_AREALINK,
87  RID_BMP_CONTENT_DRAWING
88 };
89 
91 {
92  ScDocShell* pSh = nullptr;
93  if ( !aManualDoc.isEmpty() )
94  {
95  SfxObjectShell* pObjSh = SfxObjectShell::GetFirst( checkSfxObjectShell<ScDocShell> );
96  while ( pObjSh && !pSh )
97  {
98  if ( pObjSh->GetTitle() == aManualDoc )
99  pSh = dynamic_cast<ScDocShell*>( pObjSh );
100  pObjSh = SfxObjectShell::GetNext( *pObjSh, checkSfxObjectShell<ScDocShell> );
101  }
102  }
103  else
104  {
105  // only current when manual isn't set
106  // (so it's detected when the documents don't exists any longer)
107 
108  SfxViewShell* pViewSh = SfxViewShell::Current();
109  if ( pViewSh )
110  {
111  SfxObjectShell* pObjSh = pViewSh->GetViewFrame()->GetObjectShell();
112  pSh = dynamic_cast<ScDocShell*>( pObjSh );
113  }
114  }
115 
116  return pSh;
117 }
118 
119 // ScContentTree
120 
121 ScContentTree::ScContentTree(std::unique_ptr<weld::TreeView> xTreeView, ScNavigatorDlg* pNavigatorDlg)
122  : m_xTreeView(std::move(xTreeView))
123  , m_xScratchIter(m_xTreeView->make_iterator())
124  , m_xTransferObj(new ScLinkTransferObj)
125  , pParentWindow(pNavigatorDlg)
126  , nRootType(ScContentId::ROOT)
127  , bHiddenDoc(false)
128  , pHiddenDocument(nullptr)
129  , bIsInNavigatorDlg(false)
130  , m_bFreeze(false)
131  , m_nAsyncMouseReleaseId(nullptr)
132 {
133  for (sal_uInt16 i = 0; i <= int(ScContentId::LAST); ++i)
134  pPosList[pTypeList[i]] = i; // inverse for searching
135 
136  m_aRootNodes[ScContentId::ROOT] = nullptr;
137  for (sal_uInt16 i = 1; i < int(ScContentId::LAST); ++i)
138  InitRoot(static_cast<ScContentId>(i));
139 
140  m_xTreeView->connect_row_activated(LINK(this, ScContentTree, ContentDoubleClickHdl));
141  m_xTreeView->connect_mouse_release(LINK(this, ScContentTree, MouseReleaseHdl));
142  m_xTreeView->connect_key_press(LINK(this, ScContentTree, KeyInputHdl));
143  m_xTreeView->connect_popup_menu(LINK(this, ScContentTree, CommandHdl));
144  m_xTreeView->connect_query_tooltip(LINK(this, ScContentTree, QueryTooltipHdl));
145 
147  m_xTreeView->enable_drag_source(xHelper, DND_ACTION_COPY | DND_ACTION_LINK);
148 
149  m_xTreeView->connect_drag_begin(LINK(this, ScContentTree, DragBeginHdl));
150 
151  m_xTreeView->set_selection_mode( SelectionMode::Single );
152 
153  m_xTreeView->set_size_request(m_xTreeView->get_approximate_digit_width() * 30,
154  m_xTreeView->get_text_height() * 13);
155 }
156 
158 {
160  {
162  m_nAsyncMouseReleaseId = nullptr;
163  }
164 }
165 
167 {
168  SCSTR_CONTENT_ROOT,
169  SCSTR_CONTENT_TABLE,
170  SCSTR_CONTENT_RANGENAME,
171  SCSTR_CONTENT_DBAREA,
172  SCSTR_CONTENT_GRAPHIC,
173  SCSTR_CONTENT_OLEOBJECT,
174  SCSTR_CONTENT_NOTE,
175  SCSTR_CONTENT_AREALINK,
176  SCSTR_CONTENT_DRAWING
177 };
178 
180 {
181  if ( nType == ScContentId::ROOT )
182  return;
183 
184  if ( nRootType != ScContentId::ROOT && nRootType != nType ) // hidden ?
185  {
186  m_aRootNodes[nType] = nullptr;
187  return;
188  }
189 
190  auto const aImage(aContentBmps[static_cast<int>(nType) - 1]);
191  OUString aName(ScResId(SCSTR_CONTENT_ARY[static_cast<int>(nType)]));
192  // back to the correct position:
193  sal_uInt16 nPos = nRootType != ScContentId::ROOT ? 0 : pPosList[nType]-1;
194  m_aRootNodes[nType] = m_xTreeView->make_iterator();
195  m_xTreeView->insert(nullptr, nPos, &aName, nullptr, nullptr, nullptr, false, m_aRootNodes[nType].get());
196  m_xTreeView->set_image(*m_aRootNodes[nType], OUString(aImage));
197 }
198 
200 {
201  //There are one method in Control::SetUpdateMode(), and one override method SvTreeListBox::SetUpdateMode(). Here although
202  //SvTreeListBox::SetUpdateMode() is called in refresh method, it only call SvTreeListBox::SetUpdateMode(), not Control::SetUpdateMode().
203  //In m_xTreeView->clear(), Broadcast( LISTACTION_CLEARED ) will be called and finally, it will be trapped into the event yield() loop. And
204  //the InitRoot() method won't be called. Then if a user click or press key to update the navigator tree, crash happens.
205  //So the solution is to disable the UpdateMode of Control, then call Clear(), then recover the update mode
206  bool bWasFrozen = m_bFreeze;
207  if (!bWasFrozen)
208  freeze();
209  m_xTreeView->clear();
210  if (!bWasFrozen)
211  thaw();
212  for (sal_uInt16 i=1; i<=int(ScContentId::LAST); i++)
213  InitRoot(static_cast<ScContentId>(i));
214 }
215 
217 {
218  if (nType == ScContentId::ROOT)
219  ClearAll();
220  else
221  {
222  weld::TreeIter* pParent = m_aRootNodes[nType].get();
223  if (!pParent || m_xTreeView->iter_has_child(*pParent)) // not if no children existing
224  {
225  if (pParent)
226  m_xTreeView->remove(*pParent); // with all children
227  InitRoot( nType ); // if needed insert anew
228  }
229  }
230 }
231 
232 void ScContentTree::InsertContent( ScContentId nType, const OUString& rValue )
233 {
234  weld::TreeIter* pParent = m_aRootNodes[nType].get();
235  if (pParent)
236  {
237  m_xTreeView->insert(pParent, -1, &rValue, nullptr, nullptr, nullptr, false, m_xScratchIter.get());
238  m_xTreeView->set_sensitive(*m_xScratchIter, true);
239  }
240  else
241  {
242  OSL_FAIL("InsertContent without parent");
243  }
244 }
245 
246 void ScContentTree::GetEntryIndexes(ScContentId& rnRootIndex, sal_uLong& rnChildIndex, const weld::TreeIter* pEntry) const
247 {
248  rnRootIndex = ScContentId::ROOT;
249  rnChildIndex = SC_CONTENT_NOCHILD;
250 
251  if( !pEntry )
252  return;
253 
254  std::unique_ptr<weld::TreeIter> xParent(m_xTreeView->make_iterator(pEntry));
255  if (!m_xTreeView->iter_parent(*xParent))
256  xParent.reset();
257  bool bFound = false;
258  for( int i = 1; !bFound && (i <= int(ScContentId::LAST)); ++i )
259  {
260  ScContentId nRoot = static_cast<ScContentId>(i);
261  if (!m_aRootNodes[nRoot])
262  continue;
263  if (m_xTreeView->iter_compare(*pEntry, *m_aRootNodes[nRoot]) == 0)
264  {
265  rnRootIndex = nRoot;
266  rnChildIndex = ~0UL;
267  bFound = true;
268  }
269  else if (xParent && m_xTreeView->iter_compare(*xParent, *m_aRootNodes[nRoot]) == 0)
270  {
271  rnRootIndex = nRoot;
272 
273  // search the entry in all child entries of the parent
274  sal_uLong nEntry = 0;
275  std::unique_ptr<weld::TreeIter> xIterEntry(m_xTreeView->make_iterator(xParent.get()));
276  bool bIterEntry = m_xTreeView->iter_children(*xIterEntry);
277  while (!bFound && bIterEntry)
278  {
279  if (m_xTreeView->iter_compare(*pEntry, *xIterEntry) == 0)
280  {
281  rnChildIndex = nEntry;
282  bFound = true; // exit the while loop
283  }
284  bIterEntry = m_xTreeView->iter_next_sibling(*xIterEntry);
285  ++nEntry;
286  }
287 
288  bFound = true; // exit the for loop
289  }
290  }
291 }
292 
294 {
295  ScContentId nRoot;
296  sal_uLong nChild;
297  GetEntryIndexes(nRoot, nChild, pEntry);
298  return nChild;
299 }
300 
301 static OUString lcl_GetDBAreaRange( const ScDocument* pDoc, const OUString& rDBName )
302 {
303  OUString aRet;
304  if (pDoc)
305  {
306  ScDBCollection* pDbNames = pDoc->GetDBCollection();
307  const ScDBData* pData = pDbNames->getNamedDBs().findByUpperName(ScGlobal::getCharClass().uppercase(rDBName));
308  if (pData)
309  {
310  ScRange aRange;
311  pData->GetArea(aRange);
312  aRet = aRange.Format(*pDoc, ScRefFlags::RANGE_ABS_3D);
313  }
314  }
315  return aRet;
316 }
317 
318 IMPL_LINK_NOARG(ScContentTree, ContentDoubleClickHdl, weld::TreeView&, bool)
319 {
321  sal_uLong nChild;
322  std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator());
323  if (!m_xTreeView->get_cursor(xEntry.get()))
324  xEntry.reset();
325  GetEntryIndexes(nType, nChild, xEntry.get());
326 
327  if (xEntry && (nType != ScContentId::ROOT) && (nChild != SC_CONTENT_NOCHILD))
328  {
329  if ( bHiddenDoc )
330  return false;
331 
332  OUString aText(m_xTreeView->get_text(*xEntry));
333 
334  if ( !aManualDoc.isEmpty() )
335  pParentWindow->SetCurrentDoc( aManualDoc );
336 
337  switch( nType )
338  {
339  case ScContentId::TABLE:
340  {
341  // tdf#133159 store current config before changing sheet
342  // plausible that this should be done for all cases, but this
343  // is the known case that needs it
344  StoreNavigatorSettings();
345  pParentWindow->SetCurrentTableStr( aText );
346  }
347  break;
348 
350  pParentWindow->SetCurrentCellStr( aText );
351  break;
352 
353  case ScContentId::DBAREA:
354  {
355  // If the same names of area and DB exists, then
356  // SID_CURRENTCELL takes the area name.
357  // Therefore for DB areas access them directly via address.
358 
359  OUString aRangeStr = lcl_GetDBAreaRange( GetSourceDocument(), aText );
360  if (!aRangeStr.isEmpty())
361  pParentWindow->SetCurrentCellStr( aRangeStr );
362  }
363  break;
364 
368  pParentWindow->SetCurrentObject( aText );
369  break;
370 
371  case ScContentId::NOTE:
372  {
373  ScAddress aPos = GetNotePos( nChild );
374  pParentWindow->SetCurrentTable( aPos.Tab() );
375  pParentWindow->SetCurrentCell( aPos.Col(), aPos.Row() );
376  }
377  break;
378 
380  {
381  const ScAreaLink* pLink = GetLink(nChild);
382  ScDocument* pSrcDoc = GetSourceDocument();
383  if (pLink && pSrcDoc)
384  {
385  const ScRange& aRange = pLink->GetDestArea();
386  OUString aRangeStr(aRange.Format(*pSrcDoc, ScRefFlags::RANGE_ABS_3D, pSrcDoc->GetAddressConvention()));
387  pParentWindow->SetCurrentCellStr( aRangeStr );
388  }
389  }
390  break;
391  default: break;
392  }
393 
394  ScNavigatorDlg::ReleaseFocus(); // set focus into document
395  }
396 
397  return false;
398 }
399 
401 {
403  m_nAsyncMouseReleaseId = Application::PostUserEvent(LINK(this, ScContentTree, AsyncStoreNavigatorSettings));
404 }
405 
406 IMPL_LINK_NOARG(ScContentTree, MouseReleaseHdl, const MouseEvent&, bool)
407 {
408  LaunchAsyncStoreNavigatorSettings();
409  return false;
410 }
411 
412 IMPL_LINK_NOARG(ScContentTree, AsyncStoreNavigatorSettings, void*, void)
413 {
414  m_nAsyncMouseReleaseId = nullptr;
415  StoreNavigatorSettings();
416 }
417 
418 IMPL_LINK(ScContentTree, KeyInputHdl, const KeyEvent&, rKEvt, bool)
419 {
420  bool bUsed = false;
421 
422  const vcl::KeyCode aCode = rKEvt.GetKeyCode();
423  if (aCode.GetCode() == KEY_RETURN)
424  {
425  switch (aCode.GetModifier())
426  {
427  case KEY_MOD1:
428  ToggleRoot(); // toggle root mode (as in Writer)
429  bUsed = true;
430  break;
431  case 0:
432  {
433  std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator());
434  if (!m_xTreeView->get_cursor(xEntry.get()))
435  xEntry.reset();
436  if (xEntry)
437  {
439  sal_uLong nChild;
440  GetEntryIndexes(nType, nChild, xEntry.get());
441 
442  if (nType != ScContentId::ROOT && nChild == SC_CONTENT_NOCHILD)
443  {
444  if (m_xTreeView->get_row_expanded(*xEntry))
445  m_xTreeView->collapse_row(*xEntry);
446  else
447  m_xTreeView->expand_row(*xEntry);
448  }
449  else
450  ContentDoubleClickHdl(*m_xTreeView); // select content as if double clicked
451  }
452 
453  bUsed = true;
454  }
455  break;
456  }
457  }
458  //Make KEY_SPACE has same function as DoubleClick, and realize
459  //multi-selection.
460  if ( bIsInNavigatorDlg )
461  {
462  if(aCode.GetCode() == KEY_SPACE )
463  {
464  bUsed = true;
466  sal_uLong nChild;
467  std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator());
468  if (!m_xTreeView->get_cursor(xEntry.get()))
469  xEntry.reset();
470  GetEntryIndexes(nType, nChild, xEntry.get());
471 
472  if (xEntry && (nType != ScContentId::ROOT) && (nChild != SC_CONTENT_NOCHILD))
473  {
474  if ( bHiddenDoc )
475  return true;
476  OUString aText(m_xTreeView->get_text(*xEntry));
477  if (!aManualDoc.isEmpty())
478  pParentWindow->SetCurrentDoc( aManualDoc );
479  switch (nType)
480  {
484  {
485  ScDrawView* pScDrawView = nullptr;
486  ScTabViewShell* pScTabViewShell = ScNavigatorDlg::GetTabViewShell();
487  if (pScTabViewShell)
488  pScDrawView = pScTabViewShell->GetViewData().GetScDrawView();
489  if (pScDrawView)
490  {
491  pScDrawView->SelectCurrentViewObject(aText);
492  bool bHasMakredObject = false;
493  weld::TreeIter* pParent = m_aRootNodes[nType].get();
494  std::unique_ptr<weld::TreeIter> xBeginEntry(m_xTreeView->make_iterator(pParent));
495  bool bBeginEntry = false;
496  if (pParent)
497  bBeginEntry = m_xTreeView->iter_children(*xBeginEntry);
498  while (bBeginEntry)
499  {
500  OUString aTempText(m_xTreeView->get_text(*xBeginEntry));
501  if( pScDrawView->GetObjectIsMarked( pScDrawView->GetObjectByName( aTempText ) ) )
502  {
503  bHasMakredObject = true;
504  break;
505  }
506  bBeginEntry = m_xTreeView->iter_next(*xBeginEntry);
507  }
508  if (!bHasMakredObject && pScTabViewShell)
509  pScTabViewShell->SetDrawShell(false);
510  }
511  break;
512  }
513  default:
514  break;
515  }
516  }
517  }
518  }
519 
520  if (!bUsed)
521  {
522  if (aCode.GetCode() == KEY_F5)
523  StoreNavigatorSettings();
524  else
525  LaunchAsyncStoreNavigatorSettings();
526  }
527 
528  return bUsed;
529 }
530 
531 IMPL_LINK(ScContentTree, CommandHdl, const CommandEvent&, rCEvt, bool)
532 {
533  bool bDone = false;
534 
535  switch ( rCEvt.GetCommand() )
536  {
537  case CommandEventId::ContextMenu:
538  {
539  // drag-and-drop mode
540  std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(m_xTreeView.get(), "modules/scalc/ui/dropmenu.ui"));
541  std::unique_ptr<weld::Menu> xPop(xBuilder->weld_menu("contextmenu"));
542  std::unique_ptr<weld::Menu> xDropMenu(xBuilder->weld_menu("dragmodesubmenu"));
543 
544  switch (pParentWindow->GetDropMode())
545  {
546  case 0:
547  xDropMenu->set_active("hyperlink", true);
548  break;
549  case 1:
550  xDropMenu->set_active("link", true);
551  break;
552  case 2:
553  xDropMenu->set_active("copy", true);
554  break;
555  }
556 
557  // displayed document
558  std::unique_ptr<weld::Menu> xDocMenu(xBuilder->weld_menu("displaymenu"));
559  sal_uInt16 i=0;
560  OUString sActive;
561  OUString sId;
562  // loaded documents
563  ScDocShell* pCurrentSh = dynamic_cast<ScDocShell*>( SfxObjectShell::Current() );
565  while ( pSh )
566  {
567  if ( dynamic_cast<const ScDocShell*>( pSh) != nullptr )
568  {
569  OUString aName = pSh->GetTitle();
570  OUString aEntry = aName;
571  if ( pSh == pCurrentSh )
572  aEntry += pParentWindow->aStrActive;
573  else
574  aEntry += pParentWindow->aStrNotActive;
575  ++i;
576  sId = "document" + OUString::number(i);
577  xDocMenu->append_radio(sId, aEntry);
578  if ( !bHiddenDoc && aName == aManualDoc )
579  sActive = sId;
580  }
581  pSh = SfxObjectShell::GetNext( *pSh );
582  }
583  // "active window"
584  ++i;
585  sId = "document" + OUString::number(i);
586  xDocMenu->append_radio(sId, pParentWindow->aStrActiveWin);
587  if (!bHiddenDoc && aManualDoc.isEmpty())
588  sActive = sId;
589  // hidden document
590  if ( !aHiddenTitle.isEmpty() )
591  {
592  OUString aEntry = aHiddenTitle + pParentWindow->aStrHidden;
593  ++i;
594  sId = "document" + OUString::number(i);
595  xDocMenu->append_radio(sId, aEntry);
596  if (bHiddenDoc)
597  sActive = sId;
598  }
599  xDocMenu->set_active(sActive.toUtf8(), true);
600 
601  OString sIdent = xPop->popup_at_rect(m_xTreeView.get(), tools::Rectangle(rCEvt.GetMousePosPixel(), Size(1, 1)));
602  if (sIdent == "hyperlink")
603  pParentWindow->SetDropMode(0);
604  else if (sIdent == "link")
605  pParentWindow->SetDropMode(1);
606  else if (sIdent == "copy")
607  pParentWindow->SetDropMode(2);
608  else if (sIdent.startsWith("document"))
609  {
610  OUString aName = xDocMenu->get_label(sIdent);
611  SelectDoc(aName);
612  }
613  }
614  break;
615  default: break;
616  }
617 
618  return bDone;
619 }
620 
621 IMPL_LINK(ScContentTree, QueryTooltipHdl, const weld::TreeIter&, rEntry, OUString)
622 {
623  OUString aHelpText;
624 
625  std::unique_ptr<weld::TreeIter> xParent(m_xTreeView->make_iterator(&rEntry));
626  if (!m_xTreeView->iter_parent(*xParent))
627  xParent.reset();
628 
629  if (!xParent) // Top-Level ?
630  {
631  aHelpText = OUString::number(m_xTreeView->iter_n_children(rEntry)) +
632  " " + m_xTreeView->get_text(rEntry);
633  }
634  else if (m_aRootNodes[ScContentId::NOTE] && m_xTreeView->iter_compare(*xParent, *m_aRootNodes[ScContentId::NOTE]) == 0)
635  {
636  aHelpText = m_xTreeView->get_text(rEntry); // notes as help text
637  }
638  else if (m_aRootNodes[ScContentId::AREALINK] && m_xTreeView->iter_compare(*xParent, *m_aRootNodes[ScContentId::AREALINK]) == 0)
639  {
640  auto nIndex = GetChildIndex(&rEntry);
641  if (nIndex != SC_CONTENT_NOCHILD)
642  {
643  const ScAreaLink* pLink = GetLink(nIndex);
644  if (pLink)
645  {
646  aHelpText = pLink->GetFile(); // source file as help text
647  }
648  }
649  }
650 
651  return aHelpText;
652 }
653 
655 {
656  if (bHiddenDoc)
657  return pHiddenDocument;
658  else
659  {
661  if (pSh)
662  return &pSh->GetDocument();
663 
664  }
665  return nullptr;
666 }
667 
669 {
670  if ( bHiddenDoc && !pHiddenDocument )
671  return; // other document displayed
672 
673  // if nothing has changed the cancel right away (against flicker)
674 
675  if ( nType == ScContentId::NOTE )
676  if (!NoteStringsChanged())
677  return;
678  if ( nType == ScContentId::GRAPHIC )
680  return;
681  if ( nType == ScContentId::OLEOBJECT )
683  return;
684  if ( nType == ScContentId::DRAWING )
686  return;
687 
688  freeze();
689 
690  ClearType( nType );
691 
692  if ( nType == ScContentId::ROOT || nType == ScContentId::TABLE )
693  GetTableNames();
694  if ( nType == ScContentId::ROOT || nType == ScContentId::RANGENAME )
695  GetAreaNames();
696  if ( nType == ScContentId::ROOT || nType == ScContentId::DBAREA )
697  GetDbNames();
698  if ( nType == ScContentId::ROOT || nType == ScContentId::GRAPHIC )
699  GetGraphicNames();
700  if ( nType == ScContentId::ROOT || nType == ScContentId::OLEOBJECT )
701  GetOleNames();
702  if ( nType == ScContentId::ROOT || nType == ScContentId::DRAWING )
703  GetDrawingNames();
704  if ( nType == ScContentId::ROOT || nType == ScContentId::NOTE )
705  GetNoteStrings();
706  if ( nType == ScContentId::ROOT || nType == ScContentId::AREALINK )
707  GetLinkNames();
708 
709  thaw();
710 
712 }
713 
715 {
716  if ( nRootType != ScContentId::ROOT && nRootType != ScContentId::TABLE ) // hidden ?
717  return;
718 
719  ScDocument* pDoc = GetSourceDocument();
720  if (!pDoc)
721  return;
722 
723  OUString aName;
724  SCTAB nCount = pDoc->GetTableCount();
725  for ( SCTAB i=0; i<nCount; i++ )
726  {
727  pDoc->GetName( i, aName );
729  }
730 }
731 
732 namespace {
733 
734 OUString createLocalRangeName(std::u16string_view rName, std::u16string_view rTableName)
735 {
736  return OUString::Concat(rName) + " (" + rTableName + ")";
737 }
738 }
739 
741 {
742  if ( nRootType != ScContentId::ROOT && nRootType != ScContentId::RANGENAME ) // hidden ?
743  return;
744 
745  ScDocument* pDoc = GetSourceDocument();
746  if (!pDoc)
747  return;
748 
749  ScRange aDummy;
750  std::set<OUString> aSet;
751  ScRangeName* pRangeNames = pDoc->GetRangeName();
752  for (const auto& rEntry : *pRangeNames)
753  {
754  if (rEntry.second->IsValidReference(aDummy))
755  aSet.insert(rEntry.second->GetName());
756  }
757  for (SCTAB i = 0; i < pDoc->GetTableCount(); ++i)
758  {
759  ScRangeName* pLocalRangeName = pDoc->GetRangeName(i);
760  if (pLocalRangeName && !pLocalRangeName->empty())
761  {
762  OUString aTableName;
763  pDoc->GetName(i, aTableName);
764  for (const auto& rEntry : *pLocalRangeName)
765  {
766  if (rEntry.second->IsValidReference(aDummy))
767  aSet.insert(createLocalRangeName(rEntry.second->GetName(), aTableName));
768  }
769  }
770  }
771 
772  for (const auto& rItem : aSet)
773  {
775  }
776 }
777 
779 {
780  if ( nRootType != ScContentId::ROOT && nRootType != ScContentId::DBAREA ) // hidden ?
781  return;
782 
783  ScDocument* pDoc = GetSourceDocument();
784  if (!pDoc)
785  return;
786 
787  ScDBCollection* pDbNames = pDoc->GetDBCollection();
788  const ScDBCollection::NamedDBs& rDBs = pDbNames->getNamedDBs();
789  for (const auto& rxDB : rDBs)
790  {
791  const OUString& aStrName = rxDB->GetName();
793  }
794 }
795 
796 bool ScContentTree::IsPartOfType( ScContentId nContentType, SdrObjKind nObjIdentifier )
797 {
798  bool bRet = false;
799  switch ( nContentType )
800  {
802  bRet = ( nObjIdentifier == SdrObjKind::Graphic );
803  break;
805  bRet = ( nObjIdentifier == SdrObjKind::OLE2 );
806  break;
808  bRet = ( nObjIdentifier != SdrObjKind::Graphic && nObjIdentifier != SdrObjKind::OLE2 ); // everything else
809  break;
810  default:
811  OSL_FAIL("unknown content type");
812  }
813  return bRet;
814 }
815 
816 constexpr int MAX_TREE_NODES = 1000;
817 
819 {
820  if (!bIsInNavigatorDlg)
821  return;
822 
823  if ( nRootType != ScContentId::ROOT && nRootType != nType ) // hidden ?
824  return;
825 
826  ScDocument* pDoc = GetSourceDocument();
827  if (!pDoc)
828  return;
829 
830  ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
831  if (!pDrawLayer)
832  return;
833 
834  SfxObjectShell* pShell = pDoc->GetDocumentShell();
835  if (!pShell)
836  return;
837 
838  // iterate in flat mode for groups
839  SdrIterMode eIter = ( nType == ScContentId::DRAWING ) ? SdrIterMode::Flat : SdrIterMode::DeepNoGroups;
840 
841  std::vector<OUString> aNames;
842  SCTAB nTabCount = pDoc->GetTableCount();
843  for (SCTAB nTab=0; nTab<nTabCount; nTab++)
844  {
845  SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
846  OSL_ENSURE(pPage,"Page ?");
847  if (!pPage)
848  continue;
849  SdrObjListIter aIter(pPage, eIter);
850  SdrObject* pObject = aIter.Next();
851  while (pObject)
852  {
853  if (IsPartOfType(nType, pObject->GetObjIdentifier()))
854  {
855  OUString aName = ScDrawLayer::GetVisibleName(pObject);
856  if (!aName.isEmpty())
857  aNames.push_back(aName);
858  if (aNames.size() > MAX_TREE_NODES)
859  {
860  SAL_WARN("sc", "too many tree nodes, ignoring the rest");
861  break;
862  }
863  }
864  pObject = aIter.Next();
865  }
866  }
867 
868  weld::TreeIter* pParent = m_aRootNodes[nType].get();
869  assert(pParent && "InsertContent without parent");
870  // insert all of these in one go under pParent
871  m_xTreeView->bulk_insert_for_each(aNames.size(), [this, &aNames](weld::TreeIter& rIter, int nIndex) {
872  m_xTreeView->set_text(rIter, aNames[nIndex], 0);
873  m_xTreeView->set_sensitive(rIter, true);
874  }, pParent);
875 }
876 
878 {
880 }
881 
883 {
885 }
886 
888 {
890 }
891 
893 {
894  if ( nRootType != ScContentId::ROOT && nRootType != ScContentId::AREALINK ) // hidden ?
895  return;
896 
897  ScDocument* pDoc = GetSourceDocument();
898  if (!pDoc)
899  return;
900 
901  sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager();
902  OSL_ENSURE(pLinkManager, "no LinkManager on document?");
903  const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
904  sal_uInt16 nCount = rLinks.size();
905  for (sal_uInt16 i=0; i<nCount; i++)
906  {
907  ::sfx2::SvBaseLink* pBase = rLinks[i].get();
908  if (auto pScAreaLink = dynamic_cast<const ScAreaLink*>( pBase))
909  InsertContent( ScContentId::AREALINK, pScAreaLink->GetSource() );
910 
911  // insert in list the names of source areas
912  }
913 }
914 
916 {
917  ScDocument* pDoc = GetSourceDocument();
918  if (!pDoc)
919  return nullptr;
920 
921  sal_uLong nFound = 0;
922  sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager();
923  OSL_ENSURE(pLinkManager, "no LinkManager on document?");
924  const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
925  sal_uInt16 nCount = rLinks.size();
926  for (sal_uInt16 i=0; i<nCount; i++)
927  {
928  ::sfx2::SvBaseLink* pBase = rLinks[i].get();
929  if (auto pAreaLink = dynamic_cast<const ScAreaLink*>( pBase))
930  {
931  if (nFound == nIndex)
932  return pAreaLink;
933  ++nFound;
934  }
935  }
936 
937  OSL_FAIL("link not found");
938  return nullptr;
939 }
940 
941 static OUString lcl_NoteString( const ScPostIt& rNote )
942 {
943  OUString aText = rNote.GetText();
944  sal_Int32 nAt;
945  while ( (nAt = aText.indexOf( '\n' )) != -1 )
946  aText = aText.replaceAt( nAt, 1, u" " );
947  return aText;
948 }
949 
951 {
952  if ( nRootType != ScContentId::ROOT && nRootType != ScContentId::NOTE ) // hidden ?
953  return;
954 
955  ScDocument* pDoc = GetSourceDocument();
956  if (!pDoc)
957  return;
958 
959  // loop over cell notes
960  std::vector<sc::NoteEntry> aEntries;
961  pDoc->GetAllNoteEntries(aEntries);
963  for (const auto& rEntry : aEntries)
964  {
965  OUString aValue = lcl_NoteString(*rEntry.mpNote);
966  m_xTreeView->insert(pParent, -1, &aValue, nullptr, nullptr, nullptr, false, m_xScratchIter.get());
967  m_xTreeView->set_sensitive(*m_xScratchIter, true);
968  }
969 }
970 
972 {
973  ScDocument* pDoc = GetSourceDocument();
974  if (!pDoc)
975  return ScAddress();
976 
977  return pDoc->GetNotePosition(nIndex);
978 }
979 
981 {
982  ScDocument* pDoc = GetSourceDocument();
983  if (!pDoc)
984  return false;
985 
987  if (!pParent)
988  return false;
989 
990  std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator(pParent));
991  bool bEntry = m_xTreeView->iter_children(*xEntry);
992 
993  std::vector<sc::NoteEntry> aEntries;
994  pDoc->GetAllNoteEntries(aEntries);
995  for (const auto& rEntry : aEntries)
996  {
997  const ScPostIt* pNote = rEntry.mpNote;
998  if (!bEntry)
999  return true;
1000 
1001  if (lcl_NoteString(*pNote) != m_xTreeView->get_text(*xEntry))
1002  return true;
1003 
1004  bEntry = m_xTreeView->iter_next_sibling(*xEntry);
1005  }
1006 
1007  return bEntry;
1008 }
1009 
1011 {
1012  ScDocument* pDoc = GetSourceDocument();
1013  if (!pDoc)
1014  return false;
1015 
1016  weld::TreeIter* pParent = m_aRootNodes[nType].get();
1017  if (!pParent)
1018  return false;
1019 
1020  std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator(pParent));
1021  bool bEntry = m_xTreeView->iter_children(*xEntry);
1022 
1023  // iterate in flat mode for groups
1024  SdrIterMode eIter = ( nType == ScContentId::DRAWING ) ? SdrIterMode::Flat : SdrIterMode::DeepNoGroups;
1025 
1026  bool bEqual = true;
1027  ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
1028  SfxObjectShell* pShell = pDoc->GetDocumentShell();
1029  if (pDrawLayer && pShell)
1030  {
1031  SCTAB nTabCount = pDoc->GetTableCount();
1032  for (SCTAB nTab=0; nTab<nTabCount && bEqual; nTab++)
1033  {
1034  SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
1035  OSL_ENSURE(pPage,"Page ?");
1036  if (pPage)
1037  {
1038  SdrObjListIter aIter( pPage, eIter );
1039  SdrObject* pObject = aIter.Next();
1040  while (pObject && bEqual)
1041  {
1042  if ( IsPartOfType( nType, pObject->GetObjIdentifier() ) )
1043  {
1044  if ( !bEntry )
1045  bEqual = false;
1046  else
1047  {
1048  if (ScDrawLayer::GetVisibleName(pObject) != m_xTreeView->get_text(*xEntry))
1049  bEqual = false;
1050 
1051  bEntry = m_xTreeView->iter_next_sibling(*xEntry);
1052  }
1053  }
1054  pObject = aIter.Next();
1055  }
1056  }
1057  }
1058  }
1059 
1060  if ( bEntry )
1061  bEqual = false; // anything else
1062 
1063  return !bEqual;
1064 }
1065 
1066 static bool lcl_GetRange( const ScDocument& rDoc, ScContentId nType, const OUString& rName, ScRange& rRange )
1067 {
1068  bool bFound = false;
1069 
1070  if ( nType == ScContentId::RANGENAME )
1071  {
1072  ScRangeName* pList = rDoc.GetRangeName();
1073  if (pList)
1074  {
1075  const ScRangeData* p = pList->findByUpperName(ScGlobal::getCharClass().uppercase(rName));
1076  if (p && p->IsValidReference(rRange))
1077  bFound = true;
1078  }
1079  }
1080  else if ( nType == ScContentId::DBAREA )
1081  {
1082  ScDBCollection* pList = rDoc.GetDBCollection();
1083  if (pList)
1084  {
1085  const ScDBData* p = pList->getNamedDBs().findByUpperName(ScGlobal::getCharClass().uppercase(rName));
1086  if (p)
1087  {
1088  SCTAB nTab;
1089  SCCOL nCol1, nCol2;
1090  SCROW nRow1, nRow2;
1091  p->GetArea(nTab, nCol1, nRow1, nCol2, nRow2);
1092  rRange = ScRange(nCol1, nRow1, nTab, nCol2, nRow2, nTab);
1093  bFound = true;
1094  }
1095  }
1096  }
1097 
1098  return bFound;
1099 }
1100 
1101 static bool lcl_DoDragObject( ScDocShell* pSrcShell, std::u16string_view rName, ScContentId nType, weld::TreeView& rTreeView )
1102 {
1103  bool bDisallow = true;
1104 
1105  ScDocument& rSrcDoc = pSrcShell->GetDocument();
1106  ScDrawLayer* pModel = rSrcDoc.GetDrawLayer();
1107  if (pModel)
1108  {
1109  bool bOle = ( nType == ScContentId::OLEOBJECT );
1110  bool bGraf = ( nType == ScContentId::GRAPHIC );
1111  SdrObjKind nDrawId = bOle ? SdrObjKind::OLE2 : ( bGraf ? SdrObjKind::Graphic : SdrObjKind::Group );
1112  SCTAB nTab = 0;
1113  SdrObject* pObject = pModel->GetNamedObject( rName, nDrawId, nTab );
1114  if (pObject)
1115  {
1116  SdrView aEditView(*pModel);
1117  aEditView.ShowSdrPage(aEditView.GetModel()->GetPage(nTab));
1118  SdrPageView* pPV = aEditView.GetSdrPageView();
1119  aEditView.MarkObj(pObject, pPV);
1120 
1121  // tdf125520 this is a D&D-start potentially with an OLE object. If
1122  // so, we need to do similar as e.g. in ScDrawView::BeginDrag so that
1123  // the temporary SdrModel for transfer does have a GetPersist() so
1124  // that the EmbeddedObjectContainer gets copied. We need no CheckOle
1125  // here, test is simpler.
1126  ScDocShellRef aDragShellRef;
1127  if(SdrObjKind::OLE2 == pObject->GetObjIdentifier())
1128  {
1129  aDragShellRef = new ScDocShell; // DocShell needs a Ref immediately
1130  aDragShellRef->DoInitNew();
1131  }
1132 
1133  ScDrawLayer::SetGlobalDrawPersist(aDragShellRef.get());
1134  std::unique_ptr<SdrModel> pDragModel(aEditView.CreateMarkedObjModel());
1136 
1138  pSrcShell->FillTransferableObjectDescriptor( aObjDesc );
1139  aObjDesc.maDisplayName = pSrcShell->GetMedium()->GetURLObject().GetURLNoPass();
1140  // maSize is set in ScDrawTransferObj ctor
1141 
1142  rtl::Reference<ScDrawTransferObj> pTransferObj = new ScDrawTransferObj( std::move(pDragModel), pSrcShell, aObjDesc );
1143 
1144  pTransferObj->SetDragSourceObj( *pObject, nTab );
1145  pTransferObj->SetDragSourceFlags(ScDragSrc::Navigator);
1146 
1147  SC_MOD()->SetDragObject( nullptr, pTransferObj.get() );
1148 
1149  rtl::Reference<TransferDataContainer> xHelper(pTransferObj);
1150  rTreeView.enable_drag_source(xHelper, DND_ACTION_COPY | DND_ACTION_LINK);
1151 
1152  bDisallow = false;
1153  }
1154  }
1155 
1156  return bDisallow;
1157 }
1158 
1159 static bool lcl_DoDragCells( ScDocShell* pSrcShell, const ScRange& rRange, ScDragSrc nFlags, weld::TreeView& rTreeView )
1160 {
1161  bool bDisallow = true;
1162 
1163  ScDocument& rSrcDoc = pSrcShell->GetDocument();
1164  ScMarkData aMark(rSrcDoc.GetSheetLimits());
1165  aMark.SelectTable( rRange.aStart.Tab(), true );
1166  aMark.SetMarkArea( rRange );
1167 
1168  if ( !rSrcDoc.HasSelectedBlockMatrixFragment( rRange.aStart.Col(), rRange.aStart.Row(),
1169  rRange.aEnd.Col(), rRange.aEnd.Row(),
1170  aMark ) )
1171  {
1173  ScClipParam aClipParam(rRange, false);
1174  rSrcDoc.CopyToClip(aClipParam, pClipDoc.get(), &aMark, false, false);
1175  // pClipDoc->ExtendMerge( rRange, sal_True );
1176 
1178  pSrcShell->FillTransferableObjectDescriptor( aObjDesc );
1179  aObjDesc.maDisplayName = pSrcShell->GetMedium()->GetURLObject().GetURLNoPass();
1180  // maSize is set in ScTransferObj ctor
1181 
1182  rtl::Reference<ScTransferObj> pTransferObj = new ScTransferObj( std::move(pClipDoc), aObjDesc );
1183 
1184  pTransferObj->SetDragSource( pSrcShell, aMark );
1185  pTransferObj->SetDragSourceFlags( nFlags );
1186 
1187  SC_MOD()->SetDragObject( pTransferObj.get(), nullptr ); // for internal D&D
1188 
1189  rtl::Reference<TransferDataContainer> xHelper(pTransferObj);
1190  rTreeView.enable_drag_source(xHelper, DND_ACTION_COPY | DND_ACTION_LINK);
1191 
1192  bDisallow = false;
1193  }
1194 
1195  return bDisallow;
1196 }
1197 
1198 IMPL_LINK(ScContentTree, DragBeginHdl, bool&, rUnsetDragIcon, bool)
1199 {
1200  rUnsetDragIcon = true;
1201 
1202  StoreNavigatorSettings();
1203 
1204  bool bDisallow = true;
1205 
1206  std::unique_ptr<ScDocumentLoader> pDocLoader;
1207 
1208  ScModule* pScMod = SC_MOD();
1209 
1211  sal_uLong nChild;
1212 
1213  std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator());
1214  if (!m_xTreeView->get_cursor(xEntry.get()))
1215  xEntry.reset();
1216 
1217  GetEntryIndexes(nType, nChild, xEntry.get());
1218 
1219  if( xEntry &&
1220  (nChild != SC_CONTENT_NOCHILD) &&
1221  (nType != ScContentId::ROOT) &&
1222  (nType != ScContentId::NOTE) &&
1223  (nType != ScContentId::AREALINK) )
1224  {
1225  OUString aText(m_xTreeView->get_text(*xEntry));
1226 
1227  ScDocument* pLocalDoc = nullptr; // for URL drop
1228  OUString aDocName;
1229  if (bHiddenDoc)
1230  aDocName = aHiddenName;
1231  else
1232  {
1233  ScDocShell* pDocSh = GetManualOrCurrent();
1234  if (pDocSh)
1235  {
1236  if (pDocSh->HasName())
1237  aDocName = pDocSh->GetMedium()->GetName();
1238  else
1239  pLocalDoc = &pDocSh->GetDocument(); // drop only in this document
1240  }
1241  }
1242 
1243  bool bDoLinkTrans = false; // use ScLinkTransferObj
1244  OUString aLinkURL; // for ScLinkTransferObj
1245  OUString aLinkText;
1246 
1247  sal_uInt16 nDropMode = pParentWindow->GetDropMode();
1248  switch ( nDropMode )
1249  {
1250  case SC_DROPMODE_URL:
1251  {
1252  OUString aUrl = aDocName + "#" + aText;
1253 
1254  pScMod->SetDragJump( pLocalDoc, aUrl, aText );
1255 
1256  if (!aDocName.isEmpty())
1257  {
1258  // provide URL to outside only if the document has a name
1259  // (without name, only internal D&D via SetDragJump)
1260 
1261  aLinkURL = aUrl;
1262  aLinkText = aText;
1263  }
1264  bDoLinkTrans = true;
1265  }
1266  break;
1267  case SC_DROPMODE_LINK:
1268  {
1269  if ( !aDocName.isEmpty() ) // link only to named documents
1270  {
1271  // for internal D&D, set flag to insert a link
1272 
1273  switch ( nType )
1274  {
1275  case ScContentId::TABLE:
1276  pScMod->SetDragLink( aDocName, aText, OUString() );
1277  bDoLinkTrans = true;
1278  break;
1280  case ScContentId::DBAREA:
1281  pScMod->SetDragLink( aDocName, OUString(), aText );
1282  bDoLinkTrans = true;
1283  break;
1284 
1285  // other types cannot be linked
1286  default: break;
1287  }
1288  }
1289  }
1290  break;
1291  case SC_DROPMODE_COPY:
1292  {
1293  ScDocShell* pSrcShell = nullptr;
1294  if ( bHiddenDoc )
1295  {
1296  OUString aFilter, aOptions;
1297  OUString aURL = aHiddenName;
1298  pDocLoader.reset(new ScDocumentLoader( aURL, aFilter, aOptions ));
1299  if (!pDocLoader->IsError())
1300  pSrcShell = pDocLoader->GetDocShell();
1301  }
1302  else
1303  pSrcShell = GetManualOrCurrent();
1304 
1305  if ( pSrcShell )
1306  {
1307  ScDocument& rSrcDoc = pSrcShell->GetDocument();
1308  if ( nType == ScContentId::RANGENAME || nType == ScContentId::DBAREA )
1309  {
1310  ScRange aRange;
1311  if ( lcl_GetRange( rSrcDoc, nType, aText, aRange ) )
1312  {
1313  bDisallow = lcl_DoDragCells( pSrcShell, aRange, ScDragSrc::Navigator, *m_xTreeView );
1314  }
1315  }
1316  else if ( nType == ScContentId::TABLE )
1317  {
1318  SCTAB nTab;
1319  if ( rSrcDoc.GetTable( aText, nTab ) )
1320  {
1321  ScRange aRange(0, 0, nTab, rSrcDoc.MaxCol(), rSrcDoc.MaxRow(), nTab);
1322  bDisallow = lcl_DoDragCells( pSrcShell, aRange, (ScDragSrc::Navigator | ScDragSrc::Table), *m_xTreeView );
1323  }
1324  }
1325  else if ( nType == ScContentId::GRAPHIC || nType == ScContentId::OLEOBJECT ||
1326  nType == ScContentId::DRAWING )
1327  {
1328  bDisallow = lcl_DoDragObject( pSrcShell, aText, nType, *m_xTreeView );
1329 
1330  // during ExecuteDrag the navigator can be deleted
1331  // -> don't access member anymore !!!
1332  }
1333  }
1334  }
1335  break;
1336  }
1337 
1338  if (bDoLinkTrans)
1339  {
1340  if (!aLinkURL.isEmpty())
1341  m_xTransferObj->SetLinkURL(aLinkURL, aLinkText);
1342 
1343  rtl::Reference<TransferDataContainer> xHelper(m_xTransferObj);
1344  m_xTreeView->enable_drag_source(xHelper, DND_ACTION_COPY | DND_ACTION_LINK);
1345 
1346  bDisallow = false;
1347  }
1348  }
1349 
1350  return bDisallow;
1351 }
1352 
1353 void ScContentTree::LoadFile( const OUString& rUrl )
1354 {
1355  OUString aDocName = rUrl;
1356  sal_Int32 nPos = aDocName.indexOf('#');
1357  if ( nPos != -1 )
1358  aDocName = aDocName.copy(0, nPos); // only the name without #...
1359 
1360  OUString aURL = aDocName;
1361  OUString aFilter, aOptions;
1362  ScDocumentLoader aLoader( aURL, aFilter, aOptions );
1363  if ( aLoader.IsError() )
1364  return;
1365 
1366  bHiddenDoc = true;
1367  aHiddenName = aDocName;
1368  aHiddenTitle = aLoader.GetTitle();
1369  pHiddenDocument = aLoader.GetDocument();
1370 
1371  Refresh(); // get content from loaded document
1372 
1373  pHiddenDocument = nullptr;
1374 
1375  pParentWindow->GetDocNames( &aHiddenTitle ); // fill list
1376 
1377  // document is closed again by ScDocumentLoader in dtor
1378 }
1379 
1381 {
1382  if ( nNew != nRootType )
1383  {
1384  nRootType = nNew;
1385  Refresh();
1386 
1387  ScNavipiCfg& rCfg = SC_MOD()->GetNavipiCfg();
1388  rCfg.SetRootType( nRootType );
1389  }
1390 }
1391 
1392 void ScContentTree::ToggleRoot() // after selection
1393 {
1395  if ( nRootType == ScContentId::ROOT )
1396  {
1397  std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator());
1398  if (m_xTreeView->get_cursor(xEntry.get()))
1399  {
1400  std::unique_ptr<weld::TreeIter> xParent(m_xTreeView->make_iterator(xEntry.get()));
1401  if (!m_xTreeView->iter_parent(*xParent))
1402  xParent.reset();
1403 
1404  for (sal_uInt16 i=1; i<=int(ScContentId::LAST); i++)
1405  {
1406  if (!m_aRootNodes[static_cast<ScContentId>(i)])
1407  continue;
1408  if ((m_xTreeView->iter_compare(*xEntry, *m_aRootNodes[static_cast<ScContentId>(i)]) == 0) ||
1409  (xParent && m_xTreeView->iter_compare(*xParent, *m_aRootNodes[static_cast<ScContentId>(i)]) == 0))
1410  {
1411  nNew = static_cast<ScContentId>(i);
1412  }
1413  }
1414  }
1415  }
1416 
1417  SetRootType( nNew );
1418 }
1419 
1421 {
1422  aManualDoc.clear();
1423  bHiddenDoc = false;
1424 
1425  ActiveDocChanged();
1426 }
1427 
1429 {
1430  bool bRefreshed = false;
1431 
1432  if ( !bHiddenDoc && aManualDoc.isEmpty() )
1433  {
1434  Refresh(); // content only if automatic
1435  bRefreshed = true;
1436  }
1437 
1438  // if flag active Listbox must be updated
1439 
1440  OUString aCurrent;
1441  if ( bHiddenDoc )
1442  aCurrent = aHiddenTitle;
1443  else
1444  {
1445  ScDocShell* pSh = GetManualOrCurrent();
1446  if (pSh)
1447  aCurrent = pSh->GetTitle();
1448  else
1449  {
1450  // document is no longer available
1451 
1452  aManualDoc.clear(); // again automatically
1453  Refresh();
1454  bRefreshed = true;
1455  pSh = GetManualOrCurrent(); // should be active now
1456  if (pSh)
1457  aCurrent = pSh->GetTitle();
1458  }
1459  }
1460  pParentWindow->GetDocNames( &aCurrent ); // select
1461 
1462  return bRefreshed;
1463 }
1464 
1465 void ScContentTree::SetManualDoc(const OUString& rName)
1466 {
1467  aManualDoc = rName;
1468  if (!bHiddenDoc)
1469  {
1470  Refresh();
1471  pParentWindow->GetDocNames( &aManualDoc ); // select
1472  }
1473 }
1474 
1475 void ScContentTree::SelectDoc(const OUString& rName) // rName like shown in Menu/Listbox
1476 {
1477  if ( rName == pParentWindow->aStrActiveWin )
1478  {
1479  ResetManualDoc();
1480  return;
1481  }
1482 
1483  // omit "active" or "inactive"
1484 
1485  OUString aRealName = rName;
1486  sal_Int32 nLen = rName.getLength();
1487  sal_Int32 nActiveStart = nLen - pParentWindow->aStrActive.getLength();
1488  if ( rName.subView( nActiveStart ) == pParentWindow->aStrActive )
1489  aRealName = rName.copy( 0, nActiveStart );
1490  sal_Int32 nNotActiveStart = nLen - pParentWindow->aStrNotActive.getLength();
1491  if ( rName.subView( nNotActiveStart ) == pParentWindow->aStrNotActive )
1492  aRealName = rName.copy( 0, nNotActiveStart );
1493 
1494  bool bLoaded = false;
1495 
1496  // Is it a normally loaded document?
1497 
1499  while ( pSh && !bLoaded )
1500  {
1501  if ( dynamic_cast<const ScDocShell*>( pSh) != nullptr )
1502  if ( pSh->GetTitle() == aRealName )
1503  bLoaded = true;
1504  pSh = SfxObjectShell::GetNext( *pSh );
1505  }
1506 
1507  if (bLoaded)
1508  {
1509  bHiddenDoc = false;
1510  SetManualDoc(aRealName);
1511  }
1512  else if (!aHiddenTitle.isEmpty()) // hidden selected
1513  {
1514  if (!bHiddenDoc)
1516  }
1517  else
1518  {
1519  OSL_FAIL("SelectDoc: not found");
1520  }
1521 }
1522 
1523 void ScContentTree::SelectEntryByName(const ScContentId nRoot, std::u16string_view rName)
1524 {
1525  weld::TreeIter* pParent = m_aRootNodes[nRoot].get();
1526 
1527  if (pParent || !m_xTreeView->iter_has_child(*pParent))
1528  return;
1529 
1530  std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator(pParent));
1531  bool bEntry = m_xTreeView->iter_children(*xEntry);
1532 
1533  while (bEntry)
1534  {
1535  if (m_xTreeView->get_text(*xEntry) == rName)
1536  {
1537  m_xTreeView->select(*xEntry);
1538  m_xTreeView->set_cursor(*xEntry);
1539 
1540  // Scroll to the selected item
1541  m_xTreeView->scroll_to_row(*xEntry);
1542 
1544 
1545  return;
1546  }
1547  bEntry = m_xTreeView->iter_next(*xEntry);
1548  }
1549 }
1550 
1551 void ScContentTree::ApplyNavigatorSettings(bool bRestorePos, int nScrollPos)
1552 {
1554  if( !pSettings )
1555  return;
1556 
1557  ScContentId nRootSel = pSettings->GetRootSelected();
1558  auto nChildSel = pSettings->GetChildSelected();
1559 
1560  // tdf#133079 ensure Sheet root is selected if nothing
1561  // else would be
1562  if (nRootSel == ScContentId::ROOT)
1563  {
1564  nRootSel = ScContentId::TABLE;
1565  nChildSel = SC_CONTENT_NOCHILD;
1566  }
1567 
1568  for( int i = 1; i <= int(ScContentId::LAST); ++i )
1569  {
1570  ScContentId nEntry = static_cast<ScContentId>(i);
1571  if( m_aRootNodes[ nEntry ] )
1572  {
1573  // gray or ungray
1574  if (!m_xTreeView->iter_has_child(*m_aRootNodes[nEntry]))
1575  m_xTreeView->set_sensitive(*m_aRootNodes[nEntry], false);
1576  else
1577  m_xTreeView->set_sensitive(*m_aRootNodes[nEntry], true);
1578 
1579  // expand
1580  bool bExp = pSettings->IsExpanded( nEntry );
1581  if (bExp != m_xTreeView->get_row_expanded(*m_aRootNodes[nEntry]))
1582  {
1583  if( bExp )
1584  m_xTreeView->expand_row(*m_aRootNodes[nEntry]);
1585  else
1586  m_xTreeView->collapse_row(*m_aRootNodes[nEntry]);
1587  }
1588 
1589  // select
1590  if( nRootSel == nEntry )
1591  {
1592  if (bRestorePos)
1593  m_xTreeView->vadjustment_set_value(nScrollPos);
1594 
1595  std::unique_ptr<weld::TreeIter> xEntry;
1596  if (bExp && (nChildSel != SC_CONTENT_NOCHILD))
1597  {
1598  xEntry = m_xTreeView->make_iterator(m_aRootNodes[nEntry].get());
1599  if (!m_xTreeView->iter_children(*xEntry) || !m_xTreeView->iter_nth_sibling(*xEntry, nChildSel))
1600  xEntry.reset();
1601  }
1602  m_xTreeView->select(xEntry ? *xEntry : *m_aRootNodes[nEntry]);
1603  m_xTreeView->set_cursor(xEntry ? *xEntry : *m_aRootNodes[nEntry]);
1604  }
1605  }
1606  }
1607 }
1608 
1610 {
1612  {
1614  m_nAsyncMouseReleaseId = nullptr;
1615  }
1616 
1618  if( !pSettings )
1619  return;
1620 
1621  for( int i = 1; i <= int(ScContentId::LAST); ++i )
1622  {
1623  ScContentId nEntry = static_cast<ScContentId>(i);
1624  bool bExp = m_aRootNodes[nEntry] && m_xTreeView->get_row_expanded(*m_aRootNodes[nEntry]);
1625  pSettings->SetExpanded( nEntry, bExp );
1626  }
1627 
1628  std::unique_ptr<weld::TreeIter> xCurEntry(m_xTreeView->make_iterator());
1629  if (!m_xTreeView->get_cursor(xCurEntry.get()))
1630  xCurEntry.reset();
1631 
1632  ScContentId nRoot;
1633  sal_uLong nChild;
1634  GetEntryIndexes(nRoot, nChild, xCurEntry.get());
1635 
1636  pSettings->SetRootSelected( nRoot );
1637  pSettings->SetChildSelected( nChild );
1638 }
1639 
1640 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SfxViewFrame * GetViewFrame() const
bool m_bFreeze
Definition: content.hxx:57
ScContentId GetRootSelected() const
Definition: navsett.hxx:43
URL aURL
static bool IsPartOfType(ScContentId nContentType, SdrObjKind nObjIdentifier)
Definition: content.cxx:796
sal_Int32 nIndex
SC_DLLPUBLIC ScDBCollection * GetDBCollection() const
Definition: document.hxx:820
ScAddress GetNotePos(sal_uLong nIndex)
Definition: content.cxx:971
ScAddress aStart
Definition: address.hxx:499
todo: It should be possible to have MarkArrays for each table, in order to enable "search all" across...
Definition: markdata.hxx:42
constexpr sal_uInt16 KEY_MOD1
OUString ScResId(TranslateId aId)
Definition: scdll.cxx:89
SCROW Row() const
Definition: address.hxx:261
OUString GetTitle(sal_uInt16 nMaxLen=0) const
#define DND_ACTION_COPY
const ScAreaLink * GetLink(sal_uLong nIndex)
Definition: content.cxx:915
void SetExpanded(ScContentId nIndex, bool bExpand)
Definition: navsett.hxx:39
std::unique_ptr< sal_Int32[]> pData
void GetLinkNames()
Definition: content.cxx:892
SdrObject * GetNamedObject(std::u16string_view rName, SdrObjKind nId, SCTAB &rFoundTab) const
Definition: drwlayer.cxx:2171
const OUString & GetName() const
sal_uIntPtr sal_uLong
SC_DLLPUBLIC ScRangeName * GetRangeName(SCTAB nTab) const
Definition: documen3.cxx:168
bool NoteStringsChanged()
Definition: content.cxx:980
constexpr sal_uInt16 KEY_F5
const wchar_t *typedef int(__stdcall *DllNativeUnregProc)(int
void SetManualDoc(const OUString &rName)
Definition: content.cxx:1465
SdrObject * GetObjectByName(std::u16string_view rName)
Definition: drawview.cxx:652
bool bHiddenDoc
Definition: content.hxx:52
static ImplSVEvent * PostUserEvent(const Link< void *, void > &rLink, void *pCaller=nullptr, bool bReferenceLink=false)
OUString aStrNotActive
Definition: navipi.hxx:113
sal_uInt16 GetCode() const
Contains settings of the navigator listbox.
Definition: navsett.hxx:29
ScAddress aEnd
Definition: address.hxx:500
o3tl::enumarray< ScContentId, sal_uInt16 > pPosList
Definition: content.hxx:60
static SfxObjectShell * Current()
constexpr sal_uInt16 KEY_SPACE
virtual SdrObjKind GetObjIdentifier() const
virtual SfxObjectShell * GetObjectShell() override
void FillTransferableObjectDescriptor(TransferableObjectDescriptor &rDesc) const
EmbeddedObjectRef * pObject
SC_DLLPUBLIC formula::FormulaGrammar::AddressConvention GetAddressConvention() const
Definition: documen3.cxx:494
void GetAreaNames()
Definition: content.cxx:740
void ResetManualDoc()
Definition: content.cxx:1420
void GetDocNames(const OUString *pSelEntry)
Definition: navipi.cxx:846
OUString aManualDoc
Definition: content.hxx:51
sal_uLong GetChildSelected() const
Definition: navsett.hxx:46
SdrObjKind
std::unique_ptr< weld::TreeView > m_xTreeView
Definition: content.hxx:45
const TranslateId SCSTR_CONTENT_ARY[]
Definition: content.cxx:166
static void SetGlobalDrawPersist(SfxObjectShell *pPersist)
Definition: drwlayer.cxx:2654
void GetOleNames()
Definition: content.cxx:882
OUString GetTitle() const
Definition: tablink.cxx:586
void SetRootType(ScContentId nNew)
Definition: navicfg.cxx:51
SC_DLLPUBLIC SCROW MaxRow() const
Definition: document.hxx:878
SC_DLLPUBLIC SCTAB GetTableCount() const
Definition: document.cxx:314
Additional class containing cell annotation data.
Definition: postit.hxx:161
bool empty() const
Definition: rangenam.cxx:811
int nCount
static SfxViewShell * Current()
constexpr int MAX_TREE_NODES
Definition: content.cxx:816
SC_DLLPUBLIC bool GetTable(const OUString &rName, SCTAB &rTab) const
Definition: document.cxx:260
void freeze()
Definition: content.hxx:100
SCTAB Tab() const
Definition: address.hxx:270
sal_uInt16 GetModifier() const
SdrPageView * ShowSdrPage(SdrPage *pPage) override
bool IsExpanded(ScContentId nIndex) const
Definition: navsett.hxx:40
void ApplyNavigatorSettings(bool bRestoreScrollPos=false, int nScrollPos=0)
Applies the navigator settings to the listbox.
Definition: content.cxx:1551
ScDrawView * GetScDrawView()
Definition: viewdata.cxx:3137
ScViewData & GetViewData()
Definition: tabview.hxx:333
OUString aHiddenName
Definition: content.hxx:53
OUString aHiddenTitle
Definition: content.hxx:54
virtual void enable_drag_source(rtl::Reference< TransferDataContainer > &rTransferrable, sal_uInt8 eDNDConstants)=0
rtl::Reference< ScLinkTransferObj > m_xTransferObj
Definition: content.hxx:47
static void RemoveUserEvent(ImplSVEvent *nUserEvent)
void ClearAll()
Definition: content.cxx:199
void InitRoot(ScContentId nType)
Definition: content.cxx:179
SC_DLLPUBLIC ScDrawLayer * GetDrawLayer()
Definition: document.hxx:1064
SC_DLLPUBLIC ScRangeData * findByUpperName(const OUString &rName)
Definition: rangenam.cxx:683
void SelectCurrentViewObject(std::u16string_view rName)
Definition: drawview.cxx:683
SC_DLLPUBLIC SCCOL MaxCol() const
Definition: document.hxx:877
ScDocument * GetDocument()
Definition: tablink.cxx:573
T * get() const
void StoreNavigatorSettings()
Stores the current listbox state in the navigator settings.
Definition: content.cxx:1609
ScDragSrc
Definition: viewdata.hxx:91
void GetGraphicNames()
Definition: content.cxx:877
OUString aStrActiveWin
Definition: navipi.hxx:115
virtual std::unique_ptr< SdrModel > CreateMarkedObjModel() const
ScContentId nRootType
Definition: content.hxx:50
const SvBaseLinks & GetLinks() const
bool ActiveDocChanged()
Definition: content.cxx:1428
void InsertContent(ScContentId nType, const OUString &rValue)
Definition: content.cxx:232
int i
static OUString lcl_GetDBAreaRange(const ScDocument *pDoc, const OUString &rDBName)
Definition: content.cxx:301
static OUString lcl_NoteString(const ScPostIt &rNote)
Definition: content.cxx:941
void SelectTable(SCTAB nTab, bool bNew)
Definition: markdata.cxx:171
ScAddress GetNotePosition(size_t nIndex) const
Definition: document.cxx:6710
std::unique_ptr< ScDocument, o3tl::default_delete< ScDocument > > ScDocumentUniquePtr
Definition: document.hxx:2630
sal_Int16 SCCOL
Definition: types.hxx:21
#define SC_MOD()
Definition: scmod.hxx:250
static SC_DLLPUBLIC const CharClass & getCharClass()
Definition: global.cxx:1013
ScSheetLimits & GetSheetLimits() const
Definition: document.hxx:879
OUString Format(const ScDocument &rDocument, ScRefFlags nFlags=ScRefFlags::ZERO, const ScAddress::Details &rDetails=ScAddress::detailsOOOa1, bool bFullAddressNotation=false) const
Returns string with formatted cell range from aStart to aEnd, according to provided address conventio...
Definition: address.cxx:2204
static ScTabViewShell * GetTabViewShell()
Definition: navipi.cxx:699
const SdrPage * GetPage(sal_uInt16 nPgNum) const
void SetDrawShell(bool bActive)
Definition: tabvwsh4.cxx:611
float u
OUString GetText() const
Returns the caption text of this note.
Definition: postit.cxx:914
ImplSVEvent * m_nAsyncMouseReleaseId
Definition: content.hxx:58
void GetNoteStrings()
Definition: content.cxx:950
ScDocShell * GetManualOrCurrent()
Definition: content.cxx:90
bool HasName() const
IMPL_LINK_NOARG(ScContentTree, ContentDoubleClickHdl, weld::TreeView &, bool)
Definition: content.cxx:318
#define DND_ACTION_LINK
ScContentTree(std::unique_ptr< weld::TreeView > xTreeView, ScNavigatorDlg *pNavigatorDlg)
Definition: content.cxx:121
ScContentId
Definition: content.hxx:35
bool HasSelectedBlockMatrixFragment(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, const ScMarkData &rMark) const
Definition: document.cxx:5421
void SetDragJump(ScDocument *pLocalDoc, const OUString &rTarget, const OUString &rText)
Definition: scmod.cxx:605
void GetArea(SCTAB &rTab, SCCOL &rCol1, SCROW &rRow1, SCCOL &rCol2, SCROW &rRow2) const
Definition: dbdata.cxx:300
constexpr rtl::OUStringConstExpr aContentBmps[]
Definition: content.cxx:78
SCCOL Col() const
Definition: address.hxx:266
bool bIsInNavigatorDlg
Definition: content.hxx:56
constexpr sal_uInt16 KEY_RETURN
sal_uLong GetChildIndex(const weld::TreeIter *pEntry) const
Returns the child index of the specified listbox entry.
Definition: content.cxx:293
ScDBData * findByUpperName(const OUString &rName)
Definition: dbdata.cxx:1141
void GetDbNames()
Definition: content.cxx:778
void SetChildSelected(sal_uLong nIndex)
Definition: navsett.hxx:45
bool IsError() const
Definition: tablink.cxx:578
void GetDrawNames(ScContentId nType)
Definition: content.cxx:818
Stores global named database ranges.
Definition: dbdata.hxx:234
const ScContentId pTypeList[int(ScContentId::LAST)+1]
Definition: content.cxx:65
SdrObject * Next()
sal_Int32 SCROW
Definition: types.hxx:17
IMPL_LINK(ScContentTree, KeyInputHdl, const KeyEvent &, rKEvt, bool)
Definition: content.cxx:418
std::unique_ptr< weld::TreeIter > m_xScratchIter
Definition: content.hxx:46
void GetDrawingNames()
Definition: content.cxx:887
void LaunchAsyncStoreNavigatorSettings()
Definition: content.cxx:400
void Refresh(ScContentId nType=ScContentId::ROOT)
Definition: content.cxx:668
void LoadFile(const OUString &rUrl)
Definition: content.cxx:1353
static bool lcl_GetRange(const ScDocument &rDoc, ScContentId nType, const OUString &rName, ScRange &rRange)
Definition: content.cxx:1066
static ScNavigatorSettings * GetNavigatorSettings()
Definition: navipi.cxx:704
ScNavigatorDlg * pParentWindow
Definition: content.hxx:48
SvBaseLink * pLink
static SfxObjectShell * GetFirst(const std::function< bool(const SfxObjectShell *)> &isObjectShell=nullptr, bool bOnlyVisible=true)
SdrIterMode
OUString aName
void SelectEntryByName(const ScContentId nRoot, std::u16string_view rName)
Definition: content.cxx:1523
bool DoInitNew(SfxMedium *pMedium=nullptr)
const INetURLObject & GetURLObject() const
static OUString GetVisibleName(const SdrObject *pObj)
Definition: drwlayer.cxx:2145
void * p
QPRO_FUNC_TYPE nType
Definition: qproform.cxx:398
void SetRootType(ScContentId nNew)
Definition: content.cxx:1380
const ScDocument & GetDocument() const
Definition: docsh.hxx:220
static bool lcl_DoDragCells(ScDocShell *pSrcShell, const ScRange &rRange, ScDragSrc nFlags, weld::TreeView &rTreeView)
Definition: content.cxx:1159
void GetEntryIndexes(ScContentId &rnRootIndex, sal_uLong &rnChildIndex, const weld::TreeIter *pEntry) const
Returns the indexes of the specified listbox entry.
Definition: content.cxx:246
SC_DLLPUBLIC bool IsValidReference(ScRange &rRef) const
Definition: rangenam.cxx:386
NamedDBs & getNamedDBs()
Definition: dbdata.hxx:315
SdrPageView * GetSdrPageView() const
OUString GetURLNoPass(DecodeMechanism eMechanism=DecodeMechanism::ToIUri, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
ROOT
void SetRootSelected(ScContentId nIndex)
Definition: navsett.hxx:42
ScDocument * pHiddenDocument
Definition: content.hxx:55
ScXMLEditAttributeMap::Entry const aEntries[]
SfxObjectShell * GetDocumentShell() const
Definition: document.hxx:1063
#define SAL_WARN(area, stream)
ScDocument * GetSourceDocument()
Definition: content.cxx:654
static SfxObjectShell * GetNext(const SfxObjectShell &rPrev, const std::function< bool(const SfxObjectShell *)> &isObjectShell=nullptr, bool bOnlyVisible=true)
static void ReleaseFocus()
Definition: navipi.cxx:65
bool MarkObj(const Point &rPnt, short nTol=-2, bool bToggle=false, bool bDeep=false)
void ClearType(ScContentId nType)
Definition: content.cxx:216
bool DrawNamesChanged(ScContentId nType)
Definition: content.cxx:1010
This struct stores general clipboard parameters associated with a ScDocument instance created in clip...
Definition: clipparam.hxx:30
SC_DLLPUBLIC sfx2::LinkManager * GetLinkManager()
Definition: documen2.cxx:219
void GetTableNames()
Definition: content.cxx:714
void ToggleRoot()
Definition: content.cxx:1392
SdrModel * GetModel() const
void SelectDoc(const OUString &rName)
Definition: content.cxx:1475
void SetDragLink(const OUString &rDoc, const OUString &rTab, const OUString &rArea)
Definition: scmod.cxx:596
OUString aStrActive
Definition: navipi.hxx:112
o3tl::enumarray< ScContentId, std::unique_ptr< weld::TreeIter > > m_aRootNodes
Definition: content.hxx:49
SC_DLLPUBLIC bool GetName(SCTAB nTab, OUString &rName) const
Definition: document.cxx:213
SC_DLLPUBLIC bool insert(ScRangeData *p, bool bReuseFreeIndex=true)
Insert object into set.
Definition: rangenam.cxx:816
bool GetObjectIsMarked(const SdrObject *pObject)
Definition: drawview.cxx:796
sal_uInt16 nPos
sal_Int16 SCTAB
Definition: types.hxx:22
static std::unique_ptr< weld::Builder > CreateBuilder(weld::Widget *pParent, const OUString &rUIFile, bool bMobile=false, sal_uInt64 nLOKWindowId=0)
void thaw()
Definition: content.hxx:106
SC_DLLPUBLIC void CopyToClip(const ScClipParam &rClipParam, ScDocument *pClipDoc, const ScMarkData *pMarks, bool bKeepScenarioFlags, bool bIncludeObjects)
Definition: document.cxx:2154
static bool lcl_DoDragObject(ScDocShell *pSrcShell, std::u16string_view rName, ScContentId nType, weld::TreeView &rTreeView)
Definition: content.cxx:1101
const sal_uLong SC_CONTENT_NOCHILD
Definition: content.hxx:41
SC_DLLPUBLIC void GetAllNoteEntries(std::vector< sc::NoteEntry > &rNotes) const
Definition: document.cxx:6774
OUString sId
SfxMedium * GetMedium() const