diff options
Diffstat (limited to 'sd/source/ui/annotations')
-rwxr-xr-x | sd/source/ui/annotations/annotationmanager.cxx | 1273 | ||||
-rwxr-xr-x | sd/source/ui/annotations/annotationmanagerimpl.hxx | 144 | ||||
-rw-r--r-- | sd/source/ui/annotations/annotations.hrc | 65 | ||||
-rw-r--r-- | sd/source/ui/annotations/annotations.src | 210 | ||||
-rwxr-xr-x | sd/source/ui/annotations/annotationtag.cxx | 790 | ||||
-rwxr-xr-x | sd/source/ui/annotations/annotationtag.hxx | 107 | ||||
-rwxr-xr-x | sd/source/ui/annotations/annotationwindow.cxx | 848 | ||||
-rwxr-xr-x | sd/source/ui/annotations/annotationwindow.hxx | 175 | ||||
-rw-r--r-- | sd/source/ui/annotations/makefile.mk | 56 |
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 100755 index 000000000000..cea71438ee4f --- /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() == sal_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, sal_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, sal_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(), sal_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( sal_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") ) ); + + sal_uInt16 nParaCount = aStr.GetTokenCount( '\n' ); + for( sal_uInt16 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 = (sal_uInt16)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, sal_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()); + sal_uInt16 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 /* = sal_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; +} +#if 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; +} +#endif + +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) ? sal_True : sal_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, sal_False ); + pMenu->EnableItem( SID_ATTR_CHAR_POSTURE, sal_False ); + pMenu->EnableItem( SID_ATTR_CHAR_UNDERLINE, sal_False ); + pMenu->EnableItem( SID_ATTR_CHAR_STRIKEOUT, sal_False ); + pMenu->EnableItem( SID_PASTE, sal_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() ); + } + + sal_uInt16 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( sal_uInt16 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..af88c852ff73 --- /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 = sal_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(); +#if 0 + rtl::OUString GetHelpText( ::com::sun::star::uno::Reference< ::com::sun::star::office::XAnnotation >& xAnnotation ); +#endif + 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; + sal_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..536d10f9a417 --- /dev/null +++ b/sd/source/ui/annotations/annotations.src @@ -0,0 +1,210 @@ +/************************************************************************* + * + * 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> +#include "helpids.h" + +Menu RID_ANNOTATION_CONTEXTMENU +{ + ItemList = + { + MenuItem + { + Identifier = SID_REPLYTO_POSTIT; + HelpId = CMD_SID_REPLYTO_POSTIT ; + Text [ en-US ] = "~Reply"; + }; + MenuItem + { + Separator = TRUE; + }; + MenuItem + { + Identifier = SID_ATTR_CHAR_WEIGHT; + HelpId = CMD_SID_ATTR_CHAR_WEIGHT ; + Text [ en-US ] = "~Bold"; + }; + MenuItem + { + Identifier = SID_ATTR_CHAR_POSTURE; + HelpId = CMD_SID_ATTR_CHAR_POSTURE; + Text [ en-US ] = "~Italic"; + }; + MenuItem + { + Identifier = SID_ATTR_CHAR_UNDERLINE; + HelpId = CMD_SID_ATTR_CHAR_UNDERLINE; + Text [ en-US ] = "~Underline"; + }; + MenuItem + { + Identifier = SID_ATTR_CHAR_STRIKEOUT; + HelpId = CMD_SID_ATTR_CHAR_STRIKEOUT; + Text [ en-US ] = "~Strikethrough"; + }; + MenuItem + { + Separator = TRUE; + }; + MenuItem + { + Identifier = SID_COPY ; + HelpId = CMD_SID_COPY ; + Text [ en-US ] = "~Copy" ; + }; + MenuItem + { + Identifier = SID_PASTE ; + HelpId = CMD_SID_PASTE ; + Text [ en-US ] = "~Paste" ; + }; + MenuItem + { + Separator = TRUE; + }; + MenuItem + { + Identifier = SID_DELETE_POSTIT ; + HelpId = CMD_SID_DELETE_POSTIT; + Text [ en-US ] = "~Delete Comment" ; + }; + MenuItem + { + Identifier = SID_DELETEALLBYAUTHOR_POSTIT ; + HelpId = CMD_SID_DELETEALLBYAUTHOR_POSTIT; + Text [ en-US ] = "Delete All Comments b~y %1" ; + }; + MenuItem + { + Identifier = SID_DELETEALL_POSTIT; + HelpId = CMD_SID_DELETEALL_POSTIT; + Text [ en-US ] = "Delete ~All Comments" ; + }; + }; +}; + +Menu RID_ANNOTATION_TAG_CONTEXTMENU +{ + ItemList = + { + MenuItem + { + Identifier = SID_REPLYTO_POSTIT; + HelpId = CMD_SID_REPLYTO_POSTIT; + Text [ en-US ] = "~Reply"; + }; + MenuItem + { + Separator = TRUE; + }; + MenuItem + { + Identifier = SID_DELETE_POSTIT ; + HelpId = CMD_SID_DELETE_POSTIT ; + Text [ en-US ] = "~Delete Comment" ; + }; + MenuItem + { + Identifier = SID_DELETEALLBYAUTHOR_POSTIT ; + HelpId = CMD_SID_DELETEALLBYAUTHOR_POSTIT ; + Text [ en-US ] = "Delete All Comments ~by %1" ; + }; + MenuItem + { + Identifier = SID_DELETEALL_POSTIT; + HelpId = CMD_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 100755 index 000000000000..f73ff0377102 --- /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 sal_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 sal_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 ); +/* + (sal_uInt16)(aBitmapEx.GetSizePixel().Width() - 1) >> 1, + (sal_uInt16)(aBitmapEx.GetSizePixel().Height() - 1) >> 1, + (sal_uInt16)(aBitmapEx2.GetSizePixel().Width() - 1) >> 1, + (sal_uInt16)(aBitmapEx2.GetSizePixel().Height() - 1) >> 1); +*/ + } + else + { + pOverlayObject = new ::sdr::overlay::OverlayBitmapEx( aPosition, aBitmapEx, 0, 0 ); + } + + rPageWindow.GetOverlayManager()->add(*pOverlayObject); + maOverlayGroup.append(*pOverlayObject); + } + } + } + } + } + } +} + +// -------------------------------------------------------------------- + +sal_Bool AnnotationHdl::IsFocusHdl() const +{ + return sal_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; + + sal_uInt16 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() +{ +} + +// -------------------------------------------------------------------- + +sal_uLong AnnotationTag::GetMarkablePointCount() const +{ + return 0; +} + +// -------------------------------------------------------------------- + +sal_uLong AnnotationTag::GetMarkedPointCount() const +{ + return 0; +} + +// -------------------------------------------------------------------- + +sal_Bool AnnotationTag::MarkPoint(SdrHdl& /*rHdl*/, sal_Bool /*bUnmark*/ ) +{ + sal_Bool bRet=sal_False; + return bRet; +} + +// -------------------------------------------------------------------- + +sal_Bool AnnotationTag::MarkPoints(const Rectangle* /*pRect*/, sal_Bool /*bUnmark*/ ) +{ + sal_Bool bChgd=sal_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, sal_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); + + sal_uInt16 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 sal_uInt16 nDrgLog = (sal_uInt16)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 sal_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 100755 index 000000000000..cce7e73eb6f3 --- /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 sal_uLong GetMarkablePointCount() const; + virtual sal_uLong GetMarkedPointCount() const; + virtual sal_Bool MarkPoint(SdrHdl& rHdl, sal_Bool bUnmark=sal_False); + virtual void CheckPossibilities(); + virtual sal_Bool MarkPoints(const Rectangle* pRect, sal_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; + sal_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 100755 index 000000000000..c84bf7d76aa3 --- /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(sal_uInt8 aTransparency, Color &aFront, Color &aBack ) +{ + return Color((sal_uInt8)(aFront.GetRed() * aTransparency/(double)255 + aBack.GetRed() * (1-aTransparency/(double)255)), + (sal_uInt8)(aFront.GetGreen() * aTransparency/(double)255 + aBack.GetGreen() * (1-aTransparency/(double)255)), + (sal_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) +{ + const bool bHighContrast = Application::GetSettings().GetStyleSettings().GetHighContrastMode(); + if ( !bHighContrast ) + { + DrawGradient(Rectangle(Point(0,0),PixelToLogic(GetSizePixel())), + Gradient(GRADIENT_LINEAR,mpAnnotationWindow->maColorLight,mpAnnotationWindow->maColor)); + } + + if( mpOutlinerView ) + { + Color aBackgroundColor( mpAnnotationWindow->maColor ); + if( bHighContrast ) + { + aBackgroundColor = GetSettings().GetStyleSettings().GetWindowColor(); + } + + mpOutlinerView->SetBackgroundColor( aBackgroundColor ); + + mpOutlinerView->Paint( rRect ); + } +} + +void AnnotationTextWindow::KeyInput( const KeyEvent& rKeyEvt ) +{ + const KeyCode& rKeyCode = rKeyEvt.GetKeyCode(); + sal_uInt16 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(sal_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( sal_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 ) ); + + sal_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( sal_True ); + + Engine()->SetModifyHdl( Link() ); + Engine()->EnableUndo( sal_False ); + + Engine()->ClearModifyFlag(); + Engine()->GetUndoManager().Clear(); + Engine()->EnableUndo( sal_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::SetLanguage(const SvxLanguageItem aNewItem) +{ + Engine()->SetModifyHdl( Link() ); + ESelection aOld = getView()->GetSelection(); + + ESelection aNewSelection( 0, 0, (sal_uInt16)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() ); + + const bool bHighContrast = Application::GetSettings().GetStyleSettings().GetHighContrastMode(); + if( bHighContrast ) + { + StyleSettings aStyleSettings = GetSettings().GetStyleSettings(); + + maColor = aStyleSettings.GetWindowColor(); + maColorDark = maColor; + maColorLight = aStyleSettings.GetWindowTextColor(); + } + else + { + maColor = mrManager.GetColor( nAuthorIdx ); + maColorDark = mrManager.GetColorDark( nAuthorIdx ); + maColorLight = mrManager.GetColorLight( nAuthorIdx ); + } + + mpOutlinerView->SetBackgroundColor(maColor); + Engine()->SetBackgroundColor(maColor); + + { + SvtAccessibilityOptions aOptions; + Engine()->ForceAutoColor( bHighContrast || aOptions.GetIsAutomaticFontColor() ); + } + + mpMeta->SetControlBackground(maColor); + AllSettings aSettings = mpMeta->GetSettings(); + StyleSettings aStyleSettings = aSettings.GetStyleSettings(); + aStyleSettings.SetFieldTextColor( bHighContrast ? maColorLight : 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 ); + + // 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) + { + const bool bHighContrast = Application::GetSettings().GetStyleSettings().GetHighContrastMode(); + //draw left over space + if ( bHighContrast ) + 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 ( bHighContrast ) + { + //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( bHighContrast ) + 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( sal_uInt16 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 100755 index 000000000000..09a03e02d87d --- /dev/null +++ b/sd/source/ui/annotations/annotationwindow.hxx @@ -0,0 +1,175 @@ +/************************************************************************* + * + * 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( sal_uInt16 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(); + + 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 |