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