504 lines
12 KiB
C++
504 lines
12 KiB
C++
/*
|
|
===========================================================================
|
|
|
|
Doom 3 GPL Source Code
|
|
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
|
|
|
|
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
|
|
|
|
Doom 3 Source Code is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
Doom 3 Source Code 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 General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
|
|
|
|
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
|
|
|
===========================================================================
|
|
*/
|
|
|
|
#include "../../idlib/precompiled.h"
|
|
#pragma hdrstop
|
|
|
|
#include "../../sys/win32/win_local.h"
|
|
#include "../../sys/win32/rc/common_resource.h"
|
|
#include "OpenFileDialog.h"
|
|
|
|
char rvOpenFileDialog::mLookin[ MAX_OSPATH ];
|
|
|
|
/*
|
|
================
|
|
rvOpenFileDialog::rvOpenFileDialog
|
|
|
|
constructor
|
|
================
|
|
*/
|
|
rvOpenFileDialog::rvOpenFileDialog( void )
|
|
{
|
|
mWnd = NULL;
|
|
mInstance = NULL;
|
|
mBackBitmap = NULL;
|
|
mImageList = NULL;
|
|
mFlags = 0;
|
|
}
|
|
|
|
/*
|
|
================
|
|
rvOpenFileDialog::~rvOpenFileDialog
|
|
|
|
destructor
|
|
================
|
|
*/
|
|
rvOpenFileDialog::~rvOpenFileDialog ( void )
|
|
{
|
|
if ( mImageList )
|
|
{
|
|
ImageList_Destroy ( mImageList );
|
|
}
|
|
|
|
if ( mBackBitmap )
|
|
{
|
|
DeleteObject ( mBackBitmap );
|
|
}
|
|
}
|
|
|
|
/*
|
|
================
|
|
rvOpenFileDialog::DoModal
|
|
|
|
Opens the dialog and returns true if a filename was found
|
|
================
|
|
*/
|
|
bool rvOpenFileDialog::DoModal ( HWND parent )
|
|
{
|
|
mInstance = win32.hInstance;
|
|
|
|
INITCOMMONCONTROLSEX ex;
|
|
ex.dwICC = ICC_USEREX_CLASSES | ICC_LISTVIEW_CLASSES;
|
|
ex.dwSize = sizeof(INITCOMMONCONTROLSEX);
|
|
|
|
InitCommonControlsEx ( &ex );
|
|
|
|
return DialogBoxParam ( mInstance, MAKEINTRESOURCE(IDD_TOOLS_OPEN), parent, DlgProc, (LPARAM)this ) ? true : false;
|
|
}
|
|
|
|
/*
|
|
================
|
|
rvOpenFileDialog::UpdateLookIn
|
|
|
|
Updates the lookin combo box with the current lookin state
|
|
================
|
|
*/
|
|
void rvOpenFileDialog::UpdateLookIn ( void )
|
|
{
|
|
COMBOBOXEXITEM item;
|
|
idStr file;
|
|
idStr path;
|
|
|
|
// Reset the combo box
|
|
SendMessage ( mWndLookin, CB_RESETCONTENT, 0, 0 );
|
|
|
|
// Setup the common item structure components
|
|
ZeroMemory ( &item, sizeof(item) );
|
|
item.mask = CBEIF_TEXT | CBEIF_INDENT | CBEIF_IMAGE | CBEIF_SELECTEDIMAGE;
|
|
|
|
// Add the top left folder
|
|
item.pszText = (LPSTR)"base";
|
|
SendMessage ( mWndLookin, CBEM_INSERTITEM, 0, (LPARAM)&item );
|
|
|
|
// Break the lookin path up into its individual components and add them
|
|
// to the combo box
|
|
path = mLookin;
|
|
|
|
while ( path.Length ( ) )
|
|
{
|
|
int slash = path.Find ( "/" );
|
|
|
|
// Parse out the next subfolder
|
|
if ( slash != -1 )
|
|
{
|
|
file = path.Left ( slash );
|
|
path = path.Right ( path.Length ( ) - slash - 1 );
|
|
}
|
|
else
|
|
{
|
|
file = path;
|
|
path.Empty ( );
|
|
}
|
|
|
|
// Add the sub folder
|
|
item.pszText = (LPSTR)file.c_str();
|
|
item.iIndent++;
|
|
item.iItem = item.iIndent;
|
|
SendMessage ( mWndLookin, CBEM_INSERTITEM, 0, (LPARAM)&item );
|
|
}
|
|
|
|
// Set the selection to the last one since thats the deepest folder
|
|
SendMessage ( mWndLookin, CB_SETCURSEL, item.iIndent, 0 );
|
|
}
|
|
|
|
/*
|
|
================
|
|
rvOpenFileDialog::UpdateFileList
|
|
|
|
Updates the file list with the files that match the filter in the current
|
|
look in directory
|
|
================
|
|
*/
|
|
void rvOpenFileDialog::UpdateFileList ( void )
|
|
{
|
|
const char *basepath = mLookin;
|
|
idFileList *files;
|
|
HWND list = GetDlgItem ( mWnd, IDC_TOOLS_FILELIST );
|
|
int i;
|
|
int filter;
|
|
|
|
ListView_DeleteAllItems ( list );
|
|
|
|
// Add all the folders first
|
|
files = fileSystem->ListFiles ( basepath, "/", true );
|
|
for ( i = 0; i < files->GetNumFiles(); i ++ )
|
|
{
|
|
if ( files->GetFile( i )[0] == '.' )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
LVITEM item;
|
|
item.mask = LVIF_TEXT;
|
|
item.iItem = ListView_GetItemCount ( list );
|
|
item.pszText = (LPSTR)files->GetFile( i );
|
|
item.iSubItem = 0;
|
|
ListView_InsertItem ( list, &item );
|
|
}
|
|
fileSystem->FreeFileList( files );
|
|
|
|
// Add all the files in the current lookin directory that match the
|
|
// current filters.
|
|
for ( filter = 0; filter < mFilters.Num(); filter ++ )
|
|
{
|
|
files = fileSystem->ListFiles( basepath, mFilters[filter], true );
|
|
for ( i = 0; i < files->GetNumFiles(); i ++ )
|
|
{
|
|
if ( files->GetFile( i )[0] == '.' )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
LVITEM item;
|
|
item.mask = LVIF_TEXT|LVIF_IMAGE;
|
|
item.iImage = 2;
|
|
item.iItem = ListView_GetItemCount( list );
|
|
item.pszText = (LPSTR)files->GetFile( i );
|
|
item.iSubItem = 0;
|
|
ListView_InsertItem ( list, &item );
|
|
}
|
|
fileSystem->FreeFileList( files );
|
|
}
|
|
}
|
|
|
|
/*
|
|
================
|
|
rvOpenFileDialog::HandleCommandOK
|
|
|
|
Handles the pressing of the OK button but either opening a selected folder
|
|
or closing the dialog with the resulting filename
|
|
================
|
|
*/
|
|
void rvOpenFileDialog::HandleCommandOK ( void )
|
|
{
|
|
char temp[256];
|
|
LVITEM item;
|
|
|
|
// If nothing is selected then there is nothing to open
|
|
int sel = ListView_GetNextItem ( mWndFileList, -1, LVNI_SELECTED );
|
|
if ( sel == -1 )
|
|
{
|
|
GetWindowText ( GetDlgItem ( mWnd, IDC_TOOLS_FILENAME ), temp, sizeof(temp)-1 );
|
|
if ( !temp[0] )
|
|
{
|
|
return;
|
|
}
|
|
|
|
item.iImage = 2;
|
|
}
|
|
else
|
|
{
|
|
// Get the currently selected item
|
|
item.mask = LVIF_IMAGE|LVIF_TEXT;
|
|
item.iImage = sel;
|
|
item.iSubItem = 0;
|
|
item.pszText = temp;
|
|
item.cchTextMax = 256;
|
|
item.iItem = sel;
|
|
ListView_GetItem ( mWndFileList, &item );
|
|
}
|
|
|
|
// If the item is a folder then just open that folder
|
|
if ( item.iImage == 0 )
|
|
{
|
|
if ( strlen( mLookin ) )
|
|
{
|
|
idStr::snPrintf( mLookin, sizeof( mLookin ), "%s/%s", mLookin, temp );
|
|
} else {
|
|
idStr::Copynz( mLookin, temp, sizeof( mLookin ) );
|
|
}
|
|
UpdateLookIn ( );
|
|
UpdateFileList ( );
|
|
}
|
|
// If the item is a file then build the filename and end the dialog
|
|
else if ( item.iImage == 2 )
|
|
{
|
|
mFilename = mLookin;
|
|
if ( mFilename.Length ( ) )
|
|
{
|
|
mFilename.Append ( "/" );
|
|
}
|
|
mFilename.Append ( temp );
|
|
|
|
// Make sure the file exists
|
|
if ( mFlags & OFD_MUSTEXIST )
|
|
{
|
|
idFile* file;
|
|
file = fileSystem->OpenFileRead ( mFilename );
|
|
if ( !file )
|
|
{
|
|
MessageBox ( mWnd, va("%s\nFile not found.\nPlease verify the correct file name was given", mFilename.c_str() ), "Open", MB_ICONERROR|MB_OK );
|
|
return;
|
|
}
|
|
fileSystem->CloseFile ( file );
|
|
}
|
|
|
|
EndDialog ( mWnd, 1 );
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/*
|
|
================
|
|
rvOpenFileDialog::HandleInitDialog
|
|
|
|
Handles the init dialog message
|
|
================
|
|
*/
|
|
void rvOpenFileDialog::HandleInitDialog ( void )
|
|
{
|
|
// Cache the more used window handles
|
|
mWndFileList = GetDlgItem ( mWnd, IDC_TOOLS_FILELIST );
|
|
mWndLookin = GetDlgItem ( mWnd, IDC_TOOLS_LOOKIN );
|
|
|
|
// Load the custom resources used by the controls
|
|
mImageList = ImageList_LoadBitmap ( mInstance, MAKEINTRESOURCE(IDB_TOOLS_OPEN),16,1,RGB(255,255,255) );
|
|
mBackBitmap = (HBITMAP)LoadImage ( mInstance, MAKEINTRESOURCE(IDB_TOOLS_BACK), IMAGE_BITMAP, 16, 16, LR_DEFAULTCOLOR|LR_LOADMAP3DCOLORS );
|
|
|
|
// Attach the image list to the file list and lookin controls
|
|
ListView_SetImageList ( mWndFileList, mImageList, LVSIL_SMALL );
|
|
SendMessage( mWndLookin,CBEM_SETIMAGELIST,0,(LPARAM) mImageList );
|
|
|
|
// Back button is a bitmap button
|
|
SendMessage( GetDlgItem ( mWnd, IDC_TOOLS_BACK ), BM_SETIMAGE, IMAGE_BITMAP, (LONG) mBackBitmap );
|
|
|
|
// Allow custom titles
|
|
SetWindowText ( mWnd, mTitle );
|
|
|
|
// Custom ok button title
|
|
if ( mOKTitle.Length ( ) )
|
|
{
|
|
SetWindowText ( GetDlgItem ( mWnd, IDOK ), mOKTitle );
|
|
}
|
|
|
|
// See if there is a filename in the lookin
|
|
idStr temp;
|
|
idStr filename = mLookin;
|
|
filename.ExtractFileExtension ( temp );
|
|
if ( temp.Length ( ) )
|
|
{
|
|
filename.ExtractFileName ( temp );
|
|
SetWindowText ( GetDlgItem ( mWnd, IDC_TOOLS_FILENAME ), temp );
|
|
filename.StripFilename ( );
|
|
idStr::snPrintf( mLookin, sizeof( mLookin ), "%s", filename.c_str() );
|
|
}
|
|
|
|
// Update our controls
|
|
UpdateLookIn ( );
|
|
UpdateFileList ( );
|
|
}
|
|
|
|
/*
|
|
================
|
|
rvOpenFileDialog::HandleLookInChange
|
|
|
|
Handles a selection change within the lookin control
|
|
================
|
|
*/
|
|
void rvOpenFileDialog::HandleLookInChange ( void )
|
|
{
|
|
char temp[256];
|
|
int sel;
|
|
int i;
|
|
idStr lookin;
|
|
|
|
temp[0] = 0;
|
|
|
|
sel = SendMessage ( mWndLookin, CB_GETCURSEL, 0, 0 );
|
|
|
|
// If something other than base is selected then walk up the list
|
|
// and build the new lookin path
|
|
if ( sel >= 1 )
|
|
{
|
|
SendMessage ( mWndLookin, CB_GETLBTEXT, 1, (LPARAM)temp );
|
|
idStr::snPrintf( mLookin, sizeof( mLookin ), "%s", temp );
|
|
for ( i = 2; i <= sel; i ++ )
|
|
{
|
|
SendMessage ( mWndLookin, CB_GETLBTEXT, i, (LPARAM)temp );
|
|
idStr::snPrintf( mLookin, sizeof( mLookin ), "%s/%s", mLookin, temp );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
mLookin[0] = 0;
|
|
}
|
|
|
|
// Update the controls with the new lookin path
|
|
UpdateLookIn ( );
|
|
UpdateFileList ( );
|
|
}
|
|
|
|
/*
|
|
================
|
|
rvOpenFileDialog::SetFilter
|
|
|
|
Set the extensions available in the dialog
|
|
================
|
|
*/
|
|
void rvOpenFileDialog::SetFilter ( const char* s )
|
|
{
|
|
idStr filters = s;
|
|
idStr filter;
|
|
|
|
while ( filters.Length ( ) )
|
|
{
|
|
int semi = filters.Find ( ';' );
|
|
if ( semi != -1 )
|
|
{
|
|
filter = filters.Left ( semi );
|
|
filters = filters.Right ( filters.Length ( ) - semi );
|
|
}
|
|
else
|
|
{
|
|
filter = filters;
|
|
filters.Empty ( );
|
|
}
|
|
|
|
mFilters.Append ( filter.c_str() + (filter[0] == '*' ? 1 : 0) );
|
|
}
|
|
}
|
|
|
|
/*
|
|
================
|
|
rvOpenFileDialog::DlgProc
|
|
|
|
Dialog Procedure for the open file dialog
|
|
================
|
|
*/
|
|
INT_PTR rvOpenFileDialog::DlgProc ( HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam )
|
|
{
|
|
rvOpenFileDialog* dlg = (rvOpenFileDialog*) GetWindowLong ( wnd, GWL_USERDATA );
|
|
|
|
switch ( msg )
|
|
{
|
|
case WM_INITDIALOG:
|
|
dlg = (rvOpenFileDialog*) lparam;
|
|
SetWindowLong ( wnd, GWL_USERDATA, lparam );
|
|
dlg->mWnd = wnd;
|
|
dlg->HandleInitDialog ( );
|
|
return TRUE;
|
|
|
|
case WM_NOTIFY:
|
|
{
|
|
NMHDR* nm = (NMHDR*) lparam;
|
|
switch ( nm->idFrom )
|
|
{
|
|
case IDC_TOOLS_FILELIST:
|
|
switch ( nm->code )
|
|
{
|
|
case LVN_ITEMCHANGED:
|
|
{
|
|
NMLISTVIEW* nmlv = (NMLISTVIEW*)nm;
|
|
if ( nmlv->uNewState & LVIS_SELECTED )
|
|
{
|
|
// Get the currently selected item
|
|
LVITEM item;
|
|
char temp[256];
|
|
item.mask = LVIF_IMAGE|LVIF_TEXT;
|
|
item.iSubItem = 0;
|
|
item.pszText = temp;
|
|
item.cchTextMax = sizeof(temp)-1;
|
|
item.iItem = nmlv->iItem;
|
|
ListView_GetItem ( dlg->mWndFileList, &item );
|
|
|
|
if ( item.iImage == 2 )
|
|
{
|
|
SetWindowText ( GetDlgItem ( wnd, IDC_TOOLS_FILENAME ), temp );
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
case NM_DBLCLK:
|
|
dlg->HandleCommandOK ( );
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
|
|
case WM_COMMAND:
|
|
switch ( LOWORD ( wparam ) )
|
|
{
|
|
case IDOK:
|
|
{
|
|
dlg->HandleCommandOK ( );
|
|
break;
|
|
}
|
|
|
|
case IDCANCEL:
|
|
EndDialog ( wnd, 0 );
|
|
break;
|
|
|
|
case IDC_TOOLS_BACK:
|
|
{
|
|
int sel = SendMessage ( GetDlgItem ( wnd, IDC_TOOLS_LOOKIN ), CB_GETCURSEL, 0, 0 );
|
|
if ( sel > 0 )
|
|
{
|
|
sel--;
|
|
SendMessage ( GetDlgItem ( wnd, IDC_TOOLS_LOOKIN ), CB_SETCURSEL, sel, 0 );
|
|
dlg->HandleLookInChange ( );
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case IDC_TOOLS_LOOKIN:
|
|
if ( HIWORD ( wparam ) == CBN_SELCHANGE )
|
|
{
|
|
dlg->HandleLookInChange ( );
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|