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