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