Files
libreoffice/sw/source/ui/docvw/postit.cxx

1487 lines
46 KiB
C++
Raw Normal View History

INTEGRATION: CWS notes2 (1.1.2); FILE ADDED 2008/01/30 18:01:00 mod 1.1.2.94: #i6193# high contrast mode 2008/01/30 17:26:41 mod 1.1.2.93: #i6193# readonly state send to notes, swicht to next postit 2008/01/29 21:09:34 mba 1.1.2.92: Invalidate after setting text; Outliner seems not to be able to handle that correctly 2008/01/29 19:39:59 mod 1.1.2.91: spellchecking and context menu 2008/01/28 20:58:29 mod 1.1.2.90: yet another SetActivePostit bug 2008/01/28 11:50:39 mod 1.1.2.89: ux: meta area and popup during read-only 2008/01/28 09:50:09 mba 1.1.2.88: #i6193#: use locale from configuration to display date and time 2008/01/27 21:02:11 mba 1.1.2.87: #i84074#: improved undo implementation 2008/01/27 15:56:30 mba 1.1.2.86: #i84074#: better update procedure when content of notes is changed 2008/01/25 17:46:10 mod 1.1.2.85: View - Notes 2008/01/20 15:32:08 mod 1.1.2.84: fix for #i85392# 2008/01/18 21:02:24 mod 1.1.2.83: #i85064# scrolling inside notes 2008/01/18 17:08:47 mod 1.1.2.82: fix crash #i85375# 2008/01/18 09:58:19 mba 1.1.2.81: build problems on Solaris 2008/01/18 09:54:29 mba 1.1.2.80: build problems on Solaris 2008/01/18 09:36:35 mba 1.1.2.79: build problem on Solaris 2008/01/16 15:15:18 mod 1.1.2.78: fixes 2008/01/10 17:34:01 mod 1.1.2.77: show notes always right side, do not show popup for read only notes 2008/01/09 17:40:41 mod 1.1.2.76: scaling of scrollbar and sidebarwidth depending on zoom value 2008/01/09 16:36:24 mba 1.1.2.75: Complete rescaling of Postits 2008/01/09 15:52:04 mba 1.1.2.74: Complete rescaling of Postits 2008/01/09 13:19:20 mod 1.1.2.73: move of define 2008/01/09 07:55:06 mba 1.1.2.72: Button menu shouldn't close when mouse button is released 2008/01/07 16:08:43 mod 1.1.2.71: side of margin for each page individually, end of ankor if note is hidden at correct location 2007/12/21 16:42:54 mba 1.1.2.70: #i6193#: scale notes with zoom factor of edit window 2007/12/20 14:45:39 mod 1.1.2.69: center sidebar scrollbuttons fix 2007/12/17 09:00:11 mod 1.1.2.68: fixes for web layout and seperater between sidebar 2007/12/12 19:42:02 mod 1.1.2.67: fix for Delete Author's notes 2007/12/11 16:25:15 mod 1.1.2.66: ankor 2007/12/11 15:19:13 mod 1.1.2.65: various fixes and double ankor 2007/12/07 19:47:35 mod 1.1.2.64: fix crashes related to focus receival after destroying of a note 2007/12/06 21:21:16 mba 1.1.2.63: resetting of attributes should retain default attributes 2007/12/06 21:05:17 mod 1.1.2.62: we still need PaintPostIts for RES_SCRIPT 2007/12/02 15:26:05 mod 1.1.2.61: fix for url click and format reset 2007/12/02 15:13:28 mod 1.1.2.60: fix for url click and format reset 2007/12/02 14:04:57 mba 1.1.2.59: handling of hyperlinks 2007/11/29 14:47:00 mod 1.1.2.58: enable popup, bugfix for Ctrl-Alt-N 2007/11/29 10:53:54 mba 1.1.2.57: #i84074#: postits should be deactivated only explicitly; otherwise using dropdown toolbar buttons won't work 2007/11/29 00:12:02 mod 1.1.2.56: notes grow automatically till next note or page border 2007/11/27 14:55:32 mod 1.1.2.55: yet another layout fix; read only notes fix: copy/paste possible now; paint fix, patch by od 2007/11/22 12:09:40 mod 1.1.2.54: relayout every time note had focus, as the size could have changed 2007/11/22 11:40:24 mod 1.1.2.53: fix for scrolling behaviour in VisPortChg, register text toolbar instead of draw 2007/11/18 13:04:39 mod 1.1.2.52: yet another layout fix 2007/11/16 16:06:51 mod 1.1.2.51: fixes for keyboard shortcut popup and PreparePageContainer() 2007/11/15 17:03:13 mod 1.1.2.50: improved auto scrolling of document and notes sidebar 2007/11/13 16:43:09 mod 1.1.2.49: no doc context menu on sidebar, new keyboard shortcuts, improved sidebar scrolling, no richtext 2007/11/05 21:05:04 mod 1.1.2.48: remove uneccessary variables 2007/11/04 21:43:00 mod 1.1.2.47: completly new layout code by page 2007/10/22 15:43:19 mod 1.1.2.46: added handler for ESCAPE 2007/10/22 10:04:24 mod 1.1.2.45: fix for centered zoom; new buttons inside meta area 2007/10/15 17:33:02 mod 1.1.2.44: fix for SwRootFrm::paint bug 2007/10/12 22:30:12 mod 1.1.2.43: fix for overlays, layout algorithm fix, patch for ww8 import 2007/10/10 21:32:18 mod 1.1.2.42: paint of sidebar; notes scrollbars fixed 2007/10/08 17:18:31 mod 1.1.2.41: meta information not shown 2007/10/08 16:53:25 mod 1.1.2.40: fix for meta information tooltip, fix for localisation of date and time, assertion: object deleted is in use fix, fix for focus issue 2007/10/06 17:14:48 mod 1.1.2.39: fix for different page widths 2007/10/05 15:36:03 mod 1.1.2.38: fix for RightToLeft, fix for sidebar drawing 2007/10/04 14:23:07 mod 1.1.2.37: change fixed values to defines 2007/10/02 16:51:34 mod 1.1.2.36: bugfixing; adding of ChangeDocSize in appropiate places 2007/10/01 13:00:16 mod 1.1.2.35: fix for overlays, they are working now :-) 2007/09/29 21:53:55 mod 1.1.2.34: fix warnings 2007/09/27 14:42:57 mod 1.1.2.33: bugfix for smoketest, removal of warnings, cleanup 2007/09/25 17:48:28 mod 1.1.2.32: resize() 2007/09/25 15:37:33 mod 1.1.2.31: bugfix 2007/09/25 15:11:35 mod 1.1.2.30: cleanups and optimization 2007/09/24 13:49:51 mod 1.1.2.29: notes are now collected inside SwTxtFld::SwTxtFld, IsInVisibleArea added to PostItMg, new colors for change tracking 2007/09/14 15:49:58 mod 1.1.2.28: remove unneccessary code from SwTextShell::ExecField 2007/09/10 23:14:53 mod 1.1.2.27: m 2007/09/07 16:49:23 mod 1.1.2.26: Page_Frm bug fix 2007/09/06 21:29:35 mod 1.1.2.25: Gradient for text, no notes for print view 2007/09/05 10:16:25 mod 1.1.2.24: Options-Writer-View-Notes;EnableInput and colors for meta information, start of RTL code 2007/09/03 15:06:26 mod 1.1.2.23: SwAnnotationShell, MultiLineEdit for meta information 2007/09/01 13:06:07 mod 1.1.2.22: new colors,bugfix for delete note 2007/07/09 13:07:51 mod 1.1.2.21: work on SwAnnotationShell continues 2007/07/06 09:28:07 mba 1.1.2.20: fixed problem with font sizes 2007/07/05 18:47:31 mod 1.1.2.19: Bugfixes: spellchecking works again as well as some crashes fixed 2007/07/04 15:42:22 mba 1.1.2.18: new shell for editing notes 2007/07/01 16:22:33 mod 1.1.2.17: no relayout in Paint(), but seperately in appropiate places 2007/06/29 19:02:15 mod 1.1.2.16: Fix for Undo/Redo of Insert Field and Modify Field 2007/06/26 16:34:51 mod 1.1.2.15: navigation for notes 2007/06/23 02:49:10 mod 1.1.2.14: beauty update: round corners, bold meta text 2007/06/22 20:59:57 mba 1.1.2.13: fixing some problems with dependencies 2007/06/21 07:43:12 mod 1.1.2.12: first code for layout algorithm, use of IsReadOnly and SetModified 2007/06/17 19:27:20 mod 1.1.2.11: AddPostIts only if there is a new postit, sorting of postits 2007/06/16 08:26:01 mod 1.1.2.10: #i6193# seperation of coordinate's rect and layout 2007/06/13 10:39:46 mod 1.1.2.9: spelling 2007/06/13 08:56:10 mod 1.1.2.8: #i6193# Navigator improvements, KeyHandling SwPostit 2007/06/10 15:59:29 mod 1.1.2.7: #i6193# Navigator: Hide,Show,Delete / SwPostIt: Author,Date 2007/06/08 16:48:18 mod 1.1.2.6: Hiding and deleting of notes #i6193# 2007/05/31 07:54:58 mod 1.1.2.5: #i6193# Use of overlayobject for ankor 2007/05/29 08:24:32 mod 1.1.2.4: Collecting notes in notify, positioning in paint 2007/05/29 07:53:18 fme 1.1.2.3: #i6193# New notes - moved defines from hxx to cxx 2007/05/25 06:54:01 fme 1.1.2.2: #i6193# New notes - forward declarations 2007/05/24 04:36:31 mod 1.1.2.1: Add new files
2008-02-19 12:55:27 +00:00
/************************************************************************* *
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: postit.cxx,v $
*
* $Revision: 1.2 $
*
* last change: $Author: rt $ $Date: 2008-02-19 13:55:27 $
*
* The Contents of this file are made available subject to
* the terms of GNU Lesser General Public License Version 2.1.
*
*
* GNU Lesser General Public License Version 2.1
* =============================================
* Copyright 2007 by Sun Microsystems, Inc.
* 901 San Antonio Road, Palo Alto, CA 94303, USA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1, as published by the Free Software Foundation.
*
* This library 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 for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
************************************************************************/
#include "precompiled_sw.hxx"
#ifndef _POSTIT_HXX
#include <postit.hxx>
#endif
#ifndef _POSTITMGR_HXX
#include <PostItMgr.hxx>
#endif
#ifndef _POPUP_HRC
#include <popup.hrc>
#endif
#ifndef _DOCVW_HRC
#include <docvw.hrc>
#endif
#include <hintids.hxx>
#include "viewopt.hxx"
#include "cmdid.h"
#include <vcl/scrbar.hxx>
#include <vcl/button.hxx>
#include <tools/poly.hxx> // Polygon
#include <vcl/svapp.hxx>
#include <vcl/gradient.hxx>
#include <svx/eeitem.hxx>
#include <svx/fhgtitem.hxx>
#include <svx/bulitem.hxx>
#include <svx/udlnitem.hxx>
#include <svx/shdditem.hxx>
#include <svx/wghtitem.hxx>
#include <svx/colritem.hxx>
#include <svx/flditem.hxx>
#include <svtools/zforlist.hxx>
#include <svx/editview.hxx>
#ifndef _SVDVIEW_HXX
#include <svx/svdview.hxx>
#endif
#ifndef _TL_POLY_HXX
#include <tools/poly.hxx> // Polygon
#endif
#ifndef _BGFX_MATRIX_B2DHOMMATRIX_HXX
#include <basegfx/matrix/b2dhommatrix.hxx>
#endif
#include <sfx2/viewfrm.hxx>
#include <sfx2/bindings.hxx>
#include <sfx2/dispatch.hxx>
#ifndef _SV_SALBTYPE_HXX
#include <vcl/salbtype.hxx> // FRound
#endif
#ifndef _VCLENUM_HXX
#include <vcl/vclenum.hxx>
#endif
#include <swrect.hxx>
#include <svx/sdrpaintwindow.hxx>
#include <svx/sdr/overlay/overlaymanager.hxx>
#include <svx/editstat.hxx> //EditEngine flags
#include <svx/outliner.hxx>
#include <svx/editeng.hxx>
#include <basegfx/matrix/b2dhommatrix.hxx>
#include <basegfx/tuple/b2dtuple.hxx>
#include <docufld.hxx> // SwPostItField
#include <edtwin.hxx>
#include <view.hxx>
#include <docsh.hxx>
#include <fmtfld.hxx>
#include <wrtsh.hxx>
#include <doc.hxx>
#include <vcl/edit.hxx>
#include <svtools/svmedit.hxx>
//TODO
#ifndef _TXTFLD_HXX //autogen
#include <txtfld.hxx>
#endif
#include <SwUndoField.hxx>
#ifndef _DOCFLD_HXX
#include "../../core/inc/docfld.hxx" // fuer Expression-Felder
#endif
#ifndef _EDITSH_HXX
#include <editsh.hxx>
#endif
//
#ifndef _BGFX_POLYGON_B2DPOLYGONTOOLS_HXX
#include <basegfx/polygon/b2dpolygontools.hxx>
#endif
#define ANKORLINE_WIDTH 1
#define METABUTTON_WIDTH 16
#define METABUTTON_HEIGHT 18
#define METABUTTON_AREA_WIDTH 30
#define POSTIT_META_HEIGHT (sal_Int32) 30
#define POSTIT_MINIMUMSIZE_WITHOUT_META 50
Color ColorFromAlphaColor(UINT8 aTransparency, Color &aFront, Color &aBack )
{
return Color((UINT8)(aFront.GetRed() * aTransparency/(double)255 + aBack.GetRed() * (1-aTransparency/(double)255)),
(UINT8)(aFront.GetGreen() * aTransparency/(double)255 + aBack.GetGreen() * (1-aTransparency/(double)255)),
(UINT8)(aFront.GetBlue() * aTransparency/(double)255 + aBack.GetBlue() * (1-aTransparency/(double)255)));
}
/************ PostItTxt **************************************/
PostItTxt::PostItTxt(Window* pParent, WinBits nBits) : Window(pParent, nBits), mpOutlinerView(0),mMouseOver(false),mbShowPopup(FALSE)
{
AddEventListener( LINK( this, PostItTxt, WindowEventListener ) );
mpPostIt = static_cast<SwPostIt*>(GetParent());
}
PostItTxt::~PostItTxt()
{
RemoveEventListener( LINK( this, PostItTxt, WindowEventListener ) );
}
void PostItTxt::GetFocus()
{
if(mpPostIt)
{
mpPostIt->Mgr()->SetActivePostIt(mpPostIt);
/*
// enable visible spell checking
ULONG nCntrl = mpPostIt->Engine()->GetControlWord();
const SwViewOption* pVOpt = mpPostIt->DocView()->GetWrtShell().GetViewOptions();
if( pVOpt->IsOnlineSpell() )
{
nCntrl |= EE_CNTRL_ONLINESPELLING|EE_CNTRL_ALLOWBIGOBJS;
nCntrl &= ~EE_CNTRL_NOREDLINES;
if( pVOpt->IsHideSpell() )
nCntrl |= EE_CNTRL_NOREDLINES;
}
else
{
nCntrl &= ~EE_CNTRL_ONLINESPELLING;
nCntrl |= EE_CNTRL_NOREDLINES;
}
mpPostIt->Engine()->SetControlWord(nCntrl);
*/
// update ankor as well as turn on visible selection
mpPostIt->View()->GetEditView().SetSelectionMode(EE_SELMODE_STD);
if (mpPostIt->Ankor())
mpPostIt->Ankor()->SetLineInfo(LineInfo(LINE_SOLID,ANKORLINE_WIDTH* 15));
mpPostIt->View()->ShowCursor();
if ( !Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
mpPostIt->View()->SetBackgroundColor(mColorDark);
// we need this, otherwise no layout after note is left
mpPostIt->Mgr()->SetLayout();
}
Window::GetFocus();
Invalidate();
}
void PostItTxt::LoseFocus()
{
if(mpPostIt)
{
// disable visible spell checking
/*
ULONG nCntrl = mpPostIt->Engine()->GetControlWord();
nCntrl |= EE_CNTRL_NOREDLINES;
nCntrl &= ~EE_CNTRL_ONLINESPELLING;
mpPostIt->Engine()->SetControlWord(nCntrl);
*/
mpPostIt->View()->GetEditView().SetSelectionMode(EE_SELMODE_HIDDEN);
if (mpPostIt->Ankor())
mpPostIt->Ankor()->SetLineInfo(LineInfo(LINE_DASH,ANKORLINE_WIDTH*15));
// write the visible text back into the SwField
mpPostIt->UpdateData();
if ( !Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
mpPostIt->View()->SetBackgroundColor(COL_TRANSPARENT);
}
Window::LoseFocus();
Invalidate();
}
void PostItTxt::Paint( const Rectangle& rRect)
{
if ( !Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
{
if (mMouseOver || HasFocus())
DrawGradient(Rectangle(Point(0,0),PixelToLogic(GetSizePixel())),Gradient(GRADIENT_LINEAR,mColorDark,mColorDark));
else
DrawGradient(Rectangle(Point(0,0),PixelToLogic(GetSizePixel())),Gradient(GRADIENT_LINEAR,mColorLight,mColorDark));
}
mpOutlinerView->Paint( rRect );
}
void PostItTxt::SetColor(Color &aColorDark,Color &aColorLight)
{
mColorDark = aColorDark;
mColorLight = aColorLight;
}
void PostItTxt::KeyInput( const KeyEvent& rKeyEvt )
{
//TODO: Alt - F4
const KeyCode& rKeyCode = rKeyEvt.GetKeyCode();
USHORT nKey = rKeyCode.GetCode();
if (nKey==KEY_CONTEXTMENU)
{
Size aSize = GetSizePixel();
Point aPos = Point( aSize.getWidth()/2, aSize.getHeight()/2 );
mpPostIt->DocView()->GetViewFrame()->GetDispatcher()->ExecutePopup( 0, this,&aPos);
}
else
if ( (nKey== KEY_N) && rKeyCode.IsMod1() && rKeyCode.IsMod2())
{
mpPostIt->SwitchToFieldPos();
}
else
//if ( (rKeyCode.GetFullCode() == (KEY_PAGEUP | KEY_MOD1 |KEY_SHIFT)) ||
if (((nKey == KEY_PAGEUP) && rKeyCode.IsMod1() && rKeyCode.IsMod2()) ||
((nKey == KEY_PAGEDOWN) && rKeyCode.IsMod1() && rKeyCode.IsMod2() ))
{
mpPostIt->SwitchToPostIt(nKey);
}
else
if ((nKey == KEY_ESCAPE))
{
if (mpPostIt->Engine()->GetEditEngine().GetText()==String(::rtl::OUString::createFromAscii("")))
mpPostIt->Delete(FN_DELETE_NOTE);
else
mpPostIt->SwitchToFieldPos();
}
else
{
// we need EnableOutput, otherwise text might jump up and down
// e.g ENTER->text jumps up, if we then resize based on the new hight, it jumps back down
//EnableOutput(FALSE);
//TODO: EnableOutput is slow as hell, we need sth like VirtualKeyInput
long aOldHeight = mpPostIt->GetPostItTextHeight();
bool bDone = false;
if ( !( (nKey == KEY_Z || nKey == KEY_Y) && rKeyCode.IsMod1() ) )
// HACK: need to switch off processing of Undo/Redo in Outliner
bDone = mpOutlinerView->PostKeyEvent( rKeyEvt );
if (bDone)
{
long aNewHeight = mpPostIt->GetPostItTextHeight();
//TODO: after resizing to one line, this should still continue to resize
if ( (aOldHeight != aNewHeight) && (aNewHeight > mpPostIt->GetMinimumSizeWithoutMeta()) )
{
//check for lower border or next note and resize if space left
long aBorder = mpPostIt->Mgr()->GetNextBorder();
if (aBorder == -1)
{
// we have notes scrollbar on this page, do not set new size
// TODO: seperate scrollbar pos stuff from real resizing
mpPostIt->DoResize();
}
else
{
if (mpPostIt->GetPosPixel().Y() + aNewHeight + mpPostIt->GetMetaHeight() < aBorder)
{
mpPostIt->SetSizePixel(Size(mpPostIt->GetSizePixel().Width(),aNewHeight+mpPostIt->GetMetaHeight()));
mpPostIt->DoResize();
mpPostIt->Invalidate();
}
else
{
mpPostIt->DoResize();
}
}
}
else
{
// TODO: seperate scrollbar pos stuff from real resizing
mpPostIt->DoResize();
}
}
else
mpPostIt->DocView()->KeyInput(rKeyEvt);
}
mpPostIt->DocView()->GetViewFrame()->GetBindings().InvalidateAll(FALSE);
}
void PostItTxt::MouseMove( const MouseEvent& rMEvt )
{
if ( mpOutlinerView )
mpOutlinerView->MouseMove( rMEvt );
// mba: why does OutlinerView not handle the modifier setting?!
// this forces the postit to handle *all* pointer types
if ( rMEvt.GetModifier() == KEY_MOD1 )
SetPointer( mpOutlinerView->GetPointer( rMEvt.GetPosPixel() ) );
else
SetPointer( Pointer( mpOutlinerView->GetOutliner()->IsVertical() ? POINTER_TEXT_VERTICAL : POINTER_TEXT ) );
}
void PostItTxt::MouseButtonDown( const MouseEvent& rMEvt )
{
if ( rMEvt.GetModifier() == KEY_MOD1 && mpOutlinerView )
{
const EditView& aEV = mpOutlinerView->GetEditView();
const SvxFieldItem* pItem = aEV.GetFieldUnderMousePointer();
if ( pItem )
{
const SvxFieldData* pFld = pItem->GetField();
const SvxURLField* pURL = PTR_CAST( SvxURLField, pFld );
if ( pURL )
{
mpOutlinerView->MouseButtonDown( rMEvt );
SwWrtShell &rSh = mpPostIt->DocView()->GetWrtShell();
String sURL( pURL->GetURL() );
String sTarget( pURL->GetTargetFrame() );
::LoadURL( sURL, &rSh, URLLOAD_NOFILTER, &sTarget);
return;
}
}
}
GrabFocus();
if ( mpOutlinerView )
mpOutlinerView->MouseButtonDown( rMEvt );
mpPostIt->DocView()->GetViewFrame()->GetBindings().InvalidateAll(FALSE);
}
void PostItTxt::MouseButtonUp( const MouseEvent& rMEvt )
{
if ( mpOutlinerView )
mpOutlinerView->MouseButtonUp( rMEvt );
}
void PostItTxt::Command( const CommandEvent& rCEvt )
{
if ( rCEvt.GetCommand() == COMMAND_CONTEXTMENU )
{
if (mpOutlinerView->IsWrongSpelledWordAtPos( rCEvt.GetMousePosPixel(),TRUE ))
mpOutlinerView->ExecuteSpellPopup(rCEvt.GetMousePosPixel());
else
mpPostIt->DocView()->GetViewFrame()->GetDispatcher()->ExecutePopup( 0, this,&rCEvt.GetMousePosPixel());
}
else
if (rCEvt.GetCommand() == COMMAND_WHEEL)
{
if (mpPostIt->Scrollbar()->IsVisible())
{
const CommandWheelData* pData = rCEvt.GetWheelData();
if (pData->IsShift() || pData->IsMod1() || pData->IsMod2())
{
mpPostIt->DocView()->HandleWheelCommands(rCEvt);
}
else
{
long nLines = pData->GetNotchDelta() * (long)pData->GetScrollLines();
if ( ((mpPostIt->Scrollbar()->GetRange().Min() == mpPostIt->Scrollbar()->GetThumbPos()) && (nLines > 0)) ||
( (mpPostIt->Scrollbar()->GetRange().Max() == mpPostIt->Scrollbar()->GetThumbPos()+mpPostIt->Scrollbar()->GetVisibleSize()) && (nLines < 0)) )
{
mpPostIt->DocView()->HandleWheelCommands(rCEvt);
}
else
{
HandleScrollCommand( rCEvt, 0 , mpPostIt->Scrollbar());
}
}
}
else
{
mpPostIt->DocView()->HandleWheelCommands(rCEvt);
}
}
else
{
if ( mpOutlinerView )
mpOutlinerView->Command( rCEvt );
else
Window::Command(rCEvt);
}
}
void PostItTxt::DataChanged( const DataChangedEvent& aData)
{
Window::DataChanged( aData );
}
IMPL_LINK( PostItTxt, WindowEventListener, VclSimpleEvent*, pWinEvent )
{
if ( pWinEvent && pWinEvent->ISA( VclWindowEvent ) )
{
VclWindowEvent *pEvent = (VclWindowEvent*)pWinEvent;
if (pEvent->GetId() == VCLEVENT_WINDOW_MOUSEMOVE)
{
MouseEvent* pMouseEvt = (MouseEvent*)pEvent->GetData();
if ( pMouseEvt->IsEnterWindow() )
{
mMouseOver = true;
if (mpPostIt->Ankor())
mpPostIt->Ankor()->SetLineInfo(LineInfo(LINE_SOLID,ANKORLINE_WIDTH*15));
Invalidate();
}
else if ( pMouseEvt->IsLeaveWindow())
{
mMouseOver = false;
if (!mbShowPopup && !HasFocus())
{
if (mpPostIt->Ankor())
mpPostIt->Ankor()->SetLineInfo(LineInfo(LINE_DASH,ANKORLINE_WIDTH*15));
Invalidate();
}
}
}
}
return sal_True;
}
/******* SwPostIt **************************************/
SwPostIt::SwPostIt( Window* pParent, WinBits nBits, SwFmtFld* aField,SwPostItMgr* aMgr,bool bMarginSide) : Window(pParent, nBits),
mpOutlinerView(0),
mpOutliner(0),
mpPostItTxt(0),
mpMeta(0),
mpVScrollbar(0),
mpFmtFld(aField),
mpFld( static_cast<SwPostItField*>(aField->GetFld())),
mpAnkor(0),
mpMgr(aMgr),
mbMeta(true),
mpButtonPopup(new PopupMenu(SW_RES(MN_ANNOTATION_BUTTON))),
mbMarginSide(bMarginSide)
{
SwEditWin* aWin = static_cast<SwEditWin*>(GetParent());
mpView = &aWin->GetView();
SdrPaintWindow* pPaintWindow = mpView->GetDrawView()->GetPaintWindow(0);
if(pPaintWindow)
{
pOverlayManager = pPaintWindow->GetOverlayManager();
}
InitControls();
SetPostItText();
}
void SwPostIt::SetPostItText()
{
// get text from SwPostItField and insert into our textview
mpOutliner->EnableUndo( FALSE );
mpFld = static_cast<SwPostItField*>(mpFmtFld->GetFld());
if( mpFld->GetTextObject() )
mpOutliner->SetText( *mpFld->GetTextObject() );
else
{
mpOutliner->Clear();
SfxItemSet item( mpView->GetDocShell()->GetPool() );
item.Put(SvxFontHeightItem(200,100,EE_CHAR_FONTHEIGHT));
mpOutlinerView->SetAttribs(item);
mpOutlinerView->InsertText(mpFld->GetPar2(),false);
}
mpOutliner->ClearModifyFlag();
mpOutliner->EnableUndo( TRUE );
Invalidate();
}
SwPostIt::~SwPostIt()
{
if (mpOutlinerView)
{
delete mpOutlinerView;
}
if (mpOutliner)
{
delete mpOutliner;
}
if (mpMeta)
{
mpMeta->RemoveEventListener( LINK( mpPostItTxt, PostItTxt, WindowEventListener ) );
delete mpMeta;
}
if (mpPostItTxt)
{
delete mpPostItTxt;
}
if (mpVScrollbar)
{
delete mpVScrollbar;
}
if (mpAnkor)
{
if (mpAnkor->getOverlayManager())
{
// remove this object from the chain
mpAnkor->getOverlayManager()->remove(*mpAnkor);
}
delete mpAnkor;
}
if (mpButtonPopup)
{
delete mpButtonPopup;
}
}
void SwPostIt::Paint( const Rectangle& rRect)
{
Window::Paint(rRect);
if (mpMeta->IsVisible() )
{
//draw left over space
if ( Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
SetFillColor(COL_BLACK);
else
SetFillColor(mColorDark);
SetLineColor();
DrawRect(PixelToLogic(Rectangle(Point(mpMeta->GetPosPixel().X()+mpMeta->GetSizePixel().Width(),mpMeta->GetPosPixel().Y()),Size(GetMetaButtonAreaWidth(),mpMeta->GetSizePixel().Height()))));
if ( Application::GetSettings().GetStyleSettings().GetHighContrastMode())
{
//draw rect around button
SetFillColor(COL_BLACK);
SetLineColor(COL_WHITE);
}
else
{
//draw button
Gradient aGradient(GRADIENT_LINEAR,ColorFromAlphaColor(15,mColorAnkor,mColorDark),ColorFromAlphaColor(80,mColorAnkor,mColorDark));
DrawGradient(mRectMetaButton,aGradient);
//draw rect around button
SetFillColor();
SetLineColor(ColorFromAlphaColor(90,mColorAnkor,mColorDark));
}
DrawRect(mRectMetaButton);
//draw arrow
if ( Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
SetFillColor(COL_WHITE);
else
SetFillColor(COL_BLACK);
SetLineColor();
DrawPolygon(Polygon(aPopupTriangle));
}
}
void SwPostIt::SetPosSizePixelRect(long nX, long nY,long nWidth, long nHeight,const SwRect &aRect, const long aPageBorder, USHORT nFlags)
{
Window::SetPosSizePixel(nX,nY,nWidth,nHeight,nFlags);
Point aLineStart;
Point aLineEnd;
long X = aRect.Left();
long Y = aRect.Bottom();
if (mbMarginSide)
{
aLineStart = EditWin()->PixelToLogic( Point(GetPosPixel().X()+GetSizePixel().Width(),GetPosPixel().Y()-1) );
aLineEnd = EditWin()->PixelToLogic( Point(GetPosPixel().X(),GetPosPixel().Y()-1) );
}
else
{
aLineStart = EditWin()->PixelToLogic( Point(GetPosPixel().X(),GetPosPixel().Y()-1) );
aLineEnd = EditWin()->PixelToLogic( Point(GetPosPixel().X()+GetSizePixel().Width(),GetPosPixel().Y()-1) );
}
if (mpAnkor)
{
mpAnkor->SetAllPosition(basegfx::B2DPoint( X , Y - 5* 15),
basegfx::B2DPoint( X-5*15 , Y+5*15),
basegfx::B2DPoint( X+5*15 , Y+5*15),
basegfx::B2DPoint( X, Y+2*15),
basegfx::B2DPoint( aPageBorder ,Y+2*15),
basegfx::B2DPoint( aLineStart.X(),aLineStart.Y()),
basegfx::B2DPoint( aLineEnd.X(),aLineEnd.Y()));
mpAnkor->SetHeight(aRect.Height());
}
else
{
mpAnkor = new SwPostItAnkor(basegfx::B2DPoint( X , Y-5*15),
basegfx::B2DPoint( X-5*15 , Y+5*15),
basegfx::B2DPoint( X +5*15 , Y+5*15),
basegfx::B2DPoint( X, Y+2*15),
basegfx::B2DPoint( aPageBorder ,Y+2*15),
basegfx::B2DPoint( aLineStart.X(),aLineStart.Y()),
basegfx::B2DPoint( aLineEnd.X(),aLineEnd.Y()) , mColorAnkor,LineInfo(LINE_DASH,ANKORLINE_WIDTH*15), false);
mpAnkor->SetHeight(aRect.Height());
mpAnkor->setVisible(false);
pOverlayManager->add(*mpAnkor);
}
mbMeta = true;
Resize();
}
void SwPostIt::SetSizePixel( const Size& rNewSize )
{
Window::SetSizePixel(rNewSize);
Resize();
}
void SwPostIt::InitControls()
{
// actual window which holds the user text
mpPostItTxt = new PostItTxt(this, 0);
mpPostItTxt->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( mpPostItTxt, PostItTxt, WindowEventListener ) );
/*
String sDateTime;
SvNumberFormatter* pNumFormatter = mpView->GetDocShell()->GetDoc()->GetNumberFormatter();
const ULONG nFormatDate = pNumFormatter->GetStandardFormat( NUMBERFORMAT_DATETIME , Application::GetSettings().GetLanguage());
const DateTime aDateTime( mpFld->GetDate(), mpFld->GetTime());
pNumFormatter->GetOutputString( aDateTime - DateTime( *pNumFormatter->GetNullDate()), nFormatDate, sDateTime, &pColor );
*/
String sMeta;
const LocaleDataWrapper& rLocalData = SvtSysLocale().GetLocaleData();
sMeta = mpFld->GetPar1();
if (mpFld->GetDate()==Date())
sMeta = sMeta + rtl::OUString::createFromAscii("\n") + String(SW_RES(STR_POSTIT_TODAY));
else
if (mpFld->GetDate()==Date(Date()-1))
sMeta = sMeta + rtl::OUString::createFromAscii("\n") + String(SW_RES(STR_POSTIT_YESTERDAY));
else
sMeta = sMeta + rtl::OUString::createFromAscii("\n") + rLocalData.getDate( mpFld->GetDate() );
sMeta = sMeta + rtl::OUString::createFromAscii(" ") + rLocalData.getTime( mpFld->GetTime(),false );
mpMeta->SetText(sMeta);
SwDocShell* aShell = mpView->GetDocShell();
mpOutliner = new Outliner(&aShell->GetPool(),OUTLINERMODE_TEXTOBJECT);
aShell->GetDoc()->SetCalcFieldValueHdl( mpOutliner );
// mpOutliner->EnableUndo( FALSE );
mpOutliner->SetUpdateMode( TRUE );
Rescale();
OutputDevice* pDev = aShell->GetDoc()->getReferenceDevice(TRUE);
if ( pDev )
{
mpOutliner->SetRefDevice( pDev );
}
mpOutlinerView = new OutlinerView ( mpOutliner, mpPostItTxt );
mpOutlinerView->SetBackgroundColor(COL_TRANSPARENT);
mpOutliner->InsertView(mpOutlinerView );
mpPostItTxt->SetTextView(mpOutlinerView);
SfxItemSet item(aShell->GetPool());
item.Put(SvxFontHeightItem(200,100,EE_CHAR_FONTHEIGHT));
mpOutlinerView->SetAttribs(item);
//create Scrollbars
mpVScrollbar = new ScrollBar(this, WB_3DLOOK |WB_VSCROLL|WB_DRAG);
mpVScrollbar->EnableRTL( false );
mpVScrollbar->SetScrollHdl(LINK(this, SwPostIt, ScrollHdl));
mpVScrollbar->EnableDrag();
mpVScrollbar->AddEventListener( LINK( mpPostItTxt, PostItTxt, WindowEventListener ) );
mpButtonPopup->SetMenuFlags(MENU_FLAG_ALWAYSSHOWDISABLEDENTRIES);
const SwViewOption* pVOpt = mpView->GetWrtShellPtr()->GetViewOptions();
ULONG nCntrl = mpOutliner->GetControlWord();
// TODO: crash when AUTOCOMPLETE enabled
nCntrl |= EE_CNTRL_AUTOCORRECT | EV_CNTRL_AUTOSCROLL | EE_CNTRL_URLSFXEXECUTE | EE_CNTRL_ONLINESPELLING;; // | EE_CNTRL_AUTOCOMPLETE;
if (!pVOpt->IsOnlineSpell())
nCntrl |= EE_CNTRL_NOREDLINES;
mpOutliner->SetControlWord(nCntrl);
mpOutlinerView->StartSpeller();
mpMeta->Show();
mpVScrollbar->Show();
mpPostItTxt->Show();
}
void SwPostIt::Rescale()
{
MapMode aMode = GetParent()->GetMapMode();
aMode.SetOrigin( Point() );
//aMode.SetScaleX( aMode.GetScaleX() * Fraction( 8, 10 ) );
//aMode.SetScaleY( aMode.GetScaleY() * Fraction( 8, 10 ) );
mpOutliner->SetRefMapMode( aMode );
SetMapMode( aMode );
mpPostItTxt->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 SwPostIt::MetaInfo(const bool bMeta )
{
mbMeta = bMeta;
Resize();
}
void SwPostIt::Resize()
{
long aTextHeight = LogicToPixel( mpOutliner->CalcTextSize()).Height();
unsigned long aWidth = GetSizePixel().Width();
long aHeight = GetSizePixel().Height();
if (mbMeta)
{
aHeight -= GetMetaHeight();
mpMeta->Show();
mpPostItTxt->SetQuickHelpText(rtl::OUString::createFromAscii(""));
}
else
{
mpMeta->Hide();
mpPostItTxt->SetQuickHelpText(mpMeta->GetText());
}
if (aTextHeight > aHeight)
{ // we need vertical scrollbars and have to reduce the width
aWidth -= GetScrollbarWidth();
mpVScrollbar->Show();
}
else
{
mpVScrollbar->Hide();
}
mpPostItTxt->SetPosSizePixel(0, 0, aWidth, aHeight);
mpMeta->SetPosSizePixel(0,aHeight,GetSizePixel().Width()-GetMetaButtonAreaWidth(),GetMetaHeight());
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( 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 );
mpVScrollbar->SetThumbPos( mpOutlinerView->GetVisArea().Top()+ mpOutlinerView->GetEditView().GetCursor()->GetOffsetY());
mpVScrollbar->SetRange( Range(0, mpOutliner->GetTextHeight()));
//calculate rects for meta- button
const Fraction& fx( GetMapMode().GetScaleX() );
const Fraction& fy( GetMapMode().GetScaleY() );
Point aPos( mpMeta->GetPosPixel());
Point aBase( aPos.X() + aPos.X() + GetSizePixel().Width(), aPos.Y() );
Point aLeft = PixelToLogic( Point( aBase.X() - (METABUTTON_WIDTH+5)*fx.GetNumerator()/fx.GetDenominator(), aBase.Y()+17*fy.GetNumerator()/fx.GetDenominator() ) );
Point aRight = PixelToLogic( Point( aBase.X() - (METABUTTON_WIDTH-1)*fx.GetNumerator()/fx.GetDenominator(), aBase.Y()+17*fy.GetNumerator()/fy.GetDenominator() ) );
Point aBottom = PixelToLogic( Point( aBase.X() - (METABUTTON_WIDTH+2)*fx.GetNumerator()/fx.GetDenominator(), aBase.Y()+20*fy.GetNumerator()/fy.GetDenominator() ) );
//Point aLeft = PixelToLogic(Point(mpMeta->GetPosPixel().X()+mpMeta->GetPosPixel().X()+GetSizePixel().Width()-(GetMetaButtonWidth()+10)+5,mpMeta->GetPosPixel().Y()+17));
//Point aRight = PixelToLogic(Point(mpMeta->GetPosPixel().X()+mpMeta->GetPosPixel().X()+GetSizePixel().Width()-(GetMetaButtonWidth()+10)+11,mpMeta->GetPosPixel().Y()+17));
//Point aBottom = PixelToLogic(Point(mpMeta->GetPosPixel().X()+mpMeta->GetPosPixel().X()+GetSizePixel().Width()-(GetMetaButtonWidth()+10)+8,mpMeta->GetPosPixel().Y()+20));
aPopupTriangle.clear();
aPopupTriangle.append(basegfx::B2DPoint(aLeft.X(),aLeft.Y()));
aPopupTriangle.append(basegfx::B2DPoint(aRight.X(),aRight.Y()));
aPopupTriangle.append(basegfx::B2DPoint(aBottom.X(),aBottom.Y()));
aPopupTriangle.setClosed(true);
mRectMetaButton = PixelToLogic( Rectangle( Point(
aPos.X()+GetSizePixel().Width()-(METABUTTON_WIDTH+10)*fx.GetNumerator()/fx.GetDenominator(),
aPos.Y()+5*fy.GetNumerator()/fy.GetDenominator() ),
Size( METABUTTON_WIDTH*fx.GetNumerator()/fx.GetDenominator(), METABUTTON_HEIGHT*fy.GetNumerator()/fy.GetDenominator() ) ) );
}
void SwPostIt::SetColor(Color &aColorDark,Color &aColorLight, Color &aColorAnkor)
{
mColorDark = aColorDark;
mColorLight = aColorLight;
mColorAnkor = aColorAnkor;
mpPostItTxt->SetColor(aColorDark,aColorLight);
if ( !Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
{
mpMeta->SetControlBackground(mColorDark);
AllSettings aSettings = mpMeta->GetSettings();
StyleSettings aStyleSettings = aSettings.GetStyleSettings();
aStyleSettings.SetFieldTextColor(aColorAnkor);
aSettings.SetStyleSettings(aStyleSettings);
mpMeta->SetSettings(aSettings);
}
}
void SwPostIt::SetReadonly(BOOL bSet)
{
mbReadonly = bSet;
View()->SetReadOnly(bSet);
}
void SwPostIt::DataChanged( const DataChangedEvent& aEvent)
{
Window::DataChanged( aEvent );
}
void SwPostIt::GetFocus()
{
if (mpPostItTxt)
mpPostItTxt->GrabFocus();
}
void SwPostIt::LoseFocus()
{
}
void SwPostIt::ShowNote()
{
if (!IsVisible())
Window::Show();
if (mpAnkor)
mpAnkor->setVisible(true);
}
void SwPostIt::HideNote()
{
if (IsVisible())
Window::Hide();
if (mpAnkor)
mpAnkor->setVisible(false);
}
void SwPostIt::UpdateData()
{
if ( mpOutliner->IsModified() )
{
SwPosition * pPos = mpFmtFld->GetTxtFld()->GetPosition();
SwField* pOldField = mpFld->Copy();
mpFld->SetPar2(mpOutliner->GetEditEngine().GetText());
mpFld->SetTextObject(mpOutliner->CreateParaObject());
mpView->GetDocShell()->GetDoc()->AppendUndo(new SwUndoFieldFromDoc(*pPos, *pOldField, *mpFld, 0, true));
delete pOldField;
delete pPos;
mpView->GetDocShell()->SetModified();
}
}
void SwPostIt::Delete(USHORT nSlot)
{
switch (nSlot)
{
case FN_DELETE_NOTE:
{
if ( Mgr()->GetActivePostIt() == this)
Mgr()->SetActivePostIt(0);
// we delete the field directly, the Mgr cleans up the PostIt by listening
mpView->GetWrtShellPtr()->GotoFld(*mpFmtFld);
mpView->GetWrtShellPtr()->DelRight();
break;
}
case FN_DELETE_NOTE_AUTHOR:
{
mpMgr->Delete(mpFld->GetPar1());
break;
}
case FN_DELETE_ALL_NOTES:
{
Mgr()->SetActivePostIt(0);
mpMgr->Delete();
break;
}
}
}
void SwPostIt::Hide(USHORT nSlot)
{
switch (nSlot)
{
case FN_HIDE_NOTE:
{
mpMgr->Hide(mpFld);
break;
}
case FN_HIDE_NOTE_AUTHOR:
{
mpMgr->Hide(mpFld,true);
break;
}
case FN_HIDE_ALL_NOTES:
{
mpMgr->Hide();
break;
}
}
// put the cursor back into the document
SwitchToFieldPos();
}
Color SwPostIt::ColorDark()
{
return mColorDark;
}
Color SwPostIt::ColorLight()
{
return mColorLight;
}
Color SwPostIt::ColorAnkor()
{
return mColorAnkor;
}
SwEditWin* SwPostIt::EditWin()
{
return &mpView->GetEditWin();
}
long SwPostIt::GetPostItTextHeight()
{
return mpOutliner ? LogicToPixel(mpOutliner->CalcTextSize()).Height() : 0;
}
void SwPostIt::TranslateTopPosition(const long aAmount)
{
SetPosPixel( Point(GetPosPixel().X() , GetPosPixel().Y() + aAmount) );
if (mpAnkor)
{
Point aLineStart;
Point aLineEnd ;
if (mbMarginSide)
{
aLineStart = EditWin()->PixelToLogic( Point(GetPosPixel().X()+GetSizePixel().Width(),GetPosPixel().Y()-2) );
aLineEnd = EditWin()->PixelToLogic( Point(GetPosPixel().X(),GetPosPixel().Y()-2) );
}
else
{
aLineStart = EditWin()->PixelToLogic( Point(GetPosPixel().X(),GetPosPixel().Y()-2) );
aLineEnd = EditWin()->PixelToLogic( Point(GetPosPixel().X()+GetSizePixel().Width(),GetPosPixel().Y()-2) );
}
mpAnkor->SetSixthPosition(basegfx::B2DPoint(aLineStart.X(),aLineStart.Y()));
mpAnkor->SetSeventhPosition(basegfx::B2DPoint(aLineEnd.X(),aLineEnd.Y()));
}
}
void SwPostIt::ShowAnkorOnly(const Point &aPoint)
{
if (mpAnkor)
{
mpAnkor->SetSixthPosition(basegfx::B2DPoint(aPoint.X(),aPoint.Y()));
mpAnkor->SetSeventhPosition(basegfx::B2DPoint(aPoint.X(),aPoint.Y()));
mpAnkor->setVisible(true);
}
}
void SwPostIt::SwitchToPostIt(USHORT aDirection)
{
if (mpMgr)
{
SwPostIt* aPostIt = mpMgr->GetNextPostIt(aDirection, this);
if (aPostIt)
{
// the note we switch to should be viisble and receive the focus
/*
This would be a lot cleaner and not so hacky, but there are several issues with this,
seems like AutoScroll has to be adapted heavily
aPostIt->GrabFocus();
Rectangle aNoteRect (aPostIt->GetPosPixel(),aPostIt->GetSizePixel());
mpView->GetWrtShellPtr()->MakeVisible(SwRect(EditWin()->PixelToLogic(aNoteRect)));
mpMgr->AutoScroll(aPostIt);
*/
// hacky but easy: we do a new layout, and the note is automatically visible and has focus
aPostIt->SwitchToFieldPos(false);
mpView->GetViewFrame()->GetDispatcher()->Execute(FN_POSTIT, SFX_CALLMODE_ASYNCHRON);
}
}
}
void SwPostIt::MouseButtonDown( const MouseEvent& rMEvt )
{
if (mRectMetaButton.IsInside(PixelToLogic(rMEvt.GetPosPixel())) && rMEvt.IsLeft())
{
if (mbReadonly)
{
mpButtonPopup->EnableItem(FN_DELETE_NOTE,false);
mpButtonPopup->EnableItem(FN_DELETE_NOTE_AUTHOR,false);
mpButtonPopup->EnableItem(FN_DELETE_ALL_NOTES,false);
}
else
{
mpButtonPopup->EnableItem(FN_DELETE_NOTE,true);
mpButtonPopup->EnableItem(FN_DELETE_NOTE_AUTHOR,true);
mpButtonPopup->EnableItem(FN_DELETE_ALL_NOTES,true);
}
ExecuteCommand(mpButtonPopup->Execute( this,Rectangle(LogicToPixel(mRectMetaButton.BottomLeft()),LogicToPixel(mRectMetaButton.BottomLeft())),POPUPMENU_EXECUTE_DOWN | POPUPMENU_NOMOUSEUPCLOSE));
}
}
void SwPostIt::ExecuteCommand(USHORT aSlot)
{
switch (aSlot)
{
case FN_DELETE_NOTE:
case FN_DELETE_NOTE_AUTHOR:
case FN_DELETE_ALL_NOTES:
{
Delete(aSlot);
break;
}
case FN_HIDE_NOTE:
case FN_HIDE_NOTE_AUTHOR:
case FN_HIDE_ALL_NOTES:
{
Hide(aSlot);
break;
}
}
}
void SwPostIt::SwitchToFieldPos(bool bAfter)
{
mpView->GetDocShell()->GetWrtShell()->GotoFld(*mpMgr->GetFmtFld(this));
if (bAfter)
mpView->GetDocShell()->GetWrtShell()->SwCrsrShell::Right(1, 0, FALSE);
mpMgr->SetActivePostIt(0);
GrabFocusToDocument();
}
IMPL_LINK(SwPostIt, ScrollHdl, ScrollBar*, pScroll)
{
long nDiff = View()->GetEditView().GetVisArea().Top() - pScroll->GetThumbPos();
View()->Scroll( 0, nDiff );
return 0;
}
void SwPostIt::ResetAttributes()
{
mpOutlinerView->RemoveAttribs(TRUE);
mpOutliner->RemoveFields(TRUE);
SfxItemSet aSet( mpView->GetDocShell()->GetPool() );
aSet.Put(SvxFontHeightItem(200,100,EE_CHAR_FONTHEIGHT));
mpOutlinerView->SetAttribs(aSet);
}
sal_Int32 SwPostIt::GetScrollbarWidth()
{
return mpView->GetWrtShell().GetViewOptions()->GetZoom() / 10;
}
sal_Int32 SwPostIt::GetMetaButtonAreaWidth()
{
const Fraction& f( GetMapMode().GetScaleX() );
return METABUTTON_AREA_WIDTH * f.GetNumerator() / f.GetDenominator();
}
sal_Int32 SwPostIt::GetMetaHeight()
{
const Fraction& f( GetMapMode().GetScaleY() );
return POSTIT_META_HEIGHT * f.GetNumerator() / f.GetDenominator();
}
sal_Int32 SwPostIt::GetMinimumSizeWithMeta()
{
return mpMgr->GetMinimumSizeWithMeta();
}
sal_Int32 SwPostIt::GetMinimumSizeWithoutMeta()
{
const Fraction& f( GetMapMode().GetScaleY() );
return POSTIT_MINIMUMSIZE_WITHOUT_META * f.GetNumerator() / f.GetDenominator();
}
void SwPostIt::SetSpellChecking(bool bEnable)
{
ULONG nCntrl = mpOutliner->GetControlWord();
if (bEnable)
nCntrl &= ~EE_CNTRL_NOREDLINES;
else
nCntrl |= EE_CNTRL_NOREDLINES;
mpOutliner->SetControlWord(nCntrl);
}
/****** SwPostItAnkor ***********************************************************/
void SwPostItAnkor::implEnsureGeometry()
{
if(!maTriangle.count())
{
maTriangle.append(getBasePosition());
maTriangle.append(GetSecondPosition());
maTriangle.append(GetThirdPosition());
maTriangle.setClosed(true);
}
if(!maLine.count())
{
maLine.append(GetFourthPosition());
maLine.append(GetFifthPosition());
maLine.append(GetSixthPosition());
}
if(!maLineTop.count())
{
maLineTop.append(GetSixthPosition());
maLineTop.append(GetSeventhPosition());
}
}
void SwPostItAnkor::implResetGeometry()
{
maTriangle.clear();
maLine.clear();
maLineTop.clear();
}
void SwPostItAnkor::implDrawGeometry(OutputDevice& rOutputDevice, Color aColor, double fOffX, double fOffY)
{
basegfx::B2DPolygon aTri(maTriangle);
basegfx::B2DPolygon aLin(maLine);
const Polygon aLinTop(maLineTop);
if(0.0 != fOffX || 0.0 != fOffY)
{
// transform polygons
basegfx::B2DHomMatrix aTranslate;
aTranslate.set(0, 2, fOffX);
aTranslate.set(1, 2, fOffY);
aTri.transform(aTranslate);
aLin.transform(aTranslate);
}
// draw triangle
rOutputDevice.SetLineColor();
rOutputDevice.SetFillColor(aColor);
rOutputDevice.DrawPolygon(Polygon(aTri));
/*
basegfx::B2DHomMatrix aMatrix;
aMatrix.translate(-aTri.getB2DPoint(0).getX(),-aTri.getB2DPoint(0).getY());
aMatrix.scale(1.0, -1.0);
aMatrix.translate(aTri.getB2DPoint(0).getX(),aTri.getB2DPoint(0).getY());
aMatrix.translate(0,(mHeight*-1) + 13 * 15 );
aTri.transform(aMatrix);
rOutputDevice.DrawPolygon(Polygon(aTri));
*/
// draw line
rOutputDevice.SetLineColor(aColor);
rOutputDevice.SetFillColor();
rOutputDevice.DrawPolyLine(Polygon(aLin), mLineInfo);
rOutputDevice.DrawPolyLine(aLinTop,LineInfo(LINE_SOLID,ANKORLINE_WIDTH*15));
}
Color SwPostItAnkor::implBlendColor(const Color aOriginal, sal_Int16 nChange)
{
if(0 != nChange)
{
sal_Int16 nR(aOriginal.GetRed() + nChange);
sal_Int16 nG(aOriginal.GetGreen() + nChange);
sal_Int16 nB(aOriginal.GetBlue() + nChange);
// truncate R, G and B
if(nR > 0xff)
nR = 0xff;
else if(nR < 0)
nR = 0;
if(nG > 0xff)
nG = 0xff;
else if(nG < 0)
nG = 0;
if(nB > 0xff)
nB = 0xff;
else if(nB < 0)
nB = 0;
return Color((sal_uInt8)nR, (sal_uInt8)nG, (sal_uInt8)nB);
}
else
{
return aOriginal;
}
}
SwPostItAnkor::SwPostItAnkor(const basegfx::B2DPoint& rBasePos,
const basegfx::B2DPoint& rSecondPos,
const basegfx::B2DPoint& rThirdPos,
const basegfx::B2DPoint& rFourthPos,
const basegfx::B2DPoint& rFifthPos,
const basegfx::B2DPoint& rSixthPos,
const basegfx::B2DPoint& rSeventhPos,
Color aBaseColor,
const LineInfo &aLineInfo,
bool bShadowedEffect)
: OverlayObjectWithBasePosition(rBasePos, aBaseColor),
maSecondPosition(rSecondPos),
maThirdPosition(rThirdPos),
maFourthPosition(rFourthPos),
maFifthPosition(rFifthPos),
maSixthPosition(rSixthPos),
maSeventhPosition(rSeventhPos),
maTriangle(),
maLine(),
maLineTop(),
mLineInfo(aLineInfo),
mHeight(0),
mbShadowedEffect(bShadowedEffect)
{
if (mLineInfo.GetStyle()==LINE_DASH)
{
mLineInfo.SetDistance( 3 * 15);
mLineInfo.SetDashLen( 5 * 15);
mLineInfo.SetDashCount(100);
}
mbAllowsAnimation = sal_True;
}
SwPostItAnkor::~SwPostItAnkor()
{
}
void SwPostItAnkor::drawGeometry(OutputDevice& rOutputDevice)
{
implEnsureGeometry();
if(getShadowedEffect())
{
// calculate one pixel offset
const basegfx::B2DVector aOnePixelOffset(rOutputDevice.GetInverseViewTransformation() * basegfx::B2DVector(1.0, 1.0));
const Color aLighterColor(implBlendColor(getBaseColor(), 20));
const Color aDarkerColor(implBlendColor(getBaseColor(), -20));
// draw top-left
implDrawGeometry(rOutputDevice, aLighterColor, -aOnePixelOffset.getX(), -aOnePixelOffset.getY());
// draw bottom-right
implDrawGeometry(rOutputDevice, aDarkerColor, aOnePixelOffset.getX(), aOnePixelOffset.getY());
}
// draw original
implDrawGeometry(rOutputDevice, getBaseColor(), 0.0, 0.0);
}
void SwPostItAnkor::createBaseRange(OutputDevice& rOutputDevice)
{
// get range from geometry
implEnsureGeometry();
maBaseRange = basegfx::tools::getRange(maTriangle);
maBaseRange.expand(basegfx::tools::getRange(maLine));
maBaseRange.expand(basegfx::tools::getRange(maLineTop));
/*
basegfx::B2DHomMatrix aMatrix;
aMatrix.translate(-maTriangle.getB2DPoint(0).getX(),-maTriangle.getB2DPoint(0).getY());
aMatrix.scale(1.0,-1.0);
aMatrix.translate(maTriangle.getB2DPoint(0).getX(),maTriangle.getB2DPoint(0).getY());
aMatrix.translate(0,(mHeight*-1) + 13 * 15 );
basegfx::B2DRange MyRange(basegfx::tools::getRange(maTriangle));
MyRange.transform(aMatrix);
maBaseRange.expand(MyRange);
*/
// expand range for thick lines and shadowed geometry
double fExpand(0.0);
// take fat line into account
if(0 != mLineInfo.GetWidth())
{
// expand range for logic half line width
fExpand += static_cast< double >(mLineInfo.GetWidth()) / 2.0;
}
// take shadowed into account
if(getShadowedEffect())
{
const basegfx::B2DVector aOnePixelOffset(rOutputDevice.GetInverseViewTransformation() * basegfx::B2DVector(1.0, 1.0));
fExpand += ::std::max(aOnePixelOffset.getX(), aOnePixelOffset.getY());
}
if(0.0 != fExpand)
{
maBaseRange.grow(fExpand);
}
}
void SwPostItAnkor::SetAllPosition(const basegfx::B2DPoint& rPoint1,
const basegfx::B2DPoint& rPoint2,
const basegfx::B2DPoint& rPoint3,
const basegfx::B2DPoint& rPoint4,
const basegfx::B2DPoint& rPoint5,
const basegfx::B2DPoint& rPoint6,
const basegfx::B2DPoint& rPoint7)
{
maBasePosition = rPoint1;
maSecondPosition = rPoint2;
maThirdPosition = rPoint3;
maFourthPosition = rPoint4;
maFifthPosition = rPoint5;
maSixthPosition = rPoint6;
maSeventhPosition = rPoint7;
implResetGeometry();
objectChange();
}
void SwPostItAnkor::SetSecondPosition(const basegfx::B2DPoint& rNew)
{
if(rNew != maSecondPosition)
{
maSecondPosition = rNew;
implResetGeometry();
objectChange();
}
}
void SwPostItAnkor::SetThirdPosition(const basegfx::B2DPoint& rNew)
{
if(rNew != maThirdPosition)
{
maThirdPosition = rNew;
implResetGeometry();
objectChange();
}
}
void SwPostItAnkor::SetFourthPosition(const basegfx::B2DPoint& rNew)
{
if(rNew != maFourthPosition)
{
maFourthPosition = rNew;
implResetGeometry();
objectChange();
}
}
void SwPostItAnkor::SetFifthPosition(const basegfx::B2DPoint& rNew)
{
if(rNew != maFifthPosition)
{
maFifthPosition = rNew;
implResetGeometry();
objectChange();
}
}
void SwPostItAnkor::SetSixthPosition(const basegfx::B2DPoint& rNew)
{
if(rNew != maSixthPosition)
{
maSixthPosition = rNew;
implResetGeometry();
objectChange();
}
}
void SwPostItAnkor::SetSeventhPosition(const basegfx::B2DPoint& rNew)
{
if(rNew != maSeventhPosition)
{
maSeventhPosition = rNew;
implResetGeometry();
objectChange();
}
}
void SwPostItAnkor::transform(const basegfx::B2DHomMatrix& rMatrix)
{
if(!rMatrix.isIdentity())
{
// transform base position
OverlayObjectWithBasePosition::transform(rMatrix);
maSecondPosition = rMatrix * GetSecondPosition();
maThirdPosition = rMatrix * GetThirdPosition();
maFourthPosition = rMatrix * GetFourthPosition();
maFifthPosition = rMatrix * GetFifthPosition();
maSixthPosition = rMatrix * GetSixthPosition();
maSeventhPosition = rMatrix * GetSeventhPosition();
implResetGeometry();
objectChange();
}
}
void SwPostItAnkor::SetLineInfo(const LineInfo &aLineInfo)
{
if (aLineInfo != mLineInfo)
{
mLineInfo = aLineInfo;
if (mLineInfo.GetStyle()==LINE_DASH)
{
mLineInfo.SetDistance( 3 * 15);
mLineInfo.SetDashLen( 5 * 15);
mLineInfo.SetDashCount(100);
}
//remove and add overlayobject, so it is the last one inside the manager to draw
//therefore this line is on top
sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager();
pOverlayManager->remove(*this);
pOverlayManager->add(*this);
objectChange();
}
}
void SwPostItAnkor::SetColorLineInfo(Color aBaseColor,const LineInfo& aLineInfo)
{
if ( (maBaseColor != aBaseColor) || (mLineInfo != aLineInfo) )
{
maBaseColor = aBaseColor;
mLineInfo = aLineInfo;
if (mLineInfo.GetStyle()==LINE_DASH)
{
mLineInfo.SetDistance( 3 *15);
mLineInfo.SetDashLen( 5 * 15);
mLineInfo.SetDashCount(100);
}
objectChange();
}
}
void SwPostItAnkor::setShadowedEffect(bool bNew)
{
if(bNew != getShadowedEffect())
{
mbShadowedEffect = bNew;
objectChange();
}
}