diff --git a/include/wx/generic/panelg.h b/include/wx/generic/panelg.h index de9db536e2..eda2bd5abd 100644 --- a/include/wx/generic/panelg.h +++ b/include/wx/generic/panelg.h @@ -1,6 +1,6 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: panelg.h -// Purpose: wxPanel: similar to wxWindows but is coloured as for a dialog +// Name: wx/generic/panelg.h +// Purpose: wxPanel: a container for child controls // Author: Julian Smart // Modified by: // Created: 01/02/97 @@ -13,14 +13,23 @@ #define _WX_GENERIC_PANEL_H_ #ifdef __GNUG__ -#pragma interface "panelg.h" + #pragma interface "panelg.h" #endif +// ---------------------------------------------------------------------------- +// headers and forward declarations +// ---------------------------------------------------------------------------- + #include "wx/window.h" -#include "wx/button.h" + +class WXDLLEXPORT wxButton; WXDLLEXPORT_DATA(extern const wxChar*) wxPanelNameStr; +// ---------------------------------------------------------------------------- +// wxPanel contains other controls and implements TAB traversal between them +// ---------------------------------------------------------------------------- + class WXDLLEXPORT wxPanel : public wxWindow { public: @@ -106,5 +115,8 @@ private: DECLARE_EVENT_TABLE() }; +// this function is for wxWindows use only +extern bool wxSetFocusToChild(wxWindow *win, wxWindow **child); + #endif // _WX_GENERIC_PANEL_H_ diff --git a/include/wx/msw/frame.h b/include/wx/msw/frame.h index f17f7e57df..410081887e 100644 --- a/include/wx/msw/frame.h +++ b/include/wx/msw/frame.h @@ -149,6 +149,9 @@ protected: static bool m_useNativeStatusBar; #endif // wxUSE_STATUSBAR + // the last focused child: we restore focus to it on activation + wxWindow *m_winLastFocused; + // Data to save/restore when calling ShowFullScreen long m_fsStyle; // Passed to ShowFullScreen wxRect m_fsOldSize; diff --git a/src/generic/calctrl.cpp b/src/generic/calctrl.cpp index 4976d204b0..f2ecd265a1 100644 --- a/src/generic/calctrl.cpp +++ b/src/generic/calctrl.cpp @@ -564,7 +564,7 @@ void wxCalendarCtrl::OnPaint(wxPaintEvent& WXUNUSED(event)) RecalcGeometry(); #if DEBUG_PAINT - printf("--- starting to paint, selection: %s, week %u\n", + wxLogDebug("--- starting to paint, selection: %s, week %u\n", m_date.Format("%a %d-%m-%Y %H:%M:%S").c_str(), GetWeek(m_date)); #endif @@ -573,7 +573,7 @@ void wxCalendarCtrl::OnPaint(wxPaintEvent& WXUNUSED(event)) if ( IsExposed(0, 0, 7*m_widthCol, m_heightRow) ) { #if DEBUG_PAINT - puts("painting the header"); + wxLogDebug("painting the header"); #endif dc.SetBackgroundMode(wxTRANSPARENT); @@ -603,7 +603,7 @@ void wxCalendarCtrl::OnPaint(wxPaintEvent& WXUNUSED(event)) wxDateTime date = GetStartDate(); #if DEBUG_PAINT - printf("starting calendar from %s\n", + wxLogDebug("starting calendar from %s\n", date.Format("%a %d-%m-%Y %H:%M:%S").c_str()); #endif @@ -619,7 +619,7 @@ void wxCalendarCtrl::OnPaint(wxPaintEvent& WXUNUSED(event)) } #if DEBUG_PAINT - printf("painting week %d at y = %d\n", nWeek, y); + wxLogDebug("painting week %d at y = %d\n", nWeek, y); #endif for ( size_t wd = 0; wd < 7; wd++ ) @@ -732,7 +732,7 @@ void wxCalendarCtrl::OnPaint(wxPaintEvent& WXUNUSED(event)) } } #if DEBUG_PAINT - puts("+++ finished painting"); + wxLogDebug("+++ finished painting"); #endif } @@ -750,8 +750,17 @@ void wxCalendarCtrl::RefreshDate(const wxDateTime& date) rect.width = 7*m_widthCol; rect.height = m_heightRow; +#ifdef __WXMSW__ + // VZ: for some reason, the selected date seems to occupy more space under + // MSW - this is probably some bug in the font size calculations, but I + // don't know where exactly. This fix is ugly and leads to more + // refreshes than really needed, but without it the selected days + // leaves even more ugly underscores on screen. + rect.Inflate(0, 1); +#endif // MSW + #if DEBUG_PAINT - printf("*** refreshing week %d at (%d, %d)-(%d, %d)\n", + wxLogDebug("*** refreshing week %d at (%d, %d)-(%d, %d)\n", GetWeek(date), rect.x, rect.y, rect.x + rect.width, rect.y + rect.height); diff --git a/src/generic/grid.cpp b/src/generic/grid.cpp index 2a1c2e2688..c60fcffc49 100644 --- a/src/generic/grid.cpp +++ b/src/generic/grid.cpp @@ -604,20 +604,72 @@ void wxGridCellTextEditor::StartingKey(wxKeyEvent& event) if ( !event.AltDown() && !event.MetaDown() && !event.ControlDown() ) { // insert the key in the control + wxChar ch; int keycode = (int)event.KeyCode(); - if ( isprint(keycode) && keycode < 256 && keycode >= 0 ) + switch ( keycode ) { - // FIXME this is not going to work for non letters... - if ( !event.ShiftDown() ) - { - keycode = tolower(keycode); - } + case WXK_NUMPAD0: + case WXK_NUMPAD1: + case WXK_NUMPAD2: + case WXK_NUMPAD3: + case WXK_NUMPAD4: + case WXK_NUMPAD5: + case WXK_NUMPAD6: + case WXK_NUMPAD7: + case WXK_NUMPAD8: + case WXK_NUMPAD9: + ch = _T('0') + keycode - WXK_NUMPAD0; + break; - Text()->AppendText((wxChar)keycode); + case WXK_MULTIPLY: + case WXK_NUMPAD_MULTIPLY: + ch = _T('*'); + break; - return; + case WXK_ADD: + case WXK_NUMPAD_ADD: + ch = _T('+'); + break; + + case WXK_SUBTRACT: + case WXK_NUMPAD_SUBTRACT: + ch = _T('-'); + break; + + case WXK_DECIMAL: + case WXK_NUMPAD_DECIMAL: + ch = _T('.'); + break; + + case WXK_DIVIDE: + case WXK_NUMPAD_DIVIDE: + ch = _T('/'); + break; + + default: + if ( keycode < 256 && keycode >= 0 && isprint(keycode) ) + { + // FIXME this is not going to work for non letters... + if ( !event.ShiftDown() ) + { + keycode = tolower(keycode); + } + + ch = (wxChar)keycode; + } + else + { + ch = _T('\0'); + } } + if ( ch ) + { + Text()->AppendText(ch); + + // skip event.Skip() below + return; + } } event.Skip(); @@ -5284,15 +5336,9 @@ void wxGrid::OnKeyDown( wxKeyEvent& event ) default: // alphanumeric keys or F2 (special key just for this) enable // the cell edit control - // On just Shift/Control I get values for event.KeyCode() - // that are outside the range where isalnum's behaviour is - // well defined, so do an additional sanity check. if ( !(event.AltDown() || event.MetaDown() || event.ControlDown()) && - ((isalnum((int)event.KeyCode()) && - (event.KeyCode() < 256 && event.KeyCode() >= 0)) || - event.KeyCode() == WXK_F2 || event.KeyCode() == WXK_SPACE) && !IsCellEditControlEnabled() && CanEnableCellControl() ) { @@ -6024,19 +6070,28 @@ bool wxGrid::IsCellEditControlEnabled() const bool wxGrid::IsCellEditControlShown() const { - if (m_cellEditCtrlEnabled) + bool isShown = FALSE; + + if ( m_cellEditCtrlEnabled ) { int row = m_currentCellCoords.GetRow(); int col = m_currentCellCoords.GetCol(); wxGridCellAttr* attr = GetCellAttr(row, col); wxGridCellEditor* editor = attr->GetEditor((wxGrid*) this, row, col); - if ( editor && editor->IsCreated() ) + attr->DecRef(); + + if ( editor ) { - wxWindow *control = editor->GetControl(); - return control->IsShown(); + if ( editor->IsCreated() ) + { + isShown = editor->GetControl()->IsShown(); + } + + editor->DecRef(); } } - return FALSE; + + return isShown; } void wxGrid::ShowCellEditControl() diff --git a/src/generic/logg.cpp b/src/generic/logg.cpp index 99a3797604..4abdb81ed3 100644 --- a/src/generic/logg.cpp +++ b/src/generic/logg.cpp @@ -121,7 +121,7 @@ private: }; BEGIN_EVENT_TABLE(wxLogDialog, wxDialog) - EVT_BUTTON(wxID_OK, wxLogDialog::OnOk) + EVT_BUTTON(wxID_CANCEL, wxLogDialog::OnOk) EVT_BUTTON(wxID_MORE, wxLogDialog::OnDetails) #if wxUSE_FILE EVT_BUTTON(wxID_SAVE, wxLogDialog::OnSave) @@ -727,7 +727,10 @@ wxLogDialog::wxLogDialog(wxWindow *parent, wxBoxSizer *sizerButtons = new wxBoxSizer(wxVERTICAL); wxBoxSizer *sizerAll = new wxBoxSizer(wxHORIZONTAL); - wxButton *btnOk = new wxButton(this, wxID_OK, _("OK")); + // this "Ok" button has wxID_CANCEL id - not very logical, but this allows + // to close the log dialog with which wouldn't work otherwise (as it + // translates into click on cancel button) + wxButton *btnOk = new wxButton(this, wxID_CANCEL, _("OK")); sizerButtons->Add(btnOk, 0, wxCENTRE|wxBOTTOM, MARGIN/2); m_btnDetails = new wxButton(this, wxID_MORE, ms_details + _T(" >>")); sizerButtons->Add(m_btnDetails, 0, wxCENTRE|wxTOP, MARGIN/2 - 1); diff --git a/src/generic/panelg.cpp b/src/generic/panelg.cpp index 9e8363baa9..6895eca38f 100644 --- a/src/generic/panelg.cpp +++ b/src/generic/panelg.cpp @@ -340,39 +340,58 @@ void wxPanel::OnFocus(wxFocusEvent& event) bool wxPanel::SetFocusToChild() { - if ( m_winLastFocused ) + return wxSetFocusToChild(this, &m_winLastFocused); +} + +// ---------------------------------------------------------------------------- +// SetFocusToChild(): this function is used by wxPanel but also by wxFrame in +// wxMSW, this is why it is outside of wxPanel class +// ---------------------------------------------------------------------------- + +bool wxSetFocusToChild(wxWindow *win, wxWindow **childLastFocused) +{ + if ( *childLastFocused ) { // It might happen that the window got reparented or no longer accepts // the focus. - if ( (m_winLastFocused->GetParent() == this) && - m_winLastFocused->AcceptsFocus() ) + if ( (*childLastFocused)->GetParent() == win && + (*childLastFocused)->AcceptsFocus() ) { wxLogTrace(_T("focus"), _T("SetFocusToChild() => last child (0x%08x)."), - m_winLastFocused->GetHandle()); + (*childLastFocused)->GetHandle()); - m_winLastFocused->SetFocus(); + (*childLastFocused)->SetFocus(); return TRUE; } else { // it doesn't count as such any more - m_winLastFocused = (wxWindow *)NULL; + *childLastFocused = (wxWindow *)NULL; } } // set the focus to the first child who wants it - wxWindowList::Node *node = GetChildren().GetFirst(); + wxWindowList::Node *node = win->GetChildren().GetFirst(); while ( node ) { wxWindow *child = node->GetData(); - if ( child->AcceptsFocus() ) + + if ( child->AcceptsFocus() + && !child->IsTopLevel() +#if wxUSE_TOOLBAR + && !wxDynamicCast(child, wxToolBar) +#endif // wxUSE_TOOLBAR +#if wxUSE_STATUSBAR + && !wxDynamicCast(child, wxStatusBar) +#endif // wxUSE_STATUSBAR + ) { wxLogTrace(_T("focus"), _T("SetFocusToChild() => first child (0x%08x)."), child->GetHandle()); - m_winLastFocused = child; // should be redundant, but it is not + *childLastFocused = child; // should be redundant, but it is not child->SetFocus(); return TRUE; } diff --git a/src/msw/frame.cpp b/src/msw/frame.cpp index a22b5fa354..0e1cdfc829 100644 --- a/src/msw/frame.cpp +++ b/src/msw/frame.cpp @@ -38,6 +38,7 @@ #include "wx/settings.h" #include "wx/dcclient.h" #include "wx/mdi.h" + #include "wx/panel.h" #endif // WX_PRECOMP #include "wx/msw/private.h" @@ -110,6 +111,8 @@ void wxFrame::Init() m_fsIsMaximized = FALSE; m_fsIsShowing = FALSE; + m_winLastFocused = (wxWindow *)NULL; + // unlike (almost?) all other windows, frames are created hidden m_isShown = FALSE; } @@ -703,37 +706,32 @@ bool wxFrame::MSWCreate(int id, wxWindow *parent, const wxChar *wclass, wxWindow // subwindow found. void wxFrame::OnActivate(wxActivateEvent& event) { - if ( !event.GetActive() ) + if ( event.GetActive() ) { - event.Skip(); + // restore focus to the child which was last focused + wxLogTrace(_T("focus"), _T("wxFrame %08x activated."), m_hWnd); - return; + wxSetFocusToChild(this, &m_winLastFocused); } - - wxLogTrace(_T("focus"), _T("wxFrame %08x activated."), m_hWnd); - - for ( wxWindowList::Node *node = GetChildren().GetFirst(); - node; - node = node->GetNext() ) + else { - // FIXME all this is totally bogus - we need to do the same as wxPanel, - // but how to do it without duplicating the code? - - // restore focus - wxWindow *child = node->GetData(); - - if ( !child->IsTopLevel() -#if wxUSE_TOOLBAR - && !wxDynamicCast(child, wxToolBar) -#endif // wxUSE_TOOLBAR -#if wxUSE_STATUSBAR - && !wxDynamicCast(child, wxStatusBar) -#endif // wxUSE_STATUSBAR - ) + // remember the last focused child + m_winLastFocused = FindFocus(); + while ( m_winLastFocused ) { - child->SetFocus(); - break; + if ( GetChildren().Find(m_winLastFocused) ) + break; + + m_winLastFocused = m_winLastFocused->GetParent(); } + + wxLogTrace(_T("focus"), + _T("wxFrame %08x deactivated, last focused: %08x."), + m_hWnd, + m_winLastFocused ? GetHwndOf(m_winLastFocused) + : NULL); + + event.Skip(); } } diff --git a/src/msw/window.cpp b/src/msw/window.cpp index c6aeabb79e..b91c46ffd0 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -3543,80 +3543,82 @@ void wxGetCharSize(WXHWND wnd, int *x, int *y, const wxFont *the_font) // the key should be ignored by WM_KEYDOWN and processed by WM_CHAR instead. int wxCharCodeMSWToWX(int keySym) { - int id = 0; + int id; switch (keySym) { - case VK_CANCEL: id = WXK_CANCEL; break; - case VK_BACK: id = WXK_BACK; break; - case VK_TAB: id = WXK_TAB; break; - case VK_CLEAR: id = WXK_CLEAR; break; - case VK_RETURN: id = WXK_RETURN; break; - case VK_SHIFT: id = WXK_SHIFT; break; - case VK_CONTROL: id = WXK_CONTROL; break; - case VK_MENU : id = WXK_MENU; break; - case VK_PAUSE: id = WXK_PAUSE; break; - case VK_SPACE: id = WXK_SPACE; break; - case VK_ESCAPE: id = WXK_ESCAPE; break; - case VK_PRIOR: id = WXK_PRIOR; break; - case VK_NEXT : id = WXK_NEXT; break; - case VK_END: id = WXK_END; break; - case VK_HOME : id = WXK_HOME; break; - case VK_LEFT : id = WXK_LEFT; break; - case VK_UP: id = WXK_UP; break; - case VK_RIGHT: id = WXK_RIGHT; break; - case VK_DOWN : id = WXK_DOWN; break; - case VK_SELECT: id = WXK_SELECT; break; - case VK_PRINT: id = WXK_PRINT; break; - case VK_EXECUTE: id = WXK_EXECUTE; break; - case VK_INSERT: id = WXK_INSERT; break; - case VK_DELETE: id = WXK_DELETE; break; - case VK_HELP : id = WXK_HELP; break; - case VK_NUMPAD0: id = WXK_NUMPAD0; break; - case VK_NUMPAD1: id = WXK_NUMPAD1; break; - case VK_NUMPAD2: id = WXK_NUMPAD2; break; - case VK_NUMPAD3: id = WXK_NUMPAD3; break; - case VK_NUMPAD4: id = WXK_NUMPAD4; break; - case VK_NUMPAD5: id = WXK_NUMPAD5; break; - case VK_NUMPAD6: id = WXK_NUMPAD6; break; - case VK_NUMPAD7: id = WXK_NUMPAD7; break; - case VK_NUMPAD8: id = WXK_NUMPAD8; break; - case VK_NUMPAD9: id = WXK_NUMPAD9; break; - case VK_MULTIPLY: id = WXK_MULTIPLY; break; - case VK_ADD: id = WXK_ADD; break; - case VK_SUBTRACT: id = WXK_SUBTRACT; break; - case VK_DECIMAL: id = WXK_DECIMAL; break; - case VK_DIVIDE: id = WXK_DIVIDE; break; - case VK_F1: id = WXK_F1; break; - case VK_F2: id = WXK_F2; break; - case VK_F3: id = WXK_F3; break; - case VK_F4: id = WXK_F4; break; - case VK_F5: id = WXK_F5; break; - case VK_F6: id = WXK_F6; break; - case VK_F7: id = WXK_F7; break; - case VK_F8: id = WXK_F8; break; - case VK_F9: id = WXK_F9; break; - case VK_F10: id = WXK_F10; break; - case VK_F11: id = WXK_F11; break; - case VK_F12: id = WXK_F12; break; - case VK_F13: id = WXK_F13; break; - case VK_F14: id = WXK_F14; break; - case VK_F15: id = WXK_F15; break; - case VK_F16: id = WXK_F16; break; - case VK_F17: id = WXK_F17; break; - case VK_F18: id = WXK_F18; break; - case VK_F19: id = WXK_F19; break; - case VK_F20: id = WXK_F20; break; - case VK_F21: id = WXK_F21; break; - case VK_F22: id = WXK_F22; break; - case VK_F23: id = WXK_F23; break; - case VK_F24: id = WXK_F24; break; - case VK_NUMLOCK: id = WXK_NUMLOCK; break; - case VK_SCROLL: id = WXK_SCROLL; break; - default: - { - return 0; - } + case VK_CANCEL: id = WXK_CANCEL; break; + case VK_BACK: id = WXK_BACK; break; + case VK_TAB: id = WXK_TAB; break; + case VK_CLEAR: id = WXK_CLEAR; break; + case VK_RETURN: id = WXK_RETURN; break; + case VK_SHIFT: id = WXK_SHIFT; break; + case VK_CONTROL: id = WXK_CONTROL; break; + case VK_MENU : id = WXK_MENU; break; + case VK_PAUSE: id = WXK_PAUSE; break; + case VK_SPACE: id = WXK_SPACE; break; + case VK_ESCAPE: id = WXK_ESCAPE; break; + case VK_PRIOR: id = WXK_PRIOR; break; + case VK_NEXT : id = WXK_NEXT; break; + case VK_END: id = WXK_END; break; + case VK_HOME : id = WXK_HOME; break; + case VK_LEFT : id = WXK_LEFT; break; + case VK_UP: id = WXK_UP; break; + case VK_RIGHT: id = WXK_RIGHT; break; + case VK_DOWN : id = WXK_DOWN; break; + case VK_SELECT: id = WXK_SELECT; break; + case VK_PRINT: id = WXK_PRINT; break; + case VK_EXECUTE: id = WXK_EXECUTE; break; + case VK_INSERT: id = WXK_INSERT; break; + case VK_DELETE: id = WXK_DELETE; break; + case VK_HELP : id = WXK_HELP; break; + case VK_NUMPAD0: id = WXK_NUMPAD0; break; + case VK_NUMPAD1: id = WXK_NUMPAD1; break; + case VK_NUMPAD2: id = WXK_NUMPAD2; break; + case VK_NUMPAD3: id = WXK_NUMPAD3; break; + case VK_NUMPAD4: id = WXK_NUMPAD4; break; + case VK_NUMPAD5: id = WXK_NUMPAD5; break; + case VK_NUMPAD6: id = WXK_NUMPAD6; break; + case VK_NUMPAD7: id = WXK_NUMPAD7; break; + case VK_NUMPAD8: id = WXK_NUMPAD8; break; + case VK_NUMPAD9: id = WXK_NUMPAD9; break; + case VK_MULTIPLY: id = WXK_MULTIPLY; break; + case 0xBB: // VK_OEM_PLUS + case VK_ADD: id = WXK_ADD; break; + case 0xBD: // VK_OEM_MINUS + case VK_SUBTRACT: id = WXK_SUBTRACT; break; + case 0xBE: // VK_OEM_PERIOD + case VK_DECIMAL: id = WXK_DECIMAL; break; + case VK_DIVIDE: id = WXK_DIVIDE; break; + case VK_F1: id = WXK_F1; break; + case VK_F2: id = WXK_F2; break; + case VK_F3: id = WXK_F3; break; + case VK_F4: id = WXK_F4; break; + case VK_F5: id = WXK_F5; break; + case VK_F6: id = WXK_F6; break; + case VK_F7: id = WXK_F7; break; + case VK_F8: id = WXK_F8; break; + case VK_F9: id = WXK_F9; break; + case VK_F10: id = WXK_F10; break; + case VK_F11: id = WXK_F11; break; + case VK_F12: id = WXK_F12; break; + case VK_F13: id = WXK_F13; break; + case VK_F14: id = WXK_F14; break; + case VK_F15: id = WXK_F15; break; + case VK_F16: id = WXK_F16; break; + case VK_F17: id = WXK_F17; break; + case VK_F18: id = WXK_F18; break; + case VK_F19: id = WXK_F19; break; + case VK_F20: id = WXK_F20; break; + case VK_F21: id = WXK_F21; break; + case VK_F22: id = WXK_F22; break; + case VK_F23: id = WXK_F23; break; + case VK_F24: id = WXK_F24; break; + case VK_NUMLOCK: id = WXK_NUMLOCK; break; + case VK_SCROLL: id = WXK_SCROLL; break; + default: + id = 0; } + return id; }