xref: /trunk/main/cui/source/tabpages/grfpage.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_cui.hxx"
30 
31 #include <tools/shl.hxx>
32 #include <svl/eitem.hxx>
33 #include <sfx2/app.hxx>
34 #include <sfx2/module.hxx>
35 #include <sfx2/sfxsids.hrc>
36 #include <dialmgr.hxx>
37 #include <svx/dlgutil.hxx>
38 #include <editeng/sizeitem.hxx>
39 #include <editeng/brshitem.hxx>
40 #include <grfpage.hxx>
41 #include <svx/grfcrop.hxx>
42 #include <grfpage.hrc>
43 #include <cuires.hrc>
44 #include <svx/dialogs.hrc> // for RID_SVXPAGE_GRFCROP
45 
46 #define CM_1_TO_TWIP        567
47 
48 
49 inline long lcl_GetValue( MetricField& rMetric, FieldUnit eUnit )
50 {
51     return static_cast<long>(rMetric.Denormalize( rMetric.GetValue( eUnit )));
52 }
53 
54 /*--------------------------------------------------------------------
55     Beschreibung: Grafik zuschneiden
56  --------------------------------------------------------------------*/
57 
58 SvxGrfCropPage::SvxGrfCropPage ( Window *pParent, const SfxItemSet &rSet )
59     : SfxTabPage( pParent,  CUI_RES( RID_SVXPAGE_GRFCROP ), rSet ),
60     aCropFL(        this, CUI_RES( FL_CROP    )),
61     aZoomConstRB(   this, CUI_RES( RB_ZOOMCONST)),
62     aSizeConstRB(   this, CUI_RES( RB_SIZECONST)),
63     aLeftFT(        this, CUI_RES( FT_LEFT    )),
64     aLeftMF(        this, CUI_RES( MF_LEFT    )),
65     aRightFT(       this, CUI_RES( FT_RIGHT   )),
66     aRightMF(       this, CUI_RES( MF_RIGHT   )),
67     aTopFT(         this, CUI_RES( FT_TOP     )),
68     aTopMF(         this, CUI_RES( MF_TOP     )),
69     aBottomFT(      this, CUI_RES( FT_BOTTOM  )),
70     aBottomMF(      this, CUI_RES( MF_BOTTOM  )),
71     aZoomFL(        this, CUI_RES( FL_ZOOM    )),
72     aWidthZoomFT(   this, CUI_RES( FT_WIDTHZOOM )),
73     aWidthZoomMF(   this, CUI_RES( MF_WIDTHZOOM )),
74     aHeightZoomFT(  this, CUI_RES( FT_HEIGHTZOOM)),
75     aHeightZoomMF(  this, CUI_RES( MF_HEIGHTZOOM)),
76     aSizeFL(        this, CUI_RES( FL_SIZE    )),
77     aWidthFT(       this, CUI_RES( FT_WIDTH   )),
78     aWidthMF(       this, CUI_RES( MF_WIDTH   )),
79     aHeightFT(      this, CUI_RES( FT_HEIGHT  )),
80     aHeightMF(      this, CUI_RES( MF_HEIGHT  )),
81     aOrigSizeFT(    this, CUI_RES(FT_ORIG_SIZE)),
82     aOrigSizePB(    this, CUI_RES( PB_ORGSIZE )),
83     aExampleWN(     this, CUI_RES( WN_BSP     )),
84     pLastCropField(0),
85     bInitialized(sal_False),
86     bSetOrigSize(sal_False)
87 {
88     FreeResource();
89 
90     SetExchangeSupport();
91 
92     // set the correct metric
93     const FieldUnit eMetric = GetModuleFieldUnit( rSet );
94 
95     SetFieldUnit( aWidthMF, eMetric );
96     SetFieldUnit( aHeightMF, eMetric );
97     SetFieldUnit( aLeftMF, eMetric );
98     SetFieldUnit( aRightMF, eMetric );
99     SetFieldUnit( aTopMF , eMetric );
100     SetFieldUnit( aBottomMF, eMetric );
101 
102     Link aLk = LINK(this, SvxGrfCropPage, SizeHdl);
103     aWidthMF.SetModifyHdl( aLk );
104     aHeightMF.SetModifyHdl( aLk );
105 
106     aLk = LINK(this, SvxGrfCropPage, ZoomHdl);
107     aWidthZoomMF.SetModifyHdl( aLk );
108     aHeightZoomMF.SetModifyHdl( aLk );
109 
110     aLk = LINK(this, SvxGrfCropPage, CropHdl);
111     aLeftMF.SetDownHdl( aLk );
112     aRightMF.SetDownHdl( aLk );
113     aTopMF.SetDownHdl( aLk );
114     aBottomMF.SetDownHdl( aLk );
115     aLeftMF.SetUpHdl( aLk );
116     aRightMF.SetUpHdl( aLk );
117     aTopMF.SetUpHdl( aLk );
118     aBottomMF.SetUpHdl( aLk );
119 
120     aLk = LINK(this, SvxGrfCropPage, CropModifyHdl);
121     aLeftMF.SetModifyHdl( aLk );
122     aRightMF.SetModifyHdl( aLk );
123     aTopMF.SetModifyHdl( aLk );
124     aBottomMF.SetModifyHdl( aLk );
125 
126     aLk = LINK(this, SvxGrfCropPage, CropLoseFocusHdl);
127     aLeftMF.SetLoseFocusHdl( aLk );
128     aRightMF.SetLoseFocusHdl( aLk );
129     aTopMF.SetLoseFocusHdl( aLk );
130     aBottomMF.SetLoseFocusHdl( aLk );
131 
132     aLk = LINK(this, SvxGrfCropPage, OrigSizeHdl);
133     aOrigSizePB.SetClickHdl( aLk );
134 
135     aTimer.SetTimeoutHdl(LINK(this, SvxGrfCropPage, Timeout));
136     aTimer.SetTimeout( 1500 );
137 
138     aOrigSizePB.SetAccessibleRelationLabeledBy( &aOrigSizeFT );
139 }
140 
141 /*--------------------------------------------------------------------
142     Beschreibung:
143  --------------------------------------------------------------------*/
144 
145 SvxGrfCropPage::~SvxGrfCropPage()
146 {
147     aTimer.Stop();
148 }
149 
150 /*--------------------------------------------------------------------
151     Beschreibung:
152  --------------------------------------------------------------------*/
153 
154 SfxTabPage* SvxGrfCropPage::Create(Window *pParent, const SfxItemSet &rSet)
155 {
156     return new SvxGrfCropPage( pParent, rSet );
157 }
158 /*--------------------------------------------------------------------
159     Beschreibung:
160  --------------------------------------------------------------------*/
161 
162 void SvxGrfCropPage::Reset( const SfxItemSet &rSet )
163 {
164     const SfxPoolItem* pItem;
165     const SfxItemPool& rPool = *rSet.GetPool();
166 
167     if(SFX_ITEM_SET == rSet.GetItemState( rPool.GetWhich(
168                                     SID_ATTR_GRAF_KEEP_ZOOM ), sal_True, &pItem ))
169     {
170         if( ((const SfxBoolItem*)pItem)->GetValue() )
171             aZoomConstRB.Check();
172         else
173             aSizeConstRB.Check();
174         aZoomConstRB.SaveValue();
175     }
176 
177     sal_uInt16 nW = rPool.GetWhich( SID_ATTR_GRAF_CROP );
178     if( SFX_ITEM_SET == rSet.GetItemState( nW, sal_True, &pItem))
179     {
180         FieldUnit eUnit = MapToFieldUnit( rSet.GetPool()->GetMetric( nW ));
181 
182         SvxGrfCrop* pCrop =  (SvxGrfCrop*)pItem;
183 
184         aExampleWN.SetLeft(     pCrop->GetLeft());
185         aExampleWN.SetRight(    pCrop->GetRight());
186         aExampleWN.SetTop(      pCrop->GetTop());
187         aExampleWN.SetBottom(   pCrop->GetBottom());
188 
189         aLeftMF.SetValue( aLeftMF.Normalize( pCrop->GetLeft()), eUnit );
190         aRightMF.SetValue( aRightMF.Normalize( pCrop->GetRight()), eUnit );
191         aTopMF.SetValue( aTopMF.Normalize( pCrop->GetTop()), eUnit );
192         aBottomMF.SetValue( aBottomMF.Normalize( pCrop->GetBottom()), eUnit );
193     }
194     else
195     {
196         aLeftMF.SetValue( 0 );
197         aRightMF.SetValue( 0 );
198         aTopMF.SetValue( 0 );
199         aBottomMF.SetValue( 0 );
200     }
201 
202     nW = rPool.GetWhich( SID_ATTR_PAGE_SIZE );
203     if ( SFX_ITEM_SET == rSet.GetItemState( nW, sal_False, &pItem ) )
204     {
205         // Orientation und Size aus dem PageItem
206         FieldUnit eUnit = MapToFieldUnit( rSet.GetPool()->GetMetric( nW ));
207 
208         aPageSize = ((const SvxSizeItem*)pItem)->GetSize();
209 
210         sal_Int64 nTmp = aHeightMF.Normalize(aPageSize.Height());
211         aHeightMF.SetMax( nTmp, eUnit );
212         nTmp = aWidthMF.Normalize(aPageSize.Width());
213         aWidthMF.SetMax( nTmp, eUnit );
214         nTmp = aWidthMF.Normalize( 23 );
215         aHeightMF.SetMin( nTmp, eUnit );
216         aWidthMF.SetMin( nTmp, eUnit );
217     }
218     else
219     {
220         aPageSize = OutputDevice::LogicToLogic(
221                         Size( CM_1_TO_TWIP,  CM_1_TO_TWIP ),
222                         MapMode( MAP_TWIP ),
223                         MapMode( (MapUnit)rSet.GetPool()->GetMetric( nW ) ) );
224     }
225 
226     sal_Bool bFound = sal_False;
227     if( SFX_ITEM_SET == rSet.GetItemState( SID_ATTR_GRAF_GRAPHIC, sal_False, &pItem ) )
228     {
229         const Graphic* pGrf = ((SvxBrushItem*)pItem)->GetGraphic();
230         if( pGrf )
231             aOrigSize = GetGrfOrigSize( *pGrf );
232 
233         if( aOrigSize.Width() && aOrigSize.Height() )
234         {
235             CalcMinMaxBorder();
236             aExampleWN.SetGraphic( *pGrf );
237             aExampleWN.SetFrameSize( aOrigSize );
238 
239             bFound = sal_True;
240             if( ((SvxBrushItem*)pItem)->GetGraphicLink() )
241                 aGraphicName = *((SvxBrushItem*)pItem)->GetGraphicLink();
242         }
243     }
244 
245     GraphicHasChanged( bFound );
246     bReset = sal_True;
247     ActivatePage( rSet );
248     bReset = sal_False;
249 }
250 
251 /*--------------------------------------------------------------------
252     Beschreibung:
253  --------------------------------------------------------------------*/
254 
255 sal_Bool SvxGrfCropPage::FillItemSet(SfxItemSet &rSet)
256 {
257     const SfxItemPool& rPool = *rSet.GetPool();
258     sal_Bool bModified = sal_False;
259     if( aWidthMF.GetSavedValue() != aWidthMF.GetText() ||
260         aHeightMF.GetSavedValue() != aHeightMF.GetText() )
261     {
262         sal_uInt16 nW = rPool.GetWhich( SID_ATTR_GRAF_FRMSIZE );
263         FieldUnit eUnit = MapToFieldUnit( rSet.GetPool()->GetMetric( nW ));
264 
265         SvxSizeItem aSz( nW );
266 
267         // die Groesse koennte schon von einer anderen Page gesetzt worden sein
268         // #44204#
269         const SfxItemSet* pExSet = GetTabDialog() ? GetTabDialog()->GetExampleSet() : NULL;
270         const SfxPoolItem* pItem = 0;
271         if( pExSet && SFX_ITEM_SET ==
272                 pExSet->GetItemState( nW, sal_False, &pItem ) )
273             aSz = *(const SvxSizeItem*)pItem;
274         else
275             aSz = (const SvxSizeItem&)GetItemSet().Get( nW );
276 
277         Size aTmpSz( aSz.GetSize() );
278         if( aWidthMF.GetText() != aWidthMF.GetSavedValue() )
279             aTmpSz.Width() = lcl_GetValue( aWidthMF, eUnit );
280         if( aHeightMF.GetText() != aHeightMF.GetSavedValue() )
281             aTmpSz.Height() = lcl_GetValue( aHeightMF, eUnit );
282         aSz.SetSize( aTmpSz );
283         aWidthMF.SaveValue();
284         aHeightMF.SaveValue();
285 
286         bModified |= 0 != rSet.Put( aSz );
287 
288         if( bSetOrigSize )
289         {
290             bModified |= 0 != rSet.Put( SvxSizeItem( rPool.GetWhich(
291                         SID_ATTR_GRAF_FRMSIZE_PERCENT ), Size( 0, 0 )) );
292         }
293     }
294     if( aLeftMF.IsModified() || aRightMF.IsModified() ||
295         aTopMF.IsModified()  || aBottomMF.IsModified() )
296     {
297         sal_uInt16 nW = rPool.GetWhich( SID_ATTR_GRAF_CROP );
298         FieldUnit eUnit = MapToFieldUnit( rSet.GetPool()->GetMetric( nW ));
299         SvxGrfCrop* pNew = (SvxGrfCrop*)rSet.Get( nW ).Clone();
300 
301         pNew->SetLeft( lcl_GetValue( aLeftMF, eUnit ) );
302         pNew->SetRight( lcl_GetValue( aRightMF, eUnit ) );
303         pNew->SetTop( lcl_GetValue( aTopMF, eUnit ) );
304         pNew->SetBottom( lcl_GetValue( aBottomMF, eUnit ) );
305         bModified |= 0 != rSet.Put( *pNew );
306         delete pNew;
307     }
308 
309     if( aZoomConstRB.GetSavedValue() != aZoomConstRB.IsChecked() )
310     {
311         bModified |= 0 != rSet.Put( SfxBoolItem( rPool.GetWhich(
312                     SID_ATTR_GRAF_KEEP_ZOOM), aZoomConstRB.IsChecked() ) );
313     }
314 
315     bInitialized = sal_False;
316 
317     return bModified;
318 }
319 
320 /*--------------------------------------------------------------------
321     Beschreibung:
322  --------------------------------------------------------------------*/
323 
324 void SvxGrfCropPage::ActivatePage(const SfxItemSet& rSet)
325 {
326 #ifdef DBG_UTIL
327     SfxItemPool* pPool = GetItemSet().GetPool();
328     DBG_ASSERT( pPool, "Wo ist der Pool" );
329 #endif
330 
331     bSetOrigSize = sal_False;
332 
333     // Size
334     Size aSize;
335     const SfxPoolItem* pItem;
336     if( SFX_ITEM_SET == rSet.GetItemState( SID_ATTR_GRAF_FRMSIZE, sal_False, &pItem ) )
337         aSize = ((const SvxSizeItem*)pItem)->GetSize();
338 
339     nOldWidth = aSize.Width();
340     nOldHeight = aSize.Height();
341 
342     sal_Int64 nWidth = aWidthMF.Normalize(nOldWidth);
343     sal_Int64 nHeight = aHeightMF.Normalize(nOldHeight);
344 
345     if (nWidth != aWidthMF.GetValue(FUNIT_TWIP))
346     {
347         if(!bReset)
348         {
349             // Wert wurde von Umlauf-Tabpage geaendert und muss
350             // mit Modify-Flag gesetzt werden
351             aWidthMF.SetUserValue(nWidth, FUNIT_TWIP);
352         }
353         else
354             aWidthMF.SetValue(nWidth, FUNIT_TWIP);
355     }
356     aWidthMF.SaveValue();
357 
358     if (nHeight != aHeightMF.GetValue(FUNIT_TWIP))
359     {
360         if (!bReset)
361         {
362             // Wert wurde von Umlauf-Tabpage geaendert und muss
363             // mit Modify-Flag gesetzt werden
364             aHeightMF.SetUserValue(nHeight, FUNIT_TWIP);
365         }
366         else
367             aHeightMF.SetValue(nHeight, FUNIT_TWIP);
368     }
369     aHeightMF.SaveValue();
370     bInitialized = sal_True;
371 
372     if( SFX_ITEM_SET == rSet.GetItemState( SID_ATTR_GRAF_GRAPHIC, sal_False, &pItem ) )
373     {
374         const SvxBrushItem& rBrush = *(SvxBrushItem*)pItem;
375         if( rBrush.GetGraphicLink() &&
376             aGraphicName != *rBrush.GetGraphicLink() )
377             aGraphicName = *rBrush.GetGraphicLink();
378 
379         const Graphic* pGrf = rBrush.GetGraphic();
380         if( pGrf )
381         {
382             aExampleWN.SetGraphic( *pGrf );
383             aOrigSize = GetGrfOrigSize( *pGrf );
384             aExampleWN.SetFrameSize(aOrigSize);
385             GraphicHasChanged( aOrigSize.Width() && aOrigSize.Height() );
386             CalcMinMaxBorder();
387         }
388         else
389             GraphicHasChanged( sal_False );
390     }
391 
392     CalcZoom();
393 }
394 
395 /*--------------------------------------------------------------------
396     Beschreibung:
397  --------------------------------------------------------------------*/
398 
399 int SvxGrfCropPage::DeactivatePage(SfxItemSet *_pSet)
400 {
401     if ( _pSet )
402         FillItemSet( *_pSet );
403     return sal_True;
404 }
405 
406 /*--------------------------------------------------------------------
407     Beschreibung: Massstab geaendert, Groesse anpassen
408  --------------------------------------------------------------------*/
409 
410 IMPL_LINK( SvxGrfCropPage, ZoomHdl, MetricField *, pField )
411 {
412     SfxItemPool* pPool = GetItemSet().GetPool();
413     DBG_ASSERT( pPool, "Wo ist der Pool" );
414     FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( pPool->GetWhich(
415                                                     SID_ATTR_GRAF_CROP ) ) );
416 
417     if( pField == &aWidthZoomMF )
418     {
419         long nLRBorders = lcl_GetValue(aLeftMF, eUnit)
420                          +lcl_GetValue(aRightMF, eUnit);
421         aWidthMF.SetValue( aWidthMF.Normalize(
422             ((aOrigSize.Width() - nLRBorders) * pField->GetValue())/100L),
423             eUnit);
424     }
425     else
426     {
427         long nULBorders = lcl_GetValue(aTopMF, eUnit)
428                          +lcl_GetValue(aBottomMF, eUnit);
429         aHeightMF.SetValue( aHeightMF.Normalize(
430             ((aOrigSize.Height() - nULBorders ) * pField->GetValue())/100L) ,
431             eUnit );
432     }
433 
434     return 0;
435 }
436 
437 /*--------------------------------------------------------------------
438     Beschreibung: Groesse aendern, Massstab anpassen
439  --------------------------------------------------------------------*/
440 
441 IMPL_LINK( SvxGrfCropPage, SizeHdl, MetricField *, pField )
442 {
443     SfxItemPool* pPool = GetItemSet().GetPool();
444     DBG_ASSERT( pPool, "Wo ist der Pool" );
445     FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( pPool->GetWhich(
446                                                     SID_ATTR_GRAF_CROP ) ) );
447 
448     Size aSize( lcl_GetValue(aWidthMF, eUnit),
449                 lcl_GetValue(aHeightMF, eUnit) );
450 
451     if(pField == &aWidthMF)
452     {
453         long nWidth = aOrigSize.Width() -
454                 ( lcl_GetValue(aLeftMF, eUnit) +
455                   lcl_GetValue(aRightMF, eUnit) );
456         if(!nWidth)
457             nWidth++;
458         sal_uInt16 nZoom = (sal_uInt16)( aSize.Width() * 100L / nWidth);
459         aWidthZoomMF.SetValue(nZoom);
460     }
461     else
462     {
463         long nHeight = aOrigSize.Height() -
464                 ( lcl_GetValue(aTopMF, eUnit) +
465                   lcl_GetValue(aBottomMF, eUnit));
466         if(!nHeight)
467             nHeight++;
468         sal_uInt16 nZoom = (sal_uInt16)( aSize.Height() * 100L/ nHeight);
469         aHeightZoomMF.SetValue(nZoom);
470     }
471 
472     return 0;
473 }
474 
475 /*--------------------------------------------------------------------
476     Beschreibung: Raender auswerten
477  --------------------------------------------------------------------*/
478 
479 IMPL_LINK( SvxGrfCropPage, CropHdl, const MetricField *, pField )
480 {
481     SfxItemPool* pPool = GetItemSet().GetPool();
482     DBG_ASSERT( pPool, "Wo ist der Pool" );
483     FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( pPool->GetWhich(
484                                                     SID_ATTR_GRAF_CROP ) ) );
485 
486     sal_Bool bZoom = aZoomConstRB.IsChecked();
487     if( pField == &aLeftMF || pField == &aRightMF )
488     {
489         long nLeft = lcl_GetValue( aLeftMF, eUnit );
490         long nRight = lcl_GetValue( aRightMF, eUnit );
491         long nWidthZoom = static_cast<long>(aWidthZoomMF.GetValue());
492         if(bZoom && ( ( ( aOrigSize.Width() - (nLeft + nRight )) * nWidthZoom )
493                             / 100 >= aPageSize.Width() ) )
494         {
495             if(pField == &aLeftMF)
496             {
497 //              nLeft = aPageSize.Width() -
498 //                  ((nRight + aOrigSize.Width()) * nWidthZoom) / 100;
499                 nLeft = aOrigSize.Width() -
500                             ( aPageSize.Width() * 100 / nWidthZoom + nRight );
501                 aLeftMF.SetValue( aLeftMF.Normalize( nLeft ), eUnit );
502             }
503             else
504             {
505 //              nRight = aPageSize.Width() -
506 //                  ((nLeft - aOrigSize.Width()) * nWidthZoom) / 100;
507                 nRight = aOrigSize.Width() -
508                             ( aPageSize.Width() * 100 / nWidthZoom + nLeft );
509                 aRightMF.SetValue( aRightMF.Normalize( nRight ), eUnit );
510             }
511         }
512         aExampleWN.SetLeft(nLeft);
513         aExampleWN.SetRight(nRight);
514         if(bZoom)
515         {
516             //Massstab bleibt -> Breite neu berechnen
517             ZoomHdl(&aWidthZoomMF);
518         }
519     }
520     else
521     {
522         long nTop = lcl_GetValue( aTopMF, eUnit );
523         long nBottom = lcl_GetValue( aBottomMF, eUnit );
524         long nHeightZoom = static_cast<long>(aHeightZoomMF.GetValue());
525         if(bZoom && ( ( ( aOrigSize.Height() - (nTop + nBottom )) * nHeightZoom)
526                                             / 100 >= aPageSize.Height()))
527         {
528             if(pField == &aTopMF)
529             {
530 //              nTop = aPageSize.Height() -
531 //                  ((aOrigSize.Height() - nBottom) * nHeightZoom)/ 100;
532                 nTop = aOrigSize.Height() -
533                             ( aPageSize.Height() * 100 / nHeightZoom + nBottom);
534                 aTopMF.SetValue( aWidthMF.Normalize( nTop ), eUnit );
535             }
536             else
537             {
538 //              nBottom = aPageSize.Height() -
539 //                  ((aOrigSize.Height() - nTop)*nHeightZoom) / 100;
540                 nBottom = aOrigSize.Height() -
541                             ( aPageSize.Height() * 100 / nHeightZoom + nTop);
542                 aBottomMF.SetValue( aWidthMF.Normalize( nBottom ), eUnit );
543             }
544         }
545         aExampleWN.SetTop( nTop );
546         aExampleWN.SetBottom( nBottom );
547         if(bZoom)
548         {
549             //Massstab bleibt -> Hoehe neu berechnen
550             ZoomHdl(&aHeightZoomMF);
551         }
552     }
553     aExampleWN.Invalidate();
554     //Groesse und Raender veraendert -> Massstab neu berechnen
555     if(!bZoom)
556         CalcZoom();
557     CalcMinMaxBorder();
558     return 0;
559 }
560 /*--------------------------------------------------------------------
561     Beschreibung: Originalgroesse einstellen
562  --------------------------------------------------------------------*/
563 
564 IMPL_LINK( SvxGrfCropPage, OrigSizeHdl, PushButton *, EMPTYARG )
565 {
566     SfxItemPool* pPool = GetItemSet().GetPool();
567     DBG_ASSERT( pPool, "Wo ist der Pool" );
568     FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( pPool->GetWhich(
569                                                     SID_ATTR_GRAF_CROP ) ) );
570 
571     long nWidth = aOrigSize.Width() -
572         lcl_GetValue( aLeftMF, eUnit ) -
573         lcl_GetValue( aRightMF, eUnit );
574     aWidthMF.SetValue( aWidthMF.Normalize( nWidth ), eUnit );
575     long nHeight = aOrigSize.Height() -
576         lcl_GetValue( aTopMF, eUnit ) -
577         lcl_GetValue( aBottomMF, eUnit );
578     aHeightMF.SetValue( aHeightMF.Normalize( nHeight ), eUnit );
579     aWidthZoomMF.SetValue(100);
580     aHeightZoomMF.SetValue(100);
581     bSetOrigSize = sal_True;
582     return 0;
583 }
584 /*--------------------------------------------------------------------
585     Beschreibung: Massstab berechnen
586  --------------------------------------------------------------------*/
587 
588 void SvxGrfCropPage::CalcZoom()
589 {
590     SfxItemPool* pPool = GetItemSet().GetPool();
591     DBG_ASSERT( pPool, "Wo ist der Pool" );
592     FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( pPool->GetWhich(
593                                                     SID_ATTR_GRAF_CROP ) ) );
594 
595     long nWidth = lcl_GetValue( aWidthMF, eUnit );
596     long nHeight = lcl_GetValue( aHeightMF, eUnit );
597     long nLRBorders = lcl_GetValue( aLeftMF, eUnit ) +
598                       lcl_GetValue( aRightMF, eUnit );
599     long nULBorders = lcl_GetValue( aTopMF, eUnit ) +
600                       lcl_GetValue( aBottomMF, eUnit );
601     sal_uInt16 nZoom = 0;
602     long nDen;
603     if( (nDen = aOrigSize.Width() - nLRBorders) > 0)
604         nZoom = (sal_uInt16)((( nWidth  * 1000L / nDen )+5)/10);
605     aWidthZoomMF.SetValue(nZoom);
606     if( (nDen = aOrigSize.Height() - nULBorders) > 0)
607         nZoom = (sal_uInt16)((( nHeight * 1000L / nDen )+5)/10);
608     else
609         nZoom = 0;
610     aHeightZoomMF.SetValue(nZoom);
611 }
612 
613 /*--------------------------------------------------------------------
614     Beschreibung: Minimal-/Maximalwerte fuer die Raender setzen
615  --------------------------------------------------------------------*/
616 
617 void SvxGrfCropPage::CalcMinMaxBorder()
618 {
619     SfxItemPool* pPool = GetItemSet().GetPool();
620     DBG_ASSERT( pPool, "Wo ist der Pool" );
621     FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( pPool->GetWhich(
622                                                     SID_ATTR_GRAF_CROP ) ) );
623     long nR = lcl_GetValue(aRightMF, eUnit );
624     long nMinWidth = (aOrigSize.Width() * 10) /11;
625     long nMin = nMinWidth - (nR >= 0 ? nR : 0);
626     aLeftMF.SetMax( aLeftMF.Normalize(nMin), eUnit );
627 
628     long nL = lcl_GetValue(aLeftMF, eUnit );
629     nMin = nMinWidth - (nL >= 0 ? nL : 0);
630     aRightMF.SetMax( aRightMF.Normalize(nMin), eUnit );
631 
632     // Zoom nicht unter 2%
633 /*  nMin = (aOrigSize.Width() * 102) /100;
634     aLeftMF.SetMax(aPageSize.Width() - nR - nMin);
635     aRightMF.SetMax(aPageSize.Width() - nL - nMin);
636 */
637     long nUp  = lcl_GetValue( aTopMF, eUnit );
638     long nMinHeight = (aOrigSize.Height() * 10) /11;
639     nMin = nMinHeight - (nUp >= 0 ? nUp : 0);
640     aBottomMF.SetMax( aBottomMF.Normalize(nMin), eUnit );
641 
642     long nLow = lcl_GetValue(aBottomMF, eUnit );
643     nMin = nMinHeight - (nLow >= 0 ? nLow : 0);
644     aTopMF.SetMax( aTopMF.Normalize(nMin), eUnit );
645 
646     // Zoom nicht unter 2%
647 /*  nMin = (aOrigSize.Height() * 102) /100;
648     aTopMF.SetMax(aPageSize.Height() - nLow - nMin);
649     aBottomMF.SetMax(aPageSize.Height() - nUp - nMin);*/
650 }
651 /*--------------------------------------------------------------------
652     Beschreibung:   Spinsize auf 1/20 der Originalgroesse setzen,
653                     FixedText mit der Originalgroesse fuellen
654  --------------------------------------------------------------------*/
655 
656 void SvxGrfCropPage::GraphicHasChanged( sal_Bool bFound )
657 {
658     if( bFound )
659     {
660         SfxItemPool* pPool = GetItemSet().GetPool();
661         DBG_ASSERT( pPool, "Wo ist der Pool" );
662         FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( pPool->GetWhich(
663                                                     SID_ATTR_GRAF_CROP ) ));
664 
665         sal_Int64 nSpin = aLeftMF.Normalize(aOrigSize.Width()) / 20;
666         nSpin = MetricField::ConvertValue( nSpin, aOrigSize.Width(), 0,
667                                             eUnit, aLeftMF.GetUnit());
668 
669         // Ist der Rand zu gross, wird er auf beiden Seiten auf 1/3 eingestellt.
670         long nR = lcl_GetValue( aRightMF, eUnit );
671         long nL = lcl_GetValue( aLeftMF, eUnit );
672         if((nL + nR) < - aOrigSize.Width())
673         {
674             long nVal = aOrigSize.Width() / -3;
675             aRightMF.SetValue( aRightMF.Normalize( nVal ), eUnit );
676             aLeftMF.SetValue( aLeftMF.Normalize( nVal ), eUnit );
677             aExampleWN.SetLeft(nVal);
678             aExampleWN.SetRight(nVal);
679         }
680         long nUp  = lcl_GetValue(aTopMF, eUnit );
681         long nLow = lcl_GetValue(aBottomMF, eUnit );
682         if((nUp + nLow) < - aOrigSize.Height())
683         {
684             long nVal = aOrigSize.Height() / -3;
685             aTopMF.SetValue( aTopMF.Normalize( nVal ), eUnit );
686             aBottomMF.SetValue( aBottomMF.Normalize( nVal ), eUnit );
687             aExampleWN.SetTop(nVal);
688             aExampleWN.SetBottom(nVal);
689         }
690 
691         aLeftMF.SetSpinSize(nSpin);
692         aRightMF.SetSpinSize(nSpin);
693         nSpin = aTopMF.Normalize(aOrigSize.Height()) / 20;
694         nSpin = MetricField::ConvertValue( nSpin, aOrigSize.Width(), 0,
695                                             eUnit, aLeftMF.GetUnit() );
696         aTopMF.SetSpinSize(nSpin);
697         aBottomMF.SetSpinSize(nSpin);
698 
699         //Originalgroesse anzeigen
700         const FieldUnit eMetric = GetModuleFieldUnit( GetItemSet() );
701 
702         MetricField aFld(this, WB_HIDE);
703         SetFieldUnit( aFld, eMetric );
704         aFld.SetDecimalDigits( aWidthMF.GetDecimalDigits() );
705         aFld.SetMax( LONG_MAX - 1 );
706 
707         aFld.SetValue( aFld.Normalize( aOrigSize.Width() ), eUnit );
708         String sTemp = aFld.GetText();
709         aFld.SetValue( aFld.Normalize( aOrigSize.Height() ), eUnit );
710         sTemp += UniString::CreateFromAscii(" x ");
711         sTemp += aFld.GetText();
712         aOrigSizeFT.SetText(sTemp);
713     }
714     aLeftFT         .Enable(bFound);
715     aLeftMF         .Enable(bFound);
716     aRightFT        .Enable(bFound);
717     aRightMF        .Enable(bFound);
718     aTopFT          .Enable(bFound);
719     aTopMF          .Enable(bFound);
720     aBottomFT       .Enable(bFound);
721     aBottomMF       .Enable(bFound);
722     aSizeConstRB    .Enable(bFound);
723     aZoomConstRB    .Enable(bFound);
724     aWidthFT        .Enable(bFound);
725     aWidthMF        .Enable(bFound);
726     aHeightFT       .Enable(bFound);
727     aHeightMF       .Enable(bFound);
728     aWidthZoomFT    .Enable(bFound);
729     aWidthZoomMF    .Enable(bFound);
730     aHeightZoomFT   .Enable(bFound);
731     aHeightZoomMF   .Enable(bFound);
732     aExampleWN      .Enable(bFound);
733     aOrigSizePB     .Enable(bFound);
734     aOrigSizeFT     .Enable(bFound);
735 }
736 
737 IMPL_LINK( SvxGrfCropPage, Timeout, Timer *, EMPTYARG )
738 {
739     DBG_ASSERT(pLastCropField,"Timeout ohne Feld?");
740     CropHdl(pLastCropField);
741     pLastCropField = 0;
742     return 0;
743 }
744 
745 
746 IMPL_LINK( SvxGrfCropPage, CropLoseFocusHdl, MetricField*, pField )
747 {
748     aTimer.Stop();
749     CropHdl(pField);
750     pLastCropField = 0;
751     return 0;
752 }
753 
754 
755 IMPL_LINK( SvxGrfCropPage, CropModifyHdl, MetricField *, pField )
756 {
757     aTimer.Start();
758     pLastCropField = pField;
759     return 0;
760 }
761 
762 Size SvxGrfCropPage::GetGrfOrigSize( const Graphic& rGrf ) const
763 {
764     const MapMode aMapTwip( MAP_TWIP );
765     Size aSize( rGrf.GetPrefSize() );
766     if( MAP_PIXEL == rGrf.GetPrefMapMode().GetMapUnit() )
767         aSize = PixelToLogic( aSize, aMapTwip );
768     else
769         aSize = OutputDevice::LogicToLogic( aSize,
770                                         rGrf.GetPrefMapMode(), aMapTwip );
771     return aSize;
772 }
773 
774 /*****************************************************************/
775 
776 SvxGrfCropPage::SvxCropExample::SvxCropExample( Window* pPar,
777                                                 const ResId& rResId )
778     : Window( pPar, rResId ),
779     aFrameSize( OutputDevice::LogicToLogic(
780                             Size( CM_1_TO_TWIP / 2, CM_1_TO_TWIP / 2 ),
781                             MapMode( MAP_TWIP ), GetMapMode() )),
782     aTopLeft(0,0), aBottomRight(0,0)
783 {
784     SetBorderStyle( WINDOW_BORDER_MONO );
785 }
786 
787 void SvxGrfCropPage::SvxCropExample::Paint( const Rectangle& )
788 {
789     Size aWinSize( PixelToLogic(GetOutputSizePixel() ));
790     SetLineColor();
791     SetFillColor( GetSettings().GetStyleSettings().GetWindowColor() );
792     SetRasterOp( ROP_OVERPAINT );
793     DrawRect( Rectangle( Point(), aWinSize ) );
794 
795     SetLineColor( Color( COL_WHITE ) );
796     Rectangle aRect(Point((aWinSize.Width() - aFrameSize.Width())/2,
797                           (aWinSize.Height() - aFrameSize.Height())/2),
798                           aFrameSize );
799     aGrf.Draw( this,  aRect.TopLeft(), aRect.GetSize() );
800 
801     Size aSz( 2, 0 );
802     aSz = PixelToLogic( aSz );
803     SetFillColor( Color( COL_TRANSPARENT ) );
804     SetRasterOp( ROP_INVERT );
805     aRect.Left()    += aTopLeft.Y();
806     aRect.Top()     += aTopLeft.X();
807     aRect.Right()   -= aBottomRight.Y();
808     aRect.Bottom()  -= aBottomRight.X();
809     DrawRect( aRect );
810 }
811 
812 void SvxGrfCropPage::SvxCropExample::SetFrameSize( const Size& rSz )
813 {
814     aFrameSize = rSz;
815     if(!aFrameSize.Width())
816         aFrameSize.Width() = 1;
817     if(!aFrameSize.Height())
818         aFrameSize.Height() = 1;
819     Size aWinSize( GetOutputSizePixel() );
820     Fraction aXScale( aWinSize.Width() * 4, aFrameSize.Width() * 5 );
821     Fraction aYScale( aWinSize.Height() * 4, aFrameSize.Height() * 5 );
822 
823     if( aYScale < aXScale )
824         aXScale = aYScale;
825 
826     MapMode aMapMode( GetMapMode() );
827 
828     aMapMode.SetScaleX( aXScale );
829     aMapMode.SetScaleY( aXScale );
830 
831     SetMapMode( aMapMode );
832     Invalidate();
833 }
834 
835 
836 
837 
838