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 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_svtools.hxx"
30 #include <vcl/svapp.hxx>
31 #include <vcl/button.hxx>
32 #include <vcl/fixed.hxx>
33 #include <vcl/edit.hxx>
34 #include <vcl/lstbox.hxx>
35 #include <svtools/svtdata.hxx>
36 #include <filedlg2.hxx>
37 #include <svtools/filedlg.hxx>
38 #include <svtools/filedlg2.hrc>
39 #include <vcl/msgbox.hxx>
40 #include <vos/security.hxx>
41 #include <com/sun/star/i18n/XCollator.hpp>
42 
43 #include <svtools/stdctrl.hxx>
44 
45 #ifdef _MSC_VER
46 #pragma optimize ("", off)
47 #endif
48 
49 #include <svtools/helpid.hrc>
50 
51 using namespace com::sun::star;
52 using namespace com::sun::star::uno;
53 
54 
55 DECLARE_LIST( UniStringList, UniString* )
56 
57 #define STD_BTN_WIDTH	80
58 #define STD_BTN_HEIGHT	26
59 
60 #ifndef UNX
61 	#define ALLFILES				"*.*"
62 #else
63 	#define ALLFILES				"*"
64 #endif
65 //		#define STD_BTN_WIDTH	90
66 //		#define STD_BTN_HEIGHT	35
67 
68 #define INITCONTROL( p, ControlClass, nBits, aPos, aSize, aTitel, rHelpId ) \
69 	p = new ControlClass( GetPathDialog(), WinBits( nBits ) ); \
70 	p->SetHelpId( rHelpId ); \
71 	p->SetPosSizePixel( aPos, aSize ); \
72 	p->SetText( aTitel ); \
73 	p->Show();
74 
75 
76 inline sal_Bool IsPrintable( sal_Unicode c )
77 {
78 	return c >= 32 && c != 127 ? sal_True : sal_False;
79 }
80 
81 long
82 KbdListBox::PreNotify( NotifyEvent& rNEvt )
83 {
84 	if ( rNEvt.GetType() == EVENT_KEYINPUT )
85 	{
86 		KeyEvent aKeyEvt	= *rNEvt.GetKeyEvent();
87 		sal_Unicode  cCharCode	= aKeyEvt.GetCharCode();
88 
89 		if ( IsPrintable ( cCharCode ) )
90 		{
91 			sal_uInt16 nCurrentPos = GetSelectEntryPos();
92 			sal_uInt16 nEntries    = GetEntryCount();
93 
94 			for ( sal_uInt16 i = 1; i < nEntries; i++ )
95 			{
96 				UniString aEntry = GetEntry ( (i + nCurrentPos) % nEntries );
97 				aEntry.EraseLeadingChars( ' ' );
98 				aEntry.ToUpperAscii();
99 				UniString aCompare( cCharCode );
100 				aCompare.ToUpperAscii();
101 
102 				if ( aEntry.CompareTo( aCompare, 1 ) == COMPARE_EQUAL )
103 				{
104 					SelectEntryPos ( (i + nCurrentPos) % nEntries );
105 					break;
106 				}
107 			}
108 		}
109 		else
110 		if ( aKeyEvt.GetKeyCode().GetCode() == KEY_RETURN )
111 		{
112 			DoubleClick();
113 		}
114 	}
115 
116 	return ListBox::PreNotify ( rNEvt );
117 }
118 
119 ImpPathDialog::ImpPathDialog( PathDialog* pDlg, RESOURCE_TYPE nType, sal_Bool bCreateDir )
120 {
121 	pSvPathDialog = pDlg;
122 	nDirCount = 0;
123 
124 	// initialize Controls if not used as a base class
125 	if ( nType == WINDOW_PATHDIALOG )
126 	{
127 		InitControls();
128 		if( pNewDirBtn )
129 			pNewDirBtn->Enable( bCreateDir );
130 	}
131 
132 	pDlg->SetHelpId( HID_FILEDLG_PATHDLG );
133 
134     lang::Locale aLocale = Application::GetSettings().GetLocale();
135     xCollator = ::vcl::unohelper::CreateCollator();
136     if( xCollator.is() )
137         xCollator->loadDefaultCollator( aLocale, 1 );
138     DBG_ASSERT( xCollator.is(), "not collator service for path dialog" );
139 }
140 
141 ImpPathDialog::~ImpPathDialog()
142 {
143 	delete pEdit;
144 	delete pDirTitel;
145 	delete pDirList;
146 	delete pDirPath;
147 	delete pDriveList;
148 	delete pDriveTitle;
149 	delete pLoadBtn;
150 	delete pOkBtn;
151 	delete pCancelBtn;
152 	delete pNewDirBtn;
153 #	if defined(UNX) || defined(OS2)
154 	delete pHomeBtn;
155 #	endif
156 }
157 
158 void ImpPathDialog::InitControls()
159 {
160 	PathDialog* pDlg = GetPathDialog();
161 	pDlg->SetText( UniString( SvtResId( STR_FILEDLG_SELECT ) ) );
162 
163 	Size a3Siz = pDlg->LogicToPixel( Size( 3, 3 ), MAP_APPFONT );
164 	Size a6Siz = pDlg->LogicToPixel( Size( 6, 6 ), MAP_APPFONT );
165 	Size aBtnSiz = pDlg->LogicToPixel( Size( 50, 14 ), MAP_APPFONT );
166 	Size aFTSiz = pDlg->LogicToPixel( Size( 142, 10 ), MAP_APPFONT );
167 	Size aEDSiz = pDlg->LogicToPixel( Size( 142, 12 ), MAP_APPFONT );
168 	Point aPnt( a6Siz.Width(), a6Siz.Height() );
169 	long nLbH1 = pDlg->LogicToPixel( Size( 0, 93 ), MAP_APPFONT ).Height();
170 	long nH = 0;
171 	UniString aEmptyStr;
172 
173 	INITCONTROL( pDirTitel, FixedText, 0,
174 				 aPnt, aFTSiz, UniString( SvtResId( STR_FILEDLG_DIR ) ), HID_FILEDLG_DIR );
175 	aPnt.Y() += aFTSiz.Height() + a3Siz.Height();
176 
177 	INITCONTROL( pEdit, Edit, WB_BORDER, aPnt, aEDSiz, aPath.GetFull(), HID_FILEDLG_EDIT );
178 
179 	aPnt.Y() += aEDSiz.Height() + a3Siz.Height();
180 #ifndef UNX
181 	long nLbH2 = pDlg->LogicToPixel( Size( 0, 60 ), MAP_APPFONT ).Height();
182 	INITCONTROL( pDirList, KbdListBox, WB_AUTOHSCROLL | WB_BORDER,
183 		aPnt, Size( aEDSiz.Width(), nLbH1 ), aEmptyStr, HID_FILEDLG_DIRS );
184 	aPnt.Y() += nLbH1 + a6Siz.Height();
185 	INITCONTROL( pDriveTitle, FixedText, 0,
186 				 aPnt, aFTSiz, UniString( SvtResId( STR_FILEDLG_DRIVES ) ), HID_FILEDLG_DRIVE );
187 	aPnt.Y() += aFTSiz.Height() + a3Siz.Height();
188 	INITCONTROL( pDriveList, ListBox, WB_DROPDOWN,
189 				 aPnt, Size( aEDSiz.Width(), nLbH2 ), aEmptyStr, HID_FILEDLG_DRIVES );
190 	nH = aPnt.Y() + aEDSiz.Height() + a6Siz.Height();
191 #else
192 	long nNewH = nLbH1 + 3 * a3Siz.Height() +
193 				 aFTSiz.Height() + aEDSiz.Height();
194 	INITCONTROL( pDirList, KbdListBox, WB_AUTOHSCROLL | WB_BORDER,
195 				 aPnt, Size( aEDSiz.Width(), nNewH ), aEmptyStr, HID_FILEDLG_DIRS );
196 	nH = aPnt.Y() + nNewH + a6Siz.Height();
197 	pDriveTitle = NULL;
198 	pDriveList = NULL;
199 #endif
200 
201     long nExtraWidth = pDlg->GetTextWidth( String( RTL_CONSTASCII_USTRINGPARAM( "(W)" ) ) )+10;
202     String aOkStr = Button::GetStandardText( BUTTON_OK );
203     long nTextWidth = pDlg->GetTextWidth( aOkStr )+nExtraWidth;
204     if( nTextWidth > aBtnSiz.Width() )
205         aBtnSiz.Width() = nTextWidth;
206 
207     String aCancelStr = Button::GetStandardText( BUTTON_CANCEL );
208     nTextWidth = pDlg->GetTextWidth( aCancelStr )+nExtraWidth;
209     if( nTextWidth > aBtnSiz.Width() )
210         aBtnSiz.Width() = nTextWidth;
211 
212     String aNewDirStr( SvtResId( STR_FILEDLG_NEWDIR ) );
213     nTextWidth = pDlg->GetTextWidth( aNewDirStr )+nExtraWidth;
214     if( nTextWidth > aBtnSiz.Width() )
215         aBtnSiz.Width() = nTextWidth;
216 #if defined(UNX) || defined(OS2)
217     String aHomeDirStr( SvtResId( STR_FILEDLG_HOME ) );
218     nTextWidth = pDlg->GetTextWidth( aHomeDirStr )+nExtraWidth;
219     if( nTextWidth > aBtnSiz.Width() )
220         aBtnSiz.Width() = nTextWidth;
221 #endif
222 
223 	aPnt.X() = 2 * a6Siz.Width() + aEDSiz.Width();
224 	aPnt.Y() = a6Siz.Height();
225 	INITCONTROL( pOkBtn, PushButton, WB_DEFBUTTON,
226 				 aPnt, aBtnSiz, aOkStr, "" );
227 	aPnt.Y() += aBtnSiz.Height() + a3Siz.Height();
228 	INITCONTROL( pCancelBtn, CancelButton, 0,
229 				 aPnt, aBtnSiz, aCancelStr, "" );
230 	aPnt.Y() += aBtnSiz.Height() + a3Siz.Height();
231 	INITCONTROL( pNewDirBtn, PushButton, WB_DEFBUTTON,
232 				 aPnt, aBtnSiz, aNewDirStr, HID_FILEDLG_NEWDIR );
233 #if defined(UNX) || defined(OS2)
234 	aPnt.Y() += aBtnSiz.Height() + a3Siz.Height();
235 	INITCONTROL( pHomeBtn, PushButton, WB_DEFBUTTON,
236 				 aPnt, aBtnSiz, aHomeDirStr, HID_FILEDLG_HOME );
237 #else
238 	pHomeBtn = NULL;
239 #endif
240 
241 	pDirPath = 0;
242 	pLoadBtn = 0;
243 	// Dialogbreite == OKBtn-Position + OKBtn-Breite + Rand
244 	long nW = aPnt.X() + aBtnSiz.Width() + a6Siz.Width();
245 
246 	pDlg->SetOutputSizePixel( Size( nW, nH ) );  // Groesse ggf. auch Resource wird geplaettet?
247 
248 	if (pDirList)
249 		pDirList->SetDoubleClickHdl(LINK( this, ImpPathDialog, DblClickHdl) );
250 
251 	if (pDirList)
252 		pDirList->SetSelectHdl( LINK( this, ImpPathDialog, SelectHdl ) );
253 
254 	if (pDriveList)
255 		pDriveList->SetSelectHdl( LINK( this, ImpPathDialog, SelectHdl ) );
256 
257 	if (pOkBtn)
258 		pOkBtn->SetClickHdl( LINK( this, ImpPathDialog, ClickHdl) );
259 
260 	if (pCancelBtn)
261 		pCancelBtn->SetClickHdl( LINK( this, ImpPathDialog, ClickHdl) );
262 
263 	if (pHomeBtn)
264 		pHomeBtn->SetClickHdl( LINK( this, ImpPathDialog, ClickHdl) );
265 
266 	if (pNewDirBtn)
267 		pNewDirBtn->SetClickHdl( LINK( this, ImpPathDialog, ClickHdl) );
268 
269 	nOwnChilds = pDlg->GetChildCount();
270 }
271 
272 
273 
274 IMPL_LINK( ImpPathDialog, SelectHdl, ListBox *, p )
275 {
276 	if( p == pDriveList )
277 	{
278 		UniString aDrive( pDriveList->GetSelectEntry(), 0, 2);
279 		aDrive += '\\';
280 		SetPath( aDrive );
281 	}
282 	else
283 	if( p == pDirList )
284 	{
285 		// isolate the pure name of the entry
286 		// removing trainling stuff and leading spaces
287 		UniString aEntry( pDirList->GetSelectEntry() );
288 
289 		aEntry.EraseLeadingChars( ' ' );
290 		sal_uInt16 nPos = aEntry.Search( '/' );
291 		aEntry.Erase( nPos );
292 
293 		// build the absolute path to the selected item
294 		DirEntry aNewPath;
295 		aNewPath.ToAbs();
296 
297 		sal_uInt16 nCurPos = pDirList->GetSelectEntryPos();
298 
299 		// Wird nach oben gewechselt
300 		if( nCurPos < nDirCount )
301 			aNewPath = aNewPath[nDirCount-nCurPos-1];
302 		else
303 			aNewPath += aEntry;
304 
305 		pEdit->SetText( aNewPath.GetFull() );
306 	}
307 
308 	return 0;
309 }
310 
311 
312 IMPL_LINK( ImpPathDialog, ClickHdl, Button*, pBtn )
313 {
314 	if ( pBtn == pOkBtn || pBtn == pLoadBtn )
315 	{
316 		DirEntry aFile( pEdit->GetText() );
317 
318 		// Existiert File / File ueberschreiben
319 		if( IsFileOk( aFile ) )
320 		{
321 			// Ja, dann kompletten Pfad mit Filenamen merken und Dialog beenden
322 			aPath = aFile;
323 			aPath.ToAbs();
324 			GetPathDialog()->EndDialog( sal_True );
325 		}
326 		else
327 		{
328 			DirEntry aCheck( aPath );
329 			aCheck += aFile;
330 			if( aCheck.Exists() )
331 			{
332 				aCheck.ToAbs();
333 				SetPath( aCheck.GetFull() );
334 				pEdit->SetSelection( Selection( 0x7FFFFFFF, 0x7FFFFFFF ) );
335 			}
336 		}
337 	}
338 	else
339 	if ( pBtn == pCancelBtn )
340 	{
341 		GetPathDialog()->EndDialog( sal_False );
342 	}
343 	else
344 	if ( pBtn == pHomeBtn )
345 	{
346 		::rtl::OUString aHomeDir;
347 		vos:: OSecurity  aSecurity;
348 		if ( aSecurity.getHomeDir( aHomeDir ) )
349 		{
350 			DirEntry aFile ( aHomeDir );
351 			if ( IsFileOk( aFile ) )
352 			{
353 				aFile.ToAbs();
354 				SetPath( aFile.GetFull() );
355 			}
356 		}
357 	}
358 	else
359 	if ( pBtn == pNewDirBtn )
360 	{
361 		DirEntry aFile( pEdit->GetText() );
362 		if( ! aFile.Exists() && ! FileStat( aFile ).IsKind( FSYS_KIND_WILD ) )
363 			aFile.MakeDir();
364 
365 		if( IsFileOk ( aFile ) )
366 		{
367 			aFile.ToAbs();
368 			SetPath( aFile.GetFull() );
369 		}
370 	}
371 
372 	return 0;
373 }
374 
375 
376 IMPL_LINK( ImpPathDialog, DblClickHdl, ListBox*, pBox )
377 {
378 	// isolate the pure name of the entry
379 	// removing trainling stuff and leading spaces
380 	UniString aEntry( pBox->GetSelectEntry() );
381 
382 	aEntry.EraseLeadingChars( ' ' );
383 	sal_uInt16 nPos = aEntry.Search( '/' );
384 	aEntry.Erase( nPos );
385 
386 	// build the absolute path to the selected item
387 	DirEntry aNewPath;
388 	aNewPath.ToAbs();
389 	if( pBox == pDirList )
390 	{
391 		sal_uInt16 nCurPos = pDirList->GetSelectEntryPos();
392 
393 		// Wenn es schon das aktuelle ist, dann mache nichts
394 		if( nCurPos == nDirCount-1 )
395 			return 0;
396 
397 		// Wird nach oben gewechselt
398 		if( nCurPos < nDirCount )
399 			aNewPath = aNewPath[nDirCount-nCurPos-1];
400 		else
401 			aNewPath += aEntry;
402 	}
403 	else
404 		aNewPath += aEntry;
405 
406 	pSvPathDialog->EnterWait();
407 
408 	if( FileStat( aNewPath ).GetKind() & FSYS_KIND_DIR )
409 	{
410 		// Neuen Pfad setzen und Listboxen updaten
411 		aPath = aNewPath;
412 		if( !aPath.SetCWD( sal_True ) )
413 		{
414 			ErrorBox aBox( GetPathDialog(),
415 						   WB_OK_CANCEL | WB_DEF_OK,
416 						   UniString( SvtResId( STR_FILEDLG_CANTCHDIR ) ) );
417 			if( aBox.Execute() == RET_CANCEL )
418 				GetPathDialog()->EndDialog( sal_False );
419 		}
420 		UpdateEntries( sal_True );
421 	}
422 
423 	pSvPathDialog->LeaveWait();
424 	return 0;
425 }
426 
427 void ImpPathDialog::UpdateEntries( const sal_Bool )
428 {
429 	UniString aTabString;
430 	DirEntry aTmpPath;
431 	aTmpPath.ToAbs();
432 
433 	nDirCount = aTmpPath.Level();
434 
435 	pDirList->SetUpdateMode( sal_False );
436 	pDirList->Clear();
437 
438 	for( sal_uInt16 i = nDirCount; i > 0; i-- )
439 	{
440 		UniString aName( aTabString );
441 		aName += aTmpPath[i-1].GetName();
442 		pDirList->InsertEntry( aName );
443 		aTabString.AppendAscii( "  ", 2 );
444 	}
445 
446 	// scan the directory
447 	DirEntry aCurrent;
448 	aCurrent.ToAbs();
449 
450 	Dir aDir( aCurrent, FSYS_KIND_DIR|FSYS_KIND_FILE );
451 
452 	sal_uInt16 nEntries = aDir.Count();
453 	if( nEntries )
454 	{
455 		UniStringList aSortDirList;
456 		for ( sal_uInt16 n = 0; n < nEntries; n++ )
457 		{
458 			DirEntry& rEntry = aDir[n];
459 			UniString aName( rEntry.GetName() );
460 			if( aName.Len() && ( aName.GetChar(0) != '.' ) && rEntry.Exists() )
461 			{
462 				if( FileStat( rEntry ).GetKind() & FSYS_KIND_DIR )
463 				{
464 					sal_uLong l = 0;
465                     if( xCollator.is() )
466                     {
467                         for( l = 0; l < aSortDirList.Count(); l++ )
468                             if( xCollator->compareString( *aSortDirList.GetObject(l), aName ) > 0 )
469                                 break;
470                     }
471 					aSortDirList.Insert( new UniString( aName ), l );
472 				}
473 			}
474 		}
475 
476 		for( sal_uLong l = 0; l < aSortDirList.Count(); l++ )
477 		{
478 			UniString aEntryStr( aTabString );
479 			aEntryStr += *aSortDirList.GetObject(l);
480 			pDirList->InsertEntry( aEntryStr );
481 			delete aSortDirList.GetObject(l);
482 		}
483 	}
484 
485 	UpdateDirs( aTmpPath );
486 }
487 
488 void ImpPathDialog::UpdateDirs( const DirEntry& rTmpPath )
489 {
490 	pDirList->SelectEntryPos( nDirCount-1 );
491 	pDirList->SetTopEntry( nDirCount > 1
492 						   ? nDirCount - 2
493 						   : nDirCount - 1 );
494 	pDirList->SetUpdateMode( sal_True );
495 	pDirList->Invalidate();
496 	pDirList->Update();
497 
498 	UniString aDirName = rTmpPath.GetFull();
499 	if( pDirPath )
500 		pDirPath->SetText( aDirName );
501 	else
502 		pEdit->SetText( aDirName );
503 }
504 
505 sal_Bool ImpPathDialog::IsFileOk( const DirEntry& rDirEntry )
506 {
507 	if( FileStat( rDirEntry ).GetKind() & (FSYS_KIND_WILD | FSYS_KIND_DEV) )
508 		return sal_False;
509 	else
510 	{
511 		// Datei vorhanden ?
512 		if( ! rDirEntry.Exists() )
513 		{
514 			UniString aQueryTxt( SvtResId( STR_FILEDLG_ASKNEWDIR ) );
515 			aQueryTxt.SearchAndReplaceAscii( "%s", rDirEntry.GetFull() );
516 			QueryBox aQuery( GetPathDialog(),
517 							 WB_YES_NO | WB_DEF_YES,
518 							 aQueryTxt	);
519 			if( aQuery.Execute() == RET_YES )
520 				rDirEntry.MakeDir();
521 			else
522 				return sal_False;
523 		}
524 		if( !FileStat( rDirEntry ).IsKind( FSYS_KIND_DIR ) )
525 		{
526 			UniString aBoxText( SvtResId( STR_FILEDLG_CANTOPENDIR ) );
527 			aBoxText.AppendAscii( "\n[" );
528 			aBoxText += rDirEntry.GetFull();
529 			aBoxText.AppendAscii( "]" );
530 			InfoBox aBox( GetPathDialog(), aBoxText );
531 			aBox.Execute();
532 			return sal_False;
533 		}
534 	}
535 	return GetPathDialog()->OK() != 0;
536 }
537 
538 
539 void ImpPathDialog::PreExecute()
540 {
541 	// Neues Verzeichnis setzen und Listboxen updaten
542 	aPath.SetCWD( sal_True );
543 	UpdateEntries( sal_True );
544 
545 	// Zusaetzliche Buttons anordnen
546 	Point	aPos;
547 	Size	aSize;
548 	long	nDY;
549 	if( pLoadBtn )
550 	{
551 		aPos  = pLoadBtn->GetPosPixel();
552 		aSize = pLoadBtn->GetSizePixel();
553 		nDY   = pLoadBtn->GetSizePixel().Height() * 2;
554 	}
555 	else
556 	{
557 		aPos  = pCancelBtn->GetPosPixel();
558 		aSize = pCancelBtn->GetSizePixel();
559 		nDY   = pCancelBtn->GetPosPixel().Y() - pOkBtn->GetPosPixel().Y();
560 	}
561 
562 	// Standard-Controls anpassen
563 	long nMaxWidth = 0;
564 
565 	// Maximale Breite ermitteln
566 	sal_uInt16 nChilds = GetPathDialog()->GetChildCount();
567 	sal_uInt16 n;
568 	for ( n = nOwnChilds; n < nChilds; n++ )
569 	{
570 		Window* pChild = GetPathDialog()->GetChild( n );
571 		pChild = pChild->GetWindow( WINDOW_CLIENT );
572 		if( pChild->GetType() != WINDOW_WINDOW )
573 		{
574 			long nWidth = pChild->GetTextWidth( pChild->GetText() ) + 12;
575 			if( nMaxWidth < nWidth )
576 				nMaxWidth = nWidth;
577 			nWidth = pChild->GetSizePixel().Width();
578 			if( nMaxWidth < nWidth )
579 				nMaxWidth = nWidth;
580 		}
581 	}
582 
583 	if( nMaxWidth > aSize.Width() )
584 	{
585 		Size aDlgSize = GetPathDialog()->GetOutputSizePixel();
586 		GetPathDialog()->SetOutputSizePixel( Size( aDlgSize.Width()+nMaxWidth-aSize.Width(), aDlgSize.Height() ) );
587 		aSize.Width() = nMaxWidth;
588 
589 		if( pOkBtn )
590 			pOkBtn->SetSizePixel( aSize );
591 		if( pCancelBtn )
592 			pCancelBtn->SetSizePixel( aSize );
593 		if( pLoadBtn )
594 			pLoadBtn->SetSizePixel( aSize );
595 	}
596 	else
597 		nMaxWidth = aSize.Width();
598 
599 	for ( n = nOwnChilds; n < nChilds; n++ )
600 	{
601 		Window* pChild = GetPathDialog()->GetChild( n );
602 		pChild = pChild->GetWindow( WINDOW_CLIENT );
603 		if( pChild->GetType() != WINDOW_WINDOW )
604 		{
605 			aPos.Y() += nDY;
606 			pChild->SetPosSizePixel( aPos, aSize );
607 		}
608 		else
609 		{
610 			Size aDlgSize = GetPathDialog()->GetOutputSizePixel();
611 			long nExtra = Min( aDlgSize.Height(), (long)160);
612 			GetPathDialog()->SetOutputSizePixel( Size( aDlgSize.Width()+nExtra, aDlgSize.Height() ) );
613 			Size aSz( nExtra, nExtra );
614 			aSz.Width() -= 8;
615 			aSz.Height() -= 8;
616 			Point aCtrlPos( aDlgSize.Width() + 2, (aDlgSize.Height()-aSz.Height())/2 );
617 			pChild->SetPosSizePixel( aCtrlPos, aSz );
618 		}
619 	}
620 
621 	// Laufwerke-LB fuellen
622 	if( pDriveList )
623 	{
624 		DirEntry aTmpDirEntry;
625 		Dir aDir( aTmpDirEntry, FSYS_KIND_BLOCK );
626 
627 		sal_uInt16 nCount = aDir.Count(), i;
628 		for( i = 0; i < nCount; ++i )
629 		{
630 			DirEntry& rEntry = aDir[i];
631 			UniString aStr	  = rEntry.GetFull( FSYS_STYLE_HOST, sal_False );
632 
633 			UniString aVolume = rEntry.GetVolume() ;
634 			aStr.ToUpperAscii();
635 			if ( aVolume.Len() )
636 			{
637 				aStr += ' ';
638 				aStr += aVolume;
639 			}
640 			pDriveList->InsertEntry( aStr );
641 
642 		}
643 		UniString aPathStr = aPath.GetFull();
644 
645 		for ( i = 0; i < pDriveList->GetEntryCount(); ++i )
646 		{
647 			UniString aEntry = pDriveList->GetEntry(i);
648 			xub_StrLen nLen   = aEntry.Len();
649 			nLen = nLen > 2 ? 2 : nLen;
650 			if ( aEntry.CompareIgnoreCaseToAscii( aPathStr, nLen ) == COMPARE_EQUAL )
651 			{
652 				pDriveList->SelectEntryPos(i);
653 				break;
654 			}
655 		}
656 	}
657 }
658 
659 void ImpPathDialog::PostExecute()
660 {
661 }
662 
663 void ImpPathDialog::SetPath( UniString const & rPath )
664 {
665 	aPath = DirEntry( rPath );
666 
667 	pSvPathDialog->EnterWait();
668 
669 	DirEntry aFile( rPath );
670 	// Falls der Pfad eine Wildcard oder einen Filenamen enthaelt
671 	// -> abschneiden und merken
672 	if( FileStat( aFile ).GetKind() & (FSYS_KIND_FILE | FSYS_KIND_WILD) || !aFile.Exists() )
673 		aFile.CutName();
674 
675 	// Neue Maske und neues Verzeichnis setzen, und Listboxen updaten
676 	pEdit->SetText( rPath );
677 	aFile.SetCWD( sal_True );
678 	UpdateEntries( sal_True );
679 
680 	pSvPathDialog->LeaveWait();
681 }
682 
683 void ImpPathDialog::SetPath( Edit const & rEdit )
684 {
685 	UniString aPresetText = rEdit.GetText();
686 	if( aPresetText.Len() )
687 		SetPath( aPresetText );
688 }
689 
690 
691 UniString ImpPathDialog::GetPath() const
692 {
693 	DirEntry aFile( pEdit->GetText() );
694 	aFile.ToAbs();
695 	return aFile.GetFull();
696 }
697 
698 
699 ImpFileDialog::ImpFileDialog( PathDialog* pDlg, WinBits nWinBits, RESOURCE_TYPE nType ) :
700   ImpPathDialog( pDlg, nType, sal_False )
701 {
702 	bOpen = (nWinBits & WB_SAVEAS) == 0;
703 
704 	SvtResId aSvtResId = bOpen ? STR_FILEDLG_OPEN : STR_FILEDLG_SAVE;
705 
706 	// Titel setzen
707 	GetFileDialog()->SetText( UniString( aSvtResId ) );
708 	nDirCount = 0;
709 
710 	// initialize Controls if not used as a base class
711 	if ( nType == WINDOW_FILEDIALOG )
712 		InitControls();
713 
714 	pDlg->SetHelpId( HID_FILEDLG_OPENDLG );
715 
716 }
717 
718 ImpFileDialog::~ImpFileDialog()
719 {
720 	ImpFilterItem* pItem = aFilterList.First();
721 	while( pItem )
722 	{
723 		delete pItem;
724 		pItem = aFilterList.Next();
725 	}
726 
727 	delete pFileTitel;
728 	if (pFileList && ( pFileList != pDirList ) )
729 		delete pFileList;
730 
731 	delete pTypeTitel;
732 	delete pTypeList;
733 }
734 
735 void ImpFileDialog::InitControls()
736 {
737 	UniString aEmptyStr;
738 
739 	const int nW = 160;
740 	const int nH = 48; // Um den Dialog in eine akzeptable Form zu bringen
741 
742 	INITCONTROL( pFileTitel, FixedText, 0,
743 		Point(10, 12), Size(nW, 18), UniString( SvtResId( STR_FILEDLG_FILE ) ), HID_FILEDLG_FILE );
744 	INITCONTROL( pEdit, Edit, WB_BORDER,
745 		Point(10, 31), Size(nW, 20), aEmptyStr, HID_FILEDLG_EDIT ); // aMask()
746 	INITCONTROL( pFileList, ListBox, WB_SORT | WB_AUTOHSCROLL | WB_BORDER,
747 		Point(10, 58), Size(nW, 180-nH), aEmptyStr, HID_FILEDLG_FILES );
748 
749 	INITCONTROL( pDirTitel, FixedText, 0,
750 		Point(nW+20, 12), Size(nW, 18), UniString( SvtResId( STR_FILEDLG_DIR ) ), HID_FILEDLG_DIR );
751 	INITCONTROL( pDirPath, FixedInfo, WB_PATHELLIPSIS,
752 		Point(nW+20, 33), Size(nW, 20), aPath.GetFull(), HID_FILEDLG_PATH );
753 	INITCONTROL( pDirList, KbdListBox, WB_AUTOHSCROLL | WB_BORDER,
754 		Point(nW+20, 58), Size(nW, 180-nH ), aEmptyStr, HID_FILEDLG_DIRS );
755 
756 	INITCONTROL( pTypeTitel, FixedText, 0,
757 		Point(10, 246-nH), Size(nW, 18), UniString( SvtResId( STR_FILEDLG_TYPE ) ), HID_FILEDLG_TYPE );
758 
759 #ifndef UNX
760 	INITCONTROL( pTypeList, ListBox, WB_DROPDOWN,
761 		Point(10, 265-nH ), Size(nW, 100 ), aEmptyStr, HID_FILEDLG_TYPES );
762 
763 	INITCONTROL( pDriveTitle, FixedText, 0,
764 		Point(nW+20, 246-nH), Size(nW, 18), UniString( SvtResId( STR_FILEDLG_DRIVES ) ), HID_FILEDLG_DRIVE );
765 	INITCONTROL( pDriveList, ListBox, WB_DROPDOWN,
766 		Point(nW+20, 265-nH ), Size(nW, 100 ), aEmptyStr, HID_FILEDLG_DRIVES );
767 	pNewDirBtn = NULL;
768 	pHomeBtn   = NULL;
769 #else
770 	INITCONTROL( pTypeList, ListBox, WB_DROPDOWN,
771 		Point(10, 265-nH ), Size(2*nW+20, 100 ), aEmptyStr, HID_FILEDLG_TYPES );
772 
773 	pDriveTitle = NULL;
774 	pDriveList = NULL;
775 	pNewDirBtn = NULL;
776 	pHomeBtn   = NULL;
777 #endif
778 
779 	const long nButtonStartX = 2*nW+20+15;
780 	INITCONTROL( pOkBtn, PushButton, WB_DEFBUTTON,
781 		Point(nButtonStartX, 10), Size(STD_BTN_WIDTH, STD_BTN_HEIGHT),
782 		Button::GetStandardText( BUTTON_OK ), "" );
783 	INITCONTROL( pCancelBtn, CancelButton, 0,
784 		Point(nButtonStartX, 45 ), Size(STD_BTN_WIDTH, STD_BTN_HEIGHT),
785 		Button::GetStandardText( BUTTON_CANCEL ), "" );
786 
787 	pLoadBtn = 0;
788 
789 	GetFileDialog()->SetOutputSizePixel( Size(nButtonStartX+STD_BTN_WIDTH+10, 298-nH) );
790 
791 	nOwnChilds = GetPathDialog()->GetChildCount();
792 
793 	// Handler setzen
794 	if (pDriveList)
795 		pDriveList->SetSelectHdl( LINK( this, ImpFileDialog, SelectHdl ) );
796 
797 	if (pDirList)
798 		pDirList->SetDoubleClickHdl(LINK( this, ImpFileDialog, DblClickHdl) );
799 
800 	if (pOkBtn)
801 		pOkBtn->SetClickHdl( LINK( this, ImpFileDialog, ClickHdl) );
802 
803 	if (pCancelBtn)
804 		pCancelBtn->SetClickHdl( LINK( this, ImpFileDialog, ClickHdl) );
805 
806 	if( pFileList )
807 	{
808 		pFileList->SetSelectHdl( LINK( this, ImpFileDialog, SelectHdl ) );
809 		pFileList->SetDoubleClickHdl( LINK( this, ImpFileDialog, DblClickHdl ) );
810 	}
811 
812 	if( pTypeList )
813 		pTypeList->SetSelectHdl( LINK( this, ImpFileDialog, DblClickHdl ) );
814 }
815 
816 IMPL_LINK( ImpFileDialog, SelectHdl, ListBox *, p )
817 {
818 	if( p == pDriveList )
819 	{
820 		UniString aDrive ( pDriveList->GetSelectEntry(), 0, 2);
821 		aDrive += '\\';
822 		SetPath( aDrive );
823 	}
824 	else if (p == pFileList)
825 	{
826 		// Ausgewaehltes File in das Edit stellen
827 		pEdit->SetText( pFileList->GetSelectEntry() );
828 		GetFileDialog()->FileSelect();
829 	}
830 	return 0;
831 }
832 
833 
834 IMPL_LINK( ImpFileDialog, DblClickHdl, ListBox *, pBox )
835 {
836   // isolate the pure name of the entry
837   // removing trailing stuff and leading spaces
838 	UniString aEntry( pBox->GetSelectEntry() );
839 
840 	aEntry.EraseLeadingChars( ' ' );
841 	sal_uInt16 nPos = aEntry.Search( '/' );
842 	aEntry.Erase( nPos );
843 
844 	// build the absolute path to the selected item
845 	DirEntry aNewPath;
846 	aNewPath.ToAbs();
847 
848 	if( ( pDirList != pFileList ) && ( pBox == pDirList ) )
849 	{
850 		// SVLOOK
851 		sal_uInt16 nCurPos = pDirList->GetSelectEntryPos();
852 
853 		// Wenn es schon das aktuelle ist, dann mache nichts
854 		if( nCurPos == nDirCount-1 )
855 			return 0;
856 
857 		// Wird nach oben gewechselt
858 		if( nCurPos < nDirCount )
859 			aNewPath = aNewPath[nDirCount-nCurPos-1];
860 		else
861 			aNewPath += aEntry;
862 	}
863 	else
864 	{
865 		// non-SVLOOK
866 		if( aEntry == UniString( SvtResId( STR_FILEDLG_GOUP ) ) )
867 			aEntry.AssignAscii( ".." );
868 		aNewPath += aEntry;
869 	}
870 
871 	if( pBox == pFileList )
872 	{
873 		DirEntry aFile( aEntry );
874 
875 		// Abfrage, ob File ueberschrieben werden soll...
876 		if( !FileStat(aFile).IsKind(FSYS_KIND_DIR) && IsFileOk( aFile ) )
877 		{
878 			// dann kompletten Pfad mit Filenamen merken und Dialog beenden
879 			aPath = aNewPath;
880 			GetFileDialog()->EndDialog( sal_True );
881 		}
882 	}
883 
884 	GetFileDialog()->EnterWait();
885 
886 	UniString aFull = aNewPath.GetFull();
887 
888 	if( ( ( pBox == pDirList ) && ( pDirList != pFileList ) ) ||
889 		( ( pDirList == pFileList ) && FileStat( aNewPath ).GetKind() & FSYS_KIND_DIR ) )
890 	{
891 		// Neuen Pfad setzen und Listboxen updaten
892 		aPath = aNewPath;
893 		if( !aPath.SetCWD( sal_True ) )
894 		{
895 			if( ErrorBox( GetFileDialog(), WB_OK_CANCEL|WB_DEF_OK,
896 								UniString( SvtResId( STR_FILEDLG_CANTCHDIR ) ) ).Execute() == RET_CANCEL )
897 			{
898 				GetFileDialog()->EndDialog( sal_False );
899 			}
900 		}
901 		UpdateEntries( sal_True );
902 		GetFileDialog()->FileSelect();
903 	}
904 
905 	if( pBox == pTypeList )
906 	{
907 		// Neue Maske setzen, und Listboxen updaten
908 		sal_uInt16 nCurPos = pTypeList->GetSelectEntryPos();
909 		if( nCurPos+1 > (sal_uInt16)aFilterList.Count() )
910 			aMask = UniString::CreateFromAscii( ALLFILES );
911 		else
912 		{
913 			UniString aFilterListMask = aFilterList.GetObject( nCurPos )->aMask;
914 //						if( aFilterListMask.Search( ';' ) == STRING_NOTFOUND ) // kein ; in der Maske
915 //								aMask = WildCard( aFilterListMask, '\0' );
916 //						else // ; muss beruecksichtigt werden
917 				aMask = WildCard( aFilterListMask, ';' );
918 		}
919 
920 		pEdit->SetText( aMask() );
921 		UpdateEntries( sal_False );
922 		GetFileDialog()->FilterSelect();
923 	}
924 
925   GetFileDialog()->LeaveWait();
926 
927   return 0;
928 }
929 
930 IMPL_LINK( ImpFileDialog, ClickHdl, Button*, pBtn )
931 {
932 	if( ( pBtn == pOkBtn ) || ( pBtn == pLoadBtn ) )
933 	{
934 		DirEntry aFile( pEdit->GetText() );
935 
936 		// Existiert File / File ueberschreiben
937 		if( IsFileOk( aFile ) )
938 		{
939 			// Ja, dann kompletten Pfad mit Filenamen merken und Dialog beenden
940 			aPath = aFile;
941 			aPath.ToAbs();
942 			GetFileDialog()->EndDialog( sal_True );
943 		}
944 		else
945 		{
946 			GetFileDialog()->EnterWait();
947 
948 			// Falls der Pfad eine Wildcard oder einen Filenamen enthaelt
949 			// -> abschneiden und merken
950 			if( FileStat( aFile ).GetKind() & (FSYS_KIND_FILE | FSYS_KIND_WILD) || !aFile.Exists() )
951 			{
952 				aMask = aFile.CutName();
953 			}
954 
955 			// Neue Maske und neues Verzeichnis setzen, und Listboxen updaten
956 			pEdit->SetText( aMask() );
957 			aFile.SetCWD( sal_True );
958 			UpdateEntries( sal_True );
959 
960 			GetFileDialog()->LeaveWait();
961 		}
962 	}
963 	else if( pBtn == pCancelBtn )
964 		GetFileDialog()->EndDialog( sal_False );
965 
966 	return 0;
967 }
968 
969 void ImpFileDialog::UpdateEntries( const sal_Bool bWithDirs )
970 {
971 	GetFileDialog()->EnterWait();
972 
973 	UniString aTabString;
974 	DirEntry aTmpPath;
975 	aTmpPath.ToAbs();
976 	nDirCount = aTmpPath.Level();
977 
978 	if( pFileList )
979 	{
980 	pFileList->SetUpdateMode( sal_False );
981 		pFileList->Clear();
982 	}
983 
984 	if( bWithDirs && (pDirList != pFileList) )
985 	{
986 		pDirList->SetUpdateMode( sal_False );
987 		pDirList->Clear();
988 
989 		for( sal_uInt16 i = nDirCount; i > 0; i-- )
990 		{
991 			UniString aEntryStr( aTabString );
992 			aEntryStr += aTmpPath[i-1].GetName();
993 			pDirList->InsertEntry( aEntryStr );
994 			aTabString.AppendAscii( "  ", 2 );
995 		}
996 	}
997 
998 	// for the combined box insert a '..'
999 	// (this happens only if WB_3DLOOK is not set)
1000 
1001 	if( pDirList == pFileList && nDirCount != 1 )
1002 		pFileList->InsertEntry( UniString( SvtResId( STR_FILEDLG_GOUP ) ) );
1003 
1004 	// scan the directory
1005 	DirEntry aCurrent;
1006 	aCurrent.ToAbs();
1007 	Dir aDir( aCurrent, FSYS_KIND_DIR|FSYS_KIND_FILE );
1008 	sal_uInt16 nEntries = aDir.Count();
1009 
1010 	// TempMask, weil Vergleich case-sensitiv
1011 	sal_Bool bMatchCase = sal_False; //aCurrent.IsCaseSensitive();
1012 	UniString aWildCard( aMask.GetWildCard() );
1013 	if ( !bMatchCase )
1014 		aWildCard.ToLowerAscii();
1015 	WildCard aTmpMask( aWildCard, ';' );
1016 	if ( nEntries )
1017 	{
1018 		UniStringList	aSortDirList;
1019         for ( sal_uInt16 n = 0; n < nEntries; n++ )
1020 		{
1021 			DirEntry& rEntry = aDir[n];
1022             UniString aName( rEntry.GetName() );
1023 
1024 			if( aName.Len() &&
1025 				( ( ( aName.GetChar(0) != '.' ) ||
1026 				  ( ( aName.GetChar(0) == '.' ) && ( aMask.GetWildCard() ).GetChar(0) == '.' ) )
1027 						&& rEntry.Exists() ) )
1028 			{
1029 				FileStat aFileStat( rEntry );
1030 				UniString aTmpName( aName );
1031 				if ( !bMatchCase )
1032 					aTmpName.ToLowerAscii();
1033 				if( ( aFileStat.GetKind() & FSYS_KIND_FILE ) && aTmpMask.Matches( aTmpName ) )
1034 				{
1035 					if( pFileList )
1036                         pFileList->InsertEntry( aName );
1037 				}
1038                 else if( bWithDirs && ( aFileStat.GetKind() & FSYS_KIND_DIR ) )
1039 				{
1040 					if( pDirList == pFileList )
1041 					{
1042 						UniString aEntryStr( aName );
1043 						aEntryStr += '/';
1044 						pDirList->InsertEntry( aEntryStr );
1045 					}
1046 					else
1047 					{
1048                         sal_uLong l = 0;
1049                         if( xCollator.is() )
1050                         {
1051                             for( l = 0; l < aSortDirList.Count(); l++ )
1052                                 if( xCollator->compareString( *aSortDirList.GetObject(l), aName ) > 0 )
1053                                     break;
1054                         }
1055                         aSortDirList.Insert( new UniString( aName ), l );
1056 			}
1057 		}
1058 		}
1059 	}
1060 	for( sal_uLong l = 0; l < aSortDirList.Count(); l++ )
1061 		{
1062 			UniString aEntryStr( aTabString );
1063 			aEntryStr += *aSortDirList.GetObject(l);
1064 		pDirList->InsertEntry( aEntryStr );
1065 		delete aSortDirList.GetObject(l);
1066 	}
1067 	}
1068 
1069 	if( bWithDirs )
1070 		UpdateDirs( aTmpPath );
1071 
1072 	if( pFileList )
1073 	{
1074 	if ( pDirList == pFileList && nDirCount > 1 )
1075 		pFileList->SelectEntryPos( 1 );
1076 	else
1077 		pFileList->SetNoSelection();
1078 	pFileList->SetUpdateMode( sal_True );
1079 	pFileList->Invalidate();
1080 	pFileList->Update();
1081 	}
1082 
1083 	if( pDriveList )
1084 	{
1085 		if( pDirList->GetEntryCount() > 0 )
1086 		{
1087 			UniString aStr( pDirList->GetEntry( 0 ) );
1088 			aStr.Erase( 2 );
1089 			aStr.ToLowerAscii();
1090 			pDriveList->SelectEntry( aStr );
1091 		}
1092 	}
1093 
1094   GetFileDialog()->LeaveWait();
1095 }
1096 
1097 sal_Bool ImpFileDialog::IsFileOk( const DirEntry& rDirEntry )
1098 {
1099 	if( FileStat( rDirEntry ).GetKind() & (FSYS_KIND_WILD | FSYS_KIND_DEV) )
1100 	return sal_False;
1101 	if( FileStat( rDirEntry ).GetKind() & FSYS_KIND_DIR )
1102 	{
1103 		if( pFileList )
1104 			return sal_False;
1105 	}
1106 	else if( bOpen )
1107 	{
1108 	// Datei vorhanden ?
1109 	if( !FileStat( rDirEntry ).IsKind( FSYS_KIND_FILE ) )
1110 		{
1111 			UniString aErrorString( SvtResId( STR_FILEDLG_CANTOPENFILE ) );
1112 			aErrorString.AppendAscii( "\n[" );
1113 			aErrorString += rDirEntry.GetFull();
1114 			aErrorString += ']';
1115 			InfoBox aBox( GetFileDialog(),
1116 						  aErrorString );
1117 			aBox.Execute();
1118 		return sal_False;
1119 	}
1120 	}
1121 	else
1122 	{
1123 	// Datei vorhanden ?
1124 		if( FileStat( ExtendFileName( rDirEntry ) ).IsKind( FSYS_KIND_FILE ) )
1125 		{
1126 			UniString aQueryString( SvtResId( STR_FILEDLG_OVERWRITE ) );
1127 			aQueryString.AppendAscii( "\n[" );
1128 			aQueryString += rDirEntry.GetFull();
1129 			aQueryString += ']';
1130 			QueryBox aBox( GetFileDialog(),
1131 						   WinBits( WB_YES_NO | WB_DEF_NO ),
1132 						   aQueryString );
1133 			if( aBox.Execute() != RET_YES )
1134 				return sal_False;
1135 	}
1136 	}
1137 	return GetFileDialog()->OK() != 0;
1138 }
1139 
1140 void ImpFileDialog::SetPath( UniString const & rPath )
1141 {
1142 	aPath = DirEntry( rPath );
1143 	GetFileDialog()->EnterWait();
1144 
1145 	DirEntry aFile( rPath );
1146 
1147 	// Falls der Pfad eine Wildcard oder einen Filenamen enthaelt
1148 	// -> abschneiden und merken
1149 	if( FileStat( aFile ).GetKind() & (FSYS_KIND_FILE | FSYS_KIND_WILD) 	|| !aFile.Exists() )
1150 	{
1151 		aMask = aFile.CutName();
1152 
1153 		// Neue Maske und neues Verzeichnis setzen, und Listboxen updaten
1154 		if( pDirList )
1155 		{
1156 			UniString aWildCard( aMask.GetWildCard() );
1157 			pEdit->SetText( aWildCard );
1158 		}
1159 		else
1160 			pEdit->SetText( rPath );
1161 	}
1162 
1163 	aFile.SetCWD( sal_True );
1164 
1165 	UpdateEntries( sal_True );
1166 
1167 	GetFileDialog()->LeaveWait();
1168 }
1169 
1170 void ImpFileDialog::SetPath( Edit const& rEdit )
1171 {
1172 	UniString aPresetText = rEdit.GetText();
1173 	if( aPresetText.Len() )
1174 		SetPath( aPresetText );
1175 }
1176 
1177 
1178 void ImpFileDialog::AddFilter( const UniString& rFilter, const UniString& rMask )
1179 {
1180 	aFilterList.Insert( new ImpFilterItem( rFilter, rMask ), LIST_APPEND );
1181 	if( pTypeList )
1182 		pTypeList->InsertEntry( rFilter, LISTBOX_APPEND );
1183 
1184 	if( !GetCurFilter().Len() )
1185 		SetCurFilter( rFilter );
1186 }
1187 
1188 void ImpFileDialog::RemoveFilter( const UniString& rFilter )
1189 {
1190 	ImpFilterItem* pItem = aFilterList.First();
1191 	while( pItem && pItem->aName != rFilter )
1192 		pItem = aFilterList.Next();
1193 
1194 	if( pItem )
1195 	{
1196 		delete aFilterList.Remove();
1197 		if( pTypeList )
1198 			pTypeList->RemoveEntry( rFilter );
1199 	}
1200 }
1201 
1202 void ImpFileDialog::RemoveAllFilter()
1203 {
1204 	ImpFilterItem* pItem = aFilterList.First();
1205 	while( pItem )
1206 	{
1207 		delete pItem;
1208 		pItem = aFilterList.Next();
1209 	}
1210 	aFilterList.Clear();
1211 
1212 	if( pTypeList )
1213 		pTypeList->Clear();
1214 }
1215 
1216 void ImpFileDialog::SetCurFilter( const UniString& rFilter )
1217 {
1218 	if( !pTypeList )
1219 		return;
1220 
1221 	ImpFilterItem* pItem = aFilterList.First();
1222 	while( pItem && pItem->aName != rFilter )
1223 		pItem = aFilterList.Next();
1224 
1225 	if( pItem )
1226 		pTypeList->SelectEntryPos( (sal_uInt16)aFilterList.GetCurPos() );
1227 	else
1228 		pTypeList->SetNoSelection();
1229 }
1230 
1231 UniString ImpFileDialog::GetCurFilter() const
1232 {
1233 	UniString aFilter;
1234 	if ( pTypeList )
1235 		aFilter = pTypeList->GetSelectEntry();
1236 	return aFilter;
1237 }
1238 
1239 void ImpFileDialog::PreExecute()
1240 {
1241 	// ListBoxen erst unmittelbar vor Execute fuellen
1242 	// (damit vor Execute der Pfad umgesetzt werden kann, ohne das immer die
1243 	//	Listboxen sofort upgedatet werden)
1244 
1245 	GetFileDialog()->EnterWait();
1246 
1247 	// Wenn kein Filter vorhanden, dann auch keine FilterBox
1248 	if( pTypeList && !pTypeList->GetEntryCount() )
1249 	{
1250 		// pTypeList->InsertEntry( "* (all files)" );
1251 		pTypeTitel->Disable();
1252 		pTypeList->Disable();
1253 	}
1254 
1255 	if( pTypeList )
1256 	{
1257 		sal_uInt16 nCurType = pTypeList->GetSelectEntryPos();
1258 		if( nCurType < aFilterList.Count() )
1259 		{
1260 			UniString aFilterListMask = aFilterList.GetObject( nCurType )->aMask;
1261 			if( aFilterListMask.Search( ';' ) == STRING_NOTFOUND ) // kein ; in der Maske
1262 				aMask = WildCard( aFilterListMask, '\0' );
1263 			else // ; in der Maske, muss in der Wildcard beruecksichtigt werden
1264 				aMask = WildCard( aFilterListMask, ';' );
1265 		}
1266 		else
1267 			aMask = UniString::CreateFromAscii( ALLFILES );
1268 	}
1269 	else
1270 		aMask = UniString::CreateFromAscii( ALLFILES );
1271 
1272 	// Neue Maske setzen
1273 	if( pEdit->GetText().Len() == 0 )
1274 		pEdit->SetText( aMask() );
1275 
1276 	ImpPathDialog::PreExecute();
1277 
1278 	GetFileDialog()->LeaveWait();
1279 }
1280 
1281 UniString ImpFileDialog::GetPath() const
1282 {
1283 	DirEntry aFile( pEdit->GetText() );
1284 	return ExtendFileName( aFile );
1285 }
1286 
1287 UniString ImpFileDialog::ExtendFileName( DirEntry aEntry ) const
1288 {
1289 	aEntry.ToAbs();
1290 	// das ganze Theater hier ohnehin nur machen, wenn Dateiname
1291 	// ohne Extension angegeben wurde
1292 	if( !aEntry.GetExtension().Len() )
1293 	{
1294 		UniString aPostfix; // hier kommt die ausgesuchte Extension herein
1295 
1296 		// ist ein Filter mit Extension gesetzt?
1297 		sal_uInt16 nChosenFilterPos = pTypeList->GetSelectEntryPos();
1298 		if( nChosenFilterPos != LISTBOX_ENTRY_NOTFOUND )
1299 		{
1300 			UniString aExtensionMask = GetFileDialog()->GetFilterType( nChosenFilterPos );
1301 			// aExtension ist z.B. *.sdw, alles bis einschliesslich Punkt abschneiden
1302 			UniString aExtension = aExtensionMask.Copy( aExtensionMask.Search( '.' )+1 );
1303 
1304 			// hat der Filter ueberhaupt eine Extension
1305 			if( aExtension.Len() )
1306 			{
1307 				// keine Wildcards enthalten?
1308 				if( ( aExtension.Search( '*' ) == STRING_NOTFOUND ) &&
1309 					( aExtension.Search( '?' ) == STRING_NOTFOUND ) )
1310 				{
1311 					// OK, Filter hat Extension ohne Wildcards -> verwenden
1312 					aPostfix = aExtension;
1313 				}
1314 				else
1315 				{
1316 					// Filter hat Extension mit Wildcards (z.B. *.*) -> nicht verwenden
1317 					aPostfix.Erase();
1318 				}
1319 			}
1320 			else
1321 			{
1322 				// Filter hatte keine Extension (schwer vorstellbar) -> nichts anhaengen
1323 				aPostfix.Erase();
1324 			}
1325 		}
1326 		else
1327 		{
1328 			// kein Filter gefunden (merkw�rdig) -> Default-Extension anhaengen
1329 			aPostfix = GetFileDialog()->GetDefaultExt();
1330 		}
1331 
1332 		// jetzt kann es mit dem Anhaengen losgehen
1333 		const sal_Unicode* pExt = aPostfix.GetBuffer();
1334 		while( *pExt == '*' || *pExt == '?' )
1335 			pExt++;
1336 
1337 		if( *pExt )
1338 		{
1339 			UniString aName = aEntry.GetName();
1340 			if( *pExt != '.' )
1341 				aName += '.';
1342 			aName += pExt;
1343 			aEntry.SetName( aName );
1344 		}
1345 	}
1346 	return aEntry.GetFull();
1347 }
1348 
1349 
1350 void ImpSvFileDlg::CreateDialog( PathDialog* pSvDlg, WinBits nStyle, RESOURCE_TYPE nType, sal_Bool bCreate )
1351 {
1352 	delete pDlg;
1353 	if ( nType == WINDOW_PATHDIALOG )
1354 		pDlg = new ImpPathDialog( pSvDlg, nType, bCreate );
1355 	else
1356 		pDlg = new ImpFileDialog( pSvDlg, nStyle, nType );
1357 }
1358 
1359 
1360