diff options
Diffstat (limited to 'svtools/source/dialogs/filedlg2.cxx')
-rw-r--r-- | svtools/source/dialogs/filedlg2.cxx | 1356 |
1 files changed, 1356 insertions, 0 deletions
diff --git a/svtools/source/dialogs/filedlg2.cxx b/svtools/source/dialogs/filedlg2.cxx new file mode 100644 index 000000000000..a6ccff12a506 --- /dev/null +++ b/svtools/source/dialogs/filedlg2.cxx @@ -0,0 +1,1356 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svtools.hxx" +#include <vcl/svapp.hxx> +#include <vcl/button.hxx> +#include <vcl/fixed.hxx> +#include <vcl/edit.hxx> +#include <vcl/lstbox.hxx> +#include <svtools/svtdata.hxx> +#include <filedlg2.hxx> +#include <svtools/filedlg.hxx> +#include <svtools/filedlg2.hrc> +#include <vcl/msgbox.hxx> +#include <osl/security.hxx> +#include <comphelper/string.hxx> + +#include <svtools/stdctrl.hxx> + +#ifdef _MSC_VER +#pragma optimize ("", off) +#endif + +#include <svtools/helpid.hrc> + +using namespace com::sun::star; +using namespace com::sun::star::uno; + +typedef ::std::vector< UniString* > UniStringList; + +#define STD_BTN_WIDTH 80 +#define STD_BTN_HEIGHT 26 + +#ifndef UNX + #define ALLFILES "*.*" +#else + #define ALLFILES "*" +#endif +// #define STD_BTN_WIDTH 90 +// #define STD_BTN_HEIGHT 35 + +#define INITCONTROL( p, ControlClass, nBits, aPos, aSize, aTitel, rHelpId ) \ + p = new ControlClass( GetPathDialog(), WinBits( nBits ) ); \ + p->SetHelpId( rHelpId ); \ + p->SetPosSizePixel( aPos, aSize ); \ + p->SetText( aTitel ); \ + p->Show(); + + +inline sal_Bool IsPrintable( sal_Unicode c ) +{ + return c >= 32 && c != 127 ? sal_True : sal_False; +} + +long +KbdListBox::PreNotify( NotifyEvent& rNEvt ) +{ + if ( rNEvt.GetType() == EVENT_KEYINPUT ) + { + KeyEvent aKeyEvt = *rNEvt.GetKeyEvent(); + sal_Unicode cCharCode = aKeyEvt.GetCharCode(); + + if ( IsPrintable ( cCharCode ) ) + { + sal_uInt16 nCurrentPos = GetSelectEntryPos(); + sal_uInt16 nEntries = GetEntryCount(); + + for ( sal_uInt16 i = 1; i < nEntries; i++ ) + { + UniString aEntry = GetEntry ( (i + nCurrentPos) % nEntries ); + aEntry.EraseLeadingChars( ' ' ); + aEntry.ToUpperAscii(); + UniString aCompare( cCharCode ); + aCompare.ToUpperAscii(); + + if ( aEntry.CompareTo( aCompare, 1 ) == COMPARE_EQUAL ) + { + SelectEntryPos ( (i + nCurrentPos) % nEntries ); + break; + } + } + } + else + if ( aKeyEvt.GetKeyCode().GetCode() == KEY_RETURN ) + { + DoubleClick(); + } + } + + return ListBox::PreNotify ( rNEvt ); +} + +ImpPathDialog::ImpPathDialog( PathDialog* pDlg, RESOURCE_TYPE nType, sal_Bool bCreateDir ) +{ + pSvPathDialog = pDlg; + nDirCount = 0; + + // initialize Controls if not used as a base class + if ( nType == WINDOW_PATHDIALOG ) + { + InitControls(); + if( pNewDirBtn ) + pNewDirBtn->Enable( bCreateDir ); + } + + pDlg->SetHelpId( HID_FILEDLG_PATHDLG ); +} + +ImpPathDialog::~ImpPathDialog() +{ + delete pEdit; + delete pDirTitel; + delete pDirList; + delete pDirPath; + delete pDriveList; + delete pDriveTitle; + delete pLoadBtn; + delete pOkBtn; + delete pCancelBtn; + delete pNewDirBtn; +# if defined(UNX) || defined(OS2) + delete pHomeBtn; +# endif +} + +void ImpPathDialog::InitControls() +{ + PathDialog* pDlg = GetPathDialog(); + pDlg->SetText( UniString( SvtResId( STR_FILEDLG_SELECT ) ) ); + + Size a3Siz = pDlg->LogicToPixel( Size( 3, 3 ), MAP_APPFONT ); + Size a6Siz = pDlg->LogicToPixel( Size( 6, 6 ), MAP_APPFONT ); + Size aBtnSiz = pDlg->LogicToPixel( Size( 50, 14 ), MAP_APPFONT ); + Size aFTSiz = pDlg->LogicToPixel( Size( 142, 10 ), MAP_APPFONT ); + Size aEDSiz = pDlg->LogicToPixel( Size( 142, 12 ), MAP_APPFONT ); + Point aPnt( a6Siz.Width(), a6Siz.Height() ); + long nLbH1 = pDlg->LogicToPixel( Size( 0, 93 ), MAP_APPFONT ).Height(); + long nH = 0; + UniString aEmptyStr; + + INITCONTROL( pDirTitel, FixedText, 0, + aPnt, aFTSiz, UniString( SvtResId( STR_FILEDLG_DIR ) ), HID_FILEDLG_DIR ); + aPnt.Y() += aFTSiz.Height() + a3Siz.Height(); + + INITCONTROL( pEdit, Edit, WB_BORDER, aPnt, aEDSiz, aPath.GetFull(), HID_FILEDLG_EDIT ); + + aPnt.Y() += aEDSiz.Height() + a3Siz.Height(); +#ifndef UNX + long nLbH2 = pDlg->LogicToPixel( Size( 0, 60 ), MAP_APPFONT ).Height(); + INITCONTROL( pDirList, KbdListBox, WB_AUTOHSCROLL | WB_BORDER, + aPnt, Size( aEDSiz.Width(), nLbH1 ), aEmptyStr, HID_FILEDLG_DIRS ); + aPnt.Y() += nLbH1 + a6Siz.Height(); + INITCONTROL( pDriveTitle, FixedText, 0, + aPnt, aFTSiz, UniString( SvtResId( STR_FILEDLG_DRIVES ) ), HID_FILEDLG_DRIVE ); + aPnt.Y() += aFTSiz.Height() + a3Siz.Height(); + INITCONTROL( pDriveList, ListBox, WB_DROPDOWN, + aPnt, Size( aEDSiz.Width(), nLbH2 ), aEmptyStr, HID_FILEDLG_DRIVES ); + nH = aPnt.Y() + aEDSiz.Height() + a6Siz.Height(); +#else + long nNewH = nLbH1 + 3 * a3Siz.Height() + + aFTSiz.Height() + aEDSiz.Height(); + INITCONTROL( pDirList, KbdListBox, WB_AUTOHSCROLL | WB_BORDER, + aPnt, Size( aEDSiz.Width(), nNewH ), aEmptyStr, HID_FILEDLG_DIRS ); + nH = aPnt.Y() + nNewH + a6Siz.Height(); + pDriveTitle = NULL; + pDriveList = NULL; +#endif + + long nExtraWidth = pDlg->GetTextWidth( String( RTL_CONSTASCII_USTRINGPARAM( "(W)" ) ) )+10; + String aOkStr = Button::GetStandardText( BUTTON_OK ); + long nTextWidth = pDlg->GetTextWidth( aOkStr )+nExtraWidth; + if( nTextWidth > aBtnSiz.Width() ) + aBtnSiz.Width() = nTextWidth; + + String aCancelStr = Button::GetStandardText( BUTTON_CANCEL ); + nTextWidth = pDlg->GetTextWidth( aCancelStr )+nExtraWidth; + if( nTextWidth > aBtnSiz.Width() ) + aBtnSiz.Width() = nTextWidth; + + String aNewDirStr( SvtResId( STR_FILEDLG_NEWDIR ) ); + nTextWidth = pDlg->GetTextWidth( aNewDirStr )+nExtraWidth; + if( nTextWidth > aBtnSiz.Width() ) + aBtnSiz.Width() = nTextWidth; +#if defined(UNX) || defined(OS2) + String aHomeDirStr( SvtResId( STR_FILEDLG_HOME ) ); + nTextWidth = pDlg->GetTextWidth( aHomeDirStr )+nExtraWidth; + if( nTextWidth > aBtnSiz.Width() ) + aBtnSiz.Width() = nTextWidth; +#endif + + aPnt.X() = 2 * a6Siz.Width() + aEDSiz.Width(); + aPnt.Y() = a6Siz.Height(); + INITCONTROL( pOkBtn, PushButton, WB_DEFBUTTON, + aPnt, aBtnSiz, aOkStr, "" ); + aPnt.Y() += aBtnSiz.Height() + a3Siz.Height(); + INITCONTROL( pCancelBtn, CancelButton, 0, + aPnt, aBtnSiz, aCancelStr, "" ); + aPnt.Y() += aBtnSiz.Height() + a3Siz.Height(); + INITCONTROL( pNewDirBtn, PushButton, WB_DEFBUTTON, + aPnt, aBtnSiz, aNewDirStr, HID_FILEDLG_NEWDIR ); +#if defined(UNX) || defined(OS2) + aPnt.Y() += aBtnSiz.Height() + a3Siz.Height(); + INITCONTROL( pHomeBtn, PushButton, WB_DEFBUTTON, + aPnt, aBtnSiz, aHomeDirStr, HID_FILEDLG_HOME ); +#else + pHomeBtn = NULL; +#endif + + pDirPath = 0; + pLoadBtn = 0; + // Dialogbreite == OKBtn-Position + OKBtn-Breite + Rand + long nW = aPnt.X() + aBtnSiz.Width() + a6Siz.Width(); + + pDlg->SetOutputSizePixel( Size( nW, nH ) ); // Groesse ggf. auch Resource wird geplaettet? + + if (pDirList) + pDirList->SetDoubleClickHdl(LINK( this, ImpPathDialog, DblClickHdl) ); + + if (pDirList) + pDirList->SetSelectHdl( LINK( this, ImpPathDialog, SelectHdl ) ); + + if (pDriveList) + pDriveList->SetSelectHdl( LINK( this, ImpPathDialog, SelectHdl ) ); + + if (pOkBtn) + pOkBtn->SetClickHdl( LINK( this, ImpPathDialog, ClickHdl) ); + + if (pCancelBtn) + pCancelBtn->SetClickHdl( LINK( this, ImpPathDialog, ClickHdl) ); + + if (pHomeBtn) + pHomeBtn->SetClickHdl( LINK( this, ImpPathDialog, ClickHdl) ); + + if (pNewDirBtn) + pNewDirBtn->SetClickHdl( LINK( this, ImpPathDialog, ClickHdl) ); + + nOwnChilds = pDlg->GetChildCount(); +} + + + +IMPL_LINK( ImpPathDialog, SelectHdl, ListBox *, p ) +{ + if( p == pDriveList ) + { + UniString aDrive( pDriveList->GetSelectEntry(), 0, 2); + aDrive += '\\'; + SetPath( aDrive ); + } + else + if( p == pDirList ) + { + // isolate the pure name of the entry + // removing trainling stuff and leading spaces + UniString aEntry( pDirList->GetSelectEntry() ); + + aEntry.EraseLeadingChars( ' ' ); + sal_uInt16 nPos = aEntry.Search( '/' ); + aEntry.Erase( nPos ); + + // build the absolute path to the selected item + DirEntry aNewPath; + aNewPath.ToAbs(); + + sal_uInt16 nCurPos = pDirList->GetSelectEntryPos(); + + // Wird nach oben gewechselt + if( nCurPos < nDirCount ) + aNewPath = aNewPath[nDirCount-nCurPos-1]; + else + aNewPath += aEntry; + + pEdit->SetText( aNewPath.GetFull() ); + } + + return 0; +} + + +IMPL_LINK( ImpPathDialog, ClickHdl, Button*, pBtn ) +{ + if ( pBtn == pOkBtn || pBtn == pLoadBtn ) + { + DirEntry aFile( pEdit->GetText() ); + + // Existiert File / File ueberschreiben + if( IsFileOk( aFile ) ) + { + // Ja, dann kompletten Pfad mit Filenamen merken und Dialog beenden + aPath = aFile; + aPath.ToAbs(); + GetPathDialog()->EndDialog( sal_True ); + } + else + { + DirEntry aCheck( aPath ); + aCheck += aFile; + if( aCheck.Exists() ) + { + aCheck.ToAbs(); + SetPath( aCheck.GetFull() ); + pEdit->SetSelection( Selection( 0x7FFFFFFF, 0x7FFFFFFF ) ); + } + } + } + else + if ( pBtn == pCancelBtn ) + { + GetPathDialog()->EndDialog( sal_False ); + } + else + if ( pBtn == pHomeBtn ) + { + ::rtl::OUString aHomeDir; + osl::Security aSecurity; + if ( aSecurity.getHomeDir( aHomeDir ) ) + { + DirEntry aFile ( aHomeDir ); + if ( IsFileOk( aFile ) ) + { + aFile.ToAbs(); + SetPath( aFile.GetFull() ); + } + } + } + else + if ( pBtn == pNewDirBtn ) + { + DirEntry aFile( pEdit->GetText() ); + if( ! aFile.Exists() && ! FileStat( aFile ).IsKind( FSYS_KIND_WILD ) ) + aFile.MakeDir(); + + if( IsFileOk ( aFile ) ) + { + aFile.ToAbs(); + SetPath( aFile.GetFull() ); + } + } + + return 0; +} + + +IMPL_LINK( ImpPathDialog, DblClickHdl, ListBox*, pBox ) +{ + // isolate the pure name of the entry + // removing trainling stuff and leading spaces + UniString aEntry( pBox->GetSelectEntry() ); + + aEntry.EraseLeadingChars( ' ' ); + sal_uInt16 nPos = aEntry.Search( '/' ); + aEntry.Erase( nPos ); + + // build the absolute path to the selected item + DirEntry aNewPath; + aNewPath.ToAbs(); + if( pBox == pDirList ) + { + sal_uInt16 nCurPos = pDirList->GetSelectEntryPos(); + + // Wenn es schon das aktuelle ist, dann mache nichts + if( nCurPos == nDirCount-1 ) + return 0; + + // Wird nach oben gewechselt + if( nCurPos < nDirCount ) + aNewPath = aNewPath[nDirCount-nCurPos-1]; + else + aNewPath += aEntry; + } + else + aNewPath += aEntry; + + pSvPathDialog->EnterWait(); + + if( FileStat( aNewPath ).GetKind() & FSYS_KIND_DIR ) + { + // Neuen Pfad setzen und Listboxen updaten + aPath = aNewPath; + if( !aPath.SetCWD( sal_True ) ) + { + ErrorBox aBox( GetPathDialog(), + WB_OK_CANCEL | WB_DEF_OK, + UniString( SvtResId( STR_FILEDLG_CANTCHDIR ) ) ); + if( aBox.Execute() == RET_CANCEL ) + GetPathDialog()->EndDialog( sal_False ); + } + UpdateEntries( sal_True ); + } + + pSvPathDialog->LeaveWait(); + return 0; +} + +void ImpPathDialog::UpdateEntries( const sal_Bool ) +{ + UniString aTabString; + DirEntry aTmpPath; + aTmpPath.ToAbs(); + + nDirCount = aTmpPath.Level(); + + pDirList->SetUpdateMode( sal_False ); + pDirList->Clear(); + + for( sal_uInt16 i = nDirCount; i > 0; i-- ) + { + UniString aName( aTabString ); + aName += aTmpPath[i-1].GetName(); + pDirList->InsertEntry( aName ); + aTabString.AppendAscii( " ", 2 ); + } + + // scan the directory + DirEntry aCurrent; + aCurrent.ToAbs(); + + Dir aDir( aCurrent, FSYS_KIND_DIR|FSYS_KIND_FILE ); + + sal_uInt16 nEntries = aDir.Count(); + if( nEntries ) + { + UniStringList aSortDirList; + const comphelper::string::NaturalStringSorter& rSorter = + ::vcl::unohelper::getNaturalStringSorterForAppLocale(); + for ( sal_uInt16 n = 0; n < nEntries; n++ ) + { + DirEntry& rEntry = aDir[n]; + UniString aName( rEntry.GetName() ); + if( aName.Len() && ( aName.GetChar(0) != '.' ) && rEntry.Exists() ) + { + if( FileStat( rEntry ).GetKind() & FSYS_KIND_DIR ) + { + size_t l = 0; + for( l = 0; l < aSortDirList.size(); l++ ) + if( rSorter.compare( *aSortDirList[ l ], aName ) > 0 ) + break; + if ( l < aSortDirList.size() ) { + UniStringList::iterator it = aSortDirList.begin(); + ::std::advance( it, l ); + aSortDirList.insert( it, new UniString( aName ) ); + } else { + aSortDirList.push_back( new UniString( aName ) ); + } + } + } + } + + for( size_t l = 0; l < aSortDirList.size(); l++ ) + { + UniString aEntryStr( aTabString ); + aEntryStr += *aSortDirList[ l ]; + pDirList->InsertEntry( aEntryStr ); + delete aSortDirList[ l ]; + } + } + + UpdateDirs( aTmpPath ); +} + +void ImpPathDialog::UpdateDirs( const DirEntry& rTmpPath ) +{ + pDirList->SelectEntryPos( nDirCount-1 ); + pDirList->SetTopEntry( nDirCount > 1 + ? nDirCount - 2 + : nDirCount - 1 ); + pDirList->SetUpdateMode( sal_True ); + pDirList->Invalidate(); + pDirList->Update(); + + UniString aDirName = rTmpPath.GetFull(); + if( pDirPath ) + pDirPath->SetText( aDirName ); + else + pEdit->SetText( aDirName ); +} + +sal_Bool ImpPathDialog::IsFileOk( const DirEntry& rDirEntry ) +{ + if( FileStat( rDirEntry ).GetKind() & (FSYS_KIND_WILD | FSYS_KIND_DEV) ) + return sal_False; + else + { + // Datei vorhanden ? + if( ! rDirEntry.Exists() ) + { + UniString aQueryTxt( SvtResId( STR_FILEDLG_ASKNEWDIR ) ); + aQueryTxt.SearchAndReplaceAscii( "%s", rDirEntry.GetFull() ); + QueryBox aQuery( GetPathDialog(), + WB_YES_NO | WB_DEF_YES, + aQueryTxt ); + if( aQuery.Execute() == RET_YES ) + rDirEntry.MakeDir(); + else + return sal_False; + } + if( !FileStat( rDirEntry ).IsKind( FSYS_KIND_DIR ) ) + { + UniString aBoxText( SvtResId( STR_FILEDLG_CANTOPENDIR ) ); + aBoxText.AppendAscii( "\n[" ); + aBoxText += rDirEntry.GetFull(); + aBoxText.AppendAscii( "]" ); + InfoBox aBox( GetPathDialog(), aBoxText ); + aBox.Execute(); + return sal_False; + } + } + return GetPathDialog()->OK() != 0; +} + + +void ImpPathDialog::PreExecute() +{ + // Neues Verzeichnis setzen und Listboxen updaten + aPath.SetCWD( sal_True ); + UpdateEntries( sal_True ); + + // Zusaetzliche Buttons anordnen + Point aPos; + Size aSize; + long nDY; + if( pLoadBtn ) + { + aPos = pLoadBtn->GetPosPixel(); + aSize = pLoadBtn->GetSizePixel(); + nDY = pLoadBtn->GetSizePixel().Height() * 2; + } + else + { + aPos = pCancelBtn->GetPosPixel(); + aSize = pCancelBtn->GetSizePixel(); + nDY = pCancelBtn->GetPosPixel().Y() - pOkBtn->GetPosPixel().Y(); + } + + // Standard-Controls anpassen + long nMaxWidth = 0; + + // Maximale Breite ermitteln + sal_uInt16 nChilds = GetPathDialog()->GetChildCount(); + sal_uInt16 n; + for ( n = nOwnChilds; n < nChilds; n++ ) + { + Window* pChild = GetPathDialog()->GetChild( n ); + pChild = pChild->GetWindow( WINDOW_CLIENT ); + if( pChild->GetType() != WINDOW_WINDOW ) + { + long nWidth = pChild->GetTextWidth( pChild->GetText() ) + 12; + if( nMaxWidth < nWidth ) + nMaxWidth = nWidth; + nWidth = pChild->GetSizePixel().Width(); + if( nMaxWidth < nWidth ) + nMaxWidth = nWidth; + } + } + + if( nMaxWidth > aSize.Width() ) + { + Size aDlgSize = GetPathDialog()->GetOutputSizePixel(); + GetPathDialog()->SetOutputSizePixel( Size( aDlgSize.Width()+nMaxWidth-aSize.Width(), aDlgSize.Height() ) ); + aSize.Width() = nMaxWidth; + + if( pOkBtn ) + pOkBtn->SetSizePixel( aSize ); + if( pCancelBtn ) + pCancelBtn->SetSizePixel( aSize ); + if( pLoadBtn ) + pLoadBtn->SetSizePixel( aSize ); + } + else + nMaxWidth = aSize.Width(); + + for ( n = nOwnChilds; n < nChilds; n++ ) + { + Window* pChild = GetPathDialog()->GetChild( n ); + pChild = pChild->GetWindow( WINDOW_CLIENT ); + if( pChild->GetType() != WINDOW_WINDOW ) + { + aPos.Y() += nDY; + pChild->SetPosSizePixel( aPos, aSize ); + } + else + { + Size aDlgSize = GetPathDialog()->GetOutputSizePixel(); + long nExtra = Min( aDlgSize.Height(), (long)160); + GetPathDialog()->SetOutputSizePixel( Size( aDlgSize.Width()+nExtra, aDlgSize.Height() ) ); + Size aSz( nExtra, nExtra ); + aSz.Width() -= 8; + aSz.Height() -= 8; + Point aCtrlPos( aDlgSize.Width() + 2, (aDlgSize.Height()-aSz.Height())/2 ); + pChild->SetPosSizePixel( aCtrlPos, aSz ); + } + } + + // Laufwerke-LB fuellen + if( pDriveList ) + { + DirEntry aTmpDirEntry; + Dir aDir( aTmpDirEntry, FSYS_KIND_BLOCK ); + + sal_uInt16 nCount = aDir.Count(), i; + for( i = 0; i < nCount; ++i ) + { + DirEntry& rEntry = aDir[i]; + UniString aStr = rEntry.GetFull( FSYS_STYLE_HOST, sal_False ); + + UniString aVolume = rEntry.GetVolume() ; + aStr.ToUpperAscii(); + if ( aVolume.Len() ) + { + aStr += ' '; + aStr += aVolume; + } + pDriveList->InsertEntry( aStr ); + + } + UniString aPathStr = aPath.GetFull(); + + for ( i = 0; i < pDriveList->GetEntryCount(); ++i ) + { + UniString aEntry = pDriveList->GetEntry(i); + xub_StrLen nLen = aEntry.Len(); + nLen = nLen > 2 ? 2 : nLen; + if ( aEntry.CompareIgnoreCaseToAscii( aPathStr, nLen ) == COMPARE_EQUAL ) + { + pDriveList->SelectEntryPos(i); + break; + } + } + } +} + +void ImpPathDialog::PostExecute() +{ +} + +void ImpPathDialog::SetPath( UniString const & rPath ) +{ + aPath = DirEntry( rPath ); + + pSvPathDialog->EnterWait(); + + DirEntry aFile( rPath ); + // Falls der Pfad eine Wildcard oder einen Filenamen enthaelt + // -> abschneiden und merken + if( FileStat( aFile ).GetKind() & (FSYS_KIND_FILE | FSYS_KIND_WILD) || !aFile.Exists() ) + aFile.CutName(); + + // Neue Maske und neues Verzeichnis setzen, und Listboxen updaten + pEdit->SetText( rPath ); + aFile.SetCWD( sal_True ); + UpdateEntries( sal_True ); + + pSvPathDialog->LeaveWait(); +} + +void ImpPathDialog::SetPath( Edit const & rEdit ) +{ + UniString aPresetText = rEdit.GetText(); + if( aPresetText.Len() ) + SetPath( aPresetText ); +} + + +UniString ImpPathDialog::GetPath() const +{ + DirEntry aFile( pEdit->GetText() ); + aFile.ToAbs(); + return aFile.GetFull(); +} + + +ImpFileDialog::ImpFileDialog( PathDialog* pDlg, WinBits nWinBits, RESOURCE_TYPE nType ) : + ImpPathDialog( pDlg, nType, sal_False ) +{ + bOpen = (nWinBits & WB_SAVEAS) == 0; + + SvtResId aSvtResId = bOpen ? STR_FILEDLG_OPEN : STR_FILEDLG_SAVE; + + // Titel setzen + GetFileDialog()->SetText( UniString( aSvtResId ) ); + nDirCount = 0; + + // initialize Controls if not used as a base class + if ( nType == WINDOW_FILEDIALOG ) + InitControls(); + + pDlg->SetHelpId( HID_FILEDLG_OPENDLG ); + +} + +ImpFileDialog::~ImpFileDialog() +{ + for ( size_t i = 0, n = aFilterList.size(); i < n; ++i ) { + delete aFilterList[ i ]; + } + aFilterList.clear(); + + delete pFileTitel; + if (pFileList && ( pFileList != pDirList ) ) + delete pFileList; + + delete pTypeTitel; + delete pTypeList; +} + +void ImpFileDialog::InitControls() +{ + UniString aEmptyStr; + + const int nW = 160; + const int nH = 48; // Um den Dialog in eine akzeptable Form zu bringen + + INITCONTROL( pFileTitel, FixedText, 0, + Point(10, 12), Size(nW, 18), UniString( SvtResId( STR_FILEDLG_FILE ) ), HID_FILEDLG_FILE ); + INITCONTROL( pEdit, Edit, WB_BORDER, + Point(10, 31), Size(nW, 20), aEmptyStr, HID_FILEDLG_EDIT ); // aMask() + INITCONTROL( pFileList, ListBox, WB_SORT | WB_AUTOHSCROLL | WB_BORDER, + Point(10, 58), Size(nW, 180-nH), aEmptyStr, HID_FILEDLG_FILES ); + + INITCONTROL( pDirTitel, FixedText, 0, + Point(nW+20, 12), Size(nW, 18), UniString( SvtResId( STR_FILEDLG_DIR ) ), HID_FILEDLG_DIR ); + INITCONTROL( pDirPath, FixedInfo, WB_PATHELLIPSIS, + Point(nW+20, 33), Size(nW, 20), aPath.GetFull(), HID_FILEDLG_PATH ); + INITCONTROL( pDirList, KbdListBox, WB_AUTOHSCROLL | WB_BORDER, + Point(nW+20, 58), Size(nW, 180-nH ), aEmptyStr, HID_FILEDLG_DIRS ); + + INITCONTROL( pTypeTitel, FixedText, 0, + Point(10, 246-nH), Size(nW, 18), UniString( SvtResId( STR_FILEDLG_TYPE ) ), HID_FILEDLG_TYPE ); + +#ifndef UNX + INITCONTROL( pTypeList, ListBox, WB_DROPDOWN, + Point(10, 265-nH ), Size(nW, 100 ), aEmptyStr, HID_FILEDLG_TYPES ); + + INITCONTROL( pDriveTitle, FixedText, 0, + Point(nW+20, 246-nH), Size(nW, 18), UniString( SvtResId( STR_FILEDLG_DRIVES ) ), HID_FILEDLG_DRIVE ); + INITCONTROL( pDriveList, ListBox, WB_DROPDOWN, + Point(nW+20, 265-nH ), Size(nW, 100 ), aEmptyStr, HID_FILEDLG_DRIVES ); + pNewDirBtn = NULL; + pHomeBtn = NULL; +#else + INITCONTROL( pTypeList, ListBox, WB_DROPDOWN, + Point(10, 265-nH ), Size(2*nW+20, 100 ), aEmptyStr, HID_FILEDLG_TYPES ); + + pDriveTitle = NULL; + pDriveList = NULL; + pNewDirBtn = NULL; + pHomeBtn = NULL; +#endif + + const long nButtonStartX = 2*nW+20+15; + INITCONTROL( pOkBtn, PushButton, WB_DEFBUTTON, + Point(nButtonStartX, 10), Size(STD_BTN_WIDTH, STD_BTN_HEIGHT), + Button::GetStandardText( BUTTON_OK ), "" ); + INITCONTROL( pCancelBtn, CancelButton, 0, + Point(nButtonStartX, 45 ), Size(STD_BTN_WIDTH, STD_BTN_HEIGHT), + Button::GetStandardText( BUTTON_CANCEL ), "" ); + + pLoadBtn = 0; + + GetFileDialog()->SetOutputSizePixel( Size(nButtonStartX+STD_BTN_WIDTH+10, 298-nH) ); + + nOwnChilds = GetPathDialog()->GetChildCount(); + + // Handler setzen + if (pDriveList) + pDriveList->SetSelectHdl( LINK( this, ImpFileDialog, SelectHdl ) ); + + if (pDirList) + pDirList->SetDoubleClickHdl(LINK( this, ImpFileDialog, DblClickHdl) ); + + if (pOkBtn) + pOkBtn->SetClickHdl( LINK( this, ImpFileDialog, ClickHdl) ); + + if (pCancelBtn) + pCancelBtn->SetClickHdl( LINK( this, ImpFileDialog, ClickHdl) ); + + if( pFileList ) + { + pFileList->SetSelectHdl( LINK( this, ImpFileDialog, SelectHdl ) ); + pFileList->SetDoubleClickHdl( LINK( this, ImpFileDialog, DblClickHdl ) ); + } + + if( pTypeList ) + pTypeList->SetSelectHdl( LINK( this, ImpFileDialog, DblClickHdl ) ); +} + +IMPL_LINK( ImpFileDialog, SelectHdl, ListBox *, p ) +{ + if( p == pDriveList ) + { + UniString aDrive ( pDriveList->GetSelectEntry(), 0, 2); + aDrive += '\\'; + SetPath( aDrive ); + } + else if (p == pFileList) + { + // Ausgewaehltes File in das Edit stellen + pEdit->SetText( pFileList->GetSelectEntry() ); + GetFileDialog()->FileSelect(); + } + return 0; +} + + +IMPL_LINK( ImpFileDialog, DblClickHdl, ListBox *, pBox ) +{ + // isolate the pure name of the entry + // removing trailing stuff and leading spaces + UniString aEntry( pBox->GetSelectEntry() ); + + aEntry.EraseLeadingChars( ' ' ); + sal_uInt16 nPos = aEntry.Search( '/' ); + aEntry.Erase( nPos ); + + // build the absolute path to the selected item + DirEntry aNewPath; + aNewPath.ToAbs(); + + if( ( pDirList != pFileList ) && ( pBox == pDirList ) ) + { + // SVLOOK + sal_uInt16 nCurPos = pDirList->GetSelectEntryPos(); + + // Wenn es schon das aktuelle ist, dann mache nichts + if( nCurPos == nDirCount-1 ) + return 0; + + // Wird nach oben gewechselt + if( nCurPos < nDirCount ) + aNewPath = aNewPath[nDirCount-nCurPos-1]; + else + aNewPath += aEntry; + } + else + { + // non-SVLOOK + if( aEntry == UniString( SvtResId( STR_FILEDLG_GOUP ) ) ) + aEntry.AssignAscii( ".." ); + aNewPath += aEntry; + } + + if( pBox == pFileList ) + { + DirEntry aFile( aEntry ); + + // Abfrage, ob File ueberschrieben werden soll... + if( !FileStat(aFile).IsKind(FSYS_KIND_DIR) && IsFileOk( aFile ) ) + { + // dann kompletten Pfad mit Filenamen merken und Dialog beenden + aPath = aNewPath; + GetFileDialog()->EndDialog( sal_True ); + } + } + + GetFileDialog()->EnterWait(); + + UniString aFull = aNewPath.GetFull(); + + if( ( ( pBox == pDirList ) && ( pDirList != pFileList ) ) || + ( ( pDirList == pFileList ) && FileStat( aNewPath ).GetKind() & FSYS_KIND_DIR ) ) + { + // Neuen Pfad setzen und Listboxen updaten + aPath = aNewPath; + if( !aPath.SetCWD( sal_True ) ) + { + if( ErrorBox( GetFileDialog(), WB_OK_CANCEL|WB_DEF_OK, + UniString( SvtResId( STR_FILEDLG_CANTCHDIR ) ) ).Execute() == RET_CANCEL ) + { + GetFileDialog()->EndDialog( sal_False ); + } + } + UpdateEntries( sal_True ); + GetFileDialog()->FileSelect(); + } + + if( pBox == pTypeList ) + { + // Neue Maske setzen, und Listboxen updaten + size_t nCurPos = pTypeList->GetSelectEntryPos(); + if( nCurPos+1 > aFilterList.size() ) + aMask = UniString::CreateFromAscii( ALLFILES ); + else + { + UniString aFilterListMask = aFilterList[ nCurPos ]->aMask; + aMask = WildCard( aFilterListMask, ';' ); + } + + pEdit->SetText( aMask() ); + UpdateEntries( sal_False ); + GetFileDialog()->FilterSelect(); + } + + GetFileDialog()->LeaveWait(); + + return 0; +} + +IMPL_LINK( ImpFileDialog, ClickHdl, Button*, pBtn ) +{ + if( ( pBtn == pOkBtn ) || ( pBtn == pLoadBtn ) ) + { + DirEntry aFile( pEdit->GetText() ); + + // Existiert File / File ueberschreiben + if( IsFileOk( aFile ) ) + { + // Ja, dann kompletten Pfad mit Filenamen merken und Dialog beenden + aPath = aFile; + aPath.ToAbs(); + GetFileDialog()->EndDialog( sal_True ); + } + else + { + GetFileDialog()->EnterWait(); + + // Falls der Pfad eine Wildcard oder einen Filenamen enthaelt + // -> abschneiden und merken + if( FileStat( aFile ).GetKind() & (FSYS_KIND_FILE | FSYS_KIND_WILD) || !aFile.Exists() ) + { + aMask = aFile.CutName(); + } + + // Neue Maske und neues Verzeichnis setzen, und Listboxen updaten + pEdit->SetText( aMask() ); + aFile.SetCWD( sal_True ); + UpdateEntries( sal_True ); + + GetFileDialog()->LeaveWait(); + } + } + else if( pBtn == pCancelBtn ) + GetFileDialog()->EndDialog( sal_False ); + + return 0; +} + +void ImpFileDialog::UpdateEntries( const sal_Bool bWithDirs ) +{ + GetFileDialog()->EnterWait(); + + UniString aTabString; + DirEntry aTmpPath; + aTmpPath.ToAbs(); + nDirCount = aTmpPath.Level(); + + if( pFileList ) + { + pFileList->SetUpdateMode( sal_False ); + pFileList->Clear(); + } + + if( bWithDirs && (pDirList != pFileList) ) + { + pDirList->SetUpdateMode( sal_False ); + pDirList->Clear(); + + for( sal_uInt16 i = nDirCount; i > 0; i-- ) + { + UniString aEntryStr( aTabString ); + aEntryStr += aTmpPath[i-1].GetName(); + pDirList->InsertEntry( aEntryStr ); + aTabString.AppendAscii( " ", 2 ); + } + } + + // for the combined box insert a '..' + // (this happens only if WB_3DLOOK is not set) + + if( pDirList == pFileList && nDirCount != 1 ) + pFileList->InsertEntry( UniString( SvtResId( STR_FILEDLG_GOUP ) ) ); + + // scan the directory + DirEntry aCurrent; + aCurrent.ToAbs(); + Dir aDir( aCurrent, FSYS_KIND_DIR|FSYS_KIND_FILE ); + sal_uInt16 nEntries = aDir.Count(); + + // TempMask, weil Vergleich case-sensitiv + sal_Bool bMatchCase = sal_False; //aCurrent.IsCaseSensitive(); + UniString aWildCard( aMask.GetWildCard() ); + if ( !bMatchCase ) + aWildCard.ToLowerAscii(); + WildCard aTmpMask( aWildCard, ';' ); + if ( nEntries ) + { + UniStringList aSortDirList; + const comphelper::string::NaturalStringSorter& rSorter = + ::vcl::unohelper::getNaturalStringSorterForAppLocale(); + for ( sal_uInt16 n = 0; n < nEntries; n++ ) + { + DirEntry& rEntry = aDir[n]; + UniString aName( rEntry.GetName() ); + + if( aName.Len() && + ( ( ( aName.GetChar(0) != '.' ) || + ( ( aName.GetChar(0) == '.' ) && ( aMask.GetWildCard() ).GetChar(0) == '.' ) ) + && rEntry.Exists() ) ) + { + FileStat aFileStat( rEntry ); + UniString aTmpName( aName ); + if ( !bMatchCase ) + aTmpName.ToLowerAscii(); + if( ( aFileStat.GetKind() & FSYS_KIND_FILE ) && aTmpMask.Matches( aTmpName ) ) + { + if( pFileList ) + pFileList->InsertEntry( aName ); + } + else if( bWithDirs && ( aFileStat.GetKind() & FSYS_KIND_DIR ) ) + { + if( pDirList == pFileList ) + { + UniString aEntryStr( aName ); + aEntryStr += '/'; + pDirList->InsertEntry( aEntryStr ); + } + else + { + size_t l = 0; + for( l = 0; l < aSortDirList.size(); l++ ) + if( rSorter.compare( *aSortDirList[ l ], aName ) > 0 ) + break; + if ( l < aSortDirList.size() ) { + UniStringList::iterator it = aSortDirList.begin(); + ::std::advance( it, l ); + aSortDirList.insert( it, new UniString( aName ) ); + } else { + aSortDirList.push_back( new UniString( aName ) ); + } + } + } + } + } + for( size_t l = 0; l < aSortDirList.size(); l++ ) + { + UniString aEntryStr( aTabString ); + aEntryStr += *aSortDirList[ l ]; + pDirList->InsertEntry( aEntryStr ); + delete aSortDirList[ l ]; + } + } + + if( bWithDirs ) + UpdateDirs( aTmpPath ); + + if( pFileList ) + { + if ( pDirList == pFileList && nDirCount > 1 ) + pFileList->SelectEntryPos( 1 ); + else + pFileList->SetNoSelection(); + pFileList->SetUpdateMode( sal_True ); + pFileList->Invalidate(); + pFileList->Update(); + } + + if( pDriveList ) + { + if( pDirList->GetEntryCount() > 0 ) + { + UniString aStr( pDirList->GetEntry( 0 ) ); + aStr.Erase( 2 ); + aStr.ToLowerAscii(); + pDriveList->SelectEntry( aStr ); + } + } + + GetFileDialog()->LeaveWait(); +} + +sal_Bool ImpFileDialog::IsFileOk( const DirEntry& rDirEntry ) +{ + if( FileStat( rDirEntry ).GetKind() & (FSYS_KIND_WILD | FSYS_KIND_DEV) ) + return sal_False; + if( FileStat( rDirEntry ).GetKind() & FSYS_KIND_DIR ) + { + if( pFileList ) + return sal_False; + } + else if( bOpen ) + { + // Datei vorhanden ? + if( !FileStat( rDirEntry ).IsKind( FSYS_KIND_FILE ) ) + { + UniString aErrorString( SvtResId( STR_FILEDLG_CANTOPENFILE ) ); + aErrorString.AppendAscii( "\n[" ); + aErrorString += rDirEntry.GetFull(); + aErrorString += ']'; + InfoBox aBox( GetFileDialog(), + aErrorString ); + aBox.Execute(); + return sal_False; + } + } + else + { + // Datei vorhanden ? + if( FileStat( ExtendFileName( rDirEntry ) ).IsKind( FSYS_KIND_FILE ) ) + { + UniString aQueryString( SvtResId( STR_FILEDLG_OVERWRITE ) ); + aQueryString.AppendAscii( "\n[" ); + aQueryString += rDirEntry.GetFull(); + aQueryString += ']'; + QueryBox aBox( GetFileDialog(), + WinBits( WB_YES_NO | WB_DEF_NO ), + aQueryString ); + if( aBox.Execute() != RET_YES ) + return sal_False; + } + } + return GetFileDialog()->OK() != 0; +} + +void ImpFileDialog::SetPath( UniString const & rPath ) +{ + aPath = DirEntry( rPath ); + GetFileDialog()->EnterWait(); + + DirEntry aFile( rPath ); + + // Falls der Pfad eine Wildcard oder einen Filenamen enthaelt + // -> abschneiden und merken + if( FileStat( aFile ).GetKind() & (FSYS_KIND_FILE | FSYS_KIND_WILD) || !aFile.Exists() ) + { + aMask = aFile.CutName(); + + // Neue Maske und neues Verzeichnis setzen, und Listboxen updaten + if( pDirList ) + { + UniString aWildCard( aMask.GetWildCard() ); + pEdit->SetText( aWildCard ); + } + else + pEdit->SetText( rPath ); + } + + aFile.SetCWD( sal_True ); + + UpdateEntries( sal_True ); + + GetFileDialog()->LeaveWait(); +} + +void ImpFileDialog::SetPath( Edit const& rEdit ) +{ + UniString aPresetText = rEdit.GetText(); + if( aPresetText.Len() ) + SetPath( aPresetText ); +} + + +void ImpFileDialog::AddFilter( const UniString& rFilter, const UniString& rMask ) +{ + aFilterList.push_back( new ImpFilterItem( rFilter, rMask ) ); + if( pTypeList ) + pTypeList->InsertEntry( rFilter, LISTBOX_APPEND ); + + if( !GetCurFilter().Len() ) + SetCurFilter( rFilter ); +} + +void ImpFileDialog::RemoveFilter( const UniString& rFilter ) +{ + for ( ImpFilterList::iterator it = aFilterList.begin(); it < aFilterList.end(); ++it ) { + if ( (*it)->aName == rFilter ) { + delete *it; + aFilterList.erase( it ); + if ( pTypeList ) { + pTypeList->RemoveEntry( rFilter ); + } + break; + } + } +} + +void ImpFileDialog::RemoveAllFilter() +{ + for ( size_t i = 0, n = aFilterList.size(); i < n ; ++i ) { + delete aFilterList[ i ]; + } + aFilterList.clear(); + + if( pTypeList ) + pTypeList->Clear(); +} + +void ImpFileDialog::SetCurFilter( const UniString& rFilter ) +{ + if( !pTypeList ) + return; + + for ( size_t i = 0, n = aFilterList.size(); i < n; ++i ) { + if ( aFilterList[ i ]->aName == rFilter ) { + pTypeList->SelectEntryPos( sal_uInt16( i ) ); + return; + } + } + + pTypeList->SetNoSelection(); +} + +UniString ImpFileDialog::GetCurFilter() const +{ + UniString aFilter; + if ( pTypeList ) + aFilter = pTypeList->GetSelectEntry(); + return aFilter; +} + +void ImpFileDialog::PreExecute() +{ + // ListBoxen erst unmittelbar vor Execute fuellen + // (damit vor Execute der Pfad umgesetzt werden kann, ohne das immer die + // Listboxen sofort upgedatet werden) + + GetFileDialog()->EnterWait(); + + // Wenn kein Filter vorhanden, dann auch keine FilterBox + if( pTypeList && !pTypeList->GetEntryCount() ) + { + // pTypeList->InsertEntry( "* (all files)" ); + pTypeTitel->Disable(); + pTypeList->Disable(); + } + + if( pTypeList ) + { + sal_uInt16 nCurType = pTypeList->GetSelectEntryPos(); + if( nCurType < aFilterList.size() ) + { + UniString aFilterListMask = aFilterList[ nCurType ]->aMask; + if( aFilterListMask.Search( ';' ) == STRING_NOTFOUND ) // kein ; in der Maske + aMask = WildCard( aFilterListMask, '\0' ); + else // ; in der Maske, muss in der Wildcard beruecksichtigt werden + aMask = WildCard( aFilterListMask, ';' ); + } + else + aMask = UniString::CreateFromAscii( ALLFILES ); + } + else + aMask = UniString::CreateFromAscii( ALLFILES ); + + // Neue Maske setzen + if( pEdit->GetText().Len() == 0 ) + pEdit->SetText( aMask() ); + + ImpPathDialog::PreExecute(); + + GetFileDialog()->LeaveWait(); +} + +UniString ImpFileDialog::GetPath() const +{ + DirEntry aFile( pEdit->GetText() ); + return ExtendFileName( aFile ); +} + +UniString ImpFileDialog::ExtendFileName( DirEntry aEntry ) const +{ + aEntry.ToAbs(); + // das ganze Theater hier ohnehin nur machen, wenn Dateiname + // ohne Extension angegeben wurde + if( !aEntry.GetExtension().Len() ) + { + UniString aPostfix; // hier kommt die ausgesuchte Extension herein + + // ist ein Filter mit Extension gesetzt? + sal_uInt16 nChosenFilterPos = pTypeList->GetSelectEntryPos(); + if( nChosenFilterPos != LISTBOX_ENTRY_NOTFOUND ) + { + UniString aExtensionMask = GetFileDialog()->GetFilterType( nChosenFilterPos ); + // aExtension ist z.B. *.sdw, alles bis einschliesslich Punkt abschneiden + UniString aExtension = aExtensionMask.Copy( aExtensionMask.Search( '.' )+1 ); + + // hat der Filter ueberhaupt eine Extension + if( aExtension.Len() ) + { + // keine Wildcards enthalten? + if( ( aExtension.Search( '*' ) == STRING_NOTFOUND ) && + ( aExtension.Search( '?' ) == STRING_NOTFOUND ) ) + { + // OK, Filter hat Extension ohne Wildcards -> verwenden + aPostfix = aExtension; + } + else + { + // Filter hat Extension mit Wildcards (z.B. *.*) -> nicht verwenden + aPostfix.Erase(); + } + } + else + { + // Filter hatte keine Extension (schwer vorstellbar) -> nichts anhaengen + aPostfix.Erase(); + } + } + else + { + // kein Filter gefunden (merkw�rdig) -> Default-Extension anhaengen + aPostfix = GetFileDialog()->GetDefaultExt(); + } + + // jetzt kann es mit dem Anhaengen losgehen + const sal_Unicode* pExt = aPostfix.GetBuffer(); + while( *pExt == '*' || *pExt == '?' ) + pExt++; + + if( *pExt ) + { + UniString aName = aEntry.GetName(); + if( *pExt != '.' ) + aName += '.'; + aName += pExt; + aEntry.SetName( aName ); + } + } + return aEntry.GetFull(); +} + + +void ImpSvFileDlg::CreateDialog( PathDialog* pSvDlg, WinBits nStyle, RESOURCE_TYPE nType, sal_Bool bCreate ) +{ + delete pDlg; + if ( nType == WINDOW_PATHDIALOG ) + pDlg = new ImpPathDialog( pSvDlg, nType, bCreate ); + else + pDlg = new ImpFileDialog( pSvDlg, nStyle, nType ); +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |