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