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