diff --git a/include/wx/filehistory.h b/include/wx/filehistory.h index 9cd4be4034..a5756a7e09 100644 --- a/include/wx/filehistory.h +++ b/include/wx/filehistory.h @@ -24,6 +24,13 @@ class WXDLLIMPEXP_FWD_CORE wxMenu; class WXDLLIMPEXP_FWD_BASE wxConfigBase; class WXDLLIMPEXP_FWD_BASE wxFileName; +enum wxFileHistoryMenuPathStyle +{ + wxFH_PATH_SHOW_IF_DIFFERENT, + wxFH_PATH_SHOW_NEVER, + wxFH_PATH_SHOW_ALWAYS +}; + // ---------------------------------------------------------------------------- // File history management // ---------------------------------------------------------------------------- @@ -60,17 +67,26 @@ public: void SetBaseId(wxWindowID baseId) { m_idBase = baseId; } wxWindowID GetBaseId() const { return m_idBase; } + void SetMenuPathStyle(wxFileHistoryMenuPathStyle style); + wxFileHistoryMenuPathStyle GetMenuPathStyle() const { return m_menuPathStyle; } + protected: // Last n files - wxArrayString m_fileHistory; + wxArrayString m_fileHistory; // Menus to maintain (may need several for an MDI app) - wxList m_fileMenus; + wxList m_fileMenus; // Max files to maintain - size_t m_fileMaxFiles; + size_t m_fileMaxFiles; + + // Style of the paths in the menu labels + wxFileHistoryMenuPathStyle m_menuPathStyle; private: + void DoRefreshLabels(); + + // The ID of the first history menu item (Doesn't have to be wxID_FILE1) wxWindowID m_idBase; diff --git a/interface/wx/filehistory.h b/interface/wx/filehistory.h index 992a0a3174..21d38b686b 100644 --- a/interface/wx/filehistory.h +++ b/interface/wx/filehistory.h @@ -5,6 +5,41 @@ // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// +/** + Styles for the paths shown in wxFileHistory menus. + + The values of this enum determine whether the labels in the menu managed by + wxFileHistory show the full path for the corresponding file or just the + base name. + + The default style is wxFH_PATH_SHOW_IF_DIFFERENT, i.e. the full path of the + file is only shown in the menu if it's different from the path of the first + file. + + @since 3.1.5 +*/ +enum wxFileHistoryMenuPathStyle +{ + /** + Show the full path if it's different from the path of the first file. + + Otherwise show just the file name. + + This value corresponds to the default behaviour. + */ + wxFH_PATH_SHOW_IF_DIFFERENT, + + /** + Never show full path, always show just the base file name. + */ + wxFH_PATH_SHOW_NEVER, + + /** + Always show the full path for all files. + */ + wxFH_PATH_SHOW_ALWAYS +}; + /** @class wxFileHistory @@ -120,4 +155,26 @@ public: called, as this is not done automatically. */ virtual void UseMenu(wxMenu* menu); + + /** + Set the style of the menu item labels. + + By default, the menu item label style is ::wxFH_PATH_SHOW_IF_DIFFERENT. + + @since 3.1.5 + */ + void SetMenuPathStyle(wxFileHistoryMenuPathStyle style); + + /** + Get the current style of the menu item labels. + + Initially returns ::wxFH_PATH_SHOW_IF_DIFFERENT. + + @see SetMenuPathStyle() + + @since 3.1.5 + */ + wxFileHistoryMenuPathStyle GetMenuPathStyle() const; + + }; diff --git a/samples/menu/menu.cpp b/samples/menu/menu.cpp index 5189ec0161..f186b34966 100644 --- a/samples/menu/menu.cpp +++ b/samples/menu/menu.cpp @@ -23,6 +23,8 @@ #ifndef WX_PRECOMP #include "wx/app.h" #include "wx/bitmap.h" + #include "wx/filehistory.h" + #include "wx/filename.h" #include "wx/frame.h" #include "wx/image.h" #include "wx/menu.h" @@ -157,6 +159,12 @@ protected: void OnSize(wxSizeEvent& event); +#if wxUSE_FILE_HISTORY + void OnFileHistoryMenuItem(wxCommandEvent& event); + + void OnFileHistoryStyleItem(wxCommandEvent& event); +#endif + private: #if USE_LOG_WINDOW void LogMenuOpenCloseOrHighlight(const wxMenuEvent& event, const wxString& what); @@ -178,6 +186,11 @@ private: wxTextCtrl *m_textctrl; #endif +#if wxUSE_FILE_HISTORY + wxMenu* m_fileHistoryMenu; + wxFileHistory* m_fileHistory; +#endif + // the previous log target wxLog *m_logOld; @@ -286,6 +299,11 @@ enum #if wxUSE_TEXTDLG Menu_Menu_FindItem, #endif +#if wxUSE_FILE_HISTORY + Menu_Menu_FileHistory1, + Menu_Menu_FileHistory2, + Menu_Menu_FileHistory3, +#endif Menu_Test_Normal = 400, Menu_Test_Check, @@ -365,6 +383,16 @@ wxBEGIN_EVENT_TABLE(MyFrame, wxFrame) EVT_MENU(Menu_Test_Radio2, MyFrame::OnTestRadio) EVT_MENU(Menu_Test_Radio3, MyFrame::OnTestRadio) +#if wxUSE_FILE_HISTORY + EVT_MENU(wxID_FILE1, MyFrame::OnFileHistoryMenuItem) + EVT_MENU(wxID_FILE2, MyFrame::OnFileHistoryMenuItem) + EVT_MENU(wxID_FILE3, MyFrame::OnFileHistoryMenuItem) + + EVT_MENU(Menu_Menu_FileHistory1, MyFrame::OnFileHistoryStyleItem) + EVT_MENU(Menu_Menu_FileHistory2, MyFrame::OnFileHistoryStyleItem) + EVT_MENU(Menu_Menu_FileHistory3, MyFrame::OnFileHistoryStyleItem) +#endif + EVT_UPDATE_UI(Menu_SubMenu_Normal, MyFrame::OnUpdateSubMenuNormal) EVT_UPDATE_UI(Menu_SubMenu_Check, MyFrame::OnUpdateSubMenuCheck) EVT_UPDATE_UI(Menu_SubMenu_Radio1, MyFrame::OnUpdateSubMenuRadio) @@ -539,6 +567,27 @@ MyFrame::MyFrame() "Show a dialog"); fileMenu->AppendSeparator(); +#if wxUSE_FILE_HISTORY + m_fileHistoryMenu = new wxMenu(); + + m_fileHistory = new wxFileHistory(); + m_fileHistory->UseMenu(m_fileHistoryMenu); + + wxFileName fn( "menu.cpp" ); + fn.Normalize(); + m_fileHistory->AddFileToHistory( fn.GetFullPath() ); + + fn = "Makefile.in"; + fn.Normalize(); + m_fileHistory->AddFileToHistory( fn.GetFullPath() ); + + fn.Assign("minimal", "minimal", "cpp"); + fn.Normalize(); + m_fileHistory->AddFileToHistory( fn.GetFullPath() ); + + fileMenu->AppendSubMenu(m_fileHistoryMenu, "Sample file history"); +#endif + fileMenu->Append(Menu_File_Quit, "E&xit\tAlt-X", "Quit menu sample"); wxMenu *menubarMenu = new wxMenu; @@ -609,6 +658,16 @@ MyFrame::MyFrame() menuMenu->Append(Menu_Menu_FindItem, "Find menu item from label", "Find a menu item by searching for its label"); #endif +#if wxUSE_FILE_HISTORY + wxMenu* menuFileHistoryStyle = new wxMenu(); + + menuFileHistoryStyle->AppendRadioItem(Menu_Menu_FileHistory1, "Hide current path"); + menuFileHistoryStyle->AppendRadioItem(Menu_Menu_FileHistory2, "Hide all paths"); + menuFileHistoryStyle->AppendRadioItem(Menu_Menu_FileHistory3, "Show all paths"); + + menuMenu->AppendSeparator(); + menuMenu->AppendSubMenu(menuFileHistoryStyle, "Select file history menu style"); +#endif wxMenu *testMenu = new wxMenu; testMenu->Append(Menu_Test_Normal, "&Normal item"); @@ -689,6 +748,7 @@ MyFrame::MyFrame() MyFrame::~MyFrame() { + delete m_fileHistory; delete m_menu; // delete the event handler installed in ctor @@ -1317,6 +1377,36 @@ void MyFrame::OnSize(wxSizeEvent& WXUNUSED(event)) #endif // __WXUNIVERSAL__ } +#if wxUSE_FILE_HISTORY +void MyFrame::OnFileHistoryMenuItem(wxCommandEvent& event) +{ + int eventID = event.GetId(); + + wxString fname = m_fileHistory->GetHistoryFile(eventID - wxID_FILE1); + + wxMessageBox(wxString::Format("Selected file %s", fname), "File history activated", + wxOK | wxICON_INFORMATION); + + m_fileHistory->AddFileToHistory(fname); +} + +void MyFrame::OnFileHistoryStyleItem(wxCommandEvent& event) +{ + switch( event.GetId() ) + { + case Menu_Menu_FileHistory1: + m_fileHistory->SetMenuPathStyle(wxFH_PATH_SHOW_IF_DIFFERENT); + break; + case Menu_Menu_FileHistory2: + m_fileHistory->SetMenuPathStyle(wxFH_PATH_SHOW_NEVER); + break; + case Menu_Menu_FileHistory3: + m_fileHistory->SetMenuPathStyle(wxFH_PATH_SHOW_ALWAYS); + break; + } +} +#endif + // ---------------------------------------------------------------------------- // MyDialog // ---------------------------------------------------------------------------- diff --git a/src/common/filehistorycmn.cpp b/src/common/filehistorycmn.cpp index 929327768d..0c0070c938 100644 --- a/src/common/filehistorycmn.cpp +++ b/src/common/filehistorycmn.cpp @@ -70,6 +70,7 @@ wxFileHistoryBase::wxFileHistoryBase(size_t maxFiles, wxWindowID idBase) { m_fileMaxFiles = maxFiles; m_idBase = idBase; + m_menuPathStyle = wxFH_PATH_SHOW_IF_DIFFERENT; } /* static */ @@ -135,21 +136,44 @@ void wxFileHistoryBase::AddFileToHistory(const wxString& file) m_fileHistory.insert(m_fileHistory.begin(), file); numFiles++; - // update the labels in all menus - for ( i = 0; i < numFiles; i++ ) + DoRefreshLabels(); +} + +void wxFileHistoryBase::DoRefreshLabels() +{ + const size_t numFiles = m_fileHistory.size(); + + // If no files, then no need to refresh the menu + if ( numFiles == 0 ) + return; + + // Remember the path in case we need to compare with it below. + const wxString firstPath(wxFileName(m_fileHistory[0]).GetPath()); + + // Update the labels in all menus + for ( size_t i = 0; i < numFiles; i++ ) { - // if in same directory just show the filename; otherwise the full path - const wxFileName fnOld(m_fileHistory[i]); + const wxFileName currFn(m_fileHistory[i]); wxString pathInMenu; - if ( (fnOld.GetPath() == fnNew.GetPath()) && fnOld.HasName() ) + switch ( m_menuPathStyle ) { - pathInMenu = fnOld.GetFullName(); - } - else // file in different directory or it's not a file but a directory - { - // absolute path; could also set relative path - pathInMenu = m_fileHistory[i]; + case wxFH_PATH_SHOW_IF_DIFFERENT: + if ( currFn.HasName() && currFn.GetPath() == firstPath ) + pathInMenu = currFn.GetFullName(); + else + pathInMenu = currFn.GetFullPath(); + break; + + case wxFH_PATH_SHOW_NEVER: + // Only show the filename + extension and not the path. + pathInMenu = currFn.GetFullName(); + break; + + case wxFH_PATH_SHOW_ALWAYS: + // Always show full path. + pathInMenu = currFn.GetFullPath(); + break; } for ( wxList::compatibility_iterator node = m_fileMenus.GetFirst(); @@ -163,6 +187,15 @@ void wxFileHistoryBase::AddFileToHistory(const wxString& file) } } +void wxFileHistoryBase::SetMenuPathStyle(wxFileHistoryMenuPathStyle style) +{ + if ( style != m_menuPathStyle ) + { + m_menuPathStyle = style; + DoRefreshLabels(); + } +} + void wxFileHistoryBase::RemoveFileFromHistory(size_t i) { size_t numFiles = m_fileHistory.size();