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