]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/pickerbase.cpp
fix dereferencing end() iterator in ParseFormat() and constructing out of bound itera...
[wxWidgets.git] / src / common / pickerbase.cpp
index 3187ccdfe9049eeda94f692989e5f8fe6ff8fd3a..ec7d0a2cee57bf46573b55ce520dbbb901f90bdb 100644 (file)
     #pragma hdrstop
 #endif
 
+#if wxUSE_COLOURPICKERCTRL || \
+    wxUSE_DIRPICKERCTRL    || \
+    wxUSE_FILEPICKERCTRL   || \
+    wxUSE_FONTPICKERCTRL
+
 #include "wx/pickerbase.h"
+#include "wx/tooltip.h"
 
 #ifndef WX_PRECOMP
     #include "wx/textctrl.h"
 #endif
 
+
 // ============================================================================
 // implementation
 // ============================================================================
 
-IMPLEMENT_ABSTRACT_CLASS(wxPickerBase, wxWindow)
+IMPLEMENT_ABSTRACT_CLASS(wxPickerBase, wxControl)
+
+BEGIN_EVENT_TABLE(wxPickerBase, wxControl)
+    EVT_SIZE(wxPickerBase::OnSize)
+    WX_EVENT_TABLE_CONTROL_CONTAINER(wxPickerBase)
+END_EVENT_TABLE()
+WX_DELEGATE_TO_CONTROL_CONTAINER(wxPickerBase, wxControl)
+
 
 // ----------------------------------------------------------------------------
 // wxPickerBase
 // ----------------------------------------------------------------------------
 
-wxPickerBase::~wxPickerBase()
-{
-    // destroy the windows we are managing: these are not automatically
-    // destroyed by wxWindow because they are not built as our children
-    // but rather as children of the parent of the wxPickerBase class
-    // (since wxPickerBase does not represent a real window)
-    if (m_text) m_text->Destroy();
-    if (m_picker) m_picker->Destroy();
-}
-
 bool wxPickerBase::CreateBase(wxWindow *parent,
                          wxWindowID id,
                          const wxString &text,
@@ -62,17 +66,23 @@ bool wxPickerBase::CreateBase(wxWindow *parent,
     // remove any border style from our style as wxPickerBase's window must be
     // invisible (user styles must be set on the textctrl or the platform-dependent picker)
     style &= ~wxBORDER_MASK;
+    
     if (!wxControl::Create(parent, id, pos, size, style | wxNO_BORDER | wxTAB_TRAVERSAL,
-                            validator, name))
+                           validator, name))
         return false;
+        
+    SetMinSize( size );
+        
+    m_sizer = new wxBoxSizer(wxHORIZONTAL);
 
     if (HasFlag(wxPB_USE_TEXTCTRL))
     {
         // NOTE: the style of this class (wxPickerBase) and the style of the
         //       attached text control are different: GetTextCtrlStyle() extracts
         //       the styles related to the textctrl from the styles passed here
-        m_text = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxPoint(0, 0),
-                                wxSize(40, size.GetHeight()), GetTextCtrlStyle(style));
+        m_text = new wxTextCtrl(this, wxID_ANY, wxEmptyString,
+                                wxDefaultPosition, wxDefaultSize,
+                                GetTextCtrlStyle(style));
         if (!m_text)
         {
             wxFAIL_MSG( wxT("wxPickerBase's textctrl creation failed") );
@@ -89,114 +99,81 @@ bool wxPickerBase::CreateBase(wxWindow *parent,
         // set the initial contents of the textctrl
         m_text->SetValue(text);
 
-        m_text->Connect(wxEVT_COMMAND_TEXT_UPDATED,
+        m_text->Connect(m_text->GetId(), wxEVT_COMMAND_TEXT_UPDATED,
                 wxCommandEventHandler(wxPickerBase::OnTextCtrlUpdate),
                 NULL, this);
-        m_text->Connect(wxEVT_KILL_FOCUS,
+        m_text->Connect(m_text->GetId(), wxEVT_KILL_FOCUS,
                 wxFocusEventHandler(wxPickerBase::OnTextCtrlKillFocus),
                 NULL, this);
 
-        m_text->Connect(wxEVT_DESTROY,
+        m_text->Connect(m_text->GetId(), wxEVT_DESTROY,
                 wxWindowDestroyEventHandler(wxPickerBase::OnTextCtrlDelete),
                 NULL, this);
-    }
 
+        // the text control's proportion values defaults to 2
+        m_sizer->Add(m_text, 2, GetDefaultTextCtrlFlag(), 5);
+    }
+    
     return true;
 }
 
-void wxPickerBase::OnTextCtrlKillFocus(wxFocusEvent &)
+void wxPickerBase::PostCreation()
 {
-    wxASSERT(m_text);
+    // the picker's proportion value defaults to 1 when there's no text control
+    // associated with it - in that case it defaults to 0
+    m_sizer->Add(m_picker, HasTextCtrl() ? 0 : 1, GetDefaultPickerCtrlFlag(), 5);
 
-    // don't leave the textctrl empty
-    if (m_text->GetValue().empty())
-        UpdateTextCtrlFromPicker();
+    SetSizer(m_sizer);
+    
+    SetInitialSize( GetMinSize() );
 }
 
-void wxPickerBase::OnTextCtrlDelete(wxWindowDestroyEvent &)
-{
-    // the textctrl has been deleted; our pointer is invalid!
-    m_text = NULL;
-}
+#if wxUSE_TOOLTIPS
 
-void wxPickerBase::OnTextCtrlUpdate(wxCommandEvent &)
+void wxPickerBase::DoSetToolTip(wxToolTip *tip)
 {
-    // for each text-change, update the picker
-    UpdatePickerFromTextCtrl();
+    // don't set the tooltip on us but rather on our two child windows
+    // as otherwise it would appear only when the cursor is placed on the
+    // small area around the child windows which belong to wxPickerBase
+    m_picker->SetToolTip(tip);
+
+    // do a copy as wxWindow will own the pointer we pass
+    if ( m_text )
+        m_text->SetToolTip(tip ? new wxToolTip(tip->GetTip()) : NULL);
 }
 
-int wxPickerBase::GetTextCtrlWidth(int given)
-{
-    // compute the width of m_text like a wxBoxSizer(wxHORIZONTAL) would do
-    // NOTE: the proportion of m_picker is fixed to 1
-    return ((given - m_margin) / (m_textProportion + 1)) * m_textProportion;
-}
-
-void wxPickerBase::DoSetSizeHints(int minW, int minH, int maxW, int maxH, int incW, int incH)
-{
-    wxControl::DoSetSizeHints(minW, minH, maxW, maxH, incW, incH);
-
-    if (m_text)
-    {
-        // compute minWidth and maxWidth of the ausiliary textctrl
-        int textCtrlMinW = -1, textCtrlMaxW = -1;
-        if (minW != -1)
-        {
-            textCtrlMinW = GetTextCtrlWidth(minW);
-            minW -= textCtrlMinW + m_margin;
-        }
+#endif // wxUSE_TOOLTIPS
 
-        if (maxW != -1)
-        {
-            textCtrlMaxW = GetTextCtrlWidth(maxW);
-            maxW -= textCtrlMaxW + m_margin;
-        }
+// ----------------------------------------------------------------------------
+// wxPickerBase - event handlers
+// ----------------------------------------------------------------------------
 
-        m_text->SetSizeHints(textCtrlMinW, minH, textCtrlMaxW, maxH, incW, incH);
-    }
+void wxPickerBase::OnTextCtrlKillFocus(wxFocusEvent& event)
+{
+    event.Skip();
 
-    if (m_picker)
-        m_picker->SetSizeHints(minW, minH, maxW, maxH, incW, incH);
+    // don't leave the textctrl empty
+    if (m_text && m_text->GetValue().empty())
+        UpdateTextCtrlFromPicker();
 }
 
-void wxPickerBase::DoSetSize(int x, int y, int width, int height, int sizeFlags)
+void wxPickerBase::OnTextCtrlDelete(wxWindowDestroyEvent &)
 {
-    wxControl::DoSetSize(x, y, width, height, sizeFlags);
-
-    int pickerx = 0;
-    if (m_text)
-    {
-        // compute width of the ausiliary textctrl
-        int textCtrlW = GetTextCtrlWidth(width);
-
-        // set the m_text's position relatively to this window
-        m_text->SetSize(0, 0, textCtrlW, height, sizeFlags);
-
-        // change position of the real picker
-        pickerx += textCtrlW + m_margin;
-        width -= textCtrlW + m_margin;
-    }
-
-    if (m_picker)
-        m_picker->SetSize(pickerx, 0, width, height, sizeFlags);
+    // the textctrl has been deleted; our pointer is invalid!
+    m_text = NULL;
 }
 
-wxSize wxPickerBase::DoGetBestSize() const
+void wxPickerBase::OnTextCtrlUpdate(wxCommandEvent &)
 {
-    wxSize ret = m_picker->GetBestSize();
-
-    if (m_text)
-    {
-        wxSize sz = m_text->GetBestSize();
-
-        ret.SetWidth( ret.GetWidth() + sz.GetWidth() + m_margin );
-        ret.SetHeight( wxMax(ret.GetHeight(), sz.GetHeight()) );
-    }
-
-    return ret;
+    // for each text-change, update the picker
+    UpdatePickerFromTextCtrl();
 }
 
-void wxPickerBase::SetInternalMargin(int newmargin)
+void wxPickerBase::OnSize(wxSizeEvent &event)
 {
-    m_margin = newmargin;
+    if (GetAutoLayout())
+        Layout();
+    event.Skip();
 }
+
+#endif // Any picker in use