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>
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
61using 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
78constexpr 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
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
121ScContentTree::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
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{
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
232void 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
246void 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
301static 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
318IMPL_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 {
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
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
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
406IMPL_LINK_NOARG(ScContentTree, MouseReleaseHdl, const MouseEvent&, bool)
407{
408 LaunchAsyncStoreNavigatorSettings();
409 return false;
410}
411
412IMPL_LINK_NOARG(ScContentTree, AsyncStoreNavigatorSettings, void*, void)
413{
414 m_nAsyncMouseReleaseId = nullptr;
415 StoreNavigatorSettings();
416}
417
418IMPL_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;
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
531IMPL_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
621IMPL_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);
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;
680 return;
683 return;
686 return;
687
688 freeze();
689
690 ClearType( nType );
691
695 GetAreaNames();
697 GetDbNames();
701 GetOleNames();
707 GetLinkNames();
708
709 thaw();
710
712}
713
715{
716 if ( nRootType != ScContentId::ROOT && nRootType != ScContentId::TABLE ) // hidden ?
717 return;
718
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
732namespace {
733
734OUString createLocalRangeName(std::u16string_view rName, std::u16string_view rTableName)
735{
736 return OUString::Concat(rName) + " (" + rTableName + ")";
737}
738}
739
741{
743 return;
744
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
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
796bool 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
816constexpr int MAX_TREE_NODES = 1000;
817
819{
821 return;
822
823 if ( nRootType != ScContentId::ROOT && nRootType != nType ) // hidden ?
824 return;
825
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 {
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{
895 return;
896
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{
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
941static 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
956 if (!pDoc)
957 return;
958
959 // loop over cell notes
960 std::vector<sc::NoteEntry> 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{
974 if (!pDoc)
975 return ScAddress();
976
977 return pDoc->GetNotePosition(nIndex);
978}
979
981{
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;
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
1066static bool lcl_GetRange( const ScDocument& rDoc, ScContentId nType, const OUString& rName, ScRange& rRange )
1067{
1068 bool bFound = false;
1069
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
1101static 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);
1151
1152 bDisallow = false;
1153 }
1154 }
1155
1156 return bDisallow;
1157}
1158
1159static 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);
1191
1192 bDisallow = false;
1193 }
1194
1195 return bDisallow;
1196}
1197
1198IMPL_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) &&
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;
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();
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 }
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
1353void 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
1392void ScContentTree::ToggleRoot() // after selection
1393{
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
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 {
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
1465void ScContentTree::SetManualDoc(const OUString& rName)
1466{
1467 aManualDoc = rName;
1468 if (!bHiddenDoc)
1469 {
1470 Refresh();
1471 pParentWindow->GetDocNames( &aManualDoc ); // select
1472 }
1473}
1474
1475void ScContentTree::SelectDoc(const OUString& rName) // rName like shown in Menu/Listbox
1476{
1477 if ( rName == pParentWindow->aStrActiveWin )
1478 {
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
1523void 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
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 std::unique_ptr<weld::TreeIter> xEntry;
1593 if (bExp && (nChildSel != SC_CONTENT_NOCHILD))
1594 {
1595 xEntry = m_xTreeView->make_iterator(m_aRootNodes[nEntry].get());
1596 if (!m_xTreeView->iter_children(*xEntry) || !m_xTreeView->iter_nth_sibling(*xEntry, nChildSel))
1597 xEntry.reset();
1598 }
1599 m_xTreeView->select(xEntry ? *xEntry : *m_aRootNodes[nEntry]);
1600 m_xTreeView->set_cursor(xEntry ? *xEntry : *m_aRootNodes[nEntry]);
1601 }
1602 }
1603 }
1604}
1605
1607{
1609 {
1611 m_nAsyncMouseReleaseId = nullptr;
1612 }
1613
1615 if( !pSettings )
1616 return;
1617
1618 for( int i = 1; i <= int(ScContentId::LAST); ++i )
1619 {
1620 ScContentId nEntry = static_cast<ScContentId>(i);
1621 bool bExp = m_aRootNodes[nEntry] && m_xTreeView->get_row_expanded(*m_aRootNodes[nEntry]);
1622 pSettings->SetExpanded( nEntry, bExp );
1623 }
1624
1625 std::unique_ptr<weld::TreeIter> xCurEntry(m_xTreeView->make_iterator());
1626 if (!m_xTreeView->get_cursor(xCurEntry.get()))
1627 xCurEntry.reset();
1628
1629 ScContentId nRoot;
1630 sal_uLong nChild;
1631 GetEntryIndexes(nRoot, nChild, xCurEntry.get());
1632
1633 pSettings->SetRootSelected( nRoot );
1634 pSettings->SetChildSelected( nChild );
1635}
1636
1637/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
std::unique_ptr< weld::TreeView > m_xTreeView
static ImplSVEvent * PostUserEvent(const Link< void *, void > &rLink, void *pCaller=nullptr, bool bReferenceLink=false)
static std::unique_ptr< weld::Builder > CreateBuilder(weld::Widget *pParent, const OUString &rUIFile, bool bMobile=false, sal_uInt64 nLOKWindowId=0)
static void RemoveUserEvent(ImplSVEvent *nUserEvent)
OUString GetURLNoPass(DecodeMechanism eMechanism=DecodeMechanism::ToIUri, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
SCTAB Tab() const
Definition: address.hxx:283
SCROW Row() const
Definition: address.hxx:274
SCCOL Col() const
Definition: address.hxx:279
void SelectEntryByName(const ScContentId nRoot, std::u16string_view rName)
Definition: content.cxx:1523
ScDocument * pHiddenDocument
Definition: content.hxx:55
const ScAreaLink * GetLink(sal_uLong nIndex)
Definition: content.cxx:915
ScContentTree(std::unique_ptr< weld::TreeView > xTreeView, ScNavigatorDlg *pNavigatorDlg)
Definition: content.cxx:121
void GetLinkNames()
Definition: content.cxx:892
std::unique_ptr< weld::TreeIter > m_xScratchIter
Definition: content.hxx:46
void ToggleRoot()
Definition: content.cxx:1392
void GetNoteStrings()
Definition: content.cxx:950
void freeze()
Definition: content.hxx:100
void ClearType(ScContentId nType)
Definition: content.cxx:216
void thaw()
Definition: content.hxx:106
std::unique_ptr< weld::TreeView > m_xTreeView
Definition: content.hxx:45
void GetOleNames()
Definition: content.cxx:882
bool bHiddenDoc
Definition: content.hxx:52
void LaunchAsyncStoreNavigatorSettings()
Definition: content.cxx:400
ImplSVEvent * m_nAsyncMouseReleaseId
Definition: content.hxx:58
void StoreNavigatorSettings()
Stores the current listbox state in the navigator settings.
Definition: content.cxx:1606
void GetDrawNames(ScContentId nType)
Definition: content.cxx:818
void ApplyNavigatorSettings()
Applies the navigator settings to the listbox.
Definition: content.cxx:1551
bool NoteStringsChanged()
Definition: content.cxx:980
void GetTableNames()
Definition: content.cxx:714
bool ActiveDocChanged()
Definition: content.cxx:1428
void InsertContent(ScContentId nType, const OUString &rValue)
Definition: content.cxx:232
void Refresh(ScContentId nType=ScContentId::ROOT)
Definition: content.cxx:668
void GetDrawingNames()
Definition: content.cxx:887
OUString aHiddenName
Definition: content.hxx:53
o3tl::enumarray< ScContentId, sal_uInt16 > pPosList
Definition: content.hxx:60
OUString aManualDoc
Definition: content.hxx:51
bool bIsInNavigatorDlg
Definition: content.hxx:56
void SelectDoc(const OUString &rName)
Definition: content.cxx:1475
sal_uLong GetChildIndex(const weld::TreeIter *pEntry) const
Returns the child index of the specified listbox entry.
Definition: content.cxx:293
o3tl::enumarray< ScContentId, std::unique_ptr< weld::TreeIter > > m_aRootNodes
Definition: content.hxx:49
ScDocShell * GetManualOrCurrent()
Definition: content.cxx:90
void ClearAll()
Definition: content.cxx:199
void SetRootType(ScContentId nNew)
Definition: content.cxx:1380
static bool IsPartOfType(ScContentId nContentType, SdrObjKind nObjIdentifier)
Definition: content.cxx:796
rtl::Reference< ScLinkTransferObj > m_xTransferObj
Definition: content.hxx:47
ScContentId nRootType
Definition: content.hxx:50
void GetAreaNames()
Definition: content.cxx:740
void SetManualDoc(const OUString &rName)
Definition: content.cxx:1465
void GetDbNames()
Definition: content.cxx:778
ScNavigatorDlg * pParentWindow
Definition: content.hxx:48
void InitRoot(ScContentId nType)
Definition: content.cxx:179
void GetGraphicNames()
Definition: content.cxx:877
void GetEntryIndexes(ScContentId &rnRootIndex, sal_uLong &rnChildIndex, const weld::TreeIter *pEntry) const
Returns the indexes of the specified listbox entry.
Definition: content.cxx:246
ScDocument * GetSourceDocument()
Definition: content.cxx:654
void LoadFile(const OUString &rUrl)
Definition: content.cxx:1353
OUString aHiddenTitle
Definition: content.hxx:54
ScAddress GetNotePos(sal_uLong nIndex)
Definition: content.cxx:971
bool DrawNamesChanged(ScContentId nType)
Definition: content.cxx:1010
bool m_bFreeze
Definition: content.hxx:57
void ResetManualDoc()
Definition: content.cxx:1420
Stores global named database ranges.
Definition: dbdata.hxx:235
ScDBData * findByUpperName(const OUString &rName)
Definition: dbdata.cxx:1196
NamedDBs & getNamedDBs()
Definition: dbdata.hxx:316
const ScDocument & GetDocument() const
Definition: docsh.hxx:220
bool IsError() const
Definition: tablink.cxx:578
OUString GetTitle() const
Definition: tablink.cxx:586
ScDocument * GetDocument()
Definition: tablink.cxx:573
ScSheetLimits & GetSheetLimits() const
Definition: document.hxx:897
SC_DLLPUBLIC bool GetTable(const OUString &rName, SCTAB &rTab) const
Definition: document.cxx:262
SC_DLLPUBLIC SCCOL MaxCol() const
Definition: document.hxx:891
SC_DLLPUBLIC formula::FormulaGrammar::AddressConvention GetAddressConvention() const
Definition: documen3.cxx:494
SC_DLLPUBLIC SCROW MaxRow() const
Definition: document.hxx:892
SC_DLLPUBLIC void CopyToClip(const ScClipParam &rClipParam, ScDocument *pClipDoc, const ScMarkData *pMarks, bool bKeepScenarioFlags, bool bIncludeObjects)
Definition: document.cxx:2171
SC_DLLPUBLIC void GetAllNoteEntries(std::vector< sc::NoteEntry > &rNotes) const
Definition: document.cxx:6979
SC_DLLPUBLIC ScDrawLayer * GetDrawLayer()
Definition: document.hxx:1082
ScAddress GetNotePosition(size_t nIndex) const
Definition: document.cxx:6915
SC_DLLPUBLIC ScDBCollection * GetDBCollection() const
Definition: document.hxx:826
SfxObjectShell * GetDocumentShell() const
Definition: document.hxx:1081
SC_DLLPUBLIC ScRangeName * GetRangeName(SCTAB nTab) const
Definition: documen3.cxx:168
SC_DLLPUBLIC sfx2::LinkManager * GetLinkManager()
Definition: documen2.cxx:230
SC_DLLPUBLIC bool GetName(SCTAB nTab, OUString &rName) const
Definition: document.cxx:215
bool HasSelectedBlockMatrixFragment(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, const ScMarkData &rMark) const
Definition: document.cxx:5508
SC_DLLPUBLIC SCTAB GetTableCount() const
Definition: document.cxx:315
static OUString GetVisibleName(const SdrObject *pObj)
Definition: drwlayer.cxx:2146
static void SetGlobalDrawPersist(SfxObjectShell *pPersist)
Definition: drwlayer.cxx:2655
SdrObject * GetNamedObject(std::u16string_view rName, SdrObjKind nId, SCTAB &rFoundTab) const
Definition: drwlayer.cxx:2172
void SelectCurrentViewObject(std::u16string_view rName)
Definition: drawview.cxx:683
SdrObject * GetObjectByName(std::u16string_view rName)
Definition: drawview.cxx:652
bool GetObjectIsMarked(const SdrObject *pObject)
Definition: drawview.cxx:796
static SC_DLLPUBLIC const CharClass & getCharClass()
Definition: global.cxx:1024
todo: It should be possible to have MarkArrays for each table, in order to enable "search all" across...
Definition: markdata.hxx:43
void SelectTable(SCTAB nTab, bool bNew)
Definition: markdata.cxx:157
void SetMarkArea(const ScRange &rRange)
Definition: markdata.cxx:92
void SetDragLink(const OUString &rDoc, const OUString &rTab, const OUString &rArea)
Definition: scmod.cxx:626
void SetDragJump(ScDocument *pLocalDoc, const OUString &rTarget, const OUString &rText)
Definition: scmod.cxx:644
static ScNavigatorSettings * GetNavigatorSettings()
Definition: navipi.cxx:703
OUString aStrActiveWin
Definition: navipi.hxx:115
OUString aStrNotActive
Definition: navipi.hxx:113
static ScTabViewShell * GetTabViewShell()
Definition: navipi.cxx:698
void GetDocNames(const OUString *pSelEntry)
Definition: navipi.cxx:845
OUString aStrActive
Definition: navipi.hxx:112
static void ReleaseFocus()
Definition: navipi.cxx:64
Contains settings of the navigator listbox.
Definition: navsett.hxx:30
bool IsExpanded(ScContentId nIndex) const
Definition: navsett.hxx:40
ScContentId GetRootSelected() const
Definition: navsett.hxx:43
sal_uLong GetChildSelected() const
Definition: navsett.hxx:46
void SetRootSelected(ScContentId nIndex)
Definition: navsett.hxx:42
void SetChildSelected(sal_uLong nIndex)
Definition: navsett.hxx:45
void SetExpanded(ScContentId nIndex, bool bExpand)
Definition: navsett.hxx:39
void SetRootType(ScContentId nNew)
Definition: navicfg.cxx:51
Additional class containing cell annotation data.
Definition: postit.hxx:161
OUString GetText() const
Returns the caption text of this note.
Definition: postit.cxx:916
bool empty() const
Definition: rangenam.hxx:249
SC_DLLPUBLIC ScRangeData * findByUpperName(const OUString &rName)
Definition: rangenam.cxx:704
SC_DLLPUBLIC bool insert(ScRangeData *p, bool bReuseFreeIndex=true)
Insert object into set.
Definition: rangenam.cxx:802
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:2170
ScAddress aEnd
Definition: address.hxx:498
ScAddress aStart
Definition: address.hxx:497
void SetDrawShell(bool bActive)
Definition: tabvwsh4.cxx:612
ScViewData & GetViewData()
Definition: tabview.hxx:333
ScDrawView * GetScDrawView()
Definition: viewdata.cxx:3169
virtual std::unique_ptr< SdrModel > CreateMarkedObjModel() const
bool MarkObj(const Point &rPnt, short nTol=-2, bool bToggle=false, bool bDeep=false)
const SdrPage * GetPage(sal_uInt16 nPgNum) const
SdrPageView * ShowSdrPage(SdrPage *pPage) override
SdrObject * Next()
SdrModel * GetModel() const
SdrPageView * GetSdrPageView() const
const INetURLObject & GetURLObject() const
const OUString & GetName() const
void FillTransferableObjectDescriptor(TransferableObjectDescriptor &rDesc) const
bool HasName() const
static SfxObjectShell * GetNext(const SfxObjectShell &rPrev, const std::function< bool(const SfxObjectShell *)> &isObjectShell=nullptr, bool bOnlyVisible=true)
SfxMedium * GetMedium() const
OUString GetTitle(sal_uInt16 nMaxLen=0) const
static SfxObjectShell * GetFirst(const std::function< bool(const SfxObjectShell *)> &isObjectShell=nullptr, bool bOnlyVisible=true)
static SfxObjectShell * Current()
virtual SfxObjectShell * GetObjectShell() override
SfxViewFrame * GetViewFrame() const
static SfxViewShell * Current()
const SvBaseLinks & GetLinks() const
T * get() const
sal_uInt16 GetCode() const
sal_uInt16 GetModifier() const
virtual void enable_drag_source(rtl::Reference< TransferDataContainer > &rTransferrable, sal_uInt8 eDNDConstants)=0
constexpr rtl::OUStringConstExpr aContentBmps[]
Definition: content.cxx:78
IMPL_LINK_NOARG(ScContentTree, ContentDoubleClickHdl, weld::TreeView &, bool)
Definition: content.cxx:318
static OUString lcl_GetDBAreaRange(const ScDocument *pDoc, const OUString &rDBName)
Definition: content.cxx:301
const ScContentId pTypeList[int(ScContentId::LAST)+1]
Definition: content.cxx:65
static bool lcl_DoDragObject(ScDocShell *pSrcShell, std::u16string_view rName, ScContentId nType, weld::TreeView &rTreeView)
Definition: content.cxx:1101
const TranslateId SCSTR_CONTENT_ARY[]
Definition: content.cxx:166
IMPL_LINK(ScContentTree, KeyInputHdl, const KeyEvent &, rKEvt, bool)
Definition: content.cxx:418
static OUString lcl_NoteString(const ScPostIt &rNote)
Definition: content.cxx:941
constexpr int MAX_TREE_NODES
Definition: content.cxx:816
static bool lcl_GetRange(const ScDocument &rDoc, ScContentId nType, const OUString &rName, ScRange &rRange)
Definition: content.cxx:1066
static bool lcl_DoDragCells(ScDocShell *pSrcShell, const ScRange &rRange, ScDragSrc nFlags, weld::TreeView &rTreeView)
Definition: content.cxx:1159
ScContentId
Definition: content.hxx:35
const sal_uLong SC_CONTENT_NOCHILD
Definition: content.hxx:41
int nCount
URL aURL
std::unique_ptr< ScDocument, o3tl::default_delete< ScDocument > > ScDocumentUniquePtr
Definition: document.hxx:2715
@ SCDOCMODE_CLIP
Definition: document.hxx:256
float u
ScXMLEditAttributeMap::Entry const aEntries[]
EmbeddedObjectRef * pObject
sal_Int32 nIndex
OUString aName
void * p
constexpr sal_uInt16 KEY_RETURN
constexpr sal_uInt16 KEY_MOD1
constexpr sal_uInt16 KEY_F5
constexpr sal_uInt16 KEY_SPACE
sal_uInt16 nPos
SvBaseLink * pLink
#define SAL_WARN(area, stream)
std::unique_ptr< sal_Int32[]> pData
int i
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
ROOT
#define SC_DROPMODE_COPY
Definition: navipi.hxx:41
#define SC_DROPMODE_URL
Definition: navipi.hxx:39
#define SC_DROPMODE_LINK
Definition: navipi.hxx:40
QPRO_FUNC_TYPE nType
Definition: qproform.cxx:398
const wchar_t *typedef int(__stdcall *DllNativeUnregProc)(int
OUString ScResId(TranslateId aId)
Definition: scdll.cxx:90
#define SC_MOD()
Definition: scmod.hxx:249
sal_uIntPtr sal_uLong
This struct stores general clipboard parameters associated with a ScDocument instance created in clip...
Definition: clipparam.hxx:31
SdrIterMode
SdrObjKind
#define DND_ACTION_COPY
#define DND_ACTION_LINK
sal_Int16 SCTAB
Definition: types.hxx:22
sal_Int16 SCCOL
Definition: types.hxx:21
sal_Int32 SCROW
Definition: types.hxx:17
OUString sId
ScDragSrc
Definition: viewdata.hxx:91