xref: /aoo41x/main/cui/source/tabpages/grfpage.cxx (revision cdf0e10c)
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