LibreOffice Module sd (master) 1
Outliner.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 <Outliner.hxx>
21#include <boost/property_tree/json_parser.hpp>
22#include <vcl/settings.hxx>
23#include <vcl/svapp.hxx>
24
25#include <svl/srchitem.hxx>
26#include <svl/intitem.hxx>
27#include <editeng/editstat.hxx>
28#include <vcl/canvastools.hxx>
29#include <vcl/outdev.hxx>
30#include <vcl/weld.hxx>
31#include <sfx2/dispatch.hxx>
32#include <svx/svdotext.hxx>
33#include <svx/svdograf.hxx>
34#include <editeng/unolingu.hxx>
35#include <com/sun/star/linguistic2/XSpellChecker1.hpp>
36#include <svx/srchdlg.hxx>
38#include <unotools/lingucfg.hxx>
39#include <editeng/editeng.hxx>
40#include <sfx2/viewfrm.hxx>
41#include <tools/debug.hxx>
43
44#include <strings.hrc>
45#include <editeng/outliner.hxx>
46#include <sdmod.hxx>
47#include <Window.hxx>
48#include <sdresid.hxx>
49#include <DrawViewShell.hxx>
50#include <OutlineView.hxx>
51#include <OutlineViewShell.hxx>
52#include <drawdoc.hxx>
53#include <DrawDocShell.hxx>
54#include <drawview.hxx>
55#include <ViewShellBase.hxx>
56#include <SpellDialogChildWindow.hxx>
58#include <svx/svxids.hrc>
59#include <LibreOfficeKit/LibreOfficeKitEnums.h>
60#include <comphelper/string.hxx>
61#include <comphelper/lok.hxx>
64#include <fusearch.hxx>
65
66using namespace ::com::sun::star;
67using namespace ::com::sun::star::uno;
68using namespace ::com::sun::star::lang;
69using namespace ::com::sun::star::linguistic2;
70
72
74{
75public:
81
84
89
95 Outliner& rOutliner,
96 const std::shared_ptr<sd::ViewShell>& rpViewShell,
97 vcl::Window* pWindow);
98
101 void ReleaseOutlinerView();
102
104
105private:
111
118
120};
121
122namespace
123{
124
125sd::ViewShellBase* getViewShellBase()
126{
127 return dynamic_cast<sd::ViewShellBase*>(SfxViewShell::Current());
128}
129
130} // end anonymous namespace
131
133 : SdrOutliner( &pDoc->GetItemPool(), nMode ),
134 mpImpl(new Implementation()),
135 meMode(SEARCH),
136 mpView(nullptr),
137 mpWindow(nullptr),
138 mpDrawDocument(pDoc),
139 mnConversionLanguage(LANGUAGE_NONE),
140 mnIgnoreCurrentPageChangesLevel(0),
141 mbStringFound(false),
142 mbMatchMayExist(false),
143 mnPageCount(0),
144 mbEndOfSearch(false),
145 mbFoundObject(false),
146 mbDirectionIsForward(true),
147 mbRestrictSearchToSelection(false),
148 mpObj(nullptr),
149 mpFirstObj(nullptr),
150 mpSearchSpellTextObj(nullptr),
151 mnText(0),
152 mpParaObj(nullptr),
153 meStartViewMode(PageKind::Standard),
154 meStartEditMode(EditMode::Page),
155 mnStartPageIndex(sal_uInt16(-1)),
156 mpStartEditedObject(nullptr),
157 mbPrepareSpellingPending(true)
158{
159 SetStyleSheetPool(static_cast<SfxStyleSheetPool*>( mpDrawDocument->GetStyleSheetPool() ));
160 SetEditTextObjectPool( &pDoc->GetItemPool() );
161 SetCalcFieldValueHdl(LINK(SD_MOD(), SdModule, CalcFieldValueHdl));
162 SetForbiddenCharsTable( pDoc->GetForbiddenCharsTable() );
163
164 EEControlBits nCntrl = GetControlWord();
165 nCntrl |= EEControlBits::ALLOWBIGOBJS;
166 nCntrl |= EEControlBits::MARKFIELDS;
167 nCntrl |= EEControlBits::AUTOCORRECT;
168
169 bool bOnlineSpell = false;
170
172
173 if (pDocSh)
174 {
175 bOnlineSpell = mpDrawDocument->GetOnlineSpell();
176 }
177 else
178 {
179 bOnlineSpell = false;
180
181 try
182 {
183 const SvtLinguConfig aLinguConfig;
184 Any aAny = aLinguConfig.GetProperty( UPN_IS_SPELL_AUTO );
185 aAny >>= bOnlineSpell;
186 }
187 catch( ... )
188 {
189 OSL_FAIL( "Ill. type in linguistic property" );
190 }
191 }
192
193 if (bOnlineSpell)
194 nCntrl |= EEControlBits::ONLINESPELLING;
195 else
196 nCntrl &= ~EEControlBits::ONLINESPELLING;
197
198 SetControlWord(nCntrl);
199
200 Reference< XSpellChecker1 > xSpellChecker( LinguMgr::GetSpellChecker() );
201 if ( xSpellChecker.is() )
202 SetSpeller( xSpellChecker );
203
204 Reference< XHyphenator > xHyphenator( LinguMgr::GetHyphenator() );
205 if( xHyphenator.is() )
206 SetHyphenator( xHyphenator );
207
208 SetDefaultLanguage( Application::GetSettings().GetLanguageTag().getLanguageType() );
209}
210
213{
214}
215
217{
218 return mpImpl->GetOutlinerView();
219}
220
242{
244
245 sd::ViewShellBase* pBase = getViewShellBase();
246 if (pBase != nullptr)
248 SetRefDevice( SD_MOD()->GetVirtualRefDevice() );
249
250 std::shared_ptr<sd::ViewShell> pViewShell (mpWeakViewShell.lock());
251 if (pViewShell)
252 {
253 mbStringFound = false;
254
255 // Supposed that we are not located at the very beginning/end of
256 // the document then there may be a match in the document
257 // prior/after the current position.
258 mbMatchMayExist = true;
259
263
264 mpImpl->ProvideOutlinerView(*this, pViewShell, mpWindow);
265
267 }
268 ClearModifyFlag();
269}
270
272{
273 meMode = SPELL;
275 mpSearchItem.reset();
276}
277
282{
283 // Keep old view shell alive until we release the outliner view.
284 std::shared_ptr<sd::ViewShell> pViewShell (mpWeakViewShell.lock());
285 std::shared_ptr<sd::ViewShell> pOldViewShell (pViewShell);
286
287 sd::ViewShellBase* pBase = getViewShellBase();
288 if (pBase != nullptr)
289 pViewShell = pBase->GetMainViewShell();
290 else
291 pViewShell.reset();
292 mpWeakViewShell = pViewShell;
293
294 // When in <member>PrepareSpelling()</member> a new outline view has
295 // been created then delete it here.
296 bool bViewIsDrawViewShell(dynamic_cast< const sd::DrawViewShell *>( pViewShell.get() ));
297 if (bViewIsDrawViewShell)
298 {
299 SetStatusEventHdl(Link<EditStatus&,void>());
300 mpView = pViewShell->GetView();
303 // Make FuSelection the current function.
304 pViewShell->GetDispatcher()->Execute(
305 SID_OBJECT_SELECT,
306 SfxCallMode::SYNCHRON | SfxCallMode::RECORD);
307
308 // Remove and, if previously created by us, delete the outline
309 // view.
310 OutlinerView* pOutlinerView = getOutlinerView();
311 if (pOutlinerView != nullptr)
312 {
313 RemoveView(pOutlinerView);
314 mpImpl->ReleaseOutlinerView();
315 }
316
317 SetUpdateLayout(true);
318 }
319
320 // Before clearing the modify flag use it as a hint that
321 // changes were done at SpellCheck
322 if(IsModified())
323 {
324 if(auto pOutlineView = dynamic_cast<sd::OutlineView *>( mpView ))
325 pOutlineView->PrepareClose();
328 }
329
330 // Now clear the modify flag to have a specified state of
331 // Outliner
332 ClearModifyFlag();
333
334 // When spell checking then restore the start position.
337
338 mpWeakViewShell.reset();
339 mpView = nullptr;
340 mpWindow = nullptr;
341 mnStartPageIndex = sal_uInt16(-1);
342}
343
345{
346 std::shared_ptr<sd::ViewShell> pViewShell (mpWeakViewShell.lock());
347 if( nullptr != dynamic_cast< const sd::OutlineViewShell *>( pViewShell.get() ))
348 {
349 // When doing a spell check in the outline view then there is
350 // only one document.
351 mbEndOfSearch = true;
352 EndOfSearch ();
353 }
354 else
355 {
356 if( auto pOutlineView = dynamic_cast<sd::OutlineView *>( mpView ))
357 pOutlineView->PrepareClose();
358 mpDrawDocument->GetDocSh()->SetWaitCursor( true );
359
360 Initialize (true);
361
362 mpWindow = pViewShell->GetActiveWindow();
363 OutlinerView* pOutlinerView = getOutlinerView();
364 if (pOutlinerView != nullptr)
365 pOutlinerView->SetWindow(mpWindow);
367
368 mpDrawDocument->GetDocSh()->SetWaitCursor( false );
369 ClearModifyFlag();
370 }
371
372 return !mbEndOfSearch;
373}
374
379{
380 svx::SpellPortions aResult;
381
382 DetectChange();
383 // Iterate over sentences and text shapes until a sentence with a
384 // spelling error has been found. If no such sentence can be
385 // found the loop is left through a break.
386 // It is the responsibility of the sd outliner object to correctly
387 // iterate over all text shapes, i.e. switch between views, wrap
388 // around at the end of the document, stop when all text shapes
389 // have been examined exactly once.
390 bool bFoundNextSentence = false;
391 while ( ! bFoundNextSentence)
392 {
393 OutlinerView* pOutlinerView = GetView(0);
394 if (pOutlinerView != nullptr)
395 {
396 ESelection aCurrentSelection (pOutlinerView->GetSelection());
397 if ( ! mbMatchMayExist
398 && maStartSelection < aCurrentSelection)
399 EndOfSearch();
400
401 // Advance to the next sentence.
402 bFoundNextSentence = SpellSentence( pOutlinerView->GetEditView(), aResult);
403 }
404
405 // When no sentence with spelling errors has been found in the
406 // currently selected text shape or there is no selected text
407 // shape then advance to the next text shape.
408 if ( ! bFoundNextSentence)
409 if ( ! SpellNextDocument())
410 // All text objects have been processed so exit the
411 // loop and return an empty portions list.
412 break;
413 }
414
415 return aResult;
416}
417
421{
422 bool bEndOfSearch = true;
423
424 // clear the search toolbar entry
425 SvxSearchDialogWrapper::SetSearchLabel(SearchLabel::Empty);
426
427 mpDrawDocument->GetDocSh()->SetWaitCursor( true );
428
429 // Since REPLACE is really a replaceAndSearchNext instead of a searchAndReplace,
430 // make sure that the search portion has not changed since the last FIND.
432 && pSearchItem->GetCommand() == SvxSearchCmd::REPLACE
433 && !mpSearchItem->equalsIgnoring(*pSearchItem, /*bIgnoreReplace=*/true,
434 /*bIgnoreCommand=*/true))
435 {
436 EndSpelling();
438 }
439
442 sd::ViewShellBase* pBase = getViewShellBase();
443 // Determine whether we have to abort the search. This is necessary
444 // when the main view shell does not support searching.
445 bool bAbort = false;
446 if (pBase != nullptr)
447 {
448 std::shared_ptr<sd::ViewShell> pShell (pBase->GetMainViewShell());
449 SetViewShell(pShell);
450 if (pShell == nullptr)
451 bAbort = true;
452 else
453 switch (pShell->GetShellType())
454 {
460 bAbort = false;
461 break;
462 default:
463 bAbort = true;
464 break;
465 }
466 }
467
468 std::shared_ptr<sd::ViewShell> pViewShell (mpWeakViewShell.lock());
469 if ( ! pViewShell)
470 {
471 OSL_ASSERT(pViewShell);
472 return true;
473 }
474
475 if ( ! bAbort)
476 {
477 meMode = SEARCH;
478 mpSearchItem.reset(pSearchItem->Clone());
479
480 mbFoundObject = false;
481
482 Initialize ( ! mpSearchItem->GetBackward());
483
484 const SvxSearchCmd nCommand (mpSearchItem->GetCommand());
485 if (nCommand == SvxSearchCmd::FIND_ALL || nCommand == SvxSearchCmd::REPLACE_ALL)
486 {
487 bEndOfSearch = SearchAndReplaceAll ();
488 }
489 else
490 {
492 bEndOfSearch = SearchAndReplaceOnce ();
493 // restore start position if nothing was found
494 if(!mbStringFound)
495 {
497 // Nothing was changed, no need to restart the spellchecker.
498 if (nCommand == SvxSearchCmd::FIND)
499 bEndOfSearch = false;
500 }
501 mnStartPageIndex = sal_uInt16(-1);
502 }
503 }
504
505 mpDrawDocument->GetDocSh()->SetWaitCursor( false );
506
507 return bEndOfSearch;
508}
509
510void SdOutliner::Initialize (bool bDirectionIsForward)
511{
512 const bool bIsAtEnd (maObjectIterator == sd::outliner::OutlinerContainer(this).end());
513 const bool bOldDirectionIsForward = mbDirectionIsForward;
514 mbDirectionIsForward = bDirectionIsForward;
515
517 {
518 // Initialize a new search.
521
522 std::shared_ptr<sd::ViewShell> pViewShell (mpWeakViewShell.lock());
523 if ( ! pViewShell)
524 {
525 OSL_ASSERT(pViewShell);
526 return;
527 }
528
529 // In case we are searching in an outline view then first remove the
530 // current selection and place cursor at its start or end.
531 if( nullptr != dynamic_cast< const sd::OutlineViewShell *>( pViewShell.get() ))
532 {
533 ESelection aSelection = getOutlinerView()->GetSelection ();
535 {
536 aSelection.nEndPara = aSelection.nStartPara;
537 aSelection.nEndPos = aSelection.nStartPos;
538 }
539 else
540 {
541 aSelection.nStartPara = aSelection.nEndPara;
542 aSelection.nStartPos = aSelection.nEndPos;
543 }
544 getOutlinerView()->SetSelection (aSelection);
545 }
546
547 // When not beginning the search at the beginning of the search area
548 // then there may be matches before the current position.
550 }
551 else if (bOldDirectionIsForward != mbDirectionIsForward)
552 {
553 // Requested iteration direction has changed. Turn around the iterator.
555 if (bIsAtEnd)
556 {
557 // The iterator has pointed to end(), which after the search
558 // direction is reversed, becomes begin().
560 }
561 else
562 {
563 // The iterator has pointed to the object one ahead/before the current
564 // one. Now move it to the one before/ahead the current one.
567 {
569 }
570 }
571
572 mbMatchMayExist = true;
573 }
574
575 // Initialize the last valid position with where the search starts so
576 // that it always points to a valid position.
578}
579
581{
582 bool bRet = true;
583
584 // Save the current position to be restored after having replaced all
585 // matches.
587
588 std::shared_ptr<sd::ViewShell> pViewShell (mpWeakViewShell.lock());
589 if ( ! pViewShell)
590 {
591 OSL_ASSERT(pViewShell);
592 return true;
593 }
594
595 std::vector<sd::SearchSelection> aSelections;
596 if( nullptr != dynamic_cast< const sd::OutlineViewShell *>( pViewShell.get() ))
597 {
598 // Put the cursor to the beginning/end of the outliner.
600
601 // The outliner does all the work for us when we are in this mode.
603 }
604 else if( nullptr != dynamic_cast< const sd::DrawViewShell *>( pViewShell.get() ))
605 {
606 // Disable selection change notifications during search all.
607 SfxViewShell& rSfxViewShell = pViewShell->GetViewShellBase();
608 rSfxViewShell.setTiledSearching(true);
609 comphelper::ScopeGuard aGuard([&rSfxViewShell]()
610 {
611 rSfxViewShell.setTiledSearching(false);
612 });
613
614 // Go to beginning/end of document.
616 // Switch to the first object which contains the search string.
618 if( !mbStringFound )
619 {
621 mnStartPageIndex = sal_uInt16(-1);
622 return true;
623 }
624 // Reset the iterator back to the beginning
626
627 // Search/replace until the end of the document is reached.
628 bool bFoundMatch;
629 do
630 {
631 bFoundMatch = ! SearchAndReplaceOnce(&aSelections);
632 if (mpSearchItem->GetCommand() == SvxSearchCmd::FIND_ALL && comphelper::LibreOfficeKit::isActive() && bFoundMatch && aSelections.size() == 1)
633 {
634 // Without this, RememberStartPosition() will think it already has a remembered position.
635 mnStartPageIndex = sal_uInt16(-1);
636
638
639 // So when RestoreStartPosition() restores the first match, then spellchecker doesn't kill the selection.
640 bRet = false;
641 }
642 }
643 while (bFoundMatch);
644
645 if (mpSearchItem->GetCommand() == SvxSearchCmd::FIND_ALL && comphelper::LibreOfficeKit::isActive() && !aSelections.empty())
646 {
647 boost::property_tree::ptree aTree;
648 aTree.put("searchString", mpSearchItem->GetSearchString().toUtf8().getStr());
649 aTree.put("highlightAll", true);
650
651 boost::property_tree::ptree aChildren;
652 for (const sd::SearchSelection& rSelection : aSelections)
653 {
654 boost::property_tree::ptree aChild;
655 aChild.put("part", OString::number(rSelection.m_nPage).getStr());
656 aChild.put("rectangles", rSelection.m_aRectangles.getStr());
657 aChildren.push_back(std::make_pair("", aChild));
658 }
659 aTree.add_child("searchResultSelection", aChildren);
660
661 std::stringstream aStream;
662 boost::property_tree::write_json(aStream, aTree);
663 OString aPayload( aStream.str() );
664 rSfxViewShell.libreOfficeKitViewCallback(LOK_CALLBACK_SEARCH_RESULT_SELECTION, aPayload);
665 }
666 }
667
669
670 if (mpSearchItem->GetCommand() == SvxSearchCmd::FIND_ALL && comphelper::LibreOfficeKit::isActive() && !bRet)
671 {
672 // Find-all, tiled rendering and we have at least one match.
673 OString aPayload = OString::number(mnStartPageIndex);
674 SfxViewShell& rSfxViewShell = pViewShell->GetViewShellBase();
675 rSfxViewShell.libreOfficeKitViewCallback(LOK_CALLBACK_SET_PART, aPayload);
676
677 // Emit a selection callback here:
678 // 1) The original one is no longer valid, as we there was a SET_PART in between
679 // 2) The underlying editeng will only talk about the first match till
680 // it doesn't support multi-selection.
681 std::vector<OString> aRectangles;
682 for (const sd::SearchSelection& rSelection : aSelections)
683 {
684 if (rSelection.m_nPage == mnStartPageIndex)
685 aRectangles.push_back(rSelection.m_aRectangles);
686 }
687 OString sRectangles = comphelper::string::join("; ", aRectangles);
688 rSfxViewShell.libreOfficeKitViewCallback(LOK_CALLBACK_TEXT_SELECTION, sRectangles);
689 }
690
691 mnStartPageIndex = sal_uInt16(-1);
692
693 return bRet;
694}
695
696namespace
697{
698
699basegfx::B2DRectangle getPDFSelection(const std::unique_ptr<VectorGraphicSearch> & rVectorGraphicSearch,
700 const SdrObject* pObject)
701{
702 basegfx::B2DRectangle aSelection;
703
704 auto const & rTextRectangles = rVectorGraphicSearch->getTextRectangles();
705 if (rTextRectangles.empty())
706 return aSelection;
707
708 basegfx::B2DSize aPdfPageSizeHMM = rVectorGraphicSearch->pageSize();
709
711
712 // Setup coordinate conversion matrix to convert the inner PDF
713 // coordinates to the page relative coordinates
714 basegfx::B2DHomMatrix aB2DMatrix;
715
716 aB2DMatrix.scale(aObjectB2DRectHMM.getWidth() / aPdfPageSizeHMM.getWidth(),
717 aObjectB2DRectHMM.getHeight() / aPdfPageSizeHMM.getHeight());
718
719 aB2DMatrix.translate(aObjectB2DRectHMM.getMinX(), aObjectB2DRectHMM.getMinY());
720
721
722 for (auto const & rRectangle : rVectorGraphicSearch->getTextRectangles())
723 {
724 basegfx::B2DRectangle aRectangle(rRectangle);
725 aRectangle *= aB2DMatrix;
726
727 if (aSelection.isEmpty())
728 aSelection = aRectangle;
729 else
730 aSelection.expand(aRectangle);
731 }
732
733 return aSelection;
734}
735
736} // end namespace
737
738void SdOutliner::sendLOKSearchResultCallback(const std::shared_ptr<sd::ViewShell> & pViewShell,
739 const OutlinerView* pOutlinerView,
740 std::vector<sd::SearchSelection>* pSelections)
741{
742 std::vector<::tools::Rectangle> aLogicRects;
743 auto& rVectorGraphicSearchContext = mpImpl->getVectorGraphicSearchContext();
744 if (rVectorGraphicSearchContext.mbCurrentIsVectorGraphic)
745 {
746 basegfx::B2DRectangle aSelectionHMM = getPDFSelection(rVectorGraphicSearchContext.mpVectorGraphicSearch, mpObj);
747
748 tools::Rectangle aSelection(Point(aSelectionHMM.getMinX(), aSelectionHMM.getMinY()),
749 Size(aSelectionHMM.getWidth(), aSelectionHMM.getHeight()));
750 aSelection = o3tl::convert(aSelection, o3tl::Length::mm100, o3tl::Length::twip);
751 aLogicRects.push_back(aSelection);
752 }
753 else
754 {
755 pOutlinerView->GetSelectionRectangles(aLogicRects);
756
757 // convert to twips if in 100thmm (seems as if LibreOfficeKit is based on twips?). Do this
758 // here where we have the only place needing this, *not* in ImpEditView::GetSelectionRectangles
759 // which makes that method unusable for others
760 if (pOutlinerView->GetWindow() && MapUnit::Map100thMM == pOutlinerView->GetWindow()->GetMapMode().GetMapUnit())
761 {
762 for (tools::Rectangle& rRectangle : aLogicRects)
763 {
764 rRectangle = o3tl::convert(rRectangle, o3tl::Length::mm100, o3tl::Length::twip);
765 }
766 }
767 }
768
769 std::vector<OString> aLogicRectStrings;
770 std::transform(aLogicRects.begin(), aLogicRects.end(), std::back_inserter(aLogicRectStrings),
771 [](const ::tools::Rectangle& rRectangle)
772 {
773 return rRectangle.toString();
774 });
775
776 OString sRectangles = comphelper::string::join("; ", aLogicRectStrings);
777
778 if (!pSelections)
779 {
780 // notify LibreOfficeKit about changed page
781 OString aPayload = OString::number(maCurrentPosition.mnPageIndex);
782 SfxViewShell& rSfxViewShell = pViewShell->GetViewShellBase();
783 rSfxViewShell.libreOfficeKitViewCallback(LOK_CALLBACK_SET_PART, aPayload);
784
785 // also about search result selections
786 boost::property_tree::ptree aTree;
787 aTree.put("searchString", mpSearchItem->GetSearchString().toUtf8().getStr());
788 aTree.put("highlightAll", false);
789
790 boost::property_tree::ptree aChildren;
791 boost::property_tree::ptree aChild;
792 aChild.put("part", OString::number(maCurrentPosition.mnPageIndex).getStr());
793 aChild.put("rectangles", sRectangles.getStr());
794 aChildren.push_back(std::make_pair("", aChild));
795 aTree.add_child("searchResultSelection", aChildren);
796
797 std::stringstream aStream;
798 boost::property_tree::write_json(aStream, aTree);
799 aPayload = OString(aStream.str());
800 rSfxViewShell.libreOfficeKitViewCallback(LOK_CALLBACK_SEARCH_RESULT_SELECTION, aPayload);
801
802 if (rVectorGraphicSearchContext.mbCurrentIsVectorGraphic)
803 {
804 rSfxViewShell.libreOfficeKitViewCallback(LOK_CALLBACK_TEXT_SELECTION, sRectangles);
805 }
806 }
807 else
808 {
809 sd::SearchSelection aSelection(maCurrentPosition.mnPageIndex, sRectangles);
810 bool bDuplicate = !pSelections->empty() && pSelections->back() == aSelection;
811 if (!bDuplicate)
812 pSelections->push_back(aSelection);
813 }
814}
815
816bool SdOutliner::SearchAndReplaceOnce(std::vector<sd::SearchSelection>* pSelections)
817{
818 DetectChange ();
819
820 std::shared_ptr<sd::ViewShell> pViewShell (mpWeakViewShell.lock());
821
822 if (!getOutlinerView() || !GetEditEngine().HasView(&getOutlinerView()->GetEditView()))
823 {
824 std::shared_ptr<sd::DrawViewShell> pDrawViewShell (
825 std::dynamic_pointer_cast<sd::DrawViewShell>(pViewShell));
826
827 // Perhaps the user switched to a different page/slide between searches.
828 // If so, reset the starting search position to the current slide like DetectChange does
829 if (pDrawViewShell && pDrawViewShell->GetCurPagePos() != maCurrentPosition.mnPageIndex)
831
832 mpImpl->ProvideOutlinerView(*this, pViewShell, mpWindow);
833 }
834
835 if (pViewShell)
836 {
837 mpView = pViewShell->GetView();
838 mpWindow = pViewShell->GetActiveWindow();
840 auto& rVectorGraphicSearchContext = mpImpl->getVectorGraphicSearchContext();
841 if (nullptr != dynamic_cast<const sd::DrawViewShell*>(pViewShell.get()))
842 {
843 sal_uLong nMatchCount = 0;
844
845 if (rVectorGraphicSearchContext.mbCurrentIsVectorGraphic)
846 {
847 OUString const & rString = mpSearchItem->GetSearchString();
848 bool bBackwards = mpSearchItem->GetBackward();
849
851 aOptions.meStartPosition = bBackwards ? SearchStartPosition::End : SearchStartPosition::Begin;
852 aOptions.mbMatchCase = mpSearchItem->GetExact();
853 aOptions.mbMatchWholeWord = mpSearchItem->GetWordOnly();
854
855 bool bResult = rVectorGraphicSearchContext.mpVectorGraphicSearch->search(rString, aOptions);
856
857 if (bResult)
858 {
859 if (bBackwards)
860 bResult = rVectorGraphicSearchContext.mpVectorGraphicSearch->previous();
861 else
862 bResult = rVectorGraphicSearchContext.mpVectorGraphicSearch->next();
863 }
864
865 if (bResult)
866 {
867 nMatchCount = 1;
868
869 SdrPageView* pPageView = mpView->GetSdrPageView();
870 mpView->UnmarkAllObj(pPageView);
871
872 std::vector<basegfx::B2DRectangle> aSubSelections;
873 basegfx::B2DRectangle aSubSelection = getPDFSelection(rVectorGraphicSearchContext.mpVectorGraphicSearch, mpObj);
874 if (!aSubSelection.isEmpty())
875 aSubSelections.push_back(aSubSelection);
876 mpView->MarkObj(mpObj, pPageView, false, false, std::move(aSubSelections));
877 }
878 else
879 {
880 rVectorGraphicSearchContext.reset();
881 }
882 }
883 else
884 {
885 // When replacing we first check if there is a selection
886 // indicating a match. If there is then replace it. The
887 // following call to StartSearchAndReplace will then search for
888 // the next match.
889 if (meMode == SEARCH && mpSearchItem->GetCommand() == SvxSearchCmd::REPLACE)
890 {
891 if (getOutlinerView()->GetSelection().HasRange())
893 }
894
895 // Search for the next match.
896 if (mpSearchItem->GetCommand() != SvxSearchCmd::REPLACE_ALL)
897 {
899 }
900 }
901
902 // Go to the next text object when there have been no matches in
903 // the current object or the whole object has already been
904 // processed.
905 if (nMatchCount==0 || mpSearchItem->GetCommand()==SvxSearchCmd::REPLACE_ALL)
906 {
908
909 if (!mbEndOfSearch && !rVectorGraphicSearchContext.mbCurrentIsVectorGraphic)
910 {
911 // Remember the current position as the last one with a
912 // text object.
914
915 // Now that the mbEndOfSearch flag guards this block the
916 // following assertion and return should not be
917 // necessary anymore.
918 DBG_ASSERT(GetEditEngine().HasView(&getOutlinerView()->GetEditView() ),
919 "SearchAndReplace without valid view!" );
920 if ( ! GetEditEngine().HasView( &getOutlinerView()->GetEditView() ) )
921 {
922 mpDrawDocument->GetDocSh()->SetWaitCursor( false );
923 return true;
924 }
925
926 if (meMode == SEARCH)
928 }
929 }
930 }
931 else if (nullptr != dynamic_cast<const sd::OutlineViewShell*>(pViewShell.get()))
932 {
933 mpDrawDocument->GetDocSh()->SetWaitCursor(false);
934 // The following loop is executed more than once only when a
935 // wrap around search is done.
936 while (true)
937 {
939 if (nResult == 0)
940 {
941 if (HandleFailedSearch ())
942 {
944 continue;
945 }
946 }
947 else
948 mbStringFound = true;
949 break;
950 }
951 }
952 }
953
954 mpDrawDocument->GetDocSh()->SetWaitCursor( false );
955
957 {
958 sendLOKSearchResultCallback(pViewShell, getOutlinerView(), pSelections);
959 }
960
961 return mbEndOfSearch;
962}
963
968{
970
971 std::shared_ptr<sd::ViewShell> pViewShell (mpWeakViewShell.lock());
972 std::shared_ptr<sd::DrawViewShell> pDrawViewShell (
973 std::dynamic_pointer_cast<sd::DrawViewShell>(pViewShell));
974
975 // Detect whether the view has been switched from the outside.
976 if (pDrawViewShell != nullptr
977 && (aPosition.meEditMode != pDrawViewShell->GetEditMode()
978 || aPosition.mePageKind != pDrawViewShell->GetPageKind()))
979 {
980 // Either the edit mode or the page kind has changed.
981 SetStatusEventHdl(Link<EditStatus&,void>());
982
983 SdrPageView* pPageView = mpView->GetSdrPageView();
984 if (pPageView != nullptr)
985 mpView->UnmarkAllObj (pPageView);
987 SetUpdateLayout(false);
988 OutlinerView* pOutlinerView = getOutlinerView();
989 if (pOutlinerView != nullptr)
990 pOutlinerView->SetOutputArea( ::tools::Rectangle( Point(), Size(1, 1) ) );
991 if (meMode == SPELL)
992 SetPaperSize( Size(1, 1) );
993 SetText(OUString(), GetParagraph(0));
994
996
997 mnPageCount = mpDrawDocument->GetSdPageCount(pDrawViewShell->GetPageKind());
999 }
1000
1001 // Detect change of the set of selected objects. If their number has
1002 // changed start again with the first selected object.
1003 else if (DetectSelectionChange())
1004 {
1007 }
1008
1009 // Detect change of page count. Restart search at first/last page in
1010 // that case.
1011 else if (aPosition.meEditMode == EditMode::Page
1013 {
1014 // The number of pages has changed.
1017 }
1018 else if (aPosition.meEditMode == EditMode::MasterPage
1020 {
1021 // The number of master pages has changed.
1024 }
1025}
1026
1028{
1029 bool bSelectionHasChanged = false;
1030
1031 // If mpObj is NULL then we have not yet found our first match.
1032 // Detecting a change makes no sense.
1033 if (mpObj != nullptr)
1034 {
1035 const size_t nMarkCount = mpView ? mpView->GetMarkedObjectList().GetMarkCount() : 0;
1036 switch (nMarkCount)
1037 {
1038 case 0:
1039 // The selection has changed when previously there have been
1040 // selected objects.
1041 bSelectionHasChanged = mbRestrictSearchToSelection;
1042 break;
1043 case 1:
1044 // Check if the only selected object is not the one that we
1045 // had selected.
1046 if (mpView != nullptr)
1047 {
1049 if (pMark != nullptr)
1050 bSelectionHasChanged = (mpObj != pMark->GetMarkedSdrObj ());
1051 }
1052 break;
1053 default:
1054 // We had selected exactly one object.
1055 bSelectionHasChanged = true;
1056 break;
1057 }
1058 }
1059
1060 return bSelectionHasChanged;
1061}
1062
1064{
1065 std::shared_ptr<sd::ViewShell> pViewShell (mpWeakViewShell.lock());
1066 if ( ! pViewShell)
1067 {
1068 OSL_ASSERT(pViewShell);
1069 return;
1070 }
1071
1072 if ( mnStartPageIndex != sal_uInt16(-1) )
1073 return;
1074
1075 if( nullptr != dynamic_cast< const sd::DrawViewShell *>( pViewShell.get() ))
1076 {
1077 std::shared_ptr<sd::DrawViewShell> pDrawViewShell (
1078 std::dynamic_pointer_cast<sd::DrawViewShell>(pViewShell));
1079 if (pDrawViewShell != nullptr)
1080 {
1081 meStartViewMode = pDrawViewShell->GetPageKind();
1082 meStartEditMode = pDrawViewShell->GetEditMode();
1083 mnStartPageIndex = pDrawViewShell->GetCurPagePos();
1084 }
1085
1086 if (mpView != nullptr)
1087 {
1089 if (mpStartEditedObject != nullptr)
1090 {
1091 // Try to retrieve current caret position only when there is an
1092 // edited object.
1093 ::Outliner* pOutliner =
1094 static_cast<sd::DrawView*>(mpView)->GetTextEditOutliner();
1095 if (pOutliner!=nullptr && pOutliner->GetViewCount()>0)
1096 {
1097 OutlinerView* pOutlinerView = pOutliner->GetView(0);
1098 maStartSelection = pOutlinerView->GetSelection();
1099 }
1100 }
1101 }
1102 }
1103 else if( nullptr != dynamic_cast< const sd::OutlineViewShell *>( pViewShell.get() ))
1104 {
1105 // Remember the current cursor position.
1106 OutlinerView* pView = GetView(0);
1107 if (pView != nullptr)
1108 pView->GetSelection();
1109 }
1110 else
1111 {
1112 mnStartPageIndex = sal_uInt16(-1);
1113 }
1114}
1115
1117{
1118 bool bRestore = true;
1119 // Take a negative start page index as indicator that restoring the
1120 // start position is not requested.
1121 if (mnStartPageIndex == sal_uInt16(-1) )
1122 bRestore = false;
1123 // Don't restore when the view shell is not valid.
1124 std::shared_ptr<sd::ViewShell> pViewShell (mpWeakViewShell.lock());
1125 if (pViewShell == nullptr)
1126 bRestore = false;
1127
1128 if (!bRestore)
1129 return;
1130
1131 if( nullptr != dynamic_cast< const sd::DrawViewShell *>( pViewShell.get() ))
1132 {
1133 std::shared_ptr<sd::DrawViewShell> pDrawViewShell (
1134 std::dynamic_pointer_cast<sd::DrawViewShell>(pViewShell));
1136 if (pDrawViewShell != nullptr)
1137 {
1140 if (mpObj)
1141 {
1143 EnterEditMode(false);
1144 if (getOutlinerView())
1146 }
1147 }
1148 }
1149 else if( nullptr != dynamic_cast< const sd::OutlineViewShell *>( pViewShell.get() ))
1150 {
1151 // Set cursor to its old position.
1152 OutlinerView* pView = GetView(0);
1153 if (pView != nullptr)
1155 }
1156}
1157
1158namespace
1159{
1160
1161bool lclIsValidTextObject(const sd::outliner::IteratorPosition& rPosition)
1162{
1163 auto* pObject = DynCastSdrTextObj( rPosition.mxObject.get().get() );
1164 return (pObject != nullptr) && pObject->HasText() && ! pObject->IsEmptyPresObj();
1165}
1166
1167bool isValidVectorGraphicObject(const sd::outliner::IteratorPosition& rPosition)
1168{
1169 rtl::Reference<SdrGrafObj> pGraphicObject = dynamic_cast<SdrGrafObj*>(rPosition.mxObject.get().get());
1170 if (pGraphicObject)
1171 {
1172 auto const& pVectorGraphicData = pGraphicObject->GetGraphic().getVectorGraphicData();
1173 if (pVectorGraphicData && VectorGraphicDataType::Pdf == pVectorGraphicData->getType())
1174 {
1175 return true;
1176 }
1177 }
1178 return false;
1179}
1180
1181} // end anonymous namespace
1182
1183
1192{
1193 mbEndOfSearch = false;
1194 mbFoundObject = false;
1195
1196 // reset the vector search
1197 auto& rVectorGraphicSearchContext = mpImpl->getVectorGraphicSearchContext();
1198 rVectorGraphicSearchContext.reset();
1199
1201 try
1202 {
1204 }
1205 catch (const css::uno::Exception&)
1206 {
1207 DBG_UNHANDLED_EXCEPTION("sd.view");
1208 }
1209 SetUpdateLayout(false);
1210 OutlinerView* pOutlinerView = getOutlinerView();
1211 if (pOutlinerView != nullptr)
1212 pOutlinerView->SetOutputArea( ::tools::Rectangle( Point(), Size(1, 1) ) );
1213 if (meMode == SPELL)
1214 SetPaperSize( Size(1, 1) );
1215 SetText(OUString(), GetParagraph(0));
1216
1217 mpSearchSpellTextObj = nullptr;
1218
1219 // Iterate until a valid text object has been found or the search ends.
1220 do
1221 {
1222 mpObj = nullptr;
1223 mpParaObj = nullptr;
1224
1226 {
1228
1229 // LOK: do not descent to notes or master pages when searching
1231
1232 rVectorGraphicSearchContext.reset();
1233
1234 if (!bForbiddenPage)
1235 {
1236 // Switch to the current object only if it is a valid text object.
1237 if (lclIsValidTextObject(maCurrentPosition))
1238 {
1239 // Don't set yet in case of searching: the text object may not match.
1240 if (meMode != SEARCH)
1242 else
1244 }
1245 // Or if the object is a valid graphic object which contains vector graphic
1246 else if (meMode == SEARCH && isValidVectorGraphicObject(maCurrentPosition))
1247 {
1249 rVectorGraphicSearchContext.mbCurrentIsVectorGraphic = true;
1250 }
1251 }
1252
1253 // Advance to the next object
1255
1256 if (mpObj)
1257 {
1258 if (rVectorGraphicSearchContext.mbCurrentIsVectorGraphic)
1259 {
1260 // We know here the object is a SdrGrafObj and that it
1261 // contains a vector graphic
1262 auto* pGraphicObject = static_cast<SdrGrafObj*>(mpObj);
1263 OUString const & rString = mpSearchItem->GetSearchString();
1264 bool bBackwards = mpSearchItem->GetBackward();
1265
1267 aOptions.meStartPosition = bBackwards ? SearchStartPosition::End : SearchStartPosition::Begin;
1268 aOptions.mbMatchCase = mpSearchItem->GetExact();
1269 aOptions.mbMatchWholeWord = mpSearchItem->GetWordOnly();
1270
1271 rVectorGraphicSearchContext.mpVectorGraphicSearch = std::make_unique<VectorGraphicSearch>(pGraphicObject->GetGraphic());
1272
1273 bool bResult = rVectorGraphicSearchContext.mpVectorGraphicSearch->search(rString, aOptions);
1274 if (bResult)
1275 {
1276 if (bBackwards)
1277 bResult = rVectorGraphicSearchContext.mpVectorGraphicSearch->previous();
1278 else
1279 bResult = rVectorGraphicSearchContext.mpVectorGraphicSearch->next();
1280 }
1281
1282 if (bResult)
1283 {
1285
1286 mbStringFound = true;
1287 mbMatchMayExist = true;
1288 mbFoundObject = true;
1289
1290 SdrPageView* pPageView = mpView->GetSdrPageView();
1291 mpView->UnmarkAllObj(pPageView);
1292
1293 std::vector<basegfx::B2DRectangle> aSubSelections;
1294 basegfx::B2DRectangle aSubSelection = getPDFSelection(rVectorGraphicSearchContext.mpVectorGraphicSearch, mpObj);
1295 if (!aSubSelection.isEmpty())
1296 aSubSelections.push_back(aSubSelection);
1297
1298 mpView->MarkObj(mpObj, pPageView, false, false, std::move(aSubSelections));
1299
1300 mpDrawDocument->GetDocSh()->SetWaitCursor( false );
1301 }
1302 else
1303 {
1304 rVectorGraphicSearchContext.reset();
1305 }
1306 }
1307 else
1308 {
1310
1311 std::shared_ptr<sd::ViewShell> pViewShell (mpWeakViewShell.lock());
1312 if (pViewShell != nullptr)
1313 {
1314 switch (meMode)
1315 {
1316 case SEARCH:
1318 break;
1319 case SPELL:
1321 break;
1322 case TEXT_CONVERSION:
1324 break;
1325 }
1326 }
1327 }
1328 }
1329 }
1330 else
1331 {
1332 rVectorGraphicSearchContext.reset();
1333
1334 if (meMode == SEARCH)
1335 // Instead of doing a full-blown SetObject(), which would do the same -- but would also possibly switch pages.
1336 mbStringFound = false;
1337
1338 mbEndOfSearch = true;
1339 EndOfSearch ();
1340 }
1341 }
1342 while ( ! (mbFoundObject || mbEndOfSearch));
1343}
1344
1346{
1347 std::shared_ptr<sd::ViewShell> pViewShell (mpWeakViewShell.lock());
1348 if ( ! pViewShell)
1349 {
1350 OSL_ASSERT(pViewShell);
1351 return;
1352 }
1353
1354 // Before we display a dialog we first jump to where the last valid text
1355 // object was found. All page and view mode switching since then was
1356 // temporary and should not be visible to the user.
1357 if( nullptr == dynamic_cast< const sd::OutlineViewShell *>( pViewShell.get() ))
1359
1362 else
1363 {
1364 // When no match has been found so far then terminate the search.
1365 if ( ! mbMatchMayExist)
1366 {
1368 mbEndOfSearch = true;
1369 }
1370 // Ask the user whether to wrap around and continue the search or
1371 // to terminate.
1373 {
1374 mbMatchMayExist = false;
1375 // Everything back to beginning (or end?) of the document.
1377 if( nullptr != dynamic_cast< const sd::OutlineViewShell *>( pViewShell.get() ))
1378 {
1379 // Set cursor to first character of the document.
1380 OutlinerView* pOutlinerView = getOutlinerView();
1381 if (pOutlinerView != nullptr)
1382 pOutlinerView->SetSelection (GetSearchStartPosition ());
1383 }
1384
1385 mbEndOfSearch = false;
1386 }
1387 else
1388 {
1389 // No wrap around.
1390 mbEndOfSearch = true;
1391 }
1392 }
1393}
1394
1396{
1397 if (meMode == SEARCH)
1398 {
1399 if (!mbStringFound)
1400 {
1401 SvxSearchDialogWrapper::SetSearchLabel(SearchLabel::NotFound);
1402 std::shared_ptr<sd::ViewShell> pViewShell(mpWeakViewShell.lock());
1403 if (pViewShell)
1404 {
1405 SfxViewShell& rSfxViewShell = pViewShell->GetViewShellBase();
1406 rSfxViewShell.libreOfficeKitViewCallback(LOK_CALLBACK_SEARCH_NOT_FOUND, mpSearchItem->GetSearchString().toUtf8());
1407 }
1408 }
1409
1410 // don't do anything else for search
1411 return;
1412 }
1413
1414 OUString aString;
1415 if (mpView->AreObjectsMarked())
1416 aString = SdResId(STR_END_SPELLING_OBJ);
1417 else
1418 aString = SdResId(STR_END_SPELLING);
1419
1420 // Show the message in an info box that is modal with respect to the whole application.
1421 weld::Window* pParent = GetMessageBoxParent();
1422 std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(pParent,
1423 VclMessageType::Info, VclButtonsType::Ok, aString));
1424 xInfoBox->run();
1425}
1426
1428{
1429 // Determine whether to show the dialog.
1430 if (mpSearchItem)
1431 {
1432 // When searching display the dialog only for single find&replace.
1433 const SvxSearchCmd nCommand(mpSearchItem->GetCommand());
1434 if (nCommand == SvxSearchCmd::REPLACE || nCommand == SvxSearchCmd::FIND)
1435 {
1438 else
1439 SvxSearchDialogWrapper::SetSearchLabel(SearchLabel::Start);
1440
1441 return true;
1442 }
1443 else
1444 return false;
1445 }
1446
1447 // show dialog only for spelling
1448 if (meMode != SPELL)
1449 return false;
1450
1451 // The question text depends on the search direction.
1453
1454 TranslateId pStringId;
1456 pStringId = bImpress ? STR_SAR_WRAP_FORWARD : STR_SAR_WRAP_FORWARD_DRAW;
1457 else
1458 pStringId = bImpress ? STR_SAR_WRAP_BACKWARD : STR_SAR_WRAP_BACKWARD_DRAW;
1459
1460 // Pop up question box that asks the user whether to wrap around.
1461 // The dialog is made modal with respect to the whole application.
1462 weld::Window* pParent = GetMessageBoxParent();
1463 std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(pParent,
1464 VclMessageType::Question, VclButtonsType::YesNo, SdResId(pStringId)));
1465 sal_uInt16 nBoxResult = xQueryBox->run();
1466
1467 return (nBoxResult == RET_YES);
1468}
1469
1471{
1474 {
1476 mpParaObj = pText ? pText->GetOutlinerParaObject() : nullptr;
1477
1478 if (mpParaObj != nullptr)
1479 {
1481
1482 ClearModifyFlag();
1483 }
1484 }
1485 else
1486 {
1487 mpSearchSpellTextObj = nullptr;
1488 }
1489}
1490
1492{
1493 EESpellState eState = HasSpellErrors();
1494 DBG_ASSERT(eState != EESpellState::NoSpeller, "No SpellChecker");
1495
1496 if (eState == EESpellState::Ok)
1497 return;
1498
1499 // When spell checking we have to test whether we have processed the
1500 // whole document and have reached the start page again.
1501 if (meMode == SPELL)
1502 {
1504 // Remember the position of the first text object so that we
1505 // know when we have processed the whole document.
1508 {
1509 mbEndOfSearch = true;
1510 }
1511 }
1512
1513 EnterEditMode( false );
1514}
1515
1517{
1518 if (!HasText( *mpSearchItem ))
1519 return;
1520
1521 // Set the object now that we know it matches.
1523
1524 mbStringFound = true;
1525 mbMatchMayExist = true;
1526
1527 EnterEditMode(false);
1528
1529 mpDrawDocument->GetDocSh()->SetWaitCursor( false );
1530 // Start search at the right end of the current object's text
1531 // depending on the search direction.
1532 OutlinerView* pOutlinerView = getOutlinerView();
1533 if (pOutlinerView != nullptr)
1534 pOutlinerView->SetSelection (GetSearchStartPosition ());
1535}
1536
1538{
1539 std::shared_ptr<sd::ViewShell> pViewShell (mpWeakViewShell.lock());
1540 std::shared_ptr<sd::DrawViewShell> pDrawViewShell(
1541 std::dynamic_pointer_cast<sd::DrawViewShell>(pViewShell));
1542 if (pDrawViewShell == nullptr || ePageKind == pDrawViewShell->GetPageKind())
1543 return;
1544
1545 // Restore old edit mode.
1546 pDrawViewShell->ChangeEditMode(mpImpl->meOriginalEditMode, false);
1547
1548 SetStatusEventHdl(Link<EditStatus&,void>());
1549 OUString sViewURL;
1550 switch (ePageKind)
1551 {
1552 case PageKind::Standard:
1553 default:
1555 break;
1556 case PageKind::Notes:
1558 break;
1559 case PageKind::Handout:
1561 break;
1562 }
1563 // The text object iterator is destroyed when the shells are
1564 // switched but we need it so save it and restore it afterwards.
1566 bool bMatchMayExist = mbMatchMayExist;
1567
1568 sd::ViewShellBase& rBase = pViewShell->GetViewShellBase();
1569
1571 if (pViewShell->GetView())
1572 xFuSearch = pViewShell->GetView()->getSearchContext().getFunctionSearch();
1573
1574 SetViewShell(std::shared_ptr<sd::ViewShell>());
1575 sd::framework::FrameworkHelper::Instance(rBase)->RequestView(
1576 sViewURL,
1578
1579 // Force (well, request) a synchronous update of the configuration.
1580 // In a better world we would handle the asynchronous view update
1581 // instead. But that would involve major restructuring of the
1582 // Outliner code.
1583 sd::framework::FrameworkHelper::Instance(rBase)->RequestSynchronousUpdate();
1584
1585 auto pNewViewShell = rBase.GetMainViewShell();
1586 SetViewShell(pNewViewShell);
1587 if (xFuSearch.is() && pNewViewShell->GetView())
1588 pNewViewShell->GetView()->getSearchContext().setSearchFunction(xFuSearch);
1589
1590 // Switching to another view shell has intermediatly called
1591 // EndSpelling(). A PrepareSpelling() is pending, so call that now.
1593
1594 // Update the number of pages so that
1595 // <member>DetectChange()</member> has the correct value to compare
1596 // to.
1598
1599 maObjectIterator = aIterator;
1600 mbMatchMayExist = bMatchMayExist;
1601
1602 // Save edit mode so that it can be restored when switching the view
1603 // shell again.
1604 pDrawViewShell = std::dynamic_pointer_cast<sd::DrawViewShell>(pViewShell);
1605 OSL_ASSERT(pDrawViewShell != nullptr);
1606 if (pDrawViewShell != nullptr)
1607 mpImpl->meOriginalEditMode = pDrawViewShell->GetEditMode();
1608}
1609
1610void SdOutliner::SetPage (EditMode eEditMode, sal_uInt16 nPageIndex)
1611{
1613 {
1614 std::shared_ptr<sd::ViewShell> pViewShell (mpWeakViewShell.lock());
1615 std::shared_ptr<sd::DrawViewShell> pDrawViewShell(
1616 std::dynamic_pointer_cast<sd::DrawViewShell>(pViewShell));
1617 OSL_ASSERT(pDrawViewShell != nullptr);
1618 if (pDrawViewShell != nullptr)
1619 {
1620 pDrawViewShell->ChangeEditMode(eEditMode, false);
1621 pDrawViewShell->SwitchPage(nPageIndex);
1622 }
1623 }
1624}
1625
1626void SdOutliner::EnterEditMode (bool bGrabFocus)
1627{
1628 OutlinerView* pOutlinerView = getOutlinerView();
1629 if (!(pOutlinerView && mpSearchSpellTextObj))
1630 return;
1631
1632 pOutlinerView->SetOutputArea( ::tools::Rectangle( Point(), Size(1, 1)));
1635
1636 // Make FuText the current function.
1637 SfxUInt16Item aItem (SID_TEXTEDIT, 1);
1638 std::shared_ptr<sd::ViewShell> pViewShell (mpWeakViewShell.lock());
1639 if (!(pViewShell && pViewShell->GetDispatcher()))
1640 return;
1641
1642 pViewShell->GetDispatcher()->ExecuteList(
1643 SID_TEXTEDIT, SfxCallMode::SYNCHRON | SfxCallMode::RECORD, {&aItem});
1644
1645 if (mpView->IsTextEdit())
1646 {
1647 // end text edition before starting it again
1649 }
1650
1651 // To be consistent with the usual behaviour in the Office the text
1652 // object that is put into edit mode would have also to be selected.
1653 // Starting the text edit mode is not enough so we do it here by
1654 // hand.
1655 mpView->UnmarkAllObj(pPV);
1657
1659
1660 // Turn on the edit mode for the text object.
1661 SetUpdateLayout(true);
1663 pOutlinerView, true, true, bGrabFocus);
1664
1665 mbFoundObject = true;
1666}
1667
1669{
1670 ESelection aPosition;
1672 {
1673 // The default constructor uses the beginning of the text as default.
1674 aPosition = ESelection ();
1675 }
1676 else
1677 {
1678 // Retrieve the position after the last character in the last
1679 // paragraph.
1680 sal_Int32 nParagraphCount = GetParagraphCount();
1681 if (nParagraphCount == 0)
1682 aPosition = ESelection();
1683 else
1684 {
1685 sal_Int32 nLastParagraphLength = GetEditEngine().GetTextLen (
1686 nParagraphCount-1);
1687 aPosition = ESelection (nParagraphCount-1, nLastParagraphLength);
1688 }
1689 }
1690
1691 return aPosition;
1692}
1693
1695{
1696 OutlinerView* pOutlinerView = getOutlinerView();
1697
1698 DBG_ASSERT (pOutlinerView!=nullptr, "outline view in SdOutliner::HasNoPreviousMatch is NULL");
1699
1700 // Detect whether the cursor stands at the beginning
1701 // resp. at the end of the text.
1702 return pOutlinerView->GetSelection() == GetSearchStartPosition();
1703}
1704
1706{
1707 bool bContinueSearch = false;
1708
1709 OutlinerView* pOutlinerView = getOutlinerView();
1710 if (pOutlinerView && mpSearchItem)
1711 {
1712 // Detect whether there is/may be a prior match. If there is then
1713 // ask the user whether to wrap around. Otherwise tell the user
1714 // that there is no match.
1715 if (HasNoPreviousMatch ())
1716 {
1717 // No match found in the whole presentation.
1718 SvxSearchDialogWrapper::SetSearchLabel(SearchLabel::NotFound);
1719 }
1720
1721 else
1722 {
1723 // No further matches found. Ask the user whether to wrap
1724 // around and start again.
1725 bContinueSearch = ShowWrapAroundDialog();
1726 }
1727 }
1728
1729 return bContinueSearch;
1730}
1731
1733 const sd::outliner::IteratorPosition& rPosition)
1734{
1735 SetViewMode (rPosition.mePageKind);
1736 SetPage (rPosition.meEditMode, static_cast<sal_uInt16>(rPosition.mnPageIndex));
1737 mnText = rPosition.mnText;
1738 return rPosition.mxObject.get().get();
1739}
1740
1741void SdOutliner::SetViewShell (const std::shared_ptr<sd::ViewShell>& rpViewShell)
1742{
1743 std::shared_ptr<sd::ViewShell> pViewShell (mpWeakViewShell.lock());
1744 if (pViewShell == rpViewShell)
1745 return;
1746
1747 // Set the new view shell.
1748 mpWeakViewShell = rpViewShell;
1749 // When the outline view is not owned by us then we have to clear
1750 // that pointer so that the current one for the new view shell will
1751 // be used (in ProvideOutlinerView).
1752 if (rpViewShell)
1753 {
1754 mpView = rpViewShell->GetView();
1755
1756 mpWindow = rpViewShell->GetActiveWindow();
1757
1758 mpImpl->ProvideOutlinerView(*this, rpViewShell, mpWindow);
1759 OutlinerView* pOutlinerView = getOutlinerView();
1760 if (pOutlinerView != nullptr)
1761 pOutlinerView->SetWindow(mpWindow);
1762 }
1763 else
1764 {
1765 mpView = nullptr;
1766 mpWindow = nullptr;
1767 }
1768}
1769
1771{
1772 maMarkListCopy.clear();
1775 return;
1776
1777 // Make a copy of the current mark list.
1778 const SdrMarkList& rMarkList = mpView->GetMarkedObjectList();
1779 const size_t nCount = rMarkList.GetMarkCount();
1780 if (nCount > 0)
1781 {
1782 maMarkListCopy.clear();
1783 maMarkListCopy.reserve (nCount);
1784 for (size_t i=0; i<nCount; ++i)
1785 maMarkListCopy.emplace_back(rMarkList.GetMark(i)->GetMarkedSdrObj ());
1786 }
1787 else
1788 // No marked object. Is this case possible?
1790}
1791
1792void SdOutliner::StartConversion( LanguageType nSourceLanguage, LanguageType nTargetLanguage,
1793 const vcl::Font *pTargetFont, sal_Int32 nOptions, bool bIsInteractive )
1794{
1795 std::shared_ptr<sd::ViewShell> pViewShell (mpWeakViewShell.lock());
1796 bool bMultiDoc = nullptr != dynamic_cast< const sd::DrawViewShell *>( pViewShell.get() );
1797
1799 mbDirectionIsForward = true;
1800 mpSearchItem.reset();
1801 mnConversionLanguage = nSourceLanguage;
1802
1804
1805 OutlinerView* pOutlinerView = getOutlinerView();
1806 if (pOutlinerView != nullptr)
1807 {
1808 pOutlinerView->StartTextConversion(
1810 nSourceLanguage,
1811 nTargetLanguage,
1812 pTargetFont,
1813 nOptions,
1814 bIsInteractive,
1815 bMultiDoc);
1816 }
1817
1818 EndConversion();
1819}
1820
1825{
1826 SetUpdateLayout(true);
1827 if( HasConvertibleTextPortion( mnConversionLanguage ) )
1828 {
1829 SetUpdateLayout(false);
1830 mbStringFound = true;
1831 mbMatchMayExist = true;
1832
1833 EnterEditMode(true);
1834
1835 mpDrawDocument->GetDocSh()->SetWaitCursor( false );
1836 // Start search at the right end of the current object's text
1837 // depending on the search direction.
1838 }
1839 else
1840 {
1841 SetUpdateLayout(false);
1842 }
1843}
1844
1846{
1847 SetRefDevice( SD_MOD()->GetVirtualRefDevice() );
1848
1849 sd::ViewShellBase* pBase = getViewShellBase();
1850 if (pBase != nullptr)
1851 SetViewShell (pBase->GetMainViewShell());
1852
1853 std::shared_ptr<sd::ViewShell> pViewShell (mpWeakViewShell.lock());
1854 if (pViewShell)
1855 {
1856 mbStringFound = false;
1857
1858 // Supposed that we are not located at the very beginning/end of the
1859 // document then there may be a match in the document prior/after
1860 // the current position.
1861 mbMatchMayExist = true;
1862
1866
1867 mpImpl->ProvideOutlinerView(*this, pViewShell, mpWindow);
1868
1870 }
1871 ClearModifyFlag();
1872}
1873
1875{
1876 EndSpelling();
1877}
1878
1880{
1881 std::shared_ptr<sd::ViewShell> pViewShell (mpWeakViewShell.lock());
1882 if (dynamic_cast< const sd::OutlineViewShell *>( pViewShell.get() ) )
1883 return false;
1884
1885 mpDrawDocument->GetDocSh()->SetWaitCursor( true );
1886
1887 Initialize ( true );
1888
1889 OutlinerView* pOutlinerView = getOutlinerView();
1890 if (pOutlinerView != nullptr)
1891 {
1892 mpWindow = pViewShell->GetActiveWindow();
1893 pOutlinerView->SetWindow(mpWindow);
1894 }
1896
1897 mpDrawDocument->GetDocSh()->SetWaitCursor( false );
1898 ClearModifyFlag();
1899
1900 // for text conversion we automatically wrap around one
1901 // time and stop at the start shape
1902 if( mpFirstObj )
1903 {
1904 if( (mnText == 0) && (mpFirstObj == mpObj) )
1905 return false;
1906 }
1907 else
1908 {
1909 mpFirstObj = mpObj;
1910 }
1911
1912 return !mbEndOfSearch;
1913}
1914
1916{
1917 // We assume that the parent of the given message box is NULL, i.e. it is
1918 // modal with respect to the top application window. However, this
1919 // does not affect the search dialog. Therefore we have to lock it here
1920 // while the message box is being shown. We also have to take into
1921 // account that we are called during a spell check and the search dialog
1922 // is not available.
1923 weld::Window* pSearchDialog = nullptr;
1924 SfxChildWindow* pChildWindow = nullptr;
1925 switch (meMode)
1926 {
1927 case SEARCH:
1928 if (SfxViewFrame* pViewFrm = SfxViewFrame::Current())
1929 pChildWindow = pViewFrm->GetChildWindow(
1930 SvxSearchDialogWrapper::GetChildWindowId());
1931 break;
1932
1933 case SPELL:
1934 if (SfxViewFrame* pViewFrm = SfxViewFrame::Current())
1935 pChildWindow = pViewFrm->GetChildWindow(
1936 sd::SpellDialogChildWindow::GetChildWindowId());
1937 break;
1938
1939 case TEXT_CONVERSION:
1940 // There should no messages boxes be displayed while doing the
1941 // hangul hanja conversion.
1942 break;
1943 }
1944
1945 if (pChildWindow != nullptr)
1946 {
1947 auto xController = pChildWindow->GetController();
1948 pSearchDialog = xController ? xController->getDialog() : nullptr;
1949 }
1950
1951 if (pSearchDialog)
1952 return pSearchDialog;
1953
1954 std::shared_ptr<sd::ViewShell> pViewShell (mpWeakViewShell.lock());
1955 auto pWin = pViewShell->GetActiveWindow();
1956 return pWin ? pWin->GetFrameWeld() : nullptr;
1957}
1958
1959//===== SdOutliner::Implementation ==============================================
1960
1962 : meOriginalEditMode(EditMode::Page),
1963 mbOwnOutlineView(false),
1964 mpOutlineView(nullptr)
1965{
1966}
1967
1969{
1970 if (mbOwnOutlineView && mpOutlineView!=nullptr)
1971 {
1972 mpOutlineView->SetWindow(nullptr);
1973 delete mpOutlineView;
1974 mpOutlineView = nullptr;
1975 }
1976}
1977
1984 Outliner& rOutliner,
1985 const std::shared_ptr<sd::ViewShell>& rpViewShell,
1986 vcl::Window* pWindow)
1987{
1988 if (rpViewShell == nullptr)
1989 return;
1990
1991 switch (rpViewShell->GetShellType())
1992 {
1997 {
1998 // Create a new outline view to do the search on.
1999 bool bInsert = false;
2000 if (mpOutlineView != nullptr && !mbOwnOutlineView)
2001 mpOutlineView = nullptr;
2002
2003 if (mpOutlineView == nullptr || !rOutliner.GetEditEngine().HasView(&mpOutlineView->GetEditView()))
2004 {
2005 delete mpOutlineView;
2006 mpOutlineView = new OutlinerView(&rOutliner, pWindow);
2007 mbOwnOutlineView = true;
2008 bInsert = true;
2009 }
2010 else
2011 mpOutlineView->SetWindow(pWindow);
2012
2013 EVControlBits nStat = mpOutlineView->GetControlWord();
2014 nStat &= ~EVControlBits::AUTOSCROLL;
2015 mpOutlineView->SetControlWord(nStat);
2016
2017 if (bInsert)
2018 rOutliner.InsertView( mpOutlineView );
2019
2020 rOutliner.SetUpdateLayout(false);
2021 mpOutlineView->SetOutputArea (::tools::Rectangle (Point(), Size(1, 1)));
2022 rOutliner.SetPaperSize( Size(1, 1) );
2023 rOutliner.SetText(OUString(), rOutliner.GetParagraph(0));
2024
2025 meOriginalEditMode =
2026 std::static_pointer_cast<sd::DrawViewShell>(rpViewShell)->GetEditMode();
2027 }
2028 break;
2029
2031 {
2032 if (mpOutlineView!=nullptr && mbOwnOutlineView)
2033 delete mpOutlineView;
2034 mpOutlineView = rOutliner.GetView(0);
2035 mbOwnOutlineView = false;
2036 }
2037 break;
2038
2039 default:
2042 // Ignored
2043 break;
2044 }
2045}
2046
2048{
2049 if (mbOwnOutlineView)
2050 {
2051 OutlinerView* pView = mpOutlineView;
2052 mpOutlineView = nullptr;
2053 mbOwnOutlineView = false;
2054 if (pView != nullptr)
2055 {
2056 pView->SetWindow(nullptr);
2057 delete pView;
2058 }
2059 }
2060 else
2061 {
2062 mpOutlineView = nullptr;
2063 }
2064}
2065
2066/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static const AllSettings & GetSettings()
static weld::MessageDialog * CreateMessageDialog(weld::Widget *pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage, const ILibreOfficeKitNotifier *pNotifier=nullptr)
bool HasView(EditView *pView) const
static css::uno::Reference< css::linguistic2::XSpellChecker1 > GetSpellChecker()
static css::uno::Reference< css::linguistic2::XHyphenator > GetHyphenator()
MapUnit GetMapUnit() const
void SetSelection(const ESelection &)
void StartTextConversion(weld::Widget *pDialogParent, LanguageType nSrcLang, LanguageType nDestLang, const vcl::Font *pDestFont, sal_Int32 nOptions, bool bIsInteractive, bool bMultipleDoc)
void GetSelectionRectangles(std::vector< tools::Rectangle > &rLogicRects) const
sal_Int32 StartSearchAndReplace(const SvxSearchItem &rSearchItem)
void SetOutputArea(const tools::Rectangle &rRect)
vcl::Window * GetWindow() const
ESelection GetSelection() const
void SetWindow(vcl::Window *pWindow)
EditView & GetEditView() const
void SetText(const OutlinerParaObject &)
const EditEngine & GetEditEngine() const
Paragraph * GetParagraph(sal_Int32 nAbsPos) const
void SetPaperSize(const Size &rSize)
bool SetUpdateLayout(bool bUpdate)
OutlinerView * GetView(size_t nIndex) const
size_t InsertView(OutlinerView *pView, size_t nIndex=size_t(-1))
size_t GetViewCount() const
SAL_DLLPRIVATE bool GetOnlineSpell() const
Definition: drawdoc.hxx:431
virtual SAL_DLLPRIVATE void SetChanged(bool bFlag=true) override
Definition: drawdoc.cxx:658
SAL_DLLPRIVATE::sd::DrawDocShell * GetDocSh() const
Definition: drawdoc.hxx:242
SAL_DLLPRIVATE DocumentType GetDocumentType() const
Definition: drawdoc.hxx:251
sal_uInt16 GetSdPageCount(PageKind ePgKind) const
Definition: drawdoc2.cxx:212
void ReleaseOutlinerView()
This method is called when the OutlinerView is no longer used.
Definition: Outliner.cxx:2047
sd::VectorGraphicSearchContext & getVectorGraphicSearchContext()
Definition: Outliner.cxx:103
EditMode meOriginalEditMode
The original edit mode directly after switching to a different view mode.
Definition: Outliner.cxx:80
sd::VectorGraphicSearchContext maVectorGraphicSearchContext
Definition: Outliner.cxx:119
bool mbOwnOutlineView
Flag that specifies whether we own the outline view pointed to by <member>mpOutlineView</member> and ...
Definition: Outliner.cxx:110
OutlinerView * mpOutlineView
The outline view used for searching and spelling.
Definition: Outliner.cxx:117
void ProvideOutlinerView(Outliner &rOutliner, const std::shared_ptr< sd::ViewShell > &rpViewShell, vcl::Window *pWindow)
Provide in the member mpOutlineView an instance of OutlinerView that is either taken from the ViewShe...
Definition: Outliner.cxx:1983
OutlinerView * GetOutlinerView()
Return the OutlinerView that was provided by the last call to ProvideOutlinerView() (or NULL when the...
Definition: Outliner.cxx:88
SdOutliner(SdDrawDocument *pDoc, OutlinerMode nMode)
Create a new sd outliner object.
Definition: Outliner.cxx:132
bool HasNoPreviousMatch()
Detect whether there exists a previous match.
Definition: Outliner.cxx:1694
bool HandleFailedSearch()
Handle a failed search (with or without replace) for the outline mode.
Definition: Outliner.cxx:1705
void RememberStartPosition()
Remember the current edited object/caret position/page/view mode when starting to search/spell check ...
Definition: Outliner.cxx:1063
void PrepareSearchAndReplace()
Prepare to search and replace on the current text object.
Definition: Outliner.cxx:1516
void PrepareConversion()
Prepare to do a text conversion on the current text object.
Definition: Outliner.cxx:1824
void StartSpelling()
Initialize a spell check but do not start it yet.
Definition: Outliner.cxx:271
std::unique_ptr< const SvxSearchItem > mpSearchItem
The search item contains various attributes that define the type of search.
Definition: Outliner.hxx:320
SdrObject * mpObj
Current object that may be a text object.
Definition: Outliner.hxx:283
sal_uInt16 mnStartPageIndex
The current page index on starting to search/spell check.
Definition: Outliner.hxx:307
::std::vector< unotools::WeakReference< SdrObject > > maMarkListCopy
When the search is restricted to the current selection then this list contains pointers to all the ob...
Definition: Outliner.hxx:275
void ProvideNextTextObject()
Provide next object to search or spell check as text object in edit mode on the current page.
Definition: Outliner.cxx:1191
void sendLOKSearchResultCallback(const std::shared_ptr< sd::ViewShell > &pViewShell, const OutlinerView *pOutlinerView, std::vector< sd::SearchSelection > *pSelections)
Definition: Outliner.cxx:738
::sd::outliner::Iterator maObjectIterator
The actual object iterator.
Definition: Outliner.hxx:323
sal_uInt16 mnPageCount
The number of pages in the current view.
Definition: Outliner.hxx:248
bool mbStringFound
Specifies whether the search string has been found so far.
Definition: Outliner.hxx:237
virtual bool SpellNextDocument() override
Initiate the spell check of the next relevant text object.
Definition: Outliner.cxx:344
bool mbFoundObject
Set to <TRUE> when an object has been prepared successfully for searching/spell checking.
Definition: Outliner.hxx:259
void DetectChange()
Detect changes of the document or view and react accordingly.
Definition: Outliner.cxx:967
void ShowEndOfSearchDialog()
Show a dialog that tells the user that the search has ended either because there are no more matches ...
Definition: Outliner.cxx:1395
virtual ~SdOutliner() override
Nothing spectacular in the destructor.
Definition: Outliner.cxx:212
EditMode meStartEditMode
The master page mode that was active when starting to search/spell check.
Definition: Outliner.hxx:304
SdrObject * SetObject(const ::sd::outliner::IteratorPosition &rPosition)
Take a position as returned by an object iterator and switch to the view and page on which the object...
Definition: Outliner.cxx:1732
void PutTextIntoOutliner()
Put text of current text object into outliner so that the text can be searched/spell checked.
Definition: Outliner.cxx:1470
OutlinerParaObject * mpParaObj
Paragraph object of <member>mpTextObj</member>.
Definition: Outliner.hxx:298
void HandleChangedSelection()
Activate or deactivate the search in the current selection.
Definition: Outliner.cxx:1770
bool mbRestrictSearchToSelection
This flag indicates that only the selected objects are to be searched.
Definition: Outliner.hxx:268
bool SearchAndReplaceAll()
Do search and replace for whole document.
Definition: Outliner.cxx:580
std::weak_ptr<::sd::ViewShell > mpWeakViewShell
The view shell containing the view.
Definition: Outliner.hxx:220
VclPtr<::sd::Window > mpWindow
This window contains the view.
Definition: Outliner.hxx:222
bool mbEndOfSearch
A <TRUE> value indicates that the end of the find&replace or spell check has been reached.
Definition: Outliner.hxx:253
void SetViewShell(const std::shared_ptr<::sd::ViewShell > &rpViewShell)
Use this method when the view shell in which to search has changed.
Definition: Outliner.cxx:1741
void Initialize(bool bDirectionIsForward)
Initialize the object iterator.
Definition: Outliner.cxx:510
bool mbDirectionIsForward
This flag indicates whether to search forward or backwards.
Definition: Outliner.hxx:263
void SetPage(EditMode eEditMode, sal_uInt16 nPageIndex)
Switch to the page or master page specified by the <member>mnPage</member> index.
Definition: Outliner.cxx:1610
bool StartSearchAndReplace(const SvxSearchItem *pSearchItem)
Initiate a find and/or replace on the next relevant text object.
Definition: Outliner.cxx:420
void PrepareSpelling()
Despite the name this method is called prior to spell checking and searching and replacing.
Definition: Outliner.cxx:241
weld::Window * GetMessageBoxParent()
Find the right parent to use for a message.
Definition: Outliner.cxx:1915
void BeginConversion()
This is called internally when text conversion is started.
Definition: Outliner.cxx:1845
void StartConversion(LanguageType nSourceLanguage, LanguageType nTargetLanguage, const vcl::Font *pTargetFont, sal_Int32 nOptions, bool bIsInteractive)
Starts the text conversion (hangul/hanja or Chinese simplified/traditional) for the current viewshell...
Definition: Outliner.cxx:1792
void EndOfSearch()
Handle the situation that the iterator has reached the last object.
Definition: Outliner.cxx:1345
::sd::View * mpView
The view which displays the searched objects.
Definition: Outliner.hxx:215
PageKind meStartViewMode
The view mode that was active when starting to search/spell check.
Definition: Outliner.hxx:301
bool SearchAndReplaceOnce(std::vector<::sd::SearchSelection > *pSelections=nullptr)
Do search and replace for next match.
Definition: Outliner.cxx:816
ESelection maStartSelection
The position of the caret when searching /spell checking was started.
Definition: Outliner.hxx:314
void EndConversion()
Release all resources that have been created during the conversion.
Definition: Outliner.cxx:1874
::sd::outliner::IteratorPosition maCurrentPosition
The current position of the object iterator.
Definition: Outliner.hxx:325
void PrepareSpellCheck()
Prepare to do spell checking on the current text object.
Definition: Outliner.cxx:1491
enum SdOutliner::mode meMode
::sd::outliner::IteratorPosition maLastValidPosition
The last valid position describes where the last text object has been found.
Definition: Outliner.hxx:333
void SetViewMode(PageKind ePageKind)
Switch to a new view mode.
Definition: Outliner.cxx:1537
bool ShowWrapAroundDialog()
Show a dialog that asks the user whether to wrap around to the beginning/end of the document and cont...
Definition: Outliner.cxx:1427
LanguageType mnConversionLanguage
this is the language that is used for current text conversion.
Definition: Outliner.hxx:229
SdDrawDocument * mpDrawDocument
The document on whose objects and pages this class operates.
Definition: Outliner.hxx:224
::sd::outliner::Iterator maSearchStartPosition
The position when the search started.
Definition: Outliner.hxx:328
ESelection GetSearchStartPosition() const
Return the position at which a new search is started with respect to the search direction as specifie...
Definition: Outliner.cxx:1668
@ TEXT_CONVERSION
Definition: Outliner.hxx:211
SdrObject * mpStartEditedObject
The object in edit mode when searching /spell checking was started (if any).
Definition: Outliner.hxx:311
sal_Int32 mnText
Current text to be searched/spelled inside the current text object.
Definition: Outliner.hxx:295
bool ConvertNextDocument() override
callback for textconversion
Definition: Outliner.cxx:1879
::std::unique_ptr< Implementation > mpImpl
Definition: Outliner.hxx:199
SdrTextObj * mpSearchSpellTextObj
Candidate for being searched/spell checked.
Definition: Outliner.hxx:292
void EndSpelling()
Release all resources that have been created during the find&replace or spell check.
Definition: Outliner.cxx:281
void EnterEditMode(bool bGrabFocus)
Switch on edit mode for the currently selected text object.
Definition: Outliner.cxx:1626
svx::SpellPortions GetNextSpellSentence()
Iterate over the sentences in all text shapes and stop at the next sentence with spelling errors.
Definition: Outliner.cxx:378
SdrObject * mpFirstObj
this stores the first object that is used for text conversion.
Definition: Outliner.hxx:289
OutlinerView * getOutlinerView()
Returns the current outline view.
Definition: Outliner.cxx:216
bool DetectSelectionChange()
Detect whether the selection has changed.
Definition: Outliner.cxx:1027
bool mbPrepareSpellingPending
When this flag is true then a PrepareSpelling() is executed when StartSearchAndReplace() is called th...
Definition: Outliner.hxx:338
bool mbMatchMayExist
This flag indicates whether there may exist a match of the search string before/after the current pos...
Definition: Outliner.hxx:245
void RestoreStartPosition()
Restore the position stored in the last call of <member>RememberStartPositiony</member>.
Definition: Outliner.cxx:1116
size_t GetMarkCount() const
SdrMark * GetMark(size_t nNum) const
const SdrMarkList & GetMarkedObjectList() const
bool AreObjectsMarked() const
void UnmarkAllObj(SdrPageView const *pPV=nullptr)
bool MarkObj(const Point &rPnt, short nTol=-2, bool bToggle=false, bool bDeep=false)
SdrObject * GetMarkedSdrObj() const
bool IsChanged() const
const SfxItemPool & GetItemPool() const
SfxStyleSheetBasePool * GetStyleSheetPool() const
const std::shared_ptr< SvxForbiddenCharactersTable > & GetForbiddenCharsTable() const
SdrTextObj * GetTextEditObject() const
virtual bool IsTextEdit() const final override
bool IsEmptyPresObj() const
SdrPageView * GetSdrPageView() const
virtual const tools::Rectangle & GetLogicRect() const override
virtual bool HasText() const override
virtual void setActiveText(sal_Int32 nIndex)
virtual SdrText * getText(sal_Int32 nIndex) const override
OutlinerParaObject * GetOutlinerParaObject()
std::shared_ptr< SfxDialogController > & GetController()
static SAL_WARN_UNUSED_RESULT SfxViewFrame * Current()
virtual void libreOfficeKitViewCallback(int nType, const OString &pPayload) const override
void setTiledSearching(bool bTiledSearching)
static SAL_WARN_UNUSED_RESULT SfxViewShell * Current()
css::uno::Any GetProperty(std::u16string_view rPropertyName) const
static void SetSearchLabel(const SearchLabel &rSL)
SvxSearchCmd GetCommand() const
virtual SvxSearchItem * Clone(SfxItemPool *pPool=nullptr) const override
void translate(double fX, double fY)
void scale(double fX, double fY)
TYPE getWidth() const
TYPE getMinX() const
TYPE getMinY() const
void expand(const Tuple2D< TYPE > &rTuple)
bool isEmpty() const
TYPE getHeight() const
TYPE getWidth() const
TYPE getHeight() const
Base class of the stacked shells that provide graphical views to Draw and Impress documents and editi...
Derivative of sd::View; contains also a pointer to the document.
Definition: drawview.hxx:35
Show a textual overview of the text contents of all slides.
Derivative of sd::View for the outline mode |* .
Definition: OutlineView.hxx:55
SfxViewShell descendant that the stacked Draw/Impress shells are based on.
static ViewShellBase * GetViewShellBase(SfxViewFrame const *pFrame)
When given a view frame this static method returns the corresponding sd::ViewShellBase object.
std::shared_ptr< ViewShell > GetMainViewShell() const
Return the main view shell stacked on the called ViewShellBase object.
virtual bool SdrBeginTextEdit(SdrObject *pObj, SdrPageView *pPV=nullptr, vcl::Window *pWin=nullptr, bool bIsNewObj=false, SdrOutliner *pGivenOutliner=nullptr, OutlinerView *pGivenOutlinerView=nullptr, bool bDontDeleteOutliner=false, bool bOnlyOneView=false, bool bGrabFocus=true) override
Definition: sdview.cxx:657
virtual SdrEndTextEditKind SdrEndTextEdit(bool bDontDeleteReally=false) override
ends current text editing
Definition: sdview.cxx:772
static const OUString msHandoutViewURL
static const OUString msCenterPaneURL
static const OUString msNotesViewURL
static ::std::shared_ptr< FrameworkHelper > Instance(ViewShellBase &rBase)
Return the FrameworkHelper object that is associated with the given ViewShellBase.
static const OUString msImpressViewURL
Data collection specifying a <type>SdrObject</type> and its position in a document and view.
PageKind mePageKind
Page kind of the view.
EditMode meEditMode
Edit mode of the view.
sal_Int32 mnPageIndex
The index of a page where the object is located on.
sal_Int32 mnText
Number of the actual SdrText from the current <type>SdrObject</type>
::unotools::WeakReference< SdrObject > mxObject
Pointer to the actual <type>SdrObject</type> object.
This iterator can be used to iterate over all <type>SdrObject</type> objects of one of three set deno...
void Reverse()
Reverse the direction of iteration.
This class wraps the <type>SdOutliner</type> class and represents it as a container of <type>SdrObjec...
Iterator current()
Return an iterator that points to the current object of one of the sets described above.
Iterator begin()
Return an iterator that points to the first object of one of the sets described above.
constexpr Size GetSize() const
rtl::Reference< interface_type > SAL_CALL get() const
const MapMode & GetMapMode() const
ColorMode meMode
int nCount
#define DBG_ASSERT(sCon, aError)
#define DBG_UNHANDLED_EXCEPTION(...)
virtual void SetText(const OUString &rStr) override
EESpellState
EEControlBits
EVControlBits
EmbeddedObjectRef * pObject
#define LANGUAGE_NONE
constexpr OUStringLiteral UPN_IS_SPELL_AUTO
OString join(std::string_view rSeparator, const std::vector< OString > &rSequence)
int i
constexpr Point convert(const Point &rPoint, o3tl::Length eFrom, o3tl::Length eTo)
end
std::vector< SpellPortion > SpellPortions
basegfx::B2DRange b2DRectangleFromRectangle(const ::tools::Rectangle &rRect)
OutlinerMode
EditMode
Definition: pres.hxx:53
PageKind
Definition: pres.hxx:45
OUString SdResId(TranslateId aId)
Definition: sdmod.cxx:83
#define SD_MOD()
Definition: sdmod.hxx:184
UnoViewSharedPtr mpView
sal_uIntPtr sal_uLong
SvxSearchCmd
sal_Int32 nStartPara
sal_Int32 nEndPos
sal_Int32 nStartPos
sal_Int32 nEndPara
SearchStartPosition meStartPosition
Describes a single search hit: a set of rectangles on a given page.
Definition: Outliner.hxx:46
Reference< XController > xController
SVXCORE_DLLPUBLIC SdrTextObj * DynCastSdrTextObj(SdrObject *)
@ Page
Definition: unomodel.hxx:385
void GetSelection(struct ESelection &rSel, SvxTextForwarder const *pForwarder) noexcept
RET_YES
VclPtr< vcl::Window > mpWindow