]> git.saurik.com Git - wxWidgets.git/blobdiff - include/wx/propgrid/property.h
fixing infinite recursion for rotated text, introduced in cleanup r57915
[wxWidgets.git] / include / wx / propgrid / property.h
index 8a087be51e7c88ebd6dbc0c5f1e6a871abc91781..176db3d61ee0e0c1af93e891659222d32772cbb6 100644 (file)
@@ -75,8 +75,27 @@ public:
     // Render flags
     enum
     {
+        // We are painting selected item
         Selected        = 0x00010000,
-        Control         = 0x00020000
+
+        // We are painting item in choice popup
+        ChoicePopup     = 0x00020000,
+
+        // We are rendering wxOwnerDrawnComboBox control
+        // (or other owner drawn control, but that is only
+        // officially supported one ATM).
+        Control         = 0x00040000,
+
+        // We are painting a disable property
+        Disabled        = 0x00080000,
+
+        // We are painting selected, disabled, or similar
+        // item that dictates fore- and background colours,
+        // overriding any cell values.
+        DontUseCellFgCol    = 0x00100000,
+        DontUseCellBgCol    = 0x00200000,
+        DontUseCellColours  = DontUseCellFgCol |
+                              DontUseCellBgCol
     };
 
     virtual void Render( wxDC& dc,
@@ -145,14 +164,46 @@ private:
 };
 
 
+class WXDLLIMPEXP_PROPGRID wxPGCellData : public wxObjectRefData
+{
+    friend class wxPGCell;
+public:
+    wxPGCellData();
+
+    void SetText( const wxString& text )
+    {
+        m_text = text;
+        m_hasValidText = true;
+    }
+    void SetBitmap( const wxBitmap& bitmap ) { m_bitmap = bitmap; }
+    void SetFgCol( const wxColour& col ) { m_fgCol = col; }
+    void SetBgCol( const wxColour& col ) { m_bgCol = col; }
+
+protected:
+    virtual ~wxPGCellData() { }
+
+    wxString    m_text;
+    wxBitmap    m_bitmap;
+    wxColour    m_fgCol;
+    wxColour    m_bgCol;
+
+    // True if m_text is valid and specified
+    bool        m_hasValidText;
+};
+
 /** @class wxPGCell
 
     Base class for simple wxPropertyGrid cell information.
 */
-class WXDLLIMPEXP_PROPGRID wxPGCell
+class WXDLLIMPEXP_PROPGRID wxPGCell : public wxObject
 {
 public:
     wxPGCell();
+    wxPGCell(const wxPGCell& other)
+        : wxObject(other)
+    {
+    }
+
     wxPGCell( const wxString& text,
               const wxBitmap& bitmap = wxNullBitmap,
               const wxColour& fgCol = wxNullColour,
@@ -160,21 +211,50 @@ public:
 
     virtual ~wxPGCell() { }
 
-    void SetText( const wxString& text ) { m_text = text; }
-    void SetBitmap( const wxBitmap& bitmap ) { m_bitmap = bitmap; }
-    void SetFgCol( const wxColour& col ) { m_fgCol = col; }
-    void SetBgCol( const wxColour& col ) { m_bgCol = col; }
+    wxPGCellData* GetData()
+    {
+        return (wxPGCellData*) m_refData;
+    }
+
+    const wxPGCellData* GetData() const
+    {
+        return (const wxPGCellData*) m_refData;
+    }
+
+    bool HasText() const
+    {
+        return (m_refData && GetData()->m_hasValidText);
+    }
+
+    /**
+        Merges valid data from srcCell into this.
+    */
+    void MergeFrom( const wxPGCell& srcCell );
+
+    void SetText( const wxString& text );
+    void SetBitmap( const wxBitmap& bitmap );
+    void SetFgCol( const wxColour& col );
+    void SetBgCol( const wxColour& col );
 
-    const wxString& GetText() const { return m_text; }
-    const wxBitmap& GetBitmap() const { return m_bitmap; }
-    const wxColour& GetFgCol() const { return m_fgCol; }
-    const wxColour& GetBgCol() const { return m_bgCol; }
+    const wxString& GetText() const { return GetData()->m_text; }
+    const wxBitmap& GetBitmap() const { return GetData()->m_bitmap; }
+    const wxColour& GetFgCol() const { return GetData()->m_fgCol; }
+    const wxColour& GetBgCol() const { return GetData()->m_bgCol; }
+
+    wxPGCell& operator=( const wxPGCell& other )
+    {
+        if ( this != &other )
+        {
+            Ref(other);
+        }
+        return *this;
+    }
 
 protected:
-    wxString    m_text;
-    wxBitmap    m_bitmap;
-    wxColour    m_fgCol;
-    wxColour    m_bgCol;
+    virtual wxObjectRefData *CreateRefData() const
+        { return new wxPGCellData(); }
+
+    virtual wxObjectRefData *CloneRefData(const wxObjectRefData *data) const;
 };
 
 
@@ -242,7 +322,7 @@ public:
         data->IncRef();
         variant.SetData(data);
         variant.SetName(it->first);
-        it++;
+        ++it;
         return true;
     }
 
@@ -566,32 +646,32 @@ class WXDLLIMPEXP_PROPGRID wxPGChoiceEntry : public wxPGCell
 {
 public:
     wxPGChoiceEntry();
-    wxPGChoiceEntry( const wxPGChoiceEntry& entry );
+    wxPGChoiceEntry(const wxPGChoiceEntry& other)
+        : wxPGCell(other)
+    {
+        m_value = other.m_value;
+    }
     wxPGChoiceEntry( const wxString& label,
                      int value = wxPG_INVALID_VALUE )
         : wxPGCell(), m_value(value)
     {
-        m_text = label;
+        SetText(label);
     }
 
-    wxPGChoiceEntry( const wxString& label,
-                     int value,
-                     const wxBitmap& bitmap,
-                     const wxColour& fgCol = wxNullColour,
-                     const wxColour& bgCol = wxNullColour )
-        : wxPGCell(label, bitmap, fgCol, bgCol), m_value(value)
-    {
-    }
-
-    virtual ~wxPGChoiceEntry()
-    {
-    }
+    virtual ~wxPGChoiceEntry() { }
 
     void SetValue( int value ) { m_value = value; }
-
     int GetValue() const { return m_value; }
 
-    bool HasValue() const { return (m_value != wxPG_INVALID_VALUE); }
+    wxPGChoiceEntry& operator=( const wxPGChoiceEntry& other )
+    {
+        if ( this != &other )
+        {
+            Ref(other);
+        }
+        m_value = other.m_value;
+        return *this;
+    }
 
 protected:
     int m_value;
@@ -609,26 +689,7 @@ public:
 
     void CopyDataFrom( wxPGChoicesData* data );
 
-    // Takes ownership of 'item'
-    void Insert( int index, wxPGChoiceEntry* item )
-    {
-        wxVector<wxPGChoiceEntry*>::iterator it;
-        if ( index == -1 )
-        {
-            it = m_items.end();
-            index = (int) m_items.size();
-        }
-        else
-        {
-            it = m_items.begin() + index;
-        }
-
-        // Need to fix value?
-        if ( item->GetValue() == wxPG_INVALID_VALUE )
-            item->SetValue(index);
-
-        m_items.insert(it, item);
-    }
+    wxPGChoiceEntry& Insert( int index, const wxPGChoiceEntry& item );
 
     // Delete all entries
     void Clear();
@@ -638,10 +699,15 @@ public:
         return (unsigned int) m_items.size();
     }
 
-    wxPGChoiceEntry* Item( unsigned int i ) const
+    const wxPGChoiceEntry& Item( unsigned int i ) const
     {
-        wxCHECK_MSG( i < GetCount(), NULL, "invalid index" );
+        wxASSERT_MSG( i < GetCount(), "invalid index" );
+        return m_items[i];
+    }
 
+    wxPGChoiceEntry& Item( unsigned int i )
+    {
+        wxASSERT_MSG( i < GetCount(), "invalid index" );
         return m_items[i];
     }
 
@@ -654,7 +720,7 @@ public:
     }
 
 private:
-    wxVector<wxPGChoiceEntry*>  m_items;
+    wxVector<wxPGChoiceEntry  m_items;
 
     // So that multiple properties can use the same set
     int             m_refCount;
@@ -672,6 +738,8 @@ private:
     Each entry can have label, value, bitmap, text colour, and background
     colour.
 
+    @remarks If you do not specify value for entry, index is used.
+
     @library{wxpropgrid}
     @category{propgrid}
 */
@@ -696,14 +764,30 @@ public:
         }
     }
 
-    /** Constructor. */
+    /**
+        Constructor.
+
+        @param labels
+            Labels for choices
+
+        @param values
+            Values for choices. If NULL, indexes are used.
+    */
     wxPGChoices( const wxChar** labels, const long* values = NULL )
     {
         Init();
         Set(labels,values);
     }
 
-    /** Constructor. */
+    /**
+        Constructor.
+
+        @param labels
+            Labels for choices
+
+        @param values
+            Values for choices. If empty, indexes are used.
+    */
     wxPGChoices( const wxArrayString& labels,
                  const wxArrayInt& values = wxArrayInt() )
     {
@@ -730,16 +814,27 @@ public:
 
         If did not have own copies, creates them now. If was empty, identical
         to set except that creates copies.
+
+        @param labels
+            Labels for added choices.
+
+        @param values
+            Values for added choices. If empty, relevant entry indexes are used.
     */
     void Add( const wxChar** labels, const ValArrItem* values = NULL );
 
-    /** Version that works with wxArrayString. */
-    void Add( const wxArrayString& arr, const ValArrItem* values = NULL );
-
     /** Version that works with wxArrayString and wxArrayInt. */
-    void Add( const wxArrayString& arr, const wxArrayInt& arrint );
+    void Add( const wxArrayString& arr, const wxArrayInt& arrint = wxArrayInt() );
 
-    /** Adds single item. */
+    /**
+        Adds a single choice.
+
+        @param label
+            Label for added choice.
+
+        @param value
+            Value for added choice. If unspecified, index is used.
+    */
     wxPGChoiceEntry& Add( const wxString& label,
                           int value = wxPG_INVALID_VALUE );
 
@@ -807,14 +902,6 @@ public:
     wxArrayInt GetIndicesForStrings( const wxArrayString& strings,
                                      wxArrayString* unmatched = NULL ) const;
 
-    /** Returns true if choices in general are likely to have values
-        (depens on that all entries have values or none has)
-    */
-    bool HasValues() const;
-
-    bool HasValue( unsigned int i ) const
-        { return (i < m_data->GetCount()) && m_data->Item(i)->HasValue(); }
-
     int Index( const wxString& str ) const;
     int Index( int val ) const;
 
@@ -837,13 +924,13 @@ public:
     const wxPGChoiceEntry& Item( unsigned int i ) const
     {
         wxASSERT( IsOk() );
-        return *m_data->Item(i);
+        return m_data->Item(i);
     }
 
     wxPGChoiceEntry& Item( unsigned int i )
     {
         wxASSERT( IsOk() );
-        return *m_data->Item(i);
+        return m_data->Item(i);
     }
 
     /** Removes count items starting at position nIndex. */
@@ -905,7 +992,8 @@ public:
 #ifndef SWIG
     void operator= (const wxPGChoices& a)
     {
-        AssignData(a.m_data);
+        if (this != &a)
+            AssignData(a.m_data);
     }
 
     wxPGChoiceEntry& operator[](unsigned int i)
@@ -1107,7 +1195,7 @@ public:
         @return
         true if value was changed.
     */
-    bool SetValueFromString( const wxString& text, int flags = 0 );
+    bool SetValueFromString( const wxString& text, int flags = wxPG_PROGRAMMATIC_VALUE );
 
     /** Converts integer to a value, and if succesful, calls SetValue() on it.
         Default behavior is to do nothing.
@@ -1335,18 +1423,14 @@ public:
     */
     virtual wxPGEditorDialogAdapter* GetEditorDialog() const;
 
-    /** Returns wxPGCell of given column, NULL if none. If valid
-        object is returned, caller will gain its ownership.
-    */
-    wxPGCell* AcquireCell( unsigned int column )
-    {
-        if ( column >= m_cells.size() )
-            return NULL;
+    /**
+        Called whenever validation has failed with given pending value.
 
-        wxPGCell* cell = (wxPGCell*) m_cells[column];
-        m_cells[column] = NULL;
-        return cell;
-    }
+        @remarks If you implement this in your custom property class, please
+                 remember to call the baser implementation as well, since they
+                 may use it to revert property into pre-change state.
+    */
+    virtual void OnValidationFailure( wxVariant& pendingValue );
 
     /** Append a new choice to property's list of choices.
     */
@@ -1368,6 +1452,11 @@ public:
         return false;
     }
 
+    /**
+        Deletes children of the property.
+    */
+    void DeleteChildren();
+
     /**
         Removes entry from property's wxPGChoices and editor control (if it is
         active).
@@ -1470,18 +1559,12 @@ public:
     */
     wxDEPRECATED( wxString GetValueString( int argFlags = 0 ) const );
 
-    void UpdateControl( wxWindow* primary );
-
-    /** Returns wxPGCell of given column, NULL if none. wxPGProperty
-        will retain ownership of the cell object.
+    /**
+        Returns wxPGCell of given column.
     */
-    wxPGCell* GetCell( unsigned int column ) const
-    {
-        if ( column >= m_cells.size() )
-            return NULL;
+    const wxPGCell& GetCell( unsigned int column ) const;
 
-        return (wxPGCell*) m_cells[column];
-    }
+    wxPGCell& GetCell( unsigned int column );
 
     /** Return number of displayed common values for this property.
     */
@@ -1710,6 +1793,32 @@ public:
 
     void SetAttributes( const wxPGAttributeStorage& attributes );
 
+    /**
+        Sets property's background colour.
+
+        @param colour
+            Background colour to use.
+
+        @param recursively
+            If @true, children are affected recursively, and any categories
+            are not.
+    */
+    void SetBackgroundColour( const wxColour& colour,
+                              bool recursively = false );
+
+    /**
+        Sets property's text colour.
+
+        @param colour
+            Text colour to use.
+
+        @param recursively
+            If @true, children are affected recursively, and any categories
+            are not.
+    */
+    void SetTextColour( const wxColour& colour,
+                        bool recursively = false );
+
 #ifndef SWIG
     /** Sets editor for a property.
 
@@ -1731,11 +1840,10 @@ public:
     */
     inline void SetEditor( const wxString& editorName );
 
-    /** Sets cell information for given column.
-
-        Note that the property takes ownership of given wxPGCell instance.
+    /**
+        Sets cell information for given column.
     */
-    void SetCell( int column, wxPGCell* cellObj );
+    void SetCell( int column, const wxPGCell& cell );
 
     /** Sets common value selected for this property. -1 for none.
     */
@@ -1977,9 +2085,6 @@ public:
     /** Returns index of given child property. */
     int Index( const wxPGProperty* p ) const;
 
-    /** Deletes all sub-properties. */
-    void Empty();
-
     // Puts correct indexes to children
     void FixIndicesOfChildren( unsigned int starthere = 0 );
 
@@ -2026,6 +2131,13 @@ public:
 
 #ifndef SWIG
 
+    // Returns various display-related information for given column
+    void GetDisplayInfo( unsigned int column,
+                         int choiceIndex,
+                         int flags,
+                         wxString* pString,
+                         const wxPGCell** pCell );
+
     static wxString*            sm_wxPG_LABEL;
 
     /** This member is public so scripting language bindings
@@ -2034,9 +2146,49 @@ public:
     void*                       m_clientData;
 
 protected:
-    /** Returns text for given column.
+
+    /**
+        Sets property cell in fashion that reduces number of exclusive
+        copies of cell data. Used when setting, for instance, same
+        background colour for a number of properties.
+
+        @param firstCol
+            First column to affect.
+
+        @param lastCol
+            Last column to affect.
+
+        @param preparedCell
+            Pre-prepared cell that is used for those which cell data
+            before this matched unmodCellData.
+
+        @param srcData
+            If unmodCellData did not match, valid cell data from this
+            is merged into cell (usually generating new exclusive copy
+            of cell's data).
+
+        @param unmodCellData
+            If cell's cell data matches this, its cell is now set to
+            preparedCell.
+
+        @param ignoreWithFlags
+            Properties with any one of these flags are skipped.
+
+        @param recursively
+            If @true, apply this operation recursively in child properties.
     */
-    wxString GetColumnText( unsigned int col ) const;
+    void AdaptiveSetCell( unsigned int firstCol,
+                          unsigned int lastCol,
+                          const wxPGCell& preparedCell,
+                          const wxPGCell& srcData,
+                          wxPGCellData* unmodCellData,
+                          FlagType ignoreWithFlags,
+                          bool recursively );
+
+    /**
+        Makes sure m_cells has size of column+1 (or more).
+    */
+    void EnsureCells( unsigned int column );
 
     /** Returns (direct) child property with given name (or NULL if not found),
         with hint index.
@@ -2062,6 +2214,9 @@ protected:
 
     void DoSetName(const wxString& str) { m_name = str; }
 
+    /** Deletes all sub-properties. */
+    void Empty();
+
     void InitAfterAdded( wxPropertyGridPageState* pageState,
                          wxPropertyGrid* propgrid );
 
@@ -2081,7 +2236,7 @@ protected:
     wxString                    m_label;
     wxString                    m_name;
     wxPGProperty*               m_parent;
-    wxPropertyGridPageState*        m_parentState;
+    wxPropertyGridPageState*    m_parentState;
 
     wxClientData*               m_clientObject;
 
@@ -2101,7 +2256,7 @@ protected:
     wxArrayPGProperty           m_children;
 
     // Extended cell information
-    wxArrayPtrVoid              m_cells;
+    wxVector<wxPGCell>          m_cells;
 
     // Choices shown in drop-down list of editor control.
     wxPGChoices                 m_choices;
@@ -2130,9 +2285,6 @@ protected:
     // (essentially this is category's depth, if none then equals m_depth).
     unsigned char               m_depthBgCol;
 
-    unsigned char               m_bgColIndex; // Background brush index.
-    unsigned char               m_fgColIndex; // Foreground colour index.
-
 private:
     // Called in constructors.
     void Init();
@@ -2216,9 +2368,9 @@ public:
 
     int GetTextExtent( const wxWindow* wnd, const wxFont& font ) const;
 
-protected:
     virtual wxString ValueToString( wxVariant& value, int argFlags ) const;
 
+protected:
     void SetTextColIndex( unsigned int colInd )
         { m_capFgColIndex = (wxByte) colInd; }
     unsigned int GetTextColIndex() const