Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "PostItMgr.hxx"
21 : #include <postithelper.hxx>
22 :
23 : #include <SidebarWin.hxx>
24 : #include <AnnotationWin.hxx>
25 : #include <frmsidebarwincontainer.hxx>
26 : #include <accmap.hxx>
27 :
28 : #include <SidebarWindowsConsts.hxx>
29 : #include <AnchorOverlayObject.hxx>
30 : #include <ShadowOverlayObject.hxx>
31 :
32 : #include <vcl/svapp.hxx>
33 : #include <vcl/scrbar.hxx>
34 : #include <vcl/outdev.hxx>
35 : #include <vcl/settings.hxx>
36 :
37 : #include <viewopt.hxx>
38 :
39 : #include <view.hxx>
40 : #include <docsh.hxx>
41 : #include <wrtsh.hxx>
42 : #include <doc.hxx>
43 : #include <fldbas.hxx>
44 : #include <fmtfld.hxx>
45 : #include <docufld.hxx>
46 : #include <edtwin.hxx>
47 : #include <txtfld.hxx>
48 : #include <txtannotationfld.hxx>
49 : #include <ndtxt.hxx>
50 : #include <redline.hxx>
51 : #include <docary.hxx>
52 : #include <SwRewriter.hxx>
53 : #include <tools/color.hxx>
54 :
55 : #include <swmodule.hxx>
56 : #include <annotation.hrc>
57 : #include "cmdid.h"
58 :
59 : #include <sfx2/request.hxx>
60 : #include <sfx2/event.hxx>
61 : #include <svl/srchitem.hxx>
62 :
63 : #include <svl/languageoptions.hxx>
64 : #include <svtools/langtab.hxx>
65 : #include <svl/smplhint.hxx>
66 :
67 : #include <svx/svdview.hxx>
68 : #include <editeng/eeitem.hxx>
69 : #include <editeng/langitem.hxx>
70 : #include <editeng/outliner.hxx>
71 :
72 : #include <i18nlangtag/mslangid.hxx>
73 : #include <i18nlangtag/lang.h>
74 :
75 : #include "swevent.hxx"
76 : #include "switerator.hxx"
77 :
78 : // distance between Anchor Y and initial note position
79 : #define POSTIT_INITIAL_ANCHOR_DISTANCE 20
80 : //distance between two postits
81 : #define POSTIT_SPACE_BETWEEN 8
82 : #define POSTIT_MINIMUMSIZE_WITH_META 60
83 : #define POSTIT_SCROLL_SIDEBAR_HEIGHT 20
84 :
85 : // if we layout more often we stop, this should never happen
86 : #define MAX_LOOP_COUNT 50
87 :
88 : using namespace sw::sidebarwindows;
89 :
90 0 : bool comp_pos(const SwSidebarItem* a, const SwSidebarItem* b)
91 : {
92 : // sort by anchor position
93 0 : SwPosition aPosAnchorA = a->GetAnchorPosition();
94 0 : SwPosition aPosAnchorB = b->GetAnchorPosition();
95 :
96 0 : bool aAnchorAInFooter = false;
97 0 : bool aAnchorBInFooter = false;
98 :
99 : // is the anchor placed in Footnote or the Footer?
100 0 : if( aPosAnchorA.nNode.GetNode().FindFootnoteStartNode() || aPosAnchorA.nNode.GetNode().FindFooterStartNode() )
101 0 : aAnchorAInFooter = true;
102 0 : if( aPosAnchorB.nNode.GetNode().FindFootnoteStartNode() || aPosAnchorB.nNode.GetNode().FindFooterStartNode() )
103 0 : aAnchorBInFooter = true;
104 :
105 : // fdo#34800
106 : // if AnchorA is in footnote, and AnchorB isn't
107 : // we do not want to change over the position
108 0 : if( aAnchorAInFooter && !aAnchorBInFooter )
109 0 : return false;
110 : // if aAnchorA is not placed in a footnote, and aAnchorB is
111 : // force a change over
112 0 : else if( !aAnchorAInFooter && aAnchorBInFooter )
113 0 : return true;
114 : // If neither or both are in the footer, compare the positions.
115 : // Since footnotes are in Inserts section of nodes array and footers
116 : // in Autotext section, all footnotes precede any footers so no need
117 : // to check that.
118 : else
119 0 : return aPosAnchorA < aPosAnchorB;
120 : }
121 :
122 0 : SwPostItMgr::SwPostItMgr(SwView* pView)
123 : : mpView(pView)
124 0 : , mpWrtShell(mpView->GetDocShell()->GetWrtShell())
125 0 : , mpEditWin(&mpView->GetEditWin())
126 : , mnEventId(0)
127 : , mbWaitingForCalcRects(false)
128 : , mpActivePostIt(0)
129 : , mbLayout(false)
130 : , mbLayoutHeight(0)
131 : , mbLayouting(false)
132 0 : , mbReadOnly(mpView->GetDocShell()->IsReadOnly())
133 : , mbDeleteNote(true)
134 : , mpAnswer(0)
135 : , mbIsShowAnchor( false )
136 0 : , mpFrmSidebarWinContainer( 0 )
137 : {
138 0 : if(!mpView->GetDrawView() )
139 0 : mpView->GetWrtShell().MakeDrawView();
140 :
141 0 : SwNoteProps aProps;
142 0 : mbIsShowAnchor = aProps.IsShowAnchor();
143 :
144 : //make sure we get the colour yellow always, even if not the first one of comments or redlining
145 0 : SW_MOD()->GetRedlineAuthor();
146 :
147 : // collect all PostIts and redline comments that exist after loading the document
148 : // don't check for existance for any of them, don't focus them
149 0 : AddPostIts(false,false);
150 : /* this code can be used once we want redline comments in the Sidebar
151 : AddRedlineComments(false,false);
152 : */
153 : // we want to receive stuff like SFX_HINT_DOCCHANGED
154 0 : StartListening(*mpView->GetDocShell());
155 0 : if (!mvPostItFlds.empty())
156 : {
157 0 : mbWaitingForCalcRects = true;
158 0 : mnEventId = Application::PostUserEvent( LINK( this, SwPostItMgr, CalcHdl), 0 );
159 0 : }
160 0 : }
161 :
162 0 : SwPostItMgr::~SwPostItMgr()
163 : {
164 0 : if ( mnEventId )
165 0 : Application::RemoveUserEvent( mnEventId );
166 : // forget about all our Sidebar windows
167 0 : RemoveSidebarWin();
168 0 : EndListening( *mpView->GetDocShell() );
169 :
170 0 : for(std::vector<SwPostItPageItem*>::iterator i = mPages.begin(); i != mPages.end() ; ++i)
171 0 : delete (*i);
172 0 : mPages.clear();
173 :
174 0 : delete mpFrmSidebarWinContainer;
175 0 : mpFrmSidebarWinContainer = 0;
176 0 : }
177 :
178 0 : void SwPostItMgr::CheckForRemovedPostIts()
179 : {
180 0 : bool bRemoved = false;
181 0 : for(std::list<SwSidebarItem*>::iterator i = mvPostItFlds.begin(); i != mvPostItFlds.end(); )
182 : {
183 0 : std::list<SwSidebarItem*>::iterator it = i++;
184 0 : if ( !(*it)->UseElement() )
185 : {
186 0 : SwSidebarItem* p = (*it);
187 0 : mvPostItFlds.remove(*it);
188 0 : if (GetActiveSidebarWin() == p->pPostIt)
189 0 : SetActiveSidebarWin(0);
190 0 : if (p->pPostIt)
191 0 : delete p->pPostIt;
192 0 : delete p;
193 0 : bRemoved = true;
194 : }
195 : }
196 :
197 0 : if ( bRemoved )
198 : {
199 : // make sure that no deleted items remain in page lists
200 : // todo: only remove deleted ones?!
201 0 : if ( mvPostItFlds.empty() )
202 : {
203 0 : PreparePageContainer();
204 0 : PrepareView();
205 : }
206 : else
207 : // if postits are their make sure that page lists are not empty
208 : // otherwise sudden paints can cause pain (in BorderOverPageBorder)
209 0 : CalcRects();
210 : }
211 0 : }
212 :
213 0 : void SwPostItMgr::InsertItem(SfxBroadcaster* pItem, bool bCheckExistance, bool bFocus)
214 : {
215 0 : if (bCheckExistance)
216 : {
217 0 : for(std::list<SwSidebarItem*>::iterator i = mvPostItFlds.begin(); i != mvPostItFlds.end() ; ++i)
218 : {
219 0 : if ( (*i)->GetBroadCaster() == pItem )
220 0 : return;
221 : }
222 : }
223 0 : mbLayout = bFocus;
224 0 : if (pItem->ISA(SwFmtFld))
225 0 : mvPostItFlds.push_back(new SwAnnotationItem(static_cast<SwFmtFld&>(*pItem), true, bFocus) );
226 : OSL_ENSURE(pItem->ISA(SwFmtFld),"Mgr::InsertItem: seems like new stuff was added");
227 0 : StartListening(*pItem);
228 : }
229 :
230 0 : void SwPostItMgr::RemoveItem( SfxBroadcaster* pBroadcast )
231 : {
232 0 : EndListening(*pBroadcast);
233 0 : for(std::list<SwSidebarItem*>::iterator i = mvPostItFlds.begin(); i != mvPostItFlds.end() ; ++i)
234 : {
235 0 : if ( (*i)->GetBroadCaster() == pBroadcast )
236 : {
237 0 : SwSidebarItem* p = (*i);
238 0 : if (GetActiveSidebarWin() == p->pPostIt)
239 0 : SetActiveSidebarWin(0);
240 0 : mvPostItFlds.remove(*i);
241 0 : delete p->pPostIt;
242 0 : delete p;
243 0 : break;
244 : }
245 : }
246 0 : mbLayout = true;
247 0 : PrepareView();
248 0 : }
249 :
250 0 : void SwPostItMgr::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
251 : {
252 0 : if ( rHint.IsA(TYPE(SfxEventHint) ) )
253 : {
254 0 : sal_uInt32 nId = ((SfxEventHint&)rHint).GetEventId();
255 0 : if ( nId == SW_EVENT_LAYOUT_FINISHED )
256 : {
257 0 : if ( !mbWaitingForCalcRects && !mvPostItFlds.empty())
258 : {
259 0 : mbWaitingForCalcRects = true;
260 0 : mnEventId = Application::PostUserEvent( LINK( this, SwPostItMgr, CalcHdl), 0 );
261 : }
262 : }
263 : }
264 0 : else if ( rHint.IsA(TYPE(SfxSimpleHint) ) )
265 : {
266 0 : sal_uInt32 nId = ((SfxSimpleHint&)rHint).GetId();
267 0 : switch ( nId )
268 : {
269 : case SFX_HINT_MODECHANGED:
270 : {
271 0 : if ( mbReadOnly != !!(mpView->GetDocShell()->IsReadOnly()) )
272 : {
273 0 : mbReadOnly = !mbReadOnly;
274 0 : SetReadOnlyState();
275 0 : mbLayout = true;
276 : }
277 0 : break;
278 : }
279 : case SFX_HINT_DOCCHANGED:
280 : {
281 0 : if ( mpView->GetDocShell() == &rBC )
282 : {
283 0 : if ( !mbWaitingForCalcRects && !mvPostItFlds.empty())
284 : {
285 0 : mbWaitingForCalcRects = true;
286 0 : mnEventId = Application::PostUserEvent( LINK( this, SwPostItMgr, CalcHdl), 0 );
287 : }
288 : }
289 0 : break;
290 : }
291 : case SFX_HINT_USER04:
292 : {
293 : // if we are in a SplitNode/Cut operation, do not delete note and then add again, as this will flicker
294 0 : mbDeleteNote = !mbDeleteNote;
295 0 : break;
296 : }
297 : case SFX_HINT_DYING:
298 : {
299 0 : if ( mpView->GetDocShell() != &rBC )
300 : {
301 : // field to be removed is the broadcaster
302 : OSL_FAIL("Notification for removed SwFmtFld was not sent!");
303 0 : RemoveItem(&rBC);
304 : }
305 0 : break;
306 : }
307 : }
308 : }
309 0 : else if ( rHint.IsA(TYPE(SwFmtFldHint) ) )
310 : {
311 0 : const SwFmtFldHint& rFmtHint = static_cast<const SwFmtFldHint&>(rHint);
312 0 : SwFmtFld* pFld = const_cast <SwFmtFld*>( rFmtHint.GetField() );
313 0 : switch ( rFmtHint.Which() )
314 : {
315 : case SWFMTFLD_INSERTED :
316 : {
317 0 : if (!pFld)
318 : {
319 0 : AddPostIts(true);
320 0 : break;
321 : }
322 : // get field to be inserted from hint
323 0 : if ( pFld->IsFldInDoc() )
324 : {
325 0 : bool bEmpty = !HasNotes();
326 0 : InsertItem( pFld, true, false );
327 0 : if (bEmpty && !mvPostItFlds.empty())
328 0 : PrepareView(true);
329 : }
330 : else
331 : {
332 : OSL_FAIL("Inserted field not in document!" );
333 : }
334 0 : break;
335 : }
336 : case SWFMTFLD_REMOVED:
337 : {
338 0 : if (mbDeleteNote)
339 : {
340 0 : if (!pFld)
341 : {
342 0 : CheckForRemovedPostIts();
343 0 : break;
344 : }
345 0 : RemoveItem(pFld);
346 : }
347 0 : break;
348 : }
349 : case SWFMTFLD_FOCUS:
350 : {
351 0 : if (rFmtHint.GetView()== mpView)
352 0 : Focus(rBC);
353 0 : break;
354 : }
355 : case SWFMTFLD_CHANGED:
356 : {
357 0 : SwFmtFld* pFmtFld = dynamic_cast<SwFmtFld*>(&rBC);
358 0 : for(std::list<SwSidebarItem*>::iterator i = mvPostItFlds.begin(); i != mvPostItFlds.end() ; ++i)
359 : {
360 0 : if ( pFmtFld == (*i)->GetBroadCaster() )
361 : {
362 0 : if ((*i)->pPostIt)
363 : {
364 0 : (*i)->pPostIt->SetPostItText();
365 0 : mbLayout = true;
366 : }
367 0 : break;
368 : }
369 : }
370 0 : break;
371 : }
372 :
373 : case SWFMTFLD_LANGUAGE:
374 : {
375 0 : SwFmtFld* pFmtFld = dynamic_cast<SwFmtFld*>(&rBC);
376 0 : for(std::list<SwSidebarItem*>::iterator i = mvPostItFlds.begin(); i != mvPostItFlds.end() ; ++i)
377 : {
378 0 : if ( pFmtFld == (*i)->GetBroadCaster() )
379 : {
380 0 : if ((*i)->pPostIt)
381 : {
382 0 : const sal_uInt16 nScriptType = SvtLanguageOptions::GetScriptTypeOfLanguage( (*i)->GetFmtFld().GetField()->GetLanguage() );
383 0 : sal_uInt16 nLangWhichId = 0;
384 0 : switch (nScriptType)
385 : {
386 0 : case SCRIPTTYPE_LATIN : nLangWhichId = EE_CHAR_LANGUAGE ; break;
387 0 : case SCRIPTTYPE_ASIAN : nLangWhichId = EE_CHAR_LANGUAGE_CJK; break;
388 0 : case SCRIPTTYPE_COMPLEX : nLangWhichId = EE_CHAR_LANGUAGE_CTL; break;
389 : }
390 0 : (*i)->pPostIt->SetLanguage(
391 : SvxLanguageItem(
392 0 : (*i)->GetFmtFld().GetField()->GetLanguage(),
393 0 : nLangWhichId) );
394 : }
395 0 : break;
396 : }
397 : }
398 0 : break;
399 : }
400 : }
401 : }
402 0 : }
403 :
404 0 : void SwPostItMgr::Focus(SfxBroadcaster& rBC)
405 : {
406 0 : if (!mpWrtShell->GetViewOptions()->IsPostIts())
407 : {
408 0 : SfxRequest aRequest(mpView->GetViewFrame(),FN_VIEW_NOTES);
409 0 : mpView->ExecViewOptions(aRequest);
410 : }
411 :
412 0 : for(std::list<SwSidebarItem*>::iterator i = mvPostItFlds.begin(); i != mvPostItFlds.end() ; ++i)
413 : {
414 : // field to get the focus is the broadcaster
415 0 : if ( &rBC == (*i)->GetBroadCaster() )
416 : {
417 0 : if ((*i)->pPostIt)
418 : {
419 0 : (*i)->pPostIt->GrabFocus();
420 0 : MakeVisible((*i)->pPostIt);
421 : }
422 : else
423 : {
424 : // when the layout algorithm starts, this postit is created and receives focus
425 0 : (*i)->bFocus = true;
426 : }
427 : }
428 : }
429 0 : }
430 :
431 0 : bool SwPostItMgr::CalcRects()
432 : {
433 0 : if ( mnEventId )
434 : {
435 : // if CalcRects() was forced and an event is still pending: remove it
436 : // it is superfluous and also may cause reentrance problems if triggered while layouting
437 0 : Application::RemoveUserEvent( mnEventId );
438 0 : mnEventId = 0;
439 : }
440 :
441 0 : bool bChange = false;
442 0 : bool bRepair = false;
443 0 : PreparePageContainer();
444 0 : if ( !mvPostItFlds.empty() )
445 : {
446 0 : for(std::list<SwSidebarItem*>::iterator i = mvPostItFlds.begin(); i != mvPostItFlds.end() ; ++i)
447 : {
448 0 : SwSidebarItem* pItem = (*i);
449 0 : if ( !pItem->UseElement() )
450 : {
451 : OSL_FAIL("PostIt is not in doc or other wrong use");
452 0 : bRepair = true;
453 0 : continue;
454 : }
455 :
456 0 : const SwRect aOldAnchorRect( pItem->maLayoutInfo.mPosition );
457 0 : const SwPostItHelper::SwLayoutStatus eOldLayoutStatus = pItem->mLayoutStatus;
458 0 : const sal_uLong nOldStartNodeIdx( pItem->maLayoutInfo.mnStartNodeIdx );
459 0 : const sal_Int32 nOldStartContent( pItem->maLayoutInfo.mnStartContent );
460 : {
461 : // update layout information
462 : const SwTxtAnnotationFld* pTxtAnnotationFld =
463 0 : dynamic_cast< const SwTxtAnnotationFld* >( pItem->GetFmtFld().GetTxtFld() );
464 : const ::sw::mark::IMark* pAnnotationMark =
465 0 : pTxtAnnotationFld != NULL ? pTxtAnnotationFld->GetAnnotationMark() : NULL;
466 0 : if ( pAnnotationMark != NULL )
467 : {
468 : pItem->mLayoutStatus =
469 : SwPostItHelper::getLayoutInfos(
470 : pItem->maLayoutInfo,
471 0 : pItem->GetAnchorPosition(),
472 0 : &pAnnotationMark->GetMarkStart() );
473 : }
474 : else
475 : {
476 : pItem->mLayoutStatus =
477 0 : SwPostItHelper::getLayoutInfos( pItem->maLayoutInfo, pItem->GetAnchorPosition() );
478 : }
479 : }
480 : bChange = bChange
481 0 : || pItem->maLayoutInfo.mPosition != aOldAnchorRect
482 0 : || pItem->mLayoutStatus != eOldLayoutStatus
483 0 : || pItem->maLayoutInfo.mnStartNodeIdx != nOldStartNodeIdx
484 0 : || pItem->maLayoutInfo.mnStartContent != nOldStartContent;
485 : }
486 :
487 : // show notes in right order in navigator
488 : //prevent Anchors during layout to overlap, e.g. when moving a frame
489 0 : Sort(SORT_POS);
490 :
491 : // sort the items into the right page vector, so layout can be done by page
492 0 : for(std::list<SwSidebarItem*>::iterator i = mvPostItFlds.begin(); i != mvPostItFlds.end() ; ++i)
493 : {
494 0 : SwSidebarItem* pItem = (*i);
495 0 : if( SwPostItHelper::INVISIBLE == pItem->mLayoutStatus )
496 : {
497 0 : if (pItem->pPostIt)
498 0 : pItem->pPostIt->HideNote();
499 0 : continue;
500 : }
501 :
502 0 : if( SwPostItHelper::HIDDEN == pItem->mLayoutStatus )
503 : {
504 0 : if (!mpWrtShell->GetViewOptions()->IsShowHiddenChar())
505 : {
506 0 : if (pItem->pPostIt)
507 0 : pItem->pPostIt->HideNote();
508 0 : continue;
509 : }
510 : }
511 :
512 0 : const unsigned long aPageNum = pItem->maLayoutInfo.mnPageNumber;
513 0 : if (aPageNum > mPages.size())
514 : {
515 0 : const unsigned long nNumberOfPages = mPages.size();
516 0 : for (unsigned int j=0; j<aPageNum - nNumberOfPages; ++j)
517 0 : mPages.push_back( new SwPostItPageItem());
518 : }
519 0 : mPages[aPageNum-1]->mList->push_back(pItem);
520 0 : mPages[aPageNum-1]->mPageRect = pItem->maLayoutInfo.mPageFrame;
521 0 : mPages[aPageNum-1]->eSidebarPosition = pItem->maLayoutInfo.meSidebarPosition;
522 : }
523 :
524 0 : if (!bChange && mpWrtShell->getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE))
525 : {
526 0 : long nLayoutHeight = SwPostItHelper::getLayoutHeight( mpWrtShell->GetLayout() );
527 0 : if( nLayoutHeight > mbLayoutHeight )
528 : {
529 0 : if (mPages[0]->bScrollbar || HasScrollbars())
530 0 : bChange = true;
531 : }
532 0 : else if( nLayoutHeight < mbLayoutHeight )
533 : {
534 0 : if (mPages[0]->bScrollbar || !BorderOverPageBorder(1))
535 0 : bChange = true;
536 : }
537 : }
538 : }
539 :
540 0 : if ( bRepair )
541 0 : CheckForRemovedPostIts();
542 :
543 0 : mbLayoutHeight = SwPostItHelper::getLayoutHeight( mpWrtShell->GetLayout() );
544 0 : mbWaitingForCalcRects = false;
545 0 : return bChange;
546 : }
547 :
548 0 : bool SwPostItMgr::HasScrollbars() const
549 : {
550 0 : for(std::list<SwSidebarItem*>::const_iterator i = mvPostItFlds.begin(); i != mvPostItFlds.end() ; ++i)
551 : {
552 0 : if ((*i)->bShow && (*i)->pPostIt && (*i)->pPostIt->HasScrollbar())
553 0 : return true;
554 : }
555 0 : return false;
556 : }
557 :
558 0 : void SwPostItMgr::PreparePageContainer()
559 : {
560 : // we do not just delete the SwPostItPageItem, so offset/scrollbar is not lost
561 0 : long lPageSize = mpWrtShell->GetNumPages();
562 0 : long lContainerSize = mPages.size();
563 :
564 0 : if (lContainerSize < lPageSize)
565 : {
566 0 : for (int i=0; i<lPageSize - lContainerSize;i++)
567 0 : mPages.push_back( new SwPostItPageItem());
568 : }
569 0 : else if (lContainerSize > lPageSize)
570 : {
571 0 : for (int i=mPages.size()-1; i >= lPageSize;--i)
572 : {
573 0 : delete mPages[i];
574 0 : mPages.pop_back();
575 : }
576 : }
577 : // only clear the list, DO NOT delete the objects itself
578 0 : for(std::vector<SwPostItPageItem*>::iterator i = mPages.begin(); i != mPages.end() ; ++i)
579 : {
580 0 : (*i)->mList->clear();
581 0 : if (mvPostItFlds.empty())
582 0 : (*i)->bScrollbar = false;
583 :
584 : }
585 0 : }
586 :
587 0 : void SwPostItMgr::LayoutPostIts()
588 : {
589 0 : if ( !mvPostItFlds.empty() && !mbWaitingForCalcRects )
590 : {
591 0 : mbLayouting = true;
592 :
593 : //loop over all pages and do the layout
594 : // - create SwPostIt if necessary
595 : // - place SwPostIts on their initial position
596 : // - calculate necessary height for all PostIts together
597 0 : bool bUpdate = false;
598 0 : for (unsigned long n=0;n<mPages.size();n++)
599 : {
600 : // only layout if there are notes on this page
601 0 : if (mPages[n]->mList->size()>0)
602 : {
603 0 : std::list<SwSidebarWin*> aVisiblePostItList;
604 0 : unsigned long lNeededHeight = 0;
605 0 : long mlPageBorder = 0;
606 0 : long mlPageEnd = 0;
607 :
608 0 : for(SwSidebarItem_iterator i = mPages[n]->mList->begin(); i != mPages[n]->mList->end(); ++i)
609 : {
610 0 : SwSidebarItem* pItem = (*i);
611 0 : SwSidebarWin* pPostIt = pItem->pPostIt;
612 :
613 0 : if (mPages[n]->eSidebarPosition == sw::sidebarwindows::SIDEBAR_LEFT )
614 : {
615 : // x value for notes positioning
616 0 : mlPageBorder = mpEditWin->LogicToPixel( Point( mPages[n]->mPageRect.Left(), 0)).X() - GetSidebarWidth(true);// - GetSidebarBorderWidth(true);
617 : //bending point
618 : mlPageEnd =
619 0 : mpWrtShell->getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE)
620 0 : ? pItem->maLayoutInfo.mPagePrtArea.Left()
621 0 : : mPages[n]->mPageRect.Left() + 350;
622 : }
623 0 : else if (mPages[n]->eSidebarPosition == sw::sidebarwindows::SIDEBAR_RIGHT )
624 : {
625 : // x value for notes positioning
626 0 : mlPageBorder = mpEditWin->LogicToPixel( Point(mPages[n]->mPageRect.Right(), 0)).X() + GetSidebarBorderWidth(true);
627 : //bending point
628 : mlPageEnd =
629 0 : mpWrtShell->getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE)
630 0 : ? pItem->maLayoutInfo.mPagePrtArea.Right() :
631 0 : mPages[n]->mPageRect.Right() - 350;
632 : }
633 :
634 0 : if (pItem->bShow)
635 : {
636 0 : long Y = mpEditWin->LogicToPixel( Point(0,pItem->maLayoutInfo.mPosition.Bottom())).Y();
637 0 : long aPostItHeight = 0;
638 0 : if (!pPostIt)
639 : {
640 0 : pPostIt = (*i)->GetSidebarWindow( mpView->GetEditWin(),
641 : WB_DIALOGCONTROL,
642 : *this,
643 0 : 0 );
644 0 : pPostIt->InitControls();
645 0 : pPostIt->SetReadonly(mbReadOnly);
646 0 : pItem->pPostIt = pPostIt;
647 0 : if (mpAnswer)
648 : {
649 0 : if (pPostIt->CalcFollow()) //do we really have another note in front of this one
650 0 : static_cast<sw::annotation::SwAnnotationWin*>(pPostIt)->InitAnswer(mpAnswer);
651 0 : delete mpAnswer;
652 0 : mpAnswer = 0;
653 : }
654 : }
655 :
656 : pPostIt->SetChangeTracking(
657 : pItem->mLayoutStatus,
658 0 : GetColorAnchor(pItem->maLayoutInfo.mRedlineAuthor));
659 0 : pPostIt->SetSidebarPosition(mPages[n]->eSidebarPosition);
660 0 : pPostIt->SetFollow(pPostIt->CalcFollow());
661 0 : aPostItHeight = ( pPostIt->GetPostItTextHeight() < pPostIt->GetMinimumSizeWithoutMeta()
662 0 : ? pPostIt->GetMinimumSizeWithoutMeta()
663 0 : : pPostIt->GetPostItTextHeight() )
664 0 : + pPostIt->GetMetaHeight();
665 : pPostIt->SetPosSizePixelRect( mlPageBorder ,
666 0 : Y - GetInitialAnchorDistance(),
667 0 : GetNoteWidth() ,
668 : aPostItHeight,
669 : pItem->maLayoutInfo.mPosition,
670 0 : mlPageEnd );
671 0 : pPostIt->ChangeSidebarItem( *pItem );
672 :
673 0 : if (pItem->bFocus)
674 : {
675 0 : mbLayout = true;
676 0 : pPostIt->GrabFocus();
677 0 : pItem->bFocus = false;
678 : }
679 : // only the visible postits are used for the final layout
680 0 : aVisiblePostItList.push_back(pPostIt);
681 0 : lNeededHeight += pPostIt->IsFollow() ? aPostItHeight : aPostItHeight+GetSpaceBetween();
682 : }
683 : else // we don't want to see it
684 : {
685 0 : if (pPostIt)
686 0 : pPostIt->HideNote();
687 : }
688 : }
689 :
690 0 : if ((!aVisiblePostItList.empty()) && ShowNotes())
691 : {
692 0 : bool bOldScrollbar = mPages[n]->bScrollbar;
693 0 : if (ShowNotes())
694 0 : mPages[n]->bScrollbar = LayoutByPage(aVisiblePostItList, mPages[n]->mPageRect.SVRect(), lNeededHeight);
695 : else
696 0 : mPages[n]->bScrollbar = false;
697 0 : if (!mPages[n]->bScrollbar)
698 : {
699 0 : mPages[n]->lOffset = 0;
700 : }
701 : else
702 : {
703 : //when we changed our zoom level, the offset value can be to big, so lets check for the largest possible zoom value
704 0 : long aAvailableHeight = mpEditWin->LogicToPixel(Size(0,mPages[n]->mPageRect.Height())).Height() - 2 * GetSidebarScrollerHeight();
705 0 : long lOffset = -1 * GetScrollSize() * (aVisiblePostItList.size() - aAvailableHeight / GetScrollSize());
706 0 : if (mPages[n]->lOffset < lOffset)
707 0 : mPages[n]->lOffset = lOffset;
708 : }
709 0 : bUpdate = (bOldScrollbar != mPages[n]->bScrollbar) || bUpdate;
710 0 : const long aSidebarheight = mPages[n]->bScrollbar ? mpEditWin->PixelToLogic(Size(0,GetSidebarScrollerHeight())).Height() : 0;
711 : /*
712 : TODO
713 : - enlarge all notes till GetNextBorder(), as we resized to average value before
714 : */
715 : //lets hide the ones which overlap the page
716 0 : for(SwSidebarWin_iterator i = aVisiblePostItList.begin(); i != aVisiblePostItList.end() ; ++i)
717 : {
718 0 : if (mPages[n]->lOffset != 0)
719 0 : (*i)->TranslateTopPosition(mPages[n]->lOffset);
720 :
721 0 : bool bBottom = mpEditWin->PixelToLogic(Point(0,(*i)->VirtualPos().Y()+(*i)->VirtualSize().Height())).Y() <= (mPages[n]->mPageRect.Bottom()-aSidebarheight);
722 0 : bool bTop = mpEditWin->PixelToLogic(Point(0,(*i)->VirtualPos().Y())).Y() >= (mPages[n]->mPageRect.Top()+aSidebarheight);
723 0 : if ( bBottom && bTop )
724 : {
725 0 : (*i)->ShowNote();
726 : }
727 : else
728 : {
729 0 : if (mpEditWin->PixelToLogic(Point(0,(*i)->VirtualPos().Y())).Y() < (mPages[n]->mPageRect.Top()+aSidebarheight))
730 : {
731 0 : if ( mPages[n]->eSidebarPosition == sw::sidebarwindows::SIDEBAR_LEFT )
732 0 : (*i)->ShowAnchorOnly(Point( mPages[n]->mPageRect.Left(),
733 0 : mPages[n]->mPageRect.Top()));
734 0 : else if ( mPages[n]->eSidebarPosition == sw::sidebarwindows::SIDEBAR_RIGHT )
735 0 : (*i)->ShowAnchorOnly(Point( mPages[n]->mPageRect.Right(),
736 0 : mPages[n]->mPageRect.Top()));
737 : }
738 : else
739 : {
740 0 : if ( mPages[n]->eSidebarPosition == sw::sidebarwindows::SIDEBAR_LEFT )
741 0 : (*i)->ShowAnchorOnly(Point(mPages[n]->mPageRect.Left(),
742 0 : mPages[n]->mPageRect.Bottom()));
743 0 : else if ( mPages[n]->eSidebarPosition == sw::sidebarwindows::SIDEBAR_RIGHT )
744 0 : (*i)->ShowAnchorOnly(Point(mPages[n]->mPageRect.Right(),
745 0 : mPages[n]->mPageRect.Bottom()));
746 : }
747 : OSL_ENSURE(mPages[n]->bScrollbar,"SwPostItMgr::LayoutByPage(): note overlaps, but bScrollbar is not true");
748 : }
749 : }
750 : }
751 : else
752 : {
753 0 : for(SwSidebarWin_iterator i = aVisiblePostItList.begin(); i != aVisiblePostItList.end() ; ++i)
754 0 : (*i)->SetPosAndSize();
755 :
756 0 : bool bOldScrollbar = mPages[n]->bScrollbar;
757 0 : mPages[n]->bScrollbar = false;
758 0 : bUpdate = (bOldScrollbar != mPages[n]->bScrollbar) || bUpdate;
759 : }
760 0 : aVisiblePostItList.clear();
761 : }
762 : else
763 : {
764 0 : bUpdate = true;
765 0 : mPages[n]->bScrollbar = false;
766 : }
767 : }
768 :
769 0 : if (!ShowNotes())
770 : { // we do not want to see the notes anymore -> Options-Writer-View-Notes
771 0 : bool bRepair = false;
772 0 : for(SwSidebarItem_iterator i = mvPostItFlds.begin(); i != mvPostItFlds.end() ; ++i)
773 : {
774 0 : SwSidebarItem* pItem = (*i);
775 0 : if ( !pItem->UseElement() )
776 : {
777 : OSL_FAIL("PostIt is not in doc!");
778 0 : bRepair = true;
779 0 : continue;
780 : }
781 :
782 0 : if ((*i)->pPostIt)
783 : {
784 0 : (*i)->pPostIt->HideNote();
785 0 : if ((*i)->pPostIt->HasChildPathFocus())
786 : {
787 0 : SetActiveSidebarWin(0);
788 0 : (*i)->pPostIt->GrabFocusToDocument();
789 : }
790 : }
791 : }
792 :
793 0 : if ( bRepair )
794 0 : CheckForRemovedPostIts();
795 : }
796 :
797 : // notes scrollbar is otherwise not drawn correctly for some cases
798 : // scrollbar area is enough
799 0 : if (bUpdate)
800 0 : mpEditWin->Invalidate();
801 0 : mbLayouting = false;
802 : }
803 0 : }
804 :
805 0 : bool SwPostItMgr::BorderOverPageBorder(unsigned long aPage) const
806 : {
807 0 : if ( mPages[aPage-1]->mList->empty() )
808 : {
809 : OSL_FAIL("Notes SidePane painted but no rects and page lists calculated!");
810 0 : return false;
811 : }
812 :
813 0 : SwSidebarItem_iterator aItem = mPages[aPage-1]->mList->end();
814 0 : --aItem;
815 : OSL_ENSURE ((*aItem)->pPostIt,"BorderOverPageBorder: NULL postIt, should never happen");
816 0 : if ((*aItem)->pPostIt)
817 : {
818 0 : const long aSidebarheight = mPages[aPage-1]->bScrollbar ? mpEditWin->PixelToLogic(Size(0,GetSidebarScrollerHeight())).Height() : 0;
819 0 : const long aEndValue = mpEditWin->PixelToLogic(Point(0,(*aItem)->pPostIt->GetPosPixel().Y()+(*aItem)->pPostIt->GetSizePixel().Height())).Y();
820 0 : return aEndValue <= mPages[aPage-1]->mPageRect.Bottom()-aSidebarheight;
821 : }
822 : else
823 0 : return false;
824 : }
825 :
826 0 : void SwPostItMgr::Scroll(const long lScroll,const unsigned long aPage)
827 : {
828 : OSL_ENSURE((lScroll % GetScrollSize() )==0,"SwPostItMgr::Scroll: scrolling by wrong value");
829 : // do not scroll more than necessary up or down
830 0 : if ( ((mPages[aPage-1]->lOffset == 0) && (lScroll>0)) || ( BorderOverPageBorder(aPage) && (lScroll<0)) )
831 0 : return;
832 :
833 0 : const bool bOldUp = ArrowEnabled(KEY_PAGEUP,aPage);
834 0 : const bool bOldDown = ArrowEnabled(KEY_PAGEDOWN,aPage);
835 0 : const long aSidebarheight = mpEditWin->PixelToLogic(Size(0,GetSidebarScrollerHeight())).Height();
836 0 : for(SwSidebarItem_iterator i = mPages[aPage-1]->mList->begin(); i != mPages[aPage-1]->mList->end(); ++i)
837 : {
838 0 : SwSidebarWin* pPostIt = (*i)->pPostIt;
839 : // if this is an answer, we should take the normal position and not the real, slightly moved position
840 0 : pPostIt->SetVirtualPosSize(pPostIt->GetPosPixel(),pPostIt->GetSizePixel());
841 0 : pPostIt->TranslateTopPosition(lScroll);
842 :
843 0 : if ((*i)->bShow)
844 : {
845 0 : bool bBottom = mpEditWin->PixelToLogic(Point(0,pPostIt->VirtualPos().Y()+pPostIt->VirtualSize().Height())).Y() <= (mPages[aPage-1]->mPageRect.Bottom()-aSidebarheight);
846 0 : bool bTop = mpEditWin->PixelToLogic(Point(0,pPostIt->VirtualPos().Y())).Y() >= (mPages[aPage-1]->mPageRect.Top()+aSidebarheight);
847 0 : if ( bBottom && bTop)
848 : {
849 0 : pPostIt->ShowNote();
850 : }
851 : else
852 : {
853 0 : if ( mpEditWin->PixelToLogic(Point(0,pPostIt->VirtualPos().Y())).Y() < (mPages[aPage-1]->mPageRect.Top()+aSidebarheight))
854 : {
855 0 : if (mPages[aPage-1]->eSidebarPosition == sw::sidebarwindows::SIDEBAR_LEFT)
856 0 : pPostIt->ShowAnchorOnly(Point(mPages[aPage-1]->mPageRect.Left(),mPages[aPage-1]->mPageRect.Top()));
857 0 : else if (mPages[aPage-1]->eSidebarPosition == sw::sidebarwindows::SIDEBAR_RIGHT)
858 0 : pPostIt->ShowAnchorOnly(Point(mPages[aPage-1]->mPageRect.Right(),mPages[aPage-1]->mPageRect.Top()));
859 : }
860 : else
861 : {
862 0 : if (mPages[aPage-1]->eSidebarPosition == sw::sidebarwindows::SIDEBAR_LEFT)
863 0 : pPostIt->ShowAnchorOnly(Point(mPages[aPage-1]->mPageRect.Left(),mPages[aPage-1]->mPageRect.Bottom()));
864 0 : else if (mPages[aPage-1]->eSidebarPosition == sw::sidebarwindows::SIDEBAR_RIGHT)
865 0 : pPostIt->ShowAnchorOnly(Point(mPages[aPage-1]->mPageRect.Right(),mPages[aPage-1]->mPageRect.Bottom()));
866 : }
867 : }
868 : }
869 : }
870 0 : mPages[aPage-1]->lOffset += lScroll;
871 0 : if ( (bOldUp != ArrowEnabled(KEY_PAGEUP,aPage)) ||(bOldDown != ArrowEnabled(KEY_PAGEDOWN,aPage)) )
872 : {
873 0 : mpEditWin->Invalidate(GetBottomScrollRect(aPage));
874 0 : mpEditWin->Invalidate(GetTopScrollRect(aPage));
875 : }
876 : }
877 :
878 0 : void SwPostItMgr::AutoScroll(const SwSidebarWin* pPostIt,const unsigned long aPage )
879 : {
880 : // otherwise all notes are visible
881 0 : if (mPages[aPage-1]->bScrollbar)
882 : {
883 0 : const long aSidebarheight = mpEditWin->PixelToLogic(Size(0,GetSidebarScrollerHeight())).Height();
884 0 : const bool bBottom = mpEditWin->PixelToLogic(Point(0,pPostIt->GetPosPixel().Y()+pPostIt->GetSizePixel().Height())).Y() <= (mPages[aPage-1]->mPageRect.Bottom()-aSidebarheight);
885 0 : const bool bTop = mpEditWin->PixelToLogic(Point(0,pPostIt->GetPosPixel().Y())).Y() >= (mPages[aPage-1]->mPageRect.Top()+aSidebarheight);
886 0 : if ( !(bBottom && bTop))
887 : {
888 0 : const long aDiff = bBottom ? mpEditWin->LogicToPixel(Point(0,mPages[aPage-1]->mPageRect.Top() + aSidebarheight)).Y() - pPostIt->GetPosPixel().Y() :
889 0 : mpEditWin->LogicToPixel(Point(0,mPages[aPage-1]->mPageRect.Bottom() - aSidebarheight)).Y() - (pPostIt->GetPosPixel().Y()+pPostIt->GetSizePixel().Height());
890 : // this just adds the missing value to get the next a* GetScrollSize() after aDiff
891 : // e.g aDiff= 61 POSTIT_SCOLL=50 --> lScroll = 100
892 0 : const long lScroll = bBottom ? (aDiff + ( GetScrollSize() - (aDiff % GetScrollSize()))) : (aDiff - (GetScrollSize() + (aDiff % GetScrollSize())));
893 0 : Scroll(lScroll, aPage);
894 : }
895 : }
896 0 : }
897 :
898 0 : void SwPostItMgr::MakeVisible(const SwSidebarWin* pPostIt,long aPage )
899 : {
900 0 : if (aPage == -1)
901 : {
902 : // we dont know the page yet, lets find it ourselves
903 0 : for (unsigned long n=0;n<mPages.size();n++)
904 : {
905 0 : if (mPages[n]->mList->size()>0)
906 : {
907 0 : for(SwSidebarItem_iterator i = mPages[n]->mList->begin(); i != mPages[n]->mList->end(); ++i)
908 : {
909 0 : if ((*i)->pPostIt==pPostIt)
910 : {
911 0 : aPage = n+1;
912 0 : break;
913 : }
914 : }
915 : }
916 : }
917 : }
918 0 : if (aPage!=-1)
919 0 : AutoScroll(pPostIt,aPage);
920 0 : Rectangle aNoteRect (Point(pPostIt->GetPosPixel().X(),pPostIt->GetPosPixel().Y()-5),pPostIt->GetSizePixel());
921 0 : if (!aNoteRect.IsEmpty())
922 0 : mpWrtShell->MakeVisible(SwRect(mpEditWin->PixelToLogic(aNoteRect)));
923 0 : }
924 :
925 0 : bool SwPostItMgr::ArrowEnabled(sal_uInt16 aDirection,unsigned long aPage) const
926 : {
927 0 : switch (aDirection)
928 : {
929 : case KEY_PAGEUP:
930 : {
931 0 : return (mPages[aPage-1]->lOffset != 0);
932 : }
933 : case KEY_PAGEDOWN:
934 : {
935 0 : return (!BorderOverPageBorder(aPage));
936 : }
937 0 : default: return false;
938 : }
939 : }
940 :
941 0 : Color SwPostItMgr::GetArrowColor(sal_uInt16 aDirection,unsigned long aPage) const
942 : {
943 0 : if (ArrowEnabled(aDirection,aPage))
944 : {
945 0 : if (Application::GetSettings().GetStyleSettings().GetHighContrastMode())
946 0 : return Color(COL_WHITE);
947 : else
948 0 : return COL_NOTES_SIDEPANE_ARROW_ENABLED;
949 : }
950 : else
951 : {
952 0 : return COL_NOTES_SIDEPANE_ARROW_DISABLED;
953 : }
954 : }
955 :
956 0 : bool SwPostItMgr::LayoutByPage(std::list<SwSidebarWin*> &aVisiblePostItList,const Rectangle aBorder, long lNeededHeight)
957 : {
958 : /*** General layout idea:***/
959 : // - if we have space left, we always move the current one up,
960 : // otherwise the next one down
961 : // - first all notes are resized
962 : // - then the real layout starts
963 : /*************************************************************/
964 :
965 : //rBorder is the page rect
966 0 : const Rectangle rBorder = mpEditWin->LogicToPixel( aBorder);
967 0 : long lTopBorder = rBorder.Top() + 5;
968 0 : long lBottomBorder = rBorder.Bottom() - 5;
969 0 : const long lVisibleHeight = lBottomBorder - lTopBorder; //rBorder.GetHeight() ;
970 0 : long lTranslatePos = 0;
971 0 : bool bScrollbars = false;
972 :
973 : // do all necessary resizings
974 0 : if (lVisibleHeight < lNeededHeight)
975 : {
976 : // ok, now we have to really resize and adding scrollbars
977 0 : const long lAverageHeight = (lVisibleHeight - aVisiblePostItList.size()*GetSpaceBetween()) / aVisiblePostItList.size();
978 0 : if (lAverageHeight<GetMinimumSizeWithMeta())
979 : {
980 0 : bScrollbars = true;
981 0 : lTopBorder += GetSidebarScrollerHeight() + 10;
982 0 : lBottomBorder -= (GetSidebarScrollerHeight() + 10);
983 0 : for(SwSidebarWin_iterator i = aVisiblePostItList.begin(); i != aVisiblePostItList.end() ; ++i)
984 0 : (*i)->SetSize(Size((*i)->VirtualSize().getWidth(),(*i)->GetMinimumSizeWithMeta()));
985 : }
986 : else
987 : {
988 0 : for(SwSidebarWin_iterator i = aVisiblePostItList.begin(); i != aVisiblePostItList.end() ; ++i)
989 : {
990 0 : if ( (*i)->VirtualSize().getHeight() > lAverageHeight)
991 0 : (*i)->SetSize(Size((*i)->VirtualSize().getWidth(),lAverageHeight));
992 : }
993 : }
994 : }
995 :
996 : //start the real layout so nothing overlaps anymore
997 0 : if (aVisiblePostItList.size()>1)
998 : {
999 0 : long lSpaceUsed = 0;
1000 0 : int loop = 0;
1001 0 : bool bDone = false;
1002 : // if no window is moved anymore we are finished
1003 0 : while (!bDone)
1004 : {
1005 0 : loop++;
1006 0 : bDone = true;
1007 0 : lSpaceUsed = lTopBorder + GetSpaceBetween();
1008 0 : for(SwSidebarWin_iterator i = aVisiblePostItList.begin(); i != aVisiblePostItList.end() ; ++i)
1009 : {
1010 0 : SwSidebarWin_iterator aNextPostIt = i;
1011 0 : ++aNextPostIt;
1012 :
1013 0 : if (aNextPostIt != aVisiblePostItList.end())
1014 : {
1015 0 : lTranslatePos = ( (*i)->VirtualPos().Y() + (*i)->VirtualSize().Height()) - (*aNextPostIt)->VirtualPos().Y();
1016 0 : if (lTranslatePos > 0) // note windows overlaps the next one
1017 : {
1018 : // we are not done yet, loop at least once more
1019 0 : bDone = false;
1020 : // if there is space left, move the current note up
1021 : // it could also happen that there is no space left for the first note due to a scrollbar
1022 : // then we also jump into, so we move the current one up and the next one down
1023 0 : if ( (lSpaceUsed <= (*i)->VirtualPos().Y()) || (i==aVisiblePostItList.begin()))
1024 : {
1025 : // we have space left, so let's move the current one up
1026 0 : if ( ((*i)->VirtualPos().Y()- lTranslatePos - GetSpaceBetween()) > lTopBorder)
1027 : {
1028 0 : if ((*aNextPostIt)->IsFollow())
1029 0 : (*i)->TranslateTopPosition(-1*(lTranslatePos+ANCHORLINE_WIDTH));
1030 : else
1031 0 : (*i)->TranslateTopPosition(-1*(lTranslatePos+GetSpaceBetween()));
1032 : }
1033 : else
1034 : {
1035 0 : long lMoveUp = (*i)->VirtualPos().Y() - lTopBorder;
1036 0 : (*i)->TranslateTopPosition(-1* lMoveUp);
1037 0 : if ((*aNextPostIt)->IsFollow())
1038 0 : (*aNextPostIt)->TranslateTopPosition( (lTranslatePos+ANCHORLINE_WIDTH) - lMoveUp);
1039 : else
1040 0 : (*aNextPostIt)->TranslateTopPosition( (lTranslatePos+GetSpaceBetween()) - lMoveUp);
1041 : }
1042 : }
1043 : else
1044 : {
1045 : // no space left, left move the next one down
1046 0 : if ((*aNextPostIt)->IsFollow())
1047 0 : (*aNextPostIt)->TranslateTopPosition(lTranslatePos+ANCHORLINE_WIDTH);
1048 : else
1049 0 : (*aNextPostIt)->TranslateTopPosition(lTranslatePos+GetSpaceBetween());
1050 : }
1051 : }
1052 : else
1053 : {
1054 : // the first one could overlap the topborder instead of a second note
1055 0 : if (i==aVisiblePostItList.begin())
1056 : {
1057 0 : long lMoveDown = lTopBorder - (*i)->VirtualPos().Y();
1058 0 : if (lMoveDown>0)
1059 : {
1060 0 : bDone = false;
1061 0 : (*i)->TranslateTopPosition( lMoveDown);
1062 : }
1063 : }
1064 : }
1065 0 : if ( (*aNextPostIt)->IsFollow() )
1066 0 : lSpaceUsed += (*i)->VirtualSize().Height() + ANCHORLINE_WIDTH;
1067 : else
1068 0 : lSpaceUsed += (*i)->VirtualSize().Height() + GetSpaceBetween();
1069 : }
1070 : else
1071 : {
1072 : //(*i) is the last visible item
1073 0 : SwSidebarWin_iterator aPrevPostIt = i;
1074 0 : --aPrevPostIt;
1075 0 : lTranslatePos = ( (*aPrevPostIt)->VirtualPos().Y() + (*aPrevPostIt)->VirtualSize().Height() ) - (*i)->VirtualPos().Y();
1076 0 : if (lTranslatePos > 0)
1077 : {
1078 0 : bDone = false;
1079 0 : if ( ((*i)->VirtualPos().Y()+ (*i)->VirtualSize().Height()+lTranslatePos) < lBottomBorder)
1080 : {
1081 0 : if ( (*i)->IsFollow() )
1082 0 : (*i)->TranslateTopPosition(lTranslatePos+ANCHORLINE_WIDTH);
1083 : else
1084 0 : (*i)->TranslateTopPosition(lTranslatePos+GetSpaceBetween());
1085 : }
1086 : else
1087 : {
1088 0 : (*i)->TranslateTopPosition(lBottomBorder - ((*i)->VirtualPos().Y()+ (*i)->VirtualSize().Height()) );
1089 : }
1090 : }
1091 : else
1092 : {
1093 : // note does not overlap, but we might be over the lower border
1094 : // only do this if there are no scrollbars, otherwise notes are supposed to overlap the border
1095 0 : if (!bScrollbars && ((*i)->VirtualPos().Y()+ (*i)->VirtualSize().Height() > lBottomBorder) )
1096 : {
1097 0 : bDone = false;
1098 0 : (*i)->TranslateTopPosition(lBottomBorder - ((*i)->VirtualPos().Y()+ (*i)->VirtualSize().Height()));
1099 : }
1100 : }
1101 : }
1102 : }
1103 : // security check so we don't loop forever
1104 0 : if (loop>MAX_LOOP_COUNT)
1105 : {
1106 : OSL_FAIL("PostItMgr::Layout(): We are looping forever");
1107 0 : break;
1108 : }
1109 : }
1110 : }
1111 : else
1112 : {
1113 : // only one left, make sure it is not hidden at the top or bottom
1114 0 : SwSidebarWin_iterator i = aVisiblePostItList.begin();
1115 0 : lTranslatePos = lTopBorder - (*i)->VirtualPos().Y();
1116 0 : if (lTranslatePos>0)
1117 : {
1118 0 : (*i)->TranslateTopPosition(lTranslatePos+GetSpaceBetween());
1119 : }
1120 0 : lTranslatePos = lBottomBorder - ((*i)->VirtualPos().Y()+ (*i)->VirtualSize().Height());
1121 0 : if (lTranslatePos<0)
1122 : {
1123 0 : (*i)->TranslateTopPosition(lTranslatePos);
1124 : }
1125 : }
1126 0 : return bScrollbars;
1127 : }
1128 :
1129 0 : void SwPostItMgr::AddPostIts(bool bCheckExistance, bool bFocus)
1130 : {
1131 0 : bool bEmpty = mvPostItFlds.empty();
1132 0 : SwFieldType* pType = mpView->GetDocShell()->GetDoc()->GetFldType(RES_POSTITFLD, OUString(),false);
1133 0 : SwIterator<SwFmtFld,SwFieldType> aIter( *pType );
1134 0 : SwFmtFld* pSwFmtFld = aIter.First();
1135 0 : while(pSwFmtFld)
1136 : {
1137 0 : if ( pSwFmtFld->GetTxtFld())
1138 : {
1139 0 : if ( pSwFmtFld->IsFldInDoc() )
1140 0 : InsertItem(pSwFmtFld,bCheckExistance,bFocus);
1141 : }
1142 0 : pSwFmtFld = aIter.Next();
1143 : }
1144 :
1145 : // if we just added the first one we have to update the view for centering
1146 0 : if (bEmpty && !mvPostItFlds.empty())
1147 0 : PrepareView(true);
1148 0 : }
1149 :
1150 0 : void SwPostItMgr::RemoveSidebarWin()
1151 : {
1152 0 : if (!mvPostItFlds.empty())
1153 : {
1154 0 : for(std::list<SwSidebarItem*>::iterator i = mvPostItFlds.begin(); i != mvPostItFlds.end() ; ++i)
1155 : {
1156 0 : EndListening( *(const_cast<SfxBroadcaster*>((*i)->GetBroadCaster())) );
1157 0 : if ((*i)->pPostIt)
1158 0 : delete (*i)->pPostIt;
1159 0 : delete (*i);
1160 : }
1161 0 : mvPostItFlds.clear();
1162 : }
1163 :
1164 : // all postits removed, no items should be left in pages
1165 0 : PreparePageContainer();
1166 0 : }
1167 :
1168 : // copy to new vector, otherwise RemoveItem would operate and delete stuff on mvPostItFlds as well
1169 : // RemoveItem will clean up the core field and visible postit if necessary
1170 : // we cannot just delete everything as before, as postits could move into change tracking
1171 0 : void SwPostItMgr::Delete(const OUString& aAuthor)
1172 : {
1173 0 : mpWrtShell->StartAllAction();
1174 0 : if ( HasActiveSidebarWin() && (GetActiveSidebarWin()->GetAuthor()==aAuthor) )
1175 : {
1176 0 : SetActiveSidebarWin(0);
1177 : }
1178 0 : SwRewriter aRewriter;
1179 0 : aRewriter.AddRule(UndoArg1, SW_RESSTR(STR_DELETE_AUTHOR_NOTES) + aAuthor);
1180 0 : mpWrtShell->StartUndo( UNDO_DELETE, &aRewriter );
1181 :
1182 0 : std::vector<const SwFmtFld*> aTmp;
1183 0 : aTmp.reserve( mvPostItFlds.size() );
1184 0 : for(std::list<SwSidebarItem*>::iterator pPostIt = mvPostItFlds.begin(); pPostIt!= mvPostItFlds.end() ; ++pPostIt)
1185 : {
1186 0 : if (((*pPostIt)->pPostIt->GetAuthor() == aAuthor) )
1187 0 : aTmp.push_back( &(*pPostIt)->GetFmtFld() );
1188 : }
1189 0 : for(std::vector<const SwFmtFld*>::iterator i = aTmp.begin(); i != aTmp.end() ; ++i)
1190 : {
1191 0 : mpWrtShell->GotoField( *(*i) );
1192 0 : mpWrtShell->DelRight();
1193 : }
1194 0 : mpWrtShell->EndUndo();
1195 0 : PrepareView();
1196 0 : mpWrtShell->EndAllAction();
1197 0 : mbLayout = true;
1198 0 : CalcRects();
1199 0 : LayoutPostIts();
1200 0 : }
1201 :
1202 0 : void SwPostItMgr::Delete()
1203 : {
1204 0 : mpWrtShell->StartAllAction();
1205 0 : SetActiveSidebarWin(0);
1206 0 : SwRewriter aRewriter;
1207 0 : aRewriter.AddRule(UndoArg1, SW_RES(STR_DELETE_ALL_NOTES) );
1208 0 : mpWrtShell->StartUndo( UNDO_DELETE, &aRewriter );
1209 :
1210 0 : std::vector<const SwFmtFld*> aTmp;
1211 0 : aTmp.reserve( mvPostItFlds.size() );
1212 0 : for(std::list<SwSidebarItem*>::iterator pPostIt = mvPostItFlds.begin(); pPostIt!= mvPostItFlds.end() ; ++pPostIt)
1213 : {
1214 0 : aTmp.push_back( &(*pPostIt)->GetFmtFld() );
1215 : }
1216 0 : for(std::vector<const SwFmtFld*>::iterator i = aTmp.begin(); i != aTmp.end() ; ++i)
1217 : {
1218 0 : mpWrtShell->GotoField( *(*i) );
1219 0 : mpWrtShell->DelRight();
1220 : }
1221 :
1222 0 : mpWrtShell->EndUndo();
1223 0 : PrepareView();
1224 0 : mpWrtShell->EndAllAction();
1225 0 : mbLayout = true;
1226 0 : CalcRects();
1227 0 : LayoutPostIts();
1228 0 : }
1229 0 : void SwPostItMgr::Hide( const OUString& rAuthor )
1230 : {
1231 0 : for(SwSidebarItem_iterator i = mvPostItFlds.begin(); i != mvPostItFlds.end() ; ++i)
1232 : {
1233 0 : if ( (*i)->pPostIt && ((*i)->pPostIt->GetAuthor() == rAuthor) )
1234 : {
1235 0 : (*i)->bShow = false;
1236 0 : (*i)->pPostIt->HideNote();
1237 : }
1238 : }
1239 :
1240 0 : LayoutPostIts();
1241 0 : }
1242 :
1243 0 : void SwPostItMgr::Hide()
1244 : {
1245 0 : for(SwSidebarItem_iterator i = mvPostItFlds.begin(); i != mvPostItFlds.end() ; ++i)
1246 : {
1247 0 : (*i)->bShow = false;
1248 0 : (*i)->pPostIt->HideNote();
1249 : }
1250 0 : }
1251 :
1252 0 : void SwPostItMgr::Show()
1253 : {
1254 0 : for(SwSidebarItem_iterator i = mvPostItFlds.begin(); i != mvPostItFlds.end() ; ++i)
1255 : {
1256 0 : (*i)->bShow = true;
1257 : }
1258 0 : LayoutPostIts();
1259 0 : }
1260 :
1261 0 : void SwPostItMgr::Sort(const short aType)
1262 : {
1263 0 : if (mvPostItFlds.size()>1 )
1264 : {
1265 0 : switch (aType)
1266 : {
1267 : case SORT_POS:
1268 0 : mvPostItFlds.sort(comp_pos);
1269 0 : break;
1270 : }
1271 : }
1272 0 : }
1273 :
1274 0 : SwSidebarWin* SwPostItMgr::GetSidebarWin( const SfxBroadcaster* pBroadcaster) const
1275 : {
1276 0 : for(const_iterator i = mvPostItFlds.begin(); i != mvPostItFlds.end() ; ++i)
1277 : {
1278 0 : if ( (*i)->GetBroadCaster() == pBroadcaster)
1279 0 : return (*i)->pPostIt;
1280 : }
1281 0 : return NULL;
1282 : }
1283 :
1284 0 : sw::annotation::SwAnnotationWin* SwPostItMgr::GetAnnotationWin(const SwPostItField* pFld) const
1285 : {
1286 0 : for(const_iterator i = mvPostItFlds.begin(); i != mvPostItFlds.end() ; ++i)
1287 : {
1288 0 : if ( (*i)->GetFmtFld().GetField() == pFld )
1289 0 : return dynamic_cast<sw::annotation::SwAnnotationWin*>((*i)->pPostIt);
1290 : }
1291 0 : return NULL;
1292 : }
1293 :
1294 0 : SwSidebarWin* SwPostItMgr::GetNextPostIt( sal_uInt16 aDirection,
1295 : SwSidebarWin* aPostIt )
1296 : {
1297 0 : if (mvPostItFlds.size()>1)
1298 : {
1299 0 : for(SwSidebarItem_iterator i = mvPostItFlds.begin(); i != mvPostItFlds.end() ; ++i)
1300 : {
1301 0 : if ( (*i)->pPostIt == aPostIt)
1302 : {
1303 0 : SwSidebarItem_iterator iNextPostIt = i;
1304 0 : if (aDirection == KEY_PAGEUP)
1305 : {
1306 0 : if ( iNextPostIt == mvPostItFlds.begin() )
1307 : {
1308 0 : return NULL;
1309 : }
1310 0 : --iNextPostIt;
1311 : }
1312 : else
1313 : {
1314 0 : ++iNextPostIt;
1315 0 : if ( iNextPostIt == mvPostItFlds.end() )
1316 : {
1317 0 : return NULL;
1318 : }
1319 : }
1320 : // lets quit, we are back at the beginning
1321 0 : if ( (*iNextPostIt)->pPostIt == aPostIt)
1322 0 : return NULL;
1323 0 : return (*iNextPostIt)->pPostIt;
1324 : }
1325 : }
1326 0 : return NULL;
1327 : }
1328 : else
1329 0 : return NULL;
1330 : }
1331 :
1332 0 : long SwPostItMgr::GetNextBorder()
1333 : {
1334 0 : for (unsigned long n=0;n<mPages.size();n++)
1335 : {
1336 0 : for(SwSidebarItem_iterator b = mPages[n]->mList->begin(); b!= mPages[n]->mList->end(); ++b)
1337 : {
1338 0 : if ((*b)->pPostIt == mpActivePostIt)
1339 : {
1340 0 : SwSidebarItem_iterator aNext = b;
1341 0 : ++aNext;
1342 0 : bool bFollow = (aNext == mPages[n]->mList->end()) ? false : (*aNext)->pPostIt->IsFollow();
1343 0 : if ( mPages[n]->bScrollbar || bFollow )
1344 : {
1345 0 : return -1;
1346 : }
1347 : else
1348 : {
1349 : //if this is the last item, return the bottom border otherwise the next item
1350 0 : if (aNext == mPages[n]->mList->end())
1351 0 : return mpEditWin->LogicToPixel(Point(0,mPages[n]->mPageRect.Bottom())).Y() - GetSpaceBetween();
1352 : else
1353 0 : return (*aNext)->pPostIt->GetPosPixel().Y() - GetSpaceBetween();
1354 : }
1355 : }
1356 : }
1357 : }
1358 :
1359 : OSL_FAIL("SwPostItMgr::GetNextBorder(): We have to find a next border here");
1360 0 : return -1;
1361 : }
1362 :
1363 0 : void SwPostItMgr::SetShadowState(const SwPostItField* pFld,bool bCursor)
1364 : {
1365 0 : if (pFld)
1366 : {
1367 0 : if (pFld !=mShadowState.mpShadowFld)
1368 : {
1369 0 : if (mShadowState.mpShadowFld)
1370 : {
1371 : // reset old one if still alive
1372 : // TODO: does not work properly if mouse and cursor was set
1373 : sw::annotation::SwAnnotationWin* pOldPostIt =
1374 0 : GetAnnotationWin(mShadowState.mpShadowFld);
1375 0 : if (pOldPostIt && pOldPostIt->Shadow() && (pOldPostIt->Shadow()->GetShadowState() != SS_EDIT))
1376 0 : pOldPostIt->SetViewState(VS_NORMAL);
1377 : }
1378 : //set new one, if it is not currently edited
1379 0 : sw::annotation::SwAnnotationWin* pNewPostIt = GetAnnotationWin(pFld);
1380 0 : if (pNewPostIt && pNewPostIt->Shadow() && (pNewPostIt->Shadow()->GetShadowState() != SS_EDIT))
1381 : {
1382 0 : pNewPostIt->SetViewState(VS_VIEW);
1383 : //remember our new field
1384 0 : mShadowState.mpShadowFld = pFld;
1385 0 : mShadowState.bCursor = false;
1386 0 : mShadowState.bMouse = false;
1387 : }
1388 : }
1389 0 : if (bCursor)
1390 0 : mShadowState.bCursor = true;
1391 : else
1392 0 : mShadowState.bMouse = true;
1393 : }
1394 : else
1395 : {
1396 0 : if (mShadowState.mpShadowFld)
1397 : {
1398 0 : if (bCursor)
1399 0 : mShadowState.bCursor = false;
1400 : else
1401 0 : mShadowState.bMouse = false;
1402 0 : if (!mShadowState.bCursor && !mShadowState.bMouse)
1403 : {
1404 : // reset old one if still alive
1405 0 : sw::annotation::SwAnnotationWin* pOldPostIt = GetAnnotationWin(mShadowState.mpShadowFld);
1406 0 : if (pOldPostIt && pOldPostIt->Shadow() && (pOldPostIt->Shadow()->GetShadowState() != SS_EDIT))
1407 : {
1408 0 : pOldPostIt->SetViewState(VS_NORMAL);
1409 0 : mShadowState.mpShadowFld = 0;
1410 : }
1411 : }
1412 : }
1413 : }
1414 0 : }
1415 :
1416 0 : void SwPostItMgr::PrepareView(bool bIgnoreCount)
1417 : {
1418 0 : if (!HasNotes() || bIgnoreCount)
1419 : {
1420 0 : mpWrtShell->StartAllAction();
1421 0 : SwRootFrm* pLayout = mpWrtShell->GetLayout();
1422 0 : if ( pLayout )
1423 : SwPostItHelper::setSidebarChanged( pLayout,
1424 0 : mpWrtShell->getIDocumentSettingAccess()->get( IDocumentSettingAccess::BROWSE_MODE ) );
1425 0 : mpWrtShell->EndAllAction();
1426 : }
1427 0 : }
1428 :
1429 0 : bool SwPostItMgr::ShowScrollbar(const unsigned long aPage) const
1430 : {
1431 0 : if (mPages.size() > aPage-1)
1432 0 : return (mPages[aPage-1]->bScrollbar && !mbWaitingForCalcRects);
1433 : else
1434 0 : return false;
1435 : }
1436 :
1437 0 : bool SwPostItMgr::IsHit(const Point &aPointPixel)
1438 : {
1439 0 : if (HasNotes() && ShowNotes())
1440 : {
1441 0 : const Point aPoint = mpEditWin->PixelToLogic(aPointPixel);
1442 0 : const SwRootFrm* pLayout = mpWrtShell->GetLayout();
1443 0 : SwRect aPageFrm;
1444 0 : const unsigned long nPageNum = SwPostItHelper::getPageInfo( aPageFrm, pLayout, aPoint );
1445 0 : if( nPageNum )
1446 : {
1447 0 : Rectangle aRect;
1448 : OSL_ENSURE(mPages.size()>nPageNum-1,"SwPostitMgr:: page container size wrong");
1449 0 : aRect = mPages[nPageNum-1]->eSidebarPosition == sw::sidebarwindows::SIDEBAR_LEFT
1450 0 : ? Rectangle(Point(aPageFrm.Left()-GetSidebarWidth()-GetSidebarBorderWidth(),aPageFrm.Top()),Size(GetSidebarWidth(),aPageFrm.Height()))
1451 0 : : Rectangle( Point(aPageFrm.Right()+GetSidebarBorderWidth(),aPageFrm.Top()) , Size(GetSidebarWidth(),aPageFrm.Height()));
1452 0 : if (aRect.IsInside(aPoint))
1453 : {
1454 : // we hit the note's sidebar
1455 : // lets now test for the arrow area
1456 0 : if (mPages[nPageNum-1]->bScrollbar)
1457 0 : return ScrollbarHit(nPageNum,aPoint);
1458 : else
1459 0 : return false;
1460 : }
1461 : }
1462 : }
1463 0 : return false;
1464 : }
1465 0 : Rectangle SwPostItMgr::GetBottomScrollRect(const unsigned long aPage) const
1466 : {
1467 0 : SwRect aPageRect = mPages[aPage-1]->mPageRect;
1468 0 : Point aPointBottom = mPages[aPage-1]->eSidebarPosition == sw::sidebarwindows::SIDEBAR_LEFT
1469 0 : ? Point(aPageRect.Left() - GetSidebarWidth() - GetSidebarBorderWidth() + mpEditWin->PixelToLogic(Size(2,0)).Width(),aPageRect.Bottom()- mpEditWin->PixelToLogic(Size(0,2+GetSidebarScrollerHeight())).Height())
1470 0 : : Point(aPageRect.Right() + GetSidebarBorderWidth() + mpEditWin->PixelToLogic(Size(2,0)).Width(),aPageRect.Bottom()- mpEditWin->PixelToLogic(Size(0,2+GetSidebarScrollerHeight())).Height());
1471 0 : Size aSize(GetSidebarWidth() - mpEditWin->PixelToLogic(Size(4,0)).Width(), mpEditWin->PixelToLogic(Size(0,GetSidebarScrollerHeight())).Height()) ;
1472 0 : return Rectangle(aPointBottom,aSize);
1473 : }
1474 :
1475 0 : Rectangle SwPostItMgr::GetTopScrollRect(const unsigned long aPage) const
1476 : {
1477 0 : SwRect aPageRect = mPages[aPage-1]->mPageRect;
1478 0 : Point aPointTop = mPages[aPage-1]->eSidebarPosition == sw::sidebarwindows::SIDEBAR_LEFT
1479 0 : ? Point(aPageRect.Left() - GetSidebarWidth() -GetSidebarBorderWidth()+ mpEditWin->PixelToLogic(Size(2,0)).Width(),aPageRect.Top() + mpEditWin->PixelToLogic(Size(0,2)).Height())
1480 0 : : Point(aPageRect.Right() + GetSidebarBorderWidth() + mpEditWin->PixelToLogic(Size(2,0)).Width(),aPageRect.Top() + mpEditWin->PixelToLogic(Size(0,2)).Height());
1481 0 : Size aSize(GetSidebarWidth() - mpEditWin->PixelToLogic(Size(4,0)).Width(), mpEditWin->PixelToLogic(Size(0,GetSidebarScrollerHeight())).Height()) ;
1482 0 : return Rectangle(aPointTop,aSize);
1483 : }
1484 :
1485 : //IMPORTANT: if you change the rects here, also change SwPageFrm::PaintNotesSidebar()
1486 0 : bool SwPostItMgr::ScrollbarHit(const unsigned long aPage,const Point &aPoint)
1487 : {
1488 0 : SwRect aPageRect = mPages[aPage-1]->mPageRect;
1489 0 : Point aPointBottom = mPages[aPage-1]->eSidebarPosition == sw::sidebarwindows::SIDEBAR_LEFT
1490 0 : ? Point(aPageRect.Left() - GetSidebarWidth()-GetSidebarBorderWidth() + mpEditWin->PixelToLogic(Size(2,0)).Width(),aPageRect.Bottom()- mpEditWin->PixelToLogic(Size(0,2+GetSidebarScrollerHeight())).Height())
1491 0 : : Point(aPageRect.Right() + GetSidebarBorderWidth()+ mpEditWin->PixelToLogic(Size(2,0)).Width(),aPageRect.Bottom()- mpEditWin->PixelToLogic(Size(0,2+GetSidebarScrollerHeight())).Height());
1492 :
1493 0 : Point aPointTop = mPages[aPage-1]->eSidebarPosition == sw::sidebarwindows::SIDEBAR_LEFT
1494 0 : ? Point(aPageRect.Left() - GetSidebarWidth()-GetSidebarBorderWidth()+ mpEditWin->PixelToLogic(Size(2,0)).Width(),aPageRect.Top() + mpEditWin->PixelToLogic(Size(0,2)).Height())
1495 0 : : Point(aPageRect.Right()+GetSidebarBorderWidth()+ mpEditWin->PixelToLogic(Size(2,0)).Width(),aPageRect.Top() + mpEditWin->PixelToLogic(Size(0,2)).Height());
1496 :
1497 0 : Rectangle aRectBottom(GetBottomScrollRect(aPage));
1498 0 : Rectangle aRectTop(GetTopScrollRect(aPage));
1499 :
1500 0 : if (aRectBottom.IsInside(aPoint))
1501 : {
1502 0 : if (aPoint.X() < long((aPointBottom.X() + GetSidebarWidth()/3)))
1503 0 : Scroll( GetScrollSize(),aPage);
1504 : else
1505 0 : Scroll( -1*GetScrollSize(), aPage);
1506 0 : return true;
1507 : }
1508 0 : else if (aRectTop.IsInside(aPoint))
1509 : {
1510 0 : if (aPoint.X() < long((aPointTop.X() + GetSidebarWidth()/3*2)))
1511 0 : Scroll(GetScrollSize(), aPage);
1512 : else
1513 0 : Scroll(-1*GetScrollSize(), aPage);
1514 0 : return true;
1515 : }
1516 0 : return false;
1517 : }
1518 :
1519 0 : void SwPostItMgr::CorrectPositions()
1520 : {
1521 0 : if ( mbWaitingForCalcRects || mbLayouting || mvPostItFlds.empty() )
1522 0 : return;
1523 :
1524 : // find first valid note
1525 0 : SwSidebarWin *pFirstPostIt = 0;
1526 0 : for(SwSidebarItem_iterator i = mvPostItFlds.begin(); i != mvPostItFlds.end() ; ++i)
1527 : {
1528 0 : pFirstPostIt = (*i)->pPostIt;
1529 0 : if (pFirstPostIt)
1530 0 : break;
1531 : }
1532 :
1533 : //if we have not found a valid note, forget about it and leave
1534 0 : if (!pFirstPostIt)
1535 0 : return;
1536 :
1537 : // yeah, I know, if this is a left page it could be wrong, but finding the page and the note is probably not even faster than just doing it
1538 : // check, if anchor overlay object exists.
1539 0 : const long aAnchorX = pFirstPostIt->Anchor()
1540 0 : ? mpEditWin->LogicToPixel( Point((long)(pFirstPostIt->Anchor()->GetSixthPosition().getX()),0)).X()
1541 0 : : 0;
1542 0 : const long aAnchorY = pFirstPostIt->Anchor()
1543 0 : ? mpEditWin->LogicToPixel( Point(0,(long)(pFirstPostIt->Anchor()->GetSixthPosition().getY()))).Y() + 1
1544 0 : : 0;
1545 0 : if (Point(aAnchorX,aAnchorY) != pFirstPostIt->GetPosPixel())
1546 : {
1547 0 : long aAnchorPosX = 0;
1548 0 : long aAnchorPosY = 0;
1549 0 : for (unsigned long n=0;n<mPages.size();n++)
1550 : {
1551 0 : for(SwSidebarItem_iterator i = mPages[n]->mList->begin(); i != mPages[n]->mList->end(); ++i)
1552 : {
1553 : // check, if anchor overlay object exists.
1554 0 : if ( (*i)->bShow && (*i)->pPostIt && (*i)->pPostIt->Anchor() )
1555 : {
1556 0 : aAnchorPosX = mPages[n]->eSidebarPosition == sw::sidebarwindows::SIDEBAR_LEFT
1557 0 : ? mpEditWin->LogicToPixel( Point((long)((*i)->pPostIt->Anchor()->GetSeventhPosition().getX()),0)).X()
1558 0 : : mpEditWin->LogicToPixel( Point((long)((*i)->pPostIt->Anchor()->GetSixthPosition().getX()),0)).X();
1559 0 : aAnchorPosY = mpEditWin->LogicToPixel( Point(0,(long)((*i)->pPostIt->Anchor()->GetSixthPosition().getY()))).Y() + 1;
1560 0 : (*i)->pPostIt->SetPosPixel(Point(aAnchorPosX,aAnchorPosY));
1561 : }
1562 : }
1563 : }
1564 : }
1565 : }
1566 :
1567 0 : bool SwPostItMgr::ShowNotes() const
1568 : {
1569 : // we only want to see notes if Options - Writer - View - Notes is ticked
1570 0 : return mpWrtShell->GetViewOptions()->IsPostIts();
1571 : }
1572 :
1573 0 : bool SwPostItMgr::HasNotes() const
1574 : {
1575 0 : return !mvPostItFlds.empty();
1576 : }
1577 :
1578 0 : unsigned long SwPostItMgr::GetSidebarWidth(bool bPx) const
1579 : {
1580 0 : unsigned long aWidth = (unsigned long)(mpWrtShell->GetViewOptions()->GetZoom() * 1.8);
1581 0 : if (bPx)
1582 0 : return aWidth;
1583 : else
1584 0 : return mpEditWin->PixelToLogic(Size( aWidth ,0)).Width();
1585 : }
1586 :
1587 0 : unsigned long SwPostItMgr::GetSidebarBorderWidth(bool bPx) const
1588 : {
1589 0 : if (bPx)
1590 0 : return 2;
1591 : else
1592 0 : return mpEditWin->PixelToLogic(Size(2,0)).Width();
1593 : }
1594 :
1595 0 : unsigned long SwPostItMgr::GetNoteWidth()
1596 : {
1597 0 : return GetSidebarWidth(true);
1598 : }
1599 :
1600 0 : Color SwPostItMgr::GetColorDark(sal_uInt16 aAuthorIndex)
1601 : {
1602 0 : if (!Application::GetSettings().GetStyleSettings().GetHighContrastMode())
1603 : {
1604 : static const Color aArrayNormal[] = {
1605 : COL_AUTHOR1_NORMAL, COL_AUTHOR2_NORMAL, COL_AUTHOR3_NORMAL,
1606 : COL_AUTHOR4_NORMAL, COL_AUTHOR5_NORMAL, COL_AUTHOR6_NORMAL,
1607 0 : COL_AUTHOR7_NORMAL, COL_AUTHOR8_NORMAL, COL_AUTHOR9_NORMAL };
1608 :
1609 0 : return Color( aArrayNormal[ aAuthorIndex % (sizeof( aArrayNormal )/ sizeof( aArrayNormal[0] ))]);
1610 : }
1611 : else
1612 0 : return Color(COL_WHITE);
1613 : }
1614 :
1615 0 : Color SwPostItMgr::GetColorLight(sal_uInt16 aAuthorIndex)
1616 : {
1617 0 : if (!Application::GetSettings().GetStyleSettings().GetHighContrastMode())
1618 : {
1619 : static const Color aArrayLight[] = {
1620 : COL_AUTHOR1_LIGHT, COL_AUTHOR2_LIGHT, COL_AUTHOR3_LIGHT,
1621 : COL_AUTHOR4_LIGHT, COL_AUTHOR5_LIGHT, COL_AUTHOR6_LIGHT,
1622 0 : COL_AUTHOR7_LIGHT, COL_AUTHOR8_LIGHT, COL_AUTHOR9_LIGHT };
1623 :
1624 0 : return Color( aArrayLight[ aAuthorIndex % (sizeof( aArrayLight )/ sizeof( aArrayLight[0] ))]);
1625 : }
1626 : else
1627 0 : return Color(COL_WHITE);
1628 : }
1629 :
1630 0 : Color SwPostItMgr::GetColorAnchor(sal_uInt16 aAuthorIndex)
1631 : {
1632 0 : if (!Application::GetSettings().GetStyleSettings().GetHighContrastMode())
1633 : {
1634 : static const Color aArrayAnchor[] = {
1635 : COL_AUTHOR1_DARK, COL_AUTHOR2_DARK, COL_AUTHOR3_DARK,
1636 : COL_AUTHOR4_DARK, COL_AUTHOR5_DARK, COL_AUTHOR6_DARK,
1637 0 : COL_AUTHOR7_DARK, COL_AUTHOR8_DARK, COL_AUTHOR9_DARK };
1638 :
1639 0 : return Color( aArrayAnchor[ aAuthorIndex % (sizeof( aArrayAnchor ) / sizeof( aArrayAnchor[0] ))]);
1640 : }
1641 : else
1642 0 : return Color(COL_WHITE);
1643 : }
1644 :
1645 0 : void SwPostItMgr::SetActiveSidebarWin( SwSidebarWin* p)
1646 : {
1647 0 : if ( p != mpActivePostIt )
1648 : {
1649 : // we need the temp variable so we can set mpActivePostIt before we call DeactivatePostIt
1650 : // therefore we get a new layout in DOCCHANGED when switching from postit to document,
1651 : // otherwise, GetActivePostIt() would still hold our old postit
1652 0 : SwSidebarWin* pActive = mpActivePostIt;
1653 0 : mpActivePostIt = p;
1654 0 : if (pActive)
1655 : {
1656 0 : pActive->DeactivatePostIt();
1657 0 : mShadowState.mpShadowFld = 0;
1658 : }
1659 0 : if (mpActivePostIt)
1660 : {
1661 0 : mpActivePostIt->GotoPos();
1662 0 : mpView->SetAnnotationMode(true);
1663 0 : mpView->AttrChangedNotify(0);
1664 0 : mpView->SetAnnotationMode(false);
1665 0 : mpActivePostIt->ActivatePostIt();
1666 : }
1667 : }
1668 0 : }
1669 :
1670 0 : IMPL_LINK( SwPostItMgr, CalcHdl, void*, /* pVoid*/ )
1671 : {
1672 0 : mnEventId = 0;
1673 0 : if ( mbLayouting )
1674 : {
1675 : OSL_FAIL("Reentrance problem in Layout Manager!");
1676 0 : mbWaitingForCalcRects = false;
1677 0 : return 0;
1678 : }
1679 :
1680 : // do not change order, even if it would seem so in the first place, we need the calcrects always
1681 0 : if (CalcRects() || mbLayout)
1682 : {
1683 0 : mbLayout = false;
1684 0 : LayoutPostIts();
1685 : }
1686 0 : return 0;
1687 : }
1688 :
1689 0 : void SwPostItMgr::Rescale()
1690 : {
1691 0 : for(std::list<SwSidebarItem*>::iterator i = mvPostItFlds.begin(); i != mvPostItFlds.end() ; ++i)
1692 0 : if ( (*i)->pPostIt )
1693 0 : (*i)->pPostIt->Rescale();
1694 0 : }
1695 :
1696 0 : sal_Int32 SwPostItMgr::GetInitialAnchorDistance() const
1697 : {
1698 0 : const Fraction& f( mpEditWin->GetMapMode().GetScaleY() );
1699 0 : return POSTIT_INITIAL_ANCHOR_DISTANCE * f.GetNumerator() / f.GetDenominator();
1700 : }
1701 :
1702 0 : sal_Int32 SwPostItMgr::GetSpaceBetween() const
1703 : {
1704 0 : const Fraction& f( mpEditWin->GetMapMode().GetScaleY() );
1705 0 : return ( POSTIT_SPACE_BETWEEN ) * f.GetNumerator() / f.GetDenominator();
1706 : }
1707 :
1708 0 : sal_Int32 SwPostItMgr::GetScrollSize() const
1709 : {
1710 0 : const Fraction& f( mpEditWin->GetMapMode().GetScaleY() );
1711 0 : return ( POSTIT_SPACE_BETWEEN + POSTIT_MINIMUMSIZE_WITH_META ) * f.GetNumerator() / f.GetDenominator();
1712 : }
1713 :
1714 0 : sal_Int32 SwPostItMgr::GetMinimumSizeWithMeta() const
1715 : {
1716 0 : const Fraction& f( mpEditWin->GetMapMode().GetScaleY() );
1717 0 : return POSTIT_MINIMUMSIZE_WITH_META * f.GetNumerator() / f.GetDenominator();
1718 : }
1719 :
1720 0 : sal_Int32 SwPostItMgr::GetSidebarScrollerHeight() const
1721 : {
1722 0 : const Fraction& f( mpEditWin->GetMapMode().GetScaleY() );
1723 0 : return POSTIT_SCROLL_SIDEBAR_HEIGHT * f.GetNumerator() / f.GetDenominator();
1724 : }
1725 :
1726 0 : void SwPostItMgr::SetSpellChecking()
1727 : {
1728 0 : for(std::list<SwSidebarItem*>::iterator i = mvPostItFlds.begin(); i != mvPostItFlds.end() ; ++i)
1729 0 : if ( (*i)->pPostIt )
1730 0 : (*i)->pPostIt->SetSpellChecking();
1731 0 : }
1732 :
1733 0 : void SwPostItMgr::SetReadOnlyState()
1734 : {
1735 0 : for(std::list<SwSidebarItem*>::iterator i = mvPostItFlds.begin(); i != mvPostItFlds.end() ; ++i)
1736 0 : if ( (*i)->pPostIt )
1737 0 : (*i)->pPostIt->SetReadonly( mbReadOnly );
1738 0 : }
1739 :
1740 0 : void SwPostItMgr::CheckMetaText()
1741 : {
1742 0 : for(std::list<SwSidebarItem*>::iterator i = mvPostItFlds.begin(); i != mvPostItFlds.end() ; ++i)
1743 0 : if ( (*i)->pPostIt )
1744 0 : (*i)->pPostIt->CheckMetaText();
1745 :
1746 0 : }
1747 :
1748 0 : sal_uInt16 SwPostItMgr::Replace(SvxSearchItem* pItem)
1749 : {
1750 0 : SwSidebarWin* pWin = GetActiveSidebarWin();
1751 0 : sal_uInt16 aResult = pWin->GetOutlinerView()->StartSearchAndReplace( *pItem );
1752 0 : if (!aResult)
1753 0 : SetActiveSidebarWin(0);
1754 0 : return aResult;
1755 : }
1756 :
1757 0 : sal_uInt16 SwPostItMgr::FinishSearchReplace(const ::com::sun::star::util::SearchOptions& rSearchOptions, bool bSrchForward)
1758 : {
1759 0 : SwSidebarWin* pWin = GetActiveSidebarWin();
1760 0 : SvxSearchItem aItem(SID_SEARCH_ITEM );
1761 0 : aItem.SetSearchOptions(rSearchOptions);
1762 0 : aItem.SetBackward(!bSrchForward);
1763 0 : sal_uInt16 aResult = pWin->GetOutlinerView()->StartSearchAndReplace( aItem );
1764 0 : if (!aResult)
1765 0 : SetActiveSidebarWin(0);
1766 0 : return aResult;
1767 : }
1768 :
1769 0 : sal_uInt16 SwPostItMgr::SearchReplace(const SwFmtFld &pFld, const ::com::sun::star::util::SearchOptions& rSearchOptions, bool bSrchForward)
1770 : {
1771 0 : sal_uInt16 aResult = 0;
1772 0 : SwSidebarWin* pWin = GetSidebarWin(&pFld);
1773 0 : if (pWin)
1774 : {
1775 0 : ESelection aOldSelection = pWin->GetOutlinerView()->GetSelection();
1776 0 : if (bSrchForward)
1777 0 : pWin->GetOutlinerView()->SetSelection(ESelection(0,0,0,0));
1778 : else
1779 : pWin->GetOutlinerView()->SetSelection(
1780 0 : ESelection(EE_PARA_MAX_COUNT,EE_TEXTPOS_MAX_COUNT,EE_PARA_MAX_COUNT,EE_TEXTPOS_MAX_COUNT));
1781 0 : SvxSearchItem aItem(SID_SEARCH_ITEM );
1782 0 : aItem.SetSearchOptions(rSearchOptions);
1783 0 : aItem.SetBackward(!bSrchForward);
1784 0 : aResult = pWin->GetOutlinerView()->StartSearchAndReplace( aItem );
1785 0 : if (!aResult)
1786 0 : pWin->GetOutlinerView()->SetSelection(aOldSelection);
1787 : else
1788 : {
1789 0 : SetActiveSidebarWin(pWin);
1790 0 : MakeVisible(pWin);
1791 0 : }
1792 : }
1793 0 : return aResult;
1794 : }
1795 :
1796 0 : void SwPostItMgr::AssureStdModeAtShell()
1797 : {
1798 : // deselect any drawing or frame and leave editing mode
1799 0 : SdrView* pSdrView = mpWrtShell->GetDrawView();
1800 0 : if ( pSdrView && pSdrView->IsTextEdit() )
1801 : {
1802 0 : sal_Bool bLockView = mpWrtShell->IsViewLocked();
1803 0 : mpWrtShell->LockView( sal_True );
1804 0 : mpWrtShell->EndTextEdit();
1805 0 : mpWrtShell->LockView( bLockView );
1806 : }
1807 :
1808 0 : if( mpWrtShell->IsSelFrmMode() || mpWrtShell->IsObjSelected())
1809 : {
1810 0 : mpWrtShell->UnSelectFrm();
1811 0 : mpWrtShell->LeaveSelFrmMode();
1812 0 : mpWrtShell->GetView().LeaveDrawCreate();
1813 0 : mpWrtShell->EnterStdMode();
1814 :
1815 0 : mpWrtShell->DrawSelChanged();
1816 0 : mpView->StopShellTimer();
1817 : }
1818 0 : }
1819 :
1820 0 : bool SwPostItMgr::HasActiveSidebarWin() const
1821 : {
1822 0 : return mpActivePostIt != 0;
1823 : }
1824 :
1825 0 : bool SwPostItMgr::HasActiveAnnotationWin() const
1826 : {
1827 0 : return HasActiveSidebarWin() &&
1828 0 : dynamic_cast<sw::annotation::SwAnnotationWin*>(mpActivePostIt) != 0;
1829 : }
1830 :
1831 0 : void SwPostItMgr::GrabFocusOnActiveSidebarWin()
1832 : {
1833 0 : if ( HasActiveSidebarWin() )
1834 : {
1835 0 : mpActivePostIt->GrabFocus();
1836 : }
1837 0 : }
1838 :
1839 0 : void SwPostItMgr::UpdateDataOnActiveSidebarWin()
1840 : {
1841 0 : if ( HasActiveSidebarWin() )
1842 : {
1843 0 : mpActivePostIt->UpdateData();
1844 : }
1845 0 : }
1846 :
1847 0 : void SwPostItMgr::DeleteActiveSidebarWin()
1848 : {
1849 0 : if ( HasActiveSidebarWin() )
1850 : {
1851 0 : mpActivePostIt->Delete();
1852 : }
1853 0 : }
1854 :
1855 0 : void SwPostItMgr::HideActiveSidebarWin()
1856 : {
1857 0 : if ( HasActiveSidebarWin() )
1858 : {
1859 0 : mpActivePostIt->Hide();
1860 : }
1861 0 : }
1862 :
1863 0 : void SwPostItMgr::ToggleInsModeOnActiveSidebarWin()
1864 : {
1865 0 : if ( HasActiveSidebarWin() )
1866 : {
1867 0 : mpActivePostIt->ToggleInsMode();
1868 : }
1869 0 : }
1870 :
1871 0 : void SwPostItMgr::ConnectSidebarWinToFrm( const SwFrm& rFrm,
1872 : const SwFmtFld& rFmtFld,
1873 : SwSidebarWin& rSidebarWin )
1874 : {
1875 0 : if ( mpFrmSidebarWinContainer == 0 )
1876 : {
1877 0 : mpFrmSidebarWinContainer = new SwFrmSidebarWinContainer();
1878 : }
1879 :
1880 0 : const bool bInserted = mpFrmSidebarWinContainer->insert( rFrm, rFmtFld, rSidebarWin );
1881 0 : if ( bInserted &&
1882 0 : mpWrtShell->GetAccessibleMap() )
1883 : {
1884 0 : mpWrtShell->GetAccessibleMap()->InvalidatePosOrSize( 0, 0, &rSidebarWin, SwRect() );
1885 : }
1886 0 : }
1887 :
1888 0 : void SwPostItMgr::DisconnectSidebarWinFromFrm( const SwFrm& rFrm,
1889 : SwSidebarWin& rSidebarWin )
1890 : {
1891 0 : if ( mpFrmSidebarWinContainer != 0 )
1892 : {
1893 0 : const bool bRemoved = mpFrmSidebarWinContainer->remove( rFrm, rSidebarWin );
1894 0 : if ( bRemoved &&
1895 0 : mpWrtShell->GetAccessibleMap() )
1896 : {
1897 0 : mpWrtShell->GetAccessibleMap()->Dispose( 0, 0, &rSidebarWin );
1898 : }
1899 : }
1900 0 : }
1901 :
1902 0 : bool SwPostItMgr::HasFrmConnectedSidebarWins( const SwFrm& rFrm )
1903 : {
1904 0 : bool bRet( false );
1905 :
1906 0 : if ( mpFrmSidebarWinContainer != 0 )
1907 : {
1908 0 : bRet = !mpFrmSidebarWinContainer->empty( rFrm );
1909 : }
1910 :
1911 0 : return bRet;
1912 : }
1913 :
1914 0 : Window* SwPostItMgr::GetSidebarWinForFrmByIndex( const SwFrm& rFrm,
1915 : const sal_Int32 nIndex )
1916 : {
1917 0 : Window* pSidebarWin( 0 );
1918 :
1919 0 : if ( mpFrmSidebarWinContainer != 0 )
1920 : {
1921 0 : pSidebarWin = mpFrmSidebarWinContainer->get( rFrm, nIndex );
1922 : }
1923 :
1924 0 : return pSidebarWin;
1925 : }
1926 :
1927 0 : void SwPostItMgr::GetAllSidebarWinForFrm( const SwFrm& rFrm,
1928 : std::vector< Window* >* pChildren )
1929 : {
1930 0 : if ( mpFrmSidebarWinContainer != 0 )
1931 : {
1932 0 : mpFrmSidebarWinContainer->getAll( rFrm, pChildren );
1933 : }
1934 0 : }
1935 :
1936 0 : void SwNoteProps::Commit() {}
1937 0 : void SwNoteProps::Notify( const ::com::sun::star::uno::Sequence< OUString >& ) {}
1938 :
1939 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|