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 : #include <vcl/bitmap.hxx>
21 : #include <vcl/builder.hxx>
22 : #include <vcl/settings.hxx>
23 : #include <editeng/frmdiritem.hxx>
24 : #include <svx/pageitem.hxx>
25 : #include <svx/pagectrl.hxx>
26 : #include <editeng/boxitem.hxx>
27 : #include <algorithm>
28 : #include <basegfx/matrix/b2dhommatrix.hxx>
29 : #include <drawinglayer/geometry/viewinformation2d.hxx>
30 : #include <drawinglayer/processor2d/processor2dtools.hxx>
31 : #include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
32 : #include <basegfx/polygon/b2dpolygontools.hxx>
33 :
34 : #define CELL_WIDTH 1600L
35 : #define CELL_HEIGHT 800L
36 :
37 0 : SvxPageWindow::SvxPageWindow(vcl::Window* pParent)
38 : : Window(pParent),
39 : aWinSize(),
40 : aSize(),
41 :
42 : nTop(0),
43 : nBottom(0),
44 : nLeft(0),
45 : nRight(0),
46 :
47 : //UUUU
48 : pBorder(0),
49 : bResetBackground(false),
50 : bFrameDirection(false),
51 : nFrameDirection(0),
52 :
53 : nHdLeft(0),
54 : nHdRight(0),
55 : nHdDist(0),
56 : nHdHeight(0),
57 :
58 : pHdBorder(0),
59 : nFtLeft(0),
60 : nFtRight(0),
61 : nFtDist(0),
62 : nFtHeight(0),
63 :
64 : pFtBorder(0),
65 :
66 : maHeaderFillAttributes(),
67 : maFooterFillAttributes(),
68 : maPageFillAttributes(),
69 :
70 : bFooter(false),
71 : bHeader(false),
72 : bTable(false),
73 : bHorz(false),
74 : bVert(false),
75 : eUsage(SVX_PAGE_ALL),
76 :
77 : aLeftText(),
78 0 : aRightText()
79 : {
80 : // Count in Twips by default
81 0 : SetMapMode(MapMode(MAP_TWIP));
82 0 : aWinSize = GetOptimalSize();
83 0 : aWinSize.Height() -= 4;
84 0 : aWinSize.Width() -= 4;
85 :
86 0 : aWinSize = PixelToLogic(aWinSize);
87 0 : SetBackground();
88 0 : }
89 :
90 0 : SvxPageWindow::~SvxPageWindow()
91 : {
92 0 : delete pHdBorder;
93 0 : delete pFtBorder;
94 0 : }
95 :
96 0 : extern "C" SAL_DLLPUBLIC_EXPORT vcl::Window* SAL_CALL makeSvxPageWindow(vcl::Window *pParent, VclBuilder::stringmap &)
97 : {
98 0 : return new SvxPageWindow(pParent);
99 : }
100 :
101 :
102 :
103 0 : void SvxPageWindow::Paint(const Rectangle&)
104 : {
105 0 : Fraction aXScale(aWinSize.Width(),std::max((long)(aSize.Width() * 2 + aSize.Width() / 8),1L));
106 0 : Fraction aYScale(aWinSize.Height(),std::max(aSize.Height(),1L));
107 0 : MapMode aMapMode(GetMapMode());
108 :
109 0 : if(aYScale < aXScale)
110 : {
111 0 : aMapMode.SetScaleX(aYScale);
112 0 : aMapMode.SetScaleY(aYScale);
113 : }
114 : else
115 : {
116 0 : aMapMode.SetScaleX(aXScale);
117 0 : aMapMode.SetScaleY(aXScale);
118 : }
119 0 : SetMapMode(aMapMode);
120 0 : Size aSz(PixelToLogic(GetSizePixel()));
121 0 : long nYPos = (aSz.Height() - aSize.Height()) / 2;
122 :
123 0 : if(eUsage == SVX_PAGE_ALL)
124 : {
125 : // all pages are equal -> draw one page
126 0 : if (aSize.Width() > aSize.Height())
127 : {
128 : // Draw Landscape page of the same size
129 0 : Fraction aX = aMapMode.GetScaleX();
130 0 : Fraction aY = aMapMode.GetScaleY();
131 0 : Fraction a2(1.5);
132 0 : aX *= a2;
133 0 : aY *= a2;
134 0 : aMapMode.SetScaleX(aX);
135 0 : aMapMode.SetScaleY(aY);
136 0 : SetMapMode(aMapMode);
137 0 : aSz = PixelToLogic(GetSizePixel());
138 0 : nYPos = (aSz.Height() - aSize.Height()) / 2;
139 0 : long nXPos = (aSz.Width() - aSize.Width()) / 2;
140 0 : DrawPage(Point(nXPos,nYPos),true,true);
141 : }
142 : else
143 : // Portrait
144 0 : DrawPage(Point((aSz.Width() - aSize.Width()) / 2,nYPos),true,true);
145 : }
146 : else
147 : {
148 : // Left and right page are different -> draw two pages if possible
149 0 : DrawPage(Point(0,nYPos),false,(eUsage & SVX_PAGE_LEFT) != 0);
150 0 : DrawPage(Point(aSize.Width() + aSize.Width() / 8,nYPos),true,
151 0 : (eUsage & SVX_PAGE_RIGHT) != 0);
152 0 : }
153 0 : }
154 :
155 0 : void SvxPageWindow::DrawPage(const Point& rOrg, const bool bSecond, const bool bEnabled)
156 : {
157 0 : const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
158 0 : const Color& rFieldColor = rStyleSettings.GetFieldColor();
159 0 : const Color& rFieldTextColor = rStyleSettings.GetFieldTextColor();
160 0 : const Color& rDisableColor = rStyleSettings.GetDisableColor();
161 0 : const Color& rDlgColor = rStyleSettings.GetDialogColor();
162 :
163 : // background
164 0 : if(!bSecond || bResetBackground)
165 : {
166 0 : SetLineColor(Color(COL_TRANSPARENT));
167 0 : SetFillColor(rDlgColor);
168 0 : Size winSize(GetOutputSize());
169 0 : DrawRect(Rectangle(Point(0,0),winSize));
170 :
171 0 : if(bResetBackground)
172 0 : bResetBackground = false;
173 : }
174 0 : SetLineColor(rFieldTextColor);
175 : // Shadow
176 0 : Size aTempSize = aSize;
177 : // Page
178 0 : if(!bEnabled)
179 : {
180 0 : SetFillColor(rDisableColor);
181 0 : DrawRect(Rectangle(rOrg,aTempSize));
182 0 : return;
183 : }
184 0 : SetFillColor(rFieldColor);
185 0 : DrawRect(Rectangle(rOrg,aTempSize));
186 :
187 0 : long nL = nLeft;
188 0 : long nR = nRight;
189 :
190 0 : if(eUsage == SVX_PAGE_MIRROR && !bSecond)
191 : {
192 : // turn for mirrored
193 0 : nL = nRight;
194 0 : nR = nLeft;
195 : }
196 :
197 0 : Rectangle aRect;
198 :
199 0 : aRect.Left() = rOrg.X() + nL;
200 0 : aRect.Right() = rOrg.X() + aTempSize.Width() - nR;
201 0 : aRect.Top() = rOrg.Y() + nTop;
202 0 : aRect.Bottom() = rOrg.Y() + aTempSize.Height() - nBottom;
203 :
204 0 : Rectangle aHdRect(aRect);
205 0 : Rectangle aFtRect(aRect);
206 :
207 0 : if(bHeader || bFooter)
208 : {
209 : //UUUU Header and/or footer used
210 0 : const Color aLineColor(GetLineColor());
211 :
212 : //UUUU draw PageFill first and on the whole page, no outline
213 0 : SetLineColor();
214 0 : drawFillAttributes(maPageFillAttributes, aRect, aRect);
215 0 : SetLineColor(aLineColor);
216 :
217 0 : if(bHeader)
218 : {
219 : // show headers if possible
220 0 : aHdRect.Left() += nHdLeft;
221 0 : aHdRect.Right() -= nHdRight;
222 0 : aHdRect.Bottom() = aRect.Top() + nHdHeight;
223 0 : aRect.Top() += nHdHeight + nHdDist;
224 :
225 : // draw header over PageFill, plus outline
226 0 : drawFillAttributes(maHeaderFillAttributes, aHdRect, aHdRect);
227 : }
228 :
229 0 : if(bFooter)
230 : {
231 : // show footer if possible
232 0 : aFtRect.Left() += nFtLeft;
233 0 : aFtRect.Right() -= nFtRight;
234 0 : aFtRect.Top() = aRect.Bottom() - nFtHeight;
235 0 : aRect.Bottom() -= nFtHeight + nFtDist;
236 :
237 : // draw footer over PageFill, plus outline
238 0 : drawFillAttributes(maFooterFillAttributes, aFtRect, aFtRect);
239 : }
240 :
241 : // draw page's reduced outline, only outline
242 0 : drawFillAttributes(drawinglayer::attribute::SdrAllFillAttributesHelperPtr(), aRect, aRect);
243 : }
244 : else
245 : {
246 : //UUUU draw PageFill and outline
247 0 : drawFillAttributes(maPageFillAttributes, aRect, aRect);
248 : }
249 :
250 0 : if(bFrameDirection && !bTable)
251 : {
252 0 : Point aPos;
253 0 : vcl::Font aFont(GetFont());
254 0 : const Size aSaveSize = aFont.GetSize();
255 0 : Size aDrawSize(0,aRect.GetHeight() / 6);
256 0 : aFont.SetSize(aDrawSize);
257 0 : SetFont(aFont);
258 0 : OUString sText("ABC");
259 0 : Point aMove(1, GetTextHeight());
260 0 : sal_Unicode cArrow = 0x2193;
261 0 : long nAWidth = GetTextWidth(sText.copy(0,1));
262 0 : switch(nFrameDirection)
263 : {
264 : case FRMDIR_HORI_LEFT_TOP:
265 0 : aPos = aRect.TopLeft();
266 0 : aPos.X() += PixelToLogic(Point(1,1)).X();
267 0 : aMove.Y() = 0;
268 0 : cArrow = 0x2192;
269 0 : break;
270 : case FRMDIR_HORI_RIGHT_TOP:
271 0 : aPos = aRect.TopRight();
272 0 : aPos.X() -= nAWidth;
273 0 : aMove.Y() = 0;
274 0 : aMove.X() *= -1;
275 0 : cArrow = 0x2190;
276 0 : break;
277 : case FRMDIR_VERT_TOP_LEFT:
278 0 : aPos = aRect.TopLeft();
279 0 : aPos.X() += PixelToLogic(Point(1,1)).X();
280 0 : aMove.X() = 0;
281 0 : break;
282 : case FRMDIR_VERT_TOP_RIGHT:
283 0 : aPos = aRect.TopRight();
284 0 : aPos.X() -= nAWidth;
285 0 : aMove.X() = 0;
286 0 : break;
287 : }
288 0 : sText += OUString(cArrow);
289 0 : for(sal_uInt16 i = 0; i < sText.getLength(); i++)
290 : {
291 0 : OUString sDraw(sText.copy(i,1));
292 0 : long nHDiff = 0;
293 0 : long nCharWidth = GetTextWidth(sDraw);
294 0 : bool bHorizontal = 0 == aMove.Y();
295 0 : if(!bHorizontal)
296 : {
297 0 : nHDiff = (nAWidth - nCharWidth) / 2;
298 0 : aPos.X() += nHDiff;
299 : }
300 0 : DrawText(aPos,sDraw);
301 0 : if(bHorizontal)
302 : {
303 0 : aPos.X() += aMove.X() < 0 ? -nCharWidth : nCharWidth;
304 : }
305 : else
306 : {
307 0 : aPos.X() -= nHDiff;
308 0 : aPos.Y() += aMove.Y();
309 : }
310 0 : }
311 0 : aFont.SetSize(aSaveSize);
312 0 : SetFont(aFont);
313 :
314 : }
315 0 : if(bTable)
316 : {
317 : // Paint Table, if necessary center it
318 0 : SetLineColor(Color(COL_LIGHTGRAY));
319 :
320 0 : long nW = aRect.GetWidth(),nH = aRect.GetHeight();
321 0 : long nTW = CELL_WIDTH * 3,nTH = CELL_HEIGHT * 3;
322 0 : long _nLeft = bHorz ? aRect.Left() + ((nW - nTW) / 2) : aRect.Left();
323 0 : long _nTop = bVert ? aRect.Top() + ((nH - nTH) / 2) : aRect.Top();
324 0 : Rectangle aCellRect(Point(_nLeft,_nTop),Size(CELL_WIDTH,CELL_HEIGHT));
325 :
326 0 : for(sal_uInt16 i = 0; i < 3; ++i)
327 : {
328 0 : aCellRect.Left() = _nLeft;
329 0 : aCellRect.Right() = _nLeft + CELL_WIDTH;
330 0 : if(i > 0)
331 0 : aCellRect.Move(0,CELL_HEIGHT);
332 :
333 0 : for(sal_uInt16 j = 0; j < 3; ++j)
334 : {
335 0 : if(j > 0)
336 0 : aCellRect.Move(CELL_WIDTH,0);
337 0 : DrawRect(aCellRect);
338 : }
339 : }
340 : }
341 : }
342 :
343 : //UUUU
344 0 : void SvxPageWindow::drawFillAttributes(
345 : const drawinglayer::attribute::SdrAllFillAttributesHelperPtr& rFillAttributes,
346 : const Rectangle& rPaintRange,
347 : const Rectangle& rDefineRange)
348 : {
349 : const basegfx::B2DRange aPaintRange(
350 0 : rPaintRange.Left(),
351 0 : rPaintRange.Top(),
352 0 : rPaintRange.Right(),
353 0 : rPaintRange.Bottom());
354 :
355 0 : if(!aPaintRange.isEmpty() &&
356 0 : !basegfx::fTools::equalZero(aPaintRange.getWidth()) &&
357 0 : !basegfx::fTools::equalZero(aPaintRange.getHeight()))
358 : {
359 : const basegfx::B2DRange aDefineRange(
360 0 : rDefineRange.Left(),
361 0 : rDefineRange.Top(),
362 0 : rDefineRange.Right(),
363 0 : rDefineRange.Bottom());
364 :
365 : // prepare primitive sequence
366 0 : drawinglayer::primitive2d::Primitive2DSequence aSequence;
367 :
368 : // create fill geometry if there is something to fill
369 0 : if(rFillAttributes.get() && rFillAttributes->isUsed())
370 : {
371 : aSequence = rFillAttributes->getPrimitive2DSequence(
372 : aPaintRange,
373 0 : aDefineRange);
374 : }
375 :
376 : // create line geometry if a LineColor is set at the target device
377 0 : if(IsLineColor())
378 : {
379 : const drawinglayer::primitive2d::Primitive2DReference xOutline(
380 : new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(
381 : basegfx::tools::createPolygonFromRect(aPaintRange),
382 0 : GetLineColor().getBColor()));
383 :
384 : drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(
385 : aSequence,
386 0 : xOutline);
387 : }
388 :
389 : // draw that if we have something to draw
390 0 : if(aSequence.getLength())
391 : {
392 : const drawinglayer::geometry::ViewInformation2D aViewInformation2D(
393 : basegfx::B2DHomMatrix(),
394 : GetViewTransformation(),
395 : aPaintRange,
396 : 0,
397 : 0.0,
398 0 : com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >());
399 : drawinglayer::processor2d::BaseProcessor2D* pProcessor = drawinglayer::processor2d::createProcessor2DFromOutputDevice(
400 : *this,
401 0 : aViewInformation2D);
402 :
403 0 : if(pProcessor)
404 : {
405 0 : pProcessor->process(aSequence);
406 :
407 0 : delete pProcessor;
408 0 : }
409 0 : }
410 : }
411 0 : }
412 :
413 :
414 :
415 0 : void SvxPageWindow::SetBorder(const SvxBoxItem& rNew)
416 : {
417 0 : delete pBorder;
418 0 : pBorder = new SvxBoxItem(rNew);
419 0 : }
420 :
421 :
422 :
423 0 : void SvxPageWindow::SetHdBorder(const SvxBoxItem& rNew)
424 : {
425 0 : delete pHdBorder;
426 0 : pHdBorder = new SvxBoxItem(rNew);
427 0 : }
428 :
429 :
430 0 : void SvxPageWindow::SetFtBorder(const SvxBoxItem& rNew)
431 : {
432 0 : delete pFtBorder;
433 0 : pFtBorder = new SvxBoxItem(rNew);
434 0 : }
435 :
436 0 : void SvxPageWindow::EnableFrameDirection(bool bEnable)
437 : {
438 0 : bFrameDirection = bEnable;
439 0 : }
440 :
441 0 : void SvxPageWindow::SetFrameDirection(sal_Int32 nDirection)
442 : {
443 0 : nFrameDirection = nDirection;
444 0 : }
445 :
446 0 : void SvxPageWindow::ResetBackground()
447 : {
448 0 : bResetBackground = true;
449 0 : }
450 :
451 0 : Size SvxPageWindow::GetOptimalSize() const
452 : {
453 0 : return LogicToPixel(Size(75, 46), MapMode(MAP_APPFONT));
454 594 : }
455 :
456 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|