LibreOffice Module sd (master) 1
annotationmanager.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <com/sun/star/drawing/XDrawView.hpp>
21#include <com/sun/star/frame/XController.hpp>
22#include <com/sun/star/geometry/RealPoint2D.hpp>
23#include <com/sun/star/text/XText.hpp>
24#include <com/sun/star/document/XEventBroadcaster.hpp>
25#include <com/sun/star/office/XAnnotationAccess.hpp>
26#include <comphelper/lok.hxx>
27#include <svx/svxids.hrc>
28
29#include <vcl/settings.hxx>
30#include <vcl/svapp.hxx>
31#include <vcl/weld.hxx>
32
33#include <sal/macros.h>
34#include <svl/itempool.hxx>
35#include <svl/intitem.hxx>
39#include <unotools/saveopt.hxx>
40
41#include <tools/datetime.hxx>
44
45#include <sfx2/viewfrm.hxx>
46#include <sfx2/bindings.hxx>
47#include <sfx2/request.hxx>
48#include <sfx2/dispatch.hxx>
49
50#include <editeng/editeng.hxx>
51#include <editeng/eeitem.hxx>
52#include <editeng/fontitem.hxx>
53#include <editeng/fhgtitem.hxx>
54#include <editeng/outlobj.hxx>
55#include <editeng/postitem.hxx>
56
57#include <svx/postattr.hxx>
58
59#include <annotationmanager.hxx>
61#include "annotationwindow.hxx"
62#include <strings.hrc>
63
64#include <Annotation.hxx>
65#include <DrawDocShell.hxx>
66#include <DrawViewShell.hxx>
67#include <sdresid.hxx>
68#include <EventMultiplexer.hxx>
69#include <ViewShellBase.hxx>
70#include <sdpage.hxx>
71#include <drawdoc.hxx>
72#include <textapi.hxx>
73#include <optsitem.hxx>
74#include <sdmod.hxx>
75
76#include <memory>
77
78using namespace ::com::sun::star;
79using namespace ::com::sun::star::uno;
80using namespace ::com::sun::star::drawing;
81using namespace ::com::sun::star::document;
82using namespace ::com::sun::star::geometry;
83using namespace ::com::sun::star::container;
84using namespace ::com::sun::star::beans;
85using namespace ::com::sun::star::text;
86using namespace ::com::sun::star::view;
87using namespace ::com::sun::star::style;
88using namespace ::com::sun::star::frame;
89using namespace ::com::sun::star::lang;
90using namespace ::com::sun::star::ui;
91using namespace ::com::sun::star::task;
92using namespace ::com::sun::star::office;
93
94namespace sd {
95
97{
98 static rtl::Reference<SfxItemPool> s_pAnnotationPool;
99 if( !s_pAnnotationPool )
100 {
101 s_pAnnotationPool = EditEngine::CreatePool();
102 s_pAnnotationPool->SetPoolDefaultItem(SvxFontHeightItem(423,100,EE_CHAR_FONTHEIGHT));
103
104 vcl::Font aAppFont( Application::GetSettings().GetStyleSettings().GetAppFont() );
105 s_pAnnotationPool->SetPoolDefaultItem(SvxFontItem(aAppFont.GetFamilyType(),aAppFont.GetFamilyName(),"",PITCH_DONTKNOW,RTL_TEXTENCODING_DONTKNOW,EE_CHAR_FONTINFO));
106 }
107
108 return s_pAnnotationPool.get();
109}
110
111static SfxBindings* getBindings( ViewShellBase const & rBase )
112{
113 if( rBase.GetMainViewShell() && rBase.GetMainViewShell()->GetViewFrame() )
114 return &rBase.GetMainViewShell()->GetViewFrame()->GetBindings();
115
116 return nullptr;
117}
118
120{
121 if( rBase.GetMainViewShell() && rBase.GetMainViewShell()->GetViewFrame() )
122 return rBase.GetMainViewShell()->GetViewFrame()->GetDispatcher();
123
124 return nullptr;
125}
126
127css::util::DateTime getCurrentDateTime()
128{
129 DateTime aCurrentDate( DateTime::SYSTEM );
130 return css::util::DateTime( 0, aCurrentDate.GetSec(),
131 aCurrentDate.GetMin(), aCurrentDate.GetHour(),
132 aCurrentDate.GetDay(), aCurrentDate.GetMonth(),
133 aCurrentDate.GetYear(), false );
134}
135
136OUString getAnnotationDateTimeString( const Reference< XAnnotation >& xAnnotation )
137{
138 OUString sRet;
139 if( xAnnotation.is() )
140 {
141 const SvtSysLocale aSysLocale;
142 const LocaleDataWrapper& rLocalData = aSysLocale.GetLocaleData();
143
144 css::util::DateTime aDateTime( xAnnotation->getDateTime() );
145
146 Date aSysDate( Date::SYSTEM );
147 Date aDate( aDateTime.Day, aDateTime.Month, aDateTime.Year );
148 if (aDate==aSysDate)
149 sRet = SdResId(STR_ANNOTATION_TODAY);
150 else if (aDate == (aSysDate-1))
151 sRet = SdResId(STR_ANNOTATION_YESTERDAY);
152 else if (aDate.IsValidAndGregorian() )
153 sRet = rLocalData.getDate(aDate);
154
155 ::tools::Time aTime( aDateTime );
156 if(aTime.GetTime() != 0)
157 sRet += " " + rLocalData.getTime( aTime,false );
158 }
159 return sRet;
160}
161
163: mrBase( rViewShellBase )
164, mpDoc( rViewShellBase.GetDocument() )
165, mbShowAnnotations( true )
166, mnUpdateTagsEvent( nullptr )
167{
168 SdOptions* pOptions = SD_MOD()->GetSdOptions(mpDoc->GetDocumentType());
169 if( pOptions )
170 mbShowAnnotations = pOptions->IsShowComments();
171}
172
174{
175 // get current controller and initialize listeners
176 try
177 {
178 addListener();
179 mxView.set(mrBase.GetController(), UNO_QUERY);
180 }
181 catch( Exception& )
182 {
183 TOOLS_WARN_EXCEPTION( "sd", "sd::AnnotationManagerImpl::AnnotationManagerImpl()" );
184 }
185
186 try
187 {
188 Reference<XEventBroadcaster> xModel (mrBase.GetDocShell()->GetModel(), UNO_QUERY_THROW );
189 Reference<XEventListener> xListener( this );
190 xModel->addEventListener( xListener );
191 }
192 catch( Exception& )
193 {
194 }
195}
196
197// WeakComponentImplHelper
198void AnnotationManagerImpl::disposing (std::unique_lock<std::mutex>&)
199{
200 try
201 {
202 Reference<XEventBroadcaster> xModel (mrBase.GetDocShell()->GetModel(), UNO_QUERY_THROW );
203 Reference<XEventListener> xListener( this );
204 xModel->removeEventListener( xListener );
205 }
206 catch( Exception& )
207 {
208 }
209
211 DisposeTags();
212
214 {
216 mnUpdateTagsEvent = nullptr;
217 }
218
219 mxView.clear();
220 mxCurrentPage.clear();
221}
222
223// XEventListener
224void SAL_CALL AnnotationManagerImpl::notifyEvent( const css::document::EventObject& aEvent )
225{
226 if( !(aEvent.EventName == "OnAnnotationInserted" || aEvent.EventName == "OnAnnotationRemoved" || aEvent.EventName == "OnAnnotationChanged") )
227 return;
228
229 // AnnotationInsertion and modification is not handled here because when
230 // a new annotation is inserted, it consists of OnAnnotationInserted
231 // followed by a chain of OnAnnotationChanged (called for setting each
232 // of the annotation attributes - author, text etc.). This is not what a
233 // LOK client wants. So only handle removal here as annotation removal
234 // consists of only one event - 'OnAnnotationRemoved'
235 if ( aEvent.EventName == "OnAnnotationRemoved" )
236 {
237 Reference< XAnnotation > xAnnotation( aEvent.Source, uno::UNO_QUERY );
238 if ( xAnnotation.is() )
239 {
241 }
242 }
243
244 UpdateTags();
245}
246
247void SAL_CALL AnnotationManagerImpl::disposing( const css::lang::EventObject& /*Source*/ )
248{
249}
250
251Reference<XAnnotation> AnnotationManagerImpl::GetAnnotationById(sal_uInt32 nAnnotationId)
252{
253 SdPage* pPage = nullptr;
254 do
255 {
256 pPage = GetNextPage(pPage, true);
257 if( pPage && !pPage->getAnnotations().empty() )
258 {
259 AnnotationVector aAnnotations(pPage->getAnnotations());
260 auto iter = std::find_if(aAnnotations.begin(), aAnnotations.end(),
261 [nAnnotationId](const Reference<XAnnotation>& xAnnotation) {
262 return sd::getAnnotationId(xAnnotation) == nAnnotationId;
263 });
264 if (iter != aAnnotations.end())
265 return *iter;
266 }
267 } while( pPage );
268
269 Reference<XAnnotation> xAnnotationEmpty;
270 return xAnnotationEmpty;
271}
272
274{
275 // enforce show annotations if a new annotation is inserted
276 if( mbShowAnnotations != bShow )
277 {
278 mbShowAnnotations = bShow;
279
280 SdOptions* pOptions = SD_MOD()->GetSdOptions(mpDoc->GetDocumentType());
281 if( pOptions )
283
284 UpdateTags();
285 }
286}
287
289{
290 switch( rReq.GetSlot() )
291 {
292 case SID_INSERT_POSTIT:
294 break;
295 case SID_DELETE_POSTIT:
296 case SID_DELETEALL_POSTIT:
297 case SID_DELETEALLBYAUTHOR_POSTIT:
299 break;
300 case SID_EDIT_POSTIT:
301 ExecuteEditAnnotation( rReq );
302 break;
303 case SID_PREVIOUS_POSTIT:
304 case SID_NEXT_POSTIT:
305 SelectNextAnnotation( rReq.GetSlot() == SID_NEXT_POSTIT );
306 break;
307 case SID_REPLYTO_POSTIT:
309 break;
310 case SID_TOGGLE_NOTES:
312 break;
313 }
314}
315
317{
319 ShowAnnotations(true);
320
321 const SfxItemSet* pArgs = rReq.GetArgs();
322 OUString sText;
323 if (pArgs)
324 {
325 if (const SfxStringItem* pPoolItem = pArgs->GetItemIfSet(SID_ATTR_POSTIT_TEXT))
326 {
327 sText = pPoolItem->GetValue();
328 }
329 }
330
331 InsertAnnotation(sText);
332}
333
335{
336 ShowAnnotations( true );
337
338 const SfxItemSet* pArgs = rReq.GetArgs();
339
340 switch( rReq.GetSlot() )
341 {
342 case SID_DELETEALL_POSTIT:
344 break;
345 case SID_DELETEALLBYAUTHOR_POSTIT:
346 if( pArgs )
347 {
348 const SfxPoolItem* pPoolItem = nullptr;
349 if( SfxItemState::SET == pArgs->GetItemState( SID_DELETEALLBYAUTHOR_POSTIT, true, &pPoolItem ) )
350 {
351 OUString sAuthor( static_cast<const SfxStringItem*>( pPoolItem )->GetValue() );
352 DeleteAnnotationsByAuthor( sAuthor );
353 }
354 }
355 break;
356 case SID_DELETE_POSTIT:
357 {
358 Reference< XAnnotation > xAnnotation;
359 sal_uInt32 nId = 0;
360 if( pArgs )
361 {
362 const SfxPoolItem* pPoolItem = nullptr;
363 if( SfxItemState::SET == pArgs->GetItemState( SID_DELETE_POSTIT, true, &pPoolItem ) )
364 static_cast<const SfxUnoAnyItem*>(pPoolItem)->GetValue() >>= xAnnotation;
365 if( SfxItemState::SET == pArgs->GetItemState( SID_ATTR_POSTIT_ID, true, &pPoolItem ) )
366 nId = static_cast<const SvxPostItIdItem*>(pPoolItem)->GetValue().toUInt32();
367 }
368
369 if (nId != 0)
370 xAnnotation = GetAnnotationById(nId);
371 else if( !xAnnotation.is() )
372 GetSelectedAnnotation( xAnnotation );
373
374 DeleteAnnotation( xAnnotation );
375 }
376 break;
377 }
378
379 UpdateTags();
380}
381
383{
384 const SfxItemSet* pArgs = rReq.GetArgs();
385 Reference< XAnnotation > xAnnotation;
386 OUString sText;
387 sal_Int32 nPositionX = -1;
388 sal_Int32 nPositionY = -1;
389
390 if (!pArgs)
391 return;
392
393 if (mpDoc->IsUndoEnabled())
394 mpDoc->BegUndo(SdResId(STR_ANNOTATION_UNDO_EDIT));
395
396 if (const SvxPostItIdItem* pPoolItem = pArgs->GetItemIfSet(SID_ATTR_POSTIT_ID))
397 {
398 sal_uInt32 nId = pPoolItem->GetValue().toUInt32();
399 xAnnotation = GetAnnotationById(nId);
400 }
401 if (const SfxStringItem* pPoolItem = pArgs->GetItemIfSet(SID_ATTR_POSTIT_TEXT))
402 sText = pPoolItem->GetValue();
403
404 if (const SfxInt32Item* pPoolItem = pArgs->GetItemIfSet(SID_ATTR_POSTIT_POSITION_X))
405 nPositionX = pPoolItem->GetValue();
406
407 if (const SfxInt32Item* pPoolItem = pArgs->GetItemIfSet(SID_ATTR_POSTIT_POSITION_Y))
408 nPositionY = pPoolItem->GetValue();
409
410 if (xAnnotation.is())
411 {
412 CreateChangeUndo(xAnnotation);
413
414 if (nPositionX >= 0 && nPositionY >= 0)
415 {
416 double fX = convertTwipToMm100(nPositionX) / 100.0;
417 double fY = convertTwipToMm100(nPositionY) / 100.0;
418 xAnnotation->setPosition({fX, fY});
419 }
420
421 if (!sText.isEmpty())
422 {
423 // TODO: Not allow other authors to change others' comments ?
424 Reference<XText> xText(xAnnotation->getTextRange());
425 xText->setString(sText);
426 }
427
429 }
430
431 if (mpDoc->IsUndoEnabled())
432 mpDoc->EndUndo();
433
434 UpdateTags(true);
435}
436
438{
439 SdPage* pPage = GetCurrentPage();
440 if( !pPage )
441 return;
442
443 if( mpDoc->IsUndoEnabled() )
444 mpDoc->BegUndo( SdResId( STR_ANNOTATION_UNDO_INSERT ) );
445
446 // find free space for new annotation
447 int y = 0, x = 0;
448
449 AnnotationVector aAnnotations( pPage->getAnnotations() );
450 if( !aAnnotations.empty() )
451 {
452 const int page_width = pPage->GetSize().Width();
453 const int width = 1000;
454 const int height = 800;
455 ::tools::Rectangle aTagRect;
456
457 while( true )
458 {
459 ::tools::Rectangle aNewRect( x, y, x + width - 1, y + height - 1 );
460 bool bFree = true;
461
462 for( const auto& rxAnnotation : aAnnotations )
463 {
464 RealPoint2D aPoint( rxAnnotation->getPosition() );
465 aTagRect.SetLeft( sal::static_int_cast< ::tools::Long >( aPoint.X * 100.0 ) );
466 aTagRect.SetTop( sal::static_int_cast< ::tools::Long >( aPoint.Y * 100.0 ) );
467 aTagRect.SetRight( aTagRect.Left() + width - 1 );
468 aTagRect.SetBottom( aTagRect.Top() + height - 1 );
469
470 if( aNewRect.Overlaps( aTagRect ) )
471 {
472 bFree = false;
473 break;
474 }
475 }
476
477 if( !bFree )
478 {
479 x += width;
480 if( x > page_width )
481 {
482 x = 0;
483 y += height;
484 }
485 }
486 else
487 {
488 break;
489 }
490 }
491 }
492
493 Reference< XAnnotation > xAnnotation;
494 pPage->createAnnotation( xAnnotation );
495
496 OUString sAuthor;
498 sAuthor = mrBase.GetMainViewShell()->GetView()->GetAuthor();
499 else
500 {
501 SvtUserOptions aUserOptions;
502 sAuthor = aUserOptions.GetFullName();
503 xAnnotation->setInitials( aUserOptions.GetID() );
504 }
505
506 if (!rText.isEmpty())
507 {
508 Reference<XText> xText(xAnnotation->getTextRange());
509 xText->setString(rText);
510 }
511
512 // set current author to new annotation
513 xAnnotation->setAuthor( sAuthor );
514 // set current time to new annotation
515 xAnnotation->setDateTime( getCurrentDateTime() );
516
517 // set position
518 RealPoint2D aPos( static_cast<double>(x) / 100.0, static_cast<double>(y) / 100.0 );
519 xAnnotation->setPosition( aPos );
520
521 if( mpDoc->IsUndoEnabled() )
522 mpDoc->EndUndo();
523
524 // Tell our LOK clients about new comment added
526
527 UpdateTags(true);
528 SelectAnnotation( xAnnotation, true );
529}
530
532{
533 Reference< XAnnotation > xAnnotation;
534 const SfxItemSet* pArgs = rReq.GetArgs();
535 OUString sReplyText;
536 if( pArgs )
537 {
538 const SfxPoolItem* pPoolItem = nullptr;
539 if( SfxItemState::SET == pArgs->GetItemState( SID_ATTR_POSTIT_ID, true, &pPoolItem ) )
540 {
541 sal_uInt32 nReplyId = 0; // Id of the comment to reply to
542 nReplyId = static_cast<const SvxPostItIdItem*>(pPoolItem)->GetValue().toUInt32();
543 xAnnotation = GetAnnotationById(nReplyId);
544 }
545 else if( SfxItemState::SET == pArgs->GetItemState( rReq.GetSlot(), true, &pPoolItem ) )
546 static_cast<const SfxUnoAnyItem*>( pPoolItem )->GetValue() >>= xAnnotation;
547
548 if( SfxItemState::SET == pArgs->GetItemState( SID_ATTR_POSTIT_TEXT, true, &pPoolItem ) )
549 sReplyText = static_cast<const SvxPostItTextItem*>( pPoolItem )->GetValue();
550 }
551
552 TextApiObject* pTextApi = getTextApiObject( xAnnotation );
553 if( !pTextApi )
554 return;
555
556 ::Outliner aOutliner( GetAnnotationPool(),OutlinerMode::TextObject );
557
559 aOutliner.SetUpdateLayout( true );
560
561 OUString aStr(SdResId(STR_ANNOTATION_REPLY));
562 OUString sAuthor( xAnnotation->getAuthor() );
563 if( sAuthor.isEmpty() )
564 sAuthor = SdResId( STR_ANNOTATION_NOAUTHOR );
565
566 aStr = aStr.replaceFirst("%1", sAuthor) +
567 " (" + getAnnotationDateTimeString( xAnnotation ) + "): \"";
568
569 OUString sQuote( pTextApi->GetText() );
570
571 if( sQuote.isEmpty() )
572 sQuote = "...";
573 aStr += sQuote + "\"\n";
574
575 for( sal_Int32 nIdx = 0; nIdx >= 0; )
576 aOutliner.Insert( aStr.getToken( 0, '\n', nIdx ), EE_PARA_APPEND, -1 );
577
578 if( aOutliner.GetParagraphCount() > 1 )
579 {
580 SfxItemSet aAnswerSet( aOutliner.GetEmptyItemSet() );
582
583 ESelection aSel;
584 aSel.nEndPara = aOutliner.GetParagraphCount()-2;
585 aSel.nEndPos = aOutliner.GetText( aOutliner.GetParagraph( aSel.nEndPara ) ).getLength();
586
587 aOutliner.QuickSetAttribs( aAnswerSet, aSel );
588 }
589
590 if (!sReplyText.isEmpty())
591 aOutliner.Insert(sReplyText);
592
594 pTextApi->SetText(*pOPO);
595
596 OUString sReplyAuthor;
598 sReplyAuthor = mrBase.GetMainViewShell()->GetView()->GetAuthor();
599 else
600 {
601 SvtUserOptions aUserOptions;
602 sReplyAuthor = aUserOptions.GetFullName();
603 xAnnotation->setInitials( aUserOptions.GetID() );
604 }
605
606 xAnnotation->setAuthor( sReplyAuthor );
607 // set current time to reply
608 xAnnotation->setDateTime( getCurrentDateTime() );
609
610 // Tell our LOK clients about this (comment modification)
612
613 UpdateTags(true);
614 SelectAnnotation( xAnnotation, true );
615}
616
617void AnnotationManagerImpl::DeleteAnnotation( const Reference< XAnnotation >& xAnnotation )
618{
619 SdPage* pPage = GetCurrentPage();
620
621 if( xAnnotation.is() && pPage )
622 {
623 if( mpDoc->IsUndoEnabled() )
624 mpDoc->BegUndo( SdResId( STR_ANNOTATION_UNDO_DELETE ) );
625
626 pPage->removeAnnotation( xAnnotation );
627
628 if( mpDoc->IsUndoEnabled() )
629 mpDoc->EndUndo();
630
631 UpdateTags();
632 }
633}
634
635void AnnotationManagerImpl::DeleteAnnotationsByAuthor( std::u16string_view sAuthor )
636{
637 if( mpDoc->IsUndoEnabled() )
638 mpDoc->BegUndo( SdResId( STR_ANNOTATION_UNDO_DELETE ) );
639
640 SdPage* pPage = nullptr;
641 do
642 {
643 pPage = GetNextPage( pPage, true );
644
645 if( pPage && !pPage->getAnnotations().empty() )
646 {
647 AnnotationVector aAnnotations( pPage->getAnnotations() );
648 for( Reference< XAnnotation >& xAnnotation : aAnnotations )
649 {
650 if( xAnnotation->getAuthor() == sAuthor )
651 {
652 if( mxSelectedAnnotation == xAnnotation )
653 mxSelectedAnnotation.clear();
654 pPage->removeAnnotation( xAnnotation );
655 }
656 }
657 }
658 } while( pPage );
659
660 if( mpDoc->IsUndoEnabled() )
661 mpDoc->EndUndo();
662}
663
665{
666 if( mpDoc->IsUndoEnabled() )
667 mpDoc->BegUndo( SdResId( STR_ANNOTATION_UNDO_DELETE ) );
668
669 SdPage* pPage = nullptr;
670 do
671 {
672 pPage = GetNextPage( pPage, true );
673
674 if( pPage && !pPage->getAnnotations().empty() )
675 {
676
677 AnnotationVector aAnnotations( pPage->getAnnotations() );
678 for( const auto& rxAnnotation : aAnnotations )
679 {
680 pPage->removeAnnotation( rxAnnotation );
681 }
682 }
683 }
684 while( pPage );
685
686 mxSelectedAnnotation.clear();
687
688 if( mpDoc->IsUndoEnabled() )
689 mpDoc->EndUndo();
690}
691
693{
694 SdPage* pCurrentPage = GetCurrentPage();
695
696 const bool bReadOnly = mrBase.GetDocShell()->IsReadOnly();
697 const bool bWrongPageKind = (pCurrentPage == nullptr) || (pCurrentPage->GetPageKind() != PageKind::Standard);
698
700
701 if (bReadOnly || bWrongPageKind || (nCurrentODFVersion <= SvtSaveOptions::ODFSVER_012))
702 rSet.DisableItem( SID_INSERT_POSTIT );
703
704 rSet.Put(SfxBoolItem(SID_TOGGLE_NOTES, mbShowAnnotations));
705
706 Reference< XAnnotation > xAnnotation;
707 GetSelectedAnnotation( xAnnotation );
708
709 // Don't disable these slot in case of LOK, as postit doesn't need to
710 // selected before doing an operation on it in LOK
711 if( (!xAnnotation.is() && !comphelper::LibreOfficeKit::isActive()) || bReadOnly )
712 {
713 rSet.DisableItem( SID_DELETE_POSTIT );
714 rSet.DisableItem( SID_EDIT_POSTIT );
715 }
716
717 SdPage* pPage = nullptr;
718
719 bool bHasAnnotations = false;
720 do
721 {
722 pPage = GetNextPage( pPage, true );
723
724 if( pPage && !pPage->getAnnotations().empty() )
725 bHasAnnotations = true;
726 }
727 while( pPage && !bHasAnnotations );
728
729 if( !bHasAnnotations || bReadOnly )
730 {
731 rSet.DisableItem( SID_DELETEALL_POSTIT );
732 }
733
734 if( bWrongPageKind || !bHasAnnotations )
735 {
736 rSet.DisableItem( SID_PREVIOUS_POSTIT );
737 rSet.DisableItem( SID_NEXT_POSTIT );
738 }
739}
740
742{
743 ShowAnnotations( true );
744
745 Reference< XAnnotation > xCurrent;
746 GetSelectedAnnotation( xCurrent );
747 SdPage* pPage = GetCurrentPage();
748 if( !pPage )
749 return;
750
751 AnnotationVector aAnnotations( pPage->getAnnotations() );
752
753 if( bForward )
754 {
755 if( xCurrent.is() )
756 {
757 auto iter = std::find(aAnnotations.begin(), aAnnotations.end(), xCurrent);
758 if (iter != aAnnotations.end())
759 {
760 ++iter;
761 if( iter != aAnnotations.end() )
762 {
763 SelectAnnotation( *iter );
764 return;
765 }
766 }
767 }
768 else if( !aAnnotations.empty() )
769 {
770 SelectAnnotation( *(aAnnotations.begin()) );
771 return;
772 }
773 }
774 else
775 {
776 if( xCurrent.is() )
777 {
778 auto iter = std::find(aAnnotations.begin(), aAnnotations.end(), xCurrent);
779 if (iter != aAnnotations.end() && iter != aAnnotations.begin())
780 {
781 --iter;
782 SelectAnnotation( *iter );
783 return;
784 }
785 }
786 else if( !aAnnotations.empty() )
787 {
788 AnnotationVector::iterator iter( aAnnotations.end() );
789 SelectAnnotation( *(--iter) );
790 return;
791 }
792 }
793
794 mxSelectedAnnotation.clear();
795 do
796 {
797 do
798 {
799 pPage = GetNextPage( pPage, bForward );
800
801 if( pPage && !pPage->getAnnotations().empty() )
802 {
803 // switch to next/previous slide with annotations
804 std::shared_ptr<DrawViewShell> pDrawViewShell(std::dynamic_pointer_cast<DrawViewShell>(mrBase.GetMainViewShell()));
805 if (pDrawViewShell != nullptr)
806 {
807 pDrawViewShell->ChangeEditMode(pPage->IsMasterPage() ? EditMode::MasterPage : EditMode::Page, false);
808 pDrawViewShell->SwitchPage((pPage->GetPageNum() - 1) >> 1);
809
810 SfxDispatcher* pDispatcher = getDispatcher( mrBase );
811 if( pDispatcher )
812 pDispatcher->Execute( bForward ? SID_NEXT_POSTIT : SID_PREVIOUS_POSTIT );
813
814 return;
815 }
816 }
817 }
818 while( pPage );
819
820 // The question text depends on the search direction.
821 bool bImpress = mpDoc->GetDocumentType() == DocumentType::Impress;
822 TranslateId pStringId;
823 if(bForward)
824 pStringId = bImpress ? STR_ANNOTATION_WRAP_FORWARD : STR_ANNOTATION_WRAP_FORWARD_DRAW;
825 else
826 pStringId = bImpress ? STR_ANNOTATION_WRAP_BACKWARD : STR_ANNOTATION_WRAP_BACKWARD_DRAW;
827
828 // Pop up question box that asks the user whether to wrap around.
829 // The dialog is made modal with respect to the whole application.
830 std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(nullptr,
831 VclMessageType::Question, VclButtonsType::YesNo,
832 SdResId(pStringId)));
833 xQueryBox->set_default_response(RET_YES);
834 if (xQueryBox->run() != RET_YES)
835 break;
836 }
837 while( true );
838}
839
841{
844}
845
847{
848 if( rTag.GetAnnotation() == mxSelectedAnnotation )
849 {
850 mxSelectedAnnotation.clear();
852 }
853}
854
855void AnnotationManagerImpl::SelectAnnotation( const css::uno::Reference< css::office::XAnnotation >& xAnnotation, bool bEdit /* = sal_False */ )
856{
857 mxSelectedAnnotation = xAnnotation;
858
859 auto iter = std::find_if(maTagVector.begin(), maTagVector.end(),
860 [&xAnnotation](const rtl::Reference<AnnotationTag>& rxTag) { return rxTag->GetAnnotation() == xAnnotation; });
861 if (iter != maTagVector.end())
862 {
863 SmartTagReference xTag( *iter );
864 mrBase.GetMainViewShell()->GetView()->getSmartTags().select( xTag );
865 (*iter)->OpenPopup( bEdit );
866 }
867}
868
869void AnnotationManagerImpl::GetSelectedAnnotation( css::uno::Reference< css::office::XAnnotation >& xAnnotation )
870{
871 xAnnotation = mxSelectedAnnotation;
872}
873
875{
876 SfxBindings* pBindings = getBindings( mrBase );
877 if( pBindings )
878 {
879 pBindings->Invalidate( SID_INSERT_POSTIT );
880 pBindings->Invalidate( SID_DELETE_POSTIT );
881 pBindings->Invalidate( SID_DELETEALL_POSTIT );
882 pBindings->Invalidate( SID_PREVIOUS_POSTIT );
883 pBindings->Invalidate( SID_NEXT_POSTIT );
884 pBindings->Invalidate( SID_UNDO );
885 pBindings->Invalidate( SID_REDO );
886 }
887}
888
890{
891 if( !(mxView.is() && mrBase.GetDrawView()) )
892 return;
893
894 try
895 {
896 Reference< XAnnotationAccess > xPage( mxView->getCurrentPage(), UNO_QUERY );
897
898 if( xPage != mxCurrentPage )
899 {
900 mxCurrentPage = xPage;
901
902 UpdateTags(true);
903 }
904 }
905 catch( Exception& )
906 {
907 TOOLS_WARN_EXCEPTION( "sd", "sd::AnnotationManagerImpl::onSelectionChanged()" );
908 }
909}
910
912{
913 if( bSynchron )
914 {
917
918 UpdateTagsHdl(nullptr);
919 }
920 else
921 {
922 if( !mnUpdateTagsEvent && mxView.is() )
924 }
925}
926
927IMPL_LINK_NOARG(AnnotationManagerImpl, UpdateTagsHdl, void*, void)
928{
929 mnUpdateTagsEvent = nullptr;
930 DisposeTags();
931
932 if( mbShowAnnotations )
933 CreateTags();
934
935 if( mrBase.GetDrawView() )
936 static_cast< ::sd::View* >( mrBase.GetDrawView() )->updateHandles();
937
938 invalidateSlots();
939}
940
942{
943 if( !(mxCurrentPage.is() && mpDoc) )
944 return;
945
946 auto xViewShell = mrBase.GetMainViewShell();
947 if (!xViewShell)
948 return;
949
950 try
951 {
952 int nIndex = 1;
954
956
957 Reference< XAnnotationEnumeration > xEnum( mxCurrentPage->createAnnotationEnumeration() );
958 while( xEnum->hasMoreElements() )
959 {
960 Reference< XAnnotation > xAnnotation( xEnum->nextElement() );
961 Color aColor( GetColorLight( mpDoc->GetAnnotationAuthorIndex( xAnnotation->getAuthor() ) ) );
962 rtl::Reference< AnnotationTag > xTag( new AnnotationTag( *this, *xViewShell->GetView(), xAnnotation, aColor, nIndex++, maFont ) );
963 maTagVector.push_back(xTag);
964
965 if( xAnnotation == mxSelectedAnnotation )
966 {
967 xSelectedTag = xTag;
968 }
969 }
970
971 if( xSelectedTag.is() )
972 {
973 SmartTagReference xTag( xSelectedTag );
974 mrBase.GetMainViewShell()->GetView()->getSmartTags().select( xTag );
975 }
976 else
977 {
978 // no tag, no selection!
979 mxSelectedAnnotation.clear();
980 }
981 }
982 catch( Exception& )
983 {
984 TOOLS_WARN_EXCEPTION( "sd", "sd::AnnotationManagerImpl::onSelectionChanged()" );
985 }
986}
987
989{
990 for (auto& rxTag : maTagVector)
991 {
992 rxTag->Dispose();
993 }
994
995 maTagVector.clear();
996}
997
999{
1000 Link<tools::EventMultiplexerEvent&,void> aLink( LINK(this,AnnotationManagerImpl,EventMultiplexerListener) );
1001 mrBase.GetEventMultiplexer()->AddEventListener(aLink);
1002}
1003
1005{
1006 Link<tools::EventMultiplexerEvent&,void> aLink( LINK(this,AnnotationManagerImpl,EventMultiplexerListener) );
1007 mrBase.GetEventMultiplexer()->RemoveEventListener( aLink );
1008}
1009
1010IMPL_LINK(AnnotationManagerImpl,EventMultiplexerListener,
1011 tools::EventMultiplexerEvent&, rEvent, void)
1012{
1013 switch (rEvent.meEventId)
1014 {
1017 onSelectionChanged();
1018 break;
1019
1021 mxView.clear();
1022 onSelectionChanged();
1023 break;
1024
1026 mxView.set( mrBase.GetController(), UNO_QUERY );
1027 onSelectionChanged();
1028 break;
1029
1030 default: break;
1031 }
1032}
1033
1034void AnnotationManagerImpl::ExecuteAnnotationTagContextMenu(const Reference<XAnnotation>& xAnnotation, weld::Widget* pParent, const ::tools::Rectangle& rContextRect)
1035{
1036 SfxDispatcher* pDispatcher( getDispatcher( mrBase ) );
1037 if( !pDispatcher )
1038 return;
1039
1040 const bool bReadOnly = mrBase.GetDocShell()->IsReadOnly();
1041
1042 if (bReadOnly)
1043 return;
1044
1045 std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(pParent, "modules/simpress/ui/annotationtagmenu.ui"));
1046 std::unique_ptr<weld::Menu> xMenu(xBuilder->weld_menu("menu"));
1047
1048 SvtUserOptions aUserOptions;
1049 OUString sCurrentAuthor( aUserOptions.GetFullName() );
1050 OUString sAuthor( xAnnotation->getAuthor() );
1051
1052 OUString aStr(xMenu->get_label(".uno:DeleteAllAnnotationByAuthor"));
1053 OUString aReplace( sAuthor );
1054 if( aReplace.isEmpty() )
1055 aReplace = SdResId( STR_ANNOTATION_NOAUTHOR );
1056 aStr = aStr.replaceFirst("%1", aReplace);
1057 xMenu->set_label(".uno:DeleteAllAnnotationByAuthor", aStr);
1058
1059 bool bShowReply = sAuthor != sCurrentAuthor;
1060 xMenu->set_visible(".uno:ReplyToAnnotation", bShowReply);
1061 xMenu->set_visible("separator", bShowReply);
1062 xMenu->set_visible(".uno:DeleteAnnotation", xAnnotation.is());
1063
1064 auto sId = xMenu->popup_at_rect(pParent, rContextRect);
1065
1066 if (sId == ".uno:ReplyToAnnotation")
1067 {
1068 const SfxUnoAnyItem aItem( SID_REPLYTO_POSTIT, Any( xAnnotation ) );
1069 pDispatcher->ExecuteList(SID_REPLYTO_POSTIT,
1070 SfxCallMode::ASYNCHRON, { &aItem });
1071 }
1072 else if (sId == ".uno:DeleteAnnotation")
1073 {
1074 const SfxUnoAnyItem aItem( SID_DELETE_POSTIT, Any( xAnnotation ) );
1075 pDispatcher->ExecuteList(SID_DELETE_POSTIT, SfxCallMode::ASYNCHRON,
1076 { &aItem });
1077 }
1078 else if (sId == ".uno:DeleteAllAnnotationByAuthor")
1079 {
1080 const SfxStringItem aItem( SID_DELETEALLBYAUTHOR_POSTIT, sAuthor );
1081 pDispatcher->ExecuteList( SID_DELETEALLBYAUTHOR_POSTIT,
1082 SfxCallMode::ASYNCHRON, { &aItem });
1083 }
1084 else if (sId == ".uno:DeleteAllAnnotation")
1085 pDispatcher->Execute( SID_DELETEALL_POSTIT );
1086}
1087
1089{
1090 if (!Application::GetSettings().GetStyleSettings().GetHighContrastMode())
1091 {
1092 static const Color aArrayNormal[] = {
1096
1097 return aArrayNormal[ aAuthorIndex % SAL_N_ELEMENTS( aArrayNormal ) ];
1098 }
1099
1100 return COL_WHITE;
1101}
1102
1104{
1105 if (!Application::GetSettings().GetStyleSettings().GetHighContrastMode())
1106 {
1107 static const Color aArrayLight[] = {
1111
1112 return aArrayLight[ aAuthorIndex % SAL_N_ELEMENTS( aArrayLight ) ];
1113 }
1114
1115 return COL_WHITE;
1116}
1117
1119{
1120 if (!Application::GetSettings().GetStyleSettings().GetHighContrastMode())
1121 {
1122 static const Color aArrayAnkor[] = {
1126
1127 return aArrayAnkor[ aAuthorIndex % SAL_N_ELEMENTS( aArrayAnkor ) ];
1128 }
1129
1130 return COL_WHITE;
1131}
1132
1133SdPage* AnnotationManagerImpl::GetNextPage( SdPage const * pPage, bool bForward )
1134{
1135 if( pPage == nullptr )
1136 {
1137 if (bForward)
1138 return mpDoc->GetSdPage(0, PageKind::Standard ); // first page
1139 else
1141 }
1142
1143 sal_uInt16 nPageNum = (pPage->GetPageNum() - 1) >> 1;
1144
1145 // first all non master pages
1146 if( !pPage->IsMasterPage() )
1147 {
1148 if( bForward )
1149 {
1150 if( nPageNum >= mpDoc->GetSdPageCount(PageKind::Standard)-1 )
1151 {
1152 // we reached end of draw pages, start with master pages (skip handout master for draw)
1154 }
1155 nPageNum++;
1156 }
1157 else
1158 {
1159 if( nPageNum == 0 )
1160 return nullptr; // we are already on the first draw page, finished
1161
1162 nPageNum--;
1163 }
1164 return mpDoc->GetSdPage(nPageNum, PageKind::Standard);
1165 }
1166 else
1167 {
1168 if( bForward )
1169 {
1170 if( nPageNum >= mpDoc->GetMasterSdPageCount(PageKind::Standard)-1 )
1171 {
1172 return nullptr; // we reached the end, there is nothing more to see here
1173 }
1174 nPageNum++;
1175 }
1176 else
1177 {
1178 if( nPageNum == (mpDoc->GetDocumentType() == DocumentType::Impress ? 0 : 1) )
1179 {
1180 // we reached beginning of master pages, start with end if pages
1182 }
1183
1184 nPageNum--;
1185 }
1186 return mpDoc->GetMasterSdPage(nPageNum,PageKind::Standard);
1187 }
1188}
1189
1191{
1193 return mrBase.GetMainViewShell()->getCurrentPage();
1194 return nullptr;
1195}
1196
1198: mxImpl( new AnnotationManagerImpl( rViewShellBase ) )
1199{
1200 mxImpl->init();
1201}
1202
1204{
1205 mxImpl->dispose();
1206}
1207
1209{
1210 mxImpl->ExecuteAnnotation( rRequest );
1211}
1212
1214{
1215 mxImpl->GetAnnotationState(rItemSet);
1216}
1217
1218}
1219
1220/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
@ EditViewSelection
The selection in the center pane has changed.
@ MainViewRemoved
The current MainViewShell (the ViewShell displayed in the center pane) has been removed.
@ MainViewAdded
A new ViewShell has been made the MainViewShell.
@ CurrentPageChanged
The current page has changed.
constexpr auto convertTwipToMm100(N n)
AnyEventRef aEvent
const StyleSettings & GetStyleSettings() const
static const AllSettings & GetSettings()
static ImplSVEvent * PostUserEvent(const Link< void *, void > &rLink, void *pCaller=nullptr, bool bReferenceLink=false)
static std::unique_ptr< weld::Builder > CreateBuilder(weld::Widget *pParent, const OUString &rUIFile, bool bMobile=false, sal_uInt64 nLOKWindowId=0)
static void RemoveUserEvent(ImplSVEvent *nUserEvent)
static weld::MessageDialog * CreateMessageDialog(weld::Widget *pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage, const ILibreOfficeKitNotifier *pNotifier=nullptr)
bool IsValidAndGregorian() const
sal_Int16 GetYear() const
sal_uInt16 GetDay() const
sal_uInt16 GetMonth() const
static rtl::Reference< SfxItemPool > CreatePool()
OUString getDate(const Date &rDate) const
OUString getTime(const tools::Time &rTime, bool bSec=true, bool b100Sec=false) const
void QuickSetAttribs(const SfxItemSet &rSet, const ESelection &rSel)
OUString GetText(Paragraph const *pPara, sal_Int32 nParaCount=1) const
const SfxItemSet & GetEmptyItemSet() const
Paragraph * GetParagraph(sal_Int32 nAbsPos) const
std::optional< OutlinerParaObject > CreateParaObject(sal_Int32 nStartPara=0, sal_Int32 nParaCount=EE_PARA_ALL) const
bool SetUpdateLayout(bool bUpdate)
Paragraph * Insert(const OUString &rText, sal_Int32 nAbsPos=EE_PARA_APPEND, sal_Int16 nDepth=0)
sal_Int32 GetParagraphCount() const
static SAL_DLLPRIVATE void SetCalcFieldValueHdl(::Outliner *pOutliner)
Definition: drawdoc.cxx:1079
sal_uInt16 GetMasterSdPageCount(PageKind ePgKind) const
Definition: drawdoc2.cxx:222
SAL_DLLPRIVATE sal_uInt16 GetAnnotationAuthorIndex(const OUString &rAuthor)
Definition: drawdoc.cxx:1084
SdPage * GetSdPage(sal_uInt16 nPgNum, PageKind ePgKind) const
Definition: drawdoc2.cxx:207
SdPage * GetMasterSdPage(sal_uInt16 nPgNum, PageKind ePgKind)
Definition: drawdoc2.cxx:217
SAL_DLLPRIVATE DocumentType GetDocumentType() const
Definition: drawdoc.hxx:251
sal_uInt16 GetSdPageCount(PageKind ePgKind) const
Definition: drawdoc2.cxx:212
bool IsShowComments() const
Definition: optsitem.hxx:318
void SetShowComments(bool bShow)
Definition: optsitem.hxx:319
PageKind GetPageKind() const
Definition: sdpage.hxx:205
const sd::AnnotationVector & getAnnotations() const
Definition: sdpage.hxx:373
void removeAnnotation(const css::uno::Reference< css::office::XAnnotation > &xAnnotation)
Definition: sdpage2.cxx:591
void createAnnotation(css::uno::Reference< css::office::XAnnotation > &xAnnotation)
Definition: sdpage2.cxx:560
void BegUndo()
bool IsUndoEnabled() const
void EndUndo()
sal_uInt16 GetPageNum() const
bool IsMasterPage() const
Size GetSize() const
void Invalidate(sal_uInt16 nId)
const SfxPoolItem * Execute(sal_uInt16 nSlot, SfxCallMode nCall=SfxCallMode::SLOT, const SfxPoolItem **pArgs=nullptr, sal_uInt16 nModi=0, const SfxPoolItem **pInternalArgs=nullptr)
const SfxPoolItem * ExecuteList(sal_uInt16 nSlot, SfxCallMode nCall, std::initializer_list< SfxPoolItem const * > args, std::initializer_list< SfxPoolItem const * > internalargs=std::initializer_list< SfxPoolItem const * >())
const T * GetItemIfSet(TypedWhichId< T > nWhich, bool bSrchInParent=true) const
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
void DisableItem(sal_uInt16 nWhich)
bool IsReadOnly() const
css::uno::Reference< css::frame::XModel3 > GetModel() const
sal_uInt16 GetSlot() const
const SfxItemSet * GetArgs() const
css::uno::Reference< css::frame::XController > GetController() const
constexpr tools::Long Width() const
const vcl::Font & GetAppFont() const
const LocaleDataWrapper & GetLocaleData() const
OUString GetFullName() const
OUString GetID() const
css::uno::Reference< css::drawing::XDrawView > mxView
static Color GetColorLight(sal_uInt16 aAuthorIndex)
void onTagSelected(AnnotationTag const &rTag)
css::uno::Reference< css::office::XAnnotation > mxSelectedAnnotation
css::uno::Reference< css::office::XAnnotationAccess > mxCurrentPage
void SelectAnnotation(const css::uno::Reference< css::office::XAnnotation > &xAnnotation, bool bEdit=false)
void ExecuteEditAnnotation(SfxRequest const &rReq)
SdPage * GetNextPage(SdPage const *pPage, bool bForward)
css::uno::Reference< css::office::XAnnotation > GetAnnotationById(sal_uInt32 nAnnotationId)
void DeleteAnnotationsByAuthor(std::u16string_view sAuthor)
void SelectNextAnnotation(bool bForward)
AnnotationManagerImpl(ViewShellBase &rViewShellBase)
void onTagDeselected(AnnotationTag const &rTag)
void DeleteAnnotation(const css::uno::Reference< css::office::XAnnotation > &xAnnotation)
void ExecuteDeleteAnnotation(SfxRequest const &rReq)
void GetSelectedAnnotation(css::uno::Reference< css::office::XAnnotation > &xAnnotation)
virtual void disposing(std::unique_lock< std::mutex > &) override
void InsertAnnotation(const OUString &rText)
void ExecuteInsertAnnotation(SfxRequest const &rReq)
static Color GetColorDark(sal_uInt16 aAuthorIndex)
static Color GetColor(sal_uInt16 aAuthorIndex)
void ExecuteAnnotation(SfxRequest const &rRequest)
void ExecuteAnnotationTagContextMenu(const css::uno::Reference< css::office::XAnnotation > &xAnnotation, weld::Widget *pParent, const ::tools::Rectangle &rContextRect)
void UpdateTags(bool bSynchron=false)
virtual void SAL_CALL notifyEvent(const css::document::EventObject &Event) override
std::vector< rtl::Reference< AnnotationTag > > maTagVector
void GetAnnotationState(SfxItemSet &rItemSet)
void ExecuteReplyToAnnotation(SfxRequest const &rReq)
void GetAnnotationState(SfxItemSet &rItemSet)
void ExecuteAnnotation(SfxRequest const &rRequest)
::rtl::Reference< AnnotationManagerImpl > mxImpl
AnnotationManager(ViewShellBase &rViewShellBase)
const css::uno::Reference< css::office::XAnnotation > & GetAnnotation() const
OUString GetText() const
Definition: textapi.cxx:177
void SetText(OutlinerParaObject const &rText)
Definition: textapi.cxx:167
SfxViewShell descendant that the stacked Draw/Impress shells are based on.
std::shared_ptr< ViewShell > GetMainViewShell() const
Return the main view shell stacked on the called ViewShellBase object.
std::shared_ptr< tools::EventMultiplexer > const & GetEventMultiplexer() const
Return an event multiplexer.
DrawDocShell * GetDocShell() const
virtual SdrView * GetDrawView() const override
constexpr void SetLeft(tools::Long v)
bool Overlaps(const tools::Rectangle &rRect) const
constexpr void SetTop(tools::Long v)
constexpr tools::Long Top() const
constexpr void SetRight(tools::Long v)
constexpr void SetBottom(tools::Long v)
constexpr tools::Long Left() const
sal_uInt16 GetSec() const
sal_Int64 GetTime() const
sal_uInt16 GetMin() const
sal_uInt16 GetHour() const
FontFamily GetFamilyType()
const OUString & GetFamilyName() const
constexpr ::Color COL_AUTHOR9_DARK(0xD1, 0x76, 0x00)
constexpr ::Color COL_AUTHOR7_LIGHT(0xF2, 0xFE, 0xB5)
constexpr ::Color COL_AUTHOR5_LIGHT(0xFF, 0xE3, 0xE5)
constexpr ::Color COL_AUTHOR8_DARK(0x35, 0x55, 0x6B)
constexpr ::Color COL_AUTHOR8_LIGHT(0xE2, 0xEA, 0xF1)
constexpr ::Color COL_AUTHOR7_NORMAL(0xED, 0xFC, 0xA3)
constexpr ::Color COL_AUTHOR2_LIGHT(0xE9, 0xF2, 0xFF)
constexpr ::Color COL_AUTHOR8_NORMAL(0xD3, 0xDE, 0xE8)
constexpr ::Color COL_AUTHOR1_NORMAL(0xFF, 0xFF, 0x9E)
constexpr ::Color COL_AUTHOR9_LIGHT(0xFF, 0xE7, 0xC7)
constexpr ::Color COL_AUTHOR2_DARK(0x06, 0x46, 0xA2)
constexpr ::Color COL_AUTHOR1_LIGHT(0xFF, 0xFF, 0xC3)
constexpr ::Color COL_AUTHOR3_DARK(0x57, 0x9D, 0x1C)
constexpr ::Color COL_AUTHOR6_DARK(0x00, 0x80, 0x80)
constexpr ::Color COL_WHITE(0xFF, 0xFF, 0xFF)
constexpr ::Color COL_AUTHOR4_NORMAL(0xE4, 0xD2, 0xF5)
constexpr ::Color COL_AUTHOR7_DARK(0x8C, 0x84, 0x00)
constexpr ::Color COL_AUTHOR3_LIGHT(0xE2, 0xFA, 0xCF)
constexpr ::Color COL_AUTHOR5_NORMAL(0xFE, 0xCD, 0xD0)
constexpr ::Color COL_AUTHOR9_NORMAL(0xFF, 0xE2, 0xB9)
constexpr ::Color COL_AUTHOR4_LIGHT(0xEF, 0xE4, 0xF8)
constexpr ::Color COL_AUTHOR5_DARK(0xC5, 0x00, 0x0B)
constexpr ::Color COL_AUTHOR6_NORMAL(0xD2, 0xF6, 0xF6)
constexpr ::Color COL_AUTHOR4_DARK(0x69, 0x2B, 0x9D)
constexpr ::Color COL_AUTHOR6_LIGHT(0xE6, 0xFA, 0xFA)
constexpr ::Color COL_AUTHOR2_NORMAL(0xD8, 0xE8, 0xFF)
constexpr ::Color COL_AUTHOR1_DARK(0xC6, 0x92, 0x00)
constexpr ::Color COL_AUTHOR3_NORMAL(0xDA, 0xF8, 0xC1)
#define TOOLS_WARN_EXCEPTION(area, stream)
float y
float x
#define EE_PARA_APPEND
constexpr TypedWhichId< SvxFontHeightItem > EE_CHAR_FONTHEIGHT(EE_CHAR_START+2)
constexpr TypedWhichId< SvxPostureItem > EE_CHAR_ITALIC(EE_CHAR_START+7)
constexpr TypedWhichId< SvxFontItem > EE_CHAR_FONTINFO(EE_CHAR_START+1)
const char sQuote[]
PITCH_DONTKNOW
ITALIC_NORMAL
bool bReadOnly
sal_Int32 nIndex
#define SAL_N_ELEMENTS(arr)
aStr
@ Exception
static SfxBindings * getBindings(ViewShellBase const &rBase)
IMPL_LINK_NOARG(MainSequence, onTimerHdl, Timer *, void)
std::vector< css::uno::Reference< css::office::XAnnotation > > AnnotationVector
Definition: sdpage.hxx:82
void LOKCommentNotifyAll(CommentNotificationType nType, uno::Reference< office::XAnnotation > const &rxAnnotation)
Definition: Annotation.cxx:387
SfxItemPool * GetAnnotationPool()
static SfxDispatcher * getDispatcher(ViewShellBase const &rBase)
void CreateChangeUndo(const uno::Reference< office::XAnnotation > &xAnnotation)
Definition: Annotation.cxx:319
IMPL_LINK(SdCharHeightPropertyBox, implMenuSelectHdl, const OUString &, rIdent, void)
css::util::DateTime getCurrentDateTime()
OUString getAnnotationDateTimeString(const Reference< XAnnotation > &xAnnotation)
void LOKCommentNotify(CommentNotificationType nType, const SfxViewShell *pViewShell, uno::Reference< office::XAnnotation > const &rxAnnotation)
Definition: Annotation.cxx:377
TextApiObject * getTextApiObject(const Reference< XAnnotation > &xAnnotation)
sal_Int16 nId
const char GetValue[]
UNOTOOLS_DLLPUBLIC SvtSaveOptions::ODFSaneDefaultVersion GetODFSaneDefaultVersion()
OUString SdResId(TranslateId aId)
Definition: sdmod.cxx:83
#define SD_MOD()
Definition: sdmod.hxx:184
static SfxItemSet & rSet
uno::Reference< presentation::XSlideShowView > mxView
sal_Int32 nEndPos
sal_Int32 nEndPara
Reference< XModel > xModel
OUString sId
RET_YES