7b5aa07047
Change-Id: Ic1e641b1a9373e3ae8da09436b0e8e7b852bede7 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/138082 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
535 lines
20 KiB
C++
535 lines
20 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*
|
|
* This file is part of the LibreOffice project.
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*
|
|
* This file incorporates work covered by the following license notice:
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed
|
|
* with this work for additional information regarding copyright
|
|
* ownership. The ASF licenses this file to you under the Apache
|
|
* License, Version 2.0 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <svx/svdoutl.hxx>
|
|
#include "pres.hxx"
|
|
#include "OutlinerIterator.hxx"
|
|
#include <editeng/SpellPortions.hxx>
|
|
#include <memory>
|
|
#include <utility>
|
|
|
|
class SdrObject;
|
|
class SdrTextObj;
|
|
class SdDrawDocument;
|
|
|
|
namespace weld
|
|
{
|
|
class Window;
|
|
}
|
|
|
|
namespace sd
|
|
{
|
|
class View;
|
|
class ViewShell;
|
|
class Window;
|
|
|
|
/// Describes a single search hit: a set of rectangles on a given page.
|
|
struct SearchSelection
|
|
{
|
|
/// 0-based index of the page that has the selection.
|
|
int m_nPage;
|
|
|
|
/**
|
|
* List of selection rectangles in twips -- multiple rectangles only in
|
|
* case the selection spans over more layout lines.
|
|
*/
|
|
OString m_aRectangles;
|
|
|
|
SearchSelection(int nPage, OString aRectangles)
|
|
: m_nPage(nPage)
|
|
, m_aRectangles(std::move(aRectangles))
|
|
{
|
|
}
|
|
|
|
bool operator==(const SearchSelection& rOther) const
|
|
{
|
|
return m_nPage == rOther.m_nPage && m_aRectangles == rOther.m_aRectangles;
|
|
}
|
|
};
|
|
|
|
} // end of namespace sd
|
|
|
|
/** The main purpose of this class is searching and replacing as well as
|
|
spelling of impress documents. The main part of both tasks lies in
|
|
iterating over the pages and view modes of a document and apply the
|
|
respective function to all objects containing text on those pages.
|
|
|
|
<p>Relevant objects: There are two sets of objects to search/spell
|
|
check. One is the set of all selected objects. The other consists of
|
|
all objects on all pages in draw-, notes-, and handout view as well as
|
|
slide- and background view (draw pages and master pages).</p>
|
|
|
|
<p>Iteration: Search/replace and spelling functions operate on shapes
|
|
containing text. To cover all relevant objects an order has to be
|
|
defined on the objects. For the set of all selected objects this order
|
|
is simply the order in which they can be retrieved from the selection
|
|
object.<br>
|
|
When there is no selection the order is nested. The three modes of the
|
|
draw view are on the outer level: draw mode, notes mode, handout mode.
|
|
The inner level switches between draw pages and master pages. This
|
|
leads to the following order:
|
|
<ol>
|
|
<li>draw pages of draw mode</li>
|
|
<li>master pages of draw mode</li>
|
|
<li>draw pages of notes mode</li>
|
|
<li>master pages of notes mode</li>
|
|
<li>draw pages of handout mode</li>
|
|
<li>master pages of handout mode</li>
|
|
</ol>
|
|
Iteration starts at the top of the current page. When reaching the end
|
|
of the document, i.e. the last master page of the handout mode, it jumps
|
|
to the first draw page of draw mode. In backward searches this order is
|
|
reversed. When doing a <em>replace all</em> then the whole document is
|
|
searched for matches starting at the first page of the draw/slide view
|
|
(or last page of handout/background view even though search
|
|
direction).</p>
|
|
|
|
<p>The start position is restored after finishing spell checking or
|
|
replacing all matches in a document.</p>
|
|
|
|
<p>Some related pieces of information:
|
|
The search dialog (<type>SvxSearchDialog</type>) can be controlled in
|
|
more than one way:
|
|
<ul><li>A set of option flags returned by the slot call
|
|
SID_SEARCH_OPTIONS handled by the
|
|
<member>SdDrawDocument::GetState()</member> method.</li>
|
|
<li>The contents of the search item of type
|
|
<type>SvxSearchItem</type>.</li>
|
|
<li>The <member>HasSelection()</member> view shell method that returns
|
|
whether or not a selection exists. However, it is called from the
|
|
search dialog with an argument so that only text selections are
|
|
queried. This is only sufficient for searching the outline view.
|
|
</p>
|
|
*/
|
|
class SdOutliner final : public SdrOutliner
|
|
{
|
|
public:
|
|
friend class ::sd::outliner::OutlinerContainer;
|
|
|
|
/** Create a new sd outliner object.
|
|
@param pDoc
|
|
The draw document from which to take the content.
|
|
@param nMode
|
|
The valid values <const>OutlinerMode::DontKnow</const>,
|
|
<const>OutlinerMode::TextObject</const>,
|
|
<const>OutlinerMode::TitleObject</const>,
|
|
<const>OutlinerMode::OutlineObject</const>, and
|
|
<const>OutlinerMode::OutlineView</const> are defined in
|
|
editeng/outliner.hxx.
|
|
*/
|
|
SdOutliner(SdDrawDocument* pDoc, OutlinerMode nMode);
|
|
virtual ~SdOutliner() override;
|
|
/// Forbid copy construction and copy assignment
|
|
SdOutliner(const Outliner&) = delete;
|
|
SdOutliner& operator=(const Outliner&) = delete;
|
|
|
|
/** Despite the name this method is called prior to spell checking *and*
|
|
searching and replacing. The position of current view
|
|
mode/page/object/caret position is remembered and, depending on the
|
|
search mode, may be restored after finishing searching/spell
|
|
checking.
|
|
*/
|
|
void PrepareSpelling();
|
|
|
|
/** Initialize a spell check but do not start it yet. This method
|
|
is a better candidate for the name PrepareSpelling.
|
|
*/
|
|
void StartSpelling();
|
|
|
|
/** Initiate a find and/or replace on the next relevant text object.
|
|
@return
|
|
Returns </sal_True> when the search/replace is finished (as
|
|
indicated by user input to the search dialog). A </sal_False> value
|
|
indicates that another call to this method is required.
|
|
*/
|
|
bool StartSearchAndReplace(const SvxSearchItem* pSearchItem);
|
|
|
|
/** Iterate over the sentences in all text shapes and stop at the
|
|
next sentence with spelling errors. While doing so the view
|
|
mode may be changed and text shapes are set into edit mode.
|
|
*/
|
|
svx::SpellPortions GetNextSpellSentence();
|
|
|
|
/** Release all resources that have been created during the find&replace
|
|
or spell check.
|
|
*/
|
|
void EndSpelling();
|
|
|
|
/** callback for textconversion */
|
|
bool ConvertNextDocument() override;
|
|
|
|
/** Starts the text conversion (hangul/hanja or Chinese simplified/traditional)
|
|
for the current viewshell */
|
|
void StartConversion(LanguageType nSourceLanguage, LanguageType nTargetLanguage,
|
|
const vcl::Font* pTargetFont, sal_Int32 nOptions, bool bIsInteractive);
|
|
|
|
/** This is called internally when text conversion is started.
|
|
The position of current view mode/page/object/caret position
|
|
is remembered and will be restored after conversion.
|
|
*/
|
|
void BeginConversion();
|
|
|
|
/** Release all resources that have been created during the conversion */
|
|
void EndConversion();
|
|
|
|
int GetIgnoreCurrentPageChangesLevel() const { return mnIgnoreCurrentPageChangesLevel; };
|
|
void IncreIgnoreCurrentPageChangesLevel() { mnIgnoreCurrentPageChangesLevel++; };
|
|
void DecreIgnoreCurrentPageChangesLevel() { mnIgnoreCurrentPageChangesLevel--; };
|
|
SdDrawDocument* GetDoc() const { return mpDrawDocument; }
|
|
|
|
private:
|
|
class Implementation;
|
|
::std::unique_ptr<Implementation> mpImpl;
|
|
|
|
/// Returns the current outline view
|
|
OutlinerView* getOutlinerView();
|
|
|
|
/// Specifies whether to search and replace, to spell check or to do a
|
|
/// text conversion.
|
|
enum mode
|
|
{
|
|
SEARCH,
|
|
SPELL,
|
|
TEXT_CONVERSION
|
|
} meMode;
|
|
|
|
/// The view which displays the searched objects.
|
|
::sd::View* mpView;
|
|
/** The view shell containing the view. It is held as weak
|
|
pointer to avoid keeping it alive when the view is changed
|
|
during searching.
|
|
*/
|
|
std::weak_ptr<::sd::ViewShell> mpWeakViewShell;
|
|
/// This window contains the view.
|
|
VclPtr<::sd::Window> mpWindow;
|
|
/// The document on whose objects and pages this class operates.
|
|
SdDrawDocument* mpDrawDocument;
|
|
|
|
/** this is the language that is used for current text conversion.
|
|
Only valid if meMode is TEXT_CONVERSION.
|
|
*/
|
|
LanguageType mnConversionLanguage;
|
|
|
|
/** While the value of this flag is greater than 0 changes of the current page
|
|
do not lead to selecting the corresponding text in the outliner.
|
|
*/
|
|
int mnIgnoreCurrentPageChangesLevel;
|
|
|
|
/// Specifies whether the search string has been found so far.
|
|
bool mbStringFound;
|
|
|
|
/** This flag indicates whether there may exist a match of the search
|
|
string before/after the current position in the document. It can be
|
|
set to </sal_False> only when starting from the beginning/end of the
|
|
document. When reaching the end/beginning with it still be set to
|
|
</sal_False> then there exists no match and the search can be terminated.
|
|
*/
|
|
bool mbMatchMayExist;
|
|
|
|
/// The number of pages in the current view.
|
|
sal_uInt16 mnPageCount;
|
|
|
|
/** A <TRUE/> value indicates that the end of the find&replace or spell
|
|
check has been reached.
|
|
*/
|
|
bool mbEndOfSearch;
|
|
|
|
/** Set to <TRUE/> when an object has been prepared successfully for
|
|
searching/spell checking. This flag directs the internal iteration
|
|
which stops when set to </sal_True>.
|
|
*/
|
|
bool mbFoundObject;
|
|
|
|
/** This flag indicates whether to search forward or backwards.
|
|
*/
|
|
bool mbDirectionIsForward;
|
|
|
|
/** This flag indicates that only the selected objects are to be
|
|
searched.
|
|
*/
|
|
bool mbRestrictSearchToSelection;
|
|
|
|
/** When the search is restricted to the current selection then
|
|
this list contains pointers to all the objects of the
|
|
selection. This copy is necessary because during the search
|
|
process the mark list is modified.
|
|
*/
|
|
::std::vector<tools::WeakReference<SdrObject>> maMarkListCopy;
|
|
|
|
/** Current object that may be a text object. The object pointer to
|
|
corresponds to <member>mnObjIndex</member>. While iterating over the
|
|
objects on a page <member>mpObj</member> will point to every object
|
|
while <member>mpTextObj</member> will be set only to valid text
|
|
objects.
|
|
*/
|
|
SdrObject* mpObj;
|
|
|
|
/** this stores the first object that is used for text conversion.
|
|
Conversion automatically wraps around the document and stops when it
|
|
finds this object again.
|
|
*/
|
|
SdrObject* mpFirstObj;
|
|
|
|
/// Candidate for being searched/spell checked.
|
|
SdrTextObj* mpSearchSpellTextObj;
|
|
|
|
/// Current text to be searched/spelled inside the current text object
|
|
sal_Int32 mnText;
|
|
|
|
/// Paragraph object of <member>mpTextObj</member>.
|
|
OutlinerParaObject* mpParaObj;
|
|
|
|
/// The view mode that was active when starting to search/spell check.
|
|
PageKind meStartViewMode;
|
|
|
|
/// The master page mode that was active when starting to search/spell check.
|
|
EditMode meStartEditMode;
|
|
|
|
/// The current page index on starting to search/spell check.
|
|
sal_uInt16 mnStartPageIndex;
|
|
|
|
/// The object in edit mode when searching /spell checking was started
|
|
/// (if any).
|
|
SdrObject* mpStartEditedObject;
|
|
|
|
/// The position of the caret when searching /spell checking was started.
|
|
ESelection maStartSelection;
|
|
|
|
/** The search item contains various attributes that define the type of
|
|
search. It is set every time the
|
|
<member>SearchAndReplaceAll</member> method is called.
|
|
*/
|
|
std::unique_ptr<const SvxSearchItem> mpSearchItem;
|
|
|
|
/// The actual object iterator.
|
|
::sd::outliner::Iterator maObjectIterator;
|
|
/// The current position of the object iterator.
|
|
::sd::outliner::IteratorPosition maCurrentPosition;
|
|
/// The position when the search started. Corresponds largely to the
|
|
/// m?Start* members.
|
|
::sd::outliner::Iterator maSearchStartPosition;
|
|
/** The last valid position describes where the last text object has been
|
|
found. This position is restored when some dialogs are shown. The
|
|
position is initially set to the where the search begins.
|
|
*/
|
|
::sd::outliner::IteratorPosition maLastValidPosition;
|
|
|
|
/** When this flag is true then a PrepareSpelling() is executed when
|
|
StartSearchAndReplace() is called the next time.
|
|
*/
|
|
bool mbPrepareSpellingPending;
|
|
|
|
/** Initialize the object iterator. Call this method after being
|
|
invoked from the search or spellcheck dialog. It creates a new
|
|
iterator pointing at the current object when this has not been done
|
|
before. It reverses the direction of iteration if the given flag
|
|
differs from the current direction.
|
|
@param bDirectionIsForward
|
|
This flag specifies in which direction to iterator over the
|
|
objects. If it differs from the current direction the iterator
|
|
is reversed.
|
|
*/
|
|
void Initialize(bool bDirectionIsForward);
|
|
|
|
/** Do search and replace for whole document.
|
|
*/
|
|
bool SearchAndReplaceAll();
|
|
|
|
/** Do search and replace for next match.
|
|
@param pSelections
|
|
When tiled rendering and not 0, then don't emit LOK events, instead
|
|
assume the caller will do so.
|
|
@return
|
|
The return value specifies whether the search ended (</sal_True>) or
|
|
another call to this method is required (</sal_False>).
|
|
*/
|
|
bool SearchAndReplaceOnce(std::vector<::sd::SearchSelection>* pSelections = nullptr);
|
|
|
|
void sendLOKSearchResultCallback(const std::shared_ptr<sd::ViewShell>& pViewShell,
|
|
const OutlinerView* pOutlinerView,
|
|
std::vector<sd::SearchSelection>* pSelections);
|
|
|
|
/** Detect changes of the document or view and react accordingly. Such
|
|
changes may occur because different calls to
|
|
<member>SearchAndReplace()</member> there usually is user
|
|
interaction. This is at least the press of the search or replace
|
|
button but may include any other action some of which affect the
|
|
search.
|
|
*/
|
|
void DetectChange();
|
|
|
|
/** Detect whether the selection has changed.
|
|
@return
|
|
Return <TRUE/> when the selection has been changed since the
|
|
last call to this method.
|
|
*/
|
|
bool DetectSelectionChange();
|
|
|
|
/** Remember the current edited object/caret position/page/view mode
|
|
when starting to search/spell check so that it can be restored on
|
|
termination.
|
|
*/
|
|
void RememberStartPosition();
|
|
|
|
/** Restore the position stored in the last call of
|
|
<member>RememberStartPositiony</member>.
|
|
*/
|
|
void RestoreStartPosition();
|
|
|
|
/** Provide next object to search or spell check as text object in edit
|
|
mode on the current page. This skips all objects that do not
|
|
match or are no text object.
|
|
*/
|
|
void ProvideNextTextObject();
|
|
|
|
/** Handle the situation that the iterator has reached the last object.
|
|
This may result in setting the <member>mbEndOfSearch</member> flag
|
|
back to </sal_False>. This method may show either the end-of-search
|
|
dialog or the wrap-around dialog.
|
|
*/
|
|
void EndOfSearch();
|
|
|
|
/** Show a dialog that tells the user that the search has ended either
|
|
because there are no more matches after finding at least one or that
|
|
no match has been found at all.
|
|
*/
|
|
void ShowEndOfSearchDialog();
|
|
|
|
/** Show a dialog that asks the user whether to wrap around to the
|
|
beginning/end of the document and continue with the search/spell
|
|
check.
|
|
*/
|
|
bool ShowWrapAroundDialog();
|
|
|
|
/** Put text of current text object into outliner so that the text can
|
|
be searched/spell checked.
|
|
*/
|
|
void PutTextIntoOutliner();
|
|
|
|
/** Prepare to do spell checking on the current text object. This
|
|
includes putting it into edit mode. Under certain conditions this
|
|
method sets <member>mbEndOfSearch</member> to <TRUE/>.
|
|
*/
|
|
void PrepareSpellCheck();
|
|
|
|
/** Prepare to search and replace on the current text object. This
|
|
includes putting it into edit mode.
|
|
*/
|
|
void PrepareSearchAndReplace();
|
|
|
|
/** Prepare to do a text conversion on the current text
|
|
object. This includes putting it into edit mode.
|
|
*/
|
|
void PrepareConversion();
|
|
|
|
/** Switch to a new view mode. Try to restore the original edit mode
|
|
before doing so.
|
|
@param ePageKind
|
|
Specifies the new view mode.
|
|
*/
|
|
void SetViewMode(PageKind ePageKind);
|
|
|
|
/** Switch to the page or master page specified by the
|
|
<member>mnPage</member> index. Master page mode is specified by
|
|
<member>meEditMode</member>.
|
|
@param eEditMode
|
|
The new edit mode.
|
|
@param nPageIndex
|
|
The new page index.
|
|
*/
|
|
void SetPage(EditMode eEditMode, sal_uInt16 nPageIndex);
|
|
|
|
/** Switch on edit mode for the currently selected text object.
|
|
*/
|
|
void EnterEditMode(bool bGrabFocus);
|
|
|
|
/** Return the position at which a new search is started with respect to
|
|
the search direction as specified by the argument.
|
|
@return
|
|
The position mentioned above in form of a selection with start
|
|
equals end.
|
|
*/
|
|
ESelection GetSearchStartPosition() const;
|
|
|
|
/** Detect whether there exists a previous match. Note that only the
|
|
absence of such a match can be detected reliably. An existing match
|
|
is assumed when the search started not at the beginning/end of the
|
|
presentation. This does not have to be true. The user can have set
|
|
the cursor at the middle of the text without a prior search.
|
|
@return
|
|
Returns </True> when there is no previous match and </False>
|
|
when there may be one.
|
|
*/
|
|
bool HasNoPreviousMatch();
|
|
|
|
/** Handle a failed search (with or without replace) for the outline
|
|
mode. Show message boxes when the search failed completely,
|
|
i.e. there is no match in the whole presentation, or when no further
|
|
match exists.
|
|
@return
|
|
The returned value indicates whether another (wrapped around)
|
|
search shall take place. If that is so, then it is the caller's
|
|
responsibility to set the cursor position accordingly.
|
|
*/
|
|
bool HandleFailedSearch();
|
|
|
|
/** Take a position as returned by an object iterator and switch to the
|
|
view and page on which the object specified by this position is
|
|
located.
|
|
@param rPosition
|
|
This position points to a <type>SdrObject</type> object and
|
|
contains the view and page where it is located.
|
|
@return
|
|
Return a pointer to the <type>SdrObject</type>.
|
|
*/
|
|
SdrObject* SetObject(const ::sd::outliner::IteratorPosition& rPosition);
|
|
|
|
/** Use this method when the view shell in which to search has changed.
|
|
It handles i.e. registering at the associated view as selection
|
|
change listener.
|
|
*/
|
|
void SetViewShell(const std::shared_ptr<::sd::ViewShell>& rpViewShell);
|
|
|
|
/** Activate or deactivate the search in the current selection. Call
|
|
this method whenever the selection has changed. This method creates
|
|
a copy of the current selection and reassigns the object iterator to
|
|
the current() iterator.
|
|
*/
|
|
void HandleChangedSelection();
|
|
|
|
/** Initiate the spell check of the next relevant text object.
|
|
When the outline view is active then this method is called
|
|
after a wrap around to continue at the beginning of the document.
|
|
@return
|
|
Returns <TRUE/> to indicate that another call to this method is
|
|
required. When all text objects have been processed then
|
|
<FALSE/> is returned.
|
|
*/
|
|
virtual bool SpellNextDocument() override;
|
|
|
|
/** Find the right parent to use for a message. This function makes sure
|
|
that the otherwise non-modal search or spell dialogs, if visible, are
|
|
locked, too.
|
|
*/
|
|
weld::Window* GetMessageBoxParent();
|
|
};
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|