1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  *   Licensed to the Apache Software Foundation (ASF) under one or more
12  *   contributor license agreements. See the NOTICE file distributed
13  *   with this work for additional information regarding copyright
14  *   ownership. The ASF licenses this file to you under the Apache
15  *   License, Version 2.0 (the "License"); you may not use this file
16  *   except in compliance with the License. You may obtain a copy of
17  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <svx/svdoutl.hxx>
21 #include <svx/svdmodel.hxx>
22 #include <svx/svdpage.hxx>
23 #include <svx/svdocapt.hxx>
24 #include <svl/itempool.hxx>
25 #include <vcl/svapp.hxx>
26 #include <vcl/settings.hxx>
27 #include <vcl/window.hxx>
28 
29 #include <notemark.hxx>
30 #include <document.hxx>
31 #include <postit.hxx>
32 
33 #define SC_NOTEMARK_TIME    800
34 #define SC_NOTEMARK_SHORT   70
35 
ScNoteMarker(vcl::Window * pWin,vcl::Window * pRight,vcl::Window * pBottom,vcl::Window * pDiagonal,ScDocument * pD,const ScAddress & aPos,const OUString & rUser,const MapMode & rMap,bool bLeftEdge,bool bForce,bool bKeyboard)36 ScNoteMarker::ScNoteMarker( vcl::Window* pWin, vcl::Window* pRight, vcl::Window* pBottom, vcl::Window* pDiagonal,
37                             ScDocument* pD, const ScAddress& aPos, const OUString& rUser,
38                             const MapMode& rMap, bool bLeftEdge, bool bForce, bool bKeyboard) :
39     m_pWindow( pWin ),
40     m_pRightWin( pRight ),
41     m_pBottomWin( pBottom ),
42     m_pDiagWin( pDiagonal ),
43     m_pDoc( pD ),
44     m_aDocPos( aPos ),
45     m_aUserText( rUser ),
46     m_aMapMode( rMap ),
47     m_bLeft( bLeftEdge ),
48     m_bByKeyboard( bKeyboard ),
49     m_bVisible( false )
50 {
51     Size aSizePixel = m_pWindow->GetOutputSizePixel();
52     if( m_pRightWin )
53         aSizePixel.AdjustWidth(m_pRightWin->GetOutputSizePixel().Width() );
54     if( m_pBottomWin )
55         aSizePixel.AdjustHeight(m_pBottomWin->GetOutputSizePixel().Height() );
56     tools::Rectangle aVisPixel( Point( 0, 0 ), aSizePixel );
57     m_aVisRect = m_pWindow->PixelToLogic( aVisPixel, m_aMapMode );
58 
59     m_aTimer.SetInvokeHandler( LINK( this, ScNoteMarker, TimeHdl ) );
60     m_aTimer.SetTimeout( bForce ? SC_NOTEMARK_SHORT : SC_NOTEMARK_TIME );
61     m_aTimer.Start();
62 }
63 
~ScNoteMarker()64 ScNoteMarker::~ScNoteMarker()
65 {
66     if (m_pModel)
67         m_xObject.release();     // deleting pModel also deletes the SdrCaptionObj
68 
69     InvalidateWin();
70 
71     m_pModel.reset();
72 }
73 
IMPL_LINK_NOARG(ScNoteMarker,TimeHdl,Timer *,void)74 IMPL_LINK_NOARG(ScNoteMarker, TimeHdl, Timer *, void)
75 {
76     if (!m_bVisible)
77     {
78         m_pModel.reset( new SdrModel() );
79         m_pModel->SetScaleUnit(MapUnit::Map100thMM);
80         SfxItemPool& rPool = m_pModel->GetItemPool();
81         rPool.SetDefaultMetric(MapUnit::Map100thMM);
82         rPool.FreezeIdRanges();
83 
84         OutputDevice* pPrinter = m_pDoc->GetRefDevice();
85         if (pPrinter)
86         {
87             // On the outliner of the draw model also the printer is set as RefDevice,
88             // and it should look uniform.
89             Outliner& rOutliner = m_pModel->GetDrawOutliner();
90             rOutliner.SetRefDevice(pPrinter);
91         }
92 
93         if( rtl::Reference<SdrPage> pPage = m_pModel->AllocPage( false ) )
94 
95         {
96             m_xObject = ScNoteUtil::CreateTempCaption( *m_pDoc, m_aDocPos, *pPage, m_aUserText, m_aVisRect, m_bLeft );
97             if( m_xObject )
98             {
99                 // Here, SyncForGrid and GetGridOffset was used with the comment:
100                 // // Need to include grid offset: GetCurrentBoundRect is removing it
101                 // // but we need to know actual rect position
102                 // This is no longer true - SdrObject::RecalcBoundRect() uses the
103                 // GetViewContact().getViewIndependentPrimitive2DContainer()) call
104                 // that now by default adds the eventually needed GridOffset. Thus
105                 // I have removed that adaptation stuff.
106                 m_aRect = m_xObject->GetCurrentBoundRect();
107             }
108 
109             // Insert page so that the model recognise it and also deleted
110             m_pModel->InsertPage( pPage.get() );
111 
112         }
113         m_bVisible = true;
114     }
115 
116     Draw();
117 }
118 
lcl_DrawWin(const SdrObject * pObject,vcl::RenderContext * pWindow,const MapMode & rMap)119 static void lcl_DrawWin( const SdrObject* pObject, vcl::RenderContext* pWindow, const MapMode& rMap )
120 {
121     MapMode aOld = pWindow->GetMapMode();
122     pWindow->SetMapMode( rMap );
123 
124     DrawModeFlags nOldDrawMode = pWindow->GetDrawMode();
125     if ( Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
126     {
127         pWindow->SetDrawMode( nOldDrawMode | DrawModeFlags::SettingsLine | DrawModeFlags::SettingsFill |
128                             DrawModeFlags::SettingsText | DrawModeFlags::SettingsGradient );
129     }
130 
131     pObject->SingleObjectPainter( *pWindow ); // #110094#-17
132 
133     pWindow->SetDrawMode( nOldDrawMode );
134     pWindow->SetMapMode( aOld );
135 }
136 
lcl_MoveMapMode(const MapMode & rMap,const Size & rMove)137 static MapMode lcl_MoveMapMode( const MapMode& rMap, const Size& rMove )
138 {
139     MapMode aNew = rMap;
140     Point aOrigin = aNew.GetOrigin();
141     aOrigin.AdjustX( -(rMove.Width()) );
142     aOrigin.AdjustY( -rMove.Height() );
143     aNew.SetOrigin(aOrigin);
144     return aNew;
145 }
146 
Draw()147 void ScNoteMarker::Draw()
148 {
149     if ( !(m_xObject && m_bVisible) )
150         return;
151 
152     lcl_DrawWin( m_xObject.get(), m_pWindow->GetOutDev(), m_aMapMode );
153 
154     if ( m_pRightWin || m_pBottomWin )
155     {
156         Size aWinSize = m_pWindow->PixelToLogic( m_pWindow->GetOutputSizePixel(), m_aMapMode );
157         if ( m_pRightWin )
158             lcl_DrawWin( m_xObject.get(), m_pRightWin->GetOutDev(),
159                             lcl_MoveMapMode( m_aMapMode, Size( aWinSize.Width(), 0 ) ) );
160         if ( m_pBottomWin )
161             lcl_DrawWin( m_xObject.get(), m_pBottomWin->GetOutDev(),
162                             lcl_MoveMapMode( m_aMapMode, Size( 0, aWinSize.Height() ) ) );
163         if ( m_pDiagWin )
164             lcl_DrawWin( m_xObject.get(), m_pDiagWin->GetOutDev(), lcl_MoveMapMode( m_aMapMode, aWinSize ) );
165     }
166 }
167 
InvalidateWin()168 void ScNoteMarker::InvalidateWin()
169 {
170     if (!m_bVisible)
171         return;
172 
173     // Extend the invalidated rectangle by 1 pixel in each direction in case AA would slightly
174     // paint outside the nominal area.
175     tools::Rectangle aRect(m_aRect);
176     const Size aPixelSize = m_pWindow->PixelToLogic(Size(1, 1));
177     aRect.AdjustLeft(-aPixelSize.getWidth());
178     aRect.AdjustTop(-aPixelSize.getHeight());
179     aRect.AdjustRight(aPixelSize.getWidth());
180     aRect.AdjustBottom(aPixelSize.getHeight());
181 
182     m_pWindow->Invalidate( OutputDevice::LogicToLogic(aRect, m_aMapMode, m_pWindow->GetMapMode()) );
183 
184     if ( !(m_pRightWin || m_pBottomWin) )
185         return;
186 
187     Size aWinSize = m_pWindow->PixelToLogic( m_pWindow->GetOutputSizePixel(), m_aMapMode );
188     if ( m_pRightWin )
189         m_pRightWin->Invalidate( OutputDevice::LogicToLogic(aRect,
190                                 lcl_MoveMapMode( m_aMapMode, Size( aWinSize.Width(), 0 ) ),
191                                 m_pRightWin->GetMapMode()) );
192     if ( m_pBottomWin )
193         m_pBottomWin->Invalidate( OutputDevice::LogicToLogic(aRect,
194                                 lcl_MoveMapMode( m_aMapMode, Size( 0, aWinSize.Height() ) ),
195                                 m_pBottomWin->GetMapMode()) );
196     if ( m_pDiagWin )
197         m_pDiagWin->Invalidate( OutputDevice::LogicToLogic(aRect,
198                                 lcl_MoveMapMode( m_aMapMode, aWinSize ),
199                                 m_pDiagWin->GetMapMode()) );
200 }
201 
202 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
203