X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/33ddeabab99a7895d7763390f3761c5ccb1f094c..424da8bdb9f05243d8888d78a56ab0cc3f615a6c:/src/generic/dirctrlg.cpp diff --git a/src/generic/dirctrlg.cpp b/src/generic/dirctrlg.cpp index 78e5a7f7c2..a87c0812ca 100644 --- a/src/generic/dirctrlg.cpp +++ b/src/generic/dirctrlg.cpp @@ -40,6 +40,7 @@ #include "wx/module.h" #endif +#include "wx/filename.h" #include "wx/filefn.h" #include "wx/imaglist.h" #include "wx/tokenzr.h" @@ -108,7 +109,7 @@ bool wxIsDriveAvailable(const wxString& dirName); size_t wxGetAvailableDrives(wxArrayString &paths, wxArrayString &names, wxArrayInt &icon_ids) { -#if defined(__WINDOWS__) || defined(__DOS__) || defined(__OS2__) +#ifdef wxHAS_FILESYSTEM_VOLUMES #ifdef __WXWINCE__ // No logical drives; return "\" @@ -164,9 +165,10 @@ size_t wxGetAvailableDrives(wxArrayString &paths, wxArrayString &names, wxArrayI { if (ulDriveMap & ( 1 << i )) { - wxString path, name; - path.Printf(wxT("%c:\\"), 'A' + i); - name.Printf(wxT("%c:"), 'A' + i); + const wxString path = wxFileName::GetVolumeString( + 'A' + i, wxPATH_GET_SEPARATOR); + const wxString name = wxFileName::GetVolumeString( + 'A' + i, wxPATH_NO_SEPARATOR); // Note: If _filesys is unsupported by some compilers, // we can always replace it by DosQueryFSAttach @@ -201,25 +203,23 @@ size_t wxGetAvailableDrives(wxArrayString &paths, wxArrayString &names, wxArrayI } } #else // !__WIN32__, !__OS2__ - int drive; - /* If we can switch to the drive, it exists. */ - for( drive = 1; drive <= 26; drive++ ) + for ( char drive = 'A'; drive <= 'Z'; drive++ ) { - wxString path, name; - path.Printf(wxT("%c:\\"), (char) (drive + 'a' - 1)); - name.Printf(wxT("%c:"), (char) (drive + 'A' - 1)); + const wxString + path = wxFileName::GetVolumeString(drive, wxPATH_GET_SEPARATOR); if (wxIsDriveAvailable(path)) { paths.Add(path); - names.Add(name); - icon_ids.Add((drive <= 2) ? wxFileIconsTable::floppy : wxFileIconsTable::drive); + names.Add(wxFileName::GetVolumeString(drive, wxPATH_NO_SEPARATOR)); + icon_ids.Add(drive <= 2 ? wxFileIconsTable::floppy + : wxFileIconsTable::drive); } } #endif // __WIN32__/!__WIN32__ -#elif defined(__WXMAC__) +#elif defined(__WXMAC__) && wxOSX_USE_COCOA_OR_CARBON ItemCount volumeIndex = 1; OSErr err = noErr ; @@ -472,6 +472,7 @@ wxBEGIN_FLAGS( wxGenericDirCtrlStyle ) wxFLAGS_MEMBER(wxDIRCTRL_DIR_ONLY) wxFLAGS_MEMBER(wxDIRCTRL_3D_INTERNAL) wxFLAGS_MEMBER(wxDIRCTRL_SELECT_FIRST) + wxFLAGS_MEMBER(wxDIRCTRL_MULTIPLE) wxEND_FLAGS( wxGenericDirCtrlStyle ) @@ -560,6 +561,9 @@ bool wxGenericDirCtrl::Create(wxWindow *parent, if (style & wxDIRCTRL_EDIT_LABELS) treeStyle |= wxTR_EDIT_LABELS; + if (style & wxDIRCTRL_MULTIPLE) + treeStyle |= wxTR_MULTIPLE; + if ((style & wxDIRCTRL_3D_INTERNAL) == 0) treeStyle |= wxNO_BORDER; @@ -629,9 +633,22 @@ void wxGenericDirCtrl::ShowHidden( bool show ) m_showHidden = show; - wxString path = GetPath(); - ReCreateTree(); - SetPath(path); + if ( HasFlag(wxDIRCTRL_MULTIPLE) ) + { + wxArrayString paths; + GetPaths(paths); + ReCreateTree(); + for ( unsigned n = 0; n < paths.size(); n++ ) + { + ExpandPath(paths[n]); + } + } + else + { + wxString path = GetPath(); + ReCreateTree(); + SetPath(path); + } } const wxTreeItemId @@ -744,14 +761,9 @@ void wxGenericDirCtrl::OnExpandItem(wxTreeEvent &event) // ctor when wxTR_HIDE_ROOT was specified if (!m_rootId.IsOk()) - m_rootId = m_treeCtrl->GetRootItem(); ExpandDir(parentId); - if ( m_treeCtrl->GetChildrenCount(parentId, false) == 0 ) - { - m_treeCtrl->SetItemHasChildren(parentId, false); - } } void wxGenericDirCtrl::OnCollapseItem(wxTreeEvent &event ) @@ -768,22 +780,15 @@ void wxGenericDirCtrl::CollapseDir(wxTreeItemId parentId) return; data->m_isExpanded = false; - wxTreeItemIdValue cookie; - /* Workaround because DeleteChildren has disapeared (why?) and - * CollapseAndReset doesn't work as advertised (deletes parent too) */ - child = m_treeCtrl->GetFirstChild(parentId, cookie); - while (child.IsOk()) - { - m_treeCtrl->Delete(child); - /* Not GetNextChild below, because the cookie mechanism can't - * handle disappearing children! */ - child = m_treeCtrl->GetFirstChild(parentId, cookie); - } + + m_treeCtrl->Freeze(); if (parentId != m_treeCtrl->GetRootItem()) - m_treeCtrl->Collapse(parentId); + m_treeCtrl->CollapseAndReset(parentId); + m_treeCtrl->DeleteChildren(parentId); + m_treeCtrl->Thaw(); } -void wxGenericDirCtrl::ExpandDir(wxTreeItemId parentId) +void wxGenericDirCtrl::PopulateNode(wxTreeItemId parentId) { wxDirItemData *data = (wxDirItemData *) m_treeCtrl->GetItemData(parentId); @@ -882,6 +887,10 @@ void wxGenericDirCtrl::ExpandDir(wxTreeItemId parentId) filenames.Sort(wxDirCtrlStringCompareFunction); } + // Now we really know whether we have any children so tell the tree control + // about it. + m_treeCtrl->SetItemHasChildren(parentId, !dirs.empty() || !filenames.empty()); + // Add the sorted dirs size_t i; for (i = 0; i < dirs.GetCount(); i++) @@ -901,7 +910,7 @@ void wxGenericDirCtrl::ExpandDir(wxTreeItemId parentId) // assume that it does have children by default as it can take a long // time to really check for this (think remote drives...) // - // and if we're wrong, we'll correct it later in OnExpandItem() if + // and if we're wrong, we'll correct the icon later if // the user really tries to open this item m_treeCtrl->SetItemHasChildren(id); } @@ -926,6 +935,12 @@ void wxGenericDirCtrl::ExpandDir(wxTreeItemId parentId) } } +void wxGenericDirCtrl::ExpandDir(wxTreeItemId parentId) +{ + // ExpandDir() will not actually expand the tree node, just populate it + PopulateNode(parentId); +} + void wxGenericDirCtrl::ReCreateTree() { CollapseDir(m_treeCtrl->GetRootItem()); @@ -1085,6 +1100,22 @@ bool wxGenericDirCtrl::CollapsePath(const wxString& path) wxString wxGenericDirCtrl::GetPath() const { + // Allow calling GetPath() in multiple selection from OnSelFilter + if (m_treeCtrl->HasFlag(wxTR_MULTIPLE)) + { + wxArrayTreeItemIds items; + m_treeCtrl->GetSelections(items); + if (items.size() > 0) + { + // return first string only + wxTreeItemId id = items[0]; + wxDirItemData* data = (wxDirItemData*) m_treeCtrl->GetItemData(id); + return data->m_path; + } + + return wxEmptyString; + } + wxTreeItemId id = m_treeCtrl->GetSelection(); if (id) { @@ -1095,6 +1126,20 @@ wxString wxGenericDirCtrl::GetPath() const return wxEmptyString; } +void wxGenericDirCtrl::GetPaths(wxArrayString& paths) const +{ + paths.clear(); + + wxArrayTreeItemIds items; + m_treeCtrl->GetSelections(items); + for ( unsigned n = 0; n < items.size(); n++ ) + { + wxTreeItemId id = items[n]; + wxDirItemData* data = (wxDirItemData*) m_treeCtrl->GetItemData(id); + paths.Add(data->m_path); + } +} + wxString wxGenericDirCtrl::GetFilePath() const { wxTreeItemId id = m_treeCtrl->GetSelection(); @@ -1110,6 +1155,21 @@ wxString wxGenericDirCtrl::GetFilePath() const return wxEmptyString; } +void wxGenericDirCtrl::GetFilePaths(wxArrayString& paths) const +{ + paths.clear(); + + wxArrayTreeItemIds items; + m_treeCtrl->GetSelections(items); + for ( unsigned n = 0; n < items.size(); n++ ) + { + wxTreeItemId id = items[n]; + wxDirItemData* data = (wxDirItemData*) m_treeCtrl->GetItemData(id); + if ( !data->m_isDir ) + paths.Add(data->m_path); + } +} + void wxGenericDirCtrl::SetPath(const wxString& path) { m_defaultPath = path; @@ -1117,6 +1177,43 @@ void wxGenericDirCtrl::SetPath(const wxString& path) ExpandPath(path); } +void wxGenericDirCtrl::SelectPath(const wxString& path, bool select) +{ + bool done = false; + wxTreeItemId id = FindChild(m_rootId, path, done); + wxTreeItemId lastId = id; // The last non-zero id + while ( id.IsOk() && !done ) + { + id = FindChild(id, path, done); + if ( id.IsOk() ) + lastId = id; + } + if ( !lastId.IsOk() ) + return; + + if ( done ) + { + m_treeCtrl->SelectItem(id, select); + } +} + +void wxGenericDirCtrl::SelectPaths(const wxArrayString& paths) +{ + if ( HasFlag(wxDIRCTRL_MULTIPLE) ) + { + UnselectAll(); + for ( unsigned n = 0; n < paths.size(); n++ ) + { + SelectPath(paths[n]); + } + } +} + +void wxGenericDirCtrl::UnselectAll() +{ + m_treeCtrl->UnselectAll(); +} + // Not used #if 0 void wxGenericDirCtrl::FindChildFiles(wxTreeItemId id, int dirFlags, wxArrayString& filenames) @@ -1303,16 +1400,33 @@ void wxDirFilterListCtrl::OnSelFilter(wxCommandEvent& WXUNUSED(event)) { int sel = GetSelection(); - wxString currentPath = m_dirCtrl->GetPath(); + if (m_dirCtrl->HasFlag(wxDIRCTRL_MULTIPLE)) + { + wxArrayString paths; + m_dirCtrl->GetPaths(paths); - m_dirCtrl->SetFilterIndex(sel); + m_dirCtrl->SetFilterIndex(sel); - // If the filter has changed, the view is out of date, so - // collapse the tree. - m_dirCtrl->ReCreateTree(); + // If the filter has changed, the view is out of date, so + // collapse the tree. + m_dirCtrl->ReCreateTree(); - // Try to restore the selection, or at least the directory - m_dirCtrl->ExpandPath(currentPath); + // Expand and select the previously selected paths + for (unsigned int i = 0; i < paths.GetCount(); i++) + { + m_dirCtrl->ExpandPath(paths.Item(i)); + } + } + else + { + wxString currentPath = m_dirCtrl->GetPath(); + + m_dirCtrl->SetFilterIndex(sel); + m_dirCtrl->ReCreateTree(); + + // Try to restore the selection, or at least the directory + m_dirCtrl->ExpandPath(currentPath); + } } void wxDirFilterListCtrl::FillFilterList(const wxString& filter, int defaultFilter) @@ -1338,7 +1452,7 @@ void wxDirFilterListCtrl::FillFilterList(const wxString& filter, int defaultFilt #ifndef __WXGTK20__ /* Computer (c) Julian Smart */ -static const char * file_icons_tbl_computer_xpm[] = { +static const char* const file_icons_tbl_computer_xpm[] = { /* columns rows colors chars-per-pixel */ "16 16 42 1", "r c #4E7FD0", @@ -1408,7 +1522,7 @@ static const char * file_icons_tbl_computer_xpm[] = { // ---------------------------------------------------------------------------- // global instance of a wxFileIconsTable -wxFileIconsTable* wxTheFileIconsTable = (wxFileIconsTable *)NULL; +wxFileIconsTable* wxTheFileIconsTable = NULL; // A module to allow icons table cleanup @@ -1420,11 +1534,7 @@ public: bool OnInit() { wxTheFileIconsTable = new wxFileIconsTable; return true; } void OnExit() { - if (wxTheFileIconsTable) - { - delete wxTheFileIconsTable; - wxTheFileIconsTable = NULL; - } + wxDELETE(wxTheFileIconsTable); } }; @@ -1499,14 +1609,14 @@ void wxFileIconsTable::Create() wxART_CMN_DIALOG, wxSize(16, 16))); // executable - if (GetIconID(wxEmptyString, _T("application/x-executable")) == file) + if (GetIconID(wxEmptyString, wxT("application/x-executable")) == file) { m_smallImageList->Add(wxArtProvider::GetBitmap(wxART_EXECUTABLE_FILE, wxART_CMN_DIALOG, wxSize(16, 16))); - delete m_HashTable->Get(_T("exe")); - m_HashTable->Delete(_T("exe")); - m_HashTable->Put(_T("exe"), new wxFileIconEntry(executable)); + delete m_HashTable->Get(wxT("exe")); + m_HashTable->Delete(wxT("exe")); + m_HashTable->Put(wxT("exe"), new wxFileIconEntry(executable)); } /* else put into list by GetIconID (KDE defines application/x-executable for *.exe and has nice icon)