1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_svx.hxx"
31 #ifdef SVX_DLLIMPLEMENTATION
32 #undef SVX_DLLIMPLEMENTATION
35 // include ---------------------------------------------------------------
39 #define _CUI_CHARMAP_CXX_
40 #include <tools/shl.hxx>
41 #include <tools/debug.hxx>
42 #include <vcl/sound.hxx>
43 #include <vcl/svapp.hxx>
44 #include <vcl/msgbox.hxx>
45 #include <svtools/colorcfg.hxx>
46 #include <svtools/eitem.hxx>
47 #include <svtools/intitem.hxx>
48 #include <svtools/stritem.hxx>
49 #include <svtools/itempool.hxx>
51 #include <rtl/textenc.h>
52 #include <svx/ucsubset.hxx>
54 #include <svx/dialogs.hrc>
55 #include <svx/dialmgr.hxx>
56 #include "cuicharmap.hxx"
57 #include <sfx2/request.hxx>
58 #include <sfx2/sfxsids.hrc>
59 #include <sfx2/app.hxx>
60 #include <fontitem.hxx>
61 #include "charmap.hrc"
62 #include "macroass.hxx"
64 // class SvxCharacterMap =================================================
66 SvxCharacterMap::SvxCharacterMap( Window
* pParent
, BOOL bOne
, const SfxItemSet
* pSet
) :
67 SfxModalDialog( pParent
, SVX_RES( RID_SVXDLG_CHARMAP
) ),
70 SFX_ITEMSET_ARG( pSet
, pItem
, SfxBoolItem
, FN_PARAM_1
, FALSE
);
72 bOne
= pItem
->GetValue();
74 SFX_ITEMSET_ARG( pSet
, pCharItem
, SfxInt32Item
, SID_ATTR_CHAR
, FALSE
);
76 SetChar( pItem
->GetValue() );
78 mpCharMapData
= new SvxCharMapData( this, bOne
, &DIALOG_MGR() );
80 SFX_ITEMSET_ARG( pSet
, pDisableItem
, SfxBoolItem
, FN_PARAM_2
, FALSE
);
81 if ( pDisableItem
&& pDisableItem
->GetValue() )
82 DisableFontSelection();
84 SFX_ITEMSET_ARG( pSet
, pFontItem
, SvxFontItem
, SID_ATTR_CHAR_FONT
, FALSE
);
85 SFX_ITEMSET_ARG( pSet
, pFontNameItem
, SfxStringItem
, SID_FONT_NAME
, FALSE
);
88 Font
aFont( pFontItem
->GetFamilyName(), pFontItem
->GetStyleName(), GetCharFont().GetSize() );
89 aFont
.SetCharSet( pFontItem
->GetCharSet() );
90 aFont
.SetPitch( pFontItem
->GetPitch() );
93 else if ( pFontNameItem
)
95 Font
aFont( GetCharFont() );
96 aFont
.SetName( pFontNameItem
->GetValue() );
101 CreateOutputItemSet( pSet
? *pSet
->GetPool() : SFX_APP()->GetPool() );
104 // -----------------------------------------------------------------------
106 SvxCharacterMap::~SvxCharacterMap()
108 delete mpCharMapData
;
111 // -----------------------------------------------------------------------
113 const Font
& SvxCharacterMap::GetCharFont() const
115 return mpCharMapData
->aFont
;
118 // -----------------------------------------------------------------------
120 void SvxCharacterMap::SetChar( sal_UCS4 c
)
122 mpCharMapData
->aShowSet
.SelectCharacter( c
);
125 // -----------------------------------------------------------------------
127 sal_UCS4
SvxCharacterMap::GetChar() const
129 return mpCharMapData
->aShowSet
.GetSelectCharacter();
132 // -----------------------------------------------------------------------
134 String
SvxCharacterMap::GetCharacters() const
136 return mpCharMapData
->aShowText
.GetText();
140 // -----------------------------------------------------------------------
142 void SvxCharacterMap::DisableFontSelection()
144 mpCharMapData
->aFontText
.Disable();
145 mpCharMapData
->aFontLB
.Disable();
148 void SvxCharacterMap::SetCharFont( const Font
& rFont
)
150 mpCharMapData
->SetCharFont( rFont
);
153 short SvxCharacterMap::Execute()
155 short nResult
= SfxModalDialog::Execute();
156 if ( nResult
== RET_OK
)
158 SfxItemSet
* pSet
= GetItemSet();
161 const SfxItemPool
* pPool
= pSet
->GetPool();
162 const Font
& rFont( GetCharFont() );
163 pSet
->Put( SfxStringItem( pPool
->GetWhich(SID_CHARMAP
), GetCharacters() ) );
164 pSet
->Put( SvxFontItem( rFont
.GetFamily(), rFont
.GetName(),
165 rFont
.GetStyleName(), rFont
.GetPitch(), rFont
.GetCharSet(), pPool
->GetWhich(SID_ATTR_CHAR_FONT
) ) );
166 pSet
->Put( SfxStringItem( pPool
->GetWhich(SID_FONT_NAME
), rFont
.GetName() ) );
167 pSet
->Put( SfxInt32Item( pPool
->GetWhich(SID_ATTR_CHAR
), GetChar() ) );
175 // class SvxShowText =====================================================
177 SvxShowText::SvxShowText( Window
* pParent
, const ResId
& rResId
, BOOL bCenter
)
178 : Control( pParent
, rResId
),
182 // -----------------------------------------------------------------------
184 void SvxShowText::Paint( const Rectangle
& )
186 Color aTextCol
= GetTextColor();
188 const StyleSettings
& rStyleSettings
= Application::GetSettings().GetStyleSettings();
189 const Color
aWindowTextColor( rStyleSettings
.GetDialogTextColor() );
190 SetTextColor( aWindowTextColor
);
192 const String aText
= GetText();
193 const Size aSize
= GetOutputSizePixel();
194 Point
aPoint( 2, mnY
);
196 // adjust position using ink boundary if possible
197 Rectangle aBoundRect
;
198 if( !GetTextBoundRect( aBoundRect
, aText
) || aBoundRect
.IsEmpty() )
199 aPoint
.X() = (aSize
.Width() - GetTextWidth( aText
)) / 2;
202 // adjust position before it gets out of bounds
203 aBoundRect
+= aPoint
;
205 // shift back vertically if needed
206 int nYLDelta
= aBoundRect
.Top();
207 int nYHDelta
= aSize
.Height() - aBoundRect
.Bottom();
209 aPoint
.Y() -= nYLDelta
- 1;
210 else if( nYHDelta
<= 0 )
211 aPoint
.Y() += nYHDelta
- 1;
215 // move glyph to middle of cell
216 aPoint
.X() = -aBoundRect
.Left()
217 + (aSize
.Width() - aBoundRect
.GetWidth()) / 2;
221 // shift back horizontally if needed
222 int nXLDelta
= aBoundRect
.Left();
223 int nXHDelta
= aSize
.Width() - aBoundRect
.Right();
225 aPoint
.X() -= nXLDelta
- 1;
226 else if( nXHDelta
<= 0 )
227 aPoint
.X() += nXHDelta
- 1;
231 DrawText( aPoint
, aText
);
232 SetTextColor( aTextCol
);
235 // -----------------------------------------------------------------------
237 void SvxShowText::SetFont( const Font
& rFont
)
239 long nWinHeight
= GetOutputSizePixel().Height();
241 aFont
.SetWeight( WEIGHT_NORMAL
);
242 aFont
.SetAlign( ALIGN_TOP
);
243 aFont
.SetSize( PixelToLogic( Size( 0, nWinHeight
/2 ) ) );
244 aFont
.SetTransparent( TRUE
);
245 Control::SetFont( aFont
);
246 mnY
= ( nWinHeight
- GetTextHeight() ) / 2;
251 // -----------------------------------------------------------------------
253 void SvxShowText::SetText( const String
& rText
)
255 Control::SetText( rText
);
259 // -----------------------------------------------------------------------
261 SvxShowText::~SvxShowText()
264 // class SvxCharacterMap =================================================
266 SvxCharMapData::SvxCharMapData( SfxModalDialog
* pDialog
, BOOL bOne_
, ResMgr
* pResContext
)
267 : mpDialog( pDialog
),
268 aShowSet ( pDialog
, ResId( CT_SHOWSET
, *pResContext
) ),
269 aShowText ( pDialog
, ResId( CT_SHOWTEXT
, *pResContext
) ),
270 // aShowShortcut ( pDialog, ResId( CT_ASSIGN, *pResContext ) ),
271 aOKBtn ( pDialog
, ResId( BTN_CHAR_OK
, *pResContext
) ),
272 aCancelBtn ( pDialog
, ResId( BTN_CHAR_CANCEL
, *pResContext
) ),
273 aHelpBtn ( pDialog
, ResId( BTN_CHAR_HELP
, *pResContext
) ),
274 aDeleteBtn ( pDialog
, ResId( BTN_DELETE
, *pResContext
) ),
275 // aAssignBtn ( pDialog, ResId( BT_ASSIGN, *pResContext ) ),
276 aFontText ( pDialog
, ResId( FT_FONT
, *pResContext
) ),
277 aFontLB ( pDialog
, ResId( LB_FONT
, *pResContext
) ),
278 aSubsetText ( pDialog
, ResId( FT_SUBSET
, *pResContext
) ),
279 aSubsetLB ( pDialog
, ResId( LB_SUBSET
, *pResContext
) ),
280 aSymbolText ( pDialog
, ResId( FT_SYMBOLE
, *pResContext
) ),
281 aShowChar ( pDialog
, ResId( CT_SHOWCHAR
, *pResContext
), TRUE
),
282 aCharCodeText ( pDialog
, ResId( FT_CHARCODE
, *pResContext
) ),
283 // aAssignText ( pDialog, ResId( FT_ASSIGN, *pResContext ) ),
287 aFont
= pDialog
->GetFont();
288 aFont
.SetTransparent( TRUE
);
289 aFont
.SetFamily( FAMILY_DONTKNOW
);
290 aFont
.SetPitch( PITCH_DONTKNOW
);
291 aFont
.SetCharSet( RTL_TEXTENCODING_DONTKNOW
);
295 Size aDlgSize
= pDialog
->GetSizePixel();
296 pDialog
->SetSizePixel( Size( aDlgSize
.Width(),
297 aDlgSize
.Height()-aShowText
.GetSizePixel().Height() ) );
303 String
aDefStr( aFont
.GetName() );
305 int nCount
= mpDialog
->GetDevFontCount();
306 for ( int i
= 0; i
< nCount
; i
++ )
308 String
aFontName( mpDialog
->GetDevFont( i
).GetName() );
309 if ( aFontName
!= aLastName
)
311 aLastName
= aFontName
;
312 USHORT nPos
= aFontLB
.InsertEntry( aFontName
);
313 aFontLB
.SetEntryData( nPos
, (void*)(ULONG
)i
);
316 // the font may not be in the list =>
317 // try to find a font name token in list and select found font,
318 // else select topmost entry
319 FASTBOOL bFound
= (aFontLB
.GetEntryPos( aDefStr
) == LISTBOX_ENTRY_NOTFOUND
);
322 for ( xub_StrLen i
= 0; i
< aDefStr
.GetTokenCount(); ++i
)
324 String aToken
= aDefStr
.GetToken(i
);
325 if ( aFontLB
.GetEntryPos( aToken
) != LISTBOX_ENTRY_NOTFOUND
)
335 aFontLB
.SelectEntry( aDefStr
);
336 else if ( aFontLB
.GetEntryCount() )
337 aFontLB
.SelectEntryPos(0);
338 FontSelectHdl( &aFontLB
);
340 aOKBtn
.SetClickHdl( LINK( this, SvxCharMapData
, OKHdl
) );
341 aFontLB
.SetSelectHdl( LINK( this, SvxCharMapData
, FontSelectHdl
) );
342 aSubsetLB
.SetSelectHdl( LINK( this, SvxCharMapData
, SubsetSelectHdl
) );
343 aShowSet
.SetDoubleClickHdl( LINK( this, SvxCharMapData
, CharDoubleClickHdl
) );
344 aShowSet
.SetSelectHdl( LINK( this, SvxCharMapData
, CharSelectHdl
) );
345 aShowSet
.SetHighlightHdl( LINK( this, SvxCharMapData
, CharHighlightHdl
) );
346 aShowSet
.SetPreSelectHdl( LINK( this, SvxCharMapData
, CharPreSelectHdl
) );
347 aDeleteBtn
.SetClickHdl( LINK( this, SvxCharMapData
, DeleteHdl
) );
348 // aAssignBtn.SetClickHdl( LINK( this, SvxCharMapData, AssignHdl ) );
350 if( SvxShowCharSet::getSelectedChar() == ' ')
355 // left align aShowText field
356 int nLeftEdge
= aSymbolText
.GetPosPixel().X();
357 nLeftEdge
+= aSymbolText
.GetTextWidth( aSymbolText
.GetText() );
358 Size aNewSize
= aShowText
.GetOutputSizePixel();
359 aShowText
.SetPosPixel( Point( nLeftEdge
+4, aShowText
.GetPosPixel().Y() ) );
362 // -----------------------------------------------------------------------
364 void SvxCharMapData::SetCharFont( const Font
& rFont
)
366 // first get the underlying info in order to get font names
367 // like "Times New Roman;Times" resolved
368 Font
aTmp( mpDialog
->GetFontMetric( rFont
) );
370 if ( aFontLB
.GetEntryPos( aTmp
.GetName() ) == LISTBOX_ENTRY_NOTFOUND
)
373 aFontLB
.SelectEntry( aTmp
.GetName() );
375 FontSelectHdl( &aFontLB
);
377 // for compatibility reasons
378 mpDialog
->ModalDialog::SetFont( aFont
);
381 // -----------------------------------------------------------------------
383 IMPL_LINK( SvxCharMapData
, OKHdl
, OKButton
*, EMPTYARG
)
385 String aStr
= aShowText
.GetText();
389 sal_UCS4 cChar
= aShowSet
.GetSelectCharacter();
390 // using the new UCS4 constructor
391 rtl::OUString
aOUStr( &cChar
, 1 );
392 aShowText
.SetText( aOUStr
);
394 mpDialog
->EndDialog( TRUE
);
398 // -----------------------------------------------------------------------
400 IMPL_LINK( SvxCharMapData
, FontSelectHdl
, ListBox
*, EMPTYARG
)
402 USHORT nPos
= aFontLB
.GetSelectEntryPos(),
403 nFont
= (USHORT
)(ULONG
)aFontLB
.GetEntryData( nPos
);
404 aFont
= mpDialog
->GetDevFont( nFont
);
405 aFont
.SetWeight( WEIGHT_DONTKNOW
);
406 aFont
.SetItalic( ITALIC_NONE
);
407 aFont
.SetWidthType( WIDTH_DONTKNOW
);
408 aFont
.SetPitch( PITCH_DONTKNOW
);
409 aFont
.SetFamily( FAMILY_DONTKNOW
);
411 // notify children using this font
412 aShowSet
.SetFont( aFont
);
413 aShowChar
.SetFont( aFont
);
414 aShowText
.SetFont( aFont
);
416 // right align some fields to aShowSet
417 int nRightEdge
= aShowSet
.GetPosPixel().X() + aShowSet
.GetOutputSizePixel().Width();
418 Size aNewSize
= aSubsetLB
.GetOutputSizePixel();
419 aNewSize
.setWidth( nRightEdge
- aSubsetLB
.GetPosPixel().X() );
420 aSubsetLB
.SetOutputSizePixel( aNewSize
);
422 // setup unicode subset listbar with font specific subsets,
423 // hide unicode subset listbar for symbol fonts
424 // TODO: get info from the Font once it provides it
429 BOOL bNeedSubset
= (aFont
.GetCharSet() != RTL_TEXTENCODING_SYMBOL
);
432 FontCharMap aFontCharMap
;
433 aShowSet
.GetFontCharMap( aFontCharMap
);
434 pSubsetMap
= new SubsetMap( &aFontCharMap
);
436 // update subset listbox for new font's unicode subsets
438 // TODO: is it worth to improve the stupid linear search?
441 while( NULL
!= (s
= pSubsetMap
->GetNextSubset( bFirst
)) )
443 USHORT nPos_
= aSubsetLB
.InsertEntry( s
->GetName() );
444 aSubsetLB
.SetEntryData( nPos_
, (void*)s
);
445 // NOTE: subset must live at least as long as the selected font
447 aSubsetLB
.SelectEntryPos( nPos_
);
450 if( aSubsetLB
.GetEntryCount() <= 1 )
454 aSubsetText
.Show( bNeedSubset
);
455 aSubsetLB
.Show( bNeedSubset
);
460 // -----------------------------------------------------------------------
462 IMPL_LINK( SvxCharMapData
, SubsetSelectHdl
, ListBox
*, EMPTYARG
)
464 USHORT nPos
= aSubsetLB
.GetSelectEntryPos();
465 const Subset
* pSubset
= reinterpret_cast<const Subset
*> (aSubsetLB
.GetEntryData(nPos
));
468 sal_UCS4 cFirst
= pSubset
->GetRangeMin();
469 aShowSet
.SelectCharacter( cFirst
);
471 aSubsetLB
.SelectEntryPos( nPos
);
475 // -----------------------------------------------------------------------
477 IMPL_LINK( SvxCharMapData
, CharDoubleClickHdl
, Control
*, EMPTYARG
)
479 mpDialog
->EndDialog( TRUE
);
483 // -----------------------------------------------------------------------
485 IMPL_LINK( SvxCharMapData
, CharSelectHdl
, Control
*, EMPTYARG
)
489 String aText
= aShowText
.GetText();
491 if ( aText
.Len() == CHARMAP_MAXLEN
)
492 Sound::Beep( SOUND_WARNING
);
495 sal_UCS4 cChar
= aShowSet
.GetSelectCharacter();
496 // using the new UCS4 constructor
497 rtl::OUString
aOUStr( &cChar
, 1 );
498 aShowText
.SetText( aText
+ aOUStr
);
506 // -----------------------------------------------------------------------
508 IMPL_LINK( SvxCharMapData
, CharHighlightHdl
, Control
*, EMPTYARG
)
511 sal_UCS4 cChar
= aShowSet
.GetSelectCharacter();
512 sal_Bool bSelect
= (cChar
> 0);
517 // using the new UCS4 constructor
518 aText
= rtl::OUString( &cChar
, 1 );
520 const Subset
* pSubset
= NULL
;
522 pSubset
= pSubsetMap
->GetSubsetByUnicode( cChar
);
524 aSubsetLB
.SelectEntry( pSubset
->GetName() );
526 aSubsetLB
.SetNoSelection();
528 aShowChar
.SetText( aText
);
535 snprintf( aBuf
, sizeof(aBuf
), "U+%04X", static_cast<unsigned>(cChar
) );
537 snprintf( aBuf
+6, sizeof(aBuf
)-6, " (%u)", static_cast<unsigned>(cChar
) );
538 aText
= String::CreateFromAscii( aBuf
);
540 aCharCodeText
.SetText( aText
);
545 // -----------------------------------------------------------------------
547 IMPL_LINK( SvxCharMapData
, CharPreSelectHdl
, Control
*, EMPTYARG
)
549 // adjust subset selection
552 sal_UCS4 cChar
= aShowSet
.GetSelectCharacter();
553 const Subset
* pSubset
= pSubsetMap
->GetSubsetByUnicode( cChar
);
555 aSubsetLB
.SelectEntry( pSubset
->GetName() );
562 // -----------------------------------------------------------------------
564 IMPL_LINK( SvxCharMapData
, DeleteHdl
, PushButton
*, EMPTYARG
)
566 aShowText
.SetText( String() );
571 #include <sfx2/objsh.hxx>
572 #include <vcl/msgbox.hxx>
573 #include <svtools/stritem.hxx>
575 IMPL_LINK( SvxCharMapData
, AssignHdl
, PushButton
*, EMPTYARG
)
577 SfxAllItemSet
aSet( SfxObjectShell::Current()->GetPool() );
578 aSet
.Put( SfxStringItem( SID_CHARMAP
, String::CreateFromAscii("test") ) );
579 SfxModalDialog
* pDlg
= new SfxMacroAssignDlg( mpDialog
, com::sun::star::uno::Reference
< com::sun::star::frame::XFrame
>(), aSet
);
580 if ( pDlg
&& pDlg
->Execute() == RET_OK
)
582 const SfxItemSet
* pOutSet
= pDlg
->GetOutputItemSet();
583 const SfxPoolItem
* pItem
;
584 if( SFX_ITEM_SET
== pOutSet
->GetItemState( SID_CHARMAP
, FALSE
, &pItem
) )
586 // show assigned shortcut