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