xref: /aoo41x/main/padmin/source/fontentry.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #include "fontentry.hxx"
29 #include "helper.hxx"
30 #include "padialog.hrc"
31 #include "vcl/strhelper.hxx"
32 
33 #include "vcl/msgbox.hxx"
34 #include "vcl/fontmanager.hxx"
35 
36 #include "osl/thread.h"
37 
38 #include "tools/config.hxx"
39 
40 using namespace padmin;
41 using namespace osl;
42 using namespace rtl;
43 using namespace psp;
44 
45 #if 0
46 static void CreateAfmFile( const INetURLObject& rFontFile )
47 {
48 	rtl_TextEncoding aEncoding = gsl_getSystemTextEncoding();
49 
50 	INetURLObject aFontMap( rFontFile.GetPath(), INET_PROT_FILE, INetURLObject::ENCODE_ALL );
51 	aFontMap.Append( String( RTL_CONSTASCII_USTRINGPARAM( "Fontmap" ) ) );
52 	INetURLObject aAfmFile( rFontFile );
53 	aAfmFile.setExtension( String::CreateFromAscii( "afm", 3 ) );
54 
55 
56 	SvFileStream aMap( aFontMap.PathToFileName(), STREAM_WRITE | STREAM_TRUNC );
57 	if( aMap.IsOpen() )
58 	{
59 		SvFileStream aRead( rFontFile.GetFull(), STREAM_READ );
60 		ByteString aLine;
61 		ByteString aFullName;
62 		int nPos;
63 		while( ! aRead.IsEof() &&
64 			   ( nPos = aLine.Search( "/FullName" ) ) == STRING_NOTFOUND )
65 			aRead.ReadLine( aLine );
66 		aRead.Close();
67 		if( nPos != STRING_NOTFOUND )
68 		{
69 			aLine.Erase( 0, nPos );
70 			aFullName = aLine.GetToken( 1, '(' ).GetToken( 0, ')' );
71 
72 			aLine = '/';
73 			aLine += aFullName;
74 			aLine += ' ';
75 			aLine += '(';
76 			aLine += ByteString( rFontFile.GetName(), aEncoding );
77 			aLine += ')';
78 			aLine += ';';
79 
80 			aMap.WriteLine( aLine );
81 		}
82 		aMap.Close();
83 		pid_t nPID = fork();
84 		if( ! nPID )
85 		{
86 			INetURLObject aTmp( rFontFile );
87 			aTmp.CutName();
88 			ByteString aEnv( "GS_LIB=" );
89 			aEnv += ByteString( aTmp.PathToFileName(), aEncoding );
90 			putenv( const_cast<char*>(aEnv.GetBuffer()) );
91 
92 			int nDescr = open( ByteString( aAfmFile.PathToFileName(), aEncoding ).GetBuffer(),
93 							   O_CREAT | O_TRUNC| O_WRONLY,
94 							   00755 );
95 #if OSL_DEBUG_LEVEL > 1
96 			if( nDescr < 0 )
97 				fprintf( stderr, "open( %s ) failed because of %d\n", ByteString( aAfmFile.GetFull(), aEncoding ).GetBuffer(), errno );
98 #endif
99 			if( dup2( nDescr, STDOUT_FILENO ) > 0 )
100 			{
101 				execlp( "gs",
102 						"-q",
103 						"-dNODISPLAY",
104 						"--", "printafm.ps",
105 						aFullName.GetBuffer(),
106 						NULL );
107 			}
108 #if OSL_DEBUG_LEVEL > 1
109 			else
110 				fprintf( stderr, "dup2( %d, %d ) failed because of %d\n", nDescr, STDOUT_FILENO, errno );
111 #endif
112 			_exit( 0 );
113 		}
114 		if( nPID > 0 )
115 			waitpid( nPID, NULL, 0 );
116 		MetricConverter::ConvertAFM( aAfmFile );
117 	}
118 
119 	struct stat aStat;
120 	ByteString aSysFile( aAfmFile.PathToFileName(), aEncoding );
121 	if( stat( aSysFile.GetBuffer(), &aStat ) || ! aStat.st_size )
122 		unlink( aSysFile.GetBuffer() );
123 #if OSL_DEBUG_LEVEL > 1
124 	fprintf( stderr, " %s\n", ! access( aSysFile.GetBuffer(), F_OK ) ? "success" : "failed" );
125 #endif
126 	unlink( ByteString( aFontMap.PathToFileName(), aEncoding ).GetBuffer() );
127 }
128 
129 #endif
130 
131 FontNameDlg::FontNameDlg( Window *pParent ) :
132 		ModalDialog( pParent, PaResId( RID_FONTNAMEDIALOG ) ),
133 		m_aOKButton( this, PaResId( RID_FNTNM_BTN_OK ) ),
134         m_aRenameButton( this, PaResId( RID_FNTNM_BTN_RENAME ) ),
135 		m_aRemoveButton( this, PaResId( RID_FNTNM_BTN_REMOVE ) ),
136         m_aImportButton( this, PaResId( RID_FNTNM_BTN_IMPORT ) ),
137 		m_aFontBox( this, PaResId( RID_FNTNM_LB_FONTS ) ),
138 		m_aFixedText( this, PaResId( RID_FNTNM_FIXED ) ),
139         m_aRenameString( PaResId( RID_FNTNM_STR_RENAME ) ),
140         m_aRenameTTCString( PaResId( RID_FNTNM_STR_TTCRENAME ) ),
141         m_aNoRenameString( PaResId( RID_FNTNM_STR_NOTRENAMABLE ) ),
142 		m_rFontManager( PrintFontManager::get() )
143 {
144 	FreeResource();
145 
146 	m_aFontBox.EnableMultiSelection( sal_True );
147 
148 	m_aOKButton.SetClickHdl( LINK( this, FontNameDlg, ClickBtnHdl ) );
149     m_aRenameButton.SetClickHdl( LINK( this, FontNameDlg, ClickBtnHdl ) );
150 	m_aRemoveButton.SetClickHdl( LINK( this, FontNameDlg, ClickBtnHdl ) );
151     m_aImportButton.SetClickHdl( LINK( this, FontNameDlg, ClickBtnHdl ) );
152 	m_aFontBox.setDelPressedLink( LINK( this, FontNameDlg, DelPressedHdl ) );
153     m_aFontBox.SetSelectHdl( LINK( this, FontNameDlg, SelectHdl ) );
154 
155     init();
156 }
157 
158 FontNameDlg::~FontNameDlg()
159 {
160 }
161 
162 String FontNameDlg::fillFontEntry( FastPrintFontInfo& rInfo, const String& rFile, bool bAddRegular )
163 {
164     static String aThinTxt( PaResId( RID_TXT_FONT_THIN ) );
165     static String aUltraLightTxt( PaResId( RID_TXT_FONT_ULTRALIGHT ) );
166     static String aLightTxt( PaResId( RID_TXT_FONT_LIGHT ) );
167     static String aSemiLightTxt( PaResId( RID_TXT_FONT_SEMILIGHT ) );
168     static String aSemiBoldTxt( PaResId( RID_TXT_FONT_SEMIBOLD ) );
169     static String aBoldTxt( PaResId( RID_TXT_FONT_BOLD ) );
170     static String aUltraBoldTxt( PaResId( RID_TXT_FONT_ULTRABOLD ) );
171 
172     static String aItalicTxt( PaResId( RID_TXT_FONT_ITALIC ) );
173     static String aObliqueTxt( PaResId( RID_TXT_FONT_OBLIQUE ) );
174 
175     static String aUltraCondensedTxt( PaResId( RID_TXT_FONT_ULTRACONDENSED ) );
176     static String aExtraCondensedTxt( PaResId( RID_TXT_FONT_EXTRACONDENSED ) );
177     static String aCondensedTxt( PaResId( RID_TXT_FONT_CONDENSED ) );
178     static String aSemiCondensedTxt( PaResId( RID_TXT_FONT_SEMICONDENSED ) );
179     static String aSemiExpandedTxt( PaResId( RID_TXT_FONT_SEMIEXPANDED ) );
180     static String aExpandedTxt( PaResId( RID_TXT_FONT_EXPANDED ) );
181     static String aExtraExpandedTxt( PaResId( RID_TXT_FONT_EXTRAEXPANDED ) );
182     static String aUltraExpandedTxt( PaResId( RID_TXT_FONT_ULTRAEXPANDED ) );
183 
184     static String aRegularTxt( PaResId( RID_TXT_FONT_REGULAR ) );
185 
186     String aEntry( rInfo.m_aFamilyName );
187     bool bWeight = true, bItalic = true, bWidth = true;
188     switch( rInfo.m_eWeight )
189     {
190         case weight::Thin:			aEntry.AppendAscii( ", " ); aEntry.Append( aThinTxt ); break;
191         case weight::UltraLight:	aEntry.AppendAscii( ", " ); aEntry.Append( aUltraLightTxt ); break;
192         case weight::Light:			aEntry.AppendAscii( ", " ); aEntry.Append( aLightTxt ); break;
193         case weight::SemiLight:		aEntry.AppendAscii( ", " ); aEntry.Append( aSemiLightTxt ); break;
194         case weight::SemiBold:		aEntry.AppendAscii( ", " ); aEntry.Append( aSemiBoldTxt ); break;
195         case weight::Bold:			aEntry.AppendAscii( ", " ); aEntry.Append( aBoldTxt ); break;
196         case weight::UltraBold:		aEntry.AppendAscii( ", " ); aEntry.Append( aUltraBoldTxt ); break;
197         default:
198             bWeight = false;
199             break;
200     }
201     switch( rInfo.m_eItalic )
202     {
203         case italic::Oblique:		aEntry.AppendAscii( ", " ); aEntry.Append( aObliqueTxt ); break;
204         case italic::Italic:		aEntry.AppendAscii( ", " ); aEntry.Append( aItalicTxt ); break;
205         default:
206             bItalic = false;
207             break;
208     }
209     switch( rInfo.m_eWidth )
210     {
211         case width::UltraCondensed:	aEntry.AppendAscii( ", " ); aEntry.Append( aUltraCondensedTxt ); break;
212         case width::ExtraCondensed:	aEntry.AppendAscii( ", " ); aEntry.Append( aExtraCondensedTxt ); break;
213         case width::Condensed:		aEntry.AppendAscii( ", " ); aEntry.Append( aCondensedTxt ); break;
214         case width::SemiCondensed:	aEntry.AppendAscii( ", " ); aEntry.Append( aSemiCondensedTxt ); break;
215         case width::SemiExpanded:	aEntry.AppendAscii( ", " ); aEntry.Append( aSemiExpandedTxt ); break;
216         case width::Expanded:		aEntry.AppendAscii( ", " ); aEntry.Append( aExpandedTxt ); break;
217         case width::ExtraExpanded:	aEntry.AppendAscii( ", " ); aEntry.Append( aExtraExpandedTxt ); break;
218         case width::UltraExpanded:	aEntry.AppendAscii( ", " ); aEntry.Append( aUltraExpandedTxt ); break;
219         default:
220             bWidth = false;
221             break;
222     }
223 
224     if( bAddRegular && ! bItalic && ! bWidth && ! bWeight )
225     {
226         aEntry.AppendAscii( ", " );
227         aEntry.Append( aRegularTxt );
228     }
229 
230     aEntry.AppendAscii( " (" );
231     aEntry.Append( rFile );
232     aEntry.AppendAscii( ")" );
233     return aEntry;
234 }
235 
236 String FontNameDlg::fillFontEntry( const ::std::list< FastPrintFontInfo >& rInfos, const String& rFile )
237 {
238     String aEntry;
239     bool bFirst = true;
240     for( ::std::list< FastPrintFontInfo >::const_iterator it = rInfos.begin(); it != rInfos.end(); ++it )
241     {
242         if( ! bFirst )
243             aEntry.AppendAscii( " & " );
244         aEntry.Append( String( it->m_aFamilyName ) );
245         bFirst = false;
246     }
247 
248     aEntry.AppendAscii( " (" );
249     aEntry.Append( rFile );
250     aEntry.AppendAscii( ")" );
251     return aEntry;
252 }
253 
254 void FontNameDlg::init()
255 {
256 	::std::list< fontID > aFonts;
257 	m_rFontManager.getFontList( aFonts );
258     m_aFontBox.Clear();
259     m_aRemoveButton.Enable( sal_False );
260     m_aRenameButton.Enable( sal_False );
261 
262     ::std::hash_map< OUString, int, OUStringHash > aFamilies;
263     ::std::list< fontID >::iterator font_it;
264 	for( font_it = aFonts.begin(); font_it != aFonts.end(); ++font_it )
265 	{
266 		if( m_rFontManager.isPrivateFontFile( *font_it ) )
267 		{
268             const OUString& rFamily( m_rFontManager.getFontFamily( *font_it ) );
269             if( aFamilies.find( rFamily ) == aFamilies.end() )
270                 aFamilies[rFamily] = 0;
271             aFamilies[rFamily]++;
272         }
273     }
274 
275 	for( font_it = aFonts.begin(); font_it != aFonts.end(); ++font_it )
276 	{
277 		if( m_rFontManager.isPrivateFontFile( *font_it ) )
278 		{
279             OString aFile( m_rFontManager.getFontFileSysPath( *font_it ) );
280             int nLast = aFile.lastIndexOf( '/' );
281             if( nLast != -1 )
282                 aFile = aFile.copy( nLast+1 );
283 
284             FastPrintFontInfo aInfo;
285             m_rFontManager.getFontFastInfo( *font_it, aInfo );
286             std::list< fontID > aDups;
287             String aEntry;
288             if( m_rFontManager.getFileDuplicates( *font_it, aDups ) )
289             {
290                 FastPrintFontInfo aDupInfo;
291                 std::list< FastPrintFontInfo > aInfos;
292                 aInfos.push_back( aInfo );
293                 for( std::list< fontID >::iterator dup = aDups.begin(); dup != aDups.end(); ++dup )
294                 {
295                     m_rFontManager.getFontFastInfo( *dup, aDupInfo );
296                     aInfos.push_back( aDupInfo );
297                     aFonts.remove( *dup );
298                 }
299                 aEntry = fillFontEntry( aInfos, String( ByteString( aFile ), osl_getThreadTextEncoding() ) );
300             }
301             else
302                 aEntry = fillFontEntry( aInfo, String( ByteString( aFile ), osl_getThreadTextEncoding() ), aFamilies[ aInfo.m_aFamilyName ] > 1  );
303 			sal_uInt16 nEntry = m_aFontBox.InsertEntry( aEntry );
304 			m_aFontBox.SetEntryData( nEntry, (void*)(*font_it) );
305 		}
306 	}
307 }
308 
309 IMPL_LINK( FontNameDlg, SelectHdl, ListBox*, pBox )
310 {
311     if( pBox == &m_aFontBox )
312     {
313         sal_Bool bEnable = m_aFontBox.GetSelectEntryCount() ? sal_True : sal_False;
314         m_aRemoveButton.Enable( bEnable );
315         m_aRenameButton.Enable( bEnable );
316     }
317     return 0;
318 }
319 
320 IMPL_LINK( FontNameDlg, DelPressedHdl, ListBox*, pBox )
321 {
322 	if( pBox == &m_aFontBox && m_aRemoveButton.IsEnabled() )
323 	{
324 		ClickBtnHdl( &m_aRemoveButton );
325 	}
326 	return 0;
327 }
328 
329 IMPL_LINK( FontNameDlg, ClickBtnHdl, Button*, pButton )
330 {
331 
332 	int i;
333 
334 	if( pButton == &m_aOKButton )
335 	{
336 		EndDialog();
337 	}
338 	else if( pButton == &m_aRemoveButton && AreYouSure( this, RID_QUERY_REMOVEFONTFROMLIST ) && m_aFontBox.GetSelectEntryCount() )
339 	{
340         ::std::list< fontID > aRemoveIDs;
341 		for( i = 0; i < m_aFontBox.GetSelectEntryCount(); i++ )
342 		{
343             int nSelect = m_aFontBox.GetSelectEntryPos( i );
344             aRemoveIDs.push_back( (fontID)(sal_IntPtr)m_aFontBox.GetEntryData( nSelect ) );
345 		}
346         m_rFontManager.removeFonts( aRemoveIDs );
347         init();
348 	}
349     else if( pButton == &m_aImportButton )
350     {
351 		FontImportDialog aDialog( this );
352 		aDialog.Execute();
353         init();
354     }
355     else if( pButton == &m_aRenameButton && m_aFontBox.GetSelectEntryCount() )
356     {
357 		for( i = 0; i < m_aFontBox.GetSelectEntryCount(); i++ )
358 		{
359             fontID aFont = (fontID)(sal_IntPtr)m_aFontBox.GetEntryData( m_aFontBox.GetSelectEntryPos( i ) );
360             if( ! m_rFontManager.checkChangeFontPropertiesPossible( aFont ) )
361             {
362                 String aErrorText( m_aNoRenameString );
363                 aErrorText.SearchAndReplace( String( RTL_CONSTASCII_USTRINGPARAM( "%s" ) ), m_aFontBox.GetSelectEntry( i ) );
364                 ErrorBox aBox( this, WB_OK | WB_DEF_OK, aErrorText );
365                 aBox.Execute();
366                 continue;
367             }
368             ::std::list< fontID > aDuplicates;
369             m_rFontManager.getFileDuplicates( aFont, aDuplicates );
370             aDuplicates.push_front( aFont );
371             int nFonts = aDuplicates.size();
372             for( int n = 0; n < nFonts; n++ )
373             {
374                 aFont = aDuplicates.front();
375                 aDuplicates.pop_front();
376                 String aFamily( m_rFontManager.getFontFamily( aFont ) );
377                 ::std::list< OUString > aAlternatives;
378                 m_rFontManager.getAlternativeFamilyNames( aFont, aAlternatives );
379                 ::std::list< String > aChoices;
380                 while( aAlternatives.size() )
381                 {
382                     aChoices.push_back( aAlternatives.front() );
383                     aAlternatives.pop_front();
384                 }
385                 String aQueryTxt( m_aRenameString );
386                 if( nFonts > 1 )
387                 {
388                     aQueryTxt = m_aRenameTTCString;
389                     aQueryTxt.SearchAndReplace( String( RTL_CONSTASCII_USTRINGPARAM( "%d1" ) ), String::CreateFromInt32( n+1 ) );
390                     aQueryTxt.SearchAndReplace( String( RTL_CONSTASCII_USTRINGPARAM( "%d2" ) ), String::CreateFromInt32( nFonts ) );
391                 }
392                 aQueryTxt.SearchAndReplace( String( RTL_CONSTASCII_USTRINGPARAM( "%s" ) ), aFamily );
393                 QueryString aQuery( this, aQueryTxt, aFamily, aChoices );
394                 if( aQuery.Execute() )
395                 {
396                     aFamily.SearchAndReplaceAll( '-', ' ' );
397                     aFamily.SearchAndReplaceAll( '?', ' ' );
398                     aFamily.SearchAndReplaceAll( '*', ' ' );
399                     aFamily = WhitespaceToSpace( aFamily );
400                     if( aFamily.Len() )
401                     {
402                         String aXLFD = m_rFontManager.getFontXLFD( aFont );
403                         aXLFD.SetToken( 2, '-', aFamily );
404                         m_rFontManager.changeFontProperties( aFont, aXLFD );
405                     }
406                 }
407             }
408         }
409         init();
410     }
411 	return 0;
412 }
413 
414 //--------------------------------------------------
415 
416 FontImportDialog::FontImportDialog( Window* pParent ) :
417 		ModalDialog( pParent, PaResId( RID_FONTIMPORT_DIALOG ) ),
418 		m_aOKBtn( this, PaResId( RID_FIMP_BTN_OK ) ),
419 		m_aCancelBtn( this, PaResId( RID_FIMP_BTN_CANCEL ) ),
420         m_aSelectAllBtn( this, PaResId( RID_FIMP_BTN_SELECTALL ) ),
421         m_aNewFontsBox( this, PaResId( RID_FIMP_BOX_NEWFONTS ) ),
422 		m_aFromFL( this, PaResId( RID_FIMP_FL_FROM ) ),
423 		m_aFromDirEdt( this, PaResId( RID_FIMP_EDT_FROM ) ),
424 		m_aFromBtn( this, PaResId( RID_FIMP_BTN_FROM ) ),
425         m_aSubDirsBox( this, PaResId( RID_FIMP_BOX_SUBDIRS ) ),
426         m_aTargetOptFL( this, PaResId( RID_FIMP_FL_TARGETOPTS ) ),
427         m_aLinkOnlyBox( this, PaResId( RID_FIMP_BOX_LINKONLY ) ),
428         m_aFixedText( this, PaResId( RID_FIMP_TXT_HELP ) ),
429 		m_bOverwriteAll( false ),
430 		m_bOverwriteNone( false ),
431 		m_pProgress( NULL ),
432 		m_aImportOperation( PaResId( RID_FIMP_STR_IMPORTOP ) ),
433 		m_aOverwriteQueryText( PaResId( RID_FIMP_STR_QUERYOVERWRITE ) ),
434 		m_aOverwriteAllText( PaResId( RID_FIMP_STR_OVERWRITEALL ) ),
435 		m_aOverwriteNoneText( PaResId( RID_FIMP_STR_OVERWRITENONE ) ),
436 		m_aNoAfmText( PaResId( RID_FIMP_STR_NOAFM ) ),
437 		m_aAfmCopyFailedText( PaResId( RID_FIMP_STR_AFMCOPYFAILED ) ),
438 		m_aFontCopyFailedText( PaResId( RID_FIMP_STR_FONTCOPYFAILED ) ),
439 		m_aNoWritableFontsDirText( PaResId( RID_FIMP_STR_NOWRITEABLEFONTSDIR ) ),
440 		m_aFontsImportedText( PaResId( RID_FIMP_STR_NUMBEROFFONTSIMPORTED ) ),
441 		m_rFontManager( ::psp::PrintFontManager::get() )
442 {
443 	FreeResource();
444 
445 	m_aNewFontsBox.EnableMultiSelection( sal_True );
446 
447 	m_aOKBtn.SetClickHdl( LINK( this, FontImportDialog, ClickBtnHdl ) );
448     m_aSelectAllBtn.SetClickHdl( LINK( this, FontImportDialog, ClickBtnHdl ) );
449 	m_aFromBtn.SetClickHdl( LINK( this, FontImportDialog, ClickBtnHdl ) );
450     m_aFromDirEdt.SetModifyHdl( LINK( this, FontImportDialog, ModifyHdl ) );
451     m_aRefreshTimer.SetTimeoutHdl( LINK( this, FontImportDialog, RefreshTimeoutHdl ) );
452     m_aRefreshTimer.SetTimeout( 2000 );
453     m_aLinkOnlyBox.Check( sal_False );
454     m_aSubDirsBox.Check( sal_True );
455     m_aSubDirsBox.SetToggleHdl( LINK( this, FontImportDialog, ToggleHdl ) );
456 
457     Config& rPadminRC( getPadminRC() );
458     rPadminRC.SetGroup( "FontImport" );
459     m_aFromDirEdt.SetText( String( rPadminRC.ReadKey( "FromPath" ), RTL_TEXTENCODING_UTF8 ) );
460     RefreshTimeoutHdl( NULL );
461 }
462 
463 FontImportDialog::~FontImportDialog()
464 {
465     Config& rPadminRC( getPadminRC() );
466     rPadminRC.SetGroup( "FontImport" );
467     rPadminRC.WriteKey( "FromPath", ByteString( m_aFromDirEdt.GetText(), RTL_TEXTENCODING_UTF8 ) );
468 }
469 
470 void FontImportDialog::importFontsFailed( ::psp::PrintFontManager::ImportFontCallback::FailCondition eReason )
471 {
472 	String aText;
473 	switch( eReason )
474 	{
475 		case psp::PrintFontManager::ImportFontCallback::NoWritableDirectory:
476 			aText = m_aNoWritableFontsDirText;
477             break;
478         default:
479             break;
480 	}
481 	ErrorBox aBox( m_pProgress ? (Window*)m_pProgress : (Window*)this, WB_OK | WB_DEF_OK, aText );
482 	aBox.Execute();
483 }
484 
485 void FontImportDialog::progress( const ::rtl::OUString& rFile )
486 {
487 	m_pProgress->setValue( ++m_nFont );
488 	m_pProgress->setFilename( rFile );
489 }
490 
491 bool FontImportDialog::queryOverwriteFile( const ::rtl::OUString& rFile )
492 {
493 	bool bRet = false;
494 
495 	if( m_bOverwriteNone )
496 		return false;
497 	if( m_bOverwriteAll )
498 		return true;
499 
500 	String aText( m_aOverwriteQueryText );
501 	aText.SearchAndReplace( String( RTL_CONSTASCII_USTRINGPARAM( "%s" ) ), rFile );
502 
503 	QueryBox aQueryBox( m_pProgress ? (Window*)m_pProgress : (Window*)this, WB_YES_NO | WB_DEF_NO, aText );
504 	aQueryBox.AddButton( m_aOverwriteAllText, 20, 0 );
505 	aQueryBox.AddButton( m_aOverwriteNoneText, 21, 0 );
506 
507 	int nResult = aQueryBox.Execute();
508 	switch( nResult )
509 	{
510 		case BUTTONID_YES:		bRet = true; break;
511 		case BUTTONID_NO:		bRet = false; break;
512 		case 20:				bRet = m_bOverwriteAll = true; break;
513 		case 21:				bRet = false; m_bOverwriteNone = true; break;
514 	}
515 
516 	return bRet;
517 }
518 
519 void FontImportDialog::importFontFailed( const ::rtl::OUString& rFile, ::psp::PrintFontManager::ImportFontCallback::FailCondition eReason )
520 {
521 	String aText;
522 	switch( eReason )
523 	{
524 		case psp::PrintFontManager::ImportFontCallback::NoAfmMetric:
525 			aText = m_aNoAfmText;
526 			break;
527 		case psp::PrintFontManager::ImportFontCallback::AfmCopyFailed:
528 			aText = m_aAfmCopyFailedText;
529 			break;
530 		case psp::PrintFontManager::ImportFontCallback::FontCopyFailed:
531 			aText = m_aFontCopyFailedText;
532 			break;
533         default:
534             break;
535 	}
536 	aText.SearchAndReplace( String( RTL_CONSTASCII_USTRINGPARAM( "%s" ) ), rFile );
537 	ErrorBox aBox( m_pProgress ? (Window*)m_pProgress : (Window*)this, WB_OK | WB_DEF_OK, aText );
538 	aBox.Execute();
539 }
540 
541 bool FontImportDialog::isCanceled()
542 {
543 	return m_pProgress->isCanceled();
544 }
545 
546 IMPL_LINK( FontImportDialog, ModifyHdl, Edit*, EMPTYARG )
547 {
548     m_aRefreshTimer.Start();
549     return 0;
550 }
551 
552 IMPL_LINK( FontImportDialog, RefreshTimeoutHdl, void*, EMPTYARG )
553 {
554     rtl_TextEncoding aEncoding = osl_getThreadTextEncoding();
555 	std::list< String > aFiles;
556     m_aNewFonts.clear();
557 	OUString aDirectory( m_aFromDirEdt.GetText() );
558 	FindFiles( aDirectory, aFiles, String( RTL_CONSTASCII_USTRINGPARAM( "PFA;PFB;TTF;TTC;OTF" ) ), m_aSubDirsBox.IsChecked() );
559     OString aDir( OUStringToOString( aDirectory, aEncoding ) );
560     aDir += "/";
561 	while( aFiles.begin() != aFiles.end() )
562 	{
563 		OString aFont( aDir );
564 		aFont += OUStringToOString( aFiles.front(), aEncoding );
565 		aFiles.pop_front();
566         ::std::list< FastPrintFontInfo > aInfos;
567         if( m_rFontManager.getImportableFontProperties( aFont, aInfos ) )
568             m_aNewFonts[ aFont ] = aInfos;
569 	}
570     fillFontBox();
571     return 0;
572 }
573 
574 void FontImportDialog::fillFontBox()
575 {
576     rtl_TextEncoding aEncoding = osl_getThreadTextEncoding();
577     m_aNewFontsBox.Clear();
578 
579     ::std::hash_map< OUString, int, OUStringHash > aFamilies;
580     ::std::hash_map< OString, ::std::list< FastPrintFontInfo >, OStringHash >::iterator it;
581 	for( it = m_aNewFonts.begin(); it != m_aNewFonts.end(); ++it )
582 	{
583         const OUString& rFamily( it->second.front().m_aFamilyName );
584         if( aFamilies.find( rFamily ) == aFamilies.end() )
585                 aFamilies[rFamily] = 0;
586             aFamilies[rFamily]++;
587     }
588 
589     for( it = m_aNewFonts.begin(); it != m_aNewFonts.end(); ++it )
590     {
591         OString aFileName( it->first.copy( it->first.lastIndexOf( '/' )+1 ) );
592         OUString aFile( OStringToOUString( aFileName, aEncoding ) );
593         String aEntry;
594         if( it->second.size() == 1 )
595             aEntry = FontNameDlg::fillFontEntry( it->second.front(), aFile, aFamilies[ it->second.front().m_aFamilyName ] > 1 );
596         else
597             aEntry = FontNameDlg::fillFontEntry( it->second, aFile );
598         sal_uInt16 nPos = m_aNewFontsBox.InsertEntry( aEntry );
599         m_aNewFontsBox.SetEntryData( nPos, (void*)&(it->first) );
600     }
601 }
602 
603 void FontImportDialog::copyFonts()
604 {
605 	::std::list< OString > aFiles;
606     for( int i = 0; i < m_aNewFontsBox.GetSelectEntryCount(); i++ )
607     {
608         OString* pFile = (OString*)m_aNewFontsBox.GetEntryData( m_aNewFontsBox.GetSelectEntryPos( i ) );
609         aFiles.push_back( *pFile );
610     }
611 
612 	int nSuccess = 0;
613 	if( aFiles.size() )
614 	{
615 		m_nFont = 0;
616 		m_pProgress = new ProgressDialog( this );
617 		m_pProgress->setRange( 0, aFiles.size() );
618 		m_pProgress->startOperation( m_aImportOperation );
619 		m_pProgress->Show( sal_True );
620 		m_pProgress->setValue( 0 );
621 		m_pProgress->Invalidate();
622 		m_pProgress->Sync();
623 		nSuccess = m_rFontManager.importFonts( aFiles, m_aLinkOnlyBox.IsChecked() ? true : false, this );
624 		m_pProgress->Show( sal_False );
625 		delete m_pProgress;
626 		m_pProgress = NULL;
627 	}
628 	String aText( m_aFontsImportedText );
629 	aText.SearchAndReplace( String( RTL_CONSTASCII_USTRINGPARAM( "%d" ) ), String::CreateFromInt32( nSuccess ) );
630 	InfoBox aBox( this, aText );
631 	aBox.Execute();
632 }
633 
634 IMPL_LINK( FontImportDialog, ClickBtnHdl, Button*, pButton )
635 {
636 	if( pButton == &m_aFromBtn )
637 	{
638         String aPath( m_aFromDirEdt.GetText() );
639         if( chooseDirectory( aPath ) )
640         {
641 			m_aFromDirEdt.SetText( aPath );
642             RefreshTimeoutHdl( NULL );
643         }
644 	}
645 	else if( pButton == &m_aOKBtn )
646 	{
647 		copyFonts();
648 		EndDialog( 0 );
649 	}
650     else if( pButton == &m_aSelectAllBtn )
651     {
652         m_aNewFontsBox.SetUpdateMode( sal_False );
653         for( int i = 0; i < m_aNewFontsBox.GetEntryCount(); i++ )
654             m_aNewFontsBox.SelectEntryPos( i, sal_True );
655         m_aNewFontsBox.SetUpdateMode( sal_True );
656     }
657 	return 0;
658 }
659 
660 IMPL_LINK( FontImportDialog, ToggleHdl, CheckBox*, pBox )
661 {
662     if( pBox == &m_aSubDirsBox )
663     {
664         RefreshTimeoutHdl( NULL );
665     }
666 
667     return 0;
668 }
669