summaryrefslogtreecommitdiff
path: root/sd/source/ui/annotations
diff options
context:
space:
mode:
Diffstat (limited to 'sd/source/ui/annotations')
-rw-r--r--sd/source/ui/annotations/annotationmanager.cxx1273
-rwxr-xr-xsd/source/ui/annotations/annotationmanagerimpl.hxx144
-rw-r--r--sd/source/ui/annotations/annotations.hrc65
-rw-r--r--sd/source/ui/annotations/annotations.src209
-rw-r--r--sd/source/ui/annotations/annotationtag.cxx790
-rw-r--r--sd/source/ui/annotations/annotationtag.hxx107
-rw-r--r--sd/source/ui/annotations/annotationwindow.cxx848
-rw-r--r--sd/source/ui/annotations/annotationwindow.hxx176
-rw-r--r--sd/source/ui/annotations/makefile.mk56
9 files changed, 3668 insertions, 0 deletions
diff --git a/sd/source/ui/annotations/annotationmanager.cxx b/sd/source/ui/annotations/annotationmanager.cxx
new file mode 100644
index 000000000000..aa42fec50f9c
--- /dev/null
+++ b/sd/source/ui/annotations/annotationmanager.cxx
@@ -0,0 +1,1273 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sd.hxx"
+
+#include "sddll.hxx"
+
+//#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/beans/XMultiPropertyStates.hpp>
+#include <com/sun/star/frame/XController.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/view/XSelectionSupplier.hpp>
+#include <com/sun/star/geometry/RealPoint2D.hpp>
+#include <com/sun/star/text/XText.hpp>
+#include <com/sun/star/document/XEventBroadcaster.hpp>
+#include <svx/svxids.hrc>
+#include <vcl/menu.hxx>
+#include <vcl/msgbox.hxx>
+
+#include <svl/style.hxx>
+#include <svl/itempool.hxx>
+#include <unotools/useroptions.hxx>
+#include <unotools/syslocale.hxx>
+#include <unotools/saveopt.hxx>
+
+#include <sfx2/imagemgr.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/objface.hxx>
+#include <sfx2/imagemgr.hxx>
+
+#include <editeng/editeng.hxx>
+#include <editeng/eeitem.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/outlobj.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/crsditem.hxx>
+
+#include <svx/svdetc.hxx>
+
+#include "annotationmanager.hxx"
+#include "annotationmanagerimpl.hxx"
+#include "annotationwindow.hxx"
+#include "annotations.hrc"
+
+#include "ToolBarManager.hxx"
+#include "DrawDocShell.hxx"
+#include "DrawViewShell.hxx"
+#include "DrawController.hxx"
+#include "glob.hrc"
+#include "sdresid.hxx"
+#include "EventMultiplexer.hxx"
+#include "ViewShellManager.hxx"
+#include "helpids.h"
+#include "sdpage.hxx"
+#include "drawdoc.hxx"
+#include "textapi.hxx"
+#include "optsitem.hxx"
+
+#define C2U(x) OUString( RTL_CONSTASCII_USTRINGPARAM( x ) )
+using ::rtl::OUString;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::document;
+using namespace ::com::sun::star::geometry;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::text;
+using namespace ::com::sun::star::view;
+using namespace ::com::sun::star::style;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::ui;
+using namespace ::com::sun::star::task;
+using namespace ::com::sun::star::office;
+
+namespace sd {
+
+// --------------------------------------------------------------------
+
+extern TextApiObject* getTextApiObject( const Reference< XAnnotation >& xAnnotation );
+
+// --------------------------------------------------------------------
+
+SfxItemPool* GetAnnotationPool()
+{
+ static SfxItemPool* mpAnnotationPool = 0;
+ if( mpAnnotationPool == 0 )
+ {
+ mpAnnotationPool = EditEngine::CreatePool( sal_False );
+ mpAnnotationPool->SetPoolDefaultItem(SvxFontHeightItem(423,100,EE_CHAR_FONTHEIGHT));
+
+ Font aAppFont( Application::GetSettings().GetStyleSettings().GetAppFont() );
+ String EMPTYSTRING;
+ mpAnnotationPool->SetPoolDefaultItem(SvxFontItem(aAppFont.GetFamily(),aAppFont.GetName(), EMPTYSTRING,PITCH_DONTKNOW,RTL_TEXTENCODING_DONTKNOW,EE_CHAR_FONTINFO));
+ }
+
+ return mpAnnotationPool;
+}
+
+// --------------------------------------------------------------------
+
+static SfxBindings* getBindings( ViewShellBase& rBase )
+{
+ if( rBase.GetMainViewShell().get() && rBase.GetMainViewShell()->GetViewFrame() )
+ return &rBase.GetMainViewShell()->GetViewFrame()->GetBindings();
+ else
+ return 0;
+}
+
+// --------------------------------------------------------------------
+
+static SfxDispatcher* getDispatcher( ViewShellBase& rBase )
+{
+ if( rBase.GetMainViewShell().get() && rBase.GetMainViewShell()->GetViewFrame() )
+ return rBase.GetMainViewShell()->GetViewFrame()->GetDispatcher();
+ else
+ return 0;
+}
+
+com::sun::star::util::DateTime getCurrentDateTime()
+{
+ TimeValue osltime;
+ osl_getSystemTime( &osltime );
+ oslDateTime osldt;
+ osl_getDateTimeFromTimeValue( &osltime, &osldt );
+ return com::sun::star::util::DateTime( 0, osldt.Seconds, osldt.Minutes, osldt.Hours, osldt.Day, osldt.Month, osldt.Year );
+}
+
+OUString getAnnotationDateTimeString( const Reference< XAnnotation >& xAnnotation )
+{
+ OUString sRet;
+ if( xAnnotation.is() )
+ {
+ const LocaleDataWrapper& rLocalData = SvtSysLocale().GetLocaleData();
+
+ com::sun::star::util::DateTime aDateTime( xAnnotation->getDateTime() );
+
+ Date aDate = Date( aDateTime.Day, aDateTime.Month, aDateTime.Year );
+ if (aDate==Date())
+ sRet = sRet + String(SdResId(STR_ANNOTATION_TODAY));
+ else
+ if (aDate == Date(Date()-1))
+ sRet = sRet + String(SdResId(STR_ANNOTATION_YESTERDAY));
+ else
+ if (aDate.IsValid() )
+ sRet = sRet + rLocalData.getDate(aDate);
+
+ Time aTime( aDateTime.Hours, aDateTime.Minutes, aDateTime.Seconds, aDateTime.HundredthSeconds );
+ if(aTime.GetTime() != 0)
+ sRet = sRet + rtl::OUString::createFromAscii(" ") + rLocalData.getTime( aTime,false );
+ }
+ return sRet;
+}
+
+// --------------------------------------------------------------------
+
+AnnotationManagerImpl::AnnotationManagerImpl( ViewShellBase& rViewShellBase )
+: AnnotationManagerImplBase( m_aMutex )
+, mrBase( rViewShellBase )
+, mpDoc( rViewShellBase.GetDocument() )
+, mbShowAnnotations( true )
+, mnUpdateTagsEvent( 0 )
+{
+ SdOptions* pOptions = SD_MOD()->GetSdOptions(mpDoc->GetDocumentType());
+ if( pOptions )
+ mbShowAnnotations = pOptions->IsShowComments() == TRUE;
+}
+
+// --------------------------------------------------------------------
+
+void AnnotationManagerImpl::init()
+{
+ // get current controller and initialize listeners
+ try
+ {
+ addListener();
+ mxView = Reference< XDrawView >::query(mrBase.GetController());
+ }
+ catch( Exception& e )
+ {
+ (void)e;
+ DBG_ERROR( "sd::AnnotationManagerImpl::AnnotationManagerImpl(), Exception caught!" );
+ }
+
+ try
+ {
+ Reference<XEventBroadcaster> xModel (mrBase.GetDocShell()->GetModel(), UNO_QUERY_THROW );
+ Reference<XEventListener> xListener( this );
+ xModel->addEventListener( xListener );
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+// --------------------------------------------------------------------
+
+// WeakComponentImplHelper1
+void SAL_CALL AnnotationManagerImpl::disposing ()
+{
+ try
+ {
+ Reference<XEventBroadcaster> xModel (mrBase.GetDocShell()->GetModel(), UNO_QUERY_THROW );
+ Reference<XEventListener> xListener( this );
+ xModel->removeEventListener( xListener );
+ }
+ catch( Exception& )
+ {
+ }
+
+ removeListener();
+ DisposeTags();
+
+ if( mnUpdateTagsEvent )
+ {
+ Application::RemoveUserEvent( mnUpdateTagsEvent );
+ mnUpdateTagsEvent = 0;
+ }
+
+ mxView.clear();
+ mxCurrentPage.clear();
+}
+
+// --------------------------------------------------------------------
+
+// XEventListener
+void SAL_CALL AnnotationManagerImpl::notifyEvent( const ::com::sun::star::document::EventObject& aEvent ) throw (::com::sun::star::uno::RuntimeException)
+{
+ if( aEvent.EventName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "OnAnnotationInserted") ) ||
+ aEvent.EventName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "OnAnnotationRemoved") ) ||
+ aEvent.EventName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "OnAnnotationChanged" )) )
+ {
+ UpdateTags();
+ }
+}
+
+void SAL_CALL AnnotationManagerImpl::disposing( const ::com::sun::star::lang::EventObject& /*Source*/ ) throw (::com::sun::star::uno::RuntimeException)
+{
+}
+
+void AnnotationManagerImpl::ShowAnnotations( bool bShow )
+{
+ // enforce show annotations if a new annotation is inserted
+ if( mbShowAnnotations != bShow )
+ {
+ mbShowAnnotations = bShow;
+
+ SdOptions* pOptions = SD_MOD()->GetSdOptions(mpDoc->GetDocumentType());
+ if( pOptions )
+ pOptions->SetShowComments( mbShowAnnotations ? sal_True : sal_False );
+
+ UpdateTags();
+ }
+}
+
+// --------------------------------------------------------------------
+
+void AnnotationManagerImpl::ExecuteAnnotation(SfxRequest& rReq )
+{
+ switch( rReq.GetSlot() )
+ {
+ case SID_INSERT_POSTIT:
+ ExecuteInsertAnnotation( rReq );
+ break;
+ case SID_DELETE_POSTIT:
+ case SID_DELETEALL_POSTIT:
+ case SID_DELETEALLBYAUTHOR_POSTIT:
+ ExecuteDeleteAnnotation( rReq );
+ break;
+ case SID_PREVIOUS_POSTIT:
+ case SID_NEXT_POSTIT:
+ SelectNextAnnotation( rReq.GetSlot() == SID_NEXT_POSTIT );
+ break;
+ case SID_REPLYTO_POSTIT:
+ ExecuteReplyToAnnotation( rReq );
+ break;
+ case SID_SHOW_POSTIT:
+ ShowAnnotations( !mbShowAnnotations );
+ break;
+ }
+}
+
+// --------------------------------------------------------------------
+
+void AnnotationManagerImpl::ExecuteInsertAnnotation(SfxRequest& /*rReq*/)
+{
+ ShowAnnotations(true);
+ InsertAnnotation();
+}
+
+// --------------------------------------------------------------------
+
+void AnnotationManagerImpl::ExecuteDeleteAnnotation(SfxRequest& rReq)
+{
+ ShowAnnotations( true );
+
+ const SfxItemSet* pArgs = rReq.GetArgs();
+
+ switch( rReq.GetSlot() )
+ {
+ case SID_DELETEALL_POSTIT:
+ DeleteAllAnnotations();
+ break;
+ case SID_DELETEALLBYAUTHOR_POSTIT:
+ if( pArgs )
+ {
+ const SfxPoolItem* pPoolItem = NULL;
+ if( SFX_ITEM_SET == pArgs->GetItemState( SID_DELETEALLBYAUTHOR_POSTIT, TRUE, &pPoolItem ) )
+ {
+ OUString sAuthor( (( const SfxStringItem* ) pPoolItem )->GetValue() );
+ DeleteAnnotationsByAuthor( sAuthor );
+ }
+ }
+ break;
+ case SID_DELETE_POSTIT:
+ {
+ Reference< XAnnotation > xAnnotation;
+
+ if( rReq.GetSlot() == SID_DELETE_POSTIT )
+ {
+ if( pArgs )
+ {
+ const SfxPoolItem* pPoolItem = NULL;
+ if( SFX_ITEM_SET == pArgs->GetItemState( SID_DELETE_POSTIT, TRUE, &pPoolItem ) )
+ ( ( const SfxUnoAnyItem* ) pPoolItem )->GetValue() >>= xAnnotation;
+ }
+ }
+
+ if( !xAnnotation.is() )
+ GetSelectedAnnotation( xAnnotation );
+
+ DeleteAnnotation( xAnnotation );
+ }
+ break;
+ }
+
+ UpdateTags();
+}
+
+// --------------------------------------------------------------------
+
+void AnnotationManagerImpl::InsertAnnotation()
+{
+ SdPage* pPage = GetCurrentPage();
+ if( pPage )
+ {
+ if( mpDoc->IsUndoEnabled() )
+ mpDoc->BegUndo( String( SdResId( STR_ANNOTATION_UNDO_INSERT ) ) );
+
+ // find free space for new annotation
+ int y = 0, x = 0;
+
+ AnnotationVector aAnnotations( pPage->getAnnotations() );
+ if( !aAnnotations.empty() )
+ {
+ const int page_width = pPage->GetSize().Width();
+ const int width = 1000;
+ const int height = 800;
+ Rectangle aTagRect;
+
+ while( true )
+ {
+ Rectangle aNewRect( x, y, x + width - 1, y + height - 1 );
+ bool bFree = true;
+
+ for( AnnotationVector::iterator iter = aAnnotations.begin(); iter != aAnnotations.end(); iter++ )
+ {
+ RealPoint2D aPoint( (*iter)->getPosition() );
+ aTagRect.nLeft = sal::static_int_cast< long >( aPoint.X * 100.0 );
+ aTagRect.nTop = sal::static_int_cast< long >( aPoint.Y * 100.0 );
+ aTagRect.nRight = aTagRect.nLeft + width - 1;
+ aTagRect.nBottom = aTagRect.nTop + height - 1;
+
+ if( aNewRect.IsOver( aTagRect ) )
+ {
+ bFree = false;
+ break;
+ }
+ }
+
+ if( bFree == false)
+ {
+ x += width;
+ if( x > page_width )
+ {
+ x = 0;
+ y += height;
+ }
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+
+ Reference< XAnnotation > xAnnotation;
+ pPage->createAnnotation( xAnnotation );
+
+ // set current author to new annotation
+ SvtUserOptions aUserOptions;
+ xAnnotation->setAuthor( aUserOptions.GetFullName() );
+
+ // set current time to new annotation
+ xAnnotation->setDateTime( getCurrentDateTime() );
+
+ // set position
+ RealPoint2D aPos( ((double)x) / 100.0, ((double)y) / 100.0 );
+ xAnnotation->setPosition( aPos );
+
+ if( mpDoc->IsUndoEnabled() )
+ mpDoc->EndUndo();
+
+ UpdateTags(true);
+ SelectAnnotation( xAnnotation, true );
+ }
+}
+
+// --------------------------------------------------------------------
+
+void AnnotationManagerImpl::ExecuteReplyToAnnotation( SfxRequest& rReq )
+{
+ Reference< XAnnotation > xAnnotation;
+ const SfxItemSet* pArgs = rReq.GetArgs();
+ if( pArgs )
+ {
+ const SfxPoolItem* pPoolItem = NULL;
+ if( SFX_ITEM_SET == pArgs->GetItemState( rReq.GetSlot(), TRUE, &pPoolItem ) )
+ ( ( const SfxUnoAnyItem* ) pPoolItem )->GetValue() >>= xAnnotation;
+ }
+
+
+ TextApiObject* pTextApi = getTextApiObject( xAnnotation );
+ if( pTextApi )
+ {
+ std::auto_ptr< ::Outliner > pOutliner( new ::Outliner(GetAnnotationPool(),OUTLINERMODE_TEXTOBJECT) );
+
+ mpDoc->SetCalcFieldValueHdl( pOutliner.get() );
+ pOutliner->SetUpdateMode( TRUE );
+
+ String aStr(SdResId(STR_ANNOTATION_REPLY));
+ OUString sAuthor( xAnnotation->getAuthor() );
+ if( sAuthor.getLength() == 0 )
+ sAuthor = String( SdResId( STR_ANNOTATION_NOAUTHOR ) );
+
+ aStr.SearchAndReplaceAscii("%1", sAuthor);
+
+ aStr.Append( String(RTL_CONSTASCII_USTRINGPARAM(" (") ) );
+ aStr.Append( String( getAnnotationDateTimeString( xAnnotation ) ) );
+ aStr.Append( String(RTL_CONSTASCII_USTRINGPARAM("): \"") ) );
+
+ String sQuote( pTextApi->GetText() );
+
+ if( sQuote.Len() == 0 )
+ sQuote = String( RTL_CONSTASCII_USTRINGPARAM( "..." ) );
+ aStr.Append( sQuote );
+ aStr.Append( String(RTL_CONSTASCII_USTRINGPARAM("\"\n") ) );
+
+ USHORT nParaCount = aStr.GetTokenCount( '\n' );
+ for( USHORT nPara = 0; nPara < nParaCount; nPara++ )
+ pOutliner->Insert( aStr.GetToken( nPara, '\n' ), LIST_APPEND, -1 );
+
+ if( pOutliner->GetParagraphCount() > 1 )
+ {
+ SfxItemSet aAnswerSet( pOutliner->GetEmptyItemSet() );
+ aAnswerSet.Put(SvxPostureItem(ITALIC_NORMAL,EE_CHAR_ITALIC));
+
+ ESelection aSel;
+ aSel.nEndPara = (USHORT)pOutliner->GetParagraphCount()-2;
+ aSel.nEndPos = pOutliner->GetText( pOutliner->GetParagraph( aSel.nEndPara ) ).Len();
+
+ pOutliner->QuickSetAttribs( aAnswerSet, aSel );
+ }
+
+ std::auto_ptr< OutlinerParaObject > pOPO( pOutliner->CreateParaObject() );
+ pTextApi->SetText( *pOPO.get() );
+
+ SvtUserOptions aUserOptions;
+ xAnnotation->setAuthor( aUserOptions.GetFullName() );
+
+ // set current time to reply
+ xAnnotation->setDateTime( getCurrentDateTime() );
+
+ UpdateTags(true);
+ SelectAnnotation( xAnnotation, true );
+ }
+}
+
+// --------------------------------------------------------------------
+
+void AnnotationManagerImpl::DeleteAnnotation( Reference< XAnnotation > xAnnotation )
+{
+ SdPage* pPage = GetCurrentPage();
+
+ if( xAnnotation.is() && pPage )
+ {
+ if( mpDoc->IsUndoEnabled() )
+ mpDoc->BegUndo( String( SdResId( STR_ANNOTATION_UNDO_DELETE ) ) );
+
+ pPage->removeAnnotation( xAnnotation );
+
+ if( mpDoc->IsUndoEnabled() )
+ mpDoc->EndUndo();
+
+ UpdateTags();
+ }
+}
+
+void AnnotationManagerImpl::DeleteAnnotationsByAuthor( const rtl::OUString& sAuthor )
+{
+ if( mpDoc->IsUndoEnabled() )
+ mpDoc->BegUndo( String( SdResId( STR_ANNOTATION_UNDO_DELETE ) ) );
+
+ SdPage* pPage = 0;
+ do
+ {
+ pPage = GetNextPage( pPage, true );
+
+ if( pPage && !pPage->getAnnotations().empty() )
+ {
+ AnnotationVector aAnnotations( pPage->getAnnotations() );
+ for( AnnotationVector::iterator iter = aAnnotations.begin(); iter != aAnnotations.end(); iter++ )
+ {
+ Reference< XAnnotation > xAnnotation( *iter );
+ if( xAnnotation->getAuthor() == sAuthor )
+ {
+ if( mxSelectedAnnotation == xAnnotation )
+ mxSelectedAnnotation.clear();
+ pPage->removeAnnotation( xAnnotation );
+ }
+ }
+ }
+ } while( pPage );
+
+ if( mpDoc->IsUndoEnabled() )
+ mpDoc->EndUndo();
+}
+
+void AnnotationManagerImpl::DeleteAllAnnotations()
+{
+ if( mpDoc->IsUndoEnabled() )
+ mpDoc->BegUndo( String( SdResId( STR_ANNOTATION_UNDO_DELETE ) ) );
+
+ SdPage* pPage = 0;
+ do
+ {
+ pPage = GetNextPage( pPage, true );
+
+ if( pPage && !pPage->getAnnotations().empty() )
+ {
+
+ AnnotationVector aAnnotations( pPage->getAnnotations() );
+ for( AnnotationVector::iterator iter = aAnnotations.begin(); iter != aAnnotations.end(); iter++ )
+ {
+ pPage->removeAnnotation( (*iter) );
+ }
+ }
+ }
+ while( pPage );
+
+ mxSelectedAnnotation.clear();
+
+ if( mpDoc->IsUndoEnabled() )
+ mpDoc->EndUndo();
+}
+
+// --------------------------------------------------------------------
+
+void AnnotationManagerImpl::GetAnnotationState(SfxItemSet& rSet)
+{
+ SdPage* pCurrentPage = GetCurrentPage();
+
+ const bool bReadOnly = mrBase.GetDocShell()->IsReadOnly();
+ const bool bWrongPageKind = (pCurrentPage == 0) || (pCurrentPage->GetPageKind() != PK_STANDARD);
+
+ const SvtSaveOptions::ODFDefaultVersion nCurrentODFVersion( SvtSaveOptions().GetODFDefaultVersion() );
+
+ if( bReadOnly || bWrongPageKind || (nCurrentODFVersion != SvtSaveOptions::ODFVER_LATEST) )
+ rSet.DisableItem( SID_INSERT_POSTIT );
+
+ rSet.Put(SfxBoolItem(SID_SHOW_POSTIT, mbShowAnnotations));
+
+ Reference< XAnnotation > xAnnotation;
+ GetSelectedAnnotation( xAnnotation );
+
+ if( !xAnnotation.is() || bReadOnly )
+ rSet.DisableItem( SID_DELETE_POSTIT );
+
+ SdPage* pPage = 0;
+
+ bool bHasAnnotations = false;
+ do
+ {
+ pPage = GetNextPage( pPage, true );
+
+ if( pPage && !pPage->getAnnotations().empty() )
+ bHasAnnotations = true;
+ }
+ while( pPage && !bHasAnnotations );
+
+ if( !bHasAnnotations || bReadOnly )
+ {
+ rSet.DisableItem( SID_DELETEALL_POSTIT );
+ }
+
+ if( bWrongPageKind || !bHasAnnotations )
+ {
+ rSet.DisableItem( SID_PREVIOUS_POSTIT );
+ rSet.DisableItem( SID_NEXT_POSTIT );
+ }
+}
+
+// --------------------------------------------------------------------
+
+void AnnotationManagerImpl::SelectNextAnnotation(bool bForeward)
+{
+ ShowAnnotations( true );
+
+ Reference< XAnnotation > xCurrent;
+ GetSelectedAnnotation( xCurrent );
+ SdPage* pPage = GetCurrentPage();
+ if( !pPage )
+ return;
+
+ AnnotationVector aAnnotations( pPage->getAnnotations() );
+
+ if( bForeward )
+ {
+ if( xCurrent.is() )
+ {
+ for( AnnotationVector::iterator iter = aAnnotations.begin(); iter != aAnnotations.end(); iter++ )
+ {
+ if( (*iter) == xCurrent )
+ {
+ iter++;
+ if( iter != aAnnotations.end() )
+ {
+ SelectAnnotation( (*iter) );
+ return;
+ }
+ break;
+ }
+ }
+ }
+ else if( !aAnnotations.empty() )
+ {
+ SelectAnnotation( *(aAnnotations.begin()) );
+ return;
+ }
+ }
+ else
+ {
+ if( xCurrent.is() )
+ {
+ for( AnnotationVector::iterator iter = aAnnotations.begin(); iter != aAnnotations.end(); iter++ )
+ {
+ if( (*iter) == xCurrent )
+ {
+ if( iter != aAnnotations.begin() )
+ {
+ iter--;
+ SelectAnnotation( (*iter) );
+ return;
+
+ }
+ break;
+ }
+ }
+ }
+ else if( !aAnnotations.empty() )
+ {
+ AnnotationVector::iterator iter( aAnnotations.end() );
+ SelectAnnotation( *(--iter) );
+ return;
+ }
+ }
+
+ mxSelectedAnnotation.clear();
+ do
+ {
+ do
+ {
+ pPage = GetNextPage( pPage, bForeward );
+
+ if( pPage && !pPage->getAnnotations().empty() )
+ {
+ // switch to next/previous slide with annotations
+ ::boost::shared_ptr<DrawViewShell> pDrawViewShell(::boost::dynamic_pointer_cast<DrawViewShell>(mrBase.GetMainViewShell()));
+ if (pDrawViewShell.get() != NULL)
+ {
+ pDrawViewShell->ChangeEditMode(pPage->IsMasterPage() ? EM_MASTERPAGE : EM_PAGE, FALSE);
+ pDrawViewShell->SwitchPage((pPage->GetPageNum() - 1) >> 1);
+
+ SfxDispatcher* pDispatcher = getDispatcher( mrBase );
+ if( pDispatcher )
+ pDispatcher->Execute( bForeward ? SID_NEXT_POSTIT : SID_PREVIOUS_POSTIT );
+
+ return;
+ }
+ }
+ }
+ while( pPage );
+
+ // The question text depends on the search direction.
+ bool bImpress = mpDoc->GetDocumentType() == DOCUMENT_TYPE_IMPRESS;
+ sal_uInt16 nStringId;
+ if(bForeward)
+ nStringId = bImpress ? STR_ANNOTATION_WRAP_FORWARD : STR_ANNOTATION_WRAP_FORWARD_DRAW;
+ else
+ nStringId = bImpress ? STR_ANNOTATION_WRAP_BACKWARD : STR_ANNOTATION_WRAP_BACKWARD_DRAW;
+
+ // Pop up question box that asks the user whether to wrap arround.
+ // The dialog is made modal with respect to the whole application.
+ QueryBox aQuestionBox (
+ NULL,
+ WB_YES_NO | WB_DEF_YES,
+ String(SdResId(nStringId)));
+ aQuestionBox.SetImage (QueryBox::GetStandardImage());
+ USHORT nBoxResult = aQuestionBox.Execute();
+ if(nBoxResult != BUTTONID_YES)
+ break;
+ }
+ while( true );
+}
+
+// --------------------------------------------------------------------
+
+void AnnotationManagerImpl::onTagSelected( AnnotationTag& rTag )
+{
+ mxSelectedAnnotation = rTag.GetAnnotation();
+ invalidateSlots();
+}
+
+// --------------------------------------------------------------------
+
+void AnnotationManagerImpl::onTagDeselected( AnnotationTag& rTag )
+{
+ if( rTag.GetAnnotation() == mxSelectedAnnotation )
+ {
+ mxSelectedAnnotation.clear();
+ invalidateSlots();
+ }
+}
+
+// --------------------------------------------------------------------
+
+void AnnotationManagerImpl::SelectAnnotation( ::com::sun::star::uno::Reference< ::com::sun::star::office::XAnnotation > xAnnotation, bool bEdit /* = FALSE */ )
+{
+ mxSelectedAnnotation = xAnnotation;
+
+ for( AnnotationTagVector::iterator iter( maTagVector.begin() ); iter != maTagVector.end(); iter++ )
+ {
+ if( (*iter)->GetAnnotation() == xAnnotation )
+ {
+ SmartTagReference xTag( (*iter).get() );
+ mrBase.GetMainViewShell()->GetView()->getSmartTags().select( xTag );
+ (*iter)->OpenPopup( bEdit );
+ break;
+ }
+ }
+}
+
+// --------------------------------------------------------------------
+
+void AnnotationManagerImpl::GetSelectedAnnotation( ::com::sun::star::uno::Reference< ::com::sun::star::office::XAnnotation >& xAnnotation )
+{
+ xAnnotation = mxSelectedAnnotation;
+}
+
+void AnnotationManagerImpl::invalidateSlots()
+{
+ SfxBindings* pBindings = getBindings( mrBase );
+ if( pBindings )
+ {
+ pBindings->Invalidate( SID_INSERT_POSTIT );
+ pBindings->Invalidate( SID_DELETE_POSTIT );
+ pBindings->Invalidate( SID_DELETEALL_POSTIT );
+ pBindings->Invalidate( SID_PREVIOUS_POSTIT );
+ pBindings->Invalidate( SID_NEXT_POSTIT );
+ pBindings->Invalidate( SID_UNDO );
+ pBindings->Invalidate( SID_REDO );
+ }
+}
+
+// --------------------------------------------------------------------
+
+void AnnotationManagerImpl::onSelectionChanged()
+{
+ if( mxView.is() && mrBase.GetDrawView() ) try
+ {
+ Reference< XAnnotationAccess > xPage( mxView->getCurrentPage(), UNO_QUERY );
+
+ if( xPage != mxCurrentPage )
+ {
+ mxCurrentPage = xPage;
+
+ UpdateTags(true);
+ }
+ }
+ catch( Exception& )
+ {
+ DBG_ERROR( "sd::AnnotationManagerImpl::onSelectionChanged(), exception caught!" );
+ }
+}
+
+void AnnotationManagerImpl::UpdateTags( bool bSynchron )
+{
+ if( bSynchron )
+ {
+ if( mnUpdateTagsEvent )
+ Application::RemoveUserEvent( mnUpdateTagsEvent );
+
+ UpdateTagsHdl(0);
+ }
+ else
+ {
+ if( !mnUpdateTagsEvent && mxView.is() )
+ mnUpdateTagsEvent = Application::PostUserEvent( LINK( this, AnnotationManagerImpl, UpdateTagsHdl ) );
+ }
+}
+
+IMPL_LINK(AnnotationManagerImpl,UpdateTagsHdl, void *, EMPTYARG)
+{
+ mnUpdateTagsEvent = 0;
+ DisposeTags();
+
+ if( mbShowAnnotations )
+ CreateTags();
+
+ if( mrBase.GetDrawView() )
+ static_cast< ::sd::View* >( mrBase.GetDrawView() )->updateHandles();
+
+ invalidateSlots();
+
+ return 0;
+}
+
+void AnnotationManagerImpl::CreateTags()
+{
+
+ if( mxCurrentPage.is() && mpDoc ) try
+ {
+ int nIndex = 1;
+ maFont = Application::GetSettings().GetStyleSettings().GetAppFont();
+
+ rtl::Reference< AnnotationTag > xSelectedTag;
+
+ Reference< XAnnotationEnumeration > xEnum( mxCurrentPage->createAnnotationEnumeration() );
+ while( xEnum->hasMoreElements() )
+ {
+ Reference< XAnnotation > xAnnotation( xEnum->nextElement() );
+ Color aColor( GetColorLight( mpDoc->GetAnnotationAuthorIndex( xAnnotation->getAuthor() ) ) );
+ rtl::Reference< AnnotationTag > xTag( new AnnotationTag( *this, *mrBase.GetMainViewShell()->GetView(), xAnnotation, aColor, nIndex++, maFont ) );
+ maTagVector.push_back(xTag);
+
+ if( xAnnotation == mxSelectedAnnotation )
+ {
+ xSelectedTag = xTag;
+ }
+ }
+
+ if( xSelectedTag.is() )
+ {
+ SmartTagReference xTag( xSelectedTag.get() );
+ mrBase.GetMainViewShell()->GetView()->getSmartTags().select( xTag );
+ }
+ else
+ {
+ // no tag, no selection!
+ mxSelectedAnnotation.clear();
+ }
+ }
+ catch( Exception& )
+ {
+ DBG_ERROR( "sd::AnnotationManagerImpl::onSelectionChanged(), exception caught!" );
+ }
+}
+
+// --------------------------------------------------------------------
+
+void AnnotationManagerImpl::DisposeTags()
+{
+ if( !maTagVector.empty() )
+ {
+ AnnotationTagVector::iterator iter = maTagVector.begin();
+ do
+ {
+ (*iter++)->Dispose();
+ }
+ while( iter != maTagVector.end() );
+
+ maTagVector.clear();
+ }
+}
+
+// --------------------------------------------------------------------
+
+void AnnotationManagerImpl::addListener()
+{
+ Link aLink( LINK(this,AnnotationManagerImpl,EventMultiplexerListener) );
+ mrBase.GetEventMultiplexer()->AddEventListener (
+ aLink,
+ tools::EventMultiplexerEvent::EID_EDIT_VIEW_SELECTION
+ | tools::EventMultiplexerEvent::EID_CURRENT_PAGE
+ | tools::EventMultiplexerEvent::EID_MAIN_VIEW_REMOVED
+ | tools::EventMultiplexerEvent::EID_MAIN_VIEW_ADDED);
+}
+
+// --------------------------------------------------------------------
+
+void AnnotationManagerImpl::removeListener()
+{
+ Link aLink( LINK(this,AnnotationManagerImpl,EventMultiplexerListener) );
+ mrBase.GetEventMultiplexer()->RemoveEventListener( aLink );
+}
+
+// --------------------------------------------------------------------
+
+IMPL_LINK(AnnotationManagerImpl,EventMultiplexerListener,
+ tools::EventMultiplexerEvent*,pEvent)
+{
+ switch (pEvent->meEventId)
+ {
+ case tools::EventMultiplexerEvent::EID_CURRENT_PAGE:
+ case tools::EventMultiplexerEvent::EID_EDIT_VIEW_SELECTION:
+ onSelectionChanged();
+ break;
+
+ case tools::EventMultiplexerEvent::EID_MAIN_VIEW_REMOVED:
+ mxView = Reference<XDrawView>();
+ onSelectionChanged();
+ break;
+
+ case tools::EventMultiplexerEvent::EID_MAIN_VIEW_ADDED:
+ mxView = Reference<XDrawView>::query( mrBase.GetController() );
+ onSelectionChanged();
+ break;
+ }
+ return 0;
+}
+
+OUString AnnotationManagerImpl::GetHelpText( ::com::sun::star::uno::Reference< ::com::sun::star::office::XAnnotation >& xAnnotation )
+{
+ OUString sRet;
+ if( xAnnotation.is() )
+ {
+ OUString sAuthor( xAnnotation->getAuthor() );
+ if( sAuthor.getLength() != 0 )
+ {
+ sRet += sAuthor;
+ }
+ sRet += OUString( RTL_CONSTASCII_USTRINGPARAM( " [" ) );
+
+ sRet += getAnnotationDateTimeString( xAnnotation );
+ sRet += OUString( RTL_CONSTASCII_USTRINGPARAM( "]\n" ) );
+
+ Reference< XText > xText( xAnnotation->getTextRange() );
+ if( xText.is() )
+ sRet += xText->getString();
+ }
+
+ return sRet;
+}
+
+
+void AnnotationManagerImpl::ExecuteAnnotationContextMenu( Reference< XAnnotation > xAnnotation, ::Window* pParent, const Rectangle& rContextRect, bool bButtonMenu /* = false */ )
+{
+ SfxDispatcher* pDispatcher( getDispatcher( mrBase ) );
+ if( !pDispatcher )
+ return;
+
+ const bool bReadOnly = mrBase.GetDocShell()->IsReadOnly();
+
+ AnnotationWindow* pAnnotationWindow = bButtonMenu ? 0 : dynamic_cast< AnnotationWindow* >( pParent );
+
+ if( bReadOnly && !pAnnotationWindow )
+ return;
+
+ std::auto_ptr< PopupMenu > pMenu( new PopupMenu( SdResId( pAnnotationWindow ? RID_ANNOTATION_CONTEXTMENU : RID_ANNOTATION_TAG_CONTEXTMENU ) ) );
+
+ SvtUserOptions aUserOptions;
+ OUString sCurrentAuthor( aUserOptions.GetFullName() );
+ OUString sAuthor( xAnnotation->getAuthor() );
+
+ String aStr( pMenu->GetItemText( SID_DELETEALLBYAUTHOR_POSTIT ) ), aReplace( sAuthor );
+ if( aReplace.Len() == 0 )
+ aReplace = String( SdResId( STR_ANNOTATION_NOAUTHOR ) );
+ aStr.SearchAndReplaceAscii("%1", aReplace);
+ pMenu->SetItemText( SID_DELETEALLBYAUTHOR_POSTIT, aStr );
+ pMenu->EnableItem( SID_REPLYTO_POSTIT, (sAuthor != sCurrentAuthor) && !bReadOnly );
+ pMenu->EnableItem( SID_DELETE_POSTIT, (xAnnotation.is() && !bReadOnly) ? TRUE : FALSE );
+ pMenu->EnableItem( SID_DELETEALLBYAUTHOR_POSTIT, !bReadOnly );
+ pMenu->EnableItem( SID_DELETEALL_POSTIT, !bReadOnly );
+
+ if( pAnnotationWindow )
+ {
+ if( pAnnotationWindow->IsProtected() || bReadOnly )
+ {
+ pMenu->EnableItem( SID_ATTR_CHAR_WEIGHT, FALSE );
+ pMenu->EnableItem( SID_ATTR_CHAR_POSTURE, FALSE );
+ pMenu->EnableItem( SID_ATTR_CHAR_UNDERLINE, FALSE );
+ pMenu->EnableItem( SID_ATTR_CHAR_STRIKEOUT, FALSE );
+ pMenu->EnableItem( SID_PASTE, FALSE );
+ }
+ else
+ {
+ SfxItemSet aSet(pAnnotationWindow->getView()->GetAttribs());
+
+ if ( aSet.GetItemState( EE_CHAR_WEIGHT ) == SFX_ITEM_ON )
+ {
+ if( ((const SvxWeightItem&)aSet.Get( EE_CHAR_WEIGHT )).GetWeight() == WEIGHT_BOLD )
+ pMenu->CheckItem( SID_ATTR_CHAR_WEIGHT );
+ }
+
+ if ( aSet.GetItemState( EE_CHAR_ITALIC ) == SFX_ITEM_ON )
+ {
+ if( ((const SvxPostureItem&)aSet.Get( EE_CHAR_ITALIC )).GetPosture() != ITALIC_NONE )
+ pMenu->CheckItem( SID_ATTR_CHAR_POSTURE );
+
+ }
+ if ( aSet.GetItemState( EE_CHAR_UNDERLINE ) == SFX_ITEM_ON )
+ {
+ if( ((const SvxUnderlineItem&)aSet.Get( EE_CHAR_UNDERLINE )).GetLineStyle() != UNDERLINE_NONE )
+ pMenu->CheckItem( SID_ATTR_CHAR_UNDERLINE );
+ }
+
+ if ( aSet.GetItemState( EE_CHAR_STRIKEOUT ) == SFX_ITEM_ON )
+ {
+ if( ((const SvxCrossedOutItem&)aSet.Get( EE_CHAR_STRIKEOUT )).GetStrikeout() != STRIKEOUT_NONE )
+ pMenu->CheckItem( SID_ATTR_CHAR_STRIKEOUT );
+ }
+ TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pAnnotationWindow ) );
+ pMenu->EnableItem( SID_PASTE, aDataHelper.GetFormatCount() != 0 );
+ }
+
+ pMenu->EnableItem( SID_COPY, pAnnotationWindow->getView()->HasSelection() );
+ }
+
+ USHORT nId = 0;
+
+ // set slot images
+ Reference< ::com::sun::star::frame::XFrame > xFrame( mrBase.GetMainViewShell()->GetViewFrame()->GetFrame().GetFrameInterface() );
+ if( xFrame.is() )
+ {
+ const bool bHighContrast = Application::GetSettings().GetStyleSettings().GetHighContrastMode();
+ for( USHORT nPos = 0; nPos < pMenu->GetItemCount(); nPos++ )
+ {
+ nId = pMenu->GetItemId( nPos );
+ if( pMenu->IsItemEnabled( nId ) )
+ {
+ OUString sSlotURL( RTL_CONSTASCII_USTRINGPARAM( "slot:" ));
+ sSlotURL += OUString::valueOf( sal_Int32( nId ));
+
+ Image aImage( GetImage( xFrame, sSlotURL, false, bHighContrast ) );
+ if( !!aImage )
+ pMenu->SetItemImage( nId, aImage );
+ }
+ }
+ }
+
+ nId = pMenu->Execute( pParent, rContextRect, POPUPMENU_EXECUTE_DOWN|POPUPMENU_NOMOUSEUPCLOSE );
+ switch( nId )
+ {
+ case SID_REPLYTO_POSTIT:
+ {
+ const SfxUnoAnyItem aItem( SID_REPLYTO_POSTIT, Any( xAnnotation ) );
+ pDispatcher->Execute( SID_REPLYTO_POSTIT, SFX_CALLMODE_ASYNCHRON, &aItem, 0 );
+ break;
+ }
+ case SID_DELETE_POSTIT:
+ {
+ const SfxUnoAnyItem aItem( SID_DELETE_POSTIT, Any( xAnnotation ) );
+ pDispatcher->Execute( SID_DELETE_POSTIT, SFX_CALLMODE_ASYNCHRON, &aItem, 0 );
+ break;
+ }
+ case SID_DELETEALLBYAUTHOR_POSTIT:
+ {
+ const SfxStringItem aItem( SID_DELETEALLBYAUTHOR_POSTIT, sAuthor );
+ pDispatcher->Execute( SID_DELETEALLBYAUTHOR_POSTIT, SFX_CALLMODE_ASYNCHRON, &aItem, 0 );
+ break;
+ }
+ case SID_DELETEALL_POSTIT:
+ pDispatcher->Execute( SID_DELETEALL_POSTIT );
+ break;
+ case SID_COPY:
+ case SID_PASTE:
+ case SID_ATTR_CHAR_WEIGHT:
+ case SID_ATTR_CHAR_POSTURE:
+ case SID_ATTR_CHAR_UNDERLINE:
+ case SID_ATTR_CHAR_STRIKEOUT:
+ if( pAnnotationWindow )
+ pAnnotationWindow->ExecuteSlot( nId );
+ break;
+ }
+}
+
+// ====================================================================
+
+Color AnnotationManagerImpl::GetColor(sal_uInt16 aAuthorIndex)
+{
+ if (!Application::GetSettings().GetStyleSettings().GetHighContrastMode())
+ {
+ static const Color aArrayNormal[] = {
+ COL_AUTHOR1_NORMAL, COL_AUTHOR2_NORMAL, COL_AUTHOR3_NORMAL,
+ COL_AUTHOR4_NORMAL, COL_AUTHOR5_NORMAL, COL_AUTHOR6_NORMAL,
+ COL_AUTHOR7_NORMAL, COL_AUTHOR8_NORMAL, COL_AUTHOR9_NORMAL };
+
+ return Color( aArrayNormal[ aAuthorIndex % (sizeof( aArrayNormal )/ sizeof( aArrayNormal[0] ))]);
+ }
+ else
+ return Color(COL_WHITE);
+}
+
+Color AnnotationManagerImpl::GetColorLight(sal_uInt16 aAuthorIndex)
+{
+ if (!Application::GetSettings().GetStyleSettings().GetHighContrastMode())
+ {
+ static const Color aArrayLight[] = {
+ COL_AUTHOR1_LIGHT, COL_AUTHOR2_LIGHT, COL_AUTHOR3_LIGHT,
+ COL_AUTHOR4_LIGHT, COL_AUTHOR5_LIGHT, COL_AUTHOR6_LIGHT,
+ COL_AUTHOR7_LIGHT, COL_AUTHOR8_LIGHT, COL_AUTHOR9_LIGHT };
+
+ return Color( aArrayLight[ aAuthorIndex % (sizeof( aArrayLight )/ sizeof( aArrayLight[0] ))]);
+ }
+ else
+ return Color(COL_WHITE);
+}
+
+Color AnnotationManagerImpl::GetColorDark(sal_uInt16 aAuthorIndex)
+{
+ if (!Application::GetSettings().GetStyleSettings().GetHighContrastMode())
+ {
+ static const Color aArrayAnkor[] = {
+ COL_AUTHOR1_DARK, COL_AUTHOR2_DARK, COL_AUTHOR3_DARK,
+ COL_AUTHOR4_DARK, COL_AUTHOR5_DARK, COL_AUTHOR6_DARK,
+ COL_AUTHOR7_DARK, COL_AUTHOR8_DARK, COL_AUTHOR9_DARK };
+
+ return Color( aArrayAnkor[ aAuthorIndex % (sizeof( aArrayAnkor ) / sizeof( aArrayAnkor[0] ))]);
+ }
+ else
+ return Color(COL_WHITE);
+}
+
+SdPage* AnnotationManagerImpl::GetNextPage( SdPage* pPage, bool bForeward )
+{
+ if( pPage == 0 )
+ return bForeward ? GetFirstPage() : GetLastPage();
+
+ sal_uInt16 nPageNum = (pPage->GetPageNum() - 1) >> 1;
+
+ // first all non master pages
+ if( !pPage->IsMasterPage() )
+ {
+ if( bForeward )
+ {
+ if( nPageNum >= mpDoc->GetSdPageCount(PK_STANDARD)-1 )
+ {
+ // we reached end of draw pages, start with master pages (skip handout master for draw)
+ return mpDoc->GetMasterSdPage( (mpDoc->GetDocumentType() == DOCUMENT_TYPE_IMPRESS) ? 0 : 1, PK_STANDARD );
+ }
+ nPageNum++;
+ }
+ else
+ {
+ if( nPageNum == 0 )
+ return 0; // we are already on the first draw page, finished
+
+ nPageNum--;
+ }
+ return mpDoc->GetSdPage(nPageNum, PK_STANDARD);
+ }
+ else
+ {
+ if( bForeward )
+ {
+ if( nPageNum >= mpDoc->GetMasterSdPageCount(PK_STANDARD)-1 )
+ {
+ return 0; // we reached the end, there is nothing more to see here
+ }
+ nPageNum++;
+ }
+ else
+ {
+ if( nPageNum == (mpDoc->GetDocumentType() == DOCUMENT_TYPE_IMPRESS) ? 0 : 1 )
+ {
+ // we reached beginning of master pages, start with end if pages
+ return mpDoc->GetSdPage( mpDoc->GetSdPageCount(PK_STANDARD)-1, PK_STANDARD );
+ }
+
+ nPageNum--;
+ }
+ return mpDoc->GetMasterSdPage(nPageNum,PK_STANDARD);
+ }
+}
+
+SdPage* AnnotationManagerImpl::GetFirstPage()
+{
+ // return first drawing page
+ return mpDoc->GetSdPage(0, PK_STANDARD );
+}
+
+SdPage* AnnotationManagerImpl::GetLastPage()
+{
+ return mpDoc->GetMasterSdPage( mpDoc->GetMasterSdPageCount(PK_STANDARD) - 1, PK_STANDARD );
+}
+
+SdPage* AnnotationManagerImpl::GetCurrentPage()
+{
+/*
+ ::boost::shared_ptr<DrawViewShell> pDrawViewShell(::boost::dynamic_pointer_cast<DrawViewShell>(mrBase.GetMainViewShell()));
+ if (pDrawViewShell.get() != NULL)
+ return pDrawViewShell->GetActualPage();
+*/
+ return mrBase.GetMainViewShell()->getCurrentPage();
+}
+
+// ====================================================================
+
+AnnotationManager::AnnotationManager( ViewShellBase& rViewShellBase )
+: mxImpl( new AnnotationManagerImpl( rViewShellBase ) )
+{
+ mxImpl->init();
+}
+
+AnnotationManager::~AnnotationManager()
+{
+ mxImpl->dispose();
+}
+
+void AnnotationManager::ExecuteAnnotation(SfxRequest& rRequest)
+{
+ mxImpl->ExecuteAnnotation( rRequest );
+}
+
+void AnnotationManager::GetAnnotationState(SfxItemSet& rItemSet)
+{
+ mxImpl->GetAnnotationState(rItemSet);
+}
+
+}
diff --git a/sd/source/ui/annotations/annotationmanagerimpl.hxx b/sd/source/ui/annotations/annotationmanagerimpl.hxx
new file mode 100755
index 000000000000..43b53d8467f9
--- /dev/null
+++ b/sd/source/ui/annotations/annotationmanagerimpl.hxx
@@ -0,0 +1,144 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SD_ANNOTATIONMANAGER_IMPL_HXX
+#define _SD_ANNOTATIONMANAGER_IMPL_HXX
+
+#include <com/sun/star/document/XEventListener.hpp>
+#include <com/sun/star/office/XAnnotationAccess.hpp>
+
+#include <rtl/ustring.hxx>
+
+#include <cppuhelper/basemutex.hxx>
+#include <cppuhelper/compbase1.hxx>
+
+#include "ViewShellBase.hxx"
+
+#include "annotationtag.hxx"
+
+class SfxRequest;
+
+namespace sd
+{
+
+typedef std::vector< rtl::Reference< AnnotationTag > > AnnotationTagVector;
+
+namespace tools {
+class EventMultiplexerEvent;
+}
+
+typedef ::cppu::WeakComponentImplHelper1 <
+ com::sun::star::document::XEventListener
+ > AnnotationManagerImplBase;
+
+class AnnotationManagerImpl : private ::cppu::BaseMutex, public AnnotationManagerImplBase
+{
+public:
+ AnnotationManagerImpl( ViewShellBase& rViewShellBase );
+
+ void init();
+
+ // WeakComponentImplHelper1
+ virtual void SAL_CALL disposing ();
+
+ // XEventListener
+ virtual void SAL_CALL notifyEvent( const ::com::sun::star::document::EventObject& Event ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException);
+
+ //
+ void ExecuteAnnotation (SfxRequest& rRequest);
+ void GetAnnotationState (SfxItemSet& rItemSet);
+
+ void ExecuteInsertAnnotation(SfxRequest& rReq);
+ void ExecuteDeleteAnnotation(SfxRequest& rReq);
+ void ExecuteReplyToAnnotation(SfxRequest& rReq);
+
+ void SelectNextAnnotation(bool bForeward);
+
+ void SelectAnnotation( ::com::sun::star::uno::Reference< ::com::sun::star::office::XAnnotation > xAnnotation, bool bEdit = FALSE );
+ void GetSelectedAnnotation( ::com::sun::star::uno::Reference< ::com::sun::star::office::XAnnotation >& xAnnotation );
+
+ void InsertAnnotation();
+ void DeleteAnnotation( ::com::sun::star::uno::Reference< ::com::sun::star::office::XAnnotation > xAnnotation );
+ void DeleteAnnotationsByAuthor( const rtl::OUString& sAuthor );
+ void DeleteAllAnnotations();
+
+ void ExecuteAnnotationContextMenu( ::com::sun::star::uno::Reference< ::com::sun::star::office::XAnnotation > xAnnotation, ::Window* pParent, const Rectangle& rContextRect, bool bButtonMenu = false );
+
+ Color GetColorDark(sal_uInt16 aAuthorIndex);
+ Color GetColorLight(sal_uInt16 aAuthorIndex);
+ Color GetColor(sal_uInt16 aAuthorIndex);
+
+
+ // callbacks
+ void onTagSelected( AnnotationTag& rTag );
+ void onTagDeselected( AnnotationTag& rTag );
+
+ void onSelectionChanged();
+
+ rtl::OUString GetHelpText( ::com::sun::star::uno::Reference< ::com::sun::star::office::XAnnotation >& xAnnotation );
+
+ void addListener();
+ void removeListener();
+
+ void invalidateSlots();
+
+ DECL_LINK(EventMultiplexerListener, tools::EventMultiplexerEvent*);
+ DECL_LINK(UpdateTagsHdl, void *);
+
+ void UpdateTags(bool bSynchron = false);
+ void CreateTags();
+ void DisposeTags();
+
+ SdPage* GetNextPage( SdPage* pPage, bool bForeward );
+ SdPage* GetFirstPage();
+ SdPage* GetLastPage();
+
+ SdPage* GetCurrentPage();
+
+ SdDrawDocument* GetDoc() { return mpDoc; }
+
+ void ShowAnnotations(bool bShow);
+
+private:
+ ViewShellBase& mrBase;
+ SdDrawDocument* mpDoc;
+
+ AnnotationTagVector maTagVector;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XDrawView > mxView;
+ ::com::sun::star::uno::Reference< ::com::sun::star::office::XAnnotationAccess > mxCurrentPage;
+ ::com::sun::star::uno::Reference< ::com::sun::star::office::XAnnotation > mxSelectedAnnotation;
+
+ bool mbShowAnnotations;
+ ULONG mnUpdateTagsEvent;
+ Font maFont;
+};
+
+}
+
+#endif // _SD_ANNOTATIONMANAGER_IMPL_HXX
diff --git a/sd/source/ui/annotations/annotations.hrc b/sd/source/ui/annotations/annotations.hrc
new file mode 100644
index 000000000000..d2969f91be41
--- /dev/null
+++ b/sd/source/ui/annotations/annotations.hrc
@@ -0,0 +1,65 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SD_ANNOTATIONPANE_HRC
+#define _SD_ANNOTATIONPANE_HRC
+
+#include "glob.hrc"
+
+// strings
+#define STR_ANNOTATION_TODAY (RID_ANNOTATIONS_START+1)
+#define STR_ANNOTATION_YESTERDAY (RID_ANNOTATIONS_START+2)
+#define STR_ANNOTATION_NOAUTHOR (RID_ANNOTATIONS_START+3)
+#define STR_ANNOTATION_WRAP_FORWARD (RID_ANNOTATIONS_START+4)
+#define STR_ANNOTATION_WRAP_BACKWARD (RID_ANNOTATIONS_START+5)
+#define STR_ANNOTATION_WRAP_FORWARD_DRAW (RID_ANNOTATIONS_START+6)
+#define STR_ANNOTATION_WRAP_BACKWARD_DRAW (RID_ANNOTATIONS_START+7)
+#define STR_ANNOTATION_UNDO_INSERT (RID_ANNOTATIONS_START+8)
+#define STR_ANNOTATION_UNDO_DELETE (RID_ANNOTATIONS_START+9)
+#define STR_ANNOTATION_UNDO_MOVE (RID_ANNOTATIONS_START+10)
+#define STR_ANNOTATION_UNDO_EDIT (RID_ANNOTATIONS_START+11)
+#define STR_ANNOTATION_UNDO_REPLY (RID_ANNOTATIONS_START+12)
+#define STR_ANNOTATION_REPLY (RID_ANNOTATIONS_START+13)
+
+// menus
+#define RID_ANNOTATION_CONTEXTMENU (RID_ANNOTATIONS_START+0)
+#define RID_ANNOTATION_TAG_CONTEXTMENU (RID_ANNOTATIONS_START+1)
+
+#define BTN_NEW 1
+#define BTN_DELETE 2
+#define BTN_NEXT 3
+#define BTN_PREV 4
+
+#define TBX_TOOLBAR 1
+#define FT_AUTHOR 1
+#define ED_AUTHOR 2
+#define FT_DATE 3
+#define ED_DATE 4
+
+#define CT_TEXT 5
+
+#endif // _SD_ANNOTATIONPANE_HRC
diff --git a/sd/source/ui/annotations/annotations.src b/sd/source/ui/annotations/annotations.src
new file mode 100644
index 000000000000..0ca43731d6b0
--- /dev/null
+++ b/sd/source/ui/annotations/annotations.src
@@ -0,0 +1,209 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "annotations.hrc"
+#include "glob.hrc"
+#include <svx/svxids.hrc>
+
+Menu RID_ANNOTATION_CONTEXTMENU
+{
+ ItemList =
+ {
+ MenuItem
+ {
+ Identifier = SID_REPLYTO_POSTIT;
+ HelpID = SID_REPLYTO_POSTIT ;
+ Text [ en-US ] = "~Reply";
+ };
+ MenuItem
+ {
+ Separator = TRUE;
+ };
+ MenuItem
+ {
+ Identifier = SID_ATTR_CHAR_WEIGHT;
+ HelpID = SID_ATTR_CHAR_WEIGHT ;
+ Text [ en-US ] = "~Bold";
+ };
+ MenuItem
+ {
+ Identifier = SID_ATTR_CHAR_POSTURE;
+ HelpID = SID_ATTR_CHAR_POSTURE;
+ Text [ en-US ] = "~Italic";
+ };
+ MenuItem
+ {
+ Identifier = SID_ATTR_CHAR_UNDERLINE;
+ HelpID = SID_ATTR_CHAR_UNDERLINE;
+ Text [ en-US ] = "~Underline";
+ };
+ MenuItem
+ {
+ Identifier = SID_ATTR_CHAR_STRIKEOUT;
+ HelpID = SID_ATTR_CHAR_STRIKEOUT;
+ Text [ en-US ] = "~Strikethrough";
+ };
+ MenuItem
+ {
+ Separator = TRUE;
+ };
+ MenuItem
+ {
+ Identifier = SID_COPY ;
+ HelpID = SID_COPY ;
+ Text [ en-US ] = "~Copy" ;
+ };
+ MenuItem
+ {
+ Identifier = SID_PASTE ;
+ HelpID = SID_PASTE ;
+ Text [ en-US ] = "~Paste" ;
+ };
+ MenuItem
+ {
+ Separator = TRUE;
+ };
+ MenuItem
+ {
+ Identifier = SID_DELETE_POSTIT ;
+ HelpID = SID_DELETE_POSTIT;
+ Text [ en-US ] = "~Delete Comment" ;
+ };
+ MenuItem
+ {
+ Identifier = SID_DELETEALLBYAUTHOR_POSTIT ;
+ HelpID = SID_DELETEALLBYAUTHOR_POSTIT;
+ Text [ en-US ] = "Delete All Comments b~y %1" ;
+ };
+ MenuItem
+ {
+ Identifier = SID_DELETEALL_POSTIT;
+ HelpID = SID_DELETEALL_POSTIT;
+ Text [ en-US ] = "Delete ~All Comments" ;
+ };
+ };
+};
+
+Menu RID_ANNOTATION_TAG_CONTEXTMENU
+{
+ ItemList =
+ {
+ MenuItem
+ {
+ Identifier = SID_REPLYTO_POSTIT;
+ HelpID = SID_REPLYTO_POSTIT;
+ Text [ en-US ] = "~Reply";
+ };
+ MenuItem
+ {
+ Separator = TRUE;
+ };
+ MenuItem
+ {
+ Identifier = SID_DELETE_POSTIT ;
+ HelpID = SID_DELETE_POSTIT ;
+ Text [ en-US ] = "~Delete Comment" ;
+ };
+ MenuItem
+ {
+ Identifier = SID_DELETEALLBYAUTHOR_POSTIT ;
+ HelpID = SID_DELETEALLBYAUTHOR_POSTIT ;
+ Text [ en-US ] = "Delete All Comments ~by %1" ;
+ };
+ MenuItem
+ {
+ Identifier = SID_DELETEALL_POSTIT;
+ HelpID = SID_DELETEALL_POSTIT;
+ Text [ en-US ] = "Delete ~All Comments" ;
+ };
+ };
+};
+
+String STR_ANNOTATION_TODAY
+{
+ Text [ en-US ] = "Today," ;
+};
+
+String STR_ANNOTATION_YESTERDAY
+{
+ Text [ en-US ] = "Yesterday," ;
+};
+
+String STR_ANNOTATION_NOAUTHOR
+{
+ Text [ en-US ] = "(no author)" ;
+};
+
+String STR_ANNOTATION_WRAP_FORWARD
+{
+ Text [ en-US ] = "%PRODUCTNAME Impress reached the end of the presentation. Do you want to continue at the beginning?";
+};
+
+String STR_ANNOTATION_WRAP_BACKWARD
+{
+ Text [ en-US ] = "%PRODUCTNAME Impress reached the beginning of the presentation. Do you want to continue at the end?";
+};
+
+String STR_ANNOTATION_WRAP_FORWARD_DRAW
+{
+ Text [ en-US ] = "%PRODUCTNAME Draw reached the end of the document. Do you want to continue at the beginning?";
+};
+
+String STR_ANNOTATION_WRAP_BACKWARD_DRAW
+{
+ Text [ en-US ] = "%PRODUCTNAME Draw reached the beginning of the document. Do you want to continue at the end?";
+};
+
+String STR_ANNOTATION_UNDO_INSERT
+{
+ Text [ en-US ] = "Insert Comment";
+};
+
+String STR_ANNOTATION_UNDO_DELETE
+{
+ Text [ en-US ] = "Delete Comment(s)";
+};
+
+String STR_ANNOTATION_UNDO_MOVE
+{
+ Text [ en-US ] = "Move Comment";
+};
+
+String STR_ANNOTATION_UNDO_EDIT
+{
+ Text [ en-US ] = "Edit Comment";
+};
+
+String STR_ANNOTATION_UNDO_REPLY
+{
+ Text [ en-US ] = "Reply to Comment";
+};
+
+String STR_ANNOTATION_REPLY
+{
+ Text [ en-US ] = "Reply to %1" ;
+};
diff --git a/sd/source/ui/annotations/annotationtag.cxx b/sd/source/ui/annotations/annotationtag.cxx
new file mode 100644
index 000000000000..6439245a94c0
--- /dev/null
+++ b/sd/source/ui/annotations/annotationtag.cxx
@@ -0,0 +1,790 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sd.hxx"
+
+#include <com/sun/star/util/XChangesNotifier.hpp>
+
+#include <vcl/help.hxx>
+#include <vcl/svapp.hxx>
+
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/dispatch.hxx>
+
+#include <svx/sdr/overlay/overlaymanager.hxx>
+#include <svx/sdr/overlay/overlayanimatedbitmapex.hxx>
+#include <svx/sdr/overlay/overlaybitmapex.hxx>
+#include <svx/svdpagv.hxx>
+#include <svx/sdrpagewindow.hxx>
+#include <svx/sdrpaintwindow.hxx>
+#include <svx/svddrgmt.hxx>
+
+#include "View.hxx"
+#include "sdresid.hxx"
+#include "annotations.hrc"
+#include "annotationmanagerimpl.hxx"
+#include "annotationwindow.hxx"
+#include "annotationtag.hxx"
+#include "sdpage.hxx"
+#include "ViewShell.hxx"
+#include "app.hrc"
+#include "Window.hxx"
+#include "drawdoc.hxx"
+
+using ::rtl::OUString;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+//using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::office;
+using namespace ::com::sun::star::geometry;
+
+namespace sd
+{
+
+const sal_uInt32 SMART_TAG_HDL_NUM = SAL_MAX_UINT32;
+static const int DRGPIX = 2; // Drag MinMove in Pixel
+
+// --------------------------------------------------------------------
+
+static OUString getInitials( const OUString& rName )
+{
+ OUString sInitials;
+
+ const sal_Unicode * pStr = rName.getStr();
+ sal_Int32 nLength = rName.getLength();
+
+ while( nLength )
+ {
+ // skip whitespace
+ while( nLength && (*pStr <= ' ') )
+ {
+ nLength--; pStr++;
+ }
+
+ // take letter
+ if( nLength )
+ {
+ sInitials += OUString( *pStr );
+ nLength--; pStr++;
+ }
+
+ // skip letters until whitespace
+ while( nLength && (*pStr > ' ') )
+ {
+ nLength--; pStr++;
+ }
+ }
+
+ return sInitials;
+}
+
+// --------------------------------------------------------------------
+
+// --------------------------------------------------------------------
+
+class AnnotationDragMove : public SdrDragMove
+{
+public:
+ AnnotationDragMove(SdrDragView& rNewView, const rtl::Reference <AnnotationTag >& xTag);
+ virtual bool BeginSdrDrag();
+ virtual bool EndSdrDrag(bool bCopy);
+ virtual void MoveSdrDrag(const Point& rNoSnapPnt);
+ virtual void CancelSdrDrag();
+
+private:
+ rtl::Reference <AnnotationTag > mxTag;
+ Point maOrigin;
+};
+
+AnnotationDragMove::AnnotationDragMove(SdrDragView& rNewView, const rtl::Reference <AnnotationTag >& xTag)
+: SdrDragMove(rNewView)
+, mxTag( xTag )
+{
+}
+
+bool AnnotationDragMove::BeginSdrDrag()
+{
+ DragStat().Ref1()=GetDragHdl()->GetPos();
+ DragStat().SetShown(!DragStat().IsShown());
+
+ maOrigin = GetDragHdl()->GetPos();
+ DragStat().SetActionRect(Rectangle(maOrigin,maOrigin));
+
+ return true;
+}
+
+void AnnotationDragMove::MoveSdrDrag(const Point& rNoSnapPnt)
+{
+ Point aPnt(rNoSnapPnt);
+
+ if (DragStat().CheckMinMoved(rNoSnapPnt))
+ {
+ if (aPnt!=DragStat().GetNow())
+ {
+ Hide();
+ DragStat().NextMove(aPnt);
+ GetDragHdl()->SetPos( maOrigin + Point( DragStat().GetDX(), DragStat().GetDY() ) );
+ Show();
+ DragStat().SetActionRect(Rectangle(aPnt,aPnt));
+ }
+ }
+}
+
+bool AnnotationDragMove::EndSdrDrag(bool /*bCopy*/)
+{
+ Hide();
+ if( mxTag.is() )
+ mxTag->Move( DragStat().GetDX(), DragStat().GetDY() );
+ return TRUE;
+}
+
+void AnnotationDragMove::CancelSdrDrag()
+{
+ Hide();
+}
+
+// --------------------------------------------------------------------
+
+class AnnotationHdl : public SmartHdl
+{
+public:
+ AnnotationHdl( const SmartTagReference& xTag, const Reference< XAnnotation >& xAnnotation, const Point& rPnt );
+ virtual ~AnnotationHdl();
+ virtual void CreateB2dIAObject();
+ virtual BOOL IsFocusHdl() const;
+ virtual Pointer GetSdrDragPointer() const;
+ virtual bool isMarkable() const;
+
+
+private:
+ Reference< XAnnotation > mxAnnotation;
+ rtl::Reference< AnnotationTag > mxTag;
+};
+
+// --------------------------------------------------------------------
+
+AnnotationHdl::AnnotationHdl( const SmartTagReference& xTag, const Reference< XAnnotation >& xAnnotation, const Point& rPnt )
+: SmartHdl( xTag, rPnt )
+, mxAnnotation( xAnnotation )
+, mxTag( dynamic_cast< AnnotationTag* >( xTag.get() ) )
+{
+}
+
+// --------------------------------------------------------------------
+
+AnnotationHdl::~AnnotationHdl()
+{
+}
+
+// --------------------------------------------------------------------
+
+void AnnotationHdl::CreateB2dIAObject()
+{
+ // first throw away old one
+ GetRidOfIAObject();
+
+ if( mxAnnotation.is() )
+ {
+ const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
+
+ const Point aTagPos( GetPos() );
+ basegfx::B2DPoint aPosition( aTagPos.X(), aTagPos.Y() );
+
+ const bool bFocused = IsFocusHdl() && pHdlList && (pHdlList->GetFocusHdl() == this);
+
+ BitmapEx aBitmapEx( mxTag->CreateAnnotationBitmap(mxTag->isSelected()) );
+ BitmapEx aBitmapEx2;
+ if( bFocused )
+ aBitmapEx2 = mxTag->CreateAnnotationBitmap(!mxTag->isSelected() );
+
+ if(pHdlList)
+ {
+ SdrMarkView* pView = pHdlList->GetView();
+
+ if(pView && !pView->areMarkHandlesHidden())
+ {
+ SdrPageView* pPageView = pView->GetSdrPageView();
+
+ if(pPageView)
+ {
+ for(sal_uInt32 b = 0; b < pPageView->PageWindowCount(); b++)
+ {
+ // const SdrPageViewWinRec& rPageViewWinRec = rPageViewWinList[b];
+ const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
+
+ SdrPaintWindow& rPaintWindow = rPageWindow.GetPaintWindow();
+ if(rPaintWindow.OutputToWindow() && rPageWindow.GetOverlayManager() )
+ {
+ ::sdr::overlay::OverlayObject* pOverlayObject = 0;
+
+ // animate focused handles
+ if(bFocused)
+ {
+ const sal_uInt32 nBlinkTime = sal::static_int_cast<sal_uInt32>(rStyleSettings.GetCursorBlinkTime());
+
+ pOverlayObject = new ::sdr::overlay::OverlayAnimatedBitmapEx(aPosition, aBitmapEx, aBitmapEx2, nBlinkTime, 0, 0, 0, 0 );
+/*
+ (UINT16)(aBitmapEx.GetSizePixel().Width() - 1) >> 1,
+ (UINT16)(aBitmapEx.GetSizePixel().Height() - 1) >> 1,
+ (UINT16)(aBitmapEx2.GetSizePixel().Width() - 1) >> 1,
+ (UINT16)(aBitmapEx2.GetSizePixel().Height() - 1) >> 1);
+*/
+ }
+ else
+ {
+ pOverlayObject = new ::sdr::overlay::OverlayBitmapEx( aPosition, aBitmapEx, 0, 0 );
+ }
+
+ rPageWindow.GetOverlayManager()->add(*pOverlayObject);
+ maOverlayGroup.append(*pOverlayObject);
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+// --------------------------------------------------------------------
+
+BOOL AnnotationHdl::IsFocusHdl() const
+{
+ return TRUE;
+}
+
+// --------------------------------------------------------------------
+
+bool AnnotationHdl::isMarkable() const
+{
+ return false;
+}
+
+// --------------------------------------------------------------------
+
+Pointer AnnotationHdl::GetSdrDragPointer() const
+{
+ PointerStyle eStyle = POINTER_NOTALLOWED;
+ if( mxTag.is() )
+ {
+ if( mxTag->isSelected() )
+ {
+ eStyle = POINTER_MOVE;
+ }
+ else
+ {
+ eStyle = POINTER_ARROW;
+
+ }
+ }
+ return Pointer( eStyle );
+}
+
+// ====================================================================
+
+AnnotationTag::AnnotationTag( AnnotationManagerImpl& rManager, ::sd::View& rView, const Reference< XAnnotation >& xAnnotation, Color& rColor, int nIndex, const Font& rFont )
+: SmartTag( rView )
+, mrManager( rManager )
+, mxAnnotation( xAnnotation )
+, maColor( rColor )
+, mnIndex( nIndex )
+, mrFont( rFont )
+, mnClosePopupEvent( 0 )
+, mpListenWindow( 0 )
+{
+}
+
+// --------------------------------------------------------------------
+
+AnnotationTag::~AnnotationTag()
+{
+ DBG_ASSERT( !mxAnnotation.is(), "sd::AnnotationTag::~AnnotationTag(), dispose me first!" );
+ Dispose();
+}
+
+// --------------------------------------------------------------------
+
+/** returns true if the AnnotationTag handled the event. */
+bool AnnotationTag::MouseButtonDown( const MouseEvent& rMEvt, SmartHdl& /*rHdl*/ )
+{
+ if( !mxAnnotation.is() )
+ return false;
+
+ bool bRet = false;
+ if( !isSelected() )
+ {
+ SmartTagReference xTag( this );
+ mrView.getSmartTags().select( xTag );
+ bRet = true;
+ }
+ /*
+ if( rMEvt.IsLeft() && (rMEvt.GetClicks() == 2) )
+ {
+ // double click;
+ return true;
+ }
+ else */
+ if( rMEvt.IsLeft() && !rMEvt.IsRight() )
+ {
+ Window* pWindow = mrView.GetViewShell()->GetActiveWindow();
+ if( pWindow )
+ {
+ maMouseDownPos = pWindow->PixelToLogic( rMEvt.GetPosPixel() );
+
+ if( mpListenWindow )
+ mpListenWindow->RemoveEventListener( LINK(this, AnnotationTag, WindowEventHandler));
+
+ mpListenWindow = pWindow;
+ mpListenWindow->AddEventListener( LINK(this, AnnotationTag, WindowEventHandler));
+ }
+
+ bRet = true;
+ }
+
+ return bRet;
+}
+
+// --------------------------------------------------------------------
+
+/** returns true if the SmartTag consumes this event. */
+bool AnnotationTag::KeyInput( const KeyEvent& rKEvt )
+{
+ if( !mxAnnotation.is() )
+ return false;
+
+ USHORT nCode = rKEvt.GetKeyCode().GetCode();
+ switch( nCode )
+ {
+ case KEY_DELETE:
+ mrManager.DeleteAnnotation( mxAnnotation );
+ return true;
+
+ case KEY_DOWN:
+ case KEY_UP:
+ case KEY_LEFT:
+ case KEY_RIGHT:
+ return OnMove( rKEvt );
+
+ case KEY_ESCAPE:
+ {
+ SmartTagReference xThis( this );
+ mrView.getSmartTags().deselect();
+ return true;
+ }
+
+ case KEY_TAB:
+ mrManager.SelectNextAnnotation(!rKEvt.GetKeyCode().IsShift());
+ return true;
+
+ case KEY_RETURN:
+ case KEY_SPACE:
+ OpenPopup( true );
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+/** returns true if the SmartTag consumes this event. */
+bool AnnotationTag::RequestHelp( const HelpEvent& /*rHEvt*/ )
+{
+/*
+ ::Window* pWindow = mrView.GetViewShell()->GetActiveWindow();
+ if( mxAnnotation.is() && pWindow )
+ {
+ OUString aHelpText( mrManager.GetHelpText( mxAnnotation ) );
+
+ RealPoint2D aPosition( mxAnnotation->getPosition() );
+ Point aPos( pWindow->LogicToPixel( Point( static_cast<long>(aPosition.X * 100.0), static_cast<long>(aPosition.Y * 100.0) ) ) );
+
+ Rectangle aRect( aPos, maSize );
+
+ if (Help::IsBalloonHelpEnabled())
+ Help::ShowBalloon( pWindow, aPos, aRect, aHelpText);
+ else if (Help::IsQuickHelpEnabled())
+ Help::ShowQuickHelp( pWindow, aRect, aHelpText);
+
+ return true;
+ }
+*/
+ return false;
+}
+
+/** returns true if the SmartTag consumes this event. */
+bool AnnotationTag::Command( const CommandEvent& rCEvt )
+{
+ if ( rCEvt.GetCommand() == COMMAND_CONTEXTMENU )
+ {
+ ::Window* pWindow = mrView.GetViewShell()->GetActiveWindow();
+ if( pWindow )
+ {
+ Rectangle aContextRect(rCEvt.GetMousePosPixel(),Size(1,1));
+ mrManager.ExecuteAnnotationContextMenu( mxAnnotation, pWindow, aContextRect );
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void AnnotationTag::Move( int nDX, int nDY )
+{
+ if( mxAnnotation.is() )
+ {
+ if( mrManager.GetDoc()->IsUndoEnabled() )
+ mrManager.GetDoc()->BegUndo( String( SdResId( STR_ANNOTATION_UNDO_MOVE ) ) );
+
+ RealPoint2D aPosition( mxAnnotation->getPosition() );
+ aPosition.X += (double)nDX / 100.0;
+ aPosition.Y += (double)nDY / 100.0;
+ mxAnnotation->setPosition( aPosition );
+
+ if( mrManager.GetDoc()->IsUndoEnabled() )
+ mrManager.GetDoc()->EndUndo();
+
+ mrView.updateHandles();
+ }
+}
+
+bool AnnotationTag::OnMove( const KeyEvent& rKEvt )
+{
+ long nX = 0;
+ long nY = 0;
+
+ switch( rKEvt.GetKeyCode().GetCode() )
+ {
+ case KEY_UP: nY = -1; break;
+ case KEY_DOWN: nY = 1; break;
+ case KEY_LEFT: nX = -1; break;
+ case KEY_RIGHT: nX = 1; break;
+ default: break;
+ }
+
+ if(rKEvt.GetKeyCode().IsMod2())
+ {
+ OutputDevice* pOut = mrView.GetViewShell()->GetActiveWindow();
+ Size aLogicSizeOnePixel = (pOut) ? pOut->PixelToLogic(Size(1,1)) : Size(100, 100);
+ nX *= aLogicSizeOnePixel.Width();
+ nY *= aLogicSizeOnePixel.Height();
+ }
+ else
+ {
+ // old, fixed move distance
+ nX *= 100;
+ nY *= 100;
+ }
+
+ if( nX || nY )
+ {
+ // move the annotation
+ Move( nX, nY );
+ }
+
+ return true;
+}
+
+// --------------------------------------------------------------------
+
+void AnnotationTag::CheckPossibilities()
+{
+}
+
+// --------------------------------------------------------------------
+
+ULONG AnnotationTag::GetMarkablePointCount() const
+{
+ return 0;
+}
+
+// --------------------------------------------------------------------
+
+ULONG AnnotationTag::GetMarkedPointCount() const
+{
+ return 0;
+}
+
+// --------------------------------------------------------------------
+
+BOOL AnnotationTag::MarkPoint(SdrHdl& /*rHdl*/, BOOL /*bUnmark*/ )
+{
+ BOOL bRet=FALSE;
+ return bRet;
+}
+
+// --------------------------------------------------------------------
+
+BOOL AnnotationTag::MarkPoints(const Rectangle* /*pRect*/, BOOL /*bUnmark*/ )
+{
+ BOOL bChgd=FALSE;
+ return bChgd;
+}
+
+// --------------------------------------------------------------------
+
+bool AnnotationTag::getContext( SdrViewContext& /*rContext*/ )
+{
+ return false;
+}
+
+// --------------------------------------------------------------------
+
+void AnnotationTag::addCustomHandles( SdrHdlList& rHandlerList )
+{
+ if( mxAnnotation.is() )
+ {
+ SmartTagReference xThis( this );
+ Point aPoint;
+ AnnotationHdl* pHdl = new AnnotationHdl( xThis, mxAnnotation, aPoint );
+ pHdl->SetObjHdlNum( SMART_TAG_HDL_NUM );
+ pHdl->SetPageView( mrView.GetSdrPageView() );
+
+ RealPoint2D aPosition( mxAnnotation->getPosition() );
+ Point aBasePos( static_cast<long>(aPosition.X * 100.0), static_cast<long>(aPosition.Y * 100.0) );
+ pHdl->SetPos( aBasePos );
+
+ rHandlerList.AddHdl( pHdl );
+ }
+}
+
+// --------------------------------------------------------------------
+
+void AnnotationTag::disposing()
+{
+ if( mpListenWindow )
+ {
+ mpListenWindow->RemoveEventListener( LINK(this, AnnotationTag, WindowEventHandler));
+ }
+
+ if( mnClosePopupEvent )
+ {
+ Application::RemoveUserEvent( mnClosePopupEvent );
+ mnClosePopupEvent = 0;
+ }
+
+ mxAnnotation.clear();
+ ClosePopup();
+ SmartTag::disposing();
+}
+
+// --------------------------------------------------------------------
+
+void AnnotationTag::select()
+{
+ SmartTag::select();
+
+ mrManager.onTagSelected( *this );
+
+ Window* pWindow = mrView.GetViewShell()->GetActiveWindow();
+ if( pWindow )
+ {
+ RealPoint2D aPosition( mxAnnotation->getPosition() );
+ Point aPos( static_cast<long>(aPosition.X * 100.0), static_cast<long>(aPosition.Y * 100.0) );
+
+ Rectangle aVisRect( aPos, pWindow->PixelToLogic(maSize) );
+ mrView.MakeVisible(aVisRect, *pWindow);
+ }
+}
+
+// --------------------------------------------------------------------
+
+void AnnotationTag::deselect()
+{
+ SmartTag::deselect();
+
+ ClosePopup();
+
+ mrManager.onTagDeselected( *this );
+}
+
+// --------------------------------------------------------------------
+
+BitmapEx AnnotationTag::CreateAnnotationBitmap( bool bSelected )
+{
+ VirtualDevice aVDev;
+
+ OUString sAuthor( getInitials( mxAnnotation->getAuthor() ) );
+ sAuthor += OUString( sal_Unicode( ' ' ) );
+ sAuthor += OUString::valueOf( (sal_Int32)mnIndex );
+
+ aVDev.SetFont( mrFont );
+
+ const int BORDER_X = 4; // pixels
+ const int BORDER_Y = 4; // pixels
+
+ maSize = Size( aVDev.GetTextWidth( sAuthor ) + 2*BORDER_X, aVDev.GetTextHeight() + 2*BORDER_Y );
+ aVDev.SetOutputSizePixel( maSize, FALSE );
+
+ Color aBorderColor( maColor );
+
+ if( bSelected )
+ {
+ aBorderColor.Invert();
+ }
+ else
+ {
+ if( maColor.IsDark() )
+ {
+ aBorderColor.IncreaseLuminance( 32 );
+ }
+ else
+ {
+ aBorderColor.DecreaseLuminance( 32 );
+ }
+ }
+
+ Point aPos;
+ Rectangle aBorderRect( aPos, maSize );
+ aVDev.SetLineColor(aBorderColor);
+ aVDev.SetFillColor(maColor);
+ aVDev.DrawRect( aBorderRect );
+
+ aVDev.SetTextColor( maColor.IsDark() ? COL_WHITE : COL_BLACK );
+ aVDev.DrawText( Point( BORDER_X, BORDER_Y ), sAuthor );
+
+ return aVDev.GetBitmapEx( aPos, maSize );
+}
+
+void AnnotationTag::OpenPopup( bool bEdit )
+{
+ if( !mxAnnotation.is() )
+ return;
+
+ if( !mpAnnotationWindow.get() )
+ {
+ ::Window* pWindow = dynamic_cast< ::Window* >( getView().GetFirstOutputDevice() );
+ if( pWindow )
+ {
+ RealPoint2D aPosition( mxAnnotation->getPosition() );
+ Point aPos( pWindow->OutputToScreenPixel( pWindow->LogicToPixel( Point( static_cast<long>(aPosition.X * 100.0), static_cast<long>(aPosition.Y * 100.0) ) ) ) );
+
+ aPos.X() += 4; // magic!
+ aPos.Y() += 1;
+
+ Rectangle aRect( aPos, maSize );
+
+ mpAnnotationWindow.reset( new AnnotationWindow( mrManager, mrView.GetDocSh(), pWindow->GetWindow(WINDOW_FRAME) ) );
+ mpAnnotationWindow->InitControls();
+ mpAnnotationWindow->setAnnotation(mxAnnotation);
+
+ USHORT nArrangeIndex = 0;
+ Point aPopupPos( FloatingWindow::CalcFloatingPosition( mpAnnotationWindow.get(), aRect, FLOATWIN_POPUPMODE_RIGHT, nArrangeIndex ) );
+ Size aPopupSize( 320, 240 );
+
+ mpAnnotationWindow->SetPosSizePixel( aPopupPos, aPopupSize );
+ mpAnnotationWindow->DoResize();
+
+ mpAnnotationWindow->Show();
+ mpAnnotationWindow->GrabFocus();
+ mpAnnotationWindow->AddEventListener( LINK(this, AnnotationTag, WindowEventHandler));
+ }
+ }
+
+ if( bEdit && mpAnnotationWindow.get() )
+ mpAnnotationWindow->StartEdit();
+}
+
+void AnnotationTag::ClosePopup()
+{
+ if( mpAnnotationWindow.get() )
+ {
+ mpAnnotationWindow->RemoveEventListener( LINK(this, AnnotationTag, WindowEventHandler));
+ mpAnnotationWindow->Deactivate();
+ mpAnnotationWindow.reset();
+ }
+}
+
+IMPL_LINK(AnnotationTag, WindowEventHandler, VclWindowEvent*, pEvent)
+{
+ if( pEvent != NULL )
+ {
+ ::Window* pWindow = pEvent->GetWindow();
+
+ if( pWindow )
+ {
+ if( pWindow == mpAnnotationWindow.get() )
+ {
+ if( pEvent->GetId() == VCLEVENT_WINDOW_DEACTIVATE )
+ {
+ if( mnClosePopupEvent )
+ Application::RemoveUserEvent( mnClosePopupEvent );
+
+ mnClosePopupEvent = Application::PostUserEvent( LINK( this, AnnotationTag, ClosePopupHdl ) );
+ }
+ }
+ else if( pWindow == mpListenWindow )
+ {
+ switch( pEvent->GetId() )
+ {
+ case VCLEVENT_WINDOW_MOUSEBUTTONUP:
+ {
+ // if we stop pressing the button without a mouse move we open the popup
+ mpListenWindow->RemoveEventListener( LINK(this, AnnotationTag, WindowEventHandler));
+ mpListenWindow = 0;
+ if( mpAnnotationWindow.get() == 0 )
+ OpenPopup(false);
+ }
+ break;
+ case VCLEVENT_WINDOW_MOUSEMOVE:
+ {
+ // if we move the mouse after a button down we wan't to start draging
+ mpListenWindow->RemoveEventListener( LINK(this, AnnotationTag, WindowEventHandler));
+ mpListenWindow = 0;
+
+ SdrHdl* pHdl = mrView.PickHandle(maMouseDownPos);
+ if( pHdl )
+ {
+ mrView.BrkAction();
+ const USHORT nDrgLog = (USHORT)pWindow->PixelToLogic(Size(DRGPIX,0)).Width();
+
+ rtl::Reference< AnnotationTag > xTag( this );
+
+ SdrDragMethod* pDragMethod = new AnnotationDragMove( mrView, xTag );
+ mrView.BegDragObj(maMouseDownPos, NULL, pHdl, nDrgLog, pDragMethod );
+ }
+ }
+ break;
+ case VCLEVENT_OBJECT_DYING:
+ mpListenWindow = 0;
+ break;
+ }
+ }
+ }
+ }
+ return TRUE;
+}
+
+IMPL_LINK( AnnotationTag, ClosePopupHdl, void *, EMPTYARG )
+{
+ mnClosePopupEvent = 0;
+ ClosePopup();
+ return 0;
+}
+
+} // end of namespace sd
+
diff --git a/sd/source/ui/annotations/annotationtag.hxx b/sd/source/ui/annotations/annotationtag.hxx
new file mode 100644
index 000000000000..ea0d57fd3e3e
--- /dev/null
+++ b/sd/source/ui/annotations/annotationtag.hxx
@@ -0,0 +1,107 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SD_ANNOTATIONTAG_HXX_
+#define _SD_ANNOTATIONTAG_HXX_
+
+#include <com/sun/star/office/XAnnotation.hpp>
+#include <basegfx/polygon/b2dpolypolygon.hxx>
+#include <basegfx/polygon/b2dpolypolygontools.hxx>
+#include "smarttag.hxx"
+
+namespace css = ::com::sun::star;
+
+namespace sd {
+
+class View;
+class AnnotationManagerImpl;
+class AnnotationWindow;
+
+class AnnotationTag : public SmartTag
+{
+public:
+ AnnotationTag( AnnotationManagerImpl& rManager, ::sd::View& rView, const css::uno::Reference< css::office::XAnnotation >& xAnnotation, Color& rColor, int nIndex, const Font& rFont );
+ virtual ~AnnotationTag();
+
+ /** returns true if the SmartTag handled the event. */
+ virtual bool MouseButtonDown( const MouseEvent&, SmartHdl& );
+
+ /** returns true if the SmartTag consumes this event. */
+ virtual bool KeyInput( const KeyEvent& rKEvt );
+
+ /** returns true if the SmartTag consumes this event. */
+ virtual bool RequestHelp( const HelpEvent& rHEvt );
+
+ /** returns true if the SmartTag consumes this event. */
+ virtual bool Command( const CommandEvent& rCEvt );
+
+ // callbacks from sdr view
+ virtual ULONG GetMarkablePointCount() const;
+ virtual ULONG GetMarkedPointCount() const;
+ virtual BOOL MarkPoint(SdrHdl& rHdl, BOOL bUnmark=FALSE);
+ virtual void CheckPossibilities();
+ virtual BOOL MarkPoints(const Rectangle* pRect, BOOL bUnmark);
+
+ void Move( int nDX, int nDY );
+ bool OnMove( const KeyEvent& rKEvt );
+
+ // ---
+
+ BitmapEx CreateAnnotationBitmap(bool);
+
+ css::uno::Reference< css::office::XAnnotation > GetAnnotation() const { return mxAnnotation; }
+
+ void OpenPopup( bool bEdit );
+ void ClosePopup();
+
+protected:
+ virtual void addCustomHandles( SdrHdlList& rHandlerList );
+ virtual bool getContext( SdrViewContext& rContext );
+ virtual void disposing();
+ virtual void select();
+ virtual void deselect();
+
+ DECL_LINK( WindowEventHandler, VclWindowEvent* );
+ DECL_LINK( ClosePopupHdl, void* );
+
+private:
+ AnnotationManagerImpl& mrManager;
+ css::uno::Reference< css::office::XAnnotation > mxAnnotation;
+ std::auto_ptr<AnnotationWindow> mpAnnotationWindow;
+ Color maColor;
+ int mnIndex;
+ const Font& mrFont;
+ Size maSize;
+ ULONG mnClosePopupEvent;
+ ::Window* mpListenWindow;
+ Point maMouseDownPos;
+};
+
+} // end of namespace sd
+
+#endif // _SD_ANNOTATIONTAG_HXX_
+
diff --git a/sd/source/ui/annotations/annotationwindow.cxx b/sd/source/ui/annotations/annotationwindow.cxx
new file mode 100644
index 000000000000..ad6709c776ce
--- /dev/null
+++ b/sd/source/ui/annotations/annotationwindow.cxx
@@ -0,0 +1,848 @@
+/************************************************************************* *
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "precompiled_sd.hxx"
+
+#include <editeng/fontitem.hxx>
+#include <editeng/eeitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/bulitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/shdditem.hxx>
+#include <editeng/flditem.hxx>
+#include <editeng/frmdir.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <editeng/langitem.hxx>
+#include <editeng/adjitem.hxx>
+#include <editeng/editview.hxx>
+#include <svx/svdview.hxx>
+#include <svx/sdrpaintwindow.hxx>
+#include <svx/sdr/overlay/overlaymanager.hxx>
+#include <editeng/editstat.hxx> //EditEngine flags
+#include <editeng/outliner.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/editobj.hxx>
+#include <editeng/unolingu.hxx>
+#include <editeng/outlobj.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/crsditem.hxx>
+#include <svx/svxids.hrc>
+#include <svtools/langtab.hxx>
+#include <svl/slstitm.hxx>
+#include <unotools/securityoptions.hxx>
+#include <unotools/useroptions.hxx>
+#include <svl/languageoptions.hxx>
+#include <svl/zforlist.hxx>
+#include <svtools/svmedit.hxx>
+
+#include <linguistic/lngprops.hxx>
+
+#include <sfx2/request.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/mnumgr.hxx>
+
+#include <vcl/vclenum.hxx>
+#include <vcl/edit.hxx>
+#include <vcl/help.hxx>
+#include <vcl/scrbar.hxx>
+#include <vcl/button.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/gradient.hxx>
+#include <vcl/salbtype.hxx> // FRound
+#include <vcl/cursor.hxx>
+
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <basegfx/tuple/b2dtuple.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+
+#include "annotations.hrc"
+#include "annotationwindow.hxx"
+#include "annotationmanagerimpl.hxx"
+
+#include "DrawDocShell.hxx"
+#include "ViewShell.hxx"
+#include "drawdoc.hxx"
+#include "View.hxx"
+#include "textapi.hxx"
+#include "sdresid.hxx"
+
+using rtl::OUString;
+using namespace ::sd;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::office;
+using namespace ::com::sun::star::text;
+
+#define METABUTTON_WIDTH 16
+#define METABUTTON_HEIGHT 18
+#define METABUTTON_AREA_WIDTH 30
+#define POSTIT_META_HEIGHT (sal_Int32) 30
+
+#define EMPTYSTRING rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(""))
+
+namespace sd {
+
+extern OUString getAnnotationDateTimeString( const Reference< XAnnotation >& xAnnotation );
+extern SfxItemPool* GetAnnotationPool();
+extern com::sun::star::util::DateTime getCurrentDateTime();
+
+Color ColorFromAlphaColor(UINT8 aTransparency, Color &aFront, Color &aBack )
+{
+ return Color((UINT8)(aFront.GetRed() * aTransparency/(double)255 + aBack.GetRed() * (1-aTransparency/(double)255)),
+ (UINT8)(aFront.GetGreen() * aTransparency/(double)255 + aBack.GetGreen() * (1-aTransparency/(double)255)),
+ (UINT8)(aFront.GetBlue() * aTransparency/(double)255 + aBack.GetBlue() * (1-aTransparency/(double)255)));
+}
+
+/************ AnnotationTextWindow **********************************/
+
+AnnotationTextWindow::AnnotationTextWindow( AnnotationWindow* pParent, WinBits nBits )
+: Control(pParent, nBits)
+, mpOutlinerView(0)
+, mpAnnotationWindow( pParent )
+{
+}
+
+AnnotationTextWindow::~AnnotationTextWindow()
+{
+}
+
+void AnnotationTextWindow::Paint( const Rectangle& rRect)
+{
+ if ( !Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
+ {
+ DrawGradient(Rectangle(Point(0,0),PixelToLogic(GetSizePixel())),
+ Gradient(GRADIENT_LINEAR,mpAnnotationWindow->maColorLight,mpAnnotationWindow->maColor));
+ }
+
+ if( mpOutlinerView )
+ mpOutlinerView->Paint( rRect );
+}
+
+void AnnotationTextWindow::KeyInput( const KeyEvent& rKeyEvt )
+{
+ const KeyCode& rKeyCode = rKeyEvt.GetKeyCode();
+ USHORT nKey = rKeyCode.GetCode();
+
+ if ((rKeyCode.IsMod1() && rKeyCode.IsMod2()) && ((nKey == KEY_PAGEUP) || (nKey == KEY_PAGEDOWN)))
+ {
+ SfxDispatcher* pDispatcher = mpAnnotationWindow->DocShell()->GetViewShell()->GetViewFrame()->GetDispatcher();
+ if( pDispatcher )
+ pDispatcher->Execute( nKey == KEY_PAGEDOWN ? SID_NEXT_POSTIT : SID_PREVIOUS_POSTIT );
+ }
+ else if (nKey == KEY_INSERT)
+ {
+ if (!rKeyCode.IsMod1() && !rKeyCode.IsMod2())
+ mpAnnotationWindow->ToggleInsMode();
+ }
+ else
+ {
+ long aOldHeight = mpAnnotationWindow->GetPostItTextHeight();
+ bool bDone = false;
+
+ /// HACK: need to switch off processing of Undo/Redo in Outliner
+ if ( !( (nKey == KEY_Z || nKey == KEY_Y) && rKeyCode.IsMod1()) )
+ {
+ bool bIsProtected = mpAnnotationWindow->IsProtected();
+ if (!bIsProtected || (bIsProtected && !mpAnnotationWindow->Engine()->GetEditEngine().DoesKeyChangeText(rKeyEvt)) )
+
+ bDone = mpOutlinerView->PostKeyEvent( rKeyEvt );
+ }
+ if (bDone)
+ {
+ mpAnnotationWindow->ResizeIfNeccessary(aOldHeight,mpAnnotationWindow->GetPostItTextHeight());
+ }
+ else
+ {
+ Control::KeyInput(rKeyEvt);
+ }
+ }
+}
+
+void AnnotationTextWindow::MouseMove( const MouseEvent& rMEvt )
+{
+ if ( mpOutlinerView )
+ {
+ mpOutlinerView->MouseMove( rMEvt );
+ SetPointer( mpOutlinerView->GetPointer( rMEvt.GetPosPixel() ) );
+ }
+}
+
+void AnnotationTextWindow::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ GrabFocus();
+ if ( mpOutlinerView )
+ mpOutlinerView->MouseButtonDown( rMEvt );
+ // todo mpOutlinerView->DocView()->GetViewFrame()->GetBindings().InvalidateAll(FALSE);
+}
+
+void AnnotationTextWindow::MouseButtonUp( const MouseEvent& rMEvt )
+{
+ if ( mpOutlinerView )
+ mpOutlinerView->MouseButtonUp( rMEvt );
+}
+
+void AnnotationTextWindow::Command( const CommandEvent& rCEvt )
+{
+ if ( rCEvt.GetCommand() == COMMAND_CONTEXTMENU )
+ {
+ mpAnnotationWindow->Command(rCEvt);
+ }
+ else
+ {
+ if ( mpOutlinerView )
+ mpOutlinerView->Command( rCEvt );
+ else
+ Window::Command(rCEvt);
+ }
+}
+
+void AnnotationTextWindow::GetFocus()
+{
+ Window::GetFocus();
+}
+
+void AnnotationTextWindow::LoseFocus()
+{
+// if ( mpAnnotationWindow )
+// mpAnnotationWindow->UpdateAnnotation();
+
+ Window::LoseFocus();
+}
+
+XubString AnnotationTextWindow::GetSurroundingText() const
+{
+ if( mpOutlinerView )
+ {
+ EditEngine *aEditEngine = mpOutlinerView->GetEditView().GetEditEngine();
+ if( mpOutlinerView->HasSelection() )
+ return mpOutlinerView->GetSelected();
+ else
+ {
+ ESelection aSelection = mpOutlinerView->GetEditView().GetSelection();
+ XubString aStr = aEditEngine->GetText(aSelection.nStartPara);
+ return aStr;
+ }
+ }
+ else
+ return XubString::EmptyString();
+}
+
+Selection AnnotationTextWindow::GetSurroundingTextSelection() const
+{
+ if( mpOutlinerView )
+ {
+ if( mpOutlinerView->HasSelection() )
+ return Selection( 0, mpOutlinerView->GetSelected().Len() );
+ else
+ {
+ ESelection aSelection = mpOutlinerView->GetEditView().GetSelection();
+ return Selection( aSelection.nStartPos, aSelection.nEndPos );
+ }
+ }
+ else
+ return Selection( 0, 0 );
+}
+
+/************** AnnotationWindow***********************************++*/
+
+AnnotationWindow::AnnotationWindow( AnnotationManagerImpl& rManager, DrawDocShell* pDocShell, Window* pParent )
+: FloatingWindow(pParent, WB_SYSTEMWINDOW|WB_BORDER|WB_NEEDSFOCUS)
+, mrManager( rManager )
+, mpDocShell( pDocShell )
+, mpView( pDocShell->GetViewShell()->GetView() )
+, mpDoc( pDocShell->GetDoc() )
+, mpOutlinerView(0)
+, mpOutliner(0)
+, mpVScrollbar(0)
+, mbReadonly(pDocShell->IsReadOnly())
+, mbProtected(false)
+, mbMouseOverButton(false)
+, mpTextWindow(0)
+, mpMeta(0)
+{
+}
+
+AnnotationWindow::~AnnotationWindow()
+{
+ delete mpMeta;
+ delete mpOutlinerView;
+ delete mpOutliner;
+ delete mpVScrollbar;
+ delete mpTextWindow;
+}
+
+void AnnotationWindow::InitControls()
+{
+ // actual window which holds the user text
+ mpTextWindow = new AnnotationTextWindow(this, WB_NODIALOGCONTROL);
+ mpTextWindow->SetPointer(Pointer(POINTER_TEXT));
+
+ // window control for author and date
+ mpMeta = new MultiLineEdit(this,0);
+ mpMeta->SetReadOnly();
+ mpMeta->SetRightToLeft(Application::GetSettings().GetLayoutRTL());
+ mpMeta->AlwaysDisableInput(true);
+ mpMeta->SetCallHandlersOnInputDisabled(true);
+
+// mpMeta->AddEventListener( LINK( mpPostItTxt, PostItTxt, WindowEventListener ) );
+// AddEventListener( LINK( mpTextWindow, PostItTxt, WindowEventListener ) );
+
+ // we should leave this setting alone, but for this we need a better layout algo
+ // with variable meta size height
+ AllSettings aSettings = mpMeta->GetSettings();
+ StyleSettings aStyleSettings = aSettings.GetStyleSettings();
+ Font aFont = aStyleSettings.GetFieldFont();
+ aFont.SetHeight(8);
+ aStyleSettings.SetFieldFont(aFont);
+ aSettings.SetStyleSettings(aStyleSettings);
+ mpMeta->SetSettings(aSettings);
+
+ mpOutliner = new ::Outliner(GetAnnotationPool(),OUTLINERMODE_TEXTOBJECT);
+ Doc()->SetCalcFieldValueHdl( mpOutliner );
+ mpOutliner->SetUpdateMode( TRUE );
+ Rescale();
+
+ OutputDevice* pDev = Doc()->GetRefDevice();
+ if( pDev )
+ {
+ mpOutliner->SetRefDevice( pDev );
+ }
+
+ mpOutlinerView = new OutlinerView ( mpOutliner, mpTextWindow );
+ mpOutliner->InsertView(mpOutlinerView );
+ mpTextWindow->SetOutlinerView(mpOutlinerView);
+ mpOutlinerView->SetOutputArea( PixelToLogic( Rectangle(0,0,1,1) ) );
+
+// SfxItemSet item(DocShell()->GetPool());
+// item.Put(SvxFontHeightItem(352,100,EE_CHAR_FONTHEIGHT));
+// mpOutlinerView->SetAttribs(item);
+
+ // TODO: ??
+ EEHorizontalTextDirection aDefHoriTextDir = Application::GetSettings().GetLayoutRTL() ? EE_HTEXTDIR_R2L : EE_HTEXTDIR_L2R;
+ mpOutliner->SetDefaultHorizontalTextDirection( aDefHoriTextDir );
+
+ //create Scrollbars
+ mpVScrollbar = new ScrollBar(this, WB_3DLOOK |WB_VSCROLL|WB_DRAG);
+ mpVScrollbar->EnableNativeWidget(false);
+ mpVScrollbar->EnableRTL( false );
+ mpVScrollbar->SetScrollHdl(LINK(this, AnnotationWindow, ScrollHdl));
+ mpVScrollbar->EnableDrag();
+// mpVScrollbar->AddEventListener( LINK( this, AnnotationWindow, WindowEventListener ) );
+
+ ULONG nCntrl = mpOutliner->GetControlWord();
+ nCntrl |= EE_CNTRL_PASTESPECIAL | EE_CNTRL_AUTOCORRECT | EV_CNTRL_AUTOSCROLL | EE_CNTRL_NOCOLORS;
+/*
+ if (pVOpt->IsFieldShadings())
+ nCntrl |= EE_CNTRL_MARKFIELDS;
+ else
+ nCntrl &= ~EE_CNTRL_MARKFIELDS;
+ if (pVOpt->IsOnlineSpell())
+ nCntrl |= EE_CNTRL_ONLINESPELLING;
+ else
+ nCntrl &= ~EE_CNTRL_ONLINESPELLING;
+*/
+ mpOutliner->SetControlWord(nCntrl);
+// mpOutliner->SetFlatMode( TRUE );
+
+ Engine()->SetModifyHdl( Link() );
+ Engine()->EnableUndo( FALSE );
+
+ Engine()->ClearModifyFlag();
+ Engine()->GetUndoManager().Clear();
+ Engine()->EnableUndo( TRUE );
+ Engine()->SetModifyHdl( LINK( this, AnnotationWindow, ModifyHdl ) );
+
+ Invalidate();
+
+ SetLanguage(GetLanguage());
+
+ mpMeta->Show();
+ mpVScrollbar->Show();
+ mpTextWindow->Show();
+}
+
+void AnnotationWindow::StartEdit()
+{
+ getView()->SetSelection(ESelection(0xFFFF,0xFFFF,0xFFFF,0xFFFF));
+ getView()->ShowCursor();
+}
+
+void AnnotationWindow::Rescale()
+{
+ MapMode aMode(MAP_100TH_MM);
+ aMode.SetOrigin( Point() );
+ //aMode.SetScaleX( aMode.GetScaleX() * Fraction( 8, 10 ) );
+ //aMode.SetScaleY( aMode.GetScaleY() * Fraction( 8, 10 ) );
+ mpOutliner->SetRefMapMode( aMode );
+ SetMapMode( aMode );
+ mpTextWindow->SetMapMode( aMode );
+ if ( mpMeta )
+ {
+ Font aFont( mpMeta->GetSettings().GetStyleSettings().GetFieldFont() );
+ sal_Int32 nHeight = aFont.GetHeight();
+ nHeight = nHeight * aMode.GetScaleY().GetNumerator() / aMode.GetScaleY().GetDenominator();
+ aFont.SetHeight( nHeight );
+ mpMeta->SetControlFont( aFont );
+ }
+}
+
+void AnnotationWindow::DoResize()
+{
+ unsigned long aWidth = GetSizePixel().Width();
+ long aHeight = GetSizePixel().Height() - POSTIT_META_HEIGHT;
+
+ mpOutliner->SetPaperSize( PixelToLogic( Size(aWidth,aHeight) ) ) ;
+ long aTextHeight = LogicToPixel( mpOutliner->CalcTextSize()).Height();
+
+ if( aTextHeight > aHeight )
+ { // we need vertical scrollbars and have to reduce the width
+ aWidth -= GetScrollbarWidth();
+ mpVScrollbar->Show();
+ }
+ else
+ {
+ mpVScrollbar->Hide();
+ }
+
+ mpTextWindow->SetPosSizePixel(0,0,aWidth, aHeight);
+
+ if( mbReadonly )
+ mpMeta->SetPosSizePixel(0,aHeight,GetSizePixel().Width(),POSTIT_META_HEIGHT);
+ else
+ mpMeta->SetPosSizePixel(0,aHeight,GetSizePixel().Width()-METABUTTON_AREA_WIDTH,POSTIT_META_HEIGHT);
+
+ mpOutliner->SetPaperSize( PixelToLogic( Size(aWidth,aHeight) ) ) ;
+ mpOutlinerView->SetOutputArea( PixelToLogic( Rectangle(0,0,aWidth,aHeight) ) );
+ if (!mpVScrollbar->IsVisible())
+ { // if we do not have a scrollbar anymore, we want to see the complete text
+ mpOutlinerView->SetVisArea( PixelToLogic( Rectangle(0,0,aWidth,aHeight) ) );
+ }
+ mpVScrollbar->SetPosSizePixel( 0 + aWidth, 0, GetScrollbarWidth(), aHeight );
+ mpVScrollbar->SetVisibleSize( PixelToLogic(Size(0,aHeight)).Height() );
+ mpVScrollbar->SetPageSize( PixelToLogic(Size(0,aHeight)).Height() * 8 / 10 );
+ mpVScrollbar->SetLineSize( mpOutliner->GetTextHeight() / 10 );
+ SetScrollbar();
+ mpVScrollbar->SetRange( Range(0, mpOutliner->GetTextHeight()));
+
+ Point aPos( mpMeta->GetPosPixel());
+ Point aBase( aPos.X() + aPos.X() + GetSizePixel().Width(), aPos.Y() );
+ Point aLeft = PixelToLogic( Point( aBase.X() - (METABUTTON_WIDTH+5), aBase.Y()+17 ) );
+ Point aRight = PixelToLogic( Point( aBase.X() - (METABUTTON_WIDTH-1), aBase.Y()+17 ) );
+ Point aBottom = PixelToLogic( Point( aBase.X() - (METABUTTON_WIDTH+2), aBase.Y()+20 ) );
+
+ maPopupTriangle.clear();
+ maPopupTriangle.append(basegfx::B2DPoint(aLeft.X(),aLeft.Y()));
+ maPopupTriangle.append(basegfx::B2DPoint(aRight.X(),aRight.Y()));
+ maPopupTriangle.append(basegfx::B2DPoint(aBottom.X(),aBottom.Y()));
+ maPopupTriangle.setClosed(true);
+ maRectMetaButton = PixelToLogic( Rectangle( Point(
+ aPos.X()+GetSizePixel().Width()-(METABUTTON_WIDTH+10),
+ aPos.Y()+5 ),
+ Size( METABUTTON_WIDTH, METABUTTON_HEIGHT ) ) );
+
+}
+
+void AnnotationWindow::SetSizePixel( const Size& rNewSize )
+{
+ Window::SetSizePixel(rNewSize);
+}
+
+void AnnotationWindow::SetScrollbar()
+{
+ mpVScrollbar->SetThumbPos( mpOutlinerView->GetVisArea().Top()+ mpOutlinerView->GetEditView().GetCursor()->GetOffsetY());
+}
+
+void AnnotationWindow::ResizeIfNeccessary(long aOldHeight, long aNewHeight)
+{
+ if (aOldHeight != aNewHeight)
+ {
+ DoResize();
+ Invalidate();
+ }
+ else
+ {
+ SetScrollbar();
+ }
+}
+
+void AnnotationWindow::SetReadonly(bool bSet)
+{
+ mbReadonly = bSet;
+ getView()->SetReadOnly(bSet);
+}
+
+void AnnotationWindow::SetLanguage(const SvxLanguageItem aNewItem)
+{
+ Engine()->SetModifyHdl( Link() );
+ ESelection aOld = getView()->GetSelection();
+
+ ESelection aNewSelection( 0, 0, (USHORT)Engine()->GetParagraphCount()-1, USHRT_MAX );
+ getView()->SetSelection( aNewSelection );
+ SfxItemSet aEditAttr(getView()->GetAttribs());
+ aEditAttr.Put(aNewItem);
+ getView()->SetAttribs( aEditAttr );
+
+ getView()->SetSelection(aOld);
+ Engine()->SetModifyHdl( LINK( this, AnnotationWindow, ModifyHdl ) );
+
+ Invalidate();
+}
+
+void AnnotationWindow::ToggleInsMode()
+{
+ if( mpOutlinerView )
+ {
+ SfxBindings &rBnd = mpDocShell->GetViewShell()->GetViewFrame()->GetBindings();
+ rBnd.Invalidate(SID_ATTR_INSERT);
+ rBnd.Update(SID_ATTR_INSERT);
+ }
+}
+
+long AnnotationWindow::GetPostItTextHeight()
+{
+ return mpOutliner ? LogicToPixel(mpOutliner->CalcTextSize()).Height() : 0;
+}
+
+IMPL_LINK(AnnotationWindow, ScrollHdl, ScrollBar*, pScroll)
+{
+ long nDiff = getView()->GetEditView().GetVisArea().Top() - pScroll->GetThumbPos();
+ getView()->Scroll( 0, nDiff );
+ return 0;
+}
+
+IMPL_LINK(AnnotationWindow, ModifyHdl, void*, EMPTYARG)
+{
+ return 0;
+}
+
+sal_Int32 AnnotationWindow::GetScrollbarWidth()
+{
+ return 16;
+// return mpView->GetWrtShell().GetViewOptions()->GetZoom() / 10;
+}
+
+SvxLanguageItem AnnotationWindow::GetLanguage(void)
+{
+ return SvxLanguageItem( Doc()->GetLanguage( EE_CHAR_LANGUAGE ), SID_ATTR_LANGUAGE );
+}
+
+// --------------------------------------------------------------------
+
+TextApiObject* getTextApiObject( const Reference< XAnnotation >& xAnnotation )
+{
+ if( xAnnotation.is() )
+ {
+ Reference< XText > xText( xAnnotation->getTextRange() );
+ return TextApiObject::getImplementation( xText );
+ }
+ return 0;
+}
+
+// --------------------------------------------------------------------
+
+void AnnotationWindow::setAnnotation( const Reference< XAnnotation >& xAnnotation, bool bGrabFocus )
+{
+ if( (xAnnotation != mxAnnotation) && xAnnotation.is() )
+ {
+ mxAnnotation = xAnnotation;
+
+ SetColor();
+
+ SvtUserOptions aUserOptions;
+ mbProtected = aUserOptions.GetFullName() != xAnnotation->getAuthor();
+
+ Engine()->Clear();
+ TextApiObject* pTextApi = getTextApiObject( mxAnnotation );
+
+ if( pTextApi )
+ {
+ std::auto_ptr< OutlinerParaObject > pOPO( pTextApi->CreateText() );
+ Engine()->SetText( *pOPO.get() );
+ }
+
+ Engine()->SetModifyHdl( LINK( this, AnnotationWindow, ModifyHdl ) );
+ Engine()->ClearModifyFlag();
+ Engine()->GetUndoManager().Clear();
+
+ Invalidate();
+
+ OUString sMeta( xAnnotation->getAuthor() );
+ OUString sDateTime( getAnnotationDateTimeString(xAnnotation) );
+
+ if( sDateTime.getLength() != 0 )
+ {
+ if( sMeta.getLength() != 0 )
+ sMeta += OUString( RTL_CONSTASCII_USTRINGPARAM( "\n" ) );
+
+ sMeta += sDateTime;
+ }
+ mpMeta->SetText(sMeta);
+
+ if( bGrabFocus )
+ GrabFocus();
+ }
+}
+
+void AnnotationWindow::SetColor()
+{
+ sal_uInt16 nAuthorIdx = mpDoc->GetAnnotationAuthorIndex( mxAnnotation->getAuthor() );
+
+ maColor = mrManager.GetColor( nAuthorIdx );
+ maColorDark = mrManager.GetColorDark( nAuthorIdx );
+ maColorLight = mrManager.GetColorLight( nAuthorIdx );
+
+ mpOutlinerView->SetBackgroundColor(maColor);
+
+ mpMeta->SetControlBackground(maColor);
+ AllSettings aSettings = mpMeta->GetSettings();
+ StyleSettings aStyleSettings = aSettings.GetStyleSettings();
+ aStyleSettings.SetFieldTextColor(maColorDark);
+ aSettings.SetStyleSettings(aStyleSettings);
+ mpMeta->SetSettings(aSettings);
+
+ AllSettings aSettings2 = mpVScrollbar->GetSettings();
+ StyleSettings aStyleSettings2 = aSettings2.GetStyleSettings();
+ aStyleSettings2.SetButtonTextColor(Color(0,0,0));
+ aStyleSettings2.SetCheckedColor(maColorLight); //hintergund
+ aStyleSettings2.SetShadowColor(maColorDark);
+ aStyleSettings2.SetFaceColor(maColor);
+ aSettings2.SetStyleSettings(aStyleSettings2);
+ mpVScrollbar->SetSettings(aSettings2);
+}
+
+void AnnotationWindow::Deactivate()
+{
+ Reference< XAnnotation > xAnnotation( mxAnnotation );
+/*
+ // check if text is empty
+ Paragraph* p1stPara=Engine()->GetParagraph( 0 );
+ ULONG nParaAnz=Engine()->GetParagraphCount();
+ if(p1stPara==NULL)
+ nParaAnz=0;
+
+ if(nParaAnz==1)
+ {
+ // if it is only one paragraph, check if that paragraph is empty
+ XubString aStr(Engine()->GetText(p1stPara));
+
+ if(!aStr.Len())
+ nParaAnz = 0;
+ }
+
+ if( nParaAnz == 0 )
+ {
+ // text is empty, delete postit
+ DeleteAnnotation( xAnnotation );
+ }
+ else
+*/
+ {
+ // write changed text back to annotation
+ if ( Engine()->IsModified() )
+ {
+ TextApiObject* pTextApi = getTextApiObject( xAnnotation );
+
+ if( pTextApi )
+ {
+ OutlinerParaObject* pOPO = Engine()->CreateParaObject();
+ if( pOPO )
+ {
+ if( mpDoc->IsUndoEnabled() )
+ mpDoc->BegUndo( String( SdResId( STR_ANNOTATION_UNDO_EDIT ) ) );
+
+ pTextApi->SetText( *pOPO );
+ delete pOPO;
+
+ // set current time to changed annotation
+ xAnnotation->setDateTime( getCurrentDateTime() );
+
+ if( mpDoc->IsUndoEnabled() )
+ mpDoc->EndUndo();
+
+ DocView()->GetDocSh()->SetModified(sal_True);
+ }
+
+ }
+ }
+ Engine()->ClearModifyFlag();
+ }
+
+ Engine()->GetUndoManager().Clear();
+}
+
+void AnnotationWindow::Paint( const Rectangle& rRect)
+{
+ FloatingWindow::Paint( rRect );
+
+ if(mpMeta->IsVisible() && !mbReadonly)
+ {
+ //draw left over space
+ if ( Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
+ SetFillColor(COL_BLACK);
+ else
+ SetFillColor(maColor);
+ SetLineColor();
+ DrawRect(PixelToLogic(Rectangle(Point(mpMeta->GetPosPixel().X()+mpMeta->GetSizePixel().Width(),mpMeta->GetPosPixel().Y()),Size(METABUTTON_AREA_WIDTH,mpMeta->GetSizePixel().Height()))));
+
+ if ( Application::GetSettings().GetStyleSettings().GetHighContrastMode())
+ {
+ //draw rect around button
+ SetFillColor(COL_BLACK);
+ SetLineColor(COL_WHITE);
+ }
+ else
+ {
+ //draw button
+ Gradient aGradient;
+ if (mbMouseOverButton)
+ aGradient = Gradient(GRADIENT_LINEAR,ColorFromAlphaColor(80,maColorDark,maColor),ColorFromAlphaColor(15,maColorDark,maColor));
+ else
+ aGradient = Gradient(GRADIENT_LINEAR,ColorFromAlphaColor(15,maColorDark,maColor),ColorFromAlphaColor(80,maColorDark,maColor));
+ DrawGradient(maRectMetaButton,aGradient);
+ //draw rect around button
+ SetFillColor();
+ SetLineColor(ColorFromAlphaColor(90,maColorDark,maColor));
+ }
+ DrawRect(maRectMetaButton);
+
+ //draw arrow
+ if ( Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
+ SetFillColor(COL_WHITE);
+ else
+ SetFillColor(COL_BLACK);
+ SetLineColor();
+ DrawPolygon(Polygon(maPopupTriangle));
+ }
+}
+
+void AnnotationWindow::MouseMove( const MouseEvent& rMEvt )
+{
+ if( !mbReadonly )
+ {
+ if (maRectMetaButton.IsInside(PixelToLogic(rMEvt.GetPosPixel())))
+ {
+ if (!mbMouseOverButton)
+ {
+ Invalidate(maRectMetaButton);
+ mbMouseOverButton = true;
+ }
+ }
+ else
+ {
+ if (mbMouseOverButton)
+ {
+ Invalidate(maRectMetaButton);
+ mbMouseOverButton = false;
+ }
+ }
+ }
+}
+
+void AnnotationWindow::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ if (!mbReadonly && maRectMetaButton.IsInside(PixelToLogic(rMEvt.GetPosPixel())) && rMEvt.IsLeft())
+ {
+ // context menu
+ Rectangle aRect(LogicToPixel(maRectMetaButton.BottomLeft()),LogicToPixel(maRectMetaButton.BottomLeft()));
+ mrManager.ExecuteAnnotationContextMenu( mxAnnotation, (::Window*)this, aRect, true );
+ }
+}
+
+void AnnotationWindow::Command( const CommandEvent& rCEvt )
+{
+ if ( rCEvt.GetCommand() == COMMAND_CONTEXTMENU )
+ {
+ if( mpMeta->IsVisible() &&(mpMeta->GetPosPixel().Y() < rCEvt.GetMousePosPixel().Y()) )
+ return;
+ mrManager.ExecuteAnnotationContextMenu( mxAnnotation, this, Rectangle(rCEvt.GetMousePosPixel(),Size(1,1)) );
+ }
+ else
+ {
+ FloatingWindow::Command(rCEvt);
+ }
+}
+
+void AnnotationWindow::GetFocus()
+{
+ if( mpTextWindow )
+ mpTextWindow->GrabFocus();
+ else
+ FloatingWindow::GetFocus();
+}
+
+void AnnotationWindow::ExecuteSlot( USHORT nSID )
+{
+ if( nSID == SID_COPY )
+ {
+ getView()->Copy();
+ }
+ else if( nSID == SID_PASTE )
+ {
+ getView()->PasteSpecial();
+ DoResize();
+ }
+ else
+ {
+ SfxItemSet aEditAttr(getView()->GetAttribs());
+ SfxItemSet aNewAttr(mpOutliner->GetEmptyItemSet());
+
+ switch( nSID )
+ {
+ case SID_ATTR_CHAR_WEIGHT:
+ {
+ FontWeight eFW = ( (const SvxWeightItem&) aEditAttr.Get( EE_CHAR_WEIGHT ) ).GetWeight();
+ aNewAttr.Put( SvxWeightItem( eFW == WEIGHT_NORMAL ? WEIGHT_BOLD : WEIGHT_NORMAL, EE_CHAR_WEIGHT ) );
+ }
+ break;
+ case SID_ATTR_CHAR_POSTURE:
+ {
+ FontItalic eFI = ( (const SvxPostureItem&) aEditAttr.Get( EE_CHAR_ITALIC ) ).GetPosture();
+ aNewAttr.Put( SvxPostureItem( eFI == ITALIC_NORMAL ? ITALIC_NONE : ITALIC_NORMAL, EE_CHAR_ITALIC ) );
+ }
+ break;
+ case SID_ATTR_CHAR_UNDERLINE:
+ {
+ FontUnderline eFU = ( (const SvxUnderlineItem&) aEditAttr. Get( EE_CHAR_UNDERLINE ) ).GetLineStyle();
+ aNewAttr.Put( SvxUnderlineItem( eFU == UNDERLINE_SINGLE ? UNDERLINE_NONE : UNDERLINE_SINGLE, EE_CHAR_UNDERLINE ) );
+ }
+ break;
+ case SID_ATTR_CHAR_STRIKEOUT:
+ {
+ FontStrikeout eFSO = ( ( (const SvxCrossedOutItem&) aEditAttr.Get( EE_CHAR_STRIKEOUT ) ).GetStrikeout() );
+ aNewAttr.Put( SvxCrossedOutItem( eFSO == STRIKEOUT_SINGLE ? STRIKEOUT_NONE : STRIKEOUT_SINGLE, EE_CHAR_STRIKEOUT ) );
+ }
+ break;
+ }
+ getView()->SetAttribs( aNewAttr );
+ }
+}
+
+}
diff --git a/sd/source/ui/annotations/annotationwindow.hxx b/sd/source/ui/annotations/annotationwindow.hxx
new file mode 100644
index 000000000000..ba82d4e862d3
--- /dev/null
+++ b/sd/source/ui/annotations/annotationwindow.hxx
@@ -0,0 +1,176 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _ANNOTATIONWINDOW_HXX
+#define _ANNOTATIONWINDOW_HXX
+
+#include <com/sun/star/office/XAnnotation.hpp>
+
+#include <tools/datetime.hxx>
+#include <tools/date.hxx>
+
+#include <vcl/ctrl.hxx>
+#include <vcl/lineinfo.hxx>
+#include <vcl/floatwin.hxx>
+
+#include <basegfx/polygon/b2dpolygon.hxx>
+
+#include <svx/sdr/overlay/overlayobject.hxx>
+#include <editeng/editstat.hxx>
+
+class OutlinerView;
+class Outliner;
+class ScrollBar;
+class Edit;
+class MultiLineEdit;
+class PopupMenu;
+class SvxLanguageItem;
+class OutlinerParaObject;
+class SdDrawDocument;
+
+namespace sd {
+
+class AnnotationManagerImpl;
+class AnnotationWindow;
+class DrawDocShell;
+class View;
+
+class AnnotationTextWindow : public Control
+{
+private:
+ OutlinerView* mpOutlinerView;
+ AnnotationWindow* mpAnnotationWindow;
+
+protected:
+ virtual void Paint( const Rectangle& rRect);
+ virtual void KeyInput( const KeyEvent& rKeyEvt );
+ virtual void MouseMove( const MouseEvent& rMEvt );
+ virtual void MouseButtonDown( const MouseEvent& rMEvt );
+ virtual void MouseButtonUp( const MouseEvent& rMEvt );
+ virtual void Command( const CommandEvent& rCEvt );
+ virtual void LoseFocus();
+
+public:
+ AnnotationTextWindow( AnnotationWindow* pParent, WinBits nBits );
+ ~AnnotationTextWindow();
+
+ void SetOutlinerView( OutlinerView* pOutlinerView ) { mpOutlinerView = pOutlinerView; }
+
+ virtual XubString GetSurroundingText() const;
+ virtual Selection GetSurroundingTextSelection() const;
+
+ virtual void GetFocus();
+};
+
+
+class AnnotationWindow : public FloatingWindow
+{
+ private:
+ AnnotationManagerImpl& mrManager;
+ DrawDocShell* mpDocShell;
+ View* mpView;
+ SdDrawDocument* mpDoc;
+
+ OutlinerView* mpOutlinerView;
+ Outliner* mpOutliner;
+ ScrollBar* mpVScrollbar;
+ ::com::sun::star::uno::Reference< ::com::sun::star::office::XAnnotation > mxAnnotation;
+ bool mbReadonly;
+ bool mbProtected;
+ bool mbMouseOverButton;
+ AnnotationTextWindow* mpTextWindow;
+ MultiLineEdit* mpMeta;
+ Rectangle maRectMetaButton;
+ basegfx::B2DPolygon maPopupTriangle;
+
+ protected:
+ void SetSizePixel( const Size& rNewSize );
+
+ DECL_LINK(ModifyHdl, void*);
+ DECL_LINK(ScrollHdl, ScrollBar*);
+
+ public:
+ AnnotationWindow( AnnotationManagerImpl& rManager, DrawDocShell* pDocShell, ::Window* pParent );
+ virtual ~AnnotationWindow();
+
+ void StartEdit();
+
+ virtual SvxLanguageItem GetLanguage(void);
+
+ void setAnnotation( const ::com::sun::star::uno::Reference< ::com::sun::star::office::XAnnotation >& xAnnotation, bool bGrabFocus = false );
+ const ::com::sun::star::uno::Reference< ::com::sun::star::office::XAnnotation >& getAnnotation() const { return mxAnnotation; }
+
+ void ExecuteSlot( USHORT nSID );
+
+ ScrollBar* Scrollbar() { return mpVScrollbar;}
+
+ DrawDocShell* DocShell() { return mpDocShell; }
+ OutlinerView* getView() { return mpOutlinerView; }
+ sd::View* DocView() { return mpView; }
+ Outliner* Engine() { return mpOutliner; }
+ SdDrawDocument* Doc() { return mpDoc; }
+
+ long GetPostItTextHeight();
+
+ void InitControls();
+ void HidePostIt();
+ void DoResize();
+ void ResizeIfNeccessary(long aOldHeight, long aNewHeight);
+ void SetScrollbar();
+
+ void Rescale();
+
+ void SetReadonly(bool bSet);
+ bool IsReadOnly() { return mbReadonly;}
+
+ bool IsProtected() { return mbProtected; }
+
+ void SetLanguage(const SvxLanguageItem aNewItem);
+
+ sal_Int32 GetScrollbarWidth();
+
+ void ToggleInsMode();
+
+ DECL_LINK( OnlineSpellCallback, SpellCallbackInfo*);
+
+ virtual void Deactivate();
+ virtual void Paint( const Rectangle& rRect);
+ virtual void MouseMove( const MouseEvent& rMEvt );
+ virtual void MouseButtonDown( const MouseEvent& rMEvt );
+ virtual void Command( const CommandEvent& rCEvt );
+ virtual void GetFocus();
+
+ void SetColor();
+
+ Color maColor;
+ Color maColorDark;
+ Color maColorLight;
+};
+
+} // namespace sd
+
+#endif
diff --git a/sd/source/ui/annotations/makefile.mk b/sd/source/ui/annotations/makefile.mk
new file mode 100644
index 000000000000..40a5c9181f16
--- /dev/null
+++ b/sd/source/ui/annotations/makefile.mk
@@ -0,0 +1,56 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PROJECTPCH=sd
+PROJECTPCHSOURCE=$(PRJ)$/util$/sd
+PRJNAME=sd
+TARGET=uiannotations
+ENABLE_EXCEPTIONS=TRUE
+AUTOSEG=true
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+SRS1NAME=$(TARGET)
+SRC1FILES =\
+ annotations.src
+
+SLOFILES = \
+ $(SLO)$/annotationwindow.obj \
+ $(SLO)$/annotationtag.obj \
+ $(SLO)$/annotationmanager.obj
+
+
+# --- Tagets -------------------------------------------------------
+
+.INCLUDE : target.mk