Bug Summary

File:home/maarten/src/libreoffice/core/sw/inc/ring.hxx
Warning:line 85, column 19
Use of memory after it is freed

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name unotxvw.cxx -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/11.0.0 -isystem /usr/include/libxml2 -D BOOST_ERROR_CODE_HEADER_ONLY -D BOOST_SYSTEM_NO_DEPRECATED -D CPPU_ENV=gcc3 -D LINUX -D OSL_DEBUG_LEVEL=1 -D SAL_LOG_INFO -D SAL_LOG_WARN -D UNIX -D UNX -D X86_64 -D _PTHREADS -D _REENTRANT -D SW_DLLIMPLEMENTATION -D SWUI_DLL_NAME="libswuilo.so" -D SYSTEM_LIBXML -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/i18n -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/common -I /home/maarten/src/libreoffice/core/external/boost/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost -I /home/maarten/src/libreoffice/core/sw/source/core/inc -I /home/maarten/src/libreoffice/core/sw/source/filter/inc -I /home/maarten/src/libreoffice/core/sw/source/uibase/inc -I /home/maarten/src/libreoffice/core/sw/inc -I /home/maarten/src/libreoffice/core/workdir/SdiTarget/sw/sdi -I /home/maarten/src/libreoffice/core/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include/linux -I /home/maarten/src/libreoffice/core/config_host -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/officecfg/registry -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/sw/generated -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/udkapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/offapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/oovbaapi/normal -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/x86_64-redhat-linux -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/11.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wno-missing-braces -std=c++17 -fdeprecated-macro -fdebug-compilation-dir /home/maarten/src/libreoffice/core -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -debug-info-kind=constructor -analyzer-output=html -faddrsig -o /home/maarten/tmp/wis/scan-build-libreoffice/output/report/2020-10-07-141433-9725-1 -x c++ /home/maarten/src/libreoffice/core/sw/source/uibase/uno/unotxvw.cxx

/home/maarten/src/libreoffice/core/sw/source/uibase/uno/unotxvw.cxx

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 <memory>
21#include <viscrs.hxx>
22#include <o3tl/any.hxx>
23#include <sfx2/frame.hxx>
24#include <sfx2/printer.hxx>
25#include <sfx2/viewfrm.hxx>
26#include <cmdid.h>
27#include <docsh.hxx>
28#include <rubylist.hxx>
29#include <doc.hxx>
30#include <IDocumentDeviceAccess.hxx>
31#include <unotxvw.hxx>
32#include <unodispatch.hxx>
33#include <unomap.hxx>
34#include <unoprnms.hxx>
35#include <view.hxx>
36#include <viewopt.hxx>
37#include <unomod.hxx>
38#include <unoframe.hxx>
39#include <unocrsr.hxx>
40#include <wrtsh.hxx>
41#include <unotbl.hxx>
42#include <svx/fmshell.hxx>
43#include <svx/svdview.hxx>
44#include <svx/svdpage.hxx>
45#include <svx/svdouno.hxx>
46#include <editeng/pbinitem.hxx>
47#include <pagedesc.hxx>
48#include <editeng/lrspitem.hxx>
49#include <editeng/ulspitem.hxx>
50#include <sfx2/bindings.hxx>
51#include <sfx2/request.hxx>
52#include <frmatr.hxx>
53#include <IMark.hxx>
54#include <unodraw.hxx>
55#include <svx/svdpagv.hxx>
56#include <ndtxt.hxx>
57#include <SwStyleNameMapper.hxx>
58#include <com/sun/star/beans/PropertyAttribute.hpp>
59#include <com/sun/star/drawing/ShapeCollection.hpp>
60#include <editeng/outliner.hxx>
61#include <editeng/editview.hxx>
62#include <unoparagraph.hxx>
63#include <unocrsrhelper.hxx>
64#include <unotextrange.hxx>
65#include <sfx2/docfile.hxx>
66#include <swdtflvr.hxx>
67#include <vcl/svapp.hxx>
68#include <comphelper/processfactory.hxx>
69#include <comphelper/profilezone.hxx>
70#include <comphelper/servicehelper.hxx>
71#include <cppuhelper/supportsservice.hxx>
72#include <cppuhelper/typeprovider.hxx>
73#include <tools/UnitConversion.hxx>
74
75using namespace ::com::sun::star;
76using namespace ::com::sun::star::uno;
77using namespace ::com::sun::star::lang;
78using namespace ::com::sun::star::beans;
79using namespace ::com::sun::star::text;
80using namespace ::com::sun::star::view;
81using namespace ::com::sun::star::frame;
82
83using ::com::sun::star::util::URL;
84
85SwXTextView::SwXTextView(SwView* pSwView) :
86 SfxBaseController(pSwView),
87 m_SelChangedListeners(m_aMutex),
88 m_pView(pSwView),
89 m_pPropSet( aSwMapProvider.GetPropertySet( PROPERTY_MAP_TEXT_VIEW92 ) ),
90 mxViewSettings(),
91 mxTextViewCursor()
92{
93
94}
95
96SwXTextView::~SwXTextView()
97{
98 Invalidate();
99}
100
101void SwXTextView::Invalidate()
102{
103 if(mxViewSettings.is())
104 {
105 comphelper::ChainablePropertySet *pSettings = static_cast < comphelper::ChainablePropertySet * > ( mxViewSettings.get() );
106 static_cast < SwXViewSettings* > ( pSettings )->Invalidate();
107 mxViewSettings.clear();
108 }
109 if(mxTextViewCursor.is())
110 {
111 text::XTextViewCursor* pCursor = mxTextViewCursor.get();
112 static_cast<SwXTextViewCursor*>(pCursor)->Invalidate();
113 mxTextViewCursor.clear();
114 }
115
116 osl_atomic_increment(&m_refCount)__sync_add_and_fetch((&m_refCount), 1); //prevent second d'tor call
117
118 {
119 uno::Reference<uno::XInterface> const xInt(static_cast<
120 cppu::OWeakObject*>(static_cast<SfxBaseController*>(this)));
121 lang::EventObject aEvent(xInt);
122 m_SelChangedListeners.disposeAndClear(aEvent);
123 }
124
125 osl_atomic_decrement(&m_refCount)__sync_sub_and_fetch((&m_refCount), 1);
126 m_pView = nullptr;
127}
128
129Sequence< uno::Type > SAL_CALL SwXTextView::getTypes( )
130{
131 return cppu::OTypeCollection(
132 cppu::UnoType<XSelectionSupplier>::get(),
133 cppu::UnoType<XServiceInfo>::get(),
134 cppu::UnoType<XFormLayerAccess>::get(),
135 cppu::UnoType<XTextViewCursorSupplier>::get(),
136 cppu::UnoType<XViewSettingsSupplier>::get(),
137 cppu::UnoType<XRubySelection>::get(),
138 cppu::UnoType<XPropertySet>::get(),
139 cppu::UnoType<datatransfer::XTransferableSupplier>::get(),
140 SfxBaseController::getTypes()
141 ).getTypes();
142}
143
144Sequence< sal_Int8 > SAL_CALL SwXTextView::getImplementationId( )
145{
146 return css::uno::Sequence<sal_Int8>();
147}
148
149void SAL_CALL SwXTextView::acquire( )throw()
150{
151 SfxBaseController::acquire();
152}
153
154void SAL_CALL SwXTextView::release( )throw()
155{
156 SfxBaseController::release();
157}
158
159uno::Any SAL_CALL SwXTextView::queryInterface( const uno::Type& aType )
160{
161 uno::Any aRet;
162 if(aType == cppu::UnoType<view::XSelectionSupplier>::get())
163 {
164 uno::Reference<view::XSelectionSupplier> xRet = this;
165 aRet <<= xRet;
166 }
167 else if(aType == cppu::UnoType<lang::XServiceInfo>::get())
168 {
169 uno::Reference<lang::XServiceInfo> xRet = this;
170 aRet <<= xRet;
171 }
172 else if(aType == cppu::UnoType<view::XControlAccess>::get())
173 {
174 uno::Reference<view::XControlAccess> xRet = this;
175 aRet <<= xRet;
176 }
177 else if(aType == cppu::UnoType<view::XFormLayerAccess>::get())
178 {
179 uno::Reference<view::XFormLayerAccess> xRet = this;
180 aRet <<= xRet;
181 }
182 else if(aType == cppu::UnoType<text::XTextViewCursorSupplier>::get())
183 {
184 uno::Reference<text::XTextViewCursorSupplier> xRet = this;
185 aRet <<= xRet;
186 }
187 else if(aType == cppu::UnoType<view::XViewSettingsSupplier>::get())
188 {
189 uno::Reference<view::XViewSettingsSupplier> xRet = this;
190 aRet <<= xRet;
191 }
192 else if(aType == cppu::UnoType<XRubySelection>::get())
193 {
194 uno::Reference<XRubySelection> xRet = this;
195 aRet <<= xRet;
196 }
197 else if(aType == cppu::UnoType<XPropertySet>::get())
198 {
199 uno::Reference<XPropertySet> xRet = this;
200 aRet <<= xRet;
201 }
202 else if(aType == cppu::UnoType<datatransfer::XTransferableSupplier>::get())
203 {
204 uno::Reference<datatransfer::XTransferableSupplier> xRet = this;
205 aRet <<= xRet;
206 }
207 else
208 aRet = SfxBaseController::queryInterface(aType);
209 return aRet;
210}
211
212sal_Bool SwXTextView::select(const uno::Any& aInterface)
213{
214 SolarMutexGuard aGuard;
215
216 uno::Reference< uno::XInterface > xInterface;
217 if (!GetView() || !(aInterface >>= xInterface))
1
Assuming the condition is false
2
Assuming the condition is false
3
Taking false branch
218 {
219 return false;
220 }
221
222 SwWrtShell& rSh = GetView()->GetWrtShell();
223 SwDoc* pDoc = GetView()->GetDocShell()->GetDoc();
224 std::vector<SdrObject *> sdrObjects;
225 uno::Reference<awt::XControlModel> const xCtrlModel(xInterface,
226 UNO_QUERY);
227 if (xCtrlModel.is())
4
Taking false branch
228 {
229 uno::Reference<awt::XControl> xControl;
230 SdrObject *const pSdrObject = GetControl(xCtrlModel, xControl);
231 if (pSdrObject) // hmm... needs view to verify it's in right doc...
232 {
233 sdrObjects.push_back(pSdrObject);
234 }
235 }
236 else
237 {
238 SwPaM * pPaM(nullptr);
239 std::pair<OUString, FlyCntType> frame;
240 OUString tableName;
241 SwUnoTableCursor const* pTableCursor(nullptr);
242 ::sw::mark::IMark const* pMark(nullptr);
243 SwUnoCursorHelper::GetSelectableFromAny(xInterface, *pDoc,
244 pPaM, frame, tableName, pTableCursor, pMark, sdrObjects);
245 if (pPaM)
5
Assuming 'pPaM' is non-null
6
Taking true branch
246 {
247 rSh.EnterStdMode();
248 rSh.SetSelection(*pPaM);
249 // the pPaM has been copied - delete it
250 while (pPaM->GetNext() != pPaM)
7
Assuming the condition is true
8
Loop condition is true. Entering loop body
10
Calling 'SwPaM::GetNext'
251 delete pPaM->GetNext();
9
Memory is released
252 delete pPaM;
253 return true;
254 }
255 else if (!frame.first.isEmpty())
256 {
257 bool const bSuccess(rSh.GotoFly(frame.first, frame.second));
258 if (bSuccess)
259 {
260 rSh.HideCursor();
261 rSh.EnterSelFrameMode();
262 }
263 return true;
264 }
265 else if (!tableName.isEmpty())
266 {
267 rSh.EnterStdMode();
268 rSh.GotoTable(tableName);
269 return true;
270 }
271 else if (pTableCursor)
272 {
273 UnoActionRemoveContext const aContext(*pTableCursor);
274 rSh.EnterStdMode();
275 rSh.SetSelection(*pTableCursor);
276 return true;
277 }
278 else if (pMark)
279 {
280 rSh.EnterStdMode();
281 rSh.GotoMark(pMark);
282 return true;
283 }
284 // sdrObjects handled below
285 }
286 bool bRet(false);
287 if (!sdrObjects.empty())
288 {
289
290 SdrView *const pDrawView = rSh.GetDrawView();
291 SdrPageView *const pPV = pDrawView->GetSdrPageView();
292
293 pDrawView->SdrEndTextEdit();
294 pDrawView->UnmarkAll();
295
296 for (SdrObject* pSdrObject : sdrObjects)
297 {
298 // GetSelectableFromAny did not check pSdrObject is in right doc!
299 if (pPV && pSdrObject->getSdrPageFromSdrObject() == pPV->GetPage())
300 {
301 pDrawView->MarkObj(pSdrObject, pPV);
302 bRet = true;
303 }
304 }
305
306 // tdf#112696 if we selected every individual element of a group, then
307 // select that group instead
308 const SdrMarkList &rMrkList = pDrawView->GetMarkedObjectList();
309 size_t nMarkCount = rMrkList.GetMarkCount();
310 if (nMarkCount > 1)
311 {
312 SdrObject* pObject = rMrkList.GetMark(0)->GetMarkedSdrObj();
313 SdrObject* pGroupParent = pObject->getParentSdrObjectFromSdrObject();
314 for (size_t i = 1; i < nMarkCount; ++i)
315 {
316 pObject = rMrkList.GetMark(i)->GetMarkedSdrObj();
317 SdrObject* pParent = pObject->getParentSdrObjectFromSdrObject();
318 if (pParent != pGroupParent)
319 {
320 pGroupParent = nullptr;
321 break;
322 }
323 }
324
325 if (pGroupParent && pGroupParent->IsGroupObject() &&
326 pGroupParent->getChildrenOfSdrObject()->GetObjCount() == nMarkCount)
327 {
328 pDrawView->UnmarkAll();
329 pDrawView->MarkObj(pGroupParent, pPV);
330 }
331 }
332 }
333 return bRet;
334}
335
336uno::Any SwXTextView::getSelection()
337{
338 SolarMutexGuard aGuard;
339 uno::Reference< uno::XInterface > aRef;
340 if(GetView())
341 {
342 //force immediat shell update
343 m_pView->StopShellTimer();
344 //Generating an interface from the current selection.
345 SwWrtShell& rSh = m_pView->GetWrtShell();
346 ShellMode eSelMode = m_pView->GetShellMode();
347 switch(eSelMode)
348 {
349 case ShellMode::TableText :
350 {
351 if(rSh.GetTableCursor())
352 {
353 OSL_ENSURE(rSh.GetTableFormat(), "not a table format?")do { if (true && (!(rSh.GetTableFormat()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/uibase/uno/unotxvw.cxx"
":" "353" ": "), "%s", "not a table format?"); } } while (false
)
;
354 uno::Reference< text::XTextTableCursor > xCursor = new SwXTextTableCursor(*rSh.GetTableFormat(),
355 rSh.GetTableCursor());
356 aRef.set(xCursor, uno::UNO_QUERY);
357 break;
358 }
359 [[fallthrough]];
360 // without a table selection the text will be delivered
361 }
362 case ShellMode::ListText :
363 case ShellMode::TableListText:
364 case ShellMode::Text :
365 {
366 uno::Reference< container::XIndexAccess > xPos = SwXTextRanges::Create(rSh.GetCursor());
367 aRef.set(xPos, uno::UNO_QUERY);
368 }
369 break;
370 case ShellMode::Frame :
371 {
372 SwFrameFormat *const pFormat = rSh.GetFlyFrameFormat();
373 if (pFormat)
374 {
375 aRef = SwXTextFrame::CreateXTextFrame(
376 *pFormat->GetDoc(), pFormat);
377 }
378 }
379 break;
380 case ShellMode::Graphic :
381 {
382 SwFrameFormat *const pFormat = rSh.GetFlyFrameFormat();
383 if (pFormat)
384 {
385 aRef = SwXTextGraphicObject::CreateXTextGraphicObject(
386 *pFormat->GetDoc(), pFormat);
387 }
388 }
389 break;
390 case ShellMode::Object :
391 {
392 SwFrameFormat *const pFormat = rSh.GetFlyFrameFormat();
393 if (pFormat)
394 {
395 aRef = SwXTextEmbeddedObject::CreateXTextEmbeddedObject(
396 *pFormat->GetDoc(), pFormat);
397 }
398 }
399 break;
400 case ShellMode::Draw :
401 case ShellMode::DrawForm :
402 case ShellMode::DrawText :
403 case ShellMode::Bezier :
404 {
405 uno::Reference< drawing::XShapes > xShCol = drawing::ShapeCollection::create(
406 comphelper::getProcessComponentContext());
407
408 const SdrMarkList& rMarkList = rSh.GetDrawView()->GetMarkedObjectList();
409 for(size_t i = 0; i < rMarkList.GetMarkCount(); ++i)
410 {
411 SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
412 uno::Reference<drawing::XShape> xShape = SwFmDrawPage::GetShape( pObj );
413 xShCol->add(xShape);
414 }
415 aRef.set(xShCol, uno::UNO_QUERY);
416 }
417 break;
418 default:;//prevent warning
419 }
420 }
421 uno::Any aRet(&aRef, cppu::UnoType<uno::XInterface>::get());
422 return aRet;
423}
424
425void SwXTextView::addSelectionChangeListener(
426 const uno::Reference< view::XSelectionChangeListener > & rxListener)
427{
428 SolarMutexGuard aGuard;
429 m_SelChangedListeners.addInterface(rxListener);
430}
431
432void SwXTextView::removeSelectionChangeListener(
433 const uno::Reference< view::XSelectionChangeListener > & rxListener)
434{
435 SolarMutexGuard aGuard;
436 m_SelChangedListeners.removeInterface(rxListener);
437}
438
439SdrObject* SwXTextView::GetControl(
440 const uno::Reference< awt::XControlModel > & xModel,
441 uno::Reference< awt::XControl >& xToFill )
442{
443 SwView* pView2 = GetView();
444 FmFormShell* pFormShell = pView2 ? pView2->GetFormShell() : nullptr;
445 SdrView* pDrawView = pView2 ? pView2->GetDrawView() : nullptr;
446 vcl::Window* pWindow = pView2 ? pView2->GetWrtShell().GetWin() : nullptr;
447
448 OSL_ENSURE( pFormShell && pDrawView && pWindow, "SwXTextView::GetControl: how could I?" )do { if (true && (!(pFormShell && pDrawView &&
pWindow))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/uibase/uno/unotxvw.cxx"
":" "448" ": "), "%s", "SwXTextView::GetControl: how could I?"
); } } while (false)
;
449
450 SdrObject* pControl = nullptr;
451 if ( pFormShell && pDrawView && pWindow )
452 pControl = pFormShell->GetFormControl( xModel, *pDrawView, *pWindow, xToFill );
453 return pControl;
454}
455
456uno::Reference< awt::XControl > SwXTextView::getControl(const uno::Reference< awt::XControlModel > & xModel)
457{
458 SolarMutexGuard aGuard;
459 uno::Reference< awt::XControl > xRet;
460 GetControl(xModel, xRet);
461 return xRet;
462}
463
464uno::Reference< form::runtime::XFormController > SAL_CALL SwXTextView::getFormController( const uno::Reference< form::XForm >& Form )
465{
466 SolarMutexGuard aGuard;
467
468 SwView* pView2 = GetView();
469 FmFormShell* pFormShell = pView2 ? pView2->GetFormShell() : nullptr;
470 SdrView* pDrawView = pView2 ? pView2->GetDrawView() : nullptr;
471 vcl::Window* pWindow = pView2 ? pView2->GetWrtShell().GetWin() : nullptr;
472 OSL_ENSURE( pFormShell && pDrawView && pWindow, "SwXTextView::getFormController: how could I?" )do { if (true && (!(pFormShell && pDrawView &&
pWindow))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/uibase/uno/unotxvw.cxx"
":" "472" ": "), "%s", "SwXTextView::getFormController: how could I?"
); } } while (false)
;
473
474 uno::Reference< form::runtime::XFormController > xController;
475 if ( pFormShell && pDrawView && pWindow )
476 xController = FmFormShell::GetFormController( Form, *pDrawView, *pWindow );
477 return xController;
478}
479
480sal_Bool SAL_CALL SwXTextView::isFormDesignMode( )
481{
482 SolarMutexGuard aGuard;
483 SwView* pView2 = GetView();
484 FmFormShell* pFormShell = pView2 ? pView2->GetFormShell() : nullptr;
485 return !pFormShell || pFormShell->IsDesignMode();
486}
487
488void SAL_CALL SwXTextView::setFormDesignMode( sal_Bool DesignMode )
489{
490 SolarMutexGuard aGuard;
491 SwView* pView2 = GetView();
492 FmFormShell* pFormShell = pView2 ? pView2->GetFormShell() : nullptr;
493 if ( pFormShell )
494 pFormShell->SetDesignMode( DesignMode );
495}
496
497uno::Reference< text::XTextViewCursor > SwXTextView::getViewCursor()
498{
499 SolarMutexGuard aGuard;
500 comphelper::ProfileZone aZone("getViewCursor");
501 if(!GetView())
502 throw uno::RuntimeException();
503
504 if(!mxTextViewCursor.is())
505 {
506 mxTextViewCursor = new SwXTextViewCursor(GetView());
507 }
508 return mxTextViewCursor;
509}
510
511uno::Reference< beans::XPropertySet > SwXTextView::getViewSettings()
512{
513 SolarMutexGuard aGuard;
514 if(!m_pView)
515 throw uno::RuntimeException();
516
517 if(!mxViewSettings.is())
518 {
519 mxViewSettings = new SwXViewSettings( m_pView );
520 }
521
522 return mxViewSettings;
523}
524
525Sequence< Sequence< PropertyValue > > SwXTextView::getRubyList( sal_Bool /*bAutomatic*/ )
526{
527 SolarMutexGuard aGuard;
528
529 if(!GetView())
530 throw RuntimeException();
531 SwWrtShell& rSh = m_pView->GetWrtShell();
532 ShellMode eSelMode = m_pView->GetShellMode();
533 if (eSelMode != ShellMode::ListText &&
534 eSelMode != ShellMode::TableListText &&
535 eSelMode != ShellMode::TableText &&
536 eSelMode != ShellMode::Text )
537 return Sequence< Sequence< PropertyValue > > ();
538
539 SwRubyList aList;
540
541 const sal_uInt16 nCount = SwDoc::FillRubyList( *rSh.GetCursor(), aList );
542 Sequence< Sequence< PropertyValue > > aRet(nCount);
543 Sequence< PropertyValue >* pRet = aRet.getArray();
544 OUString aString;
545 for(sal_uInt16 n = 0; n < nCount; n++)
546 {
547 const SwRubyListEntry* pEntry = aList[n].get();
548
549 const OUString& rEntryText = pEntry->GetText();
550 const SwFormatRuby& rAttr = pEntry->GetRubyAttr();
551
552 pRet[n].realloc(6);
553 PropertyValue* pValues = pRet[n].getArray();
554 pValues[0].Name = UNO_NAME_RUBY_BASE_TEXT"RubyBaseText";
555 pValues[0].Value <<= rEntryText;
556 pValues[1].Name = UNO_NAME_RUBY_TEXT"RubyText";
557 pValues[1].Value <<= rAttr.GetText();
558 pValues[2].Name = UNO_NAME_RUBY_CHAR_STYLE_NAME"RubyCharStyleName";
559 SwStyleNameMapper::FillProgName(rAttr.GetCharFormatName(), aString, SwGetPoolIdFromName::ChrFmt );
560 pValues[2].Value <<= aString;
561 pValues[3].Name = UNO_NAME_RUBY_ADJUST"RubyAdjust";
562 pValues[3].Value <<= static_cast<sal_Int16>(rAttr.GetAdjustment());
563 pValues[4].Name = UNO_NAME_RUBY_IS_ABOVE"RubyIsAbove";
564 pValues[4].Value <<= !rAttr.GetPosition();
565 pValues[5].Name = UNO_NAME_RUBY_POSITION"RubyPosition";
566 pValues[5].Value <<= rAttr.GetPosition();
567 }
568 return aRet;
569}
570
571void SAL_CALL SwXTextView::setRubyList(
572 const Sequence< Sequence< PropertyValue > >& rRubyList, sal_Bool /*bAutomatic*/ )
573{
574 SolarMutexGuard aGuard;
575
576 if(!GetView() || !rRubyList.hasElements())
577 throw RuntimeException();
578 SwWrtShell& rSh = m_pView->GetWrtShell();
579 ShellMode eSelMode = m_pView->GetShellMode();
580 if (eSelMode != ShellMode::ListText &&
581 eSelMode != ShellMode::TableListText &&
582 eSelMode != ShellMode::TableText &&
583 eSelMode != ShellMode::Text )
584 throw RuntimeException();
585
586 SwRubyList aList;
587
588 for(const Sequence<PropertyValue>& rPropList : rRubyList)
589 {
590 std::unique_ptr<SwRubyListEntry> pEntry(new SwRubyListEntry);
591 OUString sTmp;
592 for(const PropertyValue& rProperty : rPropList)
593 {
594 if(rProperty.Name == UNO_NAME_RUBY_BASE_TEXT"RubyBaseText")
595 {
596 rProperty.Value >>= sTmp;
597 pEntry->SetText(sTmp);
598 }
599 else if(rProperty.Name == UNO_NAME_RUBY_TEXT"RubyText")
600 {
601 rProperty.Value >>= sTmp;
602 pEntry->GetRubyAttr().SetText(sTmp);
603 }
604 else if(rProperty.Name == UNO_NAME_RUBY_CHAR_STYLE_NAME"RubyCharStyleName")
605 {
606 if(rProperty.Value >>= sTmp)
607 {
608 OUString sName;
609 SwStyleNameMapper::FillUIName(sTmp, sName, SwGetPoolIdFromName::ChrFmt );
610 const sal_uInt16 nPoolId = sName.isEmpty() ? 0
611 : SwStyleNameMapper::GetPoolIdFromUIName(sName,
612 SwGetPoolIdFromName::ChrFmt );
613
614 pEntry->GetRubyAttr().SetCharFormatName( sName );
615 pEntry->GetRubyAttr().SetCharFormatId( nPoolId );
616 }
617 }
618 else if(rProperty.Name == UNO_NAME_RUBY_ADJUST"RubyAdjust")
619 {
620 sal_Int16 nTmp = 0;
621 if(rProperty.Value >>= nTmp)
622 pEntry->GetRubyAttr().SetAdjustment(static_cast<css::text::RubyAdjust>(nTmp));
623 }
624 else if(rProperty.Name == UNO_NAME_RUBY_IS_ABOVE"RubyIsAbove")
625 {
626 bool bValue = !rProperty.Value.hasValue() ||
627 *o3tl::doAccess<bool>(rProperty.Value);
628 pEntry->GetRubyAttr().SetPosition(bValue ? 0 : 1);
629 }
630 else if(rProperty.Name == UNO_NAME_RUBY_POSITION"RubyPosition")
631 {
632 sal_Int16 nTmp = 0;
633 if(rProperty.Value >>= nTmp)
634 pEntry->GetRubyAttr().SetPosition( nTmp );
635 }
636 }
637 aList.push_back(std::move(pEntry));
638 }
639 SwDoc* pDoc = m_pView->GetDocShell()->GetDoc();
640 pDoc->SetRubyList( *rSh.GetCursor(), aList );
641}
642
643SfxObjectShellLock SwXTextView::BuildTmpSelectionDoc()
644{
645 SwWrtShell& rOldSh = m_pView->GetWrtShell();
646 SfxPrinter *pPrt = rOldSh.getIDocumentDeviceAccess().getPrinter( false );
647 SwDocShell* pDocSh;
648 SfxObjectShellLock xDocSh( pDocSh = new SwDocShell(SfxObjectCreateMode::STANDARD) );
649 xDocSh->DoInitNew();
650 SwDoc *const pTempDoc( pDocSh->GetDoc() );
651 // #i103634#, #i112425#: do not expand numbering and fields on PDF export
652 pTempDoc->SetClipBoard(true);
653 rOldSh.FillPrtDoc(*pTempDoc, pPrt);
654 SfxViewFrame* pDocFrame = SfxViewFrame::LoadHiddenDocument( *xDocSh, SFX_INTERFACE_NONE );
655 SwView* pDocView = static_cast<SwView*>( pDocFrame->GetViewShell() );
656 pDocView->AttrChangedNotify(nullptr);//So that SelectShell is called.
657 SwWrtShell* pSh = pDocView->GetWrtShellPtr();
658
659 IDocumentDeviceAccess& rIDDA = pSh->getIDocumentDeviceAccess();
660 SfxPrinter* pTempPrinter = rIDDA.getPrinter( true );
661
662 const SwPageDesc& rCurPageDesc = rOldSh.GetPageDesc(rOldSh.GetCurPageDesc());
663
664 IDocumentDeviceAccess& rIDDA_old = rOldSh.getIDocumentDeviceAccess();
665
666 if( rIDDA_old.getPrinter( false ) )
667 {
668 rIDDA.setJobsetup( *rIDDA_old.getJobsetup() );
669 //#69563# if it isn't the same printer then the pointer has been invalidated!
670 pTempPrinter = rIDDA.getPrinter( true );
671 }
672
673 pTempPrinter->SetPaperBin(rCurPageDesc.GetMaster().GetPaperBin().GetValue());
674
675 return xDocSh;
676}
677
678void SwXTextView::NotifySelChanged()
679{
680 OSL_ENSURE( m_pView, "view is missing" )do { if (true && (!(m_pView))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/uibase/uno/unotxvw.cxx"
":" "680" ": "), "%s", "view is missing"); } } while (false)
;
681
682 uno::Reference<uno::XInterface> const xInt(
683 static_cast<cppu::OWeakObject*>(static_cast<SfxBaseController*>(this)));
684
685 lang::EventObject const aEvent(xInt);
686 m_SelChangedListeners.notifyEach(
687 &view::XSelectionChangeListener::selectionChanged, aEvent);
688}
689
690namespace {
691 struct DispatchListener
692 {
693 URL const & m_rURL;
694 Sequence<PropertyValue> const& m_rSeq;
695 explicit DispatchListener(URL const& rURL,
696 Sequence<PropertyValue> const& rSeq)
697 : m_rURL(rURL), m_rSeq(rSeq) { }
698 void operator()(uno::Reference<XDispatch> const & xListener) const
699 {
700 xListener->dispatch(m_rURL, m_rSeq);
701 }
702 };
703}
704
705void SwXTextView::NotifyDBChanged()
706{
707 URL aURL;
708 aURL.Complete = OUString::createFromAscii(SwXDispatch::GetDBChangeURL());
709
710 m_SelChangedListeners.forEach<XDispatch>(
711 DispatchListener(aURL, Sequence<PropertyValue>(0)));
712}
713
714uno::Reference< beans::XPropertySetInfo > SAL_CALL SwXTextView::getPropertySetInfo( )
715{
716 SolarMutexGuard aGuard;
717 static uno::Reference< XPropertySetInfo > aRef = m_pPropSet->getPropertySetInfo();
718 return aRef;
719}
720
721void SAL_CALL SwXTextView::setPropertyValue(
722 const OUString& rPropertyName, const uno::Any& rValue )
723{
724 SolarMutexGuard aGuard;
725 const SfxItemPropertySimpleEntry* pEntry = m_pPropSet->getPropertyMap().getByName( rPropertyName );
726 if (!pEntry)
727 throw UnknownPropertyException(rPropertyName);
728 else if (pEntry->nFlags & PropertyAttribute::READONLY)
729 throw PropertyVetoException();
730 else
731 {
732 switch (pEntry->nWID)
733 {
734 case WID_IS_HIDE_SPELL_MARKS1103 :
735 // deprecated #i91949
736 break;
737 case WID_IS_CONSTANT_SPELLCHECK1102 :
738 {
739 bool bVal = false;
740 const SwViewOption *pOpt = m_pView->GetWrtShell().GetViewOptions();
741 if (!pOpt || !(rValue >>= bVal))
742 throw RuntimeException();
743 SwViewOption aNewOpt( *pOpt );
744 if (pEntry->nWID == WID_IS_CONSTANT_SPELLCHECK1102)
745 aNewOpt.SetOnlineSpell(bVal);
746 m_pView->GetWrtShell().ApplyViewOptions( aNewOpt );
747 }
748 break;
749 default :
750 OSL_FAIL("unknown WID")do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/uibase/uno/unotxvw.cxx"
":" "750" ": "), "%s", "unknown WID"); } } while (false)
;
751 }
752 }
753}
754
755uno::Any SAL_CALL SwXTextView::getPropertyValue(
756 const OUString& rPropertyName )
757{
758 SolarMutexGuard aGuard;
759
760 Any aRet;
761
762 const SfxItemPropertySimpleEntry* pEntry = m_pPropSet->getPropertyMap().getByName( rPropertyName );
763 if (!pEntry)
764 throw UnknownPropertyException(rPropertyName);
765
766 sal_Int16 nWID = pEntry->nWID;
767 switch (nWID)
768 {
769 case WID_PAGE_COUNT1100 :
770 case WID_LINE_COUNT1101 :
771 {
772 // format document completely in order to get meaningful
773 // values for page count and line count
774 m_pView->GetWrtShell().CalcLayout();
775
776 sal_Int32 nCount = -1;
777 if (nWID == WID_PAGE_COUNT1100)
778 nCount = m_pView->GetWrtShell().GetPageCount();
779 else // WID_LINE_COUNT
780 nCount = m_pView->GetWrtShell().GetLineCount();
781 aRet <<= nCount;
782 }
783 break;
784 case WID_IS_HIDE_SPELL_MARKS1103 :
785 // deprecated #i91949
786 break;
787 case WID_IS_CONSTANT_SPELLCHECK1102 :
788 {
789 const SwViewOption *pOpt = m_pView->GetWrtShell().GetViewOptions();
790 if (!pOpt)
791 throw RuntimeException();
792 aRet <<= bool(pOpt->GetCoreOptions() & ViewOptFlags1::OnlineSpell);
793 }
794 break;
795 default :
796 OSL_FAIL("unknown WID")do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/uibase/uno/unotxvw.cxx"
":" "796" ": "), "%s", "unknown WID"); } } while (false)
;
797 }
798
799 return aRet;
800}
801
802void SAL_CALL SwXTextView::addPropertyChangeListener(
803 const OUString& /*rPropertyName*/,
804 const uno::Reference< beans::XPropertyChangeListener >& /*rxListener*/ )
805{
806 OSL_FAIL("not implemented")do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/uibase/uno/unotxvw.cxx"
":" "806" ": "), "%s", "not implemented"); } } while (false)
;
807}
808
809void SAL_CALL SwXTextView::removePropertyChangeListener(
810 const OUString& /*rPropertyName*/,
811 const uno::Reference< beans::XPropertyChangeListener >& /*rxListener*/ )
812{
813 OSL_FAIL("not implemented")do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/uibase/uno/unotxvw.cxx"
":" "813" ": "), "%s", "not implemented"); } } while (false)
;
814}
815
816void SAL_CALL SwXTextView::addVetoableChangeListener(
817 const OUString& /*rPropertyName*/,
818 const uno::Reference< beans::XVetoableChangeListener >& /*rxListener*/ )
819{
820 OSL_FAIL("not implemented")do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/uibase/uno/unotxvw.cxx"
":" "820" ": "), "%s", "not implemented"); } } while (false)
;
821}
822
823void SAL_CALL SwXTextView::removeVetoableChangeListener(
824 const OUString& /*rPropertyName*/,
825 const uno::Reference< beans::XVetoableChangeListener >& /*rxListener*/ )
826{
827 OSL_FAIL("not implemented")do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/uibase/uno/unotxvw.cxx"
":" "827" ": "), "%s", "not implemented"); } } while (false)
;
828}
829
830OUString SwXTextView::getImplementationName()
831{
832 return "SwXTextView";
833}
834
835sal_Bool SwXTextView::supportsService(const OUString& rServiceName)
836{
837 return cppu::supportsService(this, rServiceName);
838}
839
840Sequence< OUString > SwXTextView::getSupportedServiceNames()
841{
842 return { "com.sun.star.text.TextDocumentView", "com.sun.star.view.OfficeDocumentView" };
843}
844
845SwXTextViewCursor::SwXTextViewCursor(SwView* pVw) :
846 m_pView(pVw),
847 m_pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_CURSOR0))
848{
849}
850
851SwXTextViewCursor::~SwXTextViewCursor()
852{
853}
854
855// used to determine if there is a text selection or not.
856// If there is no text selection the functions that need a working
857// cursor will be disabled (throw RuntimeException). This will be the case
858// for the following interfaces:
859// - XViewCursor
860// - XTextCursor
861// - XTextRange
862// - XLineCursor
863bool SwXTextViewCursor::IsTextSelection( bool bAllowTables ) const
864{
865
866 bool bRes = false;
867 OSL_ENSURE(m_pView, "m_pView is NULL ???")do { if (true && (!(m_pView))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/uibase/uno/unotxvw.cxx"
":" "867" ": "), "%s", "m_pView is NULL ???"); } } while (false
)
;
868 if(m_pView)
869 {
870 //! m_pView->GetShellMode() will only work after the shell
871 //! has already changed and thus can not be used here!
872 SelectionType eSelType = m_pView->GetWrtShell().GetSelectionType();
873 bRes = ( (SelectionType::Text & eSelType) ||
874 (SelectionType::NumberList & eSelType) ) &&
875 (!(SelectionType::TableCell & eSelType) || bAllowTables);
876 }
877 return bRes;
878}
879
880sal_Bool SwXTextViewCursor::isVisible()
881{
882 OSL_FAIL("not implemented")do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/uibase/uno/unotxvw.cxx"
":" "882" ": "), "%s", "not implemented"); } } while (false)
;
883 return true;
884}
885
886void SwXTextViewCursor::setVisible(sal_Bool /*bVisible*/)
887{
888 OSL_FAIL("not implemented")do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/uibase/uno/unotxvw.cxx"
":" "888" ": "), "%s", "not implemented"); } } while (false)
;
889}
890
891awt::Point SwXTextViewCursor::getPosition()
892{
893 SolarMutexGuard aGuard;
894 awt::Point aRet;
895 if(!m_pView)
896 throw uno::RuntimeException();
897
898 const SwWrtShell& rSh = m_pView->GetWrtShell();
899 const SwRect& aCharRect(rSh.GetCharRect());
900
901 const SwFrameFormat& rMaster = rSh.GetPageDesc( rSh.GetCurPageDesc() ).GetMaster();
902
903 const SvxULSpaceItem& rUL = rMaster.GetULSpace();
904 const long nY = aCharRect.Top() - (rUL.GetUpper() + DOCUMENTBORDER284);
905 aRet.Y = convertTwipToMm100(nY);
906
907 const SvxLRSpaceItem& rLR = rMaster.GetLRSpace();
908 const long nX = aCharRect.Left() - (rLR.GetLeft() + DOCUMENTBORDER284);
909 aRet.X = convertTwipToMm100(nX);
910
911 return aRet;
912}
913
914void SwXTextViewCursor::collapseToStart()
915{
916 SolarMutexGuard aGuard;
917 if(!m_pView)
918 throw uno::RuntimeException();
919
920 if (!IsTextSelection())
921 throw uno::RuntimeException("no text selection", static_cast < cppu::OWeakObject * > ( this ) );
922
923 SwWrtShell& rSh = m_pView->GetWrtShell();
924 if(rSh.HasSelection())
925 {
926 SwPaM* pShellCursor = rSh.GetCursor();
927 if(*pShellCursor->GetPoint() > *pShellCursor->GetMark())
928 pShellCursor->Exchange();
929 pShellCursor->DeleteMark();
930 rSh.EnterStdMode();
931 rSh.SetSelection(*pShellCursor);
932 }
933
934}
935
936void SwXTextViewCursor::collapseToEnd()
937{
938 SolarMutexGuard aGuard;
939 if(!m_pView)
940 throw uno::RuntimeException();
941
942 if (!IsTextSelection())
943 throw uno::RuntimeException("no text selection", static_cast < cppu::OWeakObject * > ( this ) );
944
945 SwWrtShell& rSh = m_pView->GetWrtShell();
946 if(rSh.HasSelection())
947 {
948 SwPaM* pShellCursor = rSh.GetCursor();
949 if(*pShellCursor->GetPoint() < *pShellCursor->GetMark())
950 pShellCursor->Exchange();
951 pShellCursor->DeleteMark();
952 rSh.EnterStdMode();
953 rSh.SetSelection(*pShellCursor);
954 }
955
956}
957
958sal_Bool SwXTextViewCursor::isCollapsed()
959{
960 SolarMutexGuard aGuard;
961 bool bRet = false;
962 if(!m_pView)
963 throw uno::RuntimeException();
964
965 if (!IsTextSelection())
966 throw uno::RuntimeException("no text selection", static_cast < cppu::OWeakObject * > ( this ) );
967
968 const SwWrtShell& rSh = m_pView->GetWrtShell();
969 bRet = !rSh.HasSelection();
970
971 return bRet;
972
973}
974
975sal_Bool SwXTextViewCursor::goLeft(sal_Int16 nCount, sal_Bool bExpand)
976{
977 SolarMutexGuard aGuard;
978 bool bRet = false;
979 if(!m_pView)
980 throw uno::RuntimeException();
981
982 if (!IsTextSelection())
983 throw uno::RuntimeException("no text selection", static_cast < cppu::OWeakObject * > ( this ) );
984
985 bRet = m_pView->GetWrtShell().Left( CRSR_SKIP_CHARS, bExpand, nCount, true );
986
987 return bRet;
988}
989
990sal_Bool SwXTextViewCursor::goRight(sal_Int16 nCount, sal_Bool bExpand)
991{
992 SolarMutexGuard aGuard;
993 bool bRet = false;
994 if(!m_pView)
995 throw uno::RuntimeException();
996
997 if (!IsTextSelection())
998 throw uno::RuntimeException("no text selection", static_cast < cppu::OWeakObject * > ( this ) );
999
1000 bRet = m_pView->GetWrtShell().Right( CRSR_SKIP_CHARS, bExpand, nCount, true );
1001
1002 return bRet;
1003
1004}
1005
1006void SwXTextViewCursor::gotoRange(
1007 const uno::Reference< text::XTextRange > & xRange,
1008 sal_Bool bExpand)
1009{
1010 SolarMutexGuard aGuard;
1011 if(!(m_pView && xRange.is()))
1012 throw uno::RuntimeException();
1013
1014 if (!IsTextSelection())
1015 throw uno::RuntimeException("no text selection", static_cast < cppu::OWeakObject * > ( this ) );
1016
1017 SwUnoInternalPaM rDestPam(*m_pView->GetDocShell()->GetDoc());
1018 if (!::sw::XTextRangeToSwPaM(rDestPam, xRange))
1019 {
1020 throw uno::RuntimeException();
1021 }
1022
1023 ShellMode eSelMode = m_pView->GetShellMode();
1024 SwWrtShell& rSh = m_pView->GetWrtShell();
1025 // call EnterStdMode in non-text selections only
1026 if(!bExpand ||
1027 (eSelMode != ShellMode::TableText &&
1028 eSelMode != ShellMode::ListText &&
1029 eSelMode != ShellMode::TableListText &&
1030 eSelMode != ShellMode::Text ))
1031 rSh.EnterStdMode();
1032 SwPaM* pShellCursor = rSh.GetCursor();
1033 SwPaM aOwnPaM(*pShellCursor->GetPoint());
1034 if(pShellCursor->HasMark())
1035 {
1036 aOwnPaM.SetMark();
1037 *aOwnPaM.GetMark() = *pShellCursor->GetMark();
1038 }
1039
1040 uno::Reference<lang::XUnoTunnel> xRangeTunnel( xRange, uno::UNO_QUERY);
1041 SwXTextRange* pRange = nullptr;
1042 SwXParagraph* pPara = nullptr;
1043 OTextCursorHelper* pCursor = nullptr;
1044 if(xRangeTunnel.is())
1045 {
1046 pRange = reinterpret_cast<SwXTextRange*>(xRangeTunnel->getSomething(
1047 SwXTextRange::getUnoTunnelId()));
1048 pCursor = reinterpret_cast<OTextCursorHelper*>(xRangeTunnel->getSomething(
1049 OTextCursorHelper::getUnoTunnelId()));
1050 pPara = reinterpret_cast<SwXParagraph*>(xRangeTunnel->getSomething(
1051 SwXParagraph::getUnoTunnelId()));
1052 }
1053
1054 const FrameTypeFlags nFrameType = rSh.GetFrameType(nullptr,true);
1055
1056 SwStartNodeType eSearchNodeType = SwNormalStartNode;
1057 if(nFrameType & FrameTypeFlags::FLY_ANY)
1058 eSearchNodeType = SwFlyStartNode;
1059 else if(nFrameType &FrameTypeFlags::HEADER)
1060 eSearchNodeType = SwHeaderStartNode;
1061 else if(nFrameType & FrameTypeFlags::FOOTER)
1062 eSearchNodeType = SwFooterStartNode;
1063 else if(nFrameType & FrameTypeFlags::TABLE)
1064 eSearchNodeType = SwTableBoxStartNode;
1065 else if(nFrameType & FrameTypeFlags::FOOTNOTE)
1066 eSearchNodeType = SwFootnoteStartNode;
1067
1068 const SwStartNode* pOwnStartNode = aOwnPaM.GetNode().
1069 FindSttNodeByType(eSearchNodeType);
1070
1071 const SwNode* pSrcNode = nullptr;
1072 if(pCursor && pCursor->GetPaM())
1073 {
1074 pSrcNode = &pCursor->GetPaM()->GetNode();
1075 }
1076 else if (pRange)
1077 {
1078 SwPaM aPam(pRange->GetDoc().GetNodes());
1079 if (pRange->GetPositions(aPam))
1080 {
1081 pSrcNode = &aPam.GetNode();
1082 }
1083 }
1084 else if (pPara && pPara->GetTextNode())
1085 {
1086 pSrcNode = pPara->GetTextNode();
1087 }
1088 const SwStartNode* pTmp = pSrcNode ? pSrcNode->FindSttNodeByType(eSearchNodeType) : nullptr;
1089
1090 //Skip SectionNodes
1091 while(pTmp && pTmp->IsSectionNode())
1092 {
1093 pTmp = pTmp->StartOfSectionNode();
1094 }
1095 while(pOwnStartNode && pOwnStartNode->IsSectionNode())
1096 {
1097 pOwnStartNode = pOwnStartNode->StartOfSectionNode();
1098 }
1099 //Without Expand it is allowed to jump out with the ViewCursor everywhere,
1100 //with Expand only in the same environment
1101 if(bExpand &&
1102 (pOwnStartNode != pTmp ||
1103 (eSelMode != ShellMode::TableText &&
1104 eSelMode != ShellMode::ListText &&
1105 eSelMode != ShellMode::TableListText &&
1106 eSelMode != ShellMode::Text)))
1107 throw uno::RuntimeException();
1108
1109 //Now, the selection must be expanded.
1110 if(bExpand)
1111 {
1112 // The cursor should include everything that has been included
1113 // by him and the transferred Range.
1114 SwPosition aOwnLeft(*aOwnPaM.Start());
1115 SwPosition aOwnRight(*aOwnPaM.End());
1116 SwPosition* pParamLeft = rDestPam.Start();
1117 SwPosition* pParamRight = rDestPam.End();
1118 // Now four SwPositions are there, two of them are needed, but which?
1119 if(aOwnRight > *pParamRight)
1120 *aOwnPaM.GetPoint() = aOwnRight;
1121 else
1122 *aOwnPaM.GetPoint() = *pParamRight;
1123 aOwnPaM.SetMark();
1124 if(aOwnLeft < *pParamLeft)
1125 *aOwnPaM.GetMark() = aOwnLeft;
1126 else
1127 *aOwnPaM.GetMark() = *pParamLeft;
1128 }
1129 else
1130 {
1131 //The cursor shall match the passed range.
1132 *aOwnPaM.GetPoint() = *rDestPam.GetPoint();
1133 if(rDestPam.HasMark())
1134 {
1135 aOwnPaM.SetMark();
1136 *aOwnPaM.GetMark() = *rDestPam.GetMark();
1137 }
1138 else
1139 aOwnPaM.DeleteMark();
1140 }
1141 rSh.SetSelection(aOwnPaM);
1142
1143
1144}
1145
1146void SwXTextViewCursor::gotoStart(sal_Bool bExpand)
1147{
1148 SolarMutexGuard aGuard;
1149 comphelper::ProfileZone aZone("SwXTextViewCursor::gotoStart");
1150 if(!m_pView)
1151 throw uno::RuntimeException();
1152
1153 if (!IsTextSelection())
1154 throw uno::RuntimeException("no text selection", static_cast < cppu::OWeakObject * > ( this ) );
1155
1156 m_pView->GetWrtShell().StartOfSection( bExpand );
1157
1158}
1159
1160void SwXTextViewCursor::gotoEnd(sal_Bool bExpand)
1161{
1162 SolarMutexGuard aGuard;
1163 comphelper::ProfileZone aZone("SwXTextViewCursor::gotoEnd");
1164 if(!m_pView)
1165 throw uno::RuntimeException();
1166
1167 if (!IsTextSelection())
1168 throw uno::RuntimeException("no text selection", static_cast < cppu::OWeakObject * > ( this ) );
1169
1170 m_pView->GetWrtShell().EndOfSection( bExpand );
1171
1172}
1173
1174sal_Bool SwXTextViewCursor::jumpToFirstPage()
1175{
1176 SolarMutexGuard aGuard;
1177 bool bRet = false;
1178 if(!m_pView)
1179 throw uno::RuntimeException();
1180
1181 SwWrtShell& rSh = m_pView->GetWrtShell();
1182 if (rSh.IsSelFrameMode())
1183 {
1184 rSh.UnSelectFrame();
1185 rSh.LeaveSelFrameMode();
1186 }
1187 rSh.EnterStdMode();
1188 bRet = rSh.SttEndDoc(true);
1189
1190 return bRet;
1191}
1192
1193sal_Bool SwXTextViewCursor::jumpToLastPage()
1194{
1195 SolarMutexGuard aGuard;
1196 bool bRet = false;
1197 if(!m_pView)
1198 throw uno::RuntimeException();
1199
1200 SwWrtShell& rSh = m_pView->GetWrtShell();
1201 if (rSh.IsSelFrameMode())
1202 {
1203 rSh.UnSelectFrame();
1204 rSh.LeaveSelFrameMode();
1205 }
1206 rSh.EnterStdMode();
1207 bRet = rSh.SttEndDoc(false);
1208 rSh.SttPg();
1209
1210 return bRet;
1211}
1212
1213sal_Bool SwXTextViewCursor::jumpToPage(sal_Int16 nPage)
1214{
1215 SolarMutexGuard aGuard;
1216 bool bRet = false;
1217 if(!m_pView)
1218 throw uno::RuntimeException();
1219
1220 bRet = m_pView->GetWrtShell().GotoPage(nPage, true);
1221
1222 return bRet;
1223}
1224
1225sal_Bool SwXTextViewCursor::jumpToNextPage()
1226{
1227 SolarMutexGuard aGuard;
1228 bool bRet = false;
1229 if(!m_pView)
1230 throw uno::RuntimeException();
1231
1232 bRet = m_pView->GetWrtShell().SttNxtPg();
1233
1234 return bRet;
1235}
1236
1237sal_Bool SwXTextViewCursor::jumpToPreviousPage()
1238{
1239 SolarMutexGuard aGuard;
1240 bool bRet = false;
1241 if(!m_pView)
1242 throw uno::RuntimeException();
1243
1244 bRet = m_pView->GetWrtShell().EndPrvPg();
1245
1246 return bRet;
1247}
1248
1249sal_Bool SwXTextViewCursor::jumpToEndOfPage()
1250{
1251 SolarMutexGuard aGuard;
1252 bool bRet = false;
1253 if(!m_pView)
1254 throw uno::RuntimeException();
1255
1256 bRet = m_pView->GetWrtShell().EndPg();
1257
1258 return bRet;
1259}
1260
1261sal_Bool SwXTextViewCursor::jumpToStartOfPage()
1262{
1263 SolarMutexGuard aGuard;
1264 bool bRet = false;
1265 if(!m_pView)
1266 throw uno::RuntimeException();
1267
1268 bRet = m_pView->GetWrtShell().SttPg();
1269
1270 return bRet;
1271}
1272
1273sal_Int16 SwXTextViewCursor::getPage()
1274{
1275 SolarMutexGuard aGuard;
1276 sal_Int16 nRet = 0;
1277 if(!m_pView)
1278 throw uno::RuntimeException();
1279
1280 SwWrtShell& rSh = m_pView->GetWrtShell();
1281 SwPaM* pShellCursor = rSh.GetCursor();
1282 nRet = static_cast<sal_Int16>(pShellCursor->GetPageNum());
1283
1284 return nRet;
1285}
1286
1287sal_Bool SwXTextViewCursor::screenDown()
1288{
1289 SolarMutexGuard aGuard;
1290 bool bRet = false;
1291 if(!m_pView)
1292 throw uno::RuntimeException();
1293
1294 SfxRequest aReq(FN_PAGEDOWN((20000 + 900) + 38), SfxCallMode::SLOT, m_pView->GetPool());
1295 m_pView->Execute(aReq);
1296 const SfxPoolItem* pRet = aReq.GetReturnValue();
1297 bRet = pRet && static_cast<const SfxBoolItem*>(pRet)->GetValue();
1298
1299 return bRet;
1300}
1301
1302sal_Bool SwXTextViewCursor::screenUp()
1303{
1304 SolarMutexGuard aGuard;
1305 bool bRet = false;
1306 if(!m_pView)
1307 throw uno::RuntimeException();
1308
1309 SfxRequest aReq(FN_PAGEUP((20000 + 900) + 37), SfxCallMode::SLOT, m_pView->GetPool());
1310 m_pView->Execute(aReq);
1311 const SfxPoolItem* pRet = aReq.GetReturnValue();
1312 bRet = pRet && static_cast<const SfxBoolItem*>(pRet)->GetValue();
1313
1314 return bRet;
1315}
1316
1317uno::Reference< text::XText > SwXTextViewCursor::getText()
1318{
1319 SolarMutexGuard aGuard;
1320 uno::Reference< text::XText > xRet;
1321 if(!m_pView)
1322 throw uno::RuntimeException();
1323
1324 if (!IsTextSelection( false ))
1325 throw uno::RuntimeException("no text selection", static_cast < cppu::OWeakObject * > ( this ) );
1326
1327 SwWrtShell& rSh = m_pView->GetWrtShell();
1328 SwPaM* pShellCursor = rSh.GetCursor();
1329 SwDoc* pDoc = m_pView->GetDocShell()->GetDoc();
1330 xRet = ::sw::CreateParentXText(*pDoc, *pShellCursor->Start());
1331
1332 return xRet;
1333}
1334
1335uno::Reference< text::XTextRange > SwXTextViewCursor::getStart()
1336{
1337 SolarMutexGuard aGuard;
1338 uno::Reference< text::XTextRange > xRet;
1339 if(!m_pView)
1340 throw uno::RuntimeException();
1341
1342 if (!IsTextSelection())
1343 throw uno::RuntimeException("no text selection", static_cast < cppu::OWeakObject * > ( this ) );
1344
1345 SwWrtShell& rSh = m_pView->GetWrtShell();
1346 SwPaM* pShellCursor = rSh.GetCursor();
1347 SwDoc* pDoc = m_pView->GetDocShell()->GetDoc();
1348 xRet = SwXTextRange::CreateXTextRange(*pDoc, *pShellCursor->Start(), nullptr);
1349
1350 return xRet;
1351}
1352
1353uno::Reference< text::XTextRange > SwXTextViewCursor::getEnd()
1354{
1355 SolarMutexGuard aGuard;
1356 uno::Reference< text::XTextRange > xRet;
1357 if(!m_pView)
1358 throw uno::RuntimeException();
1359
1360 if (!IsTextSelection())
1361 throw uno::RuntimeException("no text selection", static_cast < cppu::OWeakObject * > ( this ) );
1362
1363 SwWrtShell& rSh = m_pView->GetWrtShell();
1364 SwPaM* pShellCursor = rSh.GetCursor();
1365 SwDoc* pDoc = m_pView->GetDocShell()->GetDoc();
1366 xRet = SwXTextRange::CreateXTextRange(*pDoc, *pShellCursor->End(), nullptr);
1367
1368 return xRet;
1369}
1370
1371OUString SwXTextViewCursor::getString()
1372{
1373 SolarMutexGuard aGuard;
1374 OUString uRet;
1375 if(m_pView)
1376 {
1377 if (!IsTextSelection( false ))
1378 {
1379 SAL_WARN("sw.uno", "no text selection in getString() " << static_cast<cppu::OWeakObject*>(this))do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "sw.uno")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "no text selection in getString() "
<< static_cast<cppu::OWeakObject*>(this)) == 1) {
::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno"),
("/home/maarten/src/libreoffice/core/sw/source/uibase/uno/unotxvw.cxx"
":" "1379" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "no text selection in getString() " <<
static_cast<cppu::OWeakObject*>(this)), 0); } else { ::
std::ostringstream sal_detail_stream; sal_detail_stream <<
"no text selection in getString() " << static_cast<
cppu::OWeakObject*>(this); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/uibase/uno/unotxvw.cxx"
":" "1379" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "no text selection in getString() " << static_cast
<cppu::OWeakObject*>(this)) == 1) { ::sal_detail_log( (
::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/uibase/uno/unotxvw.cxx"
":" "1379" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "no text selection in getString() " <<
static_cast<cppu::OWeakObject*>(this)), 0); } else { ::
std::ostringstream sal_detail_stream; sal_detail_stream <<
"no text selection in getString() " << static_cast<
cppu::OWeakObject*>(this); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("sw.uno"), ("/home/maarten/src/libreoffice/core/sw/source/uibase/uno/unotxvw.cxx"
":" "1379" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1380 return uRet;
1381 }
1382
1383 ShellMode eSelMode = m_pView->GetShellMode();
1384 switch(eSelMode)
1385 {
1386 //! since setString for SEL_TABLE_TEXT (with possible
1387 //! multi selection of cells) would not work properly we
1388 //! will ignore this case for both
1389 //! functions (setString AND getString) because of symmetrie.
1390
1391 case ShellMode::ListText :
1392 case ShellMode::TableListText:
1393 case ShellMode::Text :
1394 {
1395 SwWrtShell& rSh = m_pView->GetWrtShell();
1396 SwPaM* pShellCursor = rSh.GetCursor();
1397 SwUnoCursorHelper::GetTextFromPam(*pShellCursor, uRet,
1398 rSh.GetLayout());
1399 break;
1400 }
1401 default:;//prevent warning
1402 }
1403 }
1404 return uRet;
1405}
1406
1407void SwXTextViewCursor::setString(const OUString& aString)
1408{
1409 SolarMutexGuard aGuard;
1410 if(!m_pView)
1411 return;
1412
1413 if (!IsTextSelection( false ))
1414 throw uno::RuntimeException("no text selection", static_cast < cppu::OWeakObject * > ( this ) );
1415
1416 ShellMode eSelMode = m_pView->GetShellMode();
1417 switch(eSelMode)
1418 {
1419 //! since setString for SEL_TABLE_TEXT (with possible
1420 //! multi selection of cells) would not work properly we
1421 //! will ignore this case for both
1422 //! functions (setString AND getString) because of symmetrie.
1423
1424 case ShellMode::ListText :
1425 case ShellMode::TableListText :
1426 case ShellMode::Text :
1427 {
1428 SwWrtShell& rSh = m_pView->GetWrtShell();
1429 SwCursor* pShellCursor = rSh.GetSwCursor();
1430 SwUnoCursorHelper::SetString(*pShellCursor, aString);
1431 break;
1432 }
1433 default:;//prevent warning
1434 }
1435}
1436
1437uno::Reference< XPropertySetInfo > SwXTextViewCursor::getPropertySetInfo( )
1438{
1439 static uno::Reference< XPropertySetInfo > xRef = m_pPropSet->getPropertySetInfo();
1440 return xRef;
1441}
1442
1443void SwXTextViewCursor::setPropertyValue( const OUString& rPropertyName, const Any& aValue )
1444{
1445 SolarMutexGuard aGuard;
1446 if(!m_pView)
1447 throw RuntimeException();
1448
1449 SwWrtShell& rSh = m_pView->GetWrtShell();
1450 SwPaM* pShellCursor = rSh.GetCursor();
1451 SwNode& rNode = pShellCursor->GetNode();
1452 if (!rNode.IsTextNode())
1453 throw RuntimeException();
1454
1455 SwUnoCursorHelper::SetPropertyValue(
1456 *pShellCursor, *m_pPropSet, rPropertyName, aValue );
1457
1458
1459}
1460
1461Any SwXTextViewCursor::getPropertyValue( const OUString& rPropertyName )
1462{
1463 SolarMutexGuard aGuard;
1464 Any aRet;
1465 if(!m_pView)
1466 throw RuntimeException();
1467
1468 SwWrtShell& rSh = m_pView->GetWrtShell();
1469 SwPaM* pShellCursor = rSh.GetCursor();
1470 aRet = SwUnoCursorHelper::GetPropertyValue(
1471 *pShellCursor, *m_pPropSet, rPropertyName);
1472
1473 return aRet;
1474}
1475
1476void SwXTextViewCursor::addPropertyChangeListener(
1477 const OUString& /*aPropertyName*/, const uno::Reference< XPropertyChangeListener >& /*xListener*/ )
1478{
1479}
1480
1481void SwXTextViewCursor::removePropertyChangeListener(
1482 const OUString& /*aPropertyName*/, const uno::Reference< XPropertyChangeListener >& /*aListener*/ )
1483{
1484}
1485
1486void SwXTextViewCursor::addVetoableChangeListener(
1487 const OUString& /*PropertyName*/, const uno::Reference< XVetoableChangeListener >& /*aListener*/ )
1488{
1489}
1490
1491void SwXTextViewCursor::removeVetoableChangeListener(
1492 const OUString& /*PropertyName*/, const uno::Reference< XVetoableChangeListener >& /*aListener*/ )
1493{
1494}
1495
1496PropertyState SwXTextViewCursor::getPropertyState( const OUString& rPropertyName )
1497{
1498 SolarMutexGuard aGuard;
1499 PropertyState eState;
1500 if(!m_pView)
1501 throw RuntimeException();
1502
1503 SwWrtShell& rSh = m_pView->GetWrtShell();
1504 SwPaM* pShellCursor = rSh.GetCursor();
1505 eState = SwUnoCursorHelper::GetPropertyState(
1506 *pShellCursor, *m_pPropSet, rPropertyName);
1507
1508 return eState;
1509}
1510
1511Sequence< PropertyState > SwXTextViewCursor::getPropertyStates(
1512 const Sequence< OUString >& rPropertyNames )
1513{
1514 SolarMutexGuard aGuard;
1515 Sequence< PropertyState > aRet;
1516 if(m_pView)
1517 {
1518 SwWrtShell& rSh = m_pView->GetWrtShell();
1519 SwPaM* pShellCursor = rSh.GetCursor();
1520 aRet = SwUnoCursorHelper::GetPropertyStates(
1521 *pShellCursor, *m_pPropSet, rPropertyNames);
1522 }
1523 return aRet;
1524}
1525
1526void SwXTextViewCursor::setPropertyToDefault( const OUString& rPropertyName )
1527{
1528 SolarMutexGuard aGuard;
1529 if(m_pView)
1530 {
1531 SwWrtShell& rSh = m_pView->GetWrtShell();
1532 SwPaM* pShellCursor = rSh.GetCursor();
1533 SwUnoCursorHelper::SetPropertyToDefault(
1534 *pShellCursor, *m_pPropSet, rPropertyName);
1535 }
1536}
1537
1538Any SwXTextViewCursor::getPropertyDefault( const OUString& rPropertyName )
1539{
1540 Any aRet;
1541 SolarMutexGuard aGuard;
1542 if(m_pView)
1543 {
1544 SwWrtShell& rSh = m_pView->GetWrtShell();
1545 SwPaM* pShellCursor = rSh.GetCursor();
1546 aRet = SwUnoCursorHelper::GetPropertyDefault(
1547 *pShellCursor, *m_pPropSet, rPropertyName);
1548 }
1549 return aRet;
1550}
1551
1552sal_Bool SwXTextViewCursor::goDown(sal_Int16 nCount, sal_Bool bExpand)
1553{
1554 SolarMutexGuard aGuard;
1555 comphelper::ProfileZone aZone("SwXTextViewCursor::goDown");
1556 bool bRet = false;
1557 if(!m_pView)
1558 throw uno::RuntimeException();
1559
1560 if (!IsTextSelection())
1561 throw uno::RuntimeException("no text selection", static_cast < cppu::OWeakObject * > ( this ) );
1562
1563 bRet = m_pView->GetWrtShell().Down( bExpand, nCount, true );
1564
1565 return bRet;
1566}
1567
1568sal_Bool SwXTextViewCursor::goUp(sal_Int16 nCount, sal_Bool bExpand)
1569{
1570 SolarMutexGuard aGuard;
1571 comphelper::ProfileZone aZone("SwXTextViewCursor::goUp");
1572 bool bRet = false;
1573 if(!m_pView)
1574 throw uno::RuntimeException();
1575
1576 if (!IsTextSelection())
1577 throw uno::RuntimeException("no text selection", static_cast < cppu::OWeakObject * > ( this ) );
1578
1579 bRet = m_pView->GetWrtShell().Up( bExpand, nCount, true );
1580
1581 return bRet;
1582}
1583
1584sal_Bool SwXTextViewCursor::isAtStartOfLine()
1585{
1586 SolarMutexGuard aGuard;
1587 bool bRet = false;
1588 if(!m_pView)
1589 throw uno::RuntimeException();
1590
1591 if (!IsTextSelection( false ))
1592 throw uno::RuntimeException("no text selection", static_cast < cppu::OWeakObject * > ( this ) );
1593
1594 bRet = m_pView->GetWrtShell().IsAtLeftMargin();
1595
1596 return bRet;
1597}
1598
1599sal_Bool SwXTextViewCursor::isAtEndOfLine()
1600{
1601 SolarMutexGuard aGuard;
1602 bool bRet = false;
1603 if(!m_pView)
1604 throw uno::RuntimeException();
1605
1606 if (!IsTextSelection( false ))
1607 throw uno::RuntimeException("no text selection", static_cast < cppu::OWeakObject * > ( this ) );
1608
1609 bRet = m_pView->GetWrtShell().IsAtRightMargin();
1610
1611 return bRet;
1612}
1613
1614void SwXTextViewCursor::gotoEndOfLine(sal_Bool bExpand)
1615{
1616 SolarMutexGuard aGuard;
1617 if(!m_pView)
1618 throw uno::RuntimeException();
1619
1620 if (!IsTextSelection( false ))
1621 throw uno::RuntimeException("no text selection", static_cast < cppu::OWeakObject * > ( this ) );
1622
1623 m_pView->GetWrtShell().RightMargin(bExpand, true);
1624
1625}
1626
1627void SwXTextViewCursor::gotoStartOfLine(sal_Bool bExpand)
1628{
1629 SolarMutexGuard aGuard;
1630 if(!m_pView)
1631 throw uno::RuntimeException();
1632
1633 if (!IsTextSelection( false ))
1634 throw uno::RuntimeException("no text selection", static_cast < cppu::OWeakObject * > ( this ) );
1635
1636 m_pView->GetWrtShell().LeftMargin(bExpand, true);
1637
1638}
1639
1640OUString SwXTextViewCursor::getImplementationName()
1641{
1642 return "SwXTextViewCursor";
1643}
1644
1645sal_Bool SwXTextViewCursor::supportsService(const OUString& rServiceName)
1646{
1647 return cppu::supportsService(this, rServiceName);
1648}
1649
1650Sequence< OUString > SwXTextViewCursor::getSupportedServiceNames()
1651{
1652 return { "com.sun.star.text.TextViewCursor",
1653 "com.sun.star.style.CharacterProperties",
1654 "com.sun.star.style.CharacterPropertiesAsian",
1655 "com.sun.star.style.CharacterPropertiesComplex",
1656 "com.sun.star.style.ParagraphProperties",
1657 "com.sun.star.style.ParagraphPropertiesAsian",
1658 "com.sun.star.style.ParagraphPropertiesComplex" };
1659}
1660
1661namespace
1662{
1663 class theSwXTextViewCursorUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSwXTextViewCursorUnoTunnelId > {};
1664}
1665
1666const uno::Sequence< sal_Int8 > & SwXTextViewCursor::getUnoTunnelId()
1667{
1668 return theSwXTextViewCursorUnoTunnelId::get().getSeq();
1669}
1670
1671//XUnoTunnel
1672sal_Int64 SAL_CALL SwXTextViewCursor::getSomething(
1673 const uno::Sequence< sal_Int8 >& rId )
1674{
1675 if( isUnoTunnelId<SwXTextViewCursor>(rId) )
1676 {
1677 return sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >( this ));
1678 }
1679 return OTextCursorHelper::getSomething(rId);
1680}
1681
1682IMPLEMENT_FORWARD_XINTERFACE2(SwXTextViewCursor,SwXTextViewCursor_Base,OTextCursorHelper)void SwXTextViewCursor::acquire() throw() { SwXTextViewCursor_Base
::acquire(); } void SwXTextViewCursor::release() throw() { SwXTextViewCursor_Base
::release(); } css::uno::Any SwXTextViewCursor::queryInterface
( const css::uno::Type& _rType ) { css::uno::Any aReturn =
SwXTextViewCursor_Base::queryInterface( _rType ); if ( !aReturn
.hasValue() ) aReturn = OTextCursorHelper::queryInterface( _rType
); return aReturn; }
1683const SwDoc* SwXTextViewCursor::GetDoc() const
1684{
1685 SwWrtShell& rSh = m_pView->GetWrtShell();
1686 return rSh.GetCursor() ? &rSh.GetCursor()->GetDoc() : nullptr;
1687}
1688
1689SwDoc* SwXTextViewCursor::GetDoc()
1690{
1691 SwWrtShell& rSh = m_pView->GetWrtShell();
1692 return rSh.GetCursor() ? &rSh.GetCursor()->GetDoc() : nullptr;
1693}
1694
1695const SwPaM* SwXTextViewCursor::GetPaM() const
1696{
1697 SwWrtShell& rSh = m_pView->GetWrtShell();
1698 return rSh.GetCursor();
1699}
1700
1701SwPaM* SwXTextViewCursor::GetPaM()
1702{
1703 SwWrtShell& rSh = m_pView->GetWrtShell();
1704 return rSh.GetCursor();
1705}
1706
1707uno::Reference< datatransfer::XTransferable > SAL_CALL SwXTextView::getTransferable()
1708{
1709 SolarMutexGuard aGuard;
1710
1711 //force immediat shell update
1712 GetView()->StopShellTimer();
1713 SwWrtShell& rSh = GetView()->GetWrtShell();
1714 if ( GetView()->GetShellMode() == ShellMode::DrawText )
1715 {
1716 SdrView *pSdrView = rSh.GetDrawView();
1717 OutlinerView* pOLV = pSdrView->GetTextEditOutlinerView();
1718 return pOLV->GetEditView().GetTransferable();
1719 }
1720 else
1721 {
1722 SwTransferable* pTransfer = new SwTransferable( rSh );
1723 const bool bLockedView = rSh.IsViewLocked();
1724 rSh.LockView( true ); //lock visible section
1725 pTransfer->PrepareForCopy();
1726 rSh.LockView( bLockedView );
1727 return uno::Reference< datatransfer::XTransferable >( pTransfer );
1728 }
1729}
1730
1731void SAL_CALL SwXTextView::insertTransferable( const uno::Reference< datatransfer::XTransferable >& xTrans )
1732{
1733 SolarMutexGuard aGuard;
1734
1735 //force immediat shell update
1736 GetView()->StopShellTimer();
1737 SwWrtShell& rSh = GetView()->GetWrtShell();
1738 if ( GetView()->GetShellMode() == ShellMode::DrawText )
1739 {
1740 SdrView *pSdrView = rSh.GetDrawView();
1741 OutlinerView* pOLV = pSdrView->GetTextEditOutlinerView();
1742 pOLV->GetEditView().InsertText( xTrans, GetView()->GetDocShell()->GetMedium()->GetBaseURL(), false );
1743 }
1744 else
1745 {
1746 TransferableDataHelper aDataHelper( xTrans );
1747 if ( SwTransferable::IsPaste( rSh, aDataHelper ) )
1748 {
1749 SwTransferable::Paste( rSh, aDataHelper );
1750 if( rSh.IsFrameSelected() || rSh.IsObjSelected() )
1751 rSh.EnterSelFrameMode();
1752 GetView()->AttrChangedNotify(nullptr);
1753 }
1754 }
1755}
1756
1757/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/sw/inc/pam.hxx

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#ifndef INCLUDED_SW_INC_PAM_HXX
20#define INCLUDED_SW_INC_PAM_HXX
21
22#include <sal/types.h>
23#include "ring.hxx"
24#include "index.hxx"
25#include "ndindex.hxx"
26#include "swdllapi.h"
27
28#include <iostream>
29
30class SwDoc;
31class SwPaM;
32class Point;
33
34/// Marks a position in the document model.
35struct SAL_WARN_UNUSED__attribute__((warn_unused)) SW_DLLPUBLIC__attribute__ ((visibility("default"))) SwPosition
36{
37 SwNodeIndex nNode;
38 SwIndex nContent;
39
40 SwPosition( const SwNodeIndex &rNode, const SwIndex &rContent );
41 explicit SwPosition( const SwNodeIndex &rNode );
42 explicit SwPosition( const SwNode& rNode );
43 explicit SwPosition( SwContentNode& rNode, const sal_Int32 nOffset = 0 );
44
45 /**
46 Returns the document this position is in.
47
48 @return the document this position is in.
49 */
50 SwDoc& GetDoc() const;
51
52 bool operator < (const SwPosition &) const;
53 bool operator > (const SwPosition &) const;
54 bool operator <=(const SwPosition &) const;
55 bool operator >=(const SwPosition &) const;
56 bool operator ==(const SwPosition &) const;
57 bool operator !=(const SwPosition &) const;
58 void dumpAsXml(xmlTextWriterPtr pWriter) const;
59};
60
61SW_DLLPUBLIC__attribute__ ((visibility("default"))) std::ostream &operator <<(std::ostream& s, const SwPosition& position);
62
63// Result of comparing positions.
64enum class SwComparePosition {
65 Before, ///< Pos1 before Pos2.
66 Behind, ///< Pos1 behind Pos2.
67 Inside, ///< Pos1 completely contained in Pos2.
68 Outside, ///< Pos2 completely contained in Pos1.
69 Equal, ///< Pos1 is as large as Pos2.
70 OverlapBefore, ///< Pos1 overlaps Pos2 at the beginning.
71 OverlapBehind, ///< Pos1 overlaps Pos2 at the end.
72 CollideStart, ///< Pos1 start touches at Pos2 end.
73 CollideEnd ///< Pos1 end touches at Pos2 start.
74};
75
76template<typename T>
77SwComparePosition ComparePosition(
78 const T& rStt1, const T& rEnd1,
79 const T& rStt2, const T& rEnd2 )
80{
81 SwComparePosition nRet;
82 if( rStt1 < rStt2 )
83 {
84 if( rEnd1 > rStt2 )
85 {
86 if( rEnd1 >= rEnd2 )
87 nRet = SwComparePosition::Outside;
88 else
89 nRet = SwComparePosition::OverlapBefore;
90
91 }
92 else if( rEnd1 == rStt2 )
93 nRet = SwComparePosition::CollideEnd;
94 else
95 nRet = SwComparePosition::Before;
96 }
97 else if( rEnd2 > rStt1 )
98 {
99 if( rEnd2 >= rEnd1 )
100 {
101 if( rEnd2 == rEnd1 && rStt2 == rStt1 )
102 nRet = SwComparePosition::Equal;
103 else
104 nRet = SwComparePosition::Inside;
105 }
106 else
107 {
108 if (rStt1 == rStt2)
109 nRet = SwComparePosition::Outside;
110 else
111 nRet = SwComparePosition::OverlapBehind;
112 }
113 }
114 else if( rEnd2 == rStt1 )
115 nRet = SwComparePosition::CollideStart;
116 else
117 nRet = SwComparePosition::Behind;
118 return nRet;
119}
120
121/// SwPointAndMark / SwPaM
122struct SwMoveFnCollection;
123SW_DLLPUBLIC__attribute__ ((visibility("default"))) extern SwMoveFnCollection const & fnMoveForward; ///< SwPam::Move()/Find() default argument.
124SW_DLLPUBLIC__attribute__ ((visibility("default"))) extern SwMoveFnCollection const & fnMoveBackward;
125
126using SwGoInDoc = auto (*)(SwPaM& rPam, SwMoveFnCollection const & fnMove) -> bool;
127SW_DLLPUBLIC__attribute__ ((visibility("default"))) bool GoInDoc( SwPaM&, SwMoveFnCollection const &);
128bool GoInSection( SwPaM&, SwMoveFnCollection const &);
129SW_DLLPUBLIC__attribute__ ((visibility("default"))) bool GoInNode( SwPaM&, SwMoveFnCollection const &);
130SW_DLLPUBLIC__attribute__ ((visibility("default"))) bool GoInContent( SwPaM&, SwMoveFnCollection const &);
131bool GoInContentCells( SwPaM&, SwMoveFnCollection const &);
132bool GoInContentSkipHidden( SwPaM&, SwMoveFnCollection const &);
133bool GoInContentCellsSkipHidden( SwPaM&, SwMoveFnCollection const &);
134
135/// PaM is Point and Mark: a selection of the document model.
136class SAL_WARN_UNUSED__attribute__((warn_unused)) SW_DLLPUBLIC__attribute__ ((visibility("default"))) SwPaM : public sw::Ring<SwPaM>
137{
138 SwPosition m_Bound1;
139 SwPosition m_Bound2;
140 SwPosition * m_pPoint; ///< points at either m_Bound1 or m_Bound2
141 SwPosition * m_pMark; ///< points at either m_Bound1 or m_Bound2
142 bool m_bIsInFrontOfLabel;
143
144 SwPaM(SwPaM const& rPaM) = delete;
145
146public:
147 explicit SwPaM( const SwPosition& rPos, SwPaM* pRing = nullptr );
148 SwPaM( const SwPosition& rMk, const SwPosition& rPt, SwPaM* pRing = nullptr );
149 SwPaM( const SwNodeIndex& rMk, const SwNodeIndex& rPt,
150 long nMkOffset = 0, long nPtOffset = 0, SwPaM* pRing = nullptr );
151 SwPaM( const SwNode& rMk, const SwNode& rPt,
152 long nMkOffset = 0, long nPtOffset = 0, SwPaM* pRing = nullptr );
153 SwPaM( const SwNodeIndex& rMk, sal_Int32 nMkContent,
154 const SwNodeIndex& rPt, sal_Int32 nPtContent, SwPaM* pRing = nullptr );
155 SwPaM( const SwNode& rMk, sal_Int32 nMkContent,
156 const SwNode& rPt, sal_Int32 nPtContent, SwPaM* pRing = nullptr );
157 SwPaM( const SwNode& rNd, sal_Int32 nContent = 0, SwPaM* pRing = nullptr );
158 SwPaM( const SwNodeIndex& rNd, sal_Int32 nContent = 0, SwPaM* pRing = nullptr );
159 virtual ~SwPaM() override;
160
161 /// this takes a second parameter, which indicates the Ring that
162 /// the new PaM should be part of (may be null)
163 SwPaM(SwPaM const& rPaM, SwPaM * pRing);
164 /// @@@ semantic: no copy assignment for super class Ring.
165 SwPaM& operator=( const SwPaM & );
166
167 /// Movement of cursor.
168 bool Move( SwMoveFnCollection const & fnMove = fnMoveForward,
169 SwGoInDoc fnGo = GoInContent );
170
171 bool IsInFrontOfLabel() const { return m_bIsInFrontOfLabel; }
172 void SetInFrontOfLabel_( bool bNew ) { m_bIsInFrontOfLabel = bNew; }
173
174 /// Unless this is called, the getter method of Mark will return Point.
175 virtual void SetMark();
176
177 void DeleteMark()
178 {
179 if (m_pMark != m_pPoint)
180 {
181 /** clear the mark position; this helps if mark's SwIndex is
182 registered at some node, and that node is then deleted */
183 *m_pMark = SwPosition( SwNodeIndex( GetNode().GetNodes() ) );
184 m_pMark = m_pPoint;
185 }
186 }
187#ifdef DBG_UTIL
188 void Exchange();
189
190#else
191 void Exchange()
192 {
193 if (m_pPoint != m_pMark)
194 {
195 SwPosition *pTmp = m_pPoint;
196 m_pPoint = m_pMark;
197 m_pMark = pTmp;
198 }
199 }
200#endif
201
202 /** A PaM marks a selection if Point and Mark are distinct positions.
203 @return true if the PaM spans a selection
204 */
205 bool HasMark() const { return m_pPoint != m_pMark; }
206
207 const SwPosition *GetPoint() const { return m_pPoint; }
208 SwPosition *GetPoint() { return m_pPoint; }
209 const SwPosition *GetMark() const { return m_pMark; }
210 SwPosition *GetMark() { return m_pMark; }
211
212 const SwPosition *Start() const
213 { return (*m_pPoint) <= (*m_pMark) ? m_pPoint : m_pMark; }
214 SwPosition *Start()
215 { return (*m_pPoint) <= (*m_pMark) ? m_pPoint : m_pMark; }
216
217 const SwPosition *End() const
218 { return (*m_pPoint) > (*m_pMark) ? m_pPoint : m_pMark; }
219 SwPosition *End()
220 { return (*m_pPoint) > (*m_pMark) ? m_pPoint : m_pMark; }
221
222 /// @return current Node at Point/Mark
223 SwNode & GetNode ( bool bPoint = true ) const
224 {
225 return ( bPoint ? m_pPoint->nNode : m_pMark->nNode ).GetNode();
226 }
227
228 /// @return current ContentNode at Point/Mark
229 SwContentNode* GetContentNode( bool bPoint = true ) const
230 {
231 return GetNode(bPoint).GetContentNode();
232 }
233
234 /**
235 Normalizes PaM, i.e. sort point and mark.
236
237 @param bPointFirst true: If the point is behind the mark then swap.
238 false: If the mark is behind the point then swap.
239 */
240 void Normalize(bool bPointFirst = true);
241
242 /// @return the document (SwDoc) at which the PaM is registered
243 SwDoc& GetDoc() const { return m_pPoint->nNode.GetNode().GetDoc(); }
244
245 SwPosition& GetBound( bool bOne = true )
246 { return bOne ? m_Bound1 : m_Bound2; }
247 const SwPosition& GetBound( bool bOne = true ) const
248 { return bOne ? m_Bound1 : m_Bound2; }
249
250 /// Get number of page which contains cursor.
251 sal_uInt16 GetPageNum( bool bAtPoint = true, const Point* pLayPos = nullptr );
252
253 /** Is in something protected (readonly) or selection contains
254 something protected. */
255 bool HasReadonlySel( bool bFormView ) const;
256
257 bool ContainsPosition(const SwPosition & rPos) const
258 {
259 return *Start() <= rPos && rPos <= *End();
260 }
261
262 OUString GetText() const;
263 void InvalidatePaM();
264 SwPaM* GetNext()
265 { return GetNextInRing(); }
11
Calling 'Ring::GetNextInRing'
266 const SwPaM* GetNext() const
267 { return GetNextInRing(); }
268 SwPaM* GetPrev()
269 { return GetPrevInRing(); }
270 const SwPaM* GetPrev() const
271 { return GetPrevInRing(); }
272 bool IsMultiSelection() const
273 { return !unique(); }
274
275 void dumpAsXml(xmlTextWriterPtr pWriter) const;
276};
277
278SW_DLLPUBLIC__attribute__ ((visibility("default"))) std::ostream &operator <<(std::ostream& s, const SwPaM& pam);
279
280bool CheckNodesRange(const SwNodeIndex&, const SwNodeIndex&, bool bChkSection);
281
282#endif // INCLUDED_SW_INC_PAM_HXX
283
284/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/sw/inc/ring.hxx

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#ifndef INCLUDED_SW_INC_RING_HXX
20#define INCLUDED_SW_INC_RING_HXX
21
22#include <utility>
23#include <sal/types.h>
24#include <iterator>
25#include <type_traits>
26#include <boost/iterator/iterator_facade.hpp>
27#include <boost/intrusive/circular_list_algorithms.hpp>
28
29namespace sw
30{
31 template <typename value_type> class RingContainer;
32 template <typename value_type> class RingIterator;
33 /**
34 * An intrusive container class double linking the contained nodes
35 * @example sw/qa/core/uwriter.cxx
36 */
37 template <typename value_type>
38 class SAL_WARN_UNUSED__attribute__((warn_unused)) Ring
39 {
40 public:
41 typedef typename std::add_const<value_type>::type const_value_type;
42 typedef RingContainer<value_type> ring_container;
43 typedef RingContainer<const_value_type> const_ring_container;
44 virtual ~Ring() COVERITY_NOEXCEPT_FALSE
45 { unlink(); };
46 /** algo::unlink is buggy! don't call it directly! */
47 void unlink()
48 {
49 algo::unlink(this);
50 m_pNext = this; // don't leave pointers to old list behind!
51 m_pPrev = this;
52 }
53 /**
54 * Removes this item from its current ring container and adds it to
55 * another ring container. If the item was not alone in the original
56 * ring container, the other items in the ring will stay in the old
57 * ring container.
58 * Note: the newly created item will be inserted just before item pDestRing.
59 * @param pDestRing the container to add this item to
60 */
61 void MoveTo( value_type* pDestRing );
62 /** @return a stl-like container with begin()/end() for iteration */
63 ring_container GetRingContainer();
64 /** @return a stl-like container with begin()/end() for const iteration */
65 const_ring_container GetRingContainer() const;
66
67 protected:
68 /**
69 * Creates a new item in a ring container all by itself.
70 * Note: Ring instances can newer be outside a container. At most, they
71 * are alone in one.
72 */
73 Ring()
74 : m_pNext(this)
75 , m_pPrev(this)
76 { }
77 /**
78 * Creates a new item and add it to an existing ring container.
79 * Note: the newly created item will be inserted just before item pRing.
80 * @param pRing ring container to add the created item to
81 */
82 Ring( value_type* pRing );
83 /** @return the next item in the ring container */
84 value_type* GetNextInRing()
85 { return static_cast<value_type *>(m_pNext); }
12
Use of memory after it is freed
86 /** @return the previous item in the ring container */
87 value_type* GetPrevInRing()
88 { return static_cast<value_type *>(m_pPrev); }
89 /** @return the next item in the ring container */
90 const_value_type* GetNextInRing() const
91 { return static_cast<value_type *>(m_pNext); }
92 /** @return the previous item in the ring container */
93 const_value_type* GetPrevInRing() const
94 { return static_cast<value_type *>(m_pPrev); }
95 /** @return true if and only if this item is alone in its ring */
96 bool unique() const
97 { return algo::unique(static_cast< const_value_type* >(this)); }
98
99 private:
100 /** internal implementation class -- not for external use */
101 struct Ring_node_traits
102 {
103 typedef Ring node;
104 typedef Ring* node_ptr;
105 typedef const Ring* const_node_ptr;
106 static node_ptr get_next(const_node_ptr n) { return const_cast<node_ptr>(n)->m_pNext; };
107 static void set_next(node_ptr n, node_ptr next) { n->m_pNext = next; };
108 static node_ptr get_previous(const_node_ptr n) { return const_cast<node_ptr>(n)->m_pPrev; };
109 static void set_previous(node_ptr n, node_ptr previous) { n->m_pPrev = previous; };
110 };
111 friend ring_container;
112 friend const_ring_container;
113 friend typename ring_container::iterator;
114 friend typename ring_container::const_iterator;
115 friend typename const_ring_container::iterator;
116 friend typename const_ring_container::const_iterator;
117 friend class boost::iterator_core_access;
118 typedef boost::intrusive::circular_list_algorithms<Ring_node_traits> algo;
119 Ring* m_pNext;
120 Ring* m_pPrev;
121 };
122
123 template <typename value_type>
124 inline Ring<value_type>::Ring( value_type* pObj )
125 : m_pNext(this)
126 , m_pPrev(this)
127 {
128 if( pObj )
129 {
130 algo::link_before(pObj, this);
131 }
132 }
133
134 template <typename value_type>
135 inline void Ring<value_type>::MoveTo(value_type* pDestRing)
136 {
137 value_type* pThis = static_cast< value_type* >(this);
138 unlink();
139 // insert into "new"
140 if (pDestRing)
141 {
142 algo::link_before(pDestRing, pThis);
143 }
144 }
145
146 /**
147 * helper class that provides Svalue_typeL-style container iteration to the ring
148 */
149 template <typename value_type>
150 class SAL_WARN_UNUSED__attribute__((warn_unused)) RingContainer final
151 {
152 private:
153 /** the item in the ring where iteration starts */
154 value_type* m_pStart;
155 typedef typename std::remove_const<value_type>::type nonconst_value_type;
156
157 public:
158 RingContainer( value_type* pRing ) : m_pStart(pRing) {};
159 typedef RingIterator<value_type> iterator;
160 typedef RingIterator<const value_type> const_iterator;
161 /**
162 * iterator access
163 * @code
164 * for(SwPaM& rCurrentPaM : pPaM->GetRingContainer())
165 * do_stuff(rCurrentPaM); // this gets called on every SwPaM in the same ring as pPaM
166 * @endcode
167 */
168 iterator begin();
169 iterator end();
170 const_iterator begin() const;
171 const_iterator end() const;
172 /** @return the number of elements in the container */
173 size_t size() const
174 { return std::distance(begin(), end()); }
175 /**
176 * Merges two ring containers. All item from both ring containers will
177 * be in the same ring container in the end.
178 * Note: The items of this ring container will be inserted just before
179 * item pDestRing
180 * @param pDestRing the container to merge this container with
181 */
182 void merge( RingContainer< value_type > aDestRing )
183 {
184 // first check that we aren't merged already, swapping would
185 // actually un-merge in this case!
186 assert(m_pStart->m_pPrev != aDestRing.m_pStart)(static_cast <bool> (m_pStart->m_pPrev != aDestRing.
m_pStart) ? void (0) : __assert_fail ("m_pStart->m_pPrev != aDestRing.m_pStart"
, "/home/maarten/src/libreoffice/core/sw/inc/ring.hxx", 186, __extension__
__PRETTY_FUNCTION__))
;
187 assert(m_pStart != aDestRing.m_pStart->m_pPrev)(static_cast <bool> (m_pStart != aDestRing.m_pStart->
m_pPrev) ? void (0) : __assert_fail ("m_pStart != aDestRing.m_pStart->m_pPrev"
, "/home/maarten/src/libreoffice/core/sw/inc/ring.hxx", 187, __extension__
__PRETTY_FUNCTION__))
;
188 std::swap(m_pStart->m_pPrev->m_pNext, aDestRing.m_pStart->m_pPrev->m_pNext);
189 std::swap(m_pStart->m_pPrev, aDestRing.m_pStart->m_pPrev);
190 }
191 };
192
193 template <typename value_type>
194 class RingIterator final : public boost::iterator_facade<
195 RingIterator<value_type>
196 , value_type
197 , boost::forward_traversal_tag
198 >
199 {
200 private:
201 typedef typename std::remove_const<value_type>::type nonconst_value_type;
202 public:
203 RingIterator()
204 : m_pCurrent(nullptr)
205 , m_pStart(nullptr)
206 {}
207 explicit RingIterator(nonconst_value_type* pRing, bool bStart = true)
208 : m_pCurrent(nullptr)
209 , m_pStart(pRing)
210 {
211 if(!bStart)
212 m_pCurrent = m_pStart;
213 }
214
215 private:
216 friend class boost::iterator_core_access;
217 void increment()
218 { m_pCurrent = m_pCurrent ? m_pCurrent->GetNextInRing() : m_pStart->GetNextInRing(); }
219 bool equal(RingIterator const& other) const
220 {
221 // we never want to compare iterators from
222 // different rings or starting points
223 assert(m_pStart == other.m_pStart)(static_cast <bool> (m_pStart == other.m_pStart) ? void
(0) : __assert_fail ("m_pStart == other.m_pStart", "/home/maarten/src/libreoffice/core/sw/inc/ring.hxx"
, 223, __extension__ __PRETTY_FUNCTION__))
;
224 return m_pCurrent == other.m_pCurrent;
225 }
226 value_type& dereference() const
227 { return m_pCurrent ? *m_pCurrent : * m_pStart; }
228 /**
229 * value_type is:
230 * - pointing to the current item in the iteration in general
231 * - nullptr if on the first item (begin())
232 * - m_pStart when beyond the last item (end())
233 */
234 nonconst_value_type* m_pCurrent;
235 /** the first item of the iteration */
236 nonconst_value_type* m_pStart;
237 };
238
239 template <typename value_type>
240 inline typename Ring<value_type>::ring_container Ring<value_type>::GetRingContainer()
241 { return Ring<value_type>::ring_container(static_cast< value_type* >(this)); };
242
243 template <typename value_type>
244 inline typename Ring<value_type>::const_ring_container Ring<value_type>::GetRingContainer() const
245 { return Ring<value_type>::const_ring_container(static_cast< const_value_type* >(this)); };
246
247 template <typename value_type>
248 inline typename RingContainer<value_type>::iterator RingContainer<value_type>::begin()
249 { return RingContainer<value_type>::iterator(const_cast< nonconst_value_type* >(m_pStart)); };
250
251 template <typename value_type>
252 inline typename RingContainer<value_type>::iterator RingContainer<value_type>::end()
253 { return RingContainer<value_type>::iterator(const_cast< nonconst_value_type* >(m_pStart), false); };
254
255 template <typename value_type>
256 inline typename RingContainer<value_type>::const_iterator RingContainer<value_type>::begin() const
257 { return RingContainer<value_type>::const_iterator(const_cast< nonconst_value_type* >(m_pStart)); };
258
259 template <typename value_type>
260 inline typename RingContainer<value_type>::const_iterator RingContainer<value_type>::end() const
261 { return RingContainer<value_type>::const_iterator(const_cast< nonconst_value_type* >(m_pStart), false); };
262}
263#endif
264
265/* vim:set shiftwidth=4 softtabstop=4 expandtab: */