///////////////////////////////////////////////////////////////////////////// // Name: filebrws.cpp // Author: John Labenski // Created: 07/01/02 // Copyright: John Labenski, 2002 // License: wxWidgets ///////////////////////////////////////////////////////////////////////////// #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) #pragma implementation "filebrws.h" #endif // For compilers that support precompilation, includes "wx/wx.h". #include "wx/wxprec.h" #ifdef __BORLANDC__ #pragma hdrstop #endif #ifndef WX_PRECOMP #include "wx/wx.h" #endif // WX_PRECOMP #include "wx/mimetype.h" #include "wx/tglbtn.h" // for EVT_TOGGLE_BUTTON #include "wx/splitter.h" #include "wx/imaglist.h" #include "wx/confbase.h" #include "wx/filename.h" #include "wx/dir.h" #include "wx/artprov.h" #include "wx/image.h" // wxInitAllImageHandlers #include "wx/renderer.h" #include "wx/file.h" #include "wx/txtstrm.h" #include "wx/wfstream.h" #include "wx/filefn.h" // wxStat #include "wx/things/filebrws.h" #include "wx/arrimpl.cpp" WX_DEFINE_OBJARRAY(wxArrayFileData); // #include "wx/stedit/stedit.h" // defined in src/generic/dirctrlg.cpp extern size_t wxGetAvailableDrives(wxArrayString &paths, wxArrayString &names, wxArrayInt &icon_ids); #define BORDER 5 #define MIN_SPLIT 8 //------------------------------------------------------------------------------ // constants //------------------------------------------------------------------------------ enum { ID_wxFILEBROWSER_PATH_COMBO = 100, ID_wxFILEBROWSER_PATH_BUTTON, ID_wxFILEBROWSER_DIRCTRL, ID_wxFILEBROWSER_LISTCTRL, ID_wxFLEBROWSER_VIEW_TOOLBAR, ID_wxFLEBROWSER_PATH_TOOLBAR, ID_wxFILEBROWSER_FILTER_COMBO, ID_wxFILEBROWSER_VIEW_BUTTON, ID_wxFILEBROWSER_VIEW_TREE, ID_wxFILEBROWSER_VIEW_LIST, ID_wxFILEBROWSER_VIEW_DETAILS, ID_wxFILEBROWSER_VIEW_SMALL_ICON, ID_wxFILEBROWSER_VIEW_LARGE_ICON, ID_wxFILEBROWSER_VIEW_PREVIEW, ID_wxFILEBROWSER_GO_BACK, ID_wxFILEBROWSER_GO_FORWARD, ID_wxFILEBROWSER_GO_UP, ID_wxFILEBROWSER_GO_HOME, ID_wxFILEBROWSER_REFRESH, ID_wxFILEBROWSER_TREE_MENU_PROPERITES, ID_wxFILEBROWSER_LIST_MENU_VIEW_FILE, ID_wxFILEBROWSER_LIST_MENU_OPEN_WITH, ID_wxFILEBROWSER_LIST_MENU_NEW_FOLDER, ID_wxFILEBROWSER_LIST_MENU_DELETE, ID_wxFILEBROWSER_LIST_MENU_RENAME, ID_wxFILEBROWSER_LIST_MENU_PROPERITES, ID_wxFILEBROWSER_LIST_MENU_OPTIONS, ID_wxFILEBROWSER_SHOW_HIDDEN, ID_wxFILEBROWSER_SHOW_FOLDERS, ID_wxFILEBROWSER_SPLIT_VERTICAL, ID_wxFILEBROWSER_COMBOSETPATH, // for delayed setting path to get out of combo event for Gtk ID_wxFILEBROWSER_COMBOSETFILTER }; int wxFileBrowser::FBStyleToLCStyle(int s) const // wxFileBrowserStyles_Type to wxLC_XXX { return (s)&wxFILEBROWSER_TREE ? wxLC_REPORT : (s)&wxFILEBROWSER_LIST ? wxLC_LIST : (s)&wxFILEBROWSER_DETAILS ? wxLC_REPORT : (s)&wxFILEBROWSER_SMALL_ICON ? wxLC_SMALL_ICON : (s)&wxFILEBROWSER_LARGE_ICON ? wxLC_ICON : (s)&wxFILEBROWSER_PREVIEW ? wxLC_ICON : wxLC_REPORT; } int wxFileBrowser::FBStyleToMenuID(int s) const // wxFileBrowserStyles_Type menu id { return (s)&wxFILEBROWSER_TREE ? ID_wxFILEBROWSER_VIEW_TREE : (s)&wxFILEBROWSER_LIST ? ID_wxFILEBROWSER_VIEW_LIST : (s)&wxFILEBROWSER_DETAILS ? ID_wxFILEBROWSER_VIEW_DETAILS : (s)&wxFILEBROWSER_SMALL_ICON ? ID_wxFILEBROWSER_VIEW_SMALL_ICON : (s)&wxFILEBROWSER_LARGE_ICON ? ID_wxFILEBROWSER_VIEW_LARGE_ICON : (s)&wxFILEBROWSER_PREVIEW ? ID_wxFILEBROWSER_VIEW_PREVIEW : ID_wxFILEBROWSER_VIEW_DETAILS; } int wxFileBrowser::MenuIDToFBStyle(int id) const // menu id to wxFileBrowserStyles_Type { return (id)==ID_wxFILEBROWSER_VIEW_TREE ? wxFILEBROWSER_TREE : (id)==ID_wxFILEBROWSER_VIEW_LIST ? wxFILEBROWSER_LIST : (id)==ID_wxFILEBROWSER_VIEW_DETAILS ? wxFILEBROWSER_DETAILS : (id)==ID_wxFILEBROWSER_VIEW_SMALL_ICON ? wxFILEBROWSER_SMALL_ICON : (id)==ID_wxFILEBROWSER_VIEW_LARGE_ICON ? wxFILEBROWSER_LARGE_ICON : (id)==ID_wxFILEBROWSER_VIEW_PREVIEW ? wxFILEBROWSER_PREVIEW : wxFILEBROWSER_DETAILS; } //============================================================================ // Button Icons //============================================================================ /* XPM */ /* static const char *view_xpm_data[] = { // columns rows colors chars-per-pixel "16 16 4 1", "a c Black", "b c #0000FF", "c c #FFFFFF", "d c #808080", // pixels "aaaaaaaaaaaaaaaa", "abbbbbbbbbbbbbba", "abbbbbbbbbbbbbba", "aaaaaaaaaaaaaaaa", "adddddddddddddda", "acccccccccccccca", "acbbccccbbccccca", "acbbaaacbbaaacca", "acccccccccccccca", "acbbccccbbccccca", "acbbaaacbbaaacca", "acccccccccccccca", "acbbccccbbccccca", "acbbaaacbbaaacca", "acccccccccccccca", "aaaaaaaaaaaaaaaa"}; static const char *details_xpm_data[]={ "16 15 4 1", "# c None", "a c #000000", "b c #000080", ". c #c0c0c0", "################", "###aaaa#aaa#aaa#", "################", "bbbbbbbbbbbbbbbb", "################", "b##aaaa#aaa#aaa#", "################", "b##aaaa#aaa#aaa#", "################", "b##aaaa#aaa#aaa#", "################", "b##aaaa#aaa#aaa#", "################", "b##aaaa#aaa#aaa#", "################"}; static const char *list_xpm_data[]={ "16 15 4 1", ". c None", "b c #000000", "# c #000080", "a c #ffffff", "................", "##......##......", "#a#.bbb.#a#.bbb.", "###.....###.....", "................", "................", "##......##......", "#a#.bbb.#a#.bbb.", "###.....###.....", "................", "................", "##......##......", "#a#.bbb.#a#.bbb.", "###.....###.....", "................"}; static const char *large_icons_xpm_data[]={ "16 15 4 1", ". c None", "b c #000000", "# c #000080", "a c #ffffff", "................", "..###...........", "..#a##..........", "..#aa#..........", "..#aa#..........", "..####..........", "................", ".bbbbbb...###...", "..........#a##..", "..........#aa#..", "..........#aa#..", "..........####..", "................", ".........bbbbbb.", "................"}; static const char *small_icons_xpm_data[]={ "16 15 4 1", ". c None", "b c #000000", "# c #000080", "a c #ffffff", "................", ".##.............", ".#a#.bbb........", ".###............", "................", "................", "........##......", "........#a#.bbb.", "........###.....", "................", "................", "...##...........", "...#a#.bbb......", "...###..........", "................"}; static const char *tree_xpm_data[]={ "16 15 4 1", ". c None", "# c #000000", "a c #ffff00", "b c #ffffff", ".#aa#...........", ".#a##...........", "..#.............", "..####aa#.......", ".....#a##.......", "......#.........", "......####b#b#..", "......#..#b#b#..", "......#.........", "......####b#b#..", "......#..#b#b#..", "......#.........", ".......###b#b#..", ".........#b#b#..", "................"}; static const char *preview_xpm_data[]={ "16 15 14 1", ". c None", "k c #000080", "l c #0058c0", "g c #0080ff", "e c #585858", "c c #808080", "b c #89562f", "f c #a0a0a0", "h c #a86a3a", "j c #bd7741", "i c #d48549", "# c #ff0000", "a c #ffff00", "d c #ffffff", ".......###......", ".a..a..bc.#.....", "..aa...bdc......", "..aa..cbddc.....", ".a..acdbdddc....", "....cddbddddc...", "....eddbddddf...", "....eddbdddddf..", ".....edbddddff..", "..g.hiijiiih.g..", ".gggghiiiihgggg.", ".kllllhhhhggllk.", ".llllllllllllll.", ".kklkllklklklkk.", "................"}; static const char *hidden_xpm_data[] = { "16 15 7 1", " c None", "a c Black", "b c #EFBE1B", "d c #F6F0B4", "e c #FFEF7D", "f c #FBD915", "g c #8E8220", " ", " aaa ", " addfa ", " adffffa ", " adfdadba ", " affaaabga ", " aedadbga ", " adfbbbgga ", " adfbaggga ", " adfba aaa ", " adfba ", " adfbgga ", " abbaga ", " aa a ", " "}; */ wxBitmap GetBitmapFromIconId(int imageId) { return wxTheFileIconsTable->GetSmallImageList()->GetBitmap(imageId); } // ---------------------------------------------------------------------------- // CopyDir - copy a full directory recursively, returns # files copied // code taken and modified from wxWidgets forum, by "Tyler" - public domain // ---------------------------------------------------------------------------- int CopyDir(const wxString& fromDir, const wxString& toDir) { wxString from(fromDir), to(toDir); if (!from.length() || !to.length()) return false; // append a slash if there is not one (for easier parsing) // because who knows what people will pass to the function. if (to[to.length()-1] != wxFILE_SEP_PATH) to += wxFILE_SEP_PATH; if (from[from.length()-1] != wxFILE_SEP_PATH) from += wxFILE_SEP_PATH; // first make sure that the source dir exists if(!wxDir::Exists(from)) { wxLogError(from + wxT(" does not exist. Can not copy directory.")); return 0; } if (!wxDir::Exists(to)) wxMkdir(to); wxDir dir(from); wxString filename; int count = 0; if (dir.GetFirst(&filename)) { do { if (wxDirExists(from + filename)) { wxMkdir(to + filename); count += CopyDir(from + filename, to + filename); } else { wxCopyFile(from + filename, to + filename); count++; } } while (dir.GetNext(&filename)); } return count; } //------------------------------------------------------------------------------ // MultilineTextDialog - makes the wxTextEntryDialog multiline //------------------------------------------------------------------------------ MultilineTextDialog::MultilineTextDialog(wxWindow *parent, const wxString& message, const wxString& caption, const wxString& value, long style, const wxPoint& pos) :wxTextEntryDialog(parent, message, caption, value, style|wxTextEntryDialogStyle|wxTE_MULTILINE, pos) { int height = m_textctrl->GetSize().y; m_textctrl->SetSize(300, 100); height = (100-height > 0) ? 100 - height : 0; wxSize size(GetSize()); SetSize(size.x, size.y+height); Layout(); //m_textctrl->SetEditable(false); } //------------------------------------------------------------------------------ // MultilineTextDialog //------------------------------------------------------------------------------ #define ID_OPENWITH_BROWSE 5 #define ID_OPENWITH_TEXTCTRL 6 class OpenWithDialog : public wxDialog { public: OpenWithDialog(wxWindow* parent, wxWindowID winId, const wxFileData& fileData, const wxString& caption = wxT("Open With"), const wxString& openCommand = wxEmptyString, long style = wxDEFAULT_DIALOG_STYLE, const wxPoint& pos = wxDefaultPosition) : wxDialog(), m_fileData(fileData) { m_textCtrl = NULL; Create(parent, winId, fileData, caption, openCommand, style, pos); } bool Create(wxWindow* parent, wxWindowID winId, const wxFileData& fileData, const wxString& caption = wxT("Open With"), const wxString& openCommand = wxEmptyString, long style = wxDEFAULT_DIALOG_STYLE, const wxPoint& pos = wxDefaultPosition); wxString GetOpenCommand() const { return m_command; } protected: void OnButton(wxCommandEvent& event); wxString m_command; wxFileData m_fileData; wxTextCtrl *m_textCtrl; DECLARE_EVENT_TABLE(); }; BEGIN_EVENT_TABLE(OpenWithDialog, wxDialog) EVT_BUTTON(-1, OpenWithDialog::OnButton) END_EVENT_TABLE() bool OpenWithDialog::Create(wxWindow *parent, wxWindowID winId, const wxFileData& fileData, const wxString& caption, const wxString& openCommand, long style, const wxPoint& pos) { if (!wxDialog::Create(parent, winId, caption, pos, wxDefaultSize, style)) return false; m_fileData = fileData; wxFileName fileName(fileData.GetFilePath()); wxString openCmd = openCommand; wxString description(wxT("Unknown file type")); if (openCmd.IsEmpty()) { wxFileType *fileType = wxTheMimeTypesManager->GetFileTypeFromExtension(fileName.GetExt()); if (fileType) { fileType->GetDescription(&description); openCmd = fileType->GetOpenCommand(fileName.GetFullPath()); } } wxBoxSizer *rootSizer = new wxBoxSizer( wxVERTICAL ); wxStaticText *labelText = new wxStaticText( this, wxID_ANY, wxT("Choose the program to open the file"), wxDefaultPosition, wxDefaultSize, 0 ); rootSizer->Add( labelText, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); wxFlexGridSizer *iconSizer = new wxFlexGridSizer( 2, 0, 0 ); iconSizer->AddGrowableCol( 1 ); wxBitmap iconBitmap = GetBitmapFromIconId(m_fileData.GetImageId()); wxStaticBitmap *staticBitmap = new wxStaticBitmap( this, wxID_ANY, iconBitmap, wxDefaultPosition, wxDefaultSize ); iconSizer->Add( staticBitmap, 0, wxALIGN_CENTER|wxALL, 5 ); wxStaticText *nameText = new wxStaticText( this, wxID_ANY, fileName.GetFullPath(), wxDefaultPosition, wxDefaultSize, 0 ); iconSizer->Add( nameText, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); iconSizer->AddSpacer(5); wxStaticText *descripText = new wxStaticText( this, wxID_ANY, description, wxDefaultPosition, wxDefaultSize, 0 ); iconSizer->Add( descripText, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); rootSizer->Add( iconSizer, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); wxStaticBox *staticBox = new wxStaticBox( this, wxID_ANY, wxT("Program") ); wxStaticBoxSizer *staticBoxSizer = new wxStaticBoxSizer( staticBox, wxVERTICAL ); m_textCtrl = new wxTextCtrl( this, ID_OPENWITH_TEXTCTRL, openCmd, wxDefaultPosition, wxSize(400,-1), 0 ); staticBoxSizer->Add( m_textCtrl, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); wxFlexGridSizer *browseSizer = new wxFlexGridSizer( 2, 0, 0 ); browseSizer->AddGrowableCol( 1 ); wxButton *browseButton = new wxButton( this, ID_OPENWITH_BROWSE, wxT("Browse..."), wxDefaultPosition, wxDefaultSize, 0 ); browseSizer->Add( browseButton, 0, wxALIGN_CENTER|wxALL, 5 ); //wxCheckBox *item10 = new wxCheckBox( this, wxID_ANY, wxT("Always use selected program to open this kind of file"), wxDefaultPosition, wxDefaultSize, 0 ); //browseSizer->Add( item10, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); browseSizer->AddSpacer(5); staticBoxSizer->Add( browseSizer, 0, wxGROW|wxALIGN_CENTER|wxALL, 0 ); rootSizer->Add( staticBoxSizer, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); wxBoxSizer *buttonSizer = new wxBoxSizer( wxHORIZONTAL ); wxButton *okButton = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxDefaultSize, 0 ); okButton->SetDefault(); buttonSizer->Add( okButton, 0, wxALIGN_CENTER|wxALL, 5 ); wxButton *cancelButton = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); buttonSizer->Add( cancelButton, 0, wxALIGN_CENTER|wxALL, 5 ); rootSizer->Add( buttonSizer, 0, wxALIGN_CENTER|wxALL, 5 ); SetMinSize(wxSize(400, 300)); SetSizer( rootSizer ); rootSizer->SetSizeHints( this ); return true; } void OpenWithDialog::OnButton(wxCommandEvent& event) { switch (event.GetId()) { case wxID_CANCEL : m_command.Clear(); break; case wxID_OK : m_command = m_textCtrl->GetValue(); break; case ID_OPENWITH_BROWSE : { wxString filters(wxT("All files (*)|*")); #ifdef __WXMSW__ filters = wxT("Executable files (*.exe)|*.exe|Batch files (*.bat)|*.bat|All files (*)|*"); #endif //__WXMSW__ wxString startPath = m_fileData.GetFilePath(); wxString fileName = wxFileSelector( wxT("Open With"), wxPathOnly(startPath), wxFileNameFromPath(startPath), wxEmptyString, filters, wxOPEN|wxFILE_MUST_EXIST ); if (!fileName.IsEmpty()) { fileName += wxT(" \"") + m_fileData.GetFilePath() + wxT("\""); m_textCtrl->SetValue(fileName); } break; } }; event.Skip(); // let wxDialog exit if OK or CANCEL } //------------------------------------------------------------------------------ // wxFilePropertiesDialog - a properties dialog for a file //------------------------------------------------------------------------------ class wxFilePropertiesDialog : public wxDialog { public: wxFilePropertiesDialog(wxWindow* parent, wxWindowID winId, const wxFileData& fileData, const wxString& caption = wxT("Properties"), long style = wxDEFAULT_DIALOG_STYLE, const wxPoint& pos = wxDefaultPosition) : wxDialog(), m_fileData(fileData) { Create(parent, winId, fileData, caption, style, pos); } bool Create(wxWindow* parent, wxWindowID winId, const wxFileData& fileData, const wxString& caption = wxT("Properties"), long style = wxDEFAULT_DIALOG_STYLE, const wxPoint& pos = wxDefaultPosition); protected: wxFileData m_fileData; DECLARE_EVENT_TABLE(); }; BEGIN_EVENT_TABLE(wxFilePropertiesDialog, wxDialog) END_EVENT_TABLE() bool wxFilePropertiesDialog::Create(wxWindow *parent, wxWindowID winId, const wxFileData& fileData, const wxString& caption, long style, const wxPoint& pos) { m_fileData = fileData; if (!wxDialog::Create(parent, winId, caption, pos, wxDefaultSize, style)) return false; wxString typeStr; wxString locationStr = fileData.GetFilePath().BeforeLast(wxFILE_SEP_PATH); wxString sizeStr; wxString modifiedStr = fileData.GetModificationTime(); wxString attrStr = fileData.GetEntry(wxFileData::FileList_Perm); if (fileData.IsDir()) { typeStr = sizeStr = _("Directory"); } else if (fileData.IsLink()) { typeStr = sizeStr = _("Link"); } else if (fileData.IsDrive()) { typeStr = sizeStr = _("Drive"); } else if (fileData.IsFile()) { wxString ext = wxFileName(fileData.GetFileName()).GetExt(); wxString description; wxFileType *ft = wxTheMimeTypesManager->GetFileTypeFromExtension(ext); if (ft && ft->GetDescription(&description)) typeStr = description; if (description.IsEmpty()) // gtk does this... { if (!ext.IsEmpty()) typeStr = ext + wxT(" file"); else typeStr = wxT("Unknown file type"); } sizeStr = fileData.GetEntry(wxFileData::FileList_Size) + wxT(" bytes"); attrStr = fileData.GetEntry(wxFileData::FileList_Perm); } wxPanel *panel = new wxPanel(this, wxID_ANY); wxBoxSizer *rootSizer = new wxBoxSizer( wxVERTICAL ); wxFlexGridSizer *fileNameSizer = new wxFlexGridSizer( 2, 0, 0 ); wxBitmap iconBitmap = GetBitmapFromIconId(fileData.GetImageId()); wxStaticBitmap *iconStaticBitmap = new wxStaticBitmap( panel, wxID_ANY, iconBitmap, wxDefaultPosition, wxDefaultSize ); fileNameSizer->Add( iconStaticBitmap, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); wxStaticText *fileNameText = new wxStaticText( panel, wxID_ANY, fileData.GetFileName(), wxDefaultPosition, wxDefaultSize, 0 ); fileNameSizer->Add( fileNameText, 0, wxALIGN_CENTRE|wxALL, 5 ); rootSizer->Add( fileNameSizer, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); wxStaticBox *generalBox = new wxStaticBox( panel, wxID_ANY, wxT("General") ); wxStaticBoxSizer *generalBoxSizer = new wxStaticBoxSizer( generalBox, wxVERTICAL ); wxFlexGridSizer *generalSizer = new wxFlexGridSizer( 2, 0, 0 ); wxStaticText *typeNameText = new wxStaticText( panel, wxID_ANY, wxT("Type:"), wxDefaultPosition, wxDefaultSize, 0 ); generalSizer->Add( typeNameText, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); wxStaticText *typeText = new wxStaticText( panel, wxID_ANY, typeStr, wxDefaultPosition, wxDefaultSize, 0 ); generalSizer->Add( typeText, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); wxStaticText *locationNameText = new wxStaticText( panel, wxID_ANY, wxT("Location:"), wxDefaultPosition, wxDefaultSize, 0 ); generalSizer->Add( locationNameText, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); wxStaticText *locationText = new wxStaticText( panel, wxID_ANY, locationStr, wxDefaultPosition, wxDefaultSize, 0 ); generalSizer->Add( locationText, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); wxStaticText *sizeNameText = new wxStaticText( panel, wxID_ANY, wxT("Size:"), wxDefaultPosition, wxDefaultSize, 0 ); generalSizer->Add( sizeNameText, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); wxStaticText *sizeText = new wxStaticText( panel, wxID_ANY, sizeStr, wxDefaultPosition, wxDefaultSize, 0 ); generalSizer->Add( sizeText, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); wxStaticText *modifiedNameText = new wxStaticText( panel, wxID_ANY, wxT("Modified:"), wxDefaultPosition, wxDefaultSize, 0 ); generalSizer->Add( modifiedNameText, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); wxStaticText *modifiedText = new wxStaticText( panel, wxID_ANY, modifiedStr, wxDefaultPosition, wxDefaultSize, 0 ); generalSizer->Add( modifiedText, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); wxStaticText *attributesNameText = new wxStaticText( panel, wxID_ANY, wxT("Attributes:"), wxDefaultPosition, wxDefaultSize, 0 ); generalSizer->Add( attributesNameText, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); wxStaticText *attributesText = new wxStaticText( panel, wxID_ANY, attrStr, wxDefaultPosition, wxDefaultSize, 0 ); generalSizer->Add( attributesText, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); generalBoxSizer->Add( generalSizer, 0, wxGROW|wxALIGN_CENTER_VERTICAL, 5 ); rootSizer->Add( generalBoxSizer, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); wxFlexGridSizer *buttonSizer = new wxFlexGridSizer( 2, 0, 0 ); wxButton *okButton = new wxButton( panel, wxID_OK, wxT("OK"), wxDefaultPosition, wxDefaultSize, 0 ); okButton->SetDefault(); buttonSizer->Add( okButton, 0, wxALIGN_CENTRE|wxALL, 5 ); rootSizer->Add( buttonSizer, 0, wxALIGN_CENTRE|wxALL, 5 ); panel->SetAutoLayout( true ); panel->SetSizer( rootSizer ); rootSizer->Fit( panel ); rootSizer->SetSizeHints( this ); // have a min size so it really only varies for really long paths wxSize size = GetSize(); if (size.x < 400) SetSize(wxSize(400, size.y)); return true; } //------------------------------------------------------------------------------ // wxFileBrowserEvent, events for the wxFileBrowser //------------------------------------------------------------------------------ DEFINE_EVENT_TYPE(wxEVT_FILEBROWSER_FILE_SELECTED) DEFINE_EVENT_TYPE(wxEVT_FILEBROWSER_FILE_ACTIVATED) DEFINE_EVENT_TYPE(wxEVT_FILEBROWSER_DIR_SELECTED) DEFINE_EVENT_TYPE(wxEVT_FILEBROWSER_DIR_ACTIVATED) IMPLEMENT_ABSTRACT_CLASS(wxFileBrowserEvent, wxCommandEvent) wxFileBrowserEvent::wxFileBrowserEvent(wxEventType commandType, wxFileBrowser *fileBrowser, wxWindowID win_id) :wxCommandEvent(commandType, win_id) { SetEventObject( fileBrowser ); } //---------------------------------------------------------------------------- // wxFileBrowser //---------------------------------------------------------------------------- IMPLEMENT_DYNAMIC_CLASS(wxFileBrowser, wxControl); BEGIN_EVENT_TABLE(wxFileBrowser, wxControl) // View toolbar items EVT_MENU(ID_wxFILEBROWSER_VIEW_TREE, wxFileBrowser::OnViewButtons) EVT_MENU(ID_wxFILEBROWSER_VIEW_LIST, wxFileBrowser::OnViewButtons) EVT_MENU(ID_wxFILEBROWSER_VIEW_DETAILS, wxFileBrowser::OnViewButtons) EVT_MENU(ID_wxFILEBROWSER_VIEW_SMALL_ICON, wxFileBrowser::OnViewButtons) EVT_MENU(ID_wxFILEBROWSER_VIEW_LARGE_ICON, wxFileBrowser::OnViewButtons) EVT_MENU(ID_wxFILEBROWSER_VIEW_PREVIEW, wxFileBrowser::OnViewButtons) EVT_BUTTON(ID_wxFILEBROWSER_VIEW_BUTTON, wxFileBrowser::OnViewButtons) //EVT_MENU(ID_wxFILEBROWSER_VIEW_BUTTON, wxFileBrowser::OnViewButtons) // menu items for the right click treectrl menu EVT_MENU(ID_wxFILEBROWSER_TREE_MENU_PROPERITES, wxFileBrowser::OnTreeMenu) // menu items for the right click listctrl menu EVT_MENU(ID_wxFILEBROWSER_GO_BACK, wxFileBrowser::OnListMenu) EVT_MENU(ID_wxFILEBROWSER_GO_FORWARD, wxFileBrowser::OnListMenu) EVT_MENU(ID_wxFILEBROWSER_GO_UP, wxFileBrowser::OnListMenu) EVT_MENU(ID_wxFILEBROWSER_GO_HOME, wxFileBrowser::OnListMenu) EVT_MENU(ID_wxFILEBROWSER_REFRESH, wxFileBrowser::OnListMenu) EVT_MENU(wxID_OPEN, wxFileBrowser::OnListMenu) EVT_MENU(ID_wxFILEBROWSER_LIST_MENU_VIEW_FILE, wxFileBrowser::OnListMenu) EVT_MENU(ID_wxFILEBROWSER_LIST_MENU_OPEN_WITH, wxFileBrowser::OnListMenu) EVT_MENU(ID_wxFILEBROWSER_LIST_MENU_NEW_FOLDER, wxFileBrowser::OnListMenu) EVT_MENU(wxID_CUT, wxFileBrowser::OnListMenu) EVT_MENU(wxID_COPY, wxFileBrowser::OnListMenu) EVT_MENU(wxID_PASTE, wxFileBrowser::OnListMenu) EVT_MENU(ID_wxFILEBROWSER_LIST_MENU_DELETE, wxFileBrowser::OnListMenu) EVT_MENU(ID_wxFILEBROWSER_LIST_MENU_RENAME, wxFileBrowser::OnListMenu) EVT_MENU(ID_wxFILEBROWSER_LIST_MENU_PROPERITES, wxFileBrowser::OnListMenu) EVT_MENU(ID_wxFILEBROWSER_SHOW_HIDDEN, wxFileBrowser::OnListMenu) EVT_MENU(ID_wxFILEBROWSER_SHOW_FOLDERS, wxFileBrowser::OnListMenu) EVT_MENU(ID_wxFILEBROWSER_SPLIT_VERTICAL, wxFileBrowser::OnListMenu) // combobox events EVT_COMBOBOX (ID_wxFILEBROWSER_FILTER_COMBO, wxFileBrowser::OnFilterCombo) EVT_TEXT_ENTER(ID_wxFILEBROWSER_FILTER_COMBO, wxFileBrowser::OnFilterComboEnter) EVT_COMBOBOX (ID_wxFILEBROWSER_PATH_COMBO, wxFileBrowser::OnPathCombo) EVT_TEXT_ENTER(ID_wxFILEBROWSER_PATH_COMBO, wxFileBrowser::OnPathComboEnter) EVT_BUTTON (ID_wxFILEBROWSER_PATH_BUTTON, wxFileBrowser::OnPathComboEnter) // fake internal events to get around GTK combo event loops EVT_MENU (ID_wxFILEBROWSER_COMBOSETPATH, wxFileBrowser::OnSetPath) EVT_MENU (ID_wxFILEBROWSER_COMBOSETFILTER, wxFileBrowser::OnSetFilter) // TreeCtrl EVT_TREE_SEL_CHANGED (wxID_ANY, wxFileBrowser::OnTreeItemSelection) EVT_TREE_ITEM_ACTIVATED (wxID_ANY, wxFileBrowser::OnTreeItemActivation) EVT_TREE_ITEM_RIGHT_CLICK(wxID_ANY, wxFileBrowser::OnTreeRightClick) // ListCtrl EVT_LIST_ITEM_ACTIVATED (wxID_ANY, wxFileBrowser::OnListItemActivated) EVT_LIST_ITEM_SELECTED (wxID_ANY, wxFileBrowser::OnListItemSelected) EVT_LIST_ITEM_RIGHT_CLICK (wxID_ANY, wxFileBrowser::OnListRightClick) EVT_SIZE (wxFileBrowser::OnSize) //EVT_IDLE (wxFileBrowser::OnIdle) END_EVENT_TABLE() void wxFileBrowser::Init() { m_ignore_tree_event = true; // turned off after Create m_init_filters = 0; m_browser_style = wxFILEBROWSER_LIST; m_path_history_index = 0; m_viewToolBar = NULL; m_pathToolBar = NULL; m_viewButton = NULL; m_filterCombo = NULL; m_pathCombo = NULL; m_splitterWin = NULL; m_dirCtrl = NULL; m_fileCtrl = NULL; m_listMenu = NULL; m_treeMenu = NULL; m_viewMenu = NULL; m_filterComboSelection = 0; m_pathComboSelection = 0; m_show_hidden = false; } bool wxFileBrowser::Create( wxWindow *parent, const wxWindowID id, const wxString& dir, const wxPoint& pos, const wxSize& size, long style, const wxString& filter, int defaultFilter, const wxString& name) { m_ignore_tree_event = true; if (!wxControl::Create(parent, id, pos, size, style, wxDefaultValidator, name)) return false; // disable the log in case image handlers have already been initialized { wxLogNull logNull; wxInitAllImageHandlers(); // need this for the icons } // Find what directory to start with if (!GetPathFromFilePath(dir, m_path)) m_path = wxGetCwd(); // ------------------------------------------------------------------------ // Create the popup menu for the wxFileCtrl m_listMenu = new wxMenu; m_listMenu->Append(wxID_OPEN, wxT("&Open")); m_listMenu->Append(ID_wxFILEBROWSER_LIST_MENU_VIEW_FILE, wxT("&View file...")); m_listMenu->Append(ID_wxFILEBROWSER_LIST_MENU_OPEN_WITH, wxT("Open &with...")); m_listMenu->AppendSeparator(); m_listMenu->Append(ID_wxFILEBROWSER_LIST_MENU_NEW_FOLDER, wxT("&New folder")); m_listMenu->AppendSeparator(); m_listMenu->Append(wxID_CUT, wxT("Cu&t")); m_listMenu->Append(wxID_COPY, wxT("&Copy")); m_listMenu->Append(wxID_PASTE, wxT("&Paste")); m_listMenu->AppendSeparator(); m_listMenu->Append(ID_wxFILEBROWSER_LIST_MENU_DELETE, wxT("&Delete...")); m_listMenu->Append(ID_wxFILEBROWSER_LIST_MENU_RENAME, wxT("Rena&me")); m_listMenu->AppendSeparator(); m_listMenu->Append(ID_wxFILEBROWSER_LIST_MENU_PROPERITES, wxT("P&roperties")); m_listMenu->AppendSeparator(); m_treeMenu = new wxMenu; m_treeMenu->Append(ID_wxFILEBROWSER_TREE_MENU_PROPERITES, wxT("P&roperties")); wxMenu *optionsMenu = new wxMenu(wxEmptyString); optionsMenu->AppendCheckItem(ID_wxFILEBROWSER_SHOW_HIDDEN, wxT("Show Hidden Files")); optionsMenu->AppendCheckItem(ID_wxFILEBROWSER_SHOW_FOLDERS, wxT("Show Folders")); optionsMenu->AppendCheckItem(ID_wxFILEBROWSER_SPLIT_VERTICAL, wxT("Split Vertically")); m_listMenu->Append(ID_wxFILEBROWSER_LIST_MENU_OPTIONS, wxT("Optio&ns"), optionsMenu); // ------------------------------------------------------------------------ // Create the menu for the view button menu m_viewMenu = new wxMenu; m_viewMenu->AppendRadioItem(ID_wxFILEBROWSER_VIEW_TREE, wxT("Tree view")); m_viewMenu->AppendRadioItem(ID_wxFILEBROWSER_VIEW_LIST, wxT("List view")); m_viewMenu->AppendRadioItem(ID_wxFILEBROWSER_VIEW_DETAILS, wxT("Details view")); m_viewMenu->AppendRadioItem(ID_wxFILEBROWSER_VIEW_SMALL_ICON, wxT("Small icon view")); //m_viewMenu->AppendRadioItem(ID_wxFILEBROWSER_VIEW_LARGE_ICON, wxT("Large icon view")); //m_viewMenu->AppendRadioItem(ID_wxFILEBROWSER_VIEW_PREVIEW, wxT("Image preview view")); // ------------------------------------------------------------------------ // Create the first Toolbar m_viewToolBar = new wxToolBar(this, ID_wxFLEBROWSER_VIEW_TOOLBAR); m_viewToolBar->AddTool(ID_wxFILEBROWSER_GO_BACK, wxT("Back"), wxArtProvider::GetBitmap(wxART_GO_BACK), wxArtProvider::GetBitmap(wxART_GO_BACK, wxART_TOOLBAR), wxITEM_NORMAL, wxT("Go back one directory"), wxT("Go back one directory")); m_viewToolBar->AddTool(ID_wxFILEBROWSER_GO_FORWARD, wxT("Forward"), wxArtProvider::GetBitmap(wxART_GO_FORWARD), wxArtProvider::GetBitmap(wxART_GO_FORWARD, wxART_TOOLBAR), wxITEM_NORMAL, wxT("Go forward one directory"), wxT("Go forward one directory")); m_viewToolBar->AddTool(ID_wxFILEBROWSER_GO_UP, wxT("Up"), wxArtProvider::GetBitmap(wxART_GO_DIR_UP), wxArtProvider::GetBitmap(wxART_GO_DIR_UP, wxART_TOOLBAR), wxITEM_NORMAL, wxT("Go up one directory"), wxT("Go up one directory")); m_viewToolBar->AddTool(ID_wxFILEBROWSER_GO_HOME, wxT("Home"), wxArtProvider::GetBitmap(wxART_GO_HOME), wxArtProvider::GetBitmap(wxART_GO_HOME, wxART_TOOLBAR), wxITEM_NORMAL, wxT("Go to your home directory"), wxT("Go to your home directory")); m_viewToolBar->AddSeparator(); m_viewToolBar->AddCheckTool(ID_wxFILEBROWSER_SHOW_FOLDERS, wxT("Folders"), wxArtProvider::GetBitmap(wxART_HELP_SIDE_PANEL), wxArtProvider::GetBitmap(wxART_HELP_SIDE_PANEL, wxART_TOOLBAR), wxT("Show folder view"), wxT("Show folder view")); m_viewToolBar->AddSeparator(); // MenuButton METHOD ---------------- // m_viewButton = new wxMenuButton(m_viewToolBar, wxID_ANY, // //wxBitmap(view_xpm_data), // wxArtProvider::GetBitmap(wxART_LIST_VIEW), // wxDefaultPosition, wxSize(32,22)); // m_viewButton->AssignMenu(viewMenu, false); // m_viewButton->SetToolTip(wxT("Change view mode")); // m_viewToolBar->AddControl(m_viewButton); // CREATE BITMAP METHOD ---------------- wxBitmap viewBmp(wxArtProvider::GetBitmap(wxART_LIST_VIEW)); //, wxART_TOOLBAR)); wxSize toolBmpSize = m_viewToolBar->GetToolSize(); wxSize toolSize = m_viewToolBar->GetToolSize(); { wxImage viewImg(viewBmp.ConvertToImage()); int w = viewImg.GetWidth(), h = viewImg.GetHeight(); int s = 10; unsigned char r = 103, g = 200, b = 101; viewImg.GetOrFindMaskColour(&r, &g, &b); viewImg.Resize(wxSize(w + s, h), wxPoint(0,0), r, g, b); viewImg.SetMask(false); viewBmp = wxBitmap(viewImg); wxMemoryDC memDC; memDC.SelectObject(viewBmp); wxRendererNative& renderer = wxRendererNative::Get(); renderer.DrawComboBoxDropButton(this, memDC, wxRect(w, 0, s, toolBmpSize.y), wxCONTROL_PRESSED); //renderer.DrawDropArrow(this, memDC, wxRect(w, 0, s, toolBmpSize.y)); memDC.SelectObject(wxNullBitmap); viewImg = viewBmp.ConvertToImage(); viewImg.SetMaskColour(r, g, b); viewBmp = wxBitmap(viewImg); } m_viewButton = new wxBitmapButton(m_viewToolBar, ID_wxFILEBROWSER_VIEW_BUTTON, //wxBitmap(view_xpm_data), viewBmp, wxDefaultPosition, wxSize(toolSize.GetWidth()+10, toolSize.GetHeight())); m_viewButton->SetToolTip(wxT("Change view mode")); m_viewToolBar->AddControl(m_viewButton); //m_viewToolBar->AddTool(ID_wxFILEBROWSER_VIEW_BUTTON, wxT("Views"), // viewBmp, viewBmp, // wxITEM_NORMAL, wxT("Change view mode"), wxT("Change view mode")); m_filterCombo = new wxComboBox(m_viewToolBar, ID_wxFILEBROWSER_FILTER_COMBO, wxT("Any file (*.*)"), // sets init size wxDefaultPosition, wxSize(40, wxDefaultCoord), 0, NULL, wxCB_DROPDOWN|wxTE_PROCESS_ENTER); m_filterCombo->SetToolTip(wxT("Filter files using wildcards (file1?2.a*)")); SetFilters(filter, defaultFilter); m_viewToolBar->AddSeparator(); m_viewToolBar->AddControl(m_filterCombo); m_viewToolBar->Realize(); // ------------------------------------------------------------------------ // Create second Toolbar m_pathToolBar = new wxToolBar(this, ID_wxFLEBROWSER_PATH_TOOLBAR); m_pathCombo = new wxComboBox(m_pathToolBar, ID_wxFILEBROWSER_PATH_COMBO, wxT("C: I'm a pretty long dir name so I'm sized big"), wxDefaultPosition, wxSize(40, wxDefaultCoord), 0, NULL, wxCB_DROPDOWN|wxTE_PROCESS_ENTER); m_pathCombo->SetToolTip(wxT("Enter path")); m_pathCombo->Append(GetPath(true), (void*)NULL); m_pathCombo->SetSelection(0); m_pathComboSelection = 0; m_pathToolBar->AddControl(m_pathCombo); m_pathToolBar->AddTool(ID_wxFILEBROWSER_PATH_BUTTON, wxT("Open"), wxArtProvider::GetBitmap(wxART_FILE_OPEN), wxArtProvider::GetBitmap(wxART_FILE_OPEN, wxART_TOOLBAR), wxITEM_NORMAL, wxT("Go to path or open file"), wxT("Go to path or open file")); m_pathToolBar->Realize(); // ------------------------------------------------------------------------ // Create the splitter window and children int dirCtrlStyle = style & wxFILEBROWSER_TREE ? wxDIRCTRL_DIR_ONLY : 0; m_splitterWin = new wxSplitterWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_BORDER|wxSP_3D|wxCLIP_CHILDREN); m_splitterWin->SetMinimumPaneSize(MIN_SPLIT); // don't let it unsplit m_splitterWin->SetSashGravity(0.3); // bottom grows more than top m_dirCtrl = new wxGenericDirCtrl(m_splitterWin, ID_wxFILEBROWSER_DIRCTRL, m_path, wxDefaultPosition, wxSize(50,50), dirCtrlStyle|wxNO_BORDER, wxEmptyString, 0); m_dirCtrl->Show(true); m_fileCtrl = new wxFileCtrl(m_splitterWin, wxID_ANY, GetWild(), false, wxDefaultPosition, wxSize(50,50), wxNO_BORDER|wxLC_SINGLE_SEL|FBStyleToLCStyle(style)); m_fileCtrl->Show(true); m_fileCtrl->GoToDir(m_path); // ------------------------------------------------------------------------ SetBrowserStyle( style ); m_splitterWin->Show(true); AddPathHistory(GetPath(true)); UpdateItems(); m_ignore_tree_event = false; return true; } wxFileBrowser::~wxFileBrowser() { // delete all the attached data int n, count = m_filterCombo->GetCount(); for ( n = 0; n < count; n++ ) { wxString *data = (wxString*)m_filterCombo->GetClientData(n); delete data; } delete m_listMenu; delete m_treeMenu; delete m_viewMenu; } void wxFileBrowser::OnSize( wxSizeEvent &event ) { //wxPrintf(wxT("OnSize GetSize(%d %d) Event(%d %d)\n"), GetSize().x, GetSize().y, event.GetSize().x, event.GetSize().y); fflush(stdout); event.Skip(); DoSize(); } // The code in src/gtk/window.cpp wxWindow::DoSetSize fails since // m_parent->m_wxwindow == NULL so nothing is done #ifdef __WXGTK__ #include void GtkToolbarResizeWindow(wxWindow* win, const wxSize& size) { // don't take the x,y values, they're wrong because toolbar sets them GtkWidget *widget = GTK_WIDGET(win->m_widget); //gtk_widget_set_usize(widget, size.x, size.y); this is deprecated use below gtk_widget_set_size_request(widget, size.x, size.y); if (GTK_WIDGET_VISIBLE(widget)) gtk_widget_queue_resize(widget); } #endif //__WXGTK__ void wxFileBrowser::DoSize() { if (!m_splitterWin) return; wxSize clientSize(GetClientSize()); int h = 0; if (m_viewToolBar && m_filterCombo) { wxSize tbSize(m_viewToolBar->GetSize()); m_viewToolBar->SetSize(0, h, clientSize.x, tbSize.y); wxSize toolSize(m_viewToolBar->GetToolSize()); wxSize marginSize(m_viewToolBar->GetMargins()); wxRect comboRect(m_filterCombo->GetRect()); wxSize comboSize(clientSize.x - comboRect.x - marginSize.x, comboRect.height); #ifdef __WXGTK__ int sep = m_viewToolBar->GetToolSeparation(); comboSize.x = clientSize.x - 6*toolSize.x - 6*sep; GtkToolbarResizeWindow(m_filterCombo, comboSize); #else m_filterCombo->SetSize(comboSize); m_viewToolBar->Realize(); #endif //wxPrintf(wxT("FilterCombo %d %d - %d\n"), comboSize.x, comboSize.y, m_filterCombo->GetSize().y); h += tbSize.y; } if (m_pathToolBar && m_pathCombo) { wxSize tbSize(m_pathToolBar->GetSize()); m_pathToolBar->SetSize(0, h, clientSize.x, tbSize.y); wxSize toolSize(m_pathToolBar->GetToolSize()); wxSize marginSize(m_pathToolBar->GetMargins()); wxRect comboRect(m_pathCombo->GetRect()); wxSize comboSize(clientSize.x - comboRect.x - toolSize.x - marginSize.x, comboRect.height); #ifdef __WXGTK__ //int sep = m_viewToolBar->GetToolSeparation(); comboSize.x = clientSize.x - toolSize.x - 2; GtkToolbarResizeWindow(m_pathCombo, comboSize); #else //wxPrintf(wxT("Do Size %d %d - %d %d %d\n"), clientSize.x, clientSize.y, clientSize.x, comboRect.width, clientSize.x - comboRect.x - toolSize.x - marginSize.x); m_pathCombo->SetSize(comboSize); m_pathToolBar->Realize(); #endif //wxPrintf(wxT("PathCombo %d %d - %d\n"), clientSize.x - comboRect.x - toolSize.x - marginSize.x, comboRect.height, m_pathCombo->GetSize().y); h += tbSize.y; } m_splitterWin->SetSize(wxRect(0, h, clientSize.x, clientSize.y - h)); // Make sure the splitter window doesn't unsplit when the window size changes, // even though we already told it not to. // FIXME : This should be fixed in the splitter window if (m_splitterWin && m_splitterWin->IsSplit()) { int splitter_pos = m_splitterWin->GetSashPosition(); int splitter_size = (m_splitterWin->GetSplitMode() == wxSPLIT_VERTICAL) ? m_splitterWin->GetSize().GetWidth() : m_splitterWin->GetSize().GetHeight(); int min_size = m_splitterWin->GetMinimumPaneSize(); if (splitter_pos < min_size) m_splitterWin->SetSashPosition(wxMin(splitter_size, min_size)); else if (splitter_pos > splitter_size - min_size) m_splitterWin->SetSashPosition(wxMax(0, splitter_size - min_size)); } } wxSize wxFileBrowser::DoGetBestSize() const { return wxSize(200,400); //return wxControl::DoGetBestSize(); } void wxFileBrowser::OnIdle(wxIdleEvent &event) { event.Skip(); // Ancient code to display a preview of images /* if ((m_browser_style & wxFILEBROWSER_PREVIEW) && (int(m_previewFiles.GetCount()) > 0)) { int i, count = m_previewFiles.GetCount(); int flags = 0; int prev_index = 0; int min_index = m_fileCtrl->HitTest(wxPoint(20,150), flags); if (min_index < 0) min_index = 0; int max_index = min_index + (m_fileCtrl->GetClientSize().x*m_fileCtrl->GetClientSize().y)/3000; for (i=0; im_list_index >= min_index) || (m_previewFiles[i]->m_list_index <= max_index)) { prev_index = i; break; } } wxFileBrowserFile *browserFile = m_previewFiles[prev_index]; int icon_index = browserFile->m_icon_index; wxString path = GetPath(true); wxImage img(path + browserFile->m_name); if (img.Ok()) { int w = img.GetWidth(), h = img.GetHeight(); browserFile->m_image_size.Printf(wxT("(%dx%d)"), w, h); int icon_w, icon_h; m_normalImageList->GetSize(0, icon_w, icon_h); if (w > icon_w || h > icon_h) { if (w > h) { h = (h*icon_w)/w; if (h == 0) h = 1; w = icon_w; } else { w = (w*icon_h)/h; if (w == 0) w = 1; h = icon_h; } img.Rescale(w, h); } wxImage img2(icon_w, icon_h); unsigned char r=5, g=5, b=5; if (img.HasMask()) { r = img.GetMaskRed(); g = img.GetMaskGreen(); b = img.GetMaskBlue(); } else { img.FindFirstUnusedColour(&r, &g, &b); img.SetMask(true); img.SetMaskColour(r, g, b); } unsigned char *data = img2.GetData(); long icon_size = icon_w*icon_h; for (i=0; iReplace(icon_index, icon); if (browserFile->m_list_index >= 0) // maybe still filling the listCtrl { m_fileCtrl->SetItemImage(browserFile->m_list_index, icon_index, icon_index); } } m_previewFiles.RemoveAt(prev_index); if (count > 1) event.RequestMore(); } */ } #define FILEBRWS_LIST_VIEW_MASK (wxFILEBROWSER_DETAILS|wxFILEBROWSER_LIST|wxFILEBROWSER_SMALL_ICON|wxFILEBROWSER_LARGE_ICON|wxFILEBROWSER_PREVIEW) #define FILEBRWS_VIEW_MASK (FILEBRWS_LIST_VIEW_MASK|wxFILEBROWSER_TREE) void wxFileBrowser::SetBrowserStyle( long style ) { style &= wxFILEBROWSER_STYLE_MASK; int n_styles = 0; if (style & wxFILEBROWSER_LIST ) n_styles++; if (style & wxFILEBROWSER_DETAILS ) n_styles++; if (style & wxFILEBROWSER_LARGE_ICON) n_styles++; if (style & wxFILEBROWSER_SMALL_ICON) n_styles++; if (style & wxFILEBROWSER_PREVIEW ) n_styles++; if (style & wxFILEBROWSER_TREE ) n_styles++; wxCHECK_RET(n_styles == 1, wxT("Only one wxFileBrowser list style allowed")); long last_style = m_browser_style; m_browser_style = style; // swap to new style immediately // Only the tree view will be shown if (!HasBrowserStyle(FILEBRWS_LIST_VIEW_MASK)) { m_fileCtrl->Show(false); if (m_splitterWin->IsSplit()) m_splitterWin->Unsplit(m_fileCtrl); else // if (m_splitterWin->GetWindow1() != m_dirCtrl) m_splitterWin->Initialize(m_dirCtrl); // show and reload the files for the dirctrl using the filter if ((m_dirCtrl->GetWindowStyleFlag() & wxDIRCTRL_DIR_ONLY) != 0) { m_ignore_tree_event = true; wxString currentPath = GetPath(false); m_dirCtrl->SetWindowStyleFlag(m_dirCtrl->GetWindowStyleFlag() & (~wxDIRCTRL_DIR_ONLY)); m_dirCtrl->SetFilter(GetFilter()); m_dirCtrl->ReCreateTree(); m_dirCtrl->ExpandPath(currentPath); m_ignore_tree_event = false; } m_splitterWin->SizeWindows(); UpdateItems(); return; } // Else - show a combination of tree and list views // Try to avoid flicker by changing mode only if necessary switch (m_browser_style & FILEBRWS_VIEW_MASK) { case wxFILEBROWSER_DETAILS : { if ((last_style & wxFILEBROWSER_DETAILS) == 0) m_fileCtrl->ChangeToReportMode(); break; } case wxFILEBROWSER_LIST : { if ((last_style & wxFILEBROWSER_LIST) == 0) m_fileCtrl->ChangeToListMode(); break; } case wxFILEBROWSER_SMALL_ICON : { if ((last_style & wxFILEBROWSER_SMALL_ICON) == 0) m_fileCtrl->ChangeToSmallIconMode(); break; } default : break; } // are both tree and list view shown if (GetShowFolders()) { if (GetSplitVertical()) { if (m_splitterWin->GetSplitMode() != wxSPLIT_VERTICAL) { if (m_splitterWin->IsSplit()) // FIXME need to unsplit to resplit m_splitterWin->Unsplit(m_splitterWin->GetWindow2()); } int sash_pos = m_splitterWin->GetSashPosition(); m_splitterWin->SplitVertically(m_dirCtrl, m_fileCtrl, sash_pos); } else { if (m_splitterWin->GetSplitMode() != wxSPLIT_HORIZONTAL) { if (m_splitterWin->IsSplit()) // FIXME need to unsplit to resplit m_splitterWin->Unsplit(m_splitterWin->GetWindow2()); } int sash_pos = m_splitterWin->GetSashPosition(); m_splitterWin->SplitHorizontally(m_dirCtrl, m_fileCtrl, sash_pos); } m_dirCtrl->Show(true); } else // just list view { if (m_splitterWin->IsSplit()) m_splitterWin->Unsplit(m_dirCtrl); else // if (m_splitterWin->GetWindow1() != m_fileCtrl) m_splitterWin->Initialize(m_fileCtrl); m_dirCtrl->Show(false); } m_fileCtrl->Show(true); // In dir mode always show all dirs m_dirCtrl->SetFilter(wxEmptyString); // if it used to have wxFILEBROWSER_TREE style, make tree show only dirs if ((m_dirCtrl->GetWindowStyleFlag() & wxDIRCTRL_DIR_ONLY) == 0) { m_ignore_tree_event = true; m_dirCtrl->SetFilter(wxT("*|*")); m_dirCtrl->SetWindowStyleFlag(m_dirCtrl->GetWindowStyleFlag() | wxDIRCTRL_DIR_ONLY); wxString currentPath = GetPath(false); m_dirCtrl->ReCreateTree(); m_dirCtrl->ExpandPath(currentPath); m_ignore_tree_event = false; } m_splitterWin->SizeWindows(); UpdateItems(); } bool wxFileBrowser::CanRead(const wxString& filePath) const { return wxFile::Access(filePath, wxFile::read); } bool wxFileBrowser::CanWrite(const wxString& filePath) const { return wxFile::Access(filePath, wxFile::write); } void wxFileBrowser::UpdateItems() { UpdateMenu(m_listMenu); UpdateMenu(m_viewMenu); UpdateToolBar(m_viewToolBar); UpdateToolBar(m_pathToolBar); } void EnableMenuItem(wxMenu *menu, wxWindowID menu_id, bool value) { if (menu) { wxMenuItem *menuItem = menu->FindItem(menu_id); if (menuItem) menuItem->Enable(value); } } void CheckMenuItem(wxMenu *menu, wxWindowID menu_id, bool value) { if (menu) { wxMenuItem *menuItem = menu->FindItem(menu_id); if (menuItem) menuItem->Check(value); } } void wxFileBrowser::UpdateMenu( wxMenu* menu ) { if (!menu) return; CheckMenuItem(menu, FBStyleToMenuID(m_browser_style), true); // Update options menu --------------------------- CheckMenuItem(menu, ID_wxFILEBROWSER_SHOW_HIDDEN, GetShowHidden()); EnableMenuItem(menu, ID_wxFILEBROWSER_SHOW_FOLDERS, !HasBrowserStyle(wxFILEBROWSER_TREE)); CheckMenuItem(menu, ID_wxFILEBROWSER_SHOW_FOLDERS, GetShowFolders()); CheckMenuItem(menu, ID_wxFILEBROWSER_SPLIT_VERTICAL, GetSplitVertical()); // Update go items --------------------------- CheckMenuItem(menu, ID_wxFILEBROWSER_GO_BACK, CanGoPathHistoryBackward()); CheckMenuItem(menu, ID_wxFILEBROWSER_GO_FORWARD, CanGoPathHistoryForward()); CheckMenuItem(menu, ID_wxFILEBROWSER_GO_UP, CanGoUpDir()); // Update cut, copy, paste --------------------------- // wxLIST_STATE_FOCUSED ? nah probably selected long item = m_fileCtrl->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); wxFileData *fd = NULL; if (item >= 0) fd = (wxFileData*)m_fileCtrl->GetItemData(item); bool is_file = fd && !fd->IsDir() && !fd->IsDrive() && !fd->IsLink(); bool is_dir = fd && fd->IsDir(); // There's nothing you can do with this if (fd && (fd->GetFileName() == wxT(".."))) { is_file = is_dir = false; } bool can_read = (is_file || is_dir) && fd && CanRead(fd->GetFilePath()); bool can_write = (is_file || is_dir) && fd && CanWrite(fd->GetFilePath()); bool can_write_dir = CanWrite(GetPath()); // can't do anything with drive listing in MSW bool is_top = false; #ifndef __UNIX__ if (GetPath(false).IsEmpty()) is_top = true; #endif //__UNIX__ EnableMenuItem(menu, wxID_OPEN, (is_file || is_dir) && can_read); EnableMenuItem(menu, ID_wxFILEBROWSER_LIST_MENU_VIEW_FILE, is_file && can_read); EnableMenuItem(menu, ID_wxFILEBROWSER_LIST_MENU_OPEN_WITH, is_file && can_read); EnableMenuItem(menu, ID_wxFILEBROWSER_LIST_MENU_NEW_FOLDER, !is_top && can_write_dir); EnableMenuItem(menu, wxID_CUT, is_file && can_write); EnableMenuItem(menu, wxID_COPY, is_file && can_read); EnableMenuItem(menu, wxID_PASTE, !is_top && (m_copycutFiles.GetCount() > 0u) && can_write_dir); EnableMenuItem(menu, ID_wxFILEBROWSER_LIST_MENU_DELETE, (is_file || is_dir) && can_write); EnableMenuItem(menu, ID_wxFILEBROWSER_LIST_MENU_RENAME, (is_file || is_dir) && can_write); EnableMenuItem(menu, ID_wxFILEBROWSER_LIST_MENU_PROPERITES, is_file || is_dir); } void wxFileBrowser::UpdateToolBar( wxToolBar* toolBar ) { if (!toolBar) return; toolBar->EnableTool(ID_wxFILEBROWSER_GO_BACK, CanGoPathHistoryBackward()); toolBar->EnableTool(ID_wxFILEBROWSER_GO_FORWARD, CanGoPathHistoryForward()); toolBar->EnableTool(ID_wxFILEBROWSER_GO_UP, CanGoUpDir()); toolBar->EnableTool(ID_wxFILEBROWSER_SHOW_FOLDERS, !HasBrowserStyle(wxFILEBROWSER_TREE)); toolBar->ToggleTool(ID_wxFILEBROWSER_SHOW_FOLDERS, GetShowFolders()); } void wxFileBrowser::ShowHidden(bool show_hidden) { m_show_hidden = show_hidden; m_ignore_tree_event = true; m_dirCtrl->ShowHidden(m_show_hidden); m_fileCtrl->ShowHidden(m_show_hidden); m_ignore_tree_event = false; UpdateItems(); } void wxFileBrowser::ShowFolders(bool show_folders) { m_browser_style &= (~wxFILEBROWSER_SHOW_FOLDERS); if (show_folders) m_browser_style |= wxFILEBROWSER_SHOW_FOLDERS; SetBrowserStyle(m_browser_style); } void wxFileBrowser::SplitVertical(bool split_vertically) { m_browser_style &= (~wxFILEBROWSER_SPLIT_VERTICAL); if (split_vertically) m_browser_style |= wxFILEBROWSER_SPLIT_VERTICAL; SetBrowserStyle(m_browser_style); } bool wxFileBrowser::GetPathFromFilePath(const wxString &filepath, wxString &path) const { path = filepath; wxFileName filename(filepath); if (filename.FileExists()) path = filename.GetPath(); if (!wxDirExists(path)) return false; if (path.Last() != wxFILE_SEP_PATH) path += wxFILE_SEP_PATH; return true; } wxString AddDelete_wxFILE_SEP_PATH(const wxString &path_, bool add_sep) { wxString path(path_); #if __UNIX__ if (path.IsEmpty()) return wxFILE_SEP_PATH; #endif if (add_sep) { if (path.IsEmpty() || (path.Last() != wxFILE_SEP_PATH)) path += wxFILE_SEP_PATH; } else if (!path.IsEmpty() && (path.Last() == wxFILE_SEP_PATH)) path = path.RemoveLast(); return path; } wxString wxFileBrowser::GetPath(bool add_wxFILE_SEP_PATH) const { return AddDelete_wxFILE_SEP_PATH(m_path, add_wxFILE_SEP_PATH); } bool wxFileBrowser::SetPath(const wxString &dirname) { wxString path = dirname; if (dirname.IsEmpty()) { #ifdef __UNIX__ path = wxFILE_SEP_PATH; #endif } else { if (!GetPathFromFilePath(dirname, path)) return false; } m_path = AddDelete_wxFILE_SEP_PATH(path, true); m_ignore_tree_event = true; m_dirCtrl->SetPath(GetPath(false)); // doesn't like trailing wxFILE_SEP_PATH - segfault m_ignore_tree_event = false; if (!HasBrowserStyle(wxFILEBROWSER_TREE)) // don't care otherwise m_fileCtrl->GoToDir(m_path); InsertComboItem(m_pathCombo, GetPath(true), 0); AddPathHistory(GetPath(true)); UpdateItems(); return true; } bool wxFileBrowser::CanGoUpDir() const { wxString path = GetPath(false).BeforeLast(wxFILE_SEP_PATH); return !path.IsEmpty() && wxDirExists(path); } bool wxFileBrowser::GoUpDir() { wxString path = GetPath(false).BeforeLast(wxFILE_SEP_PATH); if (!path.IsEmpty() && wxDirExists(path)) return SetPath(path); return false; } bool wxFileBrowser::GoToHomeDir() { return SetPath(wxFileName::GetHomeDir()); } bool wxFileBrowser::CanGoPathHistoryForward() { if (m_path_history_index < int(m_pathHistory.GetCount()) - 1) { // maybe they deleted it? if (!wxDirExists(m_pathHistory[m_path_history_index+1])) { m_path_history_index++; m_pathHistory.RemoveAt(m_path_history_index); return CanGoPathHistoryForward(); } return true; } if (m_pathHistory.GetCount() == 0u) m_pathHistory.Add(GetPath(true)); return false; } bool wxFileBrowser::CanGoPathHistoryBackward() { if (m_path_history_index != 0) { // maybe they deleted it? if (!wxDirExists(m_pathHistory[m_path_history_index-1])) { m_path_history_index--; m_pathHistory.RemoveAt(m_path_history_index); return CanGoPathHistoryBackward(); } return true; } if (m_pathHistory.GetCount() == 0u) m_pathHistory.Add(GetPath(true)); return false; } bool wxFileBrowser::GoPathHistoryForward() { if (!CanGoPathHistoryForward()) return false; m_path_history_index++; return SetPath(m_pathHistory[m_path_history_index]); } bool wxFileBrowser::GoPathHistoryBackward() { if (!CanGoPathHistoryBackward()) return false; m_path_history_index--; return SetPath(m_pathHistory[m_path_history_index]); } void wxFileBrowser::AddPathHistory(const wxString& path) { if (!wxDirExists(path) || (path == m_pathHistory[m_path_history_index])) return; int count = m_pathHistory.GetCount(); if (count == 0) { m_path_history_index = 0; m_pathHistory.Add(path); } else if (m_path_history_index == count-1) { m_path_history_index++; m_pathHistory.Add(path); } else { m_path_history_index++; m_pathHistory[m_path_history_index] = path; } } void wxFileBrowser::OnTreeItemSelection(wxTreeEvent &event) { if (m_ignore_tree_event) { event.Skip(); return; } wxFileBrowserEvent fbEvent(wxEVT_FILEBROWSER_FILE_SELECTED, this, GetId()); if (m_dirCtrl->GetFilePath().IsEmpty()) fbEvent.SetEventType(wxEVT_FILEBROWSER_DIR_SELECTED); fbEvent.SetFilePath(m_dirCtrl->GetPath()); DoSendEvent(fbEvent); } void wxFileBrowser::OnTreeItemActivation(wxTreeEvent &event) { if (m_ignore_tree_event) { event.Skip(); return; } wxString path; if (!GetPathFromFilePath(m_dirCtrl->GetPath(), path)) return; wxFileBrowserEvent fbEvent(wxEVT_FILEBROWSER_FILE_ACTIVATED, this, GetId()); m_path = path; if (m_dirCtrl->GetFilePath().IsEmpty()) { fbEvent.SetEventType(wxEVT_FILEBROWSER_DIR_ACTIVATED); if (!HasBrowserStyle(wxFILEBROWSER_TREE)) m_fileCtrl->GoToDir(m_path); } fbEvent.SetFilePath(m_dirCtrl->GetPath()); DoSendEvent(fbEvent); } void wxFileBrowser::OnTreeRightClick(wxTreeEvent &event) { UpdateMenu(m_treeMenu); m_dirCtrl->PopupMenu(m_treeMenu, event.GetPoint()); } void wxFileBrowser::OnListItemActivated(wxListEvent &event) { wxString filename = event.GetLabel(); if (filename.IsEmpty()) return; wxFileData *fd = (wxFileData*)event.GetData(); wxCHECK_RET(fd, wxT("Invalid filedata")); wxString filePath = fd->GetFilePath(); wxEventType evtType = fd->IsDir() ? wxEVT_FILEBROWSER_DIR_ACTIVATED : wxEVT_FILEBROWSER_FILE_ACTIVATED; wxFileBrowserEvent fbEvent(evtType, this, GetId()); if (fd->IsDir()) { if (filename == wxT("..")) filePath = filePath.RemoveLast().BeforeLast(wxFILE_SEP_PATH); SetPath(filePath); } fbEvent.SetFilePath(filePath); DoSendEvent(fbEvent); } void wxFileBrowser::OnListItemSelected(wxListEvent &event) { wxFileData *fd = (wxFileData*)event.GetData(); wxCHECK_RET(fd, wxT("Invalid filedata")); wxEventType evtType = fd->IsDir() ? wxEVT_FILEBROWSER_DIR_SELECTED : wxEVT_FILEBROWSER_FILE_SELECTED; wxFileBrowserEvent fbEvent(evtType, this, GetId()); fbEvent.SetFilePath(fd->GetFilePath()); DoSendEvent(fbEvent); } void wxFileBrowser::OnListRightClick(wxListEvent &event) { UpdateMenu(m_listMenu); m_fileCtrl->PopupMenu(m_listMenu, event.GetPoint()); } wxFileData* wxFileBrowser::GetFocusedListItem() const { long item = m_fileCtrl->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_FOCUSED); if (item >= 0) return (wxFileData*)m_fileCtrl->GetItemData(item); return NULL; } wxArrayInt wxFileBrowser::GetSelectedListItems() const { wxArrayInt selItems; long item = m_fileCtrl->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); while (item >= 0) { selItems.Add((int)item); item = m_fileCtrl->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); } return selItems; } wxArrayFileData wxFileBrowser::GetSelectedListFileData() const { wxArrayFileData fileDatas; wxArrayInt selItems = GetSelectedListItems(); if ((int)selItems.GetCount() < 1) return fileDatas; for (size_t n=0; nGetItemData(selItems[n]); wxCHECK_MSG(fd, fileDatas, wxT("Invalid filedata item")); wxFileData newFd(*fd); fileDatas.Add(newFd); } return fileDatas; } wxFileData wxFileBrowser::CreateFileData(const wxFileName& fileName) const { if (fileName.DirExists()) { return wxFileData(fileName.GetPath(), fileName.GetName(), wxFileData::is_dir, wxFileIconsTable::folder); } else if (fileName.FileExists()) { return wxFileData(fileName.GetPath(), fileName.GetName(), wxFileData::is_file, wxFileIconsTable::file); } #if defined(__WINDOWS__) || defined(__DOS__) || defined(__WXMAC__) || defined(__OS2__) else { // FIXME this is ugly, but should work wxArrayString names, paths; wxArrayInt icons; size_t n, count = wxGetAvailableDrives(paths, names, icons); for (n = 0; n < count; n++) { if (fileName.GetFullPath() == paths[n]) return wxFileData(fileName.GetPath(), fileName.GetName(), wxFileData::is_drive, icons[n]); } } #endif return wxFileData(); } bool wxFileBrowser::DeleteSelectedListItems(bool WXUNUSED(ask_ok)) { wxArrayInt selItems = GetSelectedListItems(); if ((int)selItems.GetCount() < 1) return false; size_t n = 0; wxArrayString filePaths; wxArrayInt isDirs; wxString fileNameString; int line_length = 0; for (n=0; nGetItemData(selItems[n]); wxCHECK_MSG(fd, false, wxT("Invalid filedata item")); if (fd->IsDrive()) { wxString msg = wxT("Unable to delete drive: \"")+fd->GetFilePath()+wxT("\"\n"); msg += wxT("Please deselect drive and try again."); wxMessageBox(msg, wxT("Error deleting"), wxOK|wxCENTRE|wxICON_INFORMATION, this); return false; } if (fd->GetFileName() == wxT("..")) { wxString msg = wxT("Unable to delete parent directory: \"")+fd->GetFilePath()+wxT("\"\n"); msg += wxT("Please deselect dir and try again."); wxMessageBox(msg, wxT("Error deleting"), wxOK|wxCENTRE|wxICON_INFORMATION, this); return false; } isDirs.Add(fd->IsDir() ? 1 : 0); filePaths.Add(fd->GetFilePath()); if (line_length > 100) { fileNameString += wxT("\n"); line_length = 0; } fileNameString += fd->GetFileName(); if (n < selItems.GetCount() - 1) fileNameString += wxT(", "); line_length += fd->GetFileName().Length() + 2; } MultilineTextDialog tDialog( this, wxT("Delete files(s)/dir(s)?"), wxT("Confirm deleting?"), fileNameString, wxTE_READONLY); if (tDialog.ShowModal() != wxID_OK) return false; for (n=0; nDeleteItem(selItems[n]); else { wxString msg = wxT("Sorry, unable to delete dir: \"")+filePaths[n]+wxT("\"\n"); msg += wxT("Perhaps it is not empty?"); int ret = wxMessageBox(msg, wxT("Error deleting dir"), wxOK|wxCANCEL|wxCENTRE|wxICON_INFORMATION, this); if (ret == wxCANCEL) break; } } else { if (CanWrite(filePaths[n]) && wxRemoveFile(filePaths[n])) m_fileCtrl->DeleteItem(selItems[n]); else { int ret = wxMessageBox(wxT("Sorry, unable to delete file : \"")+filePaths[n]+wxT("\""), wxT("Error deleting file"), wxOK|wxCANCEL|wxCENTRE|wxICON_INFORMATION, this); if (ret == wxCANCEL) break; } } } SetPath(GetPath()); // refresh views return true; } bool wxFileBrowser::CopyCutSelectedListItems(bool copy_them) { m_last_copy = copy_them; m_copycutFiles.Clear(); wxArrayInt selItems = GetSelectedListItems(); if ((int)selItems.GetCount() < 1) return false; for (size_t n=0; nGetItemData(selItems[n]); wxCHECK_MSG(fd, false, wxT("Invalid filedata item")); if (fd->GetFileName() != wxT("..")) { if (!m_last_copy) m_fileCtrl->SetItemState(selItems[n], wxLIST_MASK_STATE, wxLIST_STATE_CUT); m_copycutFiles.Add(wxFileData(*fd)); } } return m_copycutFiles.GetCount() > 0U; } bool wxFileBrowser::PasteCopyCutSelectedListItems() { wxString path = GetPath(true); for (size_t n=0; nFindItem(-1, srcFileName); if (!dst_file_exists || (item_id < 0)) { wxListItem item; item.m_itemId = m_fileCtrl->GetItemCount(); item.m_col = 0; wxFileData *fd = new wxFileData(dstFilePath, srcFileName, wxFileData::is_file, wxFileIconsTable::file); m_fileCtrl->Add(fd, item); } else { wxListItem item; item.m_itemId = item_id; m_fileCtrl->UpdateItem(item); } } SetPath(GetPath()); // refresh views return true; } void wxFileBrowser::OnTreeMenu(wxCommandEvent &event) { switch(event.GetId()) { case ID_wxFILEBROWSER_TREE_MENU_PROPERITES : { wxFileName fileName(m_dirCtrl->GetPath()); wxFileData fd(CreateFileData(fileName)); //if (!fd) return; ShowPropertiesDialog(fd); break; } default : break; } } void wxFileBrowser::OnListMenu(wxCommandEvent &event) { switch(event.GetId()) { case ID_wxFILEBROWSER_GO_BACK : { if (CanGoPathHistoryBackward()) GoPathHistoryBackward(); break; } case ID_wxFILEBROWSER_GO_FORWARD : { if (CanGoPathHistoryForward()) GoPathHistoryForward(); break; } case ID_wxFILEBROWSER_GO_UP : { if (CanGoUpDir()) GoUpDir(); break; } case ID_wxFILEBROWSER_GO_HOME : { GoToHomeDir(); break; } case ID_wxFILEBROWSER_REFRESH : { SetPath(GetPath(true)); break; } case wxID_OPEN : { wxFileData *fd = GetFocusedListItem(); if (!fd) return; OpenFilePath(fd->GetFilePath()); break; } case ID_wxFILEBROWSER_LIST_MENU_NEW_FOLDER : { m_fileCtrl->MakeDir(); SetPath(GetPath(true)); break; } case wxID_CUT : case wxID_COPY : { m_last_copy = event.GetId() == wxID_COPY; CopyCutSelectedListItems(m_last_copy); break; } case wxID_PASTE : { PasteCopyCutSelectedListItems(); break; } case ID_wxFILEBROWSER_LIST_MENU_DELETE : { DeleteSelectedListItems(true); break; } case ID_wxFILEBROWSER_LIST_MENU_RENAME : { long item = m_fileCtrl->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_FOCUSED); if (item >= 0) m_fileCtrl->EditLabel( item ); break; } case ID_wxFILEBROWSER_LIST_MENU_OPEN_WITH : { wxFileData *fd = GetFocusedListItem(); if (!fd) return; wxString cmd = GetOpenWithFileCmd(fd); if (!cmd.IsEmpty()) { long ret = wxExecute(cmd, wxEXEC_ASYNC, NULL); if (ret == 0) { wxMessageBox(wxT("Error running program"), wxT("Error running program"), wxOK, this); } } break; } case ID_wxFILEBROWSER_LIST_MENU_VIEW_FILE : { wxFileData *fd = GetFocusedListItem(); if (!fd) return; wxLogNull logNull; wxImage image(fd->GetFilePath()); if (image.Ok()) { wxDialog dialog(this, -1, wxT("Preview : ") + fd->GetFilePath(), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); wxScrolledWindow *scrWin = new wxScrolledWindow(&dialog, -1); wxStaticBitmap *statBitmap = new wxStaticBitmap(scrWin, -1, wxBitmap(image)); // not necessary in MSW int ext = 0; //dialog.GetSize().GetWidth() - dialog.GetClientSize().GetWidth(); wxRect clientRect = wxGetClientDisplayRect(); wxRect imageRect(0, 0, image.GetWidth()+ext, image.GetHeight()+ext); clientRect.Intersect(imageRect); dialog.SetClientSize(clientRect.width, clientRect.height); scrWin->SetScrollbars(1, 1, image.GetWidth(), image.GetHeight()); dialog.ShowModal(); break; } else // view as text { wxFrame* frame = new wxFrame(this, wxID_ANY, wxT("Text Viewer")); wxTextCtrl* textCtrl = new wxTextCtrl(frame, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_RICH|wxTE_READONLY); wxString s; wxFileInputStream inputStream(fd->GetFilePath()); wxTextInputStream textStream(inputStream); while (!inputStream.Eof()) { s += textStream.ReadLine() + wxT("\n"); if (s.Length() > 1000000) { wxMessageBox(wxT("This file is too large for the text viewer."), wxT("File truncated"), wxOK, this); break; } } textCtrl->AppendText(s); frame->Show(true); /* wxSTEditorOptions steOptions(STE_DEFAULT_OPTIONS); steOptions.GetMenuManager()->CreateForNotebook(); #if wxUSE_CONFIG wxConfigBase *config = wxConfigBase::Get(false); // don't create if (config) steOptions.LoadConfig(*config); #endif //wxUSE_CONFIG wxSTEditorFrame *editor = new wxSTEditorFrame(this, wxID_ANY, wxT("Editor")); editor->CreateOptions(steOptions); editor->GetEditor()->LoadFile(fd->GetFilePath()); editor->Centre(); editor->Show(true); */ } break; } case ID_wxFILEBROWSER_LIST_MENU_PROPERITES : { wxFileData *fd = GetFocusedListItem(); if (!fd) return; ShowPropertiesDialog(*fd); break; } case ID_wxFILEBROWSER_SHOW_HIDDEN : ShowHidden(event.IsChecked()); break; case ID_wxFILEBROWSER_SHOW_FOLDERS : ShowFolders(event.IsChecked()); break; case ID_wxFILEBROWSER_SPLIT_VERTICAL : SplitVertical(event.IsChecked()); break; default : break; } } void wxFileBrowser::OnViewButtons(wxCommandEvent &event) { switch (event.GetId()) { case ID_wxFILEBROWSER_VIEW_BUTTON : { wxWindow *win = (wxWindow*)event.GetEventObject(); if (win) win->PopupMenu(m_viewMenu, wxPoint(0, win->GetSize().y)); /* wxToolBar *win = (wxToolBar*)event.GetEventObject(); { wxSize toolSize(win->GetToolSize()); wxSize marginSize(win->GetMargins()); int pack = win->GetToolPacking(); int sep = win->GetToolSeparation(); wxPrintf(wxT(" %d %d, %d %d, %d %d\n"), toolSize.x, toolSize.y, marginSize.x, marginSize.y, pack, sep); win->PopupMenu(m_viewMenu, wxPoint(toolSize.x*5 + 2*marginSize.x, win->GetSize().y-marginSize.y)); } */ break; } case ID_wxFILEBROWSER_VIEW_TREE : case ID_wxFILEBROWSER_VIEW_LIST : case ID_wxFILEBROWSER_VIEW_DETAILS : case ID_wxFILEBROWSER_VIEW_SMALL_ICON : case ID_wxFILEBROWSER_VIEW_LARGE_ICON : case ID_wxFILEBROWSER_VIEW_PREVIEW : { long style = MenuIDToFBStyle(event.GetId()); style |= (m_browser_style & (~wxFILEBROWSER_VIEW_MASK)); SetBrowserStyle(style); break; } default : event.Skip(); break; } } void wxFileBrowser::OnPathCombo(wxCommandEvent &event) { // gtk sends events for just dropping the box if (m_pathComboSelection == event.GetSelection()) return; m_pathComboSelection = event.GetSelection(); // be overly cautious, GTK combo sends events and in some cases leads to a loop // it also doesn't like to have selection changed inside this handler wxCommandEvent setevent( wxEVT_COMMAND_MENU_SELECTED, ID_wxFILEBROWSER_COMBOSETPATH ); setevent.SetString(event.GetString()); GetEventHandler()->AddPendingEvent(setevent); } void wxFileBrowser::OnPathComboEnter(wxCommandEvent &WXUNUSED(event)) { OpenFilePath(m_pathCombo->GetValue()); } void wxFileBrowser::OnSetPath( wxCommandEvent &event ) { SetPath(event.GetString()); m_pathComboSelection = m_pathCombo->GetSelection(); } bool wxFileBrowser::OpenFilePath(const wxString &filePath) { wxString path = filePath; if (path.IsEmpty() || (path.Find(wxT('|')) != wxNOT_FOUND)) return false; bool want_dir = (path.Last() == wxFILE_SEP_PATH); if (want_dir) path = path.RemoveLast(); // Get home dir of user for ~ #ifdef __UNIX__ if (path == wxT("~")) { path = wxGetUserHome(); } else if (path.BeforeFirst(wxT('/')) == wxT("~")) { path = wxGetUserHome() + path.Remove(0, 1); } #endif // __UNIX__ // deal with ../ and what not if (path.Contains(wxT(".."))) { // path is just ".." or "../" if (path == wxT("..")) path = GetPath(false).BeforeLast(wxFILE_SEP_PATH); // path is "../some/dir" - note: no need to check for at least 3 chars else if ((path.Mid(0, 3) == wxString(wxT("..")) + wxFILE_SEP_PATH)) path = GetPath(false).BeforeLast(wxFILE_SEP_PATH) + wxFILE_SEP_PATH + path.AfterFirst(wxFILE_SEP_PATH); // path is "/some/where/.." else if (path.Mid(path.Len()-3) == wxFILE_SEP_PATH + wxString(wxT(".."))) path = path.BeforeLast(wxFILE_SEP_PATH).BeforeLast(wxFILE_SEP_PATH); else return false; } wxFileName filename(path); if (filename.DirExists()) { SetPath(path); return true; } // They really wanted a dir, but it doesn't exist if (want_dir) return false; // if it's a file then just "load" it if (filename.FileExists()) { //SetPath(filename.GetPath()); long item = m_fileCtrl->FindItem(-1, filename.GetName(), false); if (item >= 0) { m_fileCtrl->SetItemState(item, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED); m_fileCtrl->EnsureVisible( item ); } wxFileBrowserEvent fbEvent(wxEVT_FILEBROWSER_FILE_ACTIVATED, this, GetId()); fbEvent.SetFilePath(path); DoSendEvent(fbEvent); } return true; } bool wxFileBrowser::InsertComboItem(wxComboBox *combo, const wxString &item, int pos) const { int combo_index = combo->FindString(item); if (combo_index == wxNOT_FOUND) combo->Insert(item, pos, (void*)NULL); else if ((combo_index == pos) || (combo_index < pos)) return true; else if (combo_index > pos) { wxString *data = (wxString*) combo->GetClientData(combo_index); combo->Delete(combo_index); combo->Insert(item, pos, (void*)data); } if (combo->GetSelection() != pos) combo->SetSelection(pos); return true; } bool wxFileBrowser::SetFilter( int n ) { wxCHECK_MSG((n>=0) && (nGetCount())), false, wxT("Invalid filter item")); wxString filter = m_filterCombo->GetString(n); wxString *data = (wxString*)m_filterCombo->GetClientData(n); if (data && !data->IsEmpty()) filter += wxT("|") + (*data); else filter += wxT("|") + filter; AddFilter(filter); return true; } bool wxFileBrowser::AddFilter(const wxString &filter_) { wxString filter(filter_); if (filter.IsEmpty()) filter = wxFileSelectorDefaultWildcardStr; if (filter.Find(wxT('|')) == wxNOT_FOUND) filter += wxT("|") + filter; m_filter = filter; InsertComboItem(m_filterCombo, filter.BeforeFirst(wxT('|')), m_init_filters); m_filterComboSelection = m_filterCombo->GetSelection(); if ((m_dirCtrl->GetWindowStyleFlag() & wxDIRCTRL_DIR_ONLY) == 0) { m_ignore_tree_event = true; wxString currentPath = GetPath(false); m_dirCtrl->SetFilter(GetFilter()); m_dirCtrl->ReCreateTree(); m_dirCtrl->ExpandPath(currentPath); m_ignore_tree_event = false; } m_fileCtrl->SetWild(GetWild()); return true; } bool wxFileBrowser::SetFilters(const wxString &filter, int select) { wxArrayString filterNames; wxArrayString filterArray; if (filter.IsEmpty() || (::wxParseCommonDialogsFilter(filter, filterNames, filterArray) == 0)) { filterNames.Add(wxT("All files (")+wxString(wxFileSelectorDefaultWildcardStr)+wxT(")")); filterArray.Add(wxFileSelectorDefaultWildcardStr); } wxCHECK_MSG(select < int(filterNames.GetCount()), false, wxT("Invalid filter selection")); m_filter = filterNames[select] + wxT("|") + filterArray[select]; m_init_filters = filterArray.GetCount(); // delete old filters if any int n, count = m_filterCombo->GetCount(); for ( n = 0; n < count; n++ ) { wxString *data = (wxString*)m_filterCombo->GetClientData(n); delete data; } for ( n = 0; n < m_init_filters; n++ ) m_filterCombo->Append(filterNames[n], (void*)new wxString(filterArray[n])); m_filterCombo->SetSelection(select); m_filterComboSelection = select; if (!m_dirCtrl) return true; // This is during creation return SetFilter(select); } void wxFileBrowser::OnFilterComboEnter(wxCommandEvent &event) { if (event.GetString().Find(wxT('|')) == wxNOT_FOUND) AddFilter(event.GetString() + wxT("|") + event.GetString()); } void wxFileBrowser::OnFilterCombo(wxCommandEvent &event) { int sel = event.GetSelection(); // gtk combo sends events when the combo is opened... ignore them if ((sel < 0) || (sel == m_filterComboSelection)) return; m_filterComboSelection = sel; wxString filter = event.GetString(); wxString *data = (wxString*)m_filterCombo->GetClientData(sel); if (data && !data->IsEmpty()) filter += wxT("|") + (*data); else filter += wxT("|") + filter; // see OnPathCombo for why it's done this way wxCommandEvent setevent( wxEVT_COMMAND_MENU_SELECTED, ID_wxFILEBROWSER_COMBOSETFILTER ); setevent.SetString(filter); setevent.SetInt(data && !data->IsEmpty() ? sel : -1); GetEventHandler()->AddPendingEvent(setevent); } void wxFileBrowser::OnSetFilter( wxCommandEvent &event ) { if ( event.GetInt() != -1) SetFilter(event.GetInt()); else AddFilter(event.GetString()); } bool wxFileBrowser::DoSendEvent(wxFileBrowserEvent &event) const { return !GetEventHandler()->ProcessEvent(event); // || event.IsAllowed(); } #if wxUSE_CONFIG void wxFileBrowser::LoadConfig(wxConfigBase& config, bool paths, bool filters, const wxString &configPath ) { wxString value, key; key = configPath + wxT("/style"); if (config.Read(key, &value) && (!value.IsEmpty())) { long lvalue = 0; if (value.ToLong(&lvalue)) { SetBrowserStyle(lvalue); } } if (paths) { int n = 0; key = configPath + wxString::Format(wxT("/dir%d"), 1+n); while ((n < 21) && config.Read(key, &value) && (!value.IsEmpty())) { value.Trim(false).Trim(true); if (!value.IsEmpty()) { if (value.Last() != wxFILE_SEP_PATH) value += wxFILE_SEP_PATH; //if (wxDirExists(value)) { if (m_pathCombo->FindString(value) == wxNOT_FOUND) m_pathCombo->Append(value, (void*)NULL); } } n++; key = configPath + wxString::Format(wxT("/dir%d"), 1+n); value = wxEmptyString; } } if (filters) { int n = 0; key = configPath + wxString::Format(wxT("/filter%d"), 1+n); while ((n < 21) && config.Read(key, &value) && (!value.IsEmpty())) { value.Trim(false).Trim(true); if (!value.IsEmpty()) { if (m_filterCombo->FindString(value) == wxNOT_FOUND) m_filterCombo->Append(value, (void*)NULL); } n++; key = configPath + wxString::Format(wxT("/filter%d"), 1+n); value = wxEmptyString; } } } void wxFileBrowser::SaveConfig(wxConfigBase& config, int n_paths, int n_filters, const wxString &configPath) { wxString value, key; key = configPath + wxT("/style"); config.Write(key, GetBrowserStyle()); if (n_paths > 0) { int n, item = 1, count = m_pathCombo->GetCount(); for (n = 0; (n < count) && (item < n_paths); n++) { value = m_pathCombo->GetString(n); if (!value.IsEmpty()) { config.Write(configPath + wxString::Format(wxT("/dir%d"), item), value); item++; } } } if (n_filters > 0) { int n, item = 1, count = m_filterCombo->GetCount(); for (n = 0; (n < count) && (item < n_filters); n++) { // don't save the initial filters since they are programmed in wxString *data = (wxString*)m_filterCombo->GetClientData(n); if (data) continue; value = m_filterCombo->GetString(n); if (!value.IsEmpty()) { config.Write(configPath + wxString::Format(wxT("/filter%d"), item), value); item++; } } } } #endif // wxUSE_CONFIG void wxFileBrowser::ShowPropertiesDialog(const wxFileData &fileData) const { wxFilePropertiesDialog propDialog((wxWindow*)this, wxID_ANY, fileData, fileData.GetFileName() + wxT(" Properties"), wxDEFAULT_DIALOG_STYLE, wxDefaultPosition); propDialog.Centre(); propDialog.ShowModal(); } wxString wxFileBrowser::GetOpenWithFileCmd(wxFileData* fd) const { wxCHECK_MSG(fd, wxEmptyString, wxT("Invalid wxFileData for GetOpenWithFileCmd")); OpenWithDialog dialog((wxWindow*)this, wxID_ANY, *fd); dialog.ShowModal(); return dialog.GetOpenCommand(); }