xref: /aoo41x/main/sw/source/ui/docvw/AnnotationWin.cxx (revision cdf0e10c)
1*cdf0e10cSrcweir /************************************************************************* *
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2008 by Sun Microsystems, Inc.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * $RCSfile:  $
10*cdf0e10cSrcweir  * $Revision:  $
11*cdf0e10cSrcweir  *
12*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
13*cdf0e10cSrcweir  *
14*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
15*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
16*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
17*cdf0e10cSrcweir  *
18*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
19*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
22*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
23*cdf0e10cSrcweir  *
24*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
25*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
26*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
27*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
28*cdf0e10cSrcweir  *
29*cdf0e10cSrcweir  ************************************************************************/
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include "precompiled_sw.hxx"
32*cdf0e10cSrcweir 
33*cdf0e10cSrcweir #include <AnnotationWin.hxx>
34*cdf0e10cSrcweir 
35*cdf0e10cSrcweir #include <AnnotationMenuButton.hxx>
36*cdf0e10cSrcweir #include <PostItMgr.hxx>
37*cdf0e10cSrcweir 
38*cdf0e10cSrcweir #include <annotation.hrc>
39*cdf0e10cSrcweir #include <popup.hrc>
40*cdf0e10cSrcweir #include <cmdid.h>
41*cdf0e10cSrcweir 
42*cdf0e10cSrcweir #include <vcl/menu.hxx>
43*cdf0e10cSrcweir 
44*cdf0e10cSrcweir #include <svl/undo.hxx>
45*cdf0e10cSrcweir #include <unotools/syslocale.hxx>
46*cdf0e10cSrcweir #include <svl/languageoptions.hxx>
47*cdf0e10cSrcweir 
48*cdf0e10cSrcweir #include <editeng/postitem.hxx>
49*cdf0e10cSrcweir #include <editeng/fhgtitem.hxx>
50*cdf0e10cSrcweir #include <editeng/langitem.hxx>
51*cdf0e10cSrcweir 
52*cdf0e10cSrcweir #include <editeng/editview.hxx>
53*cdf0e10cSrcweir #include <editeng/outliner.hxx>
54*cdf0e10cSrcweir #include <editeng/editeng.hxx>
55*cdf0e10cSrcweir #include <editeng/editobj.hxx>
56*cdf0e10cSrcweir 
57*cdf0e10cSrcweir #include <docufld.hxx> // SwPostItField
58*cdf0e10cSrcweir #include <txtfld.hxx>
59*cdf0e10cSrcweir #include <ndtxt.hxx>
60*cdf0e10cSrcweir #include <view.hxx>
61*cdf0e10cSrcweir #include <wrtsh.hxx>
62*cdf0e10cSrcweir #include <docsh.hxx>
63*cdf0e10cSrcweir #include <doc.hxx>
64*cdf0e10cSrcweir #include <IDocumentUndoRedo.hxx>
65*cdf0e10cSrcweir #include <SwUndoField.hxx>
66*cdf0e10cSrcweir 
67*cdf0e10cSrcweir 
68*cdf0e10cSrcweir namespace sw { namespace annotation {
69*cdf0e10cSrcweir 
70*cdf0e10cSrcweir SwAnnotationWin::SwAnnotationWin( SwEditWin& rEditWin,
71*cdf0e10cSrcweir                                   WinBits nBits,
72*cdf0e10cSrcweir                                   SwPostItMgr& aMgr,
73*cdf0e10cSrcweir                                   SwPostItBits aBits,
74*cdf0e10cSrcweir                                   SwSidebarItem& rSidebarItem,
75*cdf0e10cSrcweir                                   SwFmtFld* aField )
76*cdf0e10cSrcweir     : SwSidebarWin( rEditWin, nBits, aMgr, aBits, rSidebarItem )
77*cdf0e10cSrcweir     , mpFmtFld(aField)
78*cdf0e10cSrcweir     , mpFld( static_cast<SwPostItField*>(aField->GetFld()))
79*cdf0e10cSrcweir     , mpButtonPopup(0)
80*cdf0e10cSrcweir {
81*cdf0e10cSrcweir }
82*cdf0e10cSrcweir 
83*cdf0e10cSrcweir SwAnnotationWin::~SwAnnotationWin()
84*cdf0e10cSrcweir {
85*cdf0e10cSrcweir     delete mpButtonPopup;
86*cdf0e10cSrcweir }
87*cdf0e10cSrcweir 
88*cdf0e10cSrcweir void SwAnnotationWin::SetPostItText()
89*cdf0e10cSrcweir {
90*cdf0e10cSrcweir     // get text from SwPostItField and insert into our textview
91*cdf0e10cSrcweir     Engine()->SetModifyHdl( Link() );
92*cdf0e10cSrcweir     Engine()->EnableUndo( sal_False );
93*cdf0e10cSrcweir     mpFld = static_cast<SwPostItField*>(mpFmtFld->GetFld());
94*cdf0e10cSrcweir     if( mpFld->GetTextObject() )
95*cdf0e10cSrcweir         Engine()->SetText( *mpFld->GetTextObject() );
96*cdf0e10cSrcweir     else
97*cdf0e10cSrcweir     {
98*cdf0e10cSrcweir         Engine()->Clear();
99*cdf0e10cSrcweir         GetOutlinerView()->SetAttribs(DefaultItem());
100*cdf0e10cSrcweir         GetOutlinerView()->InsertText(mpFld->GetPar2(),false);
101*cdf0e10cSrcweir     }
102*cdf0e10cSrcweir 
103*cdf0e10cSrcweir     Engine()->ClearModifyFlag();
104*cdf0e10cSrcweir     Engine()->GetUndoManager().Clear();
105*cdf0e10cSrcweir     Engine()->EnableUndo( sal_True );
106*cdf0e10cSrcweir     Engine()->SetModifyHdl( LINK( this, SwAnnotationWin, ModifyHdl ) );
107*cdf0e10cSrcweir     Invalidate();
108*cdf0e10cSrcweir }
109*cdf0e10cSrcweir 
110*cdf0e10cSrcweir void SwAnnotationWin::UpdateData()
111*cdf0e10cSrcweir {
112*cdf0e10cSrcweir     if ( Engine()->IsModified() )
113*cdf0e10cSrcweir     {
114*cdf0e10cSrcweir         IDocumentUndoRedo & rUndoRedo(
115*cdf0e10cSrcweir             DocView().GetDocShell()->GetDoc()->GetIDocumentUndoRedo());
116*cdf0e10cSrcweir         ::std::auto_ptr<SwField> pOldField;
117*cdf0e10cSrcweir         if (rUndoRedo.DoesUndo())
118*cdf0e10cSrcweir         {
119*cdf0e10cSrcweir             pOldField.reset(mpFld->Copy());
120*cdf0e10cSrcweir         }
121*cdf0e10cSrcweir         mpFld->SetPar2(Engine()->GetEditEngine().GetText());
122*cdf0e10cSrcweir         mpFld->SetTextObject(Engine()->CreateParaObject());
123*cdf0e10cSrcweir         if (rUndoRedo.DoesUndo())
124*cdf0e10cSrcweir         {
125*cdf0e10cSrcweir             SwTxtFld *const pTxtFld = mpFmtFld->GetTxtFld();
126*cdf0e10cSrcweir             SwPosition aPosition( pTxtFld->GetTxtNode() );
127*cdf0e10cSrcweir             aPosition.nContent = *pTxtFld->GetStart();
128*cdf0e10cSrcweir             rUndoRedo.AppendUndo(
129*cdf0e10cSrcweir                 new SwUndoFieldFromDoc(aPosition, *pOldField, *mpFld, 0, true));
130*cdf0e10cSrcweir         }
131*cdf0e10cSrcweir         // so we get a new layout of notes (anchor position is still the same and we would otherwise not get one)
132*cdf0e10cSrcweir         Mgr().SetLayout();
133*cdf0e10cSrcweir         // #i98686# if we have several views, all notes should update their text
134*cdf0e10cSrcweir         mpFmtFld->Broadcast(SwFmtFldHint( 0, SWFMTFLD_CHANGED));
135*cdf0e10cSrcweir         DocView().GetDocShell()->SetModified();
136*cdf0e10cSrcweir     }
137*cdf0e10cSrcweir     Engine()->ClearModifyFlag();
138*cdf0e10cSrcweir     Engine()->GetUndoManager().Clear();
139*cdf0e10cSrcweir }
140*cdf0e10cSrcweir 
141*cdf0e10cSrcweir void SwAnnotationWin::Delete()
142*cdf0e10cSrcweir {
143*cdf0e10cSrcweir     SwSidebarWin::Delete();
144*cdf0e10cSrcweir     // we delete the field directly, the Mgr cleans up the PostIt by listening
145*cdf0e10cSrcweir     DocView().GetWrtShellPtr()->GotoField(*mpFmtFld);
146*cdf0e10cSrcweir     GrabFocusToDocument();
147*cdf0e10cSrcweir     DocView().GetWrtShellPtr()->DelRight();
148*cdf0e10cSrcweir }
149*cdf0e10cSrcweir 
150*cdf0e10cSrcweir void SwAnnotationWin::GotoPos()
151*cdf0e10cSrcweir {
152*cdf0e10cSrcweir     DocView().GetDocShell()->GetWrtShell()->GotoField(*mpFmtFld);
153*cdf0e10cSrcweir }
154*cdf0e10cSrcweir 
155*cdf0e10cSrcweir sal_uInt32 SwAnnotationWin::MoveCaret()
156*cdf0e10cSrcweir {
157*cdf0e10cSrcweir     // if this is an answer, do not skip over all following ones, but insert directly behind the current one
158*cdf0e10cSrcweir     // but when just leaving a note, skip all following ones as well to continue typing
159*cdf0e10cSrcweir     return Mgr().IsAnswer()
160*cdf0e10cSrcweir            ? 1
161*cdf0e10cSrcweir            : 1 + CountFollowing();
162*cdf0e10cSrcweir }
163*cdf0e10cSrcweir 
164*cdf0e10cSrcweir //returns true, if there is another note right before this note
165*cdf0e10cSrcweir bool SwAnnotationWin::CalcFollow()
166*cdf0e10cSrcweir {
167*cdf0e10cSrcweir     SwTxtFld* pTxtFld = mpFmtFld->GetTxtFld();
168*cdf0e10cSrcweir     SwPosition aPosition( pTxtFld->GetTxtNode() );
169*cdf0e10cSrcweir     aPosition.nContent = *pTxtFld->GetStart();
170*cdf0e10cSrcweir     SwTxtAttr * const pTxtAttr = pTxtFld->GetTxtNode().GetTxtAttrForCharAt(
171*cdf0e10cSrcweir                     aPosition.nContent.GetIndex() - 1, RES_TXTATR_FIELD );
172*cdf0e10cSrcweir     const SwField* pFld = pTxtAttr ? pTxtAttr->GetFld().GetFld() : 0;
173*cdf0e10cSrcweir     return pFld && (pFld->Which()== RES_POSTITFLD);
174*cdf0e10cSrcweir }
175*cdf0e10cSrcweir 
176*cdf0e10cSrcweir // counts how many SwPostItField we have right after the current one
177*cdf0e10cSrcweir sal_uInt32 SwAnnotationWin::CountFollowing()
178*cdf0e10cSrcweir {
179*cdf0e10cSrcweir     sal_uInt32 aCount = 1;  // we start with 1, so we have to subtract one at the end again
180*cdf0e10cSrcweir     SwTxtFld* pTxtFld = mpFmtFld->GetTxtFld();
181*cdf0e10cSrcweir     SwPosition aPosition( pTxtFld->GetTxtNode() );
182*cdf0e10cSrcweir     aPosition.nContent = *pTxtFld->GetStart();
183*cdf0e10cSrcweir 
184*cdf0e10cSrcweir     SwTxtAttr * pTxtAttr = pTxtFld->GetTxtNode().GetTxtAttrForCharAt(
185*cdf0e10cSrcweir                                         aPosition.nContent.GetIndex() + 1,
186*cdf0e10cSrcweir                                         RES_TXTATR_FIELD );
187*cdf0e10cSrcweir     SwField* pFld = pTxtAttr
188*cdf0e10cSrcweir                     ? const_cast<SwField*>(pTxtAttr->GetFld().GetFld())
189*cdf0e10cSrcweir                     : 0;
190*cdf0e10cSrcweir     while ( pFld && ( pFld->Which()== RES_POSTITFLD ) )
191*cdf0e10cSrcweir     {
192*cdf0e10cSrcweir         aCount++;
193*cdf0e10cSrcweir         pTxtAttr = pTxtFld->GetTxtNode().GetTxtAttrForCharAt(
194*cdf0e10cSrcweir                                         aPosition.nContent.GetIndex() + aCount,
195*cdf0e10cSrcweir                                         RES_TXTATR_FIELD );
196*cdf0e10cSrcweir         pFld = pTxtAttr
197*cdf0e10cSrcweir                ? const_cast<SwField*>(pTxtAttr->GetFld().GetFld())
198*cdf0e10cSrcweir                : 0;
199*cdf0e10cSrcweir     }
200*cdf0e10cSrcweir     return aCount - 1;
201*cdf0e10cSrcweir }
202*cdf0e10cSrcweir 
203*cdf0e10cSrcweir MenuButton* SwAnnotationWin::CreateMenuButton()
204*cdf0e10cSrcweir {
205*cdf0e10cSrcweir     mpButtonPopup = new PopupMenu(SW_RES(MN_ANNOTATION_BUTTON));
206*cdf0e10cSrcweir     XubString aText = mpButtonPopup->GetItemText( FN_DELETE_NOTE_AUTHOR );
207*cdf0e10cSrcweir     SwRewriter aRewriter;
208*cdf0e10cSrcweir     aRewriter.AddRule(UNDO_ARG1,GetAuthor());
209*cdf0e10cSrcweir     aText = aRewriter.Apply(aText);
210*cdf0e10cSrcweir     mpButtonPopup->SetItemText(FN_DELETE_NOTE_AUTHOR,aText);
211*cdf0e10cSrcweir     MenuButton* pMenuButton = new AnnotationMenuButton( *this );
212*cdf0e10cSrcweir     pMenuButton->SetPopupMenu( mpButtonPopup );
213*cdf0e10cSrcweir     pMenuButton->Show();
214*cdf0e10cSrcweir     return pMenuButton;
215*cdf0e10cSrcweir }
216*cdf0e10cSrcweir 
217*cdf0e10cSrcweir void SwAnnotationWin::InitAnswer(OutlinerParaObject* pText)
218*cdf0e10cSrcweir {
219*cdf0e10cSrcweir     //collect our old meta data
220*cdf0e10cSrcweir     SwSidebarWin* pWin = Mgr().GetNextPostIt(KEY_PAGEUP, this);
221*cdf0e10cSrcweir     const SvtSysLocale aSysLocale;
222*cdf0e10cSrcweir     const LocaleDataWrapper& rLocalData = aSysLocale.GetLocaleData();
223*cdf0e10cSrcweir     String aText = String(SW_RES(STR_REPLY));
224*cdf0e10cSrcweir         SwRewriter aRewriter;
225*cdf0e10cSrcweir         aRewriter.AddRule(UNDO_ARG1, pWin->GetAuthor());
226*cdf0e10cSrcweir         aText = aRewriter.Apply(aText);
227*cdf0e10cSrcweir         aText.Append(String(rtl::OUString::createFromAscii(" (") +
228*cdf0e10cSrcweir         String(rLocalData.getDate( pWin->GetDate())) + rtl::OUString::createFromAscii(", ") +
229*cdf0e10cSrcweir         String(rLocalData.getTime( pWin->GetTime(),false)) + rtl::OUString::createFromAscii("): \"")));
230*cdf0e10cSrcweir     GetOutlinerView()->InsertText(aText,false);
231*cdf0e10cSrcweir 
232*cdf0e10cSrcweir     // insert old, selected text or "..."
233*cdf0e10cSrcweir     // TOOD: iterate over all paragraphs, not only first one to find out if it is empty
234*cdf0e10cSrcweir     if (pText->GetTextObject().GetText(0) != String(rtl::OUString::createFromAscii("")))
235*cdf0e10cSrcweir         GetOutlinerView()->GetEditView().InsertText(pText->GetTextObject());
236*cdf0e10cSrcweir     else
237*cdf0e10cSrcweir         GetOutlinerView()->InsertText(rtl::OUString::createFromAscii("..."),false);
238*cdf0e10cSrcweir     GetOutlinerView()->InsertText(rtl::OUString::createFromAscii("\"\n"),false);
239*cdf0e10cSrcweir 
240*cdf0e10cSrcweir     GetOutlinerView()->SetSelection(ESelection(0x0,0x0,0xFFFF,0xFFFF));
241*cdf0e10cSrcweir     SfxItemSet aAnswerSet( DocView().GetDocShell()->GetPool() );
242*cdf0e10cSrcweir     aAnswerSet.Put(SvxFontHeightItem(200,80,EE_CHAR_FONTHEIGHT));
243*cdf0e10cSrcweir     aAnswerSet.Put(SvxPostureItem(ITALIC_NORMAL,EE_CHAR_ITALIC));
244*cdf0e10cSrcweir     GetOutlinerView()->SetAttribs(aAnswerSet);
245*cdf0e10cSrcweir     GetOutlinerView()->SetSelection(ESelection(0xFFFF,0xFFFF,0xFFFF,0xFFFF));
246*cdf0e10cSrcweir 
247*cdf0e10cSrcweir     //remove all attributes and reset our standard ones
248*cdf0e10cSrcweir     GetOutlinerView()->GetEditView().RemoveAttribsKeepLanguages(true);
249*cdf0e10cSrcweir     GetOutlinerView()->SetAttribs(DefaultItem());
250*cdf0e10cSrcweir     // lets insert an undo step so the initial text can be easily deleted
251*cdf0e10cSrcweir     // but do not use UpdateData() directly, would set modified state again and reentrance into Mgr
252*cdf0e10cSrcweir     Engine()->SetModifyHdl( Link() );
253*cdf0e10cSrcweir     IDocumentUndoRedo & rUndoRedo(
254*cdf0e10cSrcweir         DocView().GetDocShell()->GetDoc()->GetIDocumentUndoRedo());
255*cdf0e10cSrcweir     ::std::auto_ptr<SwField> pOldField;
256*cdf0e10cSrcweir     if (rUndoRedo.DoesUndo())
257*cdf0e10cSrcweir     {
258*cdf0e10cSrcweir         pOldField.reset(mpFld->Copy());
259*cdf0e10cSrcweir     }
260*cdf0e10cSrcweir     mpFld->SetPar2(Engine()->GetEditEngine().GetText());
261*cdf0e10cSrcweir     mpFld->SetTextObject(Engine()->CreateParaObject());
262*cdf0e10cSrcweir     if (rUndoRedo.DoesUndo())
263*cdf0e10cSrcweir     {
264*cdf0e10cSrcweir         SwTxtFld *const pTxtFld = mpFmtFld->GetTxtFld();
265*cdf0e10cSrcweir         SwPosition aPosition( pTxtFld->GetTxtNode() );
266*cdf0e10cSrcweir         aPosition.nContent = *pTxtFld->GetStart();
267*cdf0e10cSrcweir         rUndoRedo.AppendUndo(
268*cdf0e10cSrcweir             new SwUndoFieldFromDoc(aPosition, *pOldField, *mpFld, 0, true));
269*cdf0e10cSrcweir     }
270*cdf0e10cSrcweir     Engine()->SetModifyHdl( LINK( this, SwAnnotationWin, ModifyHdl ) );
271*cdf0e10cSrcweir     Engine()->ClearModifyFlag();
272*cdf0e10cSrcweir     Engine()->GetUndoManager().Clear();
273*cdf0e10cSrcweir }
274*cdf0e10cSrcweir 
275*cdf0e10cSrcweir SvxLanguageItem SwAnnotationWin::GetLanguage(void)
276*cdf0e10cSrcweir {
277*cdf0e10cSrcweir     // set initial language for outliner
278*cdf0e10cSrcweir     sal_uInt16 nScriptType = SvtLanguageOptions::GetScriptTypeOfLanguage( mpFld->GetLanguage() );
279*cdf0e10cSrcweir     sal_uInt16 nLangWhichId = 0;
280*cdf0e10cSrcweir     switch (nScriptType)
281*cdf0e10cSrcweir     {
282*cdf0e10cSrcweir         case SCRIPTTYPE_LATIN :    nLangWhichId = EE_CHAR_LANGUAGE ; break;
283*cdf0e10cSrcweir         case SCRIPTTYPE_ASIAN :    nLangWhichId = EE_CHAR_LANGUAGE_CJK; break;
284*cdf0e10cSrcweir         case SCRIPTTYPE_COMPLEX :  nLangWhichId = EE_CHAR_LANGUAGE_CTL; break;
285*cdf0e10cSrcweir         default: DBG_ERROR("GetLanguage: wrong script tye");
286*cdf0e10cSrcweir     }
287*cdf0e10cSrcweir     return SvxLanguageItem(mpFld->GetLanguage(),nLangWhichId);
288*cdf0e10cSrcweir }
289*cdf0e10cSrcweir 
290*cdf0e10cSrcweir bool SwAnnotationWin::IsProtected()
291*cdf0e10cSrcweir {
292*cdf0e10cSrcweir     return SwSidebarWin::IsProtected() ||
293*cdf0e10cSrcweir            GetLayoutStatus() == SwPostItHelper::DELETED ||
294*cdf0e10cSrcweir            ( mpFmtFld ? mpFmtFld->IsProtect() : false );
295*cdf0e10cSrcweir }
296*cdf0e10cSrcweir 
297*cdf0e10cSrcweir String SwAnnotationWin::GetAuthor()
298*cdf0e10cSrcweir {
299*cdf0e10cSrcweir     return mpFld->GetPar1();
300*cdf0e10cSrcweir }
301*cdf0e10cSrcweir 
302*cdf0e10cSrcweir Date SwAnnotationWin::GetDate()
303*cdf0e10cSrcweir {
304*cdf0e10cSrcweir     return mpFld->GetDate();
305*cdf0e10cSrcweir }
306*cdf0e10cSrcweir 
307*cdf0e10cSrcweir Time SwAnnotationWin::GetTime()
308*cdf0e10cSrcweir {
309*cdf0e10cSrcweir     return mpFld->GetTime();
310*cdf0e10cSrcweir }
311*cdf0e10cSrcweir 
312*cdf0e10cSrcweir } } // end of namespace sw::annotation
313