xref: /trunk/main/svx/source/dialog/pagectrl.cxx (revision 56b35d86)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 // MARKER(update_precomp.py): autogen include statement, do not remove
23 #include "precompiled_svx.hxx"
24 
25 #include <vcl/bitmap.hxx>
26 #include <editeng/frmdiritem.hxx>
27 #include <svx/pageitem.hxx>
28 #include <svx/pagectrl.hxx>
29 #include <editeng/boxitem.hxx>
30 #include <algorithm>
31 #include <basegfx/matrix/b2dhommatrix.hxx>
32 #include <drawinglayer/geometry/viewinformation2d.hxx>
33 #include <drawinglayer/processor2d/processor2dtools.hxx>
34 #include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
35 #include <basegfx/polygon/b2dpolygontools.hxx>
36 
37 // STATIC DATA -----------------------------------------------------------
38 
39 #define CELL_WIDTH		1600L
40 #define CELL_HEIGHT		 800L
41 
42 // class SvxPageWindow ---------------------------------------------------
43 
SvxPageWindow(Window * pParent,const ResId & rId)44 SvxPageWindow::SvxPageWindow(Window* pParent,const ResId& rId)
45 : Window(pParent,rId),
46     aWinSize(),
47     aSize(),
48 
49     nTop(0),
50     nBottom(0),
51     nLeft(0),
52     nRight(0),
53 
54     //UUUU
55     pBorder(0),
56     bResetBackground(sal_False),
57     bFrameDirection(sal_False),
58     nFrameDirection(0),
59 
60     nHdLeft(0),
61     nHdRight(0),
62     nHdDist(0),
63     nHdHeight(0),
64 
65     pHdBorder(0),
66     nFtLeft(0),
67     nFtRight(0),
68     nFtDist(0),
69     nFtHeight(0),
70 
71     pFtBorder(0),
72 
73     maHeaderFillAttributes(),
74     maFooterFillAttributes(),
75     maPageFillAttributes(),
76 
77     bFooter(sal_False),
78     bHeader(sal_False),
79     bTable(sal_False),
80     bHorz(sal_False),
81     bVert(sal_False),
82     eUsage(SVX_PAGE_ALL),
83 
84     aLeftText(),
85     aRightText()
86 
87 {
88     // defaultmaessing in Twips rechnen
89     SetMapMode(MapMode(MAP_TWIP));
90     aWinSize = GetOutputSizePixel();
91     aWinSize.Height() -= 4;
92     aWinSize.Width() -= 4;
93 
94     aWinSize = PixelToLogic(aWinSize);
95     SetBackground();
96 }
97 
98 // -----------------------------------------------------------------------
99 
~SvxPageWindow()100 SvxPageWindow::~SvxPageWindow()
101 {
102     delete pHdBorder;
103     delete pFtBorder;
104 }
105 
106 // -----------------------------------------------------------------------
107 
Paint(const Rectangle &)108 void __EXPORT SvxPageWindow::Paint(const Rectangle&)
109 {
110     Fraction aXScale(aWinSize.Width(),std::max((long)(aSize.Width() * 2 + aSize.Width() / 8),1L));
111     Fraction aYScale(aWinSize.Height(),std::max(aSize.Height(),1L));
112     MapMode aMapMode(GetMapMode());
113 
114     if(aYScale < aXScale)
115     {
116         aMapMode.SetScaleX(aYScale);
117         aMapMode.SetScaleY(aYScale);
118     }
119     else
120     {
121         aMapMode.SetScaleX(aXScale);
122         aMapMode.SetScaleY(aXScale);
123     }
124     SetMapMode(aMapMode);
125     Size aSz(PixelToLogic(GetSizePixel()));
126     long nYPos = (aSz.Height() - aSize.Height()) / 2;
127 
128     if(eUsage == SVX_PAGE_ALL)
129     {
130         // alle Seiten gleich -> eine Seite malen
131         if(aSize.Width() > aSize.Height())
132         {
133             // Querformat in gleicher Gr"osse zeichnen
134             Fraction aX = aMapMode.GetScaleX();
135             Fraction aY = aMapMode.GetScaleY();
136             Fraction a2(1.5);
137             aX *= a2;
138             aY *= a2;
139             aMapMode.SetScaleX(aX);
140             aMapMode.SetScaleY(aY);
141             SetMapMode(aMapMode);
142             aSz = PixelToLogic(GetSizePixel());
143             nYPos = (aSz.Height() - aSize.Height()) / 2;
144             long nXPos = (aSz.Width() - aSize.Width()) / 2;
145             DrawPage(Point(nXPos,nYPos),sal_True,sal_True);
146         }
147         else
148             // Hochformat
149             DrawPage(Point((aSz.Width() - aSize.Width()) / 2,nYPos),sal_True,sal_True);
150     }
151     else
152     {
153         // Linke und rechte Seite unterschiedlich -> ggf. zwei Seiten malen
154         DrawPage(Point(0,nYPos),sal_False,(sal_Bool)(eUsage & SVX_PAGE_LEFT));
155         DrawPage(Point(aSize.Width() + aSize.Width() / 8,nYPos),sal_True,
156             (sal_Bool)(eUsage & SVX_PAGE_RIGHT));
157     }
158 }
159 
160 // -----------------------------------------------------------------------
DrawPage(const Point & rOrg,const sal_Bool bSecond,const sal_Bool bEnabled)161 void SvxPageWindow::DrawPage(const Point& rOrg,const sal_Bool bSecond,const sal_Bool bEnabled)
162 {
163     const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
164     const Color& rFieldColor = rStyleSettings.GetFieldColor();
165     const Color& rFieldTextColor = rStyleSettings.GetFieldTextColor();
166     const Color& rDisableColor = rStyleSettings.GetDisableColor();
167     const Color& rDlgColor = rStyleSettings.GetDialogColor();
168 
169     // background
170     if(!bSecond || bResetBackground)
171     {
172         SetLineColor(Color(COL_TRANSPARENT));
173         SetFillColor(rDlgColor);
174         Size winSize(GetOutputSize());
175         DrawRect(Rectangle(Point(0,0),winSize));
176 
177         if(bResetBackground)
178             bResetBackground = sal_False;
179     }
180     SetLineColor(rFieldTextColor);
181     // Schatten
182     Size aTempSize = aSize;
183     // Seite
184     if(!bEnabled)
185     {
186         SetFillColor(rDisableColor);
187         DrawRect(Rectangle(rOrg,aTempSize));
188         return;
189     }
190     SetFillColor(rFieldColor);
191     DrawRect(Rectangle(rOrg,aTempSize));
192 
193     // Border Top Bottom Left Right
194     Point aBegin(rOrg);
195     Point aEnd(rOrg);
196 
197     long nL = nLeft;
198     long nR = nRight;
199 
200     if(eUsage == SVX_PAGE_MIRROR && !bSecond)
201     {
202         // f"ur gespiegelt drehen
203         nL = nRight;
204         nR = nLeft;
205     }
206 
207     Rectangle aRect;
208 
209     aRect.Left() = rOrg.X() + nL;
210     aRect.Right() = rOrg.X() + aTempSize.Width() - nR;
211     aRect.Top() = rOrg.Y() + nTop;
212     aRect.Bottom() = rOrg.Y() + aTempSize.Height() - nBottom;
213 
214     Rectangle aHdRect(aRect);
215     Rectangle aFtRect(aRect);
216 
217     if(bHeader || bFooter)
218     {
219         //UUUU Header and/or footer used
220         const Color aLineColor(GetLineColor());
221 
222         //UUUU draw PageFill first and on the whole page, no outline
223         SetLineColor();
224         drawFillAttributes(maPageFillAttributes, aRect, aRect);
225         SetLineColor(aLineColor);
226 
227         if(bHeader)
228         {
229             // ggf. Header anzeigen
230             aHdRect.Left() += nHdLeft;
231             aHdRect.Right() -= nHdRight;
232             aHdRect.Bottom() = aRect.Top() + nHdHeight;
233             aRect.Top() += nHdHeight + nHdDist;
234 
235             // draw header over PageFill, plus outline
236             drawFillAttributes(maHeaderFillAttributes, aHdRect, aHdRect);
237         }
238 
239         if(bFooter)
240         {
241             // ggf. Footer anzeigen
242             aFtRect.Left() += nFtLeft;
243             aFtRect.Right() -= nFtRight;
244             aFtRect.Top() = aRect.Bottom() - nFtHeight;
245             aRect.Bottom() -= nFtHeight + nFtDist;
246 
247             // draw footer over PageFill, plus outline
248             drawFillAttributes(maFooterFillAttributes, aFtRect, aFtRect);
249         }
250 
251         // draw page's reduced outline, only outline
252         drawFillAttributes(drawinglayer::attribute::SdrAllFillAttributesHelperPtr(), aRect, aRect);
253     }
254     else
255     {
256         //UUUU draw PageFill and outline
257         drawFillAttributes(maPageFillAttributes, aRect, aRect);
258     }
259 
260     if(bFrameDirection && !bTable)
261     {
262         //pImpl->nFrameDirection
263         Point aPos;
264         Font aFont(GetFont());
265         const Size aSaveSize = aFont.GetSize();
266         Size aDrawSize(0,aRect.GetHeight() / 6);
267         aFont.SetSize(aDrawSize);
268         SetFont(aFont);
269         String sText(String::CreateFromAscii("ABC"));
270         Point aMove(1,GetTextHeight());
271         sal_Unicode cArrow = 0x2193;
272         long nAWidth = GetTextWidth(String(sText.GetChar(0)));
273         switch(nFrameDirection)
274         {
275         case FRMDIR_HORI_LEFT_TOP:
276             aPos = aRect.TopLeft();
277             aPos.X() += PixelToLogic(Point(1,1)).X();
278             aMove.Y() = 0;
279             cArrow = 0x2192;
280             break;
281         case FRMDIR_HORI_RIGHT_TOP:
282             aPos = aRect.TopRight();
283             aPos.X() -= nAWidth;
284             aMove.Y() = 0;
285             aMove.X() *= -1;
286             cArrow = 0x2190;
287             break;
288         case FRMDIR_VERT_TOP_LEFT:
289             aPos = aRect.TopLeft();
290             aPos.X() += PixelToLogic(Point(1,1)).X();
291             aMove.X() = 0;
292             break;
293         case FRMDIR_VERT_TOP_RIGHT:
294             aPos = aRect.TopRight();
295             aPos.X() -= nAWidth;
296             aMove.X() = 0;
297             break;
298         }
299         sText.Append(cArrow);
300         for(sal_uInt16 i = 0; i < sText.Len(); i++)
301         {
302             String sDraw(sText.GetChar(i));
303             long nHDiff = 0;
304             long nCharWidth = GetTextWidth(sDraw);
305             sal_Bool bHorizontal = 0 == aMove.Y();
306             if(!bHorizontal)
307             {
308                 nHDiff = (nAWidth - nCharWidth) / 2;
309                 aPos.X() += nHDiff;
310             }
311             DrawText(aPos,sDraw);
312             if(bHorizontal)
313             {
314                 aPos.X() += aMove.X() < 0 ? -nCharWidth : nCharWidth;
315             }
316             else
317             {
318                 aPos.X() -= nHDiff;
319                 aPos.Y() += aMove.Y();
320             }
321         }
322         aFont.SetSize(aSaveSize);
323         SetFont(aFont);
324 
325     }
326     if(bTable)
327     {
328         // Tabelle malen, ggf. zentrieren
329         SetLineColor(Color(COL_LIGHTGRAY));
330 
331         long nW = aRect.GetWidth(),nH = aRect.GetHeight();
332         long nTW = CELL_WIDTH * 3,nTH = CELL_HEIGHT * 3;
333         long _nLeft = bHorz ? aRect.Left() + ((nW - nTW) / 2) : aRect.Left();
334         long _nTop = bVert ? aRect.Top() + ((nH - nTH) / 2) : aRect.Top();
335         Rectangle aCellRect(Point(_nLeft,_nTop),Size(CELL_WIDTH,CELL_HEIGHT));
336 
337         for(sal_uInt16 i = 0; i < 3; ++i)
338         {
339             aCellRect.Left() = _nLeft;
340             aCellRect.Right() = _nLeft + CELL_WIDTH;
341             if(i > 0)
342                 aCellRect.Move(0,CELL_HEIGHT);
343 
344             for(sal_uInt16 j = 0; j < 3; ++j)
345             {
346                 if(j > 0)
347                     aCellRect.Move(CELL_WIDTH,0);
348                 DrawRect(aCellRect);
349             }
350         }
351     }
352 }
353 
354 //UUUU
drawFillAttributes(const drawinglayer::attribute::SdrAllFillAttributesHelperPtr & rFillAttributes,const Rectangle & rPaintRange,const Rectangle & rDefineRange)355 void SvxPageWindow::drawFillAttributes(
356     const drawinglayer::attribute::SdrAllFillAttributesHelperPtr& rFillAttributes,
357     const Rectangle& rPaintRange,
358     const Rectangle& rDefineRange)
359 {
360     const basegfx::B2DRange aPaintRange(
361         rPaintRange.Left(),
362         rPaintRange.Top(),
363         rPaintRange.Right(),
364         rPaintRange.Bottom());
365 
366     if(!aPaintRange.isEmpty() &&
367         !basegfx::fTools::equalZero(aPaintRange.getWidth()) &&
368         !basegfx::fTools::equalZero(aPaintRange.getHeight()))
369     {
370         const basegfx::B2DRange aDefineRange(
371             rDefineRange.Left(),
372             rDefineRange.Top(),
373             rDefineRange.Right(),
374             rDefineRange.Bottom());
375 
376         // prepare primitive sequence
377         drawinglayer::primitive2d::Primitive2DSequence aSequence;
378 
379         // create fill geometry if there is something to fill
380         if(rFillAttributes.get() && rFillAttributes->isUsed())
381         {
382             aSequence = rFillAttributes->getPrimitive2DSequence(
383                 aPaintRange,
384                 aDefineRange);
385         }
386 
387         // create line geometry if a LineColor is set at the target device
388         if(IsLineColor())
389         {
390             const drawinglayer::primitive2d::Primitive2DReference xOutline(
391                 new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(
392                     basegfx::tools::createPolygonFromRect(aPaintRange),
393                     GetLineColor().getBColor()));
394 
395             drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(
396                 aSequence,
397                 xOutline);
398         }
399 
400         // draw that if we have something to draw
401         if(aSequence.getLength())
402         {
403             const drawinglayer::geometry::ViewInformation2D aViewInformation2D(
404                 basegfx::B2DHomMatrix(),
405                 GetViewTransformation(),
406                 aPaintRange,
407                 0,
408                 0.0,
409                 com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >());
410             drawinglayer::processor2d::BaseProcessor2D* pProcessor = drawinglayer::processor2d::createProcessor2DFromOutputDevice(
411                 *this,
412                 aViewInformation2D);
413 
414             if(pProcessor)
415             {
416                 pProcessor->process(aSequence);
417 
418                 delete pProcessor;
419             }
420         }
421     }
422 }
423 
424 // -----------------------------------------------------------------------
425 
SetBorder(const SvxBoxItem & rNew)426 void SvxPageWindow::SetBorder(const SvxBoxItem& rNew)
427 {
428     delete pBorder;
429     pBorder = new SvxBoxItem(rNew);
430 }
431 
432 // -----------------------------------------------------------------------
433 
SetHdBorder(const SvxBoxItem & rNew)434 void SvxPageWindow::SetHdBorder(const SvxBoxItem& rNew)
435 {
436     delete pHdBorder;
437     pHdBorder = new SvxBoxItem(rNew);
438 }
439 // -----------------------------------------------------------------------
440 
SetFtBorder(const SvxBoxItem & rNew)441 void SvxPageWindow::SetFtBorder(const SvxBoxItem& rNew)
442 {
443     delete pFtBorder;
444     pFtBorder = new SvxBoxItem(rNew);
445 }
446 
EnableFrameDirection(sal_Bool bEnable)447 void SvxPageWindow::EnableFrameDirection(sal_Bool bEnable)
448 {
449     bFrameDirection = bEnable;
450 }
451 
SetFrameDirection(sal_Int32 nDirection)452 void SvxPageWindow::SetFrameDirection(sal_Int32 nDirection)
453 {
454     nFrameDirection = nDirection;
455 }
456 
ResetBackground()457 void SvxPageWindow::ResetBackground()
458 {
459     bResetBackground = sal_True;
460 }
461 
462 //eof
463