Stop leaking all ScPostIt instances.
[LibreOffice.git] / sc / source / ui / cctrl / dpcontrol.cxx
blob5c1d41563b7ef6807bbc2bf3fac95bc0b6622735
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "dpcontrol.hxx"
22 #include <vcl/outdev.hxx>
23 #include <vcl/settings.hxx>
24 #include "global.hxx"
25 #include "scitems.hxx"
26 #include "document.hxx"
27 #include "docpool.hxx"
28 #include "patattr.hxx"
31 ScDPFieldButton::ScDPFieldButton(OutputDevice* pOutDev, const StyleSettings* pStyle, const Fraction* pZoomX, const Fraction* pZoomY, ScDocument* pDoc) :
32 mpDoc(pDoc),
33 mpOutDev(pOutDev),
34 mpStyle(pStyle),
35 mbBaseButton(true),
36 mbPopupButton(false),
37 mbHasHiddenMember(false),
38 mbPopupPressed(false),
39 mbPopupLeft(false)
41 if (pZoomX)
42 maZoomX = *pZoomX;
43 else
44 maZoomX = Fraction(1, 1);
46 if (pZoomY)
47 maZoomY = *pZoomY;
48 else
49 maZoomY = Fraction(1, 1);
52 ScDPFieldButton::~ScDPFieldButton()
56 void ScDPFieldButton::setText(const OUString& rText)
58 maText = rText;
61 void ScDPFieldButton::setBoundingBox(const Point& rPos, const Size& rSize, bool bLayoutRTL)
63 maPos = rPos;
64 maSize = rSize;
65 if (bLayoutRTL)
67 // rPos is the logical-left position, adjust maPos to visual-left (inside the cell border)
68 maPos.X() -= maSize.Width() - 1;
72 void ScDPFieldButton::setDrawBaseButton(bool b)
74 mbBaseButton = b;
77 void ScDPFieldButton::setDrawPopupButton(bool b)
79 mbPopupButton = b;
82 void ScDPFieldButton::setHasHiddenMember(bool b)
84 mbHasHiddenMember = b;
87 void ScDPFieldButton::setPopupPressed(bool b)
89 mbPopupPressed = b;
92 void ScDPFieldButton::setPopupLeft(bool b)
94 mbPopupLeft = b;
97 void ScDPFieldButton::draw()
99 bool bOldMapEnablaed = mpOutDev->IsMapModeEnabled();
100 mpOutDev->EnableMapMode(false);
102 if (mbBaseButton)
104 // Background
105 Rectangle aRect(maPos, maSize);
106 mpOutDev->SetLineColor(mpStyle->GetFaceColor());
107 mpOutDev->SetFillColor(mpStyle->GetFaceColor());
108 mpOutDev->DrawRect(aRect);
110 // Border lines
111 mpOutDev->SetLineColor(mpStyle->GetLightColor());
112 mpOutDev->DrawLine(Point(maPos), Point(maPos.X(), maPos.Y()+maSize.Height()-1));
113 mpOutDev->DrawLine(Point(maPos), Point(maPos.X()+maSize.Width()-1, maPos.Y()));
115 mpOutDev->SetLineColor(mpStyle->GetShadowColor());
116 mpOutDev->DrawLine(Point(maPos.X(), maPos.Y()+maSize.Height()-1),
117 Point(maPos.X()+maSize.Width()-1, maPos.Y()+maSize.Height()-1));
118 mpOutDev->DrawLine(Point(maPos.X()+maSize.Width()-1, maPos.Y()),
119 Point(maPos.X()+maSize.Width()-1, maPos.Y()+maSize.Height()-1));
121 // Field name.
122 // Get the font and size the same way as in scenario selection (lcl_DrawOneFrame in gridwin4.cxx)
123 Font aTextFont( mpStyle->GetAppFont() );
124 if ( mpDoc )
126 // use ScPatternAttr::GetFont only for font size
127 Font aAttrFont;
128 static_cast<const ScPatternAttr&>(mpDoc->GetPool()->GetDefaultItem(ATTR_PATTERN)).
129 GetFont( aAttrFont, SC_AUTOCOL_BLACK, mpOutDev, &maZoomY );
130 aTextFont.SetSize( aAttrFont.GetSize() );
132 mpOutDev->SetFont(aTextFont);
133 mpOutDev->SetTextColor(mpStyle->GetButtonTextColor());
135 Point aTextPos = maPos;
136 long nTHeight = mpOutDev->GetTextHeight();
137 aTextPos.setX(maPos.getX() + 2); // 2 = Margin
138 aTextPos.setY(maPos.getY() + (maSize.Height()-nTHeight)/2);
140 mpOutDev->Push(PUSH_CLIPREGION);
141 mpOutDev->IntersectClipRegion(aRect);
142 mpOutDev->DrawText(aTextPos, maText);
143 mpOutDev->Pop();
146 if (mbPopupButton)
147 drawPopupButton();
149 mpOutDev->EnableMapMode(bOldMapEnablaed);
152 void ScDPFieldButton::getPopupBoundingBox(Point& rPos, Size& rSize) const
154 long nW = maSize.getWidth() / 2;
155 long nH = maSize.getHeight();
156 if (nW > 18)
157 nW = 18;
158 if (nH > 18)
159 nH = 18;
161 // #i114944# AutoFilter button is left-aligned in RTL.
162 // DataPilot button is always right-aligned for now, so text output isn't affected.
163 if (mbPopupLeft)
164 rPos.setX(maPos.getX());
165 else
166 rPos.setX(maPos.getX() + maSize.getWidth() - nW);
167 rPos.setY(maPos.getY() + maSize.getHeight() - nH);
168 rSize.setWidth(nW);
169 rSize.setHeight(nH);
172 void ScDPFieldButton::drawPopupButton()
174 Point aPos;
175 Size aSize;
176 getPopupBoundingBox(aPos, aSize);
178 // Background & outer black border
179 mpOutDev->SetLineColor(COL_BLACK);
180 mpOutDev->SetFillColor(mpStyle->GetFaceColor());
181 mpOutDev->DrawRect(Rectangle(aPos, aSize));
183 if (!mbPopupPressed)
185 // border lines
186 mpOutDev->SetLineColor(mpStyle->GetLightColor());
187 mpOutDev->DrawLine(Point(aPos.X()+1, aPos.Y()+1), Point(aPos.X()+1, aPos.Y()+aSize.Height()-2));
188 mpOutDev->DrawLine(Point(aPos.X()+1, aPos.Y()+1), Point(aPos.X()+aSize.Width()-2, aPos.Y()+1));
190 mpOutDev->SetLineColor(mpStyle->GetShadowColor());
191 mpOutDev->DrawLine(Point(aPos.X()+1, aPos.Y()+aSize.Height()-2),
192 Point(aPos.X()+aSize.Width()-2, aPos.Y()+aSize.Height()-2));
193 mpOutDev->DrawLine(Point(aPos.X()+aSize.Width()-2, aPos.Y()+1),
194 Point(aPos.X()+aSize.Width()-2, aPos.Y()+aSize.Height()-2));
197 // the arrowhead
198 Color aArrowColor = mbHasHiddenMember ? mpStyle->GetHighlightLinkColor() : mpStyle->GetButtonTextColor();
199 mpOutDev->SetLineColor(aArrowColor);
200 mpOutDev->SetFillColor(aArrowColor);
201 Point aCenter(aPos.X() + (aSize.Width() >> 1), aPos.Y() + (aSize.Height() >> 1));
202 Point aPos1, aPos2;
203 aPos1.X() = aCenter.X() - 4;
204 aPos2.X() = aCenter.X() + 4;
205 aPos1.Y() = aCenter.Y() - 3;
206 aPos2.Y() = aCenter.Y() - 3;
208 if (mbPopupPressed)
210 aPos1.X() += 1;
211 aPos2.X() += 1;
212 aPos1.Y() += 1;
213 aPos2.Y() += 1;
218 ++aPos1.X();
219 --aPos2.X();
220 ++aPos1.Y();
221 ++aPos2.Y();
222 mpOutDev->DrawLine(aPos1, aPos2);
224 while (aPos1 != aPos2);
226 if (mbHasHiddenMember)
228 // tiny little box to display in presence of hidden member(s).
229 Point aBoxPos(aPos.X() + aSize.Width() - 5, aPos.Y() + aSize.Height() - 5);
230 if (mbPopupPressed)
232 aBoxPos.X() += 1;
233 aBoxPos.Y() += 1;
235 Size aBoxSize(3, 3);
236 mpOutDev->DrawRect(Rectangle(aBoxPos, aBoxSize));
240 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */