1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
23 #include <com/sun/star/beans/XMultiPropertyStates.hpp>
24 #include <com/sun/star/frame/XController.hpp>
25 #include <com/sun/star/frame/XModel.hpp>
26 #include <com/sun/star/view/XSelectionSupplier.hpp>
27 #include <com/sun/star/geometry/RealPoint2D.hpp>
28 #include <com/sun/star/text/XText.hpp>
29 #include <com/sun/star/document/XEventBroadcaster.hpp>
30 #include <comphelper/string.hxx>
31 #include <svx/svxids.hrc>
32 #include <vcl/menu.hxx>
33 #include <vcl/msgbox.hxx>
35 #include <sal/macros.h>
36 #include <svl/style.hxx>
37 #include <svl/itempool.hxx>
38 #include <unotools/useroptions.hxx>
39 #include <unotools/syslocale.hxx>
40 #include <unotools/saveopt.hxx>
42 #include <tools/datetime.hxx>
44 #include <sfx2/imagemgr.hxx>
45 #include <sfx2/viewfrm.hxx>
46 #include <sfx2/bindings.hxx>
47 #include <sfx2/app.hxx>
48 #include <sfx2/request.hxx>
49 #include <sfx2/dispatch.hxx>
50 #include <sfx2/objface.hxx>
52 #include <editeng/editeng.hxx>
53 #include <editeng/eeitem.hxx>
54 #include <editeng/fontitem.hxx>
55 #include <editeng/fhgtitem.hxx>
56 #include <editeng/outlobj.hxx>
57 #include <editeng/postitem.hxx>
58 #include <editeng/wghtitem.hxx>
59 #include <editeng/udlnitem.hxx>
60 #include <editeng/crossedoutitem.hxx>
62 #include <svx/svdetc.hxx>
64 #include "annotationmanager.hxx"
65 #include "annotationmanagerimpl.hxx"
66 #include "annotationwindow.hxx"
67 #include "annotations.hrc"
69 #include "ToolBarManager.hxx"
70 #include "DrawDocShell.hxx"
71 #include "DrawViewShell.hxx"
72 #include "DrawController.hxx"
74 #include "sdresid.hxx"
75 #include "EventMultiplexer.hxx"
76 #include "ViewShellManager.hxx"
79 #include "drawdoc.hxx"
80 #include "textapi.hxx"
81 #include "optsitem.hxx"
83 using namespace ::com::sun::star
;
84 using namespace ::com::sun::star::uno
;
85 using namespace ::com::sun::star::drawing
;
86 using namespace ::com::sun::star::document
;
87 using namespace ::com::sun::star::geometry
;
88 using namespace ::com::sun::star::container
;
89 using namespace ::com::sun::star::beans
;
90 using namespace ::com::sun::star::text
;
91 using namespace ::com::sun::star::view
;
92 using namespace ::com::sun::star::style
;
93 using namespace ::com::sun::star::frame
;
94 using namespace ::com::sun::star::lang
;
95 using namespace ::com::sun::star::ui
;
96 using namespace ::com::sun::star::task
;
97 using namespace ::com::sun::star::office
;
101 // --------------------------------------------------------------------
103 extern TextApiObject
* getTextApiObject( const Reference
< XAnnotation
>& xAnnotation
);
105 // --------------------------------------------------------------------
107 SfxItemPool
* GetAnnotationPool()
109 static SfxItemPool
* mpAnnotationPool
= 0;
110 if( mpAnnotationPool
== 0 )
112 mpAnnotationPool
= EditEngine::CreatePool( sal_False
);
113 mpAnnotationPool
->SetPoolDefaultItem(SvxFontHeightItem(423,100,EE_CHAR_FONTHEIGHT
));
115 Font
aAppFont( Application::GetSettings().GetStyleSettings().GetAppFont() );
117 mpAnnotationPool
->SetPoolDefaultItem(SvxFontItem(aAppFont
.GetFamily(),aAppFont
.GetName(), EMPTYSTRING
,PITCH_DONTKNOW
,RTL_TEXTENCODING_DONTKNOW
,EE_CHAR_FONTINFO
));
120 return mpAnnotationPool
;
123 // --------------------------------------------------------------------
125 static SfxBindings
* getBindings( ViewShellBase
& rBase
)
127 if( rBase
.GetMainViewShell().get() && rBase
.GetMainViewShell()->GetViewFrame() )
128 return &rBase
.GetMainViewShell()->GetViewFrame()->GetBindings();
133 // --------------------------------------------------------------------
135 static SfxDispatcher
* getDispatcher( ViewShellBase
& rBase
)
137 if( rBase
.GetMainViewShell().get() && rBase
.GetMainViewShell()->GetViewFrame() )
138 return rBase
.GetMainViewShell()->GetViewFrame()->GetDispatcher();
143 com::sun::star::util::DateTime
getCurrentDateTime()
145 DateTime
aCurrentDate( DateTime::SYSTEM
);
146 return com::sun::star::util::DateTime( 0, aCurrentDate
.GetSec(),
147 aCurrentDate
.GetMin(), aCurrentDate
.GetHour(),
148 aCurrentDate
.GetDay(), aCurrentDate
.GetMonth(),
149 aCurrentDate
.GetYear(), false );
152 OUString
getAnnotationDateTimeString( const Reference
< XAnnotation
>& xAnnotation
)
155 if( xAnnotation
.is() )
157 const SvtSysLocale aSysLocale
;
158 const LocaleDataWrapper
& rLocalData
= aSysLocale
.GetLocaleData();
160 com::sun::star::util::DateTime
aDateTime( xAnnotation
->getDateTime() );
162 Date
aSysDate( Date::SYSTEM
);
163 Date aDate
= Date( aDateTime
.Day
, aDateTime
.Month
, aDateTime
.Year
);
165 sRet
= SdResId(STR_ANNOTATION_TODAY
);
166 else if (aDate
== Date(aSysDate
-1))
167 sRet
= SdResId(STR_ANNOTATION_YESTERDAY
);
168 else if (aDate
.IsValidAndGregorian() )
169 sRet
= rLocalData
.getDate(aDate
);
171 Time
aTime( aDateTime
.Hours
, aDateTime
.Minutes
, aDateTime
.Seconds
, aDateTime
.NanoSeconds
);
172 if(aTime
.GetTime() != 0)
173 sRet
= sRet
+ " " + rLocalData
.getTime( aTime
,false );
178 // --------------------------------------------------------------------
180 AnnotationManagerImpl::AnnotationManagerImpl( ViewShellBase
& rViewShellBase
)
181 : AnnotationManagerImplBase( m_aMutex
)
182 , mrBase( rViewShellBase
)
183 , mpDoc( rViewShellBase
.GetDocument() )
184 , mbShowAnnotations( true )
185 , mnUpdateTagsEvent( 0 )
187 SdOptions
* pOptions
= SD_MOD()->GetSdOptions(mpDoc
->GetDocumentType());
189 mbShowAnnotations
= pOptions
->IsShowComments() == sal_True
;
192 // --------------------------------------------------------------------
194 void AnnotationManagerImpl::init()
196 // get current controller and initialize listeners
200 mxView
= Reference
< XDrawView
>::query(mrBase
.GetController());
204 OSL_FAIL( "sd::AnnotationManagerImpl::AnnotationManagerImpl(), Exception caught!" );
209 Reference
<XEventBroadcaster
> xModel (mrBase
.GetDocShell()->GetModel(), UNO_QUERY_THROW
);
210 Reference
<XEventListener
> xListener( this );
211 xModel
->addEventListener( xListener
);
218 // --------------------------------------------------------------------
220 // WeakComponentImplHelper1
221 void SAL_CALL
AnnotationManagerImpl::disposing ()
225 Reference
<XEventBroadcaster
> xModel (mrBase
.GetDocShell()->GetModel(), UNO_QUERY_THROW
);
226 Reference
<XEventListener
> xListener( this );
227 xModel
->removeEventListener( xListener
);
236 if( mnUpdateTagsEvent
)
238 Application::RemoveUserEvent( mnUpdateTagsEvent
);
239 mnUpdateTagsEvent
= 0;
243 mxCurrentPage
.clear();
246 // --------------------------------------------------------------------
249 void SAL_CALL
AnnotationManagerImpl::notifyEvent( const ::com::sun::star::document::EventObject
& aEvent
) throw (::com::sun::star::uno::RuntimeException
)
251 if( aEvent
.EventName
== "OnAnnotationInserted" || aEvent
.EventName
== "OnAnnotationRemoved" || aEvent
.EventName
== "OnAnnotationChanged" )
257 void SAL_CALL
AnnotationManagerImpl::disposing( const ::com::sun::star::lang::EventObject
& /*Source*/ ) throw (::com::sun::star::uno::RuntimeException
)
261 void AnnotationManagerImpl::ShowAnnotations( bool bShow
)
263 // enforce show annotations if a new annotation is inserted
264 if( mbShowAnnotations
!= bShow
)
266 mbShowAnnotations
= bShow
;
268 SdOptions
* pOptions
= SD_MOD()->GetSdOptions(mpDoc
->GetDocumentType());
270 pOptions
->SetShowComments( mbShowAnnotations
? sal_True
: sal_False
);
276 // --------------------------------------------------------------------
278 void AnnotationManagerImpl::ExecuteAnnotation(SfxRequest
& rReq
)
280 switch( rReq
.GetSlot() )
282 case SID_INSERT_POSTIT
:
283 ExecuteInsertAnnotation( rReq
);
285 case SID_DELETE_POSTIT
:
286 case SID_DELETEALL_POSTIT
:
287 case SID_DELETEALLBYAUTHOR_POSTIT
:
288 ExecuteDeleteAnnotation( rReq
);
290 case SID_PREVIOUS_POSTIT
:
291 case SID_NEXT_POSTIT
:
292 SelectNextAnnotation( rReq
.GetSlot() == SID_NEXT_POSTIT
);
294 case SID_REPLYTO_POSTIT
:
295 ExecuteReplyToAnnotation( rReq
);
297 case SID_SHOW_POSTIT
:
298 ShowAnnotations( !mbShowAnnotations
);
303 // --------------------------------------------------------------------
305 void AnnotationManagerImpl::ExecuteInsertAnnotation(SfxRequest
& /*rReq*/)
307 ShowAnnotations(true);
311 // --------------------------------------------------------------------
313 void AnnotationManagerImpl::ExecuteDeleteAnnotation(SfxRequest
& rReq
)
315 ShowAnnotations( true );
317 const SfxItemSet
* pArgs
= rReq
.GetArgs();
319 switch( rReq
.GetSlot() )
321 case SID_DELETEALL_POSTIT
:
322 DeleteAllAnnotations();
324 case SID_DELETEALLBYAUTHOR_POSTIT
:
327 const SfxPoolItem
* pPoolItem
= NULL
;
328 if( SFX_ITEM_SET
== pArgs
->GetItemState( SID_DELETEALLBYAUTHOR_POSTIT
, sal_True
, &pPoolItem
) )
330 OUString
sAuthor( (( const SfxStringItem
* ) pPoolItem
)->GetValue() );
331 DeleteAnnotationsByAuthor( sAuthor
);
335 case SID_DELETE_POSTIT
:
337 Reference
< XAnnotation
> xAnnotation
;
339 if( rReq
.GetSlot() == SID_DELETE_POSTIT
)
343 const SfxPoolItem
* pPoolItem
= NULL
;
344 if( SFX_ITEM_SET
== pArgs
->GetItemState( SID_DELETE_POSTIT
, sal_True
, &pPoolItem
) )
345 ( ( const SfxUnoAnyItem
* ) pPoolItem
)->GetValue() >>= xAnnotation
;
349 if( !xAnnotation
.is() )
350 GetSelectedAnnotation( xAnnotation
);
352 DeleteAnnotation( xAnnotation
);
360 // --------------------------------------------------------------------
362 void AnnotationManagerImpl::InsertAnnotation()
364 SdPage
* pPage
= GetCurrentPage();
367 if( mpDoc
->IsUndoEnabled() )
368 mpDoc
->BegUndo( String( SdResId( STR_ANNOTATION_UNDO_INSERT
) ) );
370 // find free space for new annotation
373 AnnotationVector
aAnnotations( pPage
->getAnnotations() );
374 if( !aAnnotations
.empty() )
376 const int page_width
= pPage
->GetSize().Width();
377 const int width
= 1000;
378 const int height
= 800;
383 Rectangle
aNewRect( x
, y
, x
+ width
- 1, y
+ height
- 1 );
386 for( AnnotationVector::iterator iter
= aAnnotations
.begin(); iter
!= aAnnotations
.end(); ++iter
)
388 RealPoint2D
aPoint( (*iter
)->getPosition() );
389 aTagRect
.Left() = sal::static_int_cast
< long >( aPoint
.X
* 100.0 );
390 aTagRect
.Top() = sal::static_int_cast
< long >( aPoint
.Y
* 100.0 );
391 aTagRect
.Right() = aTagRect
.Left() + width
- 1;
392 aTagRect
.Bottom() = aTagRect
.Top() + height
- 1;
394 if( aNewRect
.IsOver( aTagRect
) )
417 Reference
< XAnnotation
> xAnnotation
;
418 pPage
->createAnnotation( xAnnotation
);
420 // set current author to new annotation
421 SvtUserOptions aUserOptions
;
422 xAnnotation
->setAuthor( aUserOptions
.GetFullName() );
424 // set current time to new annotation
425 xAnnotation
->setDateTime( getCurrentDateTime() );
428 RealPoint2D
aPos( ((double)x
) / 100.0, ((double)y
) / 100.0 );
429 xAnnotation
->setPosition( aPos
);
431 if( mpDoc
->IsUndoEnabled() )
435 SelectAnnotation( xAnnotation
, true );
439 // --------------------------------------------------------------------
441 void AnnotationManagerImpl::ExecuteReplyToAnnotation( SfxRequest
& rReq
)
443 Reference
< XAnnotation
> xAnnotation
;
444 const SfxItemSet
* pArgs
= rReq
.GetArgs();
447 const SfxPoolItem
* pPoolItem
= NULL
;
448 if( SFX_ITEM_SET
== pArgs
->GetItemState( rReq
.GetSlot(), sal_True
, &pPoolItem
) )
449 ( ( const SfxUnoAnyItem
* ) pPoolItem
)->GetValue() >>= xAnnotation
;
453 TextApiObject
* pTextApi
= getTextApiObject( xAnnotation
);
456 std::auto_ptr
< ::Outliner
> pOutliner( new ::Outliner(GetAnnotationPool(),OUTLINERMODE_TEXTOBJECT
) );
458 mpDoc
->SetCalcFieldValueHdl( pOutliner
.get() );
459 pOutliner
->SetUpdateMode( sal_True
);
461 String
aStr(SdResId(STR_ANNOTATION_REPLY
));
462 OUString
sAuthor( xAnnotation
->getAuthor() );
463 if( sAuthor
.isEmpty() )
464 sAuthor
= String( SdResId( STR_ANNOTATION_NOAUTHOR
) );
466 aStr
.SearchAndReplaceAscii("%1", sAuthor
);
468 aStr
.Append( OUString(" (") );
469 aStr
.Append( OUString( getAnnotationDateTimeString( xAnnotation
) ) );
470 aStr
.Append( OUString("): \"") );
472 String
sQuote( pTextApi
->GetText() );
474 if( sQuote
.Len() == 0 )
475 sQuote
= OUString( "..." );
476 aStr
.Append( sQuote
);
477 aStr
.Append( OUString("\"\n") );
479 sal_Int32 nParaCount
= comphelper::string::getTokenCount(aStr
, '\n');
480 for( sal_Int32 nPara
= 0; nPara
< nParaCount
; nPara
++ )
481 pOutliner
->Insert( aStr
.GetToken( nPara
, '\n' ), EE_PARA_APPEND
, -1 );
483 if( pOutliner
->GetParagraphCount() > 1 )
485 SfxItemSet
aAnswerSet( pOutliner
->GetEmptyItemSet() );
486 aAnswerSet
.Put(SvxPostureItem(ITALIC_NORMAL
,EE_CHAR_ITALIC
));
489 aSel
.nEndPara
= pOutliner
->GetParagraphCount()-2;
490 aSel
.nEndPos
= pOutliner
->GetText( pOutliner
->GetParagraph( aSel
.nEndPara
) ).Len();
492 pOutliner
->QuickSetAttribs( aAnswerSet
, aSel
);
495 std::auto_ptr
< OutlinerParaObject
> pOPO( pOutliner
->CreateParaObject() );
496 pTextApi
->SetText( *pOPO
.get() );
498 SvtUserOptions aUserOptions
;
499 xAnnotation
->setAuthor( aUserOptions
.GetFullName() );
501 // set current time to reply
502 xAnnotation
->setDateTime( getCurrentDateTime() );
505 SelectAnnotation( xAnnotation
, true );
509 // --------------------------------------------------------------------
511 void AnnotationManagerImpl::DeleteAnnotation( Reference
< XAnnotation
> xAnnotation
)
513 SdPage
* pPage
= GetCurrentPage();
515 if( xAnnotation
.is() && pPage
)
517 if( mpDoc
->IsUndoEnabled() )
518 mpDoc
->BegUndo( String( SdResId( STR_ANNOTATION_UNDO_DELETE
) ) );
520 pPage
->removeAnnotation( xAnnotation
);
522 if( mpDoc
->IsUndoEnabled() )
529 void AnnotationManagerImpl::DeleteAnnotationsByAuthor( const OUString
& sAuthor
)
531 if( mpDoc
->IsUndoEnabled() )
532 mpDoc
->BegUndo( String( SdResId( STR_ANNOTATION_UNDO_DELETE
) ) );
537 pPage
= GetNextPage( pPage
, true );
539 if( pPage
&& !pPage
->getAnnotations().empty() )
541 AnnotationVector
aAnnotations( pPage
->getAnnotations() );
542 for( AnnotationVector::iterator iter
= aAnnotations
.begin(); iter
!= aAnnotations
.end(); ++iter
)
544 Reference
< XAnnotation
> xAnnotation( *iter
);
545 if( xAnnotation
->getAuthor() == sAuthor
)
547 if( mxSelectedAnnotation
== xAnnotation
)
548 mxSelectedAnnotation
.clear();
549 pPage
->removeAnnotation( xAnnotation
);
555 if( mpDoc
->IsUndoEnabled() )
559 void AnnotationManagerImpl::DeleteAllAnnotations()
561 if( mpDoc
->IsUndoEnabled() )
562 mpDoc
->BegUndo( String( SdResId( STR_ANNOTATION_UNDO_DELETE
) ) );
567 pPage
= GetNextPage( pPage
, true );
569 if( pPage
&& !pPage
->getAnnotations().empty() )
572 AnnotationVector
aAnnotations( pPage
->getAnnotations() );
573 for( AnnotationVector::iterator iter
= aAnnotations
.begin(); iter
!= aAnnotations
.end(); ++iter
)
575 pPage
->removeAnnotation( (*iter
) );
581 mxSelectedAnnotation
.clear();
583 if( mpDoc
->IsUndoEnabled() )
587 // --------------------------------------------------------------------
589 void AnnotationManagerImpl::GetAnnotationState(SfxItemSet
& rSet
)
591 SdPage
* pCurrentPage
= GetCurrentPage();
593 const bool bReadOnly
= mrBase
.GetDocShell()->IsReadOnly();
594 const bool bWrongPageKind
= (pCurrentPage
== 0) || (pCurrentPage
->GetPageKind() != PK_STANDARD
);
596 const SvtSaveOptions::ODFDefaultVersion
nCurrentODFVersion( SvtSaveOptions().GetODFDefaultVersion() );
598 if( bReadOnly
|| bWrongPageKind
|| (nCurrentODFVersion
<= SvtSaveOptions::ODFVER_012
) )
599 rSet
.DisableItem( SID_INSERT_POSTIT
);
601 rSet
.Put(SfxBoolItem(SID_SHOW_POSTIT
, mbShowAnnotations
));
603 Reference
< XAnnotation
> xAnnotation
;
604 GetSelectedAnnotation( xAnnotation
);
606 if( !xAnnotation
.is() || bReadOnly
)
607 rSet
.DisableItem( SID_DELETE_POSTIT
);
611 bool bHasAnnotations
= false;
614 pPage
= GetNextPage( pPage
, true );
616 if( pPage
&& !pPage
->getAnnotations().empty() )
617 bHasAnnotations
= true;
619 while( pPage
&& !bHasAnnotations
);
621 if( !bHasAnnotations
|| bReadOnly
)
623 rSet
.DisableItem( SID_DELETEALL_POSTIT
);
626 if( bWrongPageKind
|| !bHasAnnotations
)
628 rSet
.DisableItem( SID_PREVIOUS_POSTIT
);
629 rSet
.DisableItem( SID_NEXT_POSTIT
);
633 // --------------------------------------------------------------------
635 void AnnotationManagerImpl::SelectNextAnnotation(bool bForeward
)
637 ShowAnnotations( true );
639 Reference
< XAnnotation
> xCurrent
;
640 GetSelectedAnnotation( xCurrent
);
641 SdPage
* pPage
= GetCurrentPage();
645 AnnotationVector
aAnnotations( pPage
->getAnnotations() );
651 for( AnnotationVector::iterator iter
= aAnnotations
.begin(); iter
!= aAnnotations
.end(); ++iter
)
653 if( (*iter
) == xCurrent
)
656 if( iter
!= aAnnotations
.end() )
658 SelectAnnotation( (*iter
) );
665 else if( !aAnnotations
.empty() )
667 SelectAnnotation( *(aAnnotations
.begin()) );
675 for( AnnotationVector::iterator iter
= aAnnotations
.begin(); iter
!= aAnnotations
.end(); ++iter
)
677 if( (*iter
) == xCurrent
)
679 if( iter
!= aAnnotations
.begin() )
682 SelectAnnotation( (*iter
) );
689 else if( !aAnnotations
.empty() )
691 AnnotationVector::iterator
iter( aAnnotations
.end() );
692 SelectAnnotation( *(--iter
) );
697 mxSelectedAnnotation
.clear();
702 pPage
= GetNextPage( pPage
, bForeward
);
704 if( pPage
&& !pPage
->getAnnotations().empty() )
706 // switch to next/previous slide with annotations
707 ::boost::shared_ptr
<DrawViewShell
> pDrawViewShell(::boost::dynamic_pointer_cast
<DrawViewShell
>(mrBase
.GetMainViewShell()));
708 if (pDrawViewShell
.get() != NULL
)
710 pDrawViewShell
->ChangeEditMode(pPage
->IsMasterPage() ? EM_MASTERPAGE
: EM_PAGE
, sal_False
);
711 pDrawViewShell
->SwitchPage((pPage
->GetPageNum() - 1) >> 1);
713 SfxDispatcher
* pDispatcher
= getDispatcher( mrBase
);
715 pDispatcher
->Execute( bForeward
? SID_NEXT_POSTIT
: SID_PREVIOUS_POSTIT
);
723 // The question text depends on the search direction.
724 bool bImpress
= mpDoc
->GetDocumentType() == DOCUMENT_TYPE_IMPRESS
;
725 sal_uInt16 nStringId
;
727 nStringId
= bImpress
? STR_ANNOTATION_WRAP_FORWARD
: STR_ANNOTATION_WRAP_FORWARD_DRAW
;
729 nStringId
= bImpress
? STR_ANNOTATION_WRAP_BACKWARD
: STR_ANNOTATION_WRAP_BACKWARD_DRAW
;
731 // Pop up question box that asks the user whether to wrap arround.
732 // The dialog is made modal with respect to the whole application.
733 QueryBox
aQuestionBox ( NULL
, (WB_YES_NO
| WB_DEF_YES
), String(SdResId(nStringId
)));
734 aQuestionBox
.SetImage (QueryBox::GetStandardImage());
735 short nBoxResult
= aQuestionBox
.Execute();
736 if (nBoxResult
!= RET_YES
)
742 // --------------------------------------------------------------------
744 void AnnotationManagerImpl::onTagSelected( AnnotationTag
& rTag
)
746 mxSelectedAnnotation
= rTag
.GetAnnotation();
750 // --------------------------------------------------------------------
752 void AnnotationManagerImpl::onTagDeselected( AnnotationTag
& rTag
)
754 if( rTag
.GetAnnotation() == mxSelectedAnnotation
)
756 mxSelectedAnnotation
.clear();
761 // --------------------------------------------------------------------
763 void AnnotationManagerImpl::SelectAnnotation( ::com::sun::star::uno::Reference
< ::com::sun::star::office::XAnnotation
> xAnnotation
, bool bEdit
/* = sal_False */ )
765 mxSelectedAnnotation
= xAnnotation
;
767 const AnnotationTagVector::const_iterator
aEnd( maTagVector
.end() );
768 for( AnnotationTagVector::const_iterator
iter( maTagVector
.begin() );
769 iter
!= aEnd
; ++iter
)
771 if( (*iter
)->GetAnnotation() == xAnnotation
)
773 SmartTagReference
xTag( (*iter
).get() );
774 mrBase
.GetMainViewShell()->GetView()->getSmartTags().select( xTag
);
775 (*iter
)->OpenPopup( bEdit
);
781 // --------------------------------------------------------------------
783 void AnnotationManagerImpl::GetSelectedAnnotation( ::com::sun::star::uno::Reference
< ::com::sun::star::office::XAnnotation
>& xAnnotation
)
785 xAnnotation
= mxSelectedAnnotation
;
788 void AnnotationManagerImpl::invalidateSlots()
790 SfxBindings
* pBindings
= getBindings( mrBase
);
793 pBindings
->Invalidate( SID_INSERT_POSTIT
);
794 pBindings
->Invalidate( SID_DELETE_POSTIT
);
795 pBindings
->Invalidate( SID_DELETEALL_POSTIT
);
796 pBindings
->Invalidate( SID_PREVIOUS_POSTIT
);
797 pBindings
->Invalidate( SID_NEXT_POSTIT
);
798 pBindings
->Invalidate( SID_UNDO
);
799 pBindings
->Invalidate( SID_REDO
);
803 // --------------------------------------------------------------------
805 void AnnotationManagerImpl::onSelectionChanged()
807 if( mxView
.is() && mrBase
.GetDrawView() ) try
809 Reference
< XAnnotationAccess
> xPage( mxView
->getCurrentPage(), UNO_QUERY
);
811 if( xPage
!= mxCurrentPage
)
813 mxCurrentPage
= xPage
;
820 OSL_FAIL( "sd::AnnotationManagerImpl::onSelectionChanged(), exception caught!" );
824 void AnnotationManagerImpl::UpdateTags( bool bSynchron
)
828 if( mnUpdateTagsEvent
)
829 Application::RemoveUserEvent( mnUpdateTagsEvent
);
835 if( !mnUpdateTagsEvent
&& mxView
.is() )
836 mnUpdateTagsEvent
= Application::PostUserEvent( LINK( this, AnnotationManagerImpl
, UpdateTagsHdl
) );
840 IMPL_LINK_NOARG(AnnotationManagerImpl
, UpdateTagsHdl
)
842 mnUpdateTagsEvent
= 0;
845 if( mbShowAnnotations
)
848 if( mrBase
.GetDrawView() )
849 static_cast< ::sd::View
* >( mrBase
.GetDrawView() )->updateHandles();
856 void AnnotationManagerImpl::CreateTags()
859 if( mxCurrentPage
.is() && mpDoc
) try
862 maFont
= Application::GetSettings().GetStyleSettings().GetAppFont();
864 rtl::Reference
< AnnotationTag
> xSelectedTag
;
866 Reference
< XAnnotationEnumeration
> xEnum( mxCurrentPage
->createAnnotationEnumeration() );
867 while( xEnum
->hasMoreElements() )
869 Reference
< XAnnotation
> xAnnotation( xEnum
->nextElement() );
870 Color
aColor( GetColorLight( mpDoc
->GetAnnotationAuthorIndex( xAnnotation
->getAuthor() ) ) );
871 rtl::Reference
< AnnotationTag
> xTag( new AnnotationTag( *this, *mrBase
.GetMainViewShell()->GetView(), xAnnotation
, aColor
, nIndex
++, maFont
) );
872 maTagVector
.push_back(xTag
);
874 if( xAnnotation
== mxSelectedAnnotation
)
880 if( xSelectedTag
.is() )
882 SmartTagReference
xTag( xSelectedTag
.get() );
883 mrBase
.GetMainViewShell()->GetView()->getSmartTags().select( xTag
);
887 // no tag, no selection!
888 mxSelectedAnnotation
.clear();
893 OSL_FAIL( "sd::AnnotationManagerImpl::onSelectionChanged(), exception caught!" );
897 // --------------------------------------------------------------------
899 void AnnotationManagerImpl::DisposeTags()
901 if( !maTagVector
.empty() )
903 AnnotationTagVector::iterator iter
= maTagVector
.begin();
906 (*iter
++)->Dispose();
908 while( iter
!= maTagVector
.end() );
914 // --------------------------------------------------------------------
916 void AnnotationManagerImpl::addListener()
918 Link
aLink( LINK(this,AnnotationManagerImpl
,EventMultiplexerListener
) );
919 mrBase
.GetEventMultiplexer()->AddEventListener (
921 tools::EventMultiplexerEvent::EID_EDIT_VIEW_SELECTION
922 | tools::EventMultiplexerEvent::EID_CURRENT_PAGE
923 | tools::EventMultiplexerEvent::EID_MAIN_VIEW_REMOVED
924 | tools::EventMultiplexerEvent::EID_MAIN_VIEW_ADDED
);
927 // --------------------------------------------------------------------
929 void AnnotationManagerImpl::removeListener()
931 Link
aLink( LINK(this,AnnotationManagerImpl
,EventMultiplexerListener
) );
932 mrBase
.GetEventMultiplexer()->RemoveEventListener( aLink
);
935 // --------------------------------------------------------------------
937 IMPL_LINK(AnnotationManagerImpl
,EventMultiplexerListener
,
938 tools::EventMultiplexerEvent
*,pEvent
)
940 switch (pEvent
->meEventId
)
942 case tools::EventMultiplexerEvent::EID_CURRENT_PAGE
:
943 case tools::EventMultiplexerEvent::EID_EDIT_VIEW_SELECTION
:
944 onSelectionChanged();
947 case tools::EventMultiplexerEvent::EID_MAIN_VIEW_REMOVED
:
948 mxView
= Reference
<XDrawView
>();
949 onSelectionChanged();
952 case tools::EventMultiplexerEvent::EID_MAIN_VIEW_ADDED
:
953 mxView
= Reference
<XDrawView
>::query( mrBase
.GetController() );
954 onSelectionChanged();
960 void AnnotationManagerImpl::ExecuteAnnotationContextMenu( Reference
< XAnnotation
> xAnnotation
, ::Window
* pParent
, const Rectangle
& rContextRect
, bool bButtonMenu
/* = false */ )
962 SfxDispatcher
* pDispatcher( getDispatcher( mrBase
) );
966 const bool bReadOnly
= mrBase
.GetDocShell()->IsReadOnly();
968 AnnotationWindow
* pAnnotationWindow
= bButtonMenu
? 0 : dynamic_cast< AnnotationWindow
* >( pParent
);
970 if( bReadOnly
&& !pAnnotationWindow
)
973 std::auto_ptr
< PopupMenu
> pMenu( new PopupMenu( SdResId( pAnnotationWindow
? RID_ANNOTATION_CONTEXTMENU
: RID_ANNOTATION_TAG_CONTEXTMENU
) ) );
975 SvtUserOptions aUserOptions
;
976 OUString
sCurrentAuthor( aUserOptions
.GetFullName() );
977 OUString
sAuthor( xAnnotation
->getAuthor() );
979 String
aStr( pMenu
->GetItemText( SID_DELETEALLBYAUTHOR_POSTIT
) ), aReplace( sAuthor
);
980 if( aReplace
.Len() == 0 )
981 aReplace
= String( SdResId( STR_ANNOTATION_NOAUTHOR
) );
982 aStr
.SearchAndReplaceAscii("%1", aReplace
);
983 pMenu
->SetItemText( SID_DELETEALLBYAUTHOR_POSTIT
, aStr
);
984 pMenu
->EnableItem( SID_REPLYTO_POSTIT
, (sAuthor
!= sCurrentAuthor
) && !bReadOnly
);
985 pMenu
->EnableItem( SID_DELETE_POSTIT
, (xAnnotation
.is() && !bReadOnly
) ? sal_True
: sal_False
);
986 pMenu
->EnableItem( SID_DELETEALLBYAUTHOR_POSTIT
, !bReadOnly
);
987 pMenu
->EnableItem( SID_DELETEALL_POSTIT
, !bReadOnly
);
989 if( pAnnotationWindow
)
991 if( pAnnotationWindow
->IsProtected() || bReadOnly
)
993 pMenu
->EnableItem( SID_ATTR_CHAR_WEIGHT
, sal_False
);
994 pMenu
->EnableItem( SID_ATTR_CHAR_POSTURE
, sal_False
);
995 pMenu
->EnableItem( SID_ATTR_CHAR_UNDERLINE
, sal_False
);
996 pMenu
->EnableItem( SID_ATTR_CHAR_STRIKEOUT
, sal_False
);
997 pMenu
->EnableItem( SID_PASTE
, sal_False
);
1001 SfxItemSet
aSet(pAnnotationWindow
->getView()->GetAttribs());
1003 if ( aSet
.GetItemState( EE_CHAR_WEIGHT
) == SFX_ITEM_ON
)
1005 if( ((const SvxWeightItem
&)aSet
.Get( EE_CHAR_WEIGHT
)).GetWeight() == WEIGHT_BOLD
)
1006 pMenu
->CheckItem( SID_ATTR_CHAR_WEIGHT
);
1009 if ( aSet
.GetItemState( EE_CHAR_ITALIC
) == SFX_ITEM_ON
)
1011 if( ((const SvxPostureItem
&)aSet
.Get( EE_CHAR_ITALIC
)).GetPosture() != ITALIC_NONE
)
1012 pMenu
->CheckItem( SID_ATTR_CHAR_POSTURE
);
1015 if ( aSet
.GetItemState( EE_CHAR_UNDERLINE
) == SFX_ITEM_ON
)
1017 if( ((const SvxUnderlineItem
&)aSet
.Get( EE_CHAR_UNDERLINE
)).GetLineStyle() != UNDERLINE_NONE
)
1018 pMenu
->CheckItem( SID_ATTR_CHAR_UNDERLINE
);
1021 if ( aSet
.GetItemState( EE_CHAR_STRIKEOUT
) == SFX_ITEM_ON
)
1023 if( ((const SvxCrossedOutItem
&)aSet
.Get( EE_CHAR_STRIKEOUT
)).GetStrikeout() != STRIKEOUT_NONE
)
1024 pMenu
->CheckItem( SID_ATTR_CHAR_STRIKEOUT
);
1026 TransferableDataHelper
aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pAnnotationWindow
) );
1027 pMenu
->EnableItem( SID_PASTE
, aDataHelper
.GetFormatCount() != 0 );
1030 pMenu
->EnableItem( SID_COPY
, pAnnotationWindow
->getView()->HasSelection() );
1036 Reference
< ::com::sun::star::frame::XFrame
> xFrame( mrBase
.GetMainViewShell()->GetViewFrame()->GetFrame().GetFrameInterface() );
1039 for( sal_uInt16 nPos
= 0; nPos
< pMenu
->GetItemCount(); nPos
++ )
1041 nId
= pMenu
->GetItemId( nPos
);
1042 if( pMenu
->IsItemEnabled( nId
) )
1044 OUString
sSlotURL( "slot:" );
1045 sSlotURL
+= OUString::valueOf( sal_Int32( nId
));
1047 Image
aImage( GetImage( xFrame
, sSlotURL
, false ) );
1049 pMenu
->SetItemImage( nId
, aImage
);
1054 nId
= pMenu
->Execute( pParent
, rContextRect
, POPUPMENU_EXECUTE_DOWN
|POPUPMENU_NOMOUSEUPCLOSE
);
1057 case SID_REPLYTO_POSTIT
:
1059 const SfxUnoAnyItem
aItem( SID_REPLYTO_POSTIT
, Any( xAnnotation
) );
1060 pDispatcher
->Execute( SID_REPLYTO_POSTIT
, SFX_CALLMODE_ASYNCHRON
, &aItem
, 0 );
1063 case SID_DELETE_POSTIT
:
1065 const SfxUnoAnyItem
aItem( SID_DELETE_POSTIT
, Any( xAnnotation
) );
1066 pDispatcher
->Execute( SID_DELETE_POSTIT
, SFX_CALLMODE_ASYNCHRON
, &aItem
, 0 );
1069 case SID_DELETEALLBYAUTHOR_POSTIT
:
1071 const SfxStringItem
aItem( SID_DELETEALLBYAUTHOR_POSTIT
, sAuthor
);
1072 pDispatcher
->Execute( SID_DELETEALLBYAUTHOR_POSTIT
, SFX_CALLMODE_ASYNCHRON
, &aItem
, 0 );
1075 case SID_DELETEALL_POSTIT
:
1076 pDispatcher
->Execute( SID_DELETEALL_POSTIT
);
1080 case SID_ATTR_CHAR_WEIGHT
:
1081 case SID_ATTR_CHAR_POSTURE
:
1082 case SID_ATTR_CHAR_UNDERLINE
:
1083 case SID_ATTR_CHAR_STRIKEOUT
:
1084 if( pAnnotationWindow
)
1085 pAnnotationWindow
->ExecuteSlot( nId
);
1090 // ====================================================================
1092 Color
AnnotationManagerImpl::GetColor(sal_uInt16 aAuthorIndex
)
1094 if (!Application::GetSettings().GetStyleSettings().GetHighContrastMode())
1096 static const Color aArrayNormal
[] = {
1097 COL_AUTHOR1_NORMAL
, COL_AUTHOR2_NORMAL
, COL_AUTHOR3_NORMAL
,
1098 COL_AUTHOR4_NORMAL
, COL_AUTHOR5_NORMAL
, COL_AUTHOR6_NORMAL
,
1099 COL_AUTHOR7_NORMAL
, COL_AUTHOR8_NORMAL
, COL_AUTHOR9_NORMAL
};
1101 return Color( aArrayNormal
[ aAuthorIndex
% (sizeof( aArrayNormal
)/ sizeof( aArrayNormal
[0] ))]);
1104 return Color(COL_WHITE
);
1107 Color
AnnotationManagerImpl::GetColorLight(sal_uInt16 aAuthorIndex
)
1109 if (!Application::GetSettings().GetStyleSettings().GetHighContrastMode())
1111 static const Color aArrayLight
[] = {
1112 COL_AUTHOR1_LIGHT
, COL_AUTHOR2_LIGHT
, COL_AUTHOR3_LIGHT
,
1113 COL_AUTHOR4_LIGHT
, COL_AUTHOR5_LIGHT
, COL_AUTHOR6_LIGHT
,
1114 COL_AUTHOR7_LIGHT
, COL_AUTHOR8_LIGHT
, COL_AUTHOR9_LIGHT
};
1116 return Color( aArrayLight
[ aAuthorIndex
% (sizeof( aArrayLight
)/ sizeof( aArrayLight
[0] ))]);
1119 return Color(COL_WHITE
);
1122 Color
AnnotationManagerImpl::GetColorDark(sal_uInt16 aAuthorIndex
)
1124 if (!Application::GetSettings().GetStyleSettings().GetHighContrastMode())
1126 static const Color aArrayAnkor
[] = {
1127 COL_AUTHOR1_DARK
, COL_AUTHOR2_DARK
, COL_AUTHOR3_DARK
,
1128 COL_AUTHOR4_DARK
, COL_AUTHOR5_DARK
, COL_AUTHOR6_DARK
,
1129 COL_AUTHOR7_DARK
, COL_AUTHOR8_DARK
, COL_AUTHOR9_DARK
};
1131 return Color( aArrayAnkor
[ aAuthorIndex
% (sizeof( aArrayAnkor
) / sizeof( aArrayAnkor
[0] ))]);
1134 return Color(COL_WHITE
);
1137 SdPage
* AnnotationManagerImpl::GetNextPage( SdPage
* pPage
, bool bForeward
)
1140 return bForeward
? GetFirstPage() : GetLastPage();
1142 sal_uInt16 nPageNum
= (pPage
->GetPageNum() - 1) >> 1;
1144 // first all non master pages
1145 if( !pPage
->IsMasterPage() )
1149 if( nPageNum
>= mpDoc
->GetSdPageCount(PK_STANDARD
)-1 )
1151 // we reached end of draw pages, start with master pages (skip handout master for draw)
1152 return mpDoc
->GetMasterSdPage( (mpDoc
->GetDocumentType() == DOCUMENT_TYPE_IMPRESS
) ? 0 : 1, PK_STANDARD
);
1159 return 0; // we are already on the first draw page, finished
1163 return mpDoc
->GetSdPage(nPageNum
, PK_STANDARD
);
1169 if( nPageNum
>= mpDoc
->GetMasterSdPageCount(PK_STANDARD
)-1 )
1171 return 0; // we reached the end, there is nothing more to see here
1177 if( nPageNum
== (mpDoc
->GetDocumentType() == DOCUMENT_TYPE_IMPRESS
) ? 0 : 1 )
1179 // we reached beginning of master pages, start with end if pages
1180 return mpDoc
->GetSdPage( mpDoc
->GetSdPageCount(PK_STANDARD
)-1, PK_STANDARD
);
1185 return mpDoc
->GetMasterSdPage(nPageNum
,PK_STANDARD
);
1189 SdPage
* AnnotationManagerImpl::GetFirstPage()
1191 // return first drawing page
1192 return mpDoc
->GetSdPage(0, PK_STANDARD
);
1195 SdPage
* AnnotationManagerImpl::GetLastPage()
1197 return mpDoc
->GetMasterSdPage( mpDoc
->GetMasterSdPageCount(PK_STANDARD
) - 1, PK_STANDARD
);
1200 SdPage
* AnnotationManagerImpl::GetCurrentPage()
1202 return mrBase
.GetMainViewShell()->getCurrentPage();
1205 // ====================================================================
1207 AnnotationManager::AnnotationManager( ViewShellBase
& rViewShellBase
)
1208 : mxImpl( new AnnotationManagerImpl( rViewShellBase
) )
1213 AnnotationManager::~AnnotationManager()
1218 void AnnotationManager::ExecuteAnnotation(SfxRequest
& rRequest
)
1220 mxImpl
->ExecuteAnnotation( rRequest
);
1223 void AnnotationManager::GetAnnotationState(SfxItemSet
& rItemSet
)
1225 mxImpl
->GetAnnotationState(rItemSet
);
1230 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */