xref: /AOO41X/main/svx/source/tbxctrls/fontworkgallery.cxx (revision ff0525f24f03981d56b7579b645949f111420994)
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