dirctrlg.cpp
来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 1,669 行 · 第 1/4 页
CPP
1,669 行
/////////////////////////////////////////////////////////////////////////////
// Name: dirctrlg.cpp
// Purpose: wxGenericDirCtrl
// Author: Harm van der Heijden, Robert Roebling, Julian Smart
// Modified by:
// Created: 12/12/98
// RCS-ID: $Id: dirctrlg.cpp,v 1.129.2.5 2006/03/05 20:50:25 VZ Exp $
// Copyright: (c) Harm van der Heijden, Robert Roebling and Julian Smart
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
#pragma implementation "dirctrlg.h"
#endif
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#if wxUSE_DIRDLG || wxUSE_FILEDLG
#include "wx/generic/dirctrlg.h"
#include "wx/module.h"
#include "wx/utils.h"
#include "wx/button.h"
#include "wx/layout.h"
#include "wx/msgdlg.h"
#include "wx/textctrl.h"
#include "wx/textdlg.h"
#include "wx/filefn.h"
#include "wx/cmndata.h"
#include "wx/gdicmn.h"
#include "wx/intl.h"
#include "wx/imaglist.h"
#include "wx/icon.h"
#include "wx/log.h"
#include "wx/sizer.h"
#include "wx/tokenzr.h"
#include "wx/dir.h"
#include "wx/settings.h"
#include "wx/artprov.h"
#include "wx/hash.h"
#include "wx/mimetype.h"
#include "wx/image.h"
#include "wx/choice.h"
#if wxUSE_STATLINE
#include "wx/statline.h"
#endif
#if defined(__WXMAC__)
#include "wx/mac/private.h" // includes mac headers
#endif
#ifdef __WXMSW__
#include <windows.h>
#include "wx/msw/winundef.h"
// FIXME - Mingw32 1.0 has both _getdrive() and _chdrive(). For now, let's assume
// older releases don't, but it should be verified and the checks modified
// accordingly.
#if !defined(__GNUWIN32__) || (defined(__MINGW32_MAJOR_VERSION) && __MINGW32_MAJOR_VERSION >= 1)
#if !defined(__WXWINCE__)
#include <direct.h>
#endif
#include <stdlib.h>
#include <ctype.h>
#endif
#endif
#if defined(__OS2__) || defined(__DOS__)
#ifdef __OS2__
#define INCL_BASE
#include <os2.h>
#ifndef __EMX__
#include <direct.h>
#endif
#include <stdlib.h>
#include <ctype.h>
#endif
extern bool wxIsDriveAvailable(const wxString& dirName);
#endif // __OS2__
#if defined(__WXMAC__)
# include "MoreFilesX.h"
#endif
#ifdef __BORLANDC__
#include "dos.h"
#endif
// If compiled under Windows, this macro can cause problems
#ifdef GetFirstChild
#undef GetFirstChild
#endif
// ----------------------------------------------------------------------------
// wxGetAvailableDrives, for WINDOWS, DOS, OS2, MAC, UNIX (returns "/")
// ----------------------------------------------------------------------------
size_t wxGetAvailableDrives(wxArrayString &paths, wxArrayString &names, wxArrayInt &icon_ids)
{
#if defined(__WINDOWS__) || defined(__DOS__) || defined(__OS2__)
#ifdef __WXWINCE__
// No logical drives; return "\"
paths.Add(wxT("\\"));
names.Add(wxT("\\"));
icon_ids.Add(wxFileIconsTable::computer);
#elif defined(__WIN32__)
wxChar driveBuffer[256];
size_t n = (size_t) GetLogicalDriveStrings(255, driveBuffer);
size_t i = 0;
while (i < n)
{
wxString path, name;
path.Printf(wxT("%c:\\"), driveBuffer[i]);
name.Printf(wxT("%c:"), driveBuffer[i]);
#if !defined(__WXWINCE__)
wxChar pname[52];
if (GetVolumeInformation( path.c_str(), pname, 52, NULL, NULL, NULL, NULL, 0 ))
{
name << _T(' ') << pname;
}
#endif // __WXWINCE__
int imageId;
int driveType = ::GetDriveType(path);
switch (driveType)
{
case DRIVE_REMOVABLE:
if (path == wxT("a:\\") || path == wxT("b:\\"))
imageId = wxFileIconsTable::floppy;
else
imageId = wxFileIconsTable::removeable;
break;
case DRIVE_CDROM:
imageId = wxFileIconsTable::cdrom;
break;
case DRIVE_REMOTE:
case DRIVE_FIXED:
default:
imageId = wxFileIconsTable::drive;
break;
}
paths.Add(path);
names.Add(name);
icon_ids.Add(imageId);
while (driveBuffer[i] != wxT('\0'))
i ++;
i ++;
if (driveBuffer[i] == wxT('\0'))
break;
}
#elif defined(__OS2__)
APIRET rc;
ULONG ulDriveNum = 0;
ULONG ulDriveMap = 0;
rc = ::DosQueryCurrentDisk(&ulDriveNum, &ulDriveMap);
if ( rc == 0)
{
size_t i = 0;
while (i < 26)
{
if (ulDriveMap & ( 1 << i ))
{
wxString path, name;
path.Printf(wxT("%c:\\"), 'A' + i);
name.Printf(wxT("%c:"), 'A' + i);
// Note: If _filesys is unsupported by some compilers,
// we can always replace it by DosQueryFSAttach
char filesysname[20];
_filesys(name.fn_str(), filesysname, sizeof(filesysname));
/* FAT, LAN, HPFS, CDFS, NFS */
int imageId;
if (path == wxT("A:\\") || path == wxT("B:\\"))
imageId = wxFileIconsTable::floppy;
else if (!strcmp(filesysname, "CDFS"))
imageId = wxFileIconsTable::cdrom;
else if (!strcmp(filesysname, "LAN") ||
!strcmp(filesysname, "NFS"))
imageId = wxFileIconsTable::drive;
else
imageId = wxFileIconsTable::drive;
paths.Add(path);
names.Add(name);
icon_ids.Add(imageId);
}
i ++;
}
}
#else // !__WIN32__, !__OS2__
int drive;
/* If we can switch to the drive, it exists. */
for( drive = 1; drive <= 26; drive++ )
{
wxString path, name;
path.Printf(wxT("%c:\\"), (char) (drive + 'a' - 1));
name.Printf(wxT("%c:"), (char) (drive + 'A' - 1));
if (wxIsDriveAvailable(path))
{
paths.Add(path);
names.Add(name);
icon_ids.Add((drive <= 2) ? wxFileIconsTable::floppy : wxFileIconsTable::drive);
}
}
#endif // __WIN32__/!__WIN32__
#elif defined(__WXMAC__)
ItemCount volumeIndex = 1;
OSErr err = noErr ;
while( noErr == err )
{
HFSUniStr255 volumeName ;
FSRef fsRef ;
FSVolumeInfo volumeInfo ;
err = FSGetVolumeInfo(0, volumeIndex, NULL, kFSVolInfoFlags , &volumeInfo , &volumeName, &fsRef);
if( noErr == err )
{
wxString path = wxMacFSRefToPath( &fsRef ) ;
wxString name = wxMacHFSUniStrToString( &volumeName ) ;
if ( (volumeInfo.flags & kFSVolFlagSoftwareLockedMask) || (volumeInfo.flags & kFSVolFlagHardwareLockedMask) )
{
icon_ids.Add(wxFileIconsTable::cdrom);
}
else
{
icon_ids.Add(wxFileIconsTable::drive);
}
// todo other removable
paths.Add(path);
names.Add(name);
volumeIndex++ ;
}
}
#elif defined(__UNIX__)
paths.Add(wxT("/"));
names.Add(wxT("/"));
icon_ids.Add(wxFileIconsTable::computer);
#else
#error "Unsupported platform in wxGenericDirCtrl!"
#endif
wxASSERT_MSG( (paths.GetCount() == names.GetCount()), wxT("The number of paths and their human readable names should be equal in number."));
wxASSERT_MSG( (paths.GetCount() == icon_ids.GetCount()), wxT("Wrong number of icons for available drives."));
return paths.GetCount();
}
// ----------------------------------------------------------------------------
// wxIsDriveAvailable
// ----------------------------------------------------------------------------
#if defined(__DOS__)
bool wxIsDriveAvailable(const wxString& dirName)
{
// FIXME_MGL - this method leads to hang up under Watcom for some reason
#ifndef __WATCOMC__
if ( dirName.Len() == 3 && dirName[1u] == wxT(':') )
{
wxString dirNameLower(dirName.Lower());
// VS: always return true for removable media, since Win95 doesn't
// like it when MS-DOS app accesses empty floppy drive
return (dirNameLower[0u] == wxT('a') ||
dirNameLower[0u] == wxT('b') ||
wxDirExists(dirNameLower));
}
else
#endif
return true;
}
#elif defined(__WINDOWS__) || defined(__OS2__)
int setdrive(int WXUNUSED_IN_WINCE(drive))
{
#ifdef __WXWINCE__
return 0;
#elif defined(__GNUWIN32__) && \
(defined(__MINGW32_MAJOR_VERSION) && __MINGW32_MAJOR_VERSION >= 1)
return _chdrive(drive);
#else
wxChar newdrive[4];
if (drive < 1 || drive > 31)
return -1;
newdrive[0] = (wxChar)(wxT('A') + drive - 1);
newdrive[1] = wxT(':');
#ifdef __OS2__
newdrive[2] = wxT('\\');
newdrive[3] = wxT('\0');
#else
newdrive[2] = wxT('\0');
#endif
#if defined(__WXMSW__)
if (::SetCurrentDirectory(newdrive))
#else
// VA doesn't know what LPSTR is and has its own set
if (!DosSetCurrentDir((PSZ)newdrive))
#endif
return 0;
else
return -1;
#endif // !GNUWIN32
}
bool wxIsDriveAvailable(const wxString& WXUNUSED_IN_WINCE(dirName))
{
#ifdef __WXWINCE__
return false;
#else
#ifdef __WIN32__
UINT errorMode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
#endif
bool success = true;
// Check if this is a root directory and if so,
// whether the drive is available.
if (dirName.Len() == 3 && dirName[(size_t)1] == wxT(':'))
{
wxString dirNameLower(dirName.Lower());
#if defined(__GNUWIN32__) && !(defined(__MINGW32_MAJOR_VERSION) && __MINGW32_MAJOR_VERSION >= 1)
success = wxDirExists(dirNameLower);
#else
#if defined(__OS2__)
// Avoid changing to drive since no media may be inserted.
if (dirNameLower[(size_t)0] == 'a' || dirNameLower[(size_t)0] == 'b')
return success;
#endif
int currentDrive = _getdrive();
int thisDrive = (int) (dirNameLower[(size_t)0] - 'a' + 1) ;
int err = setdrive( thisDrive ) ;
setdrive( currentDrive );
if (err == -1)
{
success = false;
}
#endif
}
#ifdef __WIN32__
(void) SetErrorMode(errorMode);
#endif
return success;
#endif
}
#endif // __WINDOWS__ || __OS2__
#endif // wxUSE_DIRDLG || wxUSE_FILEDLG
#if wxUSE_DIRDLG
// Function which is called by quick sort. We want to override the default wxArrayString behaviour,
// and sort regardless of case.
static int wxCMPFUNC_CONV wxDirCtrlStringCompareFunction(const wxString& strFirst, const wxString& strSecond)
{
return strFirst.CmpNoCase(strSecond);
}
//-----------------------------------------------------------------------------
// wxDirItemData
//-----------------------------------------------------------------------------
wxDirItemData::wxDirItemData(const wxString& path, const wxString& name,
bool isDir)
{
m_path = path;
m_name = name;
/* Insert logic to detect hidden files here
* In UnixLand we just check whether the first char is a dot
* For FileNameFromPath read LastDirNameInThisPath ;-) */
// m_isHidden = (bool)(wxFileNameFromPath(*m_path)[0] == '.');
m_isHidden = false;
m_isExpanded = false;
m_isDir = isDir;
}
void wxDirItemData::SetNewDirName(const wxString& path)
{
m_path = path;
m_name = wxFileNameFromPath(path);
}
bool wxDirItemData::HasSubDirs() const
{
if (m_path.empty())
return false;
wxDir dir;
{
wxLogNull nolog;
if ( !dir.Open(m_path) )
return false;
}
return dir.HasSubDirs();
}
bool wxDirItemData::HasFiles(const wxString& WXUNUSED(spec)) const
{
if (m_path.empty())
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?