From e63fdcd600e2eb717a19f9fa2895e9256e83c890 Mon Sep 17 00:00:00 2001 From: Julian Smart Date: Wed, 4 Oct 2000 12:53:28 +0000 Subject: [PATCH] Speed fix for wxGenericDirCtrl, starting to add text input control; added wxWS_EX_NO_AUTOFOCUS for wxMSW so we can stop wxToolBar accepting the focus; UI update improvement to send commands to current focus window; split tree control horiz. scrollbar problem fixed git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@8472 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- contrib/src/gizmos/splittree.cpp | 9 ++- include/wx/defs.h | 3 + include/wx/generic/dirctrlg.h | 13 +++- src/common/framecmn.cpp | 8 ++- src/common/tbarbase.cpp | 8 ++- src/common/wincmn.cpp | 2 +- src/generic/dirctrlg.cpp | 118 ++++++++++++++++++++++++++++++- src/msw/tbar95.cpp | 3 + src/msw/window.cpp | 3 +- 9 files changed, 155 insertions(+), 12 deletions(-) diff --git a/contrib/src/gizmos/splittree.cpp b/contrib/src/gizmos/splittree.cpp index b7197607b5..fbb3885081 100644 --- a/contrib/src/gizmos/splittree.cpp +++ b/contrib/src/gizmos/splittree.cpp @@ -338,7 +338,7 @@ void wxRemotelyScrolledTreeCtrl::OnScroll(wxScrollWinEvent& event) int orient = event.GetOrientation(); if (orient == wxHORIZONTAL) { - // Don't 'skip' or we'd get into infinite recursion + event.Skip(); return; } wxScrolledWindow* scrollWin = GetScrolledWindow(); @@ -439,7 +439,7 @@ void wxTreeCompanionWindow::OnScroll(wxScrollWinEvent& event) int orient = event.GetOrientation(); if (orient == wxHORIZONTAL) { - // Don't 'skip' or we'd get into infinite recursion + event.Skip(); return; } if (!m_treeCtrl) @@ -585,8 +585,13 @@ void wxSplitterScrolledWindow::OnScroll(wxScrollWinEvent& event) if (orient == wxHORIZONTAL) { + inOnScroll = FALSE; + event.Skip(); + return; +#if 0 int newPos = m_xScrollPosition + nScrollInc; SetScrollPos(wxHORIZONTAL, newPos, TRUE ); +#endif } else { diff --git a/include/wx/defs.h b/include/wx/defs.h index b850a396d0..d92fe25fb8 100644 --- a/include/wx/defs.h +++ b/include/wx/defs.h @@ -897,6 +897,9 @@ enum wxStretch // descend into all subwindows #define wxWS_EX_VALIDATE_RECURSIVELY 0x00000001 +// Don't automatically set the focus when left-clicking on the window +#define wxWS_EX_NO_AUTOFOCUS 0x10000000 + /* * wxFrame/wxDialog style flags */ diff --git a/include/wx/generic/dirctrlg.h b/include/wx/generic/dirctrlg.h index 427983e15e..cfc86d1430 100644 --- a/include/wx/generic/dirctrlg.h +++ b/include/wx/generic/dirctrlg.h @@ -27,7 +27,7 @@ // classes //----------------------------------------------------------------------------- -class wxDirItemData; +//class wxDirItemData; class wxDirCtrl; //----------------------------------------------------------------------------- @@ -224,9 +224,14 @@ public: wxGenericDirDialog(wxWindow* parent, const wxString& title, const wxString& defaultPath = wxEmptyString, long style = wxDEFAULT_DIALOG_STYLE, const wxPoint& pos = wxDefaultPosition, const wxSize& sz = wxSize(450, 550), const wxString& name = "dialog"); +//// Event handlers void OnCloseWindow(wxCloseEvent& event); void OnOK(wxCommandEvent& event); + void OnTreeSelected( wxTreeEvent &event ); + void OnTreeKeyDown( wxTreeEvent &event ); + void OnNew(wxCommandEvent& event); +//// Accessors inline void SetMessage(const wxString& message) { m_message = message; } void SetPath(const wxString& path) ; inline void SetStyle(long style) { m_dialogStyle = style; } @@ -235,11 +240,17 @@ public: wxString GetPath(void) const ; inline long GetStyle(void) const { return m_dialogStyle; } + wxTextCtrl* GetInputCtrl() const { return m_input; } + +//// Overrides + int ShowModal(); + protected: wxString m_message; long m_dialogStyle; wxString m_path; wxGenericDirCtrl* m_dirCtrl; + wxTextCtrl* m_input; }; diff --git a/src/common/framecmn.cpp b/src/common/framecmn.cpp index c7678d5b5f..b69ca51332 100644 --- a/src/common/framecmn.cpp +++ b/src/common/framecmn.cpp @@ -427,18 +427,20 @@ void wxFrameBase::DoMenuUpdates() { wxMenuBar* bar = GetMenuBar(); + wxWindow* focusWin = wxFindFocusDescendant((wxWindow*) this); + if ( bar != NULL ) { int nCount = bar->GetMenuCount(); for (int n = 0; n < nCount; n++) - DoMenuUpdates(bar->GetMenu(n), (wxWindow*) NULL); + DoMenuUpdates(bar->GetMenu(n), focusWin); } } // update a menu and all submenus recursively -void wxFrameBase::DoMenuUpdates(wxMenu* menu, wxWindow* WXUNUSED(focusWin)) +void wxFrameBase::DoMenuUpdates(wxMenu* menu, wxWindow* focusWin) { - wxEvtHandler* evtHandler = GetEventHandler(); + wxEvtHandler* evtHandler = focusWin ? focusWin->GetEventHandler() : GetEventHandler(); wxMenuItemList::Node* node = menu->GetMenuItems().GetFirst(); while (node) { diff --git a/src/common/tbarbase.cpp b/src/common/tbarbase.cpp index f66ce0f3b1..526c883fcc 100644 --- a/src/common/tbarbase.cpp +++ b/src/common/tbarbase.cpp @@ -526,7 +526,13 @@ void wxToolBarBase::OnIdle(wxIdleEvent& event) // Do the toolbar button updates (check for EVT_UPDATE_UI handlers) void wxToolBarBase::DoToolbarUpdates() { - wxEvtHandler* evtHandler = GetEventHandler(); + wxWindow* parent = this; + while (parent->GetParent()) + parent = parent->GetParent(); + + wxWindow* focusWin = wxFindFocusDescendant(parent); + + wxEvtHandler* evtHandler = focusWin ? focusWin->GetEventHandler() : GetEventHandler() ; for ( wxToolBarToolsList::Node* node = m_tools.GetFirst(); node; diff --git a/src/common/wincmn.cpp b/src/common/wincmn.cpp index ef975509ea..b95dde4a4b 100644 --- a/src/common/wincmn.cpp +++ b/src/common/wincmn.cpp @@ -421,7 +421,7 @@ wxSize wxWindowBase::DoGetBestSize() const node = node->GetNext() ) { wxWindow *win = node->GetData(); - if ( win->IsTopLevel() || wxDynamicCast(win, wxStatusBar) ) + if ( win->IsTopLevel() || wxDynamicCast(win, wxStatusBar) || !win->IsShown()) { // dialogs and frames lie in different top level windows - // don't deal with them here; as for the status bars, they diff --git a/src/generic/dirctrlg.cpp b/src/generic/dirctrlg.cpp index 173eb12a0e..b06515e348 100644 --- a/src/generic/dirctrlg.cpp +++ b/src/generic/dirctrlg.cpp @@ -338,7 +338,8 @@ wxDirItemDataEx::wxDirItemDataEx(const wxString& path, const wxString& name, * For FileNameFromPath read LastDirNameInThisPath ;-) */ // m_isHidden = (bool)(wxFileNameFromPath(*m_path)[0] == '.'); m_isHidden = FALSE; - m_hasSubDirs = HasSubDirs(); + // m_hasSubDirs is no longer needed + m_hasSubDirs = TRUE; // HasSubDirs(); m_isExpanded = FALSE; m_isDir = isDir; } @@ -353,6 +354,7 @@ void wxDirItemDataEx::SetNewDirName( wxString path ) m_name = wxFileNameFromPath( path ); } +// No longer used, and takes a very long time bool wxDirItemDataEx::HasSubDirs() { if (m_path.IsEmpty()) @@ -1179,7 +1181,11 @@ void wxDirFilterListCtrl::FillFilterList(const wxString& filter, int defaultFilt BEGIN_EVENT_TABLE(wxGenericDirDialog, wxDialog) EVT_BUTTON(wxID_OK, wxGenericDirDialog::OnOK) + EVT_BUTTON (wxID_NEW, wxGenericDirDialog::OnNew) EVT_CLOSE(wxGenericDirDialog::OnCloseWindow) + EVT_TREE_KEY_DOWN (ID_DIRCTRL, wxGenericDirDialog::OnTreeKeyDown) + EVT_TREE_SEL_CHANGED (ID_DIRCTRL, wxGenericDirDialog::OnTreeSelected) + EVT_TEXT_ENTER (ID_TEXTCTRL, wxGenericDirDialog::OnOK) END_EVENT_TABLE() wxGenericDirDialog::wxGenericDirDialog(wxWindow* parent, const wxString& title, @@ -1197,7 +1203,9 @@ wxGenericDirDialog::wxGenericDirDialog(wxWindow* parent, const wxString& title, topsizer->Add( m_dirCtrl, 1, wxTOP|wxLEFT|wxRIGHT | wxEXPAND, 10 ); - // 2) TODO: text control for entering path? + // 2) text ctrl + m_input = new wxTextCtrl( this, ID_TEXTCTRL, wxEmptyString, wxDefaultPosition ); + topsizer->Add( m_input, 0, wxTOP|wxLEFT|wxRIGHT | wxEXPAND, 10 ); #if wxUSE_STATLINE // 3) Static line @@ -1220,6 +1228,8 @@ wxGenericDirDialog::wxGenericDirDialog(wxWindow* parent, const wxString& title, okButton->SetDefault(); m_dirCtrl->SetFocus(); + m_input->SetValue(defaultPath); + SetAutoLayout( TRUE ); SetSizer( topsizer ); @@ -1236,7 +1246,36 @@ void wxGenericDirDialog::OnCloseWindow(wxCloseEvent& event) void wxGenericDirDialog::OnOK(wxCommandEvent& event) { - EndModal(wxID_OK); + m_path = m_input->GetValue(); + // Does the path exist? (User may have typed anything in m_input) + if (wxPathExists(m_path)) { + // OK, path exists, we're done. + EndModal(wxID_OK); + return; + } + // Interact with user, find out if the dir is a typo or to be created + wxString msg( _("The directory ") ); + msg = msg + m_path; + msg = msg + _("\ndoes not exist\nCreate it now?") ; + wxMessageDialog dialog(this, msg, _("Directory does not exist"), wxYES_NO | wxICON_WARNING ); + if ( dialog.ShowModal() == wxID_YES ) { + // Okay, let's make it + wxLogNull log; + if (wxMkdir(m_path)) { + // The new dir was created okay. + EndModal(wxID_OK); + return; + } + else { + // Trouble... + msg = _("Failed to create directory ")+m_path+ + _("\n(Do you have the required permissions?)"); + wxMessageDialog errmsg(this, msg, _("Error creating directory"), wxOK | wxICON_ERROR); + errmsg.ShowModal(); + // We still don't have a valid dir. Back to the main dialog. + } + } + // User has answered NO to create dir. } void wxGenericDirDialog::SetPath(const wxString& path) @@ -1248,3 +1287,76 @@ wxString wxGenericDirDialog::GetPath(void) const { return m_dirCtrl->GetPath(); } + +int wxGenericDirDialog::ShowModal() +{ + m_input->SetValue( m_path ); + return wxDialog::ShowModal(); +} + +void wxGenericDirDialog::OnTreeSelected( wxTreeEvent &event ) +{ + wxDirItemDataEx *data = (wxDirItemDataEx*)m_dirCtrl->GetTreeCtrl()->GetItemData(event.GetItem()); + if (data) + m_input->SetValue( data->m_path ); +}; + +void wxGenericDirDialog::OnTreeKeyDown( wxTreeEvent &WXUNUSED(event) ) +{ + wxDirItemDataEx *data = (wxDirItemDataEx*)m_dirCtrl->GetTreeCtrl()->GetItemData(m_dirCtrl->GetTreeCtrl()->GetSelection()); + if (data) + m_input->SetValue( data->m_path ); +}; + +void wxGenericDirDialog::OnNew( wxCommandEvent& WXUNUSED(event) ) +{ +#if 0 + wxTreeItemId id = m_dir->GetSelection(); + if ((id == m_dir->GetRootItem()) || + (m_dir->GetParent(id) == m_dir->GetRootItem())) + { + wxMessageDialog msg(this, _("You cannot add a new directory to this section."), + _("Create directory"), wxOK | wxICON_INFORMATION ); + msg.ShowModal(); + return; + } + + wxTreeItemId parent = m_dir->GetParent( id ); + wxDirItemData *data = (wxDirItemData*)m_dir->GetItemData( parent ); + wxASSERT( data ); + + wxString new_name( wxT("NewName") ); + wxString path( data->m_path ); + path += wxT("/"); + path += new_name; + if (wxFileExists(path)) + { + // try NewName0, NewName1 etc. + int i = 0; + do { + new_name = wxT("NewName"); + wxString num; + num.Printf( wxT("%d"), i ); + new_name += num; + + path = data->m_path; + path += wxT("/"); + path += new_name; + i++; + } while (wxFileExists(path)); + } + + wxLogNull log; + if (!wxMkdir(path)) + { + wxMessageDialog dialog(this, _("Operation not permitted."), _("Error"), wxOK | wxICON_ERROR ); + dialog.ShowModal(); + return; + } + + wxDirItemData *new_data = new wxDirItemData( path, new_name ); + wxTreeItemId new_id = m_dir->AppendItem( parent, new_name, 0, 1, new_data ); + m_dir->EnsureVisible( new_id ); + m_dir->EditLabel( new_id ); +#endif +} diff --git a/src/msw/tbar95.cpp b/src/msw/tbar95.cpp index 2a1a5e7ce1..57dc3bd15b 100644 --- a/src/msw/tbar95.cpp +++ b/src/msw/tbar95.cpp @@ -205,6 +205,9 @@ bool wxToolBar::Create(wxWindow *parent, long style, const wxString& name) { + // Don't want to grab the focus when we left click + SetExtraStyle(GetExtraStyle() | wxWS_EX_NO_AUTOFOCUS); + // common initialisation if ( !CreateControl(parent, id, pos, size, style, wxDefaultValidator, name) ) return FALSE; diff --git a/src/msw/window.cpp b/src/msw/window.cpp index c7b28bac0b..507019bbf8 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -1897,7 +1897,8 @@ long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam) case WM_LBUTTONDOWN: // set focus to this window - SetFocus(); + if ((GetExtraStyle() & wxWS_EX_NO_AUTOFOCUS) != wxWS_EX_NO_AUTOFOCUS) + SetFocus(); // fall through -- 2.45.2