1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: filedlg2.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svtools.hxx"
33 #include <vcl/svapp.hxx>
34 #ifndef _SV_BUTTON_HXX //autogen
35 #include <vcl/button.hxx>
37 #include <vcl/fixed.hxx>
38 #include <vcl/edit.hxx>
39 #include <vcl/lstbox.hxx>
40 #include <svtools/svtdata.hxx>
42 #include <filedlg2.hxx>
43 #include <filedlg.hxx>
44 #include <filedlg2.hrc>
45 #include <vcl/msgbox.hxx>
46 #include <vos/security.hxx>
47 #include <com/sun/star/i18n/XCollator.hpp>
49 #include <svtools/stdctrl.hxx>
52 #pragma optimize ("", off)
55 #include <svtools/helpid.hrc>
57 using namespace com::sun::star
;
58 using namespace com::sun::star::uno
;
61 DECLARE_LIST( UniStringList
, UniString
* )
63 #define STD_BTN_WIDTH 80
64 #define STD_BTN_HEIGHT 26
67 #define ALLFILES "*.*"
71 // #define STD_BTN_WIDTH 90
72 // #define STD_BTN_HEIGHT 35
74 #define INITCONTROL( p, ControlClass, nBits, aPos, aSize, aTitel, nHelpId ) \
75 p = new ControlClass( GetPathDialog(), WinBits( nBits ) ); \
76 p->SetHelpId( nHelpId ); \
77 p->SetPosSizePixel( aPos, aSize ); \
78 p->SetText( aTitel ); \
82 inline BOOL
IsPrintable( sal_Unicode c
)
84 return c
>= 32 && c
!= 127 ? TRUE
: FALSE
;
88 KbdListBox::PreNotify( NotifyEvent
& rNEvt
)
90 if ( rNEvt
.GetType() == EVENT_KEYINPUT
)
92 KeyEvent aKeyEvt
= *rNEvt
.GetKeyEvent();
93 sal_Unicode cCharCode
= aKeyEvt
.GetCharCode();
95 if ( IsPrintable ( cCharCode
) )
97 USHORT nCurrentPos
= GetSelectEntryPos();
98 USHORT nEntries
= GetEntryCount();
100 for ( USHORT i
= 1; i
< nEntries
; i
++ )
102 UniString aEntry
= GetEntry ( (i
+ nCurrentPos
) % nEntries
);
103 aEntry
.EraseLeadingChars( ' ' );
104 aEntry
.ToUpperAscii();
105 UniString
aCompare( cCharCode
);
106 aCompare
.ToUpperAscii();
108 if ( aEntry
.CompareTo( aCompare
, 1 ) == COMPARE_EQUAL
)
110 SelectEntryPos ( (i
+ nCurrentPos
) % nEntries
);
116 if ( aKeyEvt
.GetKeyCode().GetCode() == KEY_RETURN
)
122 return ListBox::PreNotify ( rNEvt
);
125 ImpPathDialog::ImpPathDialog( PathDialog
* pDlg
, RESOURCE_TYPE nType
, BOOL bCreateDir
)
127 pSvPathDialog
= pDlg
;
130 // initialize Controls if not used as a base class
131 if ( nType
== WINDOW_PATHDIALOG
)
135 pNewDirBtn
->Enable( bCreateDir
);
138 pDlg
->SetHelpId( HID_FILEDLG_PATHDLG
);
140 lang::Locale aLocale
= Application::GetSettings().GetLocale();
141 xCollator
= ::vcl::unohelper::CreateCollator();
143 xCollator
->loadDefaultCollator( aLocale
, 1 );
144 DBG_ASSERT( xCollator
.is(), "not collator service for path dialog" );
147 ImpPathDialog::~ImpPathDialog()
159 # if defined(UNX) || defined(OS2)
164 void ImpPathDialog::InitControls()
166 PathDialog
* pDlg
= GetPathDialog();
167 pDlg
->SetText( UniString( SvtResId( STR_FILEDLG_SELECT
) ) );
169 Size a3Siz
= pDlg
->LogicToPixel( Size( 3, 3 ), MAP_APPFONT
);
170 Size a6Siz
= pDlg
->LogicToPixel( Size( 6, 6 ), MAP_APPFONT
);
171 Size aBtnSiz
= pDlg
->LogicToPixel( Size( 50, 14 ), MAP_APPFONT
);
172 Size aFTSiz
= pDlg
->LogicToPixel( Size( 142, 10 ), MAP_APPFONT
);
173 Size aEDSiz
= pDlg
->LogicToPixel( Size( 142, 12 ), MAP_APPFONT
);
174 Point
aPnt( a6Siz
.Width(), a6Siz
.Height() );
175 long nLbH1
= pDlg
->LogicToPixel( Size( 0, 93 ), MAP_APPFONT
).Height();
179 INITCONTROL( pDirTitel
, FixedText
, 0,
180 aPnt
, aFTSiz
, UniString( SvtResId( STR_FILEDLG_DIR
) ), HID_FILEDLG_DIR
);
181 aPnt
.Y() += aFTSiz
.Height() + a3Siz
.Height();
183 INITCONTROL( pEdit
, Edit
, WB_BORDER
, aPnt
, aEDSiz
, aPath
.GetFull(), HID_FILEDLG_EDIT
);
185 aPnt
.Y() += aEDSiz
.Height() + a3Siz
.Height();
187 long nLbH2
= pDlg
->LogicToPixel( Size( 0, 60 ), MAP_APPFONT
).Height();
188 INITCONTROL( pDirList
, KbdListBox
, WB_AUTOHSCROLL
| WB_BORDER
,
189 aPnt
, Size( aEDSiz
.Width(), nLbH1
), aEmptyStr
, HID_FILEDLG_DIRS
);
190 aPnt
.Y() += nLbH1
+ a6Siz
.Height();
191 INITCONTROL( pDriveTitle
, FixedText
, 0,
192 aPnt
, aFTSiz
, UniString( SvtResId( STR_FILEDLG_DRIVES
) ), HID_FILEDLG_DRIVE
);
193 aPnt
.Y() += aFTSiz
.Height() + a3Siz
.Height();
194 INITCONTROL( pDriveList
, ListBox
, WB_DROPDOWN
,
195 aPnt
, Size( aEDSiz
.Width(), nLbH2
), aEmptyStr
, HID_FILEDLG_DRIVES
);
196 nH
= aPnt
.Y() + aEDSiz
.Height() + a6Siz
.Height();
198 long nNewH
= nLbH1
+ 3 * a3Siz
.Height() +
199 aFTSiz
.Height() + aEDSiz
.Height();
200 INITCONTROL( pDirList
, KbdListBox
, WB_AUTOHSCROLL
| WB_BORDER
,
201 aPnt
, Size( aEDSiz
.Width(), nNewH
), aEmptyStr
, HID_FILEDLG_DIRS
);
202 nH
= aPnt
.Y() + nNewH
+ a6Siz
.Height();
207 long nExtraWidth
= pDlg
->GetTextWidth( String( RTL_CONSTASCII_USTRINGPARAM( "(W)" ) ) )+10;
208 String aOkStr
= Button::GetStandardText( BUTTON_OK
);
209 long nTextWidth
= pDlg
->GetTextWidth( aOkStr
)+nExtraWidth
;
210 if( nTextWidth
> aBtnSiz
.Width() )
211 aBtnSiz
.Width() = nTextWidth
;
213 String aCancelStr
= Button::GetStandardText( BUTTON_CANCEL
);
214 nTextWidth
= pDlg
->GetTextWidth( aCancelStr
)+nExtraWidth
;
215 if( nTextWidth
> aBtnSiz
.Width() )
216 aBtnSiz
.Width() = nTextWidth
;
218 String
aNewDirStr( SvtResId( STR_FILEDLG_NEWDIR
) );
219 nTextWidth
= pDlg
->GetTextWidth( aNewDirStr
)+nExtraWidth
;
220 if( nTextWidth
> aBtnSiz
.Width() )
221 aBtnSiz
.Width() = nTextWidth
;
222 #if defined(UNX) || defined(OS2)
223 String
aHomeDirStr( SvtResId( STR_FILEDLG_HOME
) );
224 nTextWidth
= pDlg
->GetTextWidth( aHomeDirStr
)+nExtraWidth
;
225 if( nTextWidth
> aBtnSiz
.Width() )
226 aBtnSiz
.Width() = nTextWidth
;
229 aPnt
.X() = 2 * a6Siz
.Width() + aEDSiz
.Width();
230 aPnt
.Y() = a6Siz
.Height();
231 INITCONTROL( pOkBtn
, PushButton
, WB_DEFBUTTON
,
232 aPnt
, aBtnSiz
, aOkStr
, 0 );
233 aPnt
.Y() += aBtnSiz
.Height() + a3Siz
.Height();
234 INITCONTROL( pCancelBtn
, CancelButton
, 0,
235 aPnt
, aBtnSiz
, aCancelStr
, 0 );
236 aPnt
.Y() += aBtnSiz
.Height() + a3Siz
.Height();
237 INITCONTROL( pNewDirBtn
, PushButton
, WB_DEFBUTTON
,
238 aPnt
, aBtnSiz
, aNewDirStr
, HID_FILEDLG_NEWDIR
);
239 #if defined(UNX) || defined(OS2)
240 aPnt
.Y() += aBtnSiz
.Height() + a3Siz
.Height();
241 INITCONTROL( pHomeBtn
, PushButton
, WB_DEFBUTTON
,
242 aPnt
, aBtnSiz
, aHomeDirStr
, HID_FILEDLG_HOME
);
249 // Dialogbreite == OKBtn-Position + OKBtn-Breite + Rand
250 long nW
= aPnt
.X() + aBtnSiz
.Width() + a6Siz
.Width();
252 pDlg
->SetOutputSizePixel( Size( nW
, nH
) ); // Groesse ggf. auch Resource wird geplaettet?
255 pDirList
->SetDoubleClickHdl(LINK( this, ImpPathDialog
, DblClickHdl
) );
258 pDirList
->SetSelectHdl( LINK( this, ImpPathDialog
, SelectHdl
) );
261 pDriveList
->SetSelectHdl( LINK( this, ImpPathDialog
, SelectHdl
) );
264 pOkBtn
->SetClickHdl( LINK( this, ImpPathDialog
, ClickHdl
) );
267 pCancelBtn
->SetClickHdl( LINK( this, ImpPathDialog
, ClickHdl
) );
270 pHomeBtn
->SetClickHdl( LINK( this, ImpPathDialog
, ClickHdl
) );
273 pNewDirBtn
->SetClickHdl( LINK( this, ImpPathDialog
, ClickHdl
) );
275 nOwnChilds
= pDlg
->GetChildCount();
280 IMPL_LINK( ImpPathDialog
, SelectHdl
, ListBox
*, p
)
282 if( p
== pDriveList
)
284 UniString
aDrive( pDriveList
->GetSelectEntry(), 0, 2);
291 // isolate the pure name of the entry
292 // removing trainling stuff and leading spaces
293 UniString
aEntry( pDirList
->GetSelectEntry() );
295 aEntry
.EraseLeadingChars( ' ' );
296 USHORT nPos
= aEntry
.Search( '/' );
297 aEntry
.Erase( nPos
);
299 // build the absolute path to the selected item
303 USHORT nCurPos
= pDirList
->GetSelectEntryPos();
305 // Wird nach oben gewechselt
306 if( nCurPos
< nDirCount
)
307 aNewPath
= aNewPath
[nDirCount
-nCurPos
-1];
311 pEdit
->SetText( aNewPath
.GetFull() );
318 IMPL_LINK( ImpPathDialog
, ClickHdl
, Button
*, pBtn
)
320 if ( pBtn
== pOkBtn
|| pBtn
== pLoadBtn
)
322 DirEntry
aFile( pEdit
->GetText() );
324 // Existiert File / File ueberschreiben
325 if( IsFileOk( aFile
) )
327 // Ja, dann kompletten Pfad mit Filenamen merken und Dialog beenden
330 GetPathDialog()->EndDialog( TRUE
);
334 DirEntry
aCheck( aPath
);
336 if( aCheck
.Exists() )
339 SetPath( aCheck
.GetFull() );
340 pEdit
->SetSelection( Selection( 0x7FFFFFFF, 0x7FFFFFFF ) );
345 if ( pBtn
== pCancelBtn
)
347 GetPathDialog()->EndDialog( FALSE
);
350 if ( pBtn
== pHomeBtn
)
352 ::rtl::OUString aHomeDir
;
353 NAMESPACE_VOS( OSecurity
) aSecurity
;
354 if ( aSecurity
.getHomeDir( aHomeDir
) )
356 DirEntry
aFile ( aHomeDir
);
357 if ( IsFileOk( aFile
) )
360 SetPath( aFile
.GetFull() );
365 if ( pBtn
== pNewDirBtn
)
367 DirEntry
aFile( pEdit
->GetText() );
368 if( ! aFile
.Exists() && ! FileStat( aFile
).IsKind( FSYS_KIND_WILD
) )
371 if( IsFileOk ( aFile
) )
374 SetPath( aFile
.GetFull() );
382 IMPL_LINK( ImpPathDialog
, DblClickHdl
, ListBox
*, pBox
)
384 // isolate the pure name of the entry
385 // removing trainling stuff and leading spaces
386 UniString
aEntry( pBox
->GetSelectEntry() );
388 aEntry
.EraseLeadingChars( ' ' );
389 USHORT nPos
= aEntry
.Search( '/' );
390 aEntry
.Erase( nPos
);
392 // build the absolute path to the selected item
395 if( pBox
== pDirList
)
397 USHORT nCurPos
= pDirList
->GetSelectEntryPos();
399 // Wenn es schon das aktuelle ist, dann mache nichts
400 if( nCurPos
== nDirCount
-1 )
403 // Wird nach oben gewechselt
404 if( nCurPos
< nDirCount
)
405 aNewPath
= aNewPath
[nDirCount
-nCurPos
-1];
412 pSvPathDialog
->EnterWait();
414 if( FileStat( aNewPath
).GetKind() & FSYS_KIND_DIR
)
416 // Neuen Pfad setzen und Listboxen updaten
418 if( !aPath
.SetCWD( TRUE
) )
420 ErrorBox
aBox( GetPathDialog(),
421 WB_OK_CANCEL
| WB_DEF_OK
,
422 UniString( SvtResId( STR_FILEDLG_CANTCHDIR
) ) );
423 if( aBox
.Execute() == RET_CANCEL
)
424 GetPathDialog()->EndDialog( FALSE
);
426 UpdateEntries( TRUE
);
429 pSvPathDialog
->LeaveWait();
433 void ImpPathDialog::UpdateEntries( const BOOL
)
435 UniString aTabString
;
439 nDirCount
= aTmpPath
.Level();
441 pDirList
->SetUpdateMode( FALSE
);
444 for( USHORT i
= nDirCount
; i
> 0; i
-- )
446 UniString
aName( aTabString
);
447 aName
+= aTmpPath
[i
-1].GetName();
448 pDirList
->InsertEntry( aName
);
449 aTabString
.AppendAscii( " ", 2 );
452 // scan the directory
456 Dir
aDir( aCurrent
, FSYS_KIND_DIR
|FSYS_KIND_FILE
);
458 USHORT nEntries
= aDir
.Count();
461 UniStringList aSortDirList
;
462 for ( USHORT n
= 0; n
< nEntries
; n
++ )
464 DirEntry
& rEntry
= aDir
[n
];
465 UniString
aName( rEntry
.GetName() );
466 if( aName
.Len() && ( aName
.GetChar(0) != '.' ) && rEntry
.Exists() )
468 if( FileStat( rEntry
).GetKind() & FSYS_KIND_DIR
)
473 for( l
= 0; l
< aSortDirList
.Count(); l
++ )
474 if( xCollator
->compareString( *aSortDirList
.GetObject(l
), aName
) > 0 )
477 aSortDirList
.Insert( new UniString( aName
), l
);
482 for( ULONG l
= 0; l
< aSortDirList
.Count(); l
++ )
484 UniString
aEntryStr( aTabString
);
485 aEntryStr
+= *aSortDirList
.GetObject(l
);
486 pDirList
->InsertEntry( aEntryStr
);
487 delete aSortDirList
.GetObject(l
);
491 UpdateDirs( aTmpPath
);
494 void ImpPathDialog::UpdateDirs( const DirEntry
& rTmpPath
)
496 pDirList
->SelectEntryPos( nDirCount
-1 );
497 pDirList
->SetTopEntry( nDirCount
> 1
500 pDirList
->SetUpdateMode( TRUE
);
501 pDirList
->Invalidate();
504 UniString aDirName
= rTmpPath
.GetFull();
506 pDirPath
->SetText( aDirName
);
508 pEdit
->SetText( aDirName
);
511 BOOL
ImpPathDialog::IsFileOk( const DirEntry
& rDirEntry
)
513 if( FileStat( rDirEntry
).GetKind() & (FSYS_KIND_WILD
| FSYS_KIND_DEV
) )
518 if( ! rDirEntry
.Exists() )
520 UniString
aQueryTxt( SvtResId( STR_FILEDLG_ASKNEWDIR
) );
521 aQueryTxt
.SearchAndReplaceAscii( "%s", rDirEntry
.GetFull() );
522 QueryBox
aQuery( GetPathDialog(),
523 WB_YES_NO
| WB_DEF_YES
,
525 if( aQuery
.Execute() == RET_YES
)
530 if( !FileStat( rDirEntry
).IsKind( FSYS_KIND_DIR
) )
532 UniString
aBoxText( SvtResId( STR_FILEDLG_CANTOPENDIR
) );
533 aBoxText
.AppendAscii( "\n[" );
534 aBoxText
+= rDirEntry
.GetFull();
535 aBoxText
.AppendAscii( "]" );
536 InfoBox
aBox( GetPathDialog(), aBoxText
);
541 return GetPathDialog()->OK() != 0;
545 void ImpPathDialog::PreExecute()
547 // Neues Verzeichnis setzen und Listboxen updaten
548 aPath
.SetCWD( TRUE
);
549 UpdateEntries( TRUE
);
551 // Zusaetzliche Buttons anordnen
557 aPos
= pLoadBtn
->GetPosPixel();
558 aSize
= pLoadBtn
->GetSizePixel();
559 nDY
= pLoadBtn
->GetSizePixel().Height() * 2;
563 aPos
= pCancelBtn
->GetPosPixel();
564 aSize
= pCancelBtn
->GetSizePixel();
565 nDY
= pCancelBtn
->GetPosPixel().Y() - pOkBtn
->GetPosPixel().Y();
568 // Standard-Controls anpassen
571 // Maximale Breite ermitteln
572 USHORT nChilds
= GetPathDialog()->GetChildCount();
574 for ( n
= nOwnChilds
; n
< nChilds
; n
++ )
576 Window
* pChild
= GetPathDialog()->GetChild( n
);
577 pChild
= pChild
->GetWindow( WINDOW_CLIENT
);
578 if( pChild
->GetType() != WINDOW_WINDOW
)
580 long nWidth
= pChild
->GetTextWidth( pChild
->GetText() ) + 12;
581 if( nMaxWidth
< nWidth
)
583 nWidth
= pChild
->GetSizePixel().Width();
584 if( nMaxWidth
< nWidth
)
589 if( nMaxWidth
> aSize
.Width() )
591 Size aDlgSize
= GetPathDialog()->GetOutputSizePixel();
592 GetPathDialog()->SetOutputSizePixel( Size( aDlgSize
.Width()+nMaxWidth
-aSize
.Width(), aDlgSize
.Height() ) );
593 aSize
.Width() = nMaxWidth
;
596 pOkBtn
->SetSizePixel( aSize
);
598 pCancelBtn
->SetSizePixel( aSize
);
600 pLoadBtn
->SetSizePixel( aSize
);
603 nMaxWidth
= aSize
.Width();
605 for ( n
= nOwnChilds
; n
< nChilds
; n
++ )
607 Window
* pChild
= GetPathDialog()->GetChild( n
);
608 pChild
= pChild
->GetWindow( WINDOW_CLIENT
);
609 if( pChild
->GetType() != WINDOW_WINDOW
)
612 pChild
->SetPosSizePixel( aPos
, aSize
);
616 Size aDlgSize
= GetPathDialog()->GetOutputSizePixel();
617 long nExtra
= Min( aDlgSize
.Height(), (long)160);
618 GetPathDialog()->SetOutputSizePixel( Size( aDlgSize
.Width()+nExtra
, aDlgSize
.Height() ) );
619 Size
aSz( nExtra
, nExtra
);
622 Point
aCtrlPos( aDlgSize
.Width() + 2, (aDlgSize
.Height()-aSz
.Height())/2 );
623 pChild
->SetPosSizePixel( aCtrlPos
, aSz
);
627 // Laufwerke-LB fuellen
630 DirEntry aTmpDirEntry
;
631 Dir
aDir( aTmpDirEntry
, FSYS_KIND_BLOCK
);
633 USHORT nCount
= aDir
.Count(), i
;
634 for( i
= 0; i
< nCount
; ++i
)
636 DirEntry
& rEntry
= aDir
[i
];
637 UniString aStr
= rEntry
.GetFull( FSYS_STYLE_HOST
, FALSE
);
639 UniString aVolume
= rEntry
.GetVolume() ;
646 pDriveList
->InsertEntry( aStr
);
649 UniString aPathStr
= aPath
.GetFull();
651 for ( i
= 0; i
< pDriveList
->GetEntryCount(); ++i
)
653 UniString aEntry
= pDriveList
->GetEntry(i
);
654 xub_StrLen nLen
= aEntry
.Len();
655 nLen
= nLen
> 2 ? 2 : nLen
;
656 if ( aEntry
.CompareIgnoreCaseToAscii( aPathStr
, nLen
) == COMPARE_EQUAL
)
658 pDriveList
->SelectEntryPos(i
);
665 void ImpPathDialog::PostExecute()
669 void ImpPathDialog::SetPath( UniString
const & rPath
)
671 aPath
= DirEntry( rPath
);
673 pSvPathDialog
->EnterWait();
675 DirEntry
aFile( rPath
);
676 // Falls der Pfad eine Wildcard oder einen Filenamen enthaelt
677 // -> abschneiden und merken
678 if( FileStat( aFile
).GetKind() & (FSYS_KIND_FILE
| FSYS_KIND_WILD
) || !aFile
.Exists() )
681 // Neue Maske und neues Verzeichnis setzen, und Listboxen updaten
682 pEdit
->SetText( rPath
);
683 aFile
.SetCWD( TRUE
);
684 UpdateEntries( TRUE
);
686 pSvPathDialog
->LeaveWait();
689 void ImpPathDialog::SetPath( Edit
const & rEdit
)
691 UniString aPresetText
= rEdit
.GetText();
692 if( aPresetText
.Len() )
693 SetPath( aPresetText
);
697 UniString
ImpPathDialog::GetPath() const
699 DirEntry
aFile( pEdit
->GetText() );
701 return aFile
.GetFull();
705 ImpFileDialog::ImpFileDialog( PathDialog
* pDlg
, WinBits nWinBits
, RESOURCE_TYPE nType
) :
706 ImpPathDialog( pDlg
, nType
, FALSE
)
708 bOpen
= (nWinBits
& WB_SAVEAS
) == 0;
710 SvtResId aSvtResId
= bOpen
? STR_FILEDLG_OPEN
: STR_FILEDLG_SAVE
;
713 GetFileDialog()->SetText( UniString( aSvtResId
) );
716 // initialize Controls if not used as a base class
717 if ( nType
== WINDOW_FILEDIALOG
)
720 pDlg
->SetHelpId( HID_FILEDLG_OPENDLG
);
724 ImpFileDialog::~ImpFileDialog()
726 ImpFilterItem
* pItem
= aFilterList
.First();
730 pItem
= aFilterList
.Next();
734 if (pFileList
&& ( pFileList
!= pDirList
) )
741 void ImpFileDialog::InitControls()
746 const int nH
= 48; // Um den Dialog in eine akzeptable Form zu bringen
748 INITCONTROL( pFileTitel
, FixedText
, 0,
749 Point(10, 12), Size(nW
, 18), UniString( SvtResId( STR_FILEDLG_FILE
) ), HID_FILEDLG_FILE
);
750 INITCONTROL( pEdit
, Edit
, WB_BORDER
,
751 Point(10, 31), Size(nW
, 20), aEmptyStr
, HID_FILEDLG_EDIT
); // aMask()
752 INITCONTROL( pFileList
, ListBox
, WB_SORT
| WB_AUTOHSCROLL
| WB_BORDER
,
753 Point(10, 58), Size(nW
, 180-nH
), aEmptyStr
, HID_FILEDLG_FILES
);
755 INITCONTROL( pDirTitel
, FixedText
, 0,
756 Point(nW
+20, 12), Size(nW
, 18), UniString( SvtResId( STR_FILEDLG_DIR
) ), HID_FILEDLG_DIR
);
757 INITCONTROL( pDirPath
, FixedInfo
, WB_PATHELLIPSIS
,
758 Point(nW
+20, 33), Size(nW
, 20), aPath
.GetFull(), HID_FILEDLG_PATH
);
759 INITCONTROL( pDirList
, KbdListBox
, WB_AUTOHSCROLL
| WB_BORDER
,
760 Point(nW
+20, 58), Size(nW
, 180-nH
), aEmptyStr
, HID_FILEDLG_DIRS
);
762 INITCONTROL( pTypeTitel
, FixedText
, 0,
763 Point(10, 246-nH
), Size(nW
, 18), UniString( SvtResId( STR_FILEDLG_TYPE
) ), HID_FILEDLG_TYPE
);
766 INITCONTROL( pTypeList
, ListBox
, WB_DROPDOWN
,
767 Point(10, 265-nH
), Size(nW
, 100 ), aEmptyStr
, HID_FILEDLG_TYPES
);
769 INITCONTROL( pDriveTitle
, FixedText
, 0,
770 Point(nW
+20, 246-nH
), Size(nW
, 18), UniString( SvtResId( STR_FILEDLG_DRIVES
) ), HID_FILEDLG_DRIVE
);
771 INITCONTROL( pDriveList
, ListBox
, WB_DROPDOWN
,
772 Point(nW
+20, 265-nH
), Size(nW
, 100 ), aEmptyStr
, HID_FILEDLG_DRIVES
);
776 INITCONTROL( pTypeList
, ListBox
, WB_DROPDOWN
,
777 Point(10, 265-nH
), Size(2*nW
+20, 100 ), aEmptyStr
, HID_FILEDLG_TYPES
);
785 const long nButtonStartX
= 2*nW
+20+15;
786 INITCONTROL( pOkBtn
, PushButton
, WB_DEFBUTTON
,
787 Point(nButtonStartX
, 10), Size(STD_BTN_WIDTH
, STD_BTN_HEIGHT
),
788 Button::GetStandardText( BUTTON_OK
), 0 );
789 INITCONTROL( pCancelBtn
, CancelButton
, 0,
790 Point(nButtonStartX
, 45 ), Size(STD_BTN_WIDTH
, STD_BTN_HEIGHT
),
791 Button::GetStandardText( BUTTON_CANCEL
), 0 );
795 GetFileDialog()->SetOutputSizePixel( Size(nButtonStartX
+STD_BTN_WIDTH
+10, 298-nH
) );
797 nOwnChilds
= GetPathDialog()->GetChildCount();
801 pDriveList
->SetSelectHdl( LINK( this, ImpFileDialog
, SelectHdl
) );
804 pDirList
->SetDoubleClickHdl(LINK( this, ImpFileDialog
, DblClickHdl
) );
807 pOkBtn
->SetClickHdl( LINK( this, ImpFileDialog
, ClickHdl
) );
810 pCancelBtn
->SetClickHdl( LINK( this, ImpFileDialog
, ClickHdl
) );
814 pFileList
->SetSelectHdl( LINK( this, ImpFileDialog
, SelectHdl
) );
815 pFileList
->SetDoubleClickHdl( LINK( this, ImpFileDialog
, DblClickHdl
) );
819 pTypeList
->SetSelectHdl( LINK( this, ImpFileDialog
, DblClickHdl
) );
822 IMPL_LINK( ImpFileDialog
, SelectHdl
, ListBox
*, p
)
824 if( p
== pDriveList
)
826 UniString
aDrive ( pDriveList
->GetSelectEntry(), 0, 2);
830 else if (p
== pFileList
)
832 // Ausgewaehltes File in das Edit stellen
833 pEdit
->SetText( pFileList
->GetSelectEntry() );
834 GetFileDialog()->FileSelect();
840 IMPL_LINK( ImpFileDialog
, DblClickHdl
, ListBox
*, pBox
)
842 // isolate the pure name of the entry
843 // removing trailing stuff and leading spaces
844 UniString
aEntry( pBox
->GetSelectEntry() );
846 aEntry
.EraseLeadingChars( ' ' );
847 USHORT nPos
= aEntry
.Search( '/' );
848 aEntry
.Erase( nPos
);
850 // build the absolute path to the selected item
854 if( ( pDirList
!= pFileList
) && ( pBox
== pDirList
) )
857 USHORT nCurPos
= pDirList
->GetSelectEntryPos();
859 // Wenn es schon das aktuelle ist, dann mache nichts
860 if( nCurPos
== nDirCount
-1 )
863 // Wird nach oben gewechselt
864 if( nCurPos
< nDirCount
)
865 aNewPath
= aNewPath
[nDirCount
-nCurPos
-1];
872 if( aEntry
== UniString( SvtResId( STR_FILEDLG_GOUP
) ) )
873 aEntry
.AssignAscii( ".." );
877 if( pBox
== pFileList
)
879 DirEntry
aFile( aEntry
);
881 // Abfrage, ob File ueberschrieben werden soll...
882 if( !FileStat(aFile
).IsKind(FSYS_KIND_DIR
) && IsFileOk( aFile
) )
884 // dann kompletten Pfad mit Filenamen merken und Dialog beenden
886 GetFileDialog()->EndDialog( TRUE
);
890 GetFileDialog()->EnterWait();
892 UniString aFull
= aNewPath
.GetFull();
894 if( ( ( pBox
== pDirList
) && ( pDirList
!= pFileList
) ) ||
895 ( ( pDirList
== pFileList
) && FileStat( aNewPath
).GetKind() & FSYS_KIND_DIR
) )
897 // Neuen Pfad setzen und Listboxen updaten
899 if( !aPath
.SetCWD( TRUE
) )
901 if( ErrorBox( GetFileDialog(), WB_OK_CANCEL
|WB_DEF_OK
,
902 UniString( SvtResId( STR_FILEDLG_CANTCHDIR
) ) ).Execute() == RET_CANCEL
)
904 GetFileDialog()->EndDialog( FALSE
);
907 UpdateEntries( TRUE
);
908 GetFileDialog()->FileSelect();
911 if( pBox
== pTypeList
)
913 // Neue Maske setzen, und Listboxen updaten
914 USHORT nCurPos
= pTypeList
->GetSelectEntryPos();
915 if( nCurPos
+1 > (USHORT
)aFilterList
.Count() )
916 aMask
= UniString::CreateFromAscii( ALLFILES
);
919 UniString aFilterListMask
= aFilterList
.GetObject( nCurPos
)->aMask
;
920 // if( aFilterListMask.Search( ';' ) == STRING_NOTFOUND ) // kein ; in der Maske
921 // aMask = WildCard( aFilterListMask, '\0' );
922 // else // ; muss beruecksichtigt werden
923 aMask
= WildCard( aFilterListMask
, ';' );
926 pEdit
->SetText( aMask() );
927 UpdateEntries( FALSE
);
928 GetFileDialog()->FilterSelect();
931 GetFileDialog()->LeaveWait();
936 IMPL_LINK( ImpFileDialog
, ClickHdl
, Button
*, pBtn
)
938 if( ( pBtn
== pOkBtn
) || ( pBtn
== pLoadBtn
) )
940 DirEntry
aFile( pEdit
->GetText() );
942 // Existiert File / File ueberschreiben
943 if( IsFileOk( aFile
) )
945 // Ja, dann kompletten Pfad mit Filenamen merken und Dialog beenden
948 GetFileDialog()->EndDialog( TRUE
);
952 GetFileDialog()->EnterWait();
954 // Falls der Pfad eine Wildcard oder einen Filenamen enthaelt
955 // -> abschneiden und merken
956 if( FileStat( aFile
).GetKind() & (FSYS_KIND_FILE
| FSYS_KIND_WILD
) || !aFile
.Exists() )
958 aMask
= aFile
.CutName();
961 // Neue Maske und neues Verzeichnis setzen, und Listboxen updaten
962 pEdit
->SetText( aMask() );
963 aFile
.SetCWD( TRUE
);
964 UpdateEntries( TRUE
);
966 GetFileDialog()->LeaveWait();
969 else if( pBtn
== pCancelBtn
)
970 GetFileDialog()->EndDialog( FALSE
);
975 void ImpFileDialog::UpdateEntries( const BOOL bWithDirs
)
977 GetFileDialog()->EnterWait();
979 UniString aTabString
;
982 nDirCount
= aTmpPath
.Level();
986 pFileList
->SetUpdateMode( FALSE
);
990 if( bWithDirs
&& (pDirList
!= pFileList
) )
992 pDirList
->SetUpdateMode( FALSE
);
995 for( USHORT i
= nDirCount
; i
> 0; i
-- )
997 UniString
aEntryStr( aTabString
);
998 aEntryStr
+= aTmpPath
[i
-1].GetName();
999 pDirList
->InsertEntry( aEntryStr
);
1000 aTabString
.AppendAscii( " ", 2 );
1004 // for the combined box insert a '..'
1005 // (this happens only if WB_3DLOOK is not set)
1007 if( pDirList
== pFileList
&& nDirCount
!= 1 )
1008 pFileList
->InsertEntry( UniString( SvtResId( STR_FILEDLG_GOUP
) ) );
1010 // scan the directory
1013 Dir
aDir( aCurrent
, FSYS_KIND_DIR
|FSYS_KIND_FILE
);
1014 USHORT nEntries
= aDir
.Count();
1016 // TempMask, weil Vergleich case-sensitiv
1017 BOOL bMatchCase
= FALSE
; //aCurrent.IsCaseSensitive();
1018 UniString
aWildCard( aMask
.GetWildCard() );
1020 aWildCard
.ToLowerAscii();
1021 WildCard
aTmpMask( aWildCard
, ';' );
1024 UniStringList aSortDirList
;
1025 for ( USHORT n
= 0; n
< nEntries
; n
++ )
1027 DirEntry
& rEntry
= aDir
[n
];
1028 UniString
aName( rEntry
.GetName() );
1031 ( ( ( aName
.GetChar(0) != '.' ) ||
1032 ( ( aName
.GetChar(0) == '.' ) && ( aMask
.GetWildCard() ).GetChar(0) == '.' ) )
1033 && rEntry
.Exists() ) )
1035 FileStat
aFileStat( rEntry
);
1036 UniString
aTmpName( aName
);
1038 aTmpName
.ToLowerAscii();
1039 if( ( aFileStat
.GetKind() & FSYS_KIND_FILE
) && aTmpMask
.Matches( aTmpName
) )
1042 pFileList
->InsertEntry( aName
);
1044 else if( bWithDirs
&& ( aFileStat
.GetKind() & FSYS_KIND_DIR
) )
1046 if( pDirList
== pFileList
)
1048 UniString
aEntryStr( aName
);
1050 pDirList
->InsertEntry( aEntryStr
);
1055 if( xCollator
.is() )
1057 for( l
= 0; l
< aSortDirList
.Count(); l
++ )
1058 if( xCollator
->compareString( *aSortDirList
.GetObject(l
), aName
) > 0 )
1061 aSortDirList
.Insert( new UniString( aName
), l
);
1066 for( ULONG l
= 0; l
< aSortDirList
.Count(); l
++ )
1068 UniString
aEntryStr( aTabString
);
1069 aEntryStr
+= *aSortDirList
.GetObject(l
);
1070 pDirList
->InsertEntry( aEntryStr
);
1071 delete aSortDirList
.GetObject(l
);
1076 UpdateDirs( aTmpPath
);
1080 if ( pDirList
== pFileList
&& nDirCount
> 1 )
1081 pFileList
->SelectEntryPos( 1 );
1083 pFileList
->SetNoSelection();
1084 pFileList
->SetUpdateMode( TRUE
);
1085 pFileList
->Invalidate();
1086 pFileList
->Update();
1091 if( pDirList
->GetEntryCount() > 0 )
1093 UniString
aStr( pDirList
->GetEntry( 0 ) );
1095 aStr
.ToLowerAscii();
1096 pDriveList
->SelectEntry( aStr
);
1100 GetFileDialog()->LeaveWait();
1103 BOOL
ImpFileDialog::IsFileOk( const DirEntry
& rDirEntry
)
1105 if( FileStat( rDirEntry
).GetKind() & (FSYS_KIND_WILD
| FSYS_KIND_DEV
) )
1107 if( FileStat( rDirEntry
).GetKind() & FSYS_KIND_DIR
)
1114 // Datei vorhanden ?
1115 if( !FileStat( rDirEntry
).IsKind( FSYS_KIND_FILE
) )
1117 UniString
aErrorString( SvtResId( STR_FILEDLG_CANTOPENFILE
) );
1118 aErrorString
.AppendAscii( "\n[" );
1119 aErrorString
+= rDirEntry
.GetFull();
1120 aErrorString
+= ']';
1121 InfoBox
aBox( GetFileDialog(),
1129 // Datei vorhanden ?
1130 if( FileStat( ExtendFileName( rDirEntry
) ).IsKind( FSYS_KIND_FILE
) )
1132 UniString
aQueryString( SvtResId( STR_FILEDLG_OVERWRITE
) );
1133 aQueryString
.AppendAscii( "\n[" );
1134 aQueryString
+= rDirEntry
.GetFull();
1135 aQueryString
+= ']';
1136 QueryBox
aBox( GetFileDialog(),
1137 WinBits( WB_YES_NO
| WB_DEF_NO
),
1139 if( aBox
.Execute() != RET_YES
)
1143 return GetFileDialog()->OK() != 0;
1146 void ImpFileDialog::SetPath( UniString
const & rPath
)
1148 aPath
= DirEntry( rPath
);
1149 GetFileDialog()->EnterWait();
1151 DirEntry
aFile( rPath
);
1153 // Falls der Pfad eine Wildcard oder einen Filenamen enthaelt
1154 // -> abschneiden und merken
1155 if( FileStat( aFile
).GetKind() & (FSYS_KIND_FILE
| FSYS_KIND_WILD
) || !aFile
.Exists() )
1157 aMask
= aFile
.CutName();
1159 // Neue Maske und neues Verzeichnis setzen, und Listboxen updaten
1162 UniString
aWildCard( aMask
.GetWildCard() );
1163 pEdit
->SetText( aWildCard
);
1166 pEdit
->SetText( rPath
);
1169 aFile
.SetCWD( TRUE
);
1171 UpdateEntries( TRUE
);
1173 GetFileDialog()->LeaveWait();
1176 void ImpFileDialog::SetPath( Edit
const& rEdit
)
1178 UniString aPresetText
= rEdit
.GetText();
1179 if( aPresetText
.Len() )
1180 SetPath( aPresetText
);
1184 void ImpFileDialog::AddFilter( const UniString
& rFilter
, const UniString
& rMask
)
1186 aFilterList
.Insert( new ImpFilterItem( rFilter
, rMask
), LIST_APPEND
);
1188 pTypeList
->InsertEntry( rFilter
, LISTBOX_APPEND
);
1190 if( !GetCurFilter().Len() )
1191 SetCurFilter( rFilter
);
1194 void ImpFileDialog::RemoveFilter( const UniString
& rFilter
)
1196 ImpFilterItem
* pItem
= aFilterList
.First();
1197 while( pItem
&& pItem
->aName
!= rFilter
)
1198 pItem
= aFilterList
.Next();
1202 delete aFilterList
.Remove();
1204 pTypeList
->RemoveEntry( rFilter
);
1208 void ImpFileDialog::RemoveAllFilter()
1210 ImpFilterItem
* pItem
= aFilterList
.First();
1214 pItem
= aFilterList
.Next();
1216 aFilterList
.Clear();
1222 void ImpFileDialog::SetCurFilter( const UniString
& rFilter
)
1227 ImpFilterItem
* pItem
= aFilterList
.First();
1228 while( pItem
&& pItem
->aName
!= rFilter
)
1229 pItem
= aFilterList
.Next();
1232 pTypeList
->SelectEntryPos( (USHORT
)aFilterList
.GetCurPos() );
1234 pTypeList
->SetNoSelection();
1237 UniString
ImpFileDialog::GetCurFilter() const
1241 aFilter
= pTypeList
->GetSelectEntry();
1245 void ImpFileDialog::PreExecute()
1247 // ListBoxen erst unmittelbar vor Execute fuellen
1248 // (damit vor Execute der Pfad umgesetzt werden kann, ohne das immer die
1249 // Listboxen sofort upgedatet werden)
1251 GetFileDialog()->EnterWait();
1253 // Wenn kein Filter vorhanden, dann auch keine FilterBox
1254 if( pTypeList
&& !pTypeList
->GetEntryCount() )
1256 // pTypeList->InsertEntry( "* (all files)" );
1257 pTypeTitel
->Disable();
1258 pTypeList
->Disable();
1263 USHORT nCurType
= pTypeList
->GetSelectEntryPos();
1264 if( nCurType
< aFilterList
.Count() )
1266 UniString aFilterListMask
= aFilterList
.GetObject( nCurType
)->aMask
;
1267 if( aFilterListMask
.Search( ';' ) == STRING_NOTFOUND
) // kein ; in der Maske
1268 aMask
= WildCard( aFilterListMask
, '\0' );
1269 else // ; in der Maske, muss in der Wildcard beruecksichtigt werden
1270 aMask
= WildCard( aFilterListMask
, ';' );
1273 aMask
= UniString::CreateFromAscii( ALLFILES
);
1276 aMask
= UniString::CreateFromAscii( ALLFILES
);
1278 // Neue Maske setzen
1279 if( pEdit
->GetText().Len() == 0 )
1280 pEdit
->SetText( aMask() );
1282 ImpPathDialog::PreExecute();
1284 GetFileDialog()->LeaveWait();
1287 UniString
ImpFileDialog::GetPath() const
1289 DirEntry
aFile( pEdit
->GetText() );
1290 return ExtendFileName( aFile
);
1293 UniString
ImpFileDialog::ExtendFileName( DirEntry aEntry
) const
1296 // das ganze Theater hier ohnehin nur machen, wenn Dateiname
1297 // ohne Extension angegeben wurde
1298 if( !aEntry
.GetExtension().Len() )
1300 UniString aPostfix
; // hier kommt die ausgesuchte Extension herein
1302 // ist ein Filter mit Extension gesetzt?
1303 USHORT nChosenFilterPos
= pTypeList
->GetSelectEntryPos();
1304 if( nChosenFilterPos
!= LISTBOX_ENTRY_NOTFOUND
)
1306 UniString aExtensionMask
= GetFileDialog()->GetFilterType( nChosenFilterPos
);
1307 // aExtension ist z.B. *.sdw, alles bis einschliesslich Punkt abschneiden
1308 UniString aExtension
= aExtensionMask
.Copy( aExtensionMask
.Search( '.' )+1 );
1310 // hat der Filter ueberhaupt eine Extension
1311 if( aExtension
.Len() )
1313 // keine Wildcards enthalten?
1314 if( ( aExtension
.Search( '*' ) == STRING_NOTFOUND
) &&
1315 ( aExtension
.Search( '?' ) == STRING_NOTFOUND
) )
1317 // OK, Filter hat Extension ohne Wildcards -> verwenden
1318 aPostfix
= aExtension
;
1322 // Filter hat Extension mit Wildcards (z.B. *.*) -> nicht verwenden
1328 // Filter hatte keine Extension (schwer vorstellbar) -> nichts anhaengen
1334 // kein Filter gefunden (merkw�rdig) -> Default-Extension anhaengen
1335 aPostfix
= GetFileDialog()->GetDefaultExt();
1338 // jetzt kann es mit dem Anhaengen losgehen
1339 const sal_Unicode
* pExt
= aPostfix
.GetBuffer();
1340 while( *pExt
== '*' || *pExt
== '?' )
1345 UniString aName
= aEntry
.GetName();
1349 aEntry
.SetName( aName
);
1352 return aEntry
.GetFull();
1356 void ImpSvFileDlg::CreateDialog( PathDialog
* pSvDlg
, WinBits nStyle
, RESOURCE_TYPE nType
, BOOL bCreate
)
1359 if ( nType
== WINDOW_PATHDIALOG
)
1360 pDlg
= new ImpPathDialog( pSvDlg
, nType
, bCreate
);
1362 pDlg
= new ImpFileDialog( pSvDlg
, nStyle
, nType
);