filedlgg.cpp

来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 1,603 行 · 第 1/4 页

CPP
1,603
字号
//////////////////////////////////////////////////////////////////////////////
// Name:        filedlgg.cpp
// Purpose:     wxGenericFileDialog
// Author:      Robert Roebling
// Modified by:
// Created:     12/12/98
// RCS-ID:      $Id: filedlgg.cpp,v 1.143.2.2 2006/03/06 10:44:48 JS Exp $
// Copyright:   (c) Robert Roebling
// Licence:     wxWindows licence
/////////////////////////////////////////////////////////////////////////////

#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
#pragma implementation "filedlgg.h"
#endif

// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"

#ifdef __BORLANDC__
#pragma hdrstop
#endif

#if wxUSE_FILEDLG

// NOTE : it probably also supports MAC, untested
#if !defined(__UNIX__) && !defined(__DOS__) && !defined(__WIN32__) && !defined(__OS2__)
#error wxGenericFileDialog currently only supports Unix, win32 and DOS
#endif

#include "wx/checkbox.h"
#include "wx/textctrl.h"
#include "wx/choice.h"
#include "wx/checkbox.h"
#include "wx/stattext.h"
#include "wx/debug.h"
#include "wx/log.h"
#include "wx/intl.h"
#include "wx/msgdlg.h"
#include "wx/sizer.h"
#include "wx/bmpbuttn.h"
#include "wx/tokenzr.h"
#include "wx/config.h"
#include "wx/imaglist.h"
#include "wx/dir.h"
#include "wx/artprov.h"
#include "wx/settings.h"
#include "wx/filefn.h"
#include "wx/file.h"        // for wxS_IXXX constants only
#include "wx/filedlg.h"     // wxOPEN, wxSAVE...
#include "wx/generic/filedlgg.h"
#include "wx/generic/dirctrlg.h" // for wxFileIconsTable

#if wxUSE_TOOLTIPS
    #include "wx/tooltip.h"
#endif

#ifndef __WXWINCE__
#include <sys/types.h>
#include <sys/stat.h>
#endif

#ifdef __UNIX__
    #include <dirent.h>
    #include <pwd.h>
    #ifndef __VMS
    # include <grp.h>
    #endif
#endif

#ifdef __WINDOWS__
    #include "wx/msw/wrapwin.h"
    #include "wx/msw/mslu.h"
#endif

#ifdef __WATCOMC__
    #include <direct.h>
#endif

#ifndef __WXWINCE__
#include <time.h>
#endif

#if defined(__UNIX__) || defined(__DOS__)
#include <unistd.h>
#endif

// ----------------------------------------------------------------------------
// private functions
// ----------------------------------------------------------------------------

static
int wxCALLBACK wxFileDataNameCompare( long data1, long data2, long data)
{
     wxFileData *fd1 = (wxFileData*)data1;
     wxFileData *fd2 = (wxFileData*)data2;
     if (fd1->GetFileName() == wxT("..")) return -data;
     if (fd2->GetFileName() == wxT("..")) return data;
     if (fd1->IsDir() && !fd2->IsDir()) return -data;
     if (fd2->IsDir() && !fd1->IsDir()) return data;
     return data*wxStrcmp( fd1->GetFileName(), fd2->GetFileName() );
}

static
int wxCALLBACK wxFileDataSizeCompare( long data1, long data2, long data)
{
     wxFileData *fd1 = (wxFileData*)data1;
     wxFileData *fd2 = (wxFileData*)data2;
     if (fd1->GetFileName() == wxT("..")) return -data;
     if (fd2->GetFileName() == wxT("..")) return data;
     if (fd1->IsDir() && !fd2->IsDir()) return -data;
     if (fd2->IsDir() && !fd1->IsDir()) return data;
     if (fd1->IsLink() && !fd2->IsLink()) return -data;
     if (fd2->IsLink() && !fd1->IsLink()) return data;
     return data*(fd1->GetSize() - fd2->GetSize());
}

static
int wxCALLBACK wxFileDataTypeCompare( long data1, long data2, long data)
{
     wxFileData *fd1 = (wxFileData*)data1;
     wxFileData *fd2 = (wxFileData*)data2;
     if (fd1->GetFileName() == wxT("..")) return -data;
     if (fd2->GetFileName() == wxT("..")) return data;
     if (fd1->IsDir() && !fd2->IsDir()) return -data;
     if (fd2->IsDir() && !fd1->IsDir()) return data;
     if (fd1->IsLink() && !fd2->IsLink()) return -data;
     if (fd2->IsLink() && !fd1->IsLink()) return data;
     return data*wxStrcmp( fd1->GetFileType(), fd2->GetFileType() );
}

static
int wxCALLBACK wxFileDataTimeCompare( long data1, long data2, long data)
{
     wxFileData *fd1 = (wxFileData*)data1;
     wxFileData *fd2 = (wxFileData*)data2;
     if (fd1->GetFileName() == wxT("..")) return -data;
     if (fd2->GetFileName() == wxT("..")) return data;
     if (fd1->IsDir() && !fd2->IsDir()) return -data;
     if (fd2->IsDir() && !fd1->IsDir()) return data;

     return fd1->GetDateTime().IsLaterThan(fd2->GetDateTime()) ? int(data) : -int(data);
}

#if defined(__WXWINCE__)
#define IsTopMostDir(dir) (dir == wxT("\\") || dir == wxT("/"))
#elif (defined(__DOS__) || defined(__WINDOWS__) || defined (__OS2__))
#define IsTopMostDir(dir)   (dir.empty())
#else
#define IsTopMostDir(dir)   (dir == wxT("/"))
#endif

// defined in src/generic/dirctrlg.cpp
extern size_t wxGetAvailableDrives(wxArrayString &paths, wxArrayString &names, wxArrayInt &icon_ids);

//-----------------------------------------------------------------------------
//  wxFileData
//-----------------------------------------------------------------------------

wxFileData::wxFileData( const wxString &filePath, const wxString &fileName, fileType type, int image_id )
{
    Init();
    m_fileName = fileName;
    m_filePath = filePath;
    m_type = type;
    m_image = image_id;

    ReadData();
}

void wxFileData::Init()
{
    m_size = 0;
    m_type = wxFileData::is_file;
    m_image = wxFileIconsTable::file;
}

void wxFileData::Copy( const wxFileData& fileData )
{
    m_fileName = fileData.GetFileName();
    m_filePath = fileData.GetFilePath();
    m_size = fileData.GetSize();
    m_dateTime = fileData.GetDateTime();
    m_permissions = fileData.GetPermissions();
    m_type = fileData.GetType();
    m_image = fileData.GetImageId();
}

void wxFileData::ReadData()
{
    if (IsDrive())
    {
        m_size = 0;
        return;
    }

#if defined(__DOS__) || (defined(__WINDOWS__) && !defined(__WXWINCE__)) || defined(__OS2__)
    // c:\.. is a drive don't stat it
    if ((m_fileName == wxT("..")) && (m_filePath.length() <= 5))
    {
        m_type = is_drive;
        m_size = 0;
        return;
    }
#endif // __DOS__ || __WINDOWS__

#ifdef __WXWINCE__

    // WinCE

    DWORD fileAttribs = GetFileAttributes(m_filePath.fn_str());
    m_type |= (fileAttribs & FILE_ATTRIBUTE_DIRECTORY) != 0 ? is_dir : 0;

    wxString p, f, ext;
    wxSplitPath(m_filePath, & p, & f, & ext);
    if (wxStricmp(ext, wxT("exe")) == 0)
        m_type |= is_exe;

    // Find out size
    m_size = 0;
    HANDLE fileHandle = CreateFile(m_filePath.fn_str(),
            GENERIC_READ,
            FILE_SHARE_READ,
            NULL,
            OPEN_EXISTING,
            FILE_ATTRIBUTE_NORMAL,
            NULL);

    if (fileHandle != INVALID_HANDLE_VALUE)
    { 
        m_size = GetFileSize(fileHandle, 0);
        CloseHandle(fileHandle);
    }

    m_dateTime = wxFileModificationTime(m_filePath);

#else

    // OTHER PLATFORMS

    wxStructStat buff;

#if defined(__UNIX__) && (!defined( __OS2__ ) && !defined(__VMS))
    lstat( m_filePath.fn_str(), &buff );
    m_type |= S_ISLNK( buff.st_mode ) != 0 ? is_link : 0;
#else // no lstat()
    // only translate to file charset if we don't go by our
    // wxStat implementation
#ifndef wxNEED_WX_UNISTD_H
    wxStat( m_filePath.fn_str() , &buff );
#else
    wxStat( m_filePath, &buff );
#endif
#endif

    m_type |= (buff.st_mode & S_IFDIR) != 0 ? is_dir : 0;
    m_type |= (buff.st_mode & wxS_IXUSR) != 0 ? is_exe : 0;
    m_size = (long)buff.st_size;

    m_dateTime = buff.st_mtime;
#endif
    // __WXWINCE__

#if defined(__UNIX__)
    m_permissions.Printf(_T("%c%c%c%c%c%c%c%c%c"),
                         buff.st_mode & wxS_IRUSR ? _T('r') : _T('-'),
                         buff.st_mode & wxS_IWUSR ? _T('w') : _T('-'),
                         buff.st_mode & wxS_IXUSR ? _T('x') : _T('-'),
                         buff.st_mode & wxS_IRGRP ? _T('r') : _T('-'),
                         buff.st_mode & wxS_IWGRP ? _T('w') : _T('-'),
                         buff.st_mode & wxS_IXGRP ? _T('x') : _T('-'),
                         buff.st_mode & wxS_IROTH ? _T('r') : _T('-'),
                         buff.st_mode & wxS_IWOTH ? _T('w') : _T('-'),
                         buff.st_mode & wxS_IXOTH ? _T('x') : _T('-'));
#elif defined(__WIN32__)
    DWORD attribs = GetFileAttributes(m_filePath.fn_str());
    if (attribs != (DWORD)-1)
    {
        m_permissions.Printf(_T("%c%c%c%c"),
                             attribs & FILE_ATTRIBUTE_ARCHIVE  ? _T('A') : _T(' '),
                             attribs & FILE_ATTRIBUTE_READONLY ? _T('R') : _T(' '),
                             attribs & FILE_ATTRIBUTE_HIDDEN   ? _T('H') : _T(' '),
                             attribs & FILE_ATTRIBUTE_SYSTEM   ? _T('S') : _T(' '));
    }
#endif

    // try to get a better icon
    if (m_image == wxFileIconsTable::file)
    {
        if (m_fileName.Find(wxT('.'), true) != wxNOT_FOUND)
        {
            m_image = wxTheFileIconsTable->GetIconID( m_fileName.AfterLast(wxT('.')));
        } else if (IsExe())
        {
            m_image = wxFileIconsTable::executable;
        }
    }
}

wxString wxFileData::GetFileType() const
{
    if (IsDir())
        return _("<DIR>");
    else if (IsLink())
        return _("<LINK>");
    else if (IsDrive())
        return _("<DRIVE>");
    else if (m_fileName.Find(wxT('.'), true) != wxNOT_FOUND)
        return m_fileName.AfterLast(wxT('.'));

    return wxEmptyString;
}

wxString wxFileData::GetModificationTime() const
{
    // want time as 01:02 so they line up nicely, no %r in WIN32
    return m_dateTime.FormatDate() + wxT(" ") + m_dateTime.Format(wxT("%I:%M:%S %p"));
}

wxString wxFileData::GetHint() const
{
    wxString s = m_filePath;
    s += wxT("  ");

    if (IsDir())
        s += _("<DIR>");
    else if (IsLink())
        s += _("<LINK>");
    else if (IsDrive())
        s += _("<DRIVE>");
    else // plain file
        s += wxString::Format( _("%ld bytes"), m_size );

    s += wxT(' ');

    if ( !IsDrive() )
    {
        s << GetModificationTime()
          << wxT("  ")
          << m_permissions;
    }

    return s;
};

wxString wxFileData::GetEntry( fileListFieldType num ) const
{
    wxString s;
    switch ( num )
    {
        case FileList_Name:
            s = m_fileName;
            break;

        case FileList_Size:
            if (!IsDir() && !IsLink() && !IsDrive())
                s.Printf(_T("%ld"), m_size);
            break;

        case FileList_Type:
            s = GetFileType();
            break;

        case FileList_Time:
            if (!IsDrive())
                s = GetModificationTime();
            break;

#if defined(__UNIX__) || defined(__WIN32__)
        case FileList_Perm:
            s = m_permissions;
            break;
#endif // defined(__UNIX__) || defined(__WIN32__)

        default:
            wxFAIL_MSG( _T("unexpected field in wxFileData::GetEntry()") );
    }

    return s;
}

void wxFileData::SetNewName( const wxString &filePath, const wxString &fileName )
{
    m_fileName = fileName;
    m_filePath = filePath;
}

void wxFileData::MakeItem( wxListItem &item )
{
    item.m_text = m_fileName;
    item.ClearAttributes();
    if (IsExe())
        item.SetTextColour(*wxRED);
    if (IsDir())
        item.SetTextColour(*wxBLUE);

    item.m_image = m_image;

    if (IsLink())
    {
        wxColour dg = wxTheColourDatabase->Find( _T("MEDIUM GREY") );
        if ( dg.Ok() )

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?