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 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_svx.hxx"
26 
27 #include <com/sun/star/text/WritingMode.hpp>
28 
29 #include <vcl/toolbox.hxx>
30 
31 #include <svl/itempool.hxx>
32 
33 #include <svtools/toolbarmenu.hxx>
34 #include <svtools/popupwindowcontroller.hxx>
35 #include <svtools/popupmenucontrollerbase.hxx>
36 
37 #include <sfx2/app.hxx>
38 #include <sfx2/dispatch.hxx>
39 
40 #include <editeng/eeitem.hxx>
41 #include <editeng/frmdiritem.hxx>
42 
43 #include <svx/fmmodel.hxx>
44 #include <svx/svxids.hrc>
45 #include <svx/dialmgr.hxx>
46 #include <svx/dialogs.hrc>
47 #include <svx/svdpage.hxx>
48 #include <svx/svdobj.hxx>
49 #include <svx/svdview.hxx>
50 #include <svx/svdoutl.hxx>
51 
52 #include "svx/gallery.hxx"
53 #include <svx/dlgutil.hxx>
54 
55 #include <svx/fontworkgallery.hxx>
56 #include "fontworkgallery.hrc"
57 
58 #include <algorithm>
59 
60 #include "helpid.hrc"
61 
62 using ::rtl::OUString;
63 using ::svtools::ToolbarMenu;
64 
65 using namespace ::com::sun::star;
66 using namespace ::com::sun::star::uno;
67 using namespace ::com::sun::star::lang;
68 using namespace ::com::sun::star::beans;
69 using namespace ::com::sun::star::frame;
70 
71 namespace svx
72 {
73 
74 const int nColCount = 4;
75 const int nLineCount = 4;
76 
77 /*************************************************************************
78 |*	Svx3DWin - FloatingWindow
79 \************************************************************************/
80 FontWorkGalleryDialog::FontWorkGalleryDialog( SdrView* pSdrView, Window* pParent, sal_uInt16 /*nSID*/ ) :
81 		ModalDialog( pParent, SVX_RES( RID_SVX_MDLG_FONTWORK_GALLERY ) ),
82 		maFLFavorites		( this, SVX_RES( FL_FAVORITES ) ),
83 		maCtlFavorites		( this, SVX_RES( CTL_FAVORITES ) ),
84 		maOKButton			( this, SVX_RES( BTN_OK ) ),
85 		maCancelButton		( this, SVX_RES( BTN_CANCEL ) ),
86         maHelpButton        ( this, SVX_RES( BTN_HELP ) ),
87 		mnThemeId			( 0xffff ),
88 		mpSdrView			( pSdrView ),
89 		mpModel				( (FmFormModel*)pSdrView->GetModel() ),
90 		maStrClickToAddText ( SVX_RES( STR_CLICK_TO_ADD_TEXT ) ),
91 		mppSdrObject		( NULL ),
92 		mpDestModel			( NULL )
93 {
94 	FreeResource();
95 
96 	maCtlFavorites.SetDoubleClickHdl( LINK( this, FontWorkGalleryDialog, DoubleClickFavoriteHdl ) );
97 	maOKButton.SetClickHdl( LINK( this, FontWorkGalleryDialog, ClickOKHdl ) );
98 
99 	maCtlFavorites.SetColCount( nColCount );
100 	maCtlFavorites.SetLineCount( nLineCount );
101 	maCtlFavorites.SetExtraSpacing( 3 );
102 
103 	initfavorites( GALLERY_THEME_FONTWORK, maFavoritesHorizontal );
104 	fillFavorites( GALLERY_THEME_FONTWORK, maFavoritesHorizontal );
105 }
106 
107 static void delete_bitmap( Bitmap* p ) { delete p; }
108 
109 // -----------------------------------------------------------------------
110 FontWorkGalleryDialog::~FontWorkGalleryDialog()
111 {
112 	std::for_each( maFavoritesHorizontal.begin(), maFavoritesHorizontal.end(), delete_bitmap );
113 }
114 
115 // -----------------------------------------------------------------------
116 
117 void FontWorkGalleryDialog::initfavorites(sal_uInt16 nThemeId, std::vector< Bitmap * >& rFavorites)
118 {
119 	// Ueber die Gallery werden die Favoriten eingelesen
120 	sal_uIntPtr nFavCount = GalleryExplorer::GetSdrObjCount( nThemeId );
121 
122 	// Gallery thema locken
123 	GalleryExplorer::BeginLocking(nThemeId);
124 
125 	sal_uInt32 nModelPos;
126 	FmFormModel *pModel = NULL;
127 	for( nModelPos = 0; nModelPos < nFavCount; nModelPos++ )
128 	{
129 		Bitmap* pThumb = new Bitmap;
130 
131 		if( GalleryExplorer::GetSdrObj( nThemeId, nModelPos, pModel, pThumb ) )
132 		{
133 /*
134 			VirtualDevice aVDev;
135 			Size aRenderSize( aThumbSize.Width() * 4, aThumbSize.Height() * 4 );
136 			aVDev.SetOutputSizePixel( aRenderSize );
137 
138 			if( GalleryExplorer::DrawCentered( &aVDev, *pModel ) )
139 			{
140 				aThumb = aVDev.GetBitmap( Point(), aVDev.GetOutputSizePixel() );
141 
142 				Size aMS( 4, 4 );
143 				BmpFilterParam aParam( aMS );
144 				aThumb.Filter( BMP_FILTER_MOSAIC, &aParam );
145 				aThumb.Scale( aThumbSize );
146 			}
147 */
148 		}
149 
150 		rFavorites.push_back( pThumb );
151 	}
152 
153 	// Gallery thema freigeben
154 	GalleryExplorer::EndLocking(nThemeId);
155 }
156 
157 void FontWorkGalleryDialog::fillFavorites( sal_uInt16 nThemeId, std::vector< Bitmap * >& rFavorites )
158 {
159 	mnThemeId = nThemeId;
160 
161 	Size aThumbSize( maCtlFavorites.GetSizePixel() );
162 	aThumbSize.Width() /= nColCount;
163 	aThumbSize.Height() /= nLineCount;
164 	aThumbSize.Width() -= 12;
165 	aThumbSize.Height() -= 12;
166 
167 	std::vector< Bitmap * >::size_type nFavCount = rFavorites.size();
168 
169 	// ValueSet Favoriten
170 	if( nFavCount > (nColCount * nLineCount) )
171 	{
172 		WinBits nWinBits = maCtlFavorites.GetStyle();
173 		nWinBits |= WB_VSCROLL;
174 		maCtlFavorites.SetStyle( nWinBits );
175 	}
176 
177 	maCtlFavorites.Clear();
178 
179 	sal_uInt32 nFavorite;
180 	for( nFavorite = 1; nFavorite <= nFavCount; nFavorite++ )
181 	{
182 		String aStr(SVX_RES(RID_SVXFLOAT3D_FAVORITE));
183 		aStr += sal_Unicode(' ');
184 		aStr += String::CreateFromInt32((sal_Int32)nFavorite);
185 		Image aThumbImage( *rFavorites[nFavorite-1] );
186 		maCtlFavorites.InsertItem( (sal_uInt16)nFavorite, aThumbImage, aStr );
187 	}
188 }
189 
190 void FontWorkGalleryDialog::changeText( SdrTextObj* pObj )
191 {
192 	if( pObj )
193 	{
194 		SdrOutliner& rOutl = mpModel->GetDrawOutliner(pObj);
195 
196 		sal_uInt16 nOutlMode = rOutl.GetMode();
197 		Size aPaperSize = rOutl.GetPaperSize();
198 		sal_Bool bUpdateMode = rOutl.GetUpdateMode();
199 		rOutl.SetUpdateMode(sal_False);
200 		rOutl.SetParaAttribs( 0, rOutl.GetEmptyItemSet() );
201 
202 		// #95114# Always set the object's StyleSheet at the Outliner to
203 		// use the current objects StyleSheet. Thus it's the same as in
204 		// SetText(...).
205 		// #95114# Moved this implementation from where SetObjText(...) was called
206 		// to inside this method to work even when outliner is fetched here.
207 		rOutl.SetStyleSheet(0, pObj->GetStyleSheet());
208 
209 		rOutl.SetPaperSize( pObj->GetLogicRect().GetSize() );
210 
211 		rOutl.SetText( maStrClickToAddText, rOutl.GetParagraph( 0 ) );
212 		pObj->SetOutlinerParaObject( rOutl.CreateParaObject() );
213 
214 		rOutl.Init( nOutlMode );
215 		rOutl.SetParaAttribs( 0, rOutl.GetEmptyItemSet() );
216 		rOutl.SetUpdateMode( bUpdateMode );
217 		rOutl.SetPaperSize( aPaperSize );
218 
219 		rOutl.Clear();
220 	}
221 }
222 
223 void FontWorkGalleryDialog::SetSdrObjectRef( SdrObject** ppSdrObject, SdrModel* pModel )
224 {
225 	mppSdrObject = ppSdrObject;
226 	mpDestModel = pModel;
227 }
228 
229 void FontWorkGalleryDialog::insertSelectedFontwork()
230 {
231 	sal_uInt16 nItemId = maCtlFavorites.GetSelectItemId();
232 
233 	if( nItemId > 0 )
234 	{
235 		FmFormModel* pModel = new FmFormModel();
236 		pModel->GetItemPool().FreezeIdRanges();
237 
238 		if( GalleryExplorer::GetSdrObj( mnThemeId, nItemId-1, pModel ) )
239 		{
240 			SdrPage* pPage = pModel->GetPage(0);
241 			if( pPage && pPage->GetObjCount() )
242 			{
243 				SdrObject* pNewObject = pPage->GetObj(0)->Clone();
244 
245 				// center shape on current view
246 				OutputDevice* pOutDev = mpSdrView->GetFirstOutputDevice();
247 				if( pOutDev )
248 				{
249 					Rectangle aObjRect( pNewObject->GetLogicRect() );
250 					Rectangle aVisArea = pOutDev->PixelToLogic(Rectangle(Point(0,0), pOutDev->GetOutputSizePixel()));
251 /*
252 					sal_Int32 nObjHeight = aObjRect.GetHeight();
253 					VirtualDevice aVirDev( 1 );	// calculating the optimal textwidth
254 					Font aFont;
255 					aFont.SetHeight( nObjHeight );
256 					aVirDev.SetMapMode( MAP_100TH_MM );
257 					aVirDev.SetFont( aFont );
258 					aObjRect.SetSize( Size( aVirDev.GetTextWidth( maStrClickToAddText ), nObjHeight ) );
259 */
260 					Point aPagePos = aVisArea.Center();
261 					aPagePos.X() -= aObjRect.GetWidth() / 2;
262 					aPagePos.Y() -= aObjRect.GetHeight() / 2;
263 					Rectangle aNewObjectRectangle(aPagePos, aObjRect.GetSize());
264 					SdrPageView* pPV = mpSdrView->GetSdrPageView();
265 
266 					pNewObject->SetLogicRect(aNewObjectRectangle);
267 					if ( mppSdrObject )
268 					{
269 						*mppSdrObject = pNewObject;
270 						(*mppSdrObject)->SetModel( mpDestModel );
271 					}
272 					else if( pPV )
273 					{
274 							mpSdrView->InsertObjectAtView( pNewObject, *pPV );
275 	//						changeText( PTR_CAST( SdrTextObj, pNewObject ) );
276 					}
277 				}
278 			}
279 		}
280 
281 		delete pModel;
282 	}
283 }
284 
285 // -----------------------------------------------------------------------
286 
287 IMPL_LINK( FontWorkGalleryDialog, ClickOKHdl, void*, EMPTYARG )
288 {
289 	insertSelectedFontwork();
290 	EndDialog( true );
291 	return 0;
292 }
293 
294 // -----------------------------------------------------------------------
295 
296 IMPL_LINK( FontWorkGalleryDialog, DoubleClickFavoriteHdl, void*, EMPTYARG )
297 {
298 	insertSelectedFontwork();
299 	EndDialog( true );
300 	return( 0L );
301 }
302 
303 //------------------------------------------------------------------------
304 
305 SFX_IMPL_TOOLBOX_CONTROL( FontWorkShapeTypeControl, SfxStringItem );
306 FontWorkShapeTypeControl::FontWorkShapeTypeControl(	sal_uInt16 nSlotId, sal_uInt16 nId, ToolBox &rTbx )
307 : SfxToolBoxControl( nSlotId, nId, rTbx )
308 {
309 	rTbx.SetItemBits( nId, TIB_DROPDOWNONLY | rTbx.GetItemBits( nId ) );
310 	rTbx.Invalidate();
311 }
312 
313 // -----------------------------------------------------------------------
314 
315 FontWorkShapeTypeControl::~FontWorkShapeTypeControl()
316 {
317 }
318 
319 // -----------------------------------------------------------------------
320 
321 SfxPopupWindowType FontWorkShapeTypeControl::GetPopupWindowType() const
322 {
323 	return SFX_POPUPWINDOW_ONCLICK; //( aLastAction.getLength() == 0 ? SFX_POPUPWINDOW_ONCLICK : SFX_POPUPWINDOW_ONTIMEOUT );
324 }
325 
326 // -----------------------------------------------------------------------
327 
328 SfxPopupWindow*	FontWorkShapeTypeControl::CreatePopupWindow()
329 {
330 	rtl::OUString aSubTbxResName( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/fontworkshapetype" ) );
331     createAndPositionSubToolBar( aSubTbxResName );
332 	return NULL;
333 }
334 
335 // -----------------------------------------------------------------------
336 
337 void FontWorkShapeTypeControl::Select( sal_Bool )
338 {
339 
340 }
341 
342 // ========================================================================
343 // FontWorkAlignmentWindow
344 // ========================================================================
345 
346 class FontWorkAlignmentWindow : public ToolbarMenu
347 {
348 public:
349 	FontWorkAlignmentWindow( svt::ToolboxController& rController, const Reference< XFrame >& rFrame, Window* pParentWindow );
350 
351 	virtual void SAL_CALL statusChanged( const frame::FeatureStateEvent& Event ) throw ( RuntimeException );
352 	virtual void DataChanged( const DataChangedEvent& rDCEvt );
353 
354 private:
355 	svt::ToolboxController& mrController;
356 
357 	Image maImgAlgin1;
358 	Image maImgAlgin2;
359 	Image maImgAlgin3;
360 	Image maImgAlgin4;
361 	Image maImgAlgin5;
362 	Image maImgAlgin1h;
363 	Image maImgAlgin2h;
364 	Image maImgAlgin3h;
365 	Image maImgAlgin4h;
366 	Image maImgAlgin5h;
367 
368 	const rtl::OUString msFontworkAlignment;
369 
370 	DECL_LINK( SelectHdl, void * );
371 
372 	void	implSetAlignment( int nAlignmentMode, bool bEnabled );
373 };
374 
375 FontWorkAlignmentWindow::FontWorkAlignmentWindow( svt::ToolboxController& rController, const Reference< XFrame >& rFrame, Window* pParentWindow )
376 : ToolbarMenu( rFrame, pParentWindow, SVX_RES( RID_SVXFLOAT_FONTWORK_ALIGNMENT ))
377 , mrController( rController )
378 , maImgAlgin1( SVX_RES( IMG_FONTWORK_ALIGN_LEFT_16 ) )
379 , maImgAlgin2( SVX_RES( IMG_FONTWORK_ALIGN_CENTER_16 ) )
380 , maImgAlgin3( SVX_RES( IMG_FONTWORK_ALIGN_RIGHT_16 ) )
381 , maImgAlgin4( SVX_RES( IMG_FONTWORK_ALIGN_WORD_16 ) )
382 , maImgAlgin5( SVX_RES( IMG_FONTWORK_ALIGN_STRETCH_16 ) )
383 , maImgAlgin1h( SVX_RES( IMG_FONTWORK_ALIGN_LEFT_16_H ) )
384 , maImgAlgin2h( SVX_RES( IMG_FONTWORK_ALIGN_CENTER_16_H ) )
385 , maImgAlgin3h( SVX_RES( IMG_FONTWORK_ALIGN_RIGHT_16_H ) )
386 , maImgAlgin4h( SVX_RES( IMG_FONTWORK_ALIGN_WORD_16_H ) )
387 , maImgAlgin5h( SVX_RES( IMG_FONTWORK_ALIGN_STRETCH_16_H ) )
388 , msFontworkAlignment( RTL_CONSTASCII_USTRINGPARAM( ".uno:FontworkAlignment" ) )
389 {
390 	bool bHighContrast = GetSettings().GetStyleSettings().GetHighContrastMode();
391 
392 	SetHelpId( HID_POPUP_FONTWORK_ALIGN );
393 	SetSelectHdl( LINK( this, FontWorkAlignmentWindow, SelectHdl ) );
394 
395 	appendEntry( 0, String( SVX_RES( STR_ALIGN_LEFT ) ), bHighContrast ? maImgAlgin1h : maImgAlgin1 );
396 	appendEntry( 1, String( SVX_RES( STR_ALIGN_CENTER ) ), bHighContrast ? maImgAlgin2h : maImgAlgin2 );
397 	appendEntry( 2, String( SVX_RES( STR_ALIGN_RIGHT ) ), bHighContrast ? maImgAlgin3h : maImgAlgin3 );
398 	appendEntry( 3, String( SVX_RES( STR_ALIGN_WORD ) ), bHighContrast ? maImgAlgin4h : maImgAlgin4 );
399 	appendEntry( 4, String( SVX_RES( STR_ALIGN_STRETCH ) ), bHighContrast ? maImgAlgin5h : maImgAlgin5 );
400 
401 	SetOutputSizePixel( getMenuSize() );
402 
403 	FreeResource();
404 
405     AddStatusListener( msFontworkAlignment );
406 }
407 
408 // -----------------------------------------------------------------------
409 
410 void FontWorkAlignmentWindow::implSetAlignment( int nSurface, bool bEnabled )
411 {
412 	int i;
413 	for( i = 0; i < 5; i++ )
414 	{
415 		checkEntry( i, (i == nSurface) && bEnabled );
416 		enableEntry( i, bEnabled );
417 	}
418 }
419 
420 // -----------------------------------------------------------------------
421 
422 void SAL_CALL FontWorkAlignmentWindow::statusChanged( const frame::FeatureStateEvent& Event ) throw ( RuntimeException )
423 {
424 	if( Event.FeatureURL.Main.equals( msFontworkAlignment ) )
425 	{
426 		if( !Event.IsEnabled )
427 		{
428 			implSetAlignment( 0, false );
429 		}
430 		else
431 		{
432 			sal_Int32 nValue = 0;
433 			if( Event.State >>= nValue )
434 				implSetAlignment( nValue, true );
435 		}
436 	}
437 }
438 
439 // -----------------------------------------------------------------------
440 
441 void FontWorkAlignmentWindow::DataChanged( const DataChangedEvent& rDCEvt )
442 {
443 	ToolbarMenu::DataChanged( rDCEvt );
444 
445 	if( ( rDCEvt.GetType() == DATACHANGED_SETTINGS ) && ( rDCEvt.GetFlags() & SETTINGS_STYLE ) )
446 	{
447 		bool bHighContrast = GetSettings().GetStyleSettings().GetHighContrastMode();
448 
449 		appendEntry( 0, String( SVX_RES( STR_ALIGN_LEFT ) ), bHighContrast ? maImgAlgin1h : maImgAlgin1 );
450 		appendEntry( 1, String( SVX_RES( STR_ALIGN_CENTER ) ), bHighContrast ? maImgAlgin2h : maImgAlgin2 );
451 		appendEntry( 2, String( SVX_RES( STR_ALIGN_RIGHT ) ), bHighContrast ? maImgAlgin3h : maImgAlgin3 );
452 		appendEntry( 3, String( SVX_RES( STR_ALIGN_WORD ) ), bHighContrast ? maImgAlgin4h : maImgAlgin4 );
453 		appendEntry( 4, String( SVX_RES( STR_ALIGN_STRETCH ) ), bHighContrast ? maImgAlgin5h : maImgAlgin5 );
454 	}
455 }
456 
457 // -----------------------------------------------------------------------
458 
459 IMPL_LINK( FontWorkAlignmentWindow, SelectHdl, void *, EMPTYARG )
460 {
461 	if ( IsInPopupMode() )
462 		EndPopupMode();
463 
464 	sal_Int32 nAlignment = getSelectedEntryId();
465 	if( nAlignment >= 0 )
466 	{
467         Sequence< PropertyValue > aArgs( 1 );
468         aArgs[0].Name = msFontworkAlignment.copy(5);
469         aArgs[0].Value <<= (sal_Int32)nAlignment;
470 
471 		mrController.dispatchCommand( msFontworkAlignment, aArgs );
472 
473 		implSetAlignment( nAlignment, true );
474 	}
475 
476 	return 0;
477 }
478 
479 // ========================================================================
480 // FontWorkAlignmentControl
481 // ========================================================================
482 
483 class FontWorkAlignmentControl : public svt::PopupWindowController
484 {
485 public:
486 	FontWorkAlignmentControl( const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& rServiceManager );
487 
488 	virtual ::Window* createPopupWindow( ::Window* pParent );
489 
490     // XServiceInfo
491     virtual ::rtl::OUString SAL_CALL getImplementationName() throw( ::com::sun::star::uno::RuntimeException );
492     virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw( ::com::sun::star::uno::RuntimeException );
493 
494 	using  svt::PopupWindowController::createPopupWindow;
495 };
496 
497 
498 // -----------------------------------------------------------------------
499 
500 FontWorkAlignmentControl::FontWorkAlignmentControl( const Reference< lang::XMultiServiceFactory >& rServiceManager )
501 : svt::PopupWindowController( rServiceManager, Reference< frame::XFrame >(), OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:FontworkAlignment" ) ) )
502 {
503 }
504 
505 // -----------------------------------------------------------------------
506 
507 ::Window* FontWorkAlignmentControl::createPopupWindow( ::Window* pParent )
508 {
509     return new FontWorkAlignmentWindow( *this, m_xFrame, pParent );
510 }
511 
512 // -----------------------------------------------------------------------
513 // XServiceInfo
514 // -----------------------------------------------------------------------
515 
516 OUString SAL_CALL FontWorkAlignmentControl_getImplementationName()
517 {
518 	return OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.svx.FontWorkAlignmentController" ));
519 }
520 
521 // --------------------------------------------------------------------
522 
523 Sequence< OUString > SAL_CALL FontWorkAlignmentControl_getSupportedServiceNames() throw( RuntimeException )
524 {
525     Sequence< OUString > aSNS( 1 );
526     aSNS.getArray()[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.ToolbarController" ));
527     return aSNS;
528 }
529 
530 // --------------------------------------------------------------------
531 
532 Reference< XInterface > SAL_CALL SAL_CALL FontWorkAlignmentControl_createInstance( const Reference< XMultiServiceFactory >& rSMgr ) throw( RuntimeException )
533 {
534 	return *new FontWorkAlignmentControl( rSMgr );
535 }
536 
537 // --------------------------------------------------------------------
538 
539 OUString SAL_CALL FontWorkAlignmentControl::getImplementationName(  ) throw (RuntimeException)
540 {
541 	return FontWorkAlignmentControl_getImplementationName();
542 }
543 
544 // --------------------------------------------------------------------
545 
546 Sequence< OUString > SAL_CALL FontWorkAlignmentControl::getSupportedServiceNames(  ) throw (RuntimeException)
547 {
548 	return FontWorkAlignmentControl_getSupportedServiceNames();
549 }
550 
551 
552 // ####################################################################
553 
554 class FontWorkCharacterSpacingWindow : public ToolbarMenu
555 {
556 public:
557 	FontWorkCharacterSpacingWindow( svt::ToolboxController& rController, const Reference< XFrame >& rFrame, Window* pParentWindow );
558 
559 	virtual void SAL_CALL statusChanged( const ::com::sun::star::frame::FeatureStateEvent& Event ) throw ( ::com::sun::star::uno::RuntimeException );
560 private:
561 	svt::ToolboxController& mrController;
562 
563 	const rtl::OUString msFontworkCharacterSpacing;
564 	const rtl::OUString msFontworkKernCharacterPairs;
565 
566 	DECL_LINK( SelectHdl, void * );
567 
568 	void	implSetCharacterSpacing( sal_Int32 nCharacterSpacing, bool bEnabled );
569 	void	implSetKernCharacterPairs( sal_Bool bKernOnOff, bool bEnabled );
570 
571 };
572 
573 // -----------------------------------------------------------------------
574 
575 FontWorkCharacterSpacingWindow::FontWorkCharacterSpacingWindow( svt::ToolboxController& rController, const Reference< XFrame >& rFrame, Window* pParentWindow )
576 : ToolbarMenu( rFrame, pParentWindow, SVX_RES( RID_SVXFLOAT_FONTWORK_CHARSPACING ))
577 , mrController( rController )
578 , msFontworkCharacterSpacing( RTL_CONSTASCII_USTRINGPARAM( ".uno:FontworkCharacterSpacing" ) )
579 , msFontworkKernCharacterPairs( RTL_CONSTASCII_USTRINGPARAM( ".uno:FontworkKernCharacterPairs" ) )
580 {
581 	SetHelpId( HID_POPUP_FONTWORK_CHARSPACE );
582 	SetSelectHdl( LINK( this, FontWorkCharacterSpacingWindow, SelectHdl ) );
583 
584 	appendEntry( 0, String( SVX_RES( STR_CHARS_SPACING_VERY_TIGHT ) ), MIB_RADIOCHECK );
585 	appendEntry( 1, String( SVX_RES( STR_CHARS_SPACING_TIGHT ) ), MIB_RADIOCHECK );
586 	appendEntry( 2, String( SVX_RES( STR_CHARS_SPACING_NORMAL ) ), MIB_RADIOCHECK );
587 	appendEntry( 3, String( SVX_RES( STR_CHARS_SPACING_LOOSE ) ), MIB_RADIOCHECK );
588 	appendEntry( 4, String( SVX_RES( STR_CHARS_SPACING_VERY_LOOSE ) ), MIB_RADIOCHECK );
589 	appendEntry( 5, String( SVX_RES( STR_CHARS_SPACING_CUSTOM ) ), MIB_RADIOCHECK );
590 	appendSeparator();
591 	appendEntry( 6, String( SVX_RES( STR_CHARS_SPACING_KERN_PAIRS ) ), MIB_CHECKABLE );
592 
593 	SetOutputSizePixel( getMenuSize() );
594 
595 	FreeResource();
596 
597     AddStatusListener( msFontworkCharacterSpacing );
598 	AddStatusListener( msFontworkKernCharacterPairs );
599 }
600 
601 // -----------------------------------------------------------------------
602 
603 void FontWorkCharacterSpacingWindow::implSetCharacterSpacing( sal_Int32 nCharacterSpacing, bool bEnabled )
604 {
605 	sal_Int32 i;
606 	for ( i = 0; i < 6; i++ )
607 	{
608 		checkEntry( i, sal_False );
609 		enableEntry( i, bEnabled );
610 	}
611 	if ( nCharacterSpacing != -1 )
612 	{
613 		sal_Int32 nEntry;
614 		switch( nCharacterSpacing )
615 		{
616 			case 80 : nEntry = 0; break;
617 			case 90 : nEntry = 1; break;
618 			case 100 : nEntry = 2; break;
619 			case 120 : nEntry = 3; break;
620 			case 150 : nEntry = 4; break;
621 			default : nEntry = 5; break;
622 		}
623 		checkEntry( nEntry, bEnabled );
624 	}
625 }
626 
627 // -----------------------------------------------------------------------
628 
629 void FontWorkCharacterSpacingWindow::implSetKernCharacterPairs( sal_Bool, bool bEnabled )
630 {
631 	enableEntry( 6, bEnabled );
632 	checkEntry( 6, bEnabled );
633 }
634 
635 // -----------------------------------------------------------------------
636 
637 void SAL_CALL FontWorkCharacterSpacingWindow::statusChanged( const ::com::sun::star::frame::FeatureStateEvent& Event ) throw ( ::com::sun::star::uno::RuntimeException )
638 {
639 	if( Event.FeatureURL.Main.equals( msFontworkCharacterSpacing ) )
640 	{
641 		if( !Event.IsEnabled )
642 		{
643 			implSetCharacterSpacing( 0, false );
644 		}
645 		else
646 		{
647 			sal_Int32 nValue = 0;
648 			if( Event.State >>= nValue )
649 				implSetCharacterSpacing( nValue, true );
650 		}
651 	}
652 	else if( Event.FeatureURL.Main.equals( msFontworkKernCharacterPairs ) )
653 	{
654 		if( !Event.IsEnabled )
655 		{
656 			implSetKernCharacterPairs( 0, false );
657 		}
658 		else
659 		{
660 			sal_Bool bValue = sal_False;
661 			if( Event.State >>= bValue )
662 				implSetKernCharacterPairs( bValue, true );
663 		}
664 	}
665 }
666 
667 // -----------------------------------------------------------------------
668 
669 IMPL_LINK( FontWorkCharacterSpacingWindow, SelectHdl, void *, EMPTYARG )
670 {
671 	if ( IsInPopupMode() )
672 		EndPopupMode();
673 
674 	sal_Int32 nSelection = getSelectedEntryId();
675 	sal_Int32 nCharacterSpacing;
676 	switch( nSelection )
677 	{
678 		case 0 : nCharacterSpacing = 80; break;
679 		case 1 : nCharacterSpacing = 90; break;
680 		case 2 : nCharacterSpacing = 100; break;
681 		case 3 : nCharacterSpacing = 120; break;
682 		case 4 : nCharacterSpacing = 150; break;
683 		default : nCharacterSpacing = 100; break;
684 	}
685 	if ( nSelection == 5 )	// custom spacing
686 	{
687         Sequence< PropertyValue > aArgs( 1 );
688         aArgs[0].Name = msFontworkCharacterSpacing.copy(5);
689         aArgs[0].Value <<= (sal_Int32)nCharacterSpacing;
690 
691 		mrController.dispatchCommand( OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:FontworkCharacterSpacingDialog" )), aArgs );
692 	}
693 	else if ( nSelection == 6 )	// KernCharacterPairs
694 	{
695         rtl::OUString   aCommand( RTL_CONSTASCII_USTRINGPARAM( ".uno:FontworkKernCharacterPairs" ));
696 
697         Sequence< PropertyValue > aArgs( 1 );
698         aArgs[0].Name = msFontworkKernCharacterPairs.copy(5);
699         aArgs[0].Value <<= (sal_Bool) sal_True;
700 
701 		mrController.dispatchCommand( msFontworkKernCharacterPairs, aArgs );
702 
703 		implSetKernCharacterPairs( sal_True, true );
704 	}
705 	else if( nSelection >= 0 )
706 	{
707         Sequence< PropertyValue > aArgs( 1 );
708         aArgs[0].Name = msFontworkCharacterSpacing.copy(5);
709         aArgs[0].Value <<=( sal_Int32)nCharacterSpacing;
710 
711         mrController.dispatchCommand( msFontworkCharacterSpacing,  aArgs );
712 
713 		implSetCharacterSpacing( nCharacterSpacing, true );
714 	}
715 
716 	return 0;
717 }
718 
719 // ========================================================================
720 // FontWorkCharacterSpacingControl
721 // ========================================================================
722 
723 class FontWorkCharacterSpacingControl : public svt::PopupWindowController
724 {
725 public:
726 	FontWorkCharacterSpacingControl( const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& rServiceManager );
727 
728 	virtual ::Window* createPopupWindow( ::Window* pParent );
729 
730     // XServiceInfo
731     virtual ::rtl::OUString SAL_CALL getImplementationName() throw( ::com::sun::star::uno::RuntimeException );
732     virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw( ::com::sun::star::uno::RuntimeException );
733 
734 	using svt::PopupWindowController::createPopupWindow;
735 };
736 
737 
738 FontWorkCharacterSpacingControl::FontWorkCharacterSpacingControl( const Reference< lang::XMultiServiceFactory >& rServiceManager )
739 : svt::PopupWindowController( rServiceManager, Reference< frame::XFrame >(), OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:FontworkCharacterSpacingFloater" ) ) )
740 {
741 }
742 
743 // -----------------------------------------------------------------------
744 
745 ::Window* FontWorkCharacterSpacingControl::createPopupWindow( ::Window* pParent )
746 {
747     return new FontWorkCharacterSpacingWindow( *this, m_xFrame, pParent );
748 }
749 
750 // -----------------------------------------------------------------------
751 // XServiceInfo
752 // -----------------------------------------------------------------------
753 
754 OUString SAL_CALL FontWorkCharacterSpacingControl_getImplementationName()
755 {
756 	return OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.svx.FontWorkCharacterSpacingController" ));
757 }
758 
759 // --------------------------------------------------------------------
760 
761 Sequence< OUString > SAL_CALL FontWorkCharacterSpacingControl_getSupportedServiceNames() throw( RuntimeException )
762 {
763     Sequence< OUString > aSNS( 1 );
764     aSNS.getArray()[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.ToolbarController" ));
765     return aSNS;
766 }
767 
768 // --------------------------------------------------------------------
769 
770 Reference< XInterface > SAL_CALL SAL_CALL FontWorkCharacterSpacingControl_createInstance( const Reference< XMultiServiceFactory >& rSMgr ) throw( RuntimeException )
771 {
772 	return *new FontWorkCharacterSpacingControl( rSMgr );
773 }
774 
775 // --------------------------------------------------------------------
776 
777 OUString SAL_CALL FontWorkCharacterSpacingControl::getImplementationName(  ) throw (RuntimeException)
778 {
779 	return FontWorkCharacterSpacingControl_getImplementationName();
780 }
781 
782 // --------------------------------------------------------------------
783 
784 Sequence< OUString > SAL_CALL FontWorkCharacterSpacingControl::getSupportedServiceNames(  ) throw (RuntimeException)
785 {
786 	return FontWorkCharacterSpacingControl_getSupportedServiceNames();
787 }
788 
789 // ========================================================================
790 // FontworkCharacterSpacingDialog
791 // ========================================================================
792 
793 FontworkCharacterSpacingDialog::FontworkCharacterSpacingDialog( Window* pParent, sal_Int32 nScale )
794 :	ModalDialog( pParent, SVX_RES( RID_SVX_MDLG_FONTWORK_CHARSPACING ) ),
795 	maFLScale( this, SVX_RES( FT_VALUE ) ),
796 	maMtrScale( this, SVX_RES( MF_VALUE ) ),
797 	maOKButton( this, SVX_RES( BTN_OK ) ),
798 	maCancelButton( this, SVX_RES( BTN_CANCEL ) ),
799 	maHelpButton( this, SVX_RES( BTN_HELP ) )
800 {
801 	maMtrScale.SetValue( nScale );
802 	FreeResource();
803 }
804 
805 FontworkCharacterSpacingDialog::~FontworkCharacterSpacingDialog()
806 {
807 }
808 
809 sal_Int32 FontworkCharacterSpacingDialog::getScale() const
810 {
811 	return (sal_Int32)maMtrScale.GetValue();
812 }
813 
814 }
815