]> git.saurik.com Git - wxWidgets.git/commitdiff
1. wxNotebook::GetPageCount() returns only the number of pages actually added
authorVadim Zeitlin <vadim@wxwidgets.org>
Mon, 7 Dec 1998 18:23:57 +0000 (18:23 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Mon, 7 Dec 1998 18:23:57 +0000 (18:23 +0000)
   to the notebook
2. wxTreeCtrl: more kbd interface ad SetItemBold (doesn't work :-( )

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@1124 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/generic/treectrl.h
samples/treectrl/treetest.cpp
src/generic/treectrl.cpp
src/gtk/notebook.cpp
src/gtk1/notebook.cpp

index 6397ef5820ccb782c222f86578280eb42dd6a855..a9779e966895306e6caf701d8c620a5d983cab2c 100644 (file)
@@ -59,7 +59,7 @@ public:
 //protected: // not for gcc
     // for wxTreeCtrl usage only
     wxTreeItemId(wxGenericTreeItem *pItem) { m_pItem = pItem; }
-    
+
     wxGenericTreeItem *m_pItem;
 };
 
@@ -148,7 +148,7 @@ typedef void (wxEvtHandler::*wxTreeEventFunction)(wxTreeEvent&);
 #define EVT_TREE_GET_INFO(id, fn) { wxEVT_COMMAND_TREE_GET_INFO, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxTreeEventFunction) & fn, (wxObject *) NULL },
 #define EVT_TREE_SET_INFO(id, fn) { wxEVT_COMMAND_TREE_SET_INFO, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxTreeEventFunction) & fn, (wxObject *) NULL },
 
-// GetItem() is the item being expanded/collapsed, the "ING" versions can use 
+// GetItem() is the item being expanded/collapsed, the "ING" versions can use
 #define EVT_TREE_ITEM_EXPANDED(id, fn) { wxEVT_COMMAND_TREE_ITEM_EXPANDED, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxTreeEventFunction) & fn, (wxObject *) NULL },
 #define EVT_TREE_ITEM_EXPANDING(id, fn) { wxEVT_COMMAND_TREE_ITEM_EXPANDING, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxTreeEventFunction) & fn, (wxObject *) NULL },
 #define EVT_TREE_ITEM_COLLAPSED(id, fn) { wxEVT_COMMAND_TREE_ITEM_COLLAPSED, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxTreeEventFunction) & fn, (wxObject *) NULL },
@@ -256,6 +256,9 @@ public:
         // usage and loading time.
     void SetItemHasChildren(const wxTreeItemId& item, bool has = TRUE);
 
+        // the item will be shown in bold
+    void SetItemBold(const wxTreeItemId& item, bool bold = TRUE);
+
     // item status inquiries
     // ---------------------
 
@@ -269,6 +272,8 @@ public:
     bool IsExpanded(const wxTreeItemId& item) const;
         // is this item currently selected (the same as has focus)?
     bool IsSelected(const wxTreeItemId& item) const;
+        // is item text in bold font?
+    bool IsBold(const wxTreeItemId& item) const;
 
     // number of children
     // ------------------
@@ -419,7 +424,8 @@ protected:
                               wxTreeItemData *data);
 
     void AdjustMyScrollbars();
-    void PaintLevel( wxGenericTreeItem *item, wxDC &dc, int level, int &y );
+    void PaintLevel( wxGenericTreeItem *item, wxDC& dc, int level, int &y );
+    void PaintItem( wxGenericTreeItem *item, wxDC& dc);
 
     void CalculateLevel( wxGenericTreeItem *item, wxDC &dc, int level, int &y );
     void CalculatePositions();
index 05b9adb2a308ae9be0f8e875f29e85a839695645..5bcbd4b8d32ea19d637b26e1d31e5db46299d2e3 100644 (file)
@@ -180,7 +180,7 @@ void MyFrame::OnDump(wxCommandEvent& WXUNUSED(event))
 
 void MyFrame::DoSetBold(bool bold)
 {
-//  m_treeCtrl->SetItemBold(m_treeCtrl->GetSelection(), bold);
+  m_treeCtrl->SetItemBold(m_treeCtrl->GetSelection(), bold);
 }
 
 void MyFrame::OnDelete(wxCommandEvent& WXUNUSED(event))
index 5c0ada9b1daf55cae7b34b74fac6ef3118edcf07..c51c4a020d05d3bd0b7cc3df7565f68c875e4966 100644 (file)
@@ -68,6 +68,8 @@ public:
 
   void SetHasPlus(bool has = TRUE) { m_hasPlus = has; }
 
+  void SetBold(bool bold) { m_isBold = bold; }
+
   int GetX() const { return m_x; }
   int GetY() const { return m_y; }
 
@@ -105,6 +107,7 @@ public:
   bool HasHilight()  const { return m_hasHilight; }
   bool IsExpanded()  const { return !m_isCollapsed; }
   bool HasPlus()     const { return m_hasPlus || HasChildren(); }
+  bool IsBold()      const { return m_isBold; }
 
 private:
   wxString            m_text;
@@ -114,11 +117,12 @@ private:
 
   wxTreeItemData     *m_data;
 
-  // @@ probably should use bitfields to save size
-  bool                m_isCollapsed,
-                      m_hasHilight,   // same as focused
-                      m_hasPlus;      // used for item which doesn't have
-                                      // children but still has a [+] button
+  // use bitfields to save size
+  int                 m_isCollapsed :1;
+  int                 m_hasHilight  :1; // same as focused
+  int                 m_hasPlus     :1; // used for item which doesn't have
+                                        // children but still has a [+] button
+  int                 m_isBold      :1; // render the label in bold font
 
   int                 m_x, m_y;
   long                m_height, m_width;
@@ -167,6 +171,7 @@ wxGenericTreeItem::wxGenericTreeItem(wxGenericTreeItem *parent,
   m_isCollapsed = TRUE;
   m_hasHilight = FALSE;
   m_hasPlus = FALSE;
+  m_isBold = FALSE;
 
   m_parent = parent;
 
@@ -432,6 +437,19 @@ void wxTreeCtrl::SetItemHasChildren(const wxTreeItemId& item, bool has)
   item.m_pItem->SetHasPlus(has);
 }
 
+void wxTreeCtrl::SetItemBold(const wxTreeItemId& item, bool bold)
+{
+  wxCHECK_RET( item.IsOk(), "invalid tree item" );
+
+  // avoid redrawing the tree if no real change
+  wxGenericTreeItem *pItem = item.m_pItem;
+  if ( pItem->IsBold() != bold )
+  {
+    pItem->SetBold(bold);
+    RefreshLine(pItem);
+  }
+}
+
 // -----------------------------------------------------------------------------
 // item status inquiries
 // -----------------------------------------------------------------------------
@@ -464,6 +482,13 @@ bool wxTreeCtrl::IsSelected(const wxTreeItemId& item) const
   return item.m_pItem->HasHilight();
 }
 
+bool wxTreeCtrl::IsBold(const wxTreeItemId& item) const
+{
+  wxCHECK_MSG( item.IsOk(), FALSE, "invalid tree item" );
+
+  return item.m_pItem->IsBold();
+}
+
 // -----------------------------------------------------------------------------
 // navigation
 // -----------------------------------------------------------------------------
@@ -592,7 +617,7 @@ wxTreeItemId wxTreeCtrl::DoInsertItem(const wxTreeItemId& parentId,
   }
 
   parent->Insert( item, previous );
-  
+
   m_dirty = TRUE;
 
   return item;
@@ -800,14 +825,14 @@ void wxTreeCtrl::SelectItem(const wxTreeItemId& itemId)
 void wxTreeCtrl::EnsureVisible(const wxTreeItemId& item)
 {
   wxGenericTreeItem *gitem = item.m_pItem;
-  
+
   int item_y = gitem->GetY();
-  
+
   int start_x = 0;
   int start_y = 0;
   ViewStart( &start_x, &start_y );
   start_y *= 10;
-  
+
   if (item_y < start_y+3)
   {
     int x = 0;
@@ -818,11 +843,11 @@ void wxTreeCtrl::EnsureVisible(const wxTreeItemId& item)
     SetScrollbars( 10, 10, x/10, y/10, x_pos, item_y/10 );
     return;
   }
-  
+
   int w = 0;
   int h = 0;
   GetClientSize( &w, &h );
-  
+
   if (item_y > start_y+h-26)
   {
     int x = 0;
@@ -832,7 +857,7 @@ void wxTreeCtrl::EnsureVisible(const wxTreeItemId& item)
     int x_pos = GetScrollPos( wxHORIZONTAL );
     SetScrollbars( 10, 10, x/10, y/10, x_pos, (item_y-h+30)/10 );
      return;
-  }  
+  }
 }
 
 void wxTreeCtrl::ScrollTo(const wxTreeItemId& WXUNUSED(item))
@@ -907,6 +932,63 @@ void wxTreeCtrl::AdjustMyScrollbars()
   }
 }
 
+void wxTreeCtrl::PaintItem(wxGenericTreeItem *item, wxDC& dc)
+{
+  // render bold items in bold
+  wxFont *fontOld = (wxFont *)NULL,
+         *fontNew = (wxFont *)NULL;
+  if ( item->IsBold() )
+  {
+      fontOld = dc.GetFont();
+      if ( fontOld )
+      {
+        // @@ is there any better way to make a bold variant of old font?
+        fontNew = new wxFont(fontOld->GetPointSize(),
+                             fontOld->GetFamily(),
+                             fontOld->GetStyle(),
+                             wxBOLD,
+                             fontOld->GetUnderlined());
+        dc.SetFont(fontNew);
+      }
+      else
+      {
+        wxFAIL_MSG("wxDC::GetFont() failed!");
+      }
+  }
+
+  long text_w = 0;
+  long text_h = 0;
+  dc.GetTextExtent( item->GetText(), &text_w, &text_h );
+
+  int image_h = 0;
+  int image_w = 0;
+  if (item->GetImage() != -1)
+  {
+    m_imageListNormal->GetSize( item->GetImage(), image_w, image_h );
+    image_w += 4;
+  }
+
+  dc.DrawRectangle( item->GetX()-2, item->GetY()-2, image_w+text_w+4, text_h+4 );
+
+  if (item->GetImage() != -1)
+  {
+    dc.SetClippingRegion( item->GetX(), item->GetY(), image_w-2, text_h );
+    m_imageListNormal->Draw( item->GetImage(), dc,
+                             item->GetX(), item->GetY()-1,
+                             wxIMAGELIST_DRAW_TRANSPARENT );
+    dc.DestroyClippingRegion();
+  }
+
+  dc.DrawText( item->GetText(), image_w + item->GetX(), item->GetY() );
+
+  // restore normal font for bold items
+  if ( fontOld )
+  {
+      dc.SetFont(fontOld);
+      delete fontNew;
+  }
+}
+
 void wxTreeCtrl::PaintLevel( wxGenericTreeItem *item, wxDC &dc, int level, int &y )
 {
   int horizX = level*m_indent;
@@ -949,32 +1031,12 @@ void wxTreeCtrl::PaintLevel( wxGenericTreeItem *item, wxDC &dc, int level, int &
 
       dc.SetBrush( *m_hilightBrush );
 
-      long text_w = 0;
-      long text_h = 0;
-      dc.GetTextExtent( item->GetText(), &text_w, &text_h );
-
-      int image_h = 0;
-      int image_w = 0;
-      if (item->GetImage() != -1)
-      {
-        m_imageListNormal->GetSize( item->GetImage(), image_w, image_h );
-        image_w += 4;
-      }
-
       if (m_hasFocus)
         dc.SetPen( *wxBLACK_PEN );
       else
         dc.SetPen( *wxTRANSPARENT_PEN );
 
-      dc.DrawRectangle( item->GetX()-2, item->GetY()-2, image_w+text_w+4, text_h+4 );
-
-      if (item->GetImage() != -1)
-      {
-        dc.SetClippingRegion( item->GetX(), item->GetY(), image_w-2, text_h );
-       m_imageListNormal->Draw( item->GetImage(), dc, item->GetX(), item->GetY()-1, wxIMAGELIST_DRAW_TRANSPARENT );
-        dc.DestroyClippingRegion();
-      }
-      dc.DrawText( item->GetText(), image_w+item->GetX(), item->GetY() );
+      PaintItem(item, dc);
 
       dc.SetPen( *wxBLACK_PEN );
       dc.SetTextForeground( *wxBLACK );
@@ -985,28 +1047,8 @@ void wxTreeCtrl::PaintLevel( wxGenericTreeItem *item, wxDC &dc, int level, int &
       dc.SetBrush( *wxWHITE_BRUSH );
       dc.SetPen( *wxTRANSPARENT_PEN );
 
-      long text_w = 0;
-      long text_h = 0;
-      dc.GetTextExtent( item->GetText(), &text_w, &text_h );
-
-      int image_h = 0;
-      int image_w = 0;
-      if (item->GetImage() != -1)
-      {
-        m_imageListNormal->GetSize( item->GetImage(), image_w, image_h );
-        image_w += 4;
-      }
-
-      dc.DrawRectangle( item->GetX()-2, item->GetY()-2, image_w+text_w+4, text_h+4 );
-
-      if (item->GetImage() != -1)
-      {
-        dc.SetClippingRegion( item->GetX(), item->GetY(), image_w-2, text_h );
-       m_imageListNormal->Draw( item->GetImage(), dc, item->GetX(), item->GetY()-1, wxIMAGELIST_DRAW_TRANSPARENT );
-        dc.DestroyClippingRegion();
-      }
+      PaintItem(item, dc);
 
-      dc.DrawText( item->GetText(), image_w+item->GetX(), item->GetY() );
       dc.SetPen( *wxBLACK_PEN );
     }
   }
@@ -1067,91 +1109,105 @@ void wxTreeCtrl::OnKillFocus( wxFocusEvent &WXUNUSED(event) )
 void wxTreeCtrl::OnChar( wxKeyEvent &event )
 {
   if (m_current == 0)
-  { 
+  {
      event.Skip();
      return;
   }
-  
+
   switch (event.KeyCode())
   {
     case '+':
     case WXK_ADD:
-    {
       if (HasChildren(m_current) && !IsExpanded(m_current))
       {
         Expand(m_current);
       }
-      return;
-    }
+      break;
+
     case '-':
     case WXK_SUBTRACT:
-    {
       if (IsExpanded(m_current))
       {
         Collapse(m_current);
       }
-      return;
-    }
+      break;
+
+    case '*':
+    case WXK_MULTIPLY:
+      Toggle(m_current);
+      break;
+
     case ' ':
     case WXK_RETURN:
-    {
-      wxTreeEvent event( wxEVT_COMMAND_TREE_KEY_DOWN, GetId() );
-      event.m_item = m_current;
-      event.m_code = 0;
-      event.SetEventObject( this );
-      GetEventHandler()->ProcessEvent( event );
-      return;
-    }
+      {
+        wxTreeEvent event( wxEVT_COMMAND_TREE_KEY_DOWN, GetId() );
+        event.m_item = m_current;
+        event.m_code = 0;
+        event.SetEventObject( this );
+        GetEventHandler()->ProcessEvent( event );
+      }
+      break;
+
+    case WXK_LEFT:
     case WXK_UP:
-    {
-       wxTreeItemId prev = GetPrevSibling( m_current );
-       if (prev != 0)
-       { 
-         SelectItem( prev );
-          EnsureVisible( prev );
-       }
-       else
-       {
-         prev = GetParent( m_current );
-        if (prev)
-        {
-          EnsureVisible( prev );
-          SelectItem( prev );
-        }
-       }
-      return;
-    }
-    case WXK_DOWN:
-    {
-      if (IsExpanded(m_current))
       {
-        long cookie = 0;
-       wxTreeItemId child = GetFirstChild( m_current, cookie );
-       SelectItem( child );
-       EnsureVisible( child );
+        wxTreeItemId prev = GetPrevSibling( m_current );
+        if (prev != 0)
+        {
+          SelectItem( prev );
+          EnsureVisible( prev );
+        }
+        else
+        {
+          prev = GetParent( m_current );
+          if (prev)
+          {
+            EnsureVisible( prev );
+            SelectItem( prev );
+          }
+        }
       }
-      else
+      break;
+
+    case WXK_RIGHT:
+      // this works the same as the down arrow except that we also expand the
+      // item if it wasn't expanded yet
+      Expand(m_current);
+      // fall through
+
+    case WXK_DOWN:
       {
-       wxTreeItemId next = GetNextSibling( m_current );
-       if (next == 0)
-       {
-         wxTreeItemId current = m_current;
-         while (current && !next)
-         {
-           current = GetParent( current );
-           if (current) next = GetNextSibling( current );
-         }
-       }
-       if (next != 0)
-       {
-          SelectItem( next );
-          EnsureVisible( next );
-       }
+        if (IsExpanded(m_current))
+        {
+          long cookie = 0;
+          wxTreeItemId child = GetFirstChild( m_current, cookie );
+          SelectItem( child );
+          EnsureVisible( child );
+        }
+        else
+        {
+          wxTreeItemId next = GetNextSibling( m_current );
+          if (next == 0)
+          {
+            wxTreeItemId current = m_current;
+            while (current && !next)
+            {
+              current = GetParent( current );
+              if (current) next = GetNextSibling( current );
+            }
+          }
+          if (next != 0)
+          {
+            SelectItem( next );
+            EnsureVisible( next );
+          }
+        }
       }
-      return;
-    }
+      break;
+
+    default:
+      event.Skip();
   }
-  event.Skip();
 }
 
 void wxTreeCtrl::OnMouse( wxMouseEvent &event )
@@ -1192,9 +1248,9 @@ void wxTreeCtrl::OnMouse( wxMouseEvent &event )
 void wxTreeCtrl::OnIdle( wxIdleEvent &WXUNUSED(event) )
 {
   if (!m_dirty) return;
-  
+
   m_dirty = FALSE;
-  
+
   CalculatePositions();
 
   AdjustMyScrollbars();
index 32f8f4744bc5bb2eab30c6d4e1f6eecbb4c2d13c..0a71d34dd3920b3da10210185d1064e9ef8c626f 100644 (file)
@@ -34,8 +34,22 @@ public:
     m_client = (wxWindow *) NULL;
     m_parent = (GtkNotebook *) NULL;
     m_box = (GtkWidget *) NULL;
+    m_added = FALSE;
   }
 
+  // mark page as "added' to the notebook, return FALSE if the page was
+  // already added
+  bool Add()
+  {
+    if ( WasAdded() )
+      return FALSE;
+
+    m_added = TRUE;
+    return TRUE;
+  }
+
+  bool WasAdded() const { return m_added; }
+
   int                m_id;
   wxString           m_text;
   int                m_image;
@@ -44,6 +58,9 @@ public:
   wxWindow          *m_client;
   GtkNotebook       *m_parent;
   GtkWidget         *m_box;     // in which the label and image are packed
+
+private:
+  bool m_added;
 };
 
 //-----------------------------------------------------------------------------
@@ -60,7 +77,7 @@ static void gtk_notebook_page_change_callback(GtkNotebook *WXUNUSED(widget),
   int old = notebook->GetSelection();
 
   // TODO: emulate PAGE_CHANGING event
-  
+
   wxNotebookEvent event( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED,
                          notebook->GetId(),  nPage, old );
   event.SetEventObject( notebook );
@@ -80,7 +97,7 @@ static void gtk_page_size_callback( GtkWidget *WXUNUSED(widget), GtkAllocation*
   {
     return;
   }
-  
+
   win->SetSize( alloc->x, alloc->y, alloc->width, alloc->height );
 }
 
@@ -98,7 +115,7 @@ static void wxInsertChildInNotebook( wxNotebook* parent, wxWindow* child )
   gtk_container_border_width(GTK_CONTAINER(page->m_box), 2);
 
   GtkNotebook *notebook = GTK_NOTEBOOK(parent->m_widget);
-  
+
   page->m_client = child;
   gtk_notebook_append_page( notebook, child->m_widget, page->m_box );
 
@@ -174,7 +191,7 @@ bool wxNotebook::Create(wxWindow *parent, wxWindowID id,
   m_parent->AddChild( this );
 
   (m_parent->m_insertCallback)( m_parent, this );
-  
+
   PostCreation();
 
   Show( TRUE );
@@ -185,7 +202,7 @@ bool wxNotebook::Create(wxWindow *parent, wxWindowID id,
 int wxNotebook::GetSelection() const
 {
   wxCHECK_MSG( m_widget != NULL, -1, "invalid notebook" );
-  
+
   if (m_pages.Number() == 0) return -1;
 
   GtkNotebookPage *g_page = GTK_NOTEBOOK(m_widget)->cur_page;
@@ -197,13 +214,13 @@ int wxNotebook::GetSelection() const
   while (node)
   {
     page = (wxNotebookPage*)node->Data();
-    
-    if ((page->m_page == g_page) || (page->m_page == (GtkNotebookPage*)NULL))  
+
+    if ((page->m_page == g_page) || (page->m_page == (GtkNotebookPage*)NULL))
     {
         // page->m_page is NULL directly after gtk_notebook_append. gtk emits
-       // "switch_page" then and we ask for GetSelection() in the handler for
-       // "switch_page". otherwise m_page should never be NULL. all this
-       // might also be wrong.
+        // "switch_page" then and we ask for GetSelection() in the handler for
+        // "switch_page". otherwise m_page should never be NULL. all this
+        // might also be wrong.
         break;
     }
     node = node->Next();
@@ -216,7 +233,18 @@ int wxNotebook::GetSelection() const
 
 int wxNotebook::GetPageCount() const
 {
-  return m_pages.Number();
+  // count only the pages which were already added to the notebook for MSW
+  // compatibility (and, in fact, this behaviour makes more sense anyhow
+  // because only the added pages are shown)
+  int n = 0;
+  for ( wxNode *node = m_pages.First(); node; node = node->Next() )
+  {
+    wxNotebookPage *page = (wxNotebookPage*)node->Data();
+    if ( page->WasAdded() )
+        n++;
+  }
+
+  return n;
 }
 
 int wxNotebook::GetRowCount() const
@@ -227,7 +255,7 @@ int wxNotebook::GetRowCount() const
 wxString wxNotebook::GetPageText( int page ) const
 {
   wxCHECK_MSG( m_widget != NULL, "", "invalid notebook" );
-  
+
   wxNotebookPage* nb_page = GetNotebookPage(page);
   if (nb_page)
     return nb_page->m_text;
@@ -272,7 +300,7 @@ int wxNotebook::SetSelection( int page )
 
   int selOld = GetSelection();
   wxNotebookPage* nb_page = GetNotebookPage(page);
-  
+
   if (!nb_page) return -1;
 
   int page_num = 0;
@@ -298,7 +326,7 @@ void wxNotebook::AdvanceSelection( bool bForward )
   int sel = GetSelection();
   int max = GetPageCount();
 
-  if (bForward) 
+  if (bForward)
     SetSelection( sel == max ? 0 : sel + 1 );
   else
     SetSelection( sel == 0 ? max : sel - 1 );
@@ -314,7 +342,7 @@ bool wxNotebook::SetPageText( int page, const wxString &text )
   wxCHECK_MSG( m_widget != NULL, FALSE, "invalid notebook" );
 
   wxNotebookPage* nb_page = GetNotebookPage(page);
-  
+
   if (!nb_page) return FALSE;
 
   nb_page->m_text = text;
@@ -325,7 +353,7 @@ bool wxNotebook::SetPageText( int page, const wxString &text )
 bool wxNotebook::SetPageImage( int page, int image )
 {
   wxNotebookPage* nb_page = GetNotebookPage(page);
-  
+
   if (!nb_page) return FALSE;
 
   nb_page->m_image = image;
@@ -424,9 +452,13 @@ bool wxNotebook::AddPage(wxWindow* win, const wxString& text,
     node = node->Next();
   }
 
-  wxCHECK_MSG( page != NULL, FALSE, "Can't add a page whose parent is not the notebook!" );
+  wxCHECK_MSG( page != NULL, FALSE,
+               "Can't add a page whose parent is not the notebook!" );
+
+  wxCHECK_MSG( page->Add(), FALSE,
+               "Can't add the same page twice to a notebook." );
 
-  if (imageId != -1) 
+  if (imageId != -1)
   {
     wxASSERT( m_imageList != NULL );
 
index 32f8f4744bc5bb2eab30c6d4e1f6eecbb4c2d13c..0a71d34dd3920b3da10210185d1064e9ef8c626f 100644 (file)
@@ -34,8 +34,22 @@ public:
     m_client = (wxWindow *) NULL;
     m_parent = (GtkNotebook *) NULL;
     m_box = (GtkWidget *) NULL;
+    m_added = FALSE;
   }
 
+  // mark page as "added' to the notebook, return FALSE if the page was
+  // already added
+  bool Add()
+  {
+    if ( WasAdded() )
+      return FALSE;
+
+    m_added = TRUE;
+    return TRUE;
+  }
+
+  bool WasAdded() const { return m_added; }
+
   int                m_id;
   wxString           m_text;
   int                m_image;
@@ -44,6 +58,9 @@ public:
   wxWindow          *m_client;
   GtkNotebook       *m_parent;
   GtkWidget         *m_box;     // in which the label and image are packed
+
+private:
+  bool m_added;
 };
 
 //-----------------------------------------------------------------------------
@@ -60,7 +77,7 @@ static void gtk_notebook_page_change_callback(GtkNotebook *WXUNUSED(widget),
   int old = notebook->GetSelection();
 
   // TODO: emulate PAGE_CHANGING event
-  
+
   wxNotebookEvent event( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED,
                          notebook->GetId(),  nPage, old );
   event.SetEventObject( notebook );
@@ -80,7 +97,7 @@ static void gtk_page_size_callback( GtkWidget *WXUNUSED(widget), GtkAllocation*
   {
     return;
   }
-  
+
   win->SetSize( alloc->x, alloc->y, alloc->width, alloc->height );
 }
 
@@ -98,7 +115,7 @@ static void wxInsertChildInNotebook( wxNotebook* parent, wxWindow* child )
   gtk_container_border_width(GTK_CONTAINER(page->m_box), 2);
 
   GtkNotebook *notebook = GTK_NOTEBOOK(parent->m_widget);
-  
+
   page->m_client = child;
   gtk_notebook_append_page( notebook, child->m_widget, page->m_box );
 
@@ -174,7 +191,7 @@ bool wxNotebook::Create(wxWindow *parent, wxWindowID id,
   m_parent->AddChild( this );
 
   (m_parent->m_insertCallback)( m_parent, this );
-  
+
   PostCreation();
 
   Show( TRUE );
@@ -185,7 +202,7 @@ bool wxNotebook::Create(wxWindow *parent, wxWindowID id,
 int wxNotebook::GetSelection() const
 {
   wxCHECK_MSG( m_widget != NULL, -1, "invalid notebook" );
-  
+
   if (m_pages.Number() == 0) return -1;
 
   GtkNotebookPage *g_page = GTK_NOTEBOOK(m_widget)->cur_page;
@@ -197,13 +214,13 @@ int wxNotebook::GetSelection() const
   while (node)
   {
     page = (wxNotebookPage*)node->Data();
-    
-    if ((page->m_page == g_page) || (page->m_page == (GtkNotebookPage*)NULL))  
+
+    if ((page->m_page == g_page) || (page->m_page == (GtkNotebookPage*)NULL))
     {
         // page->m_page is NULL directly after gtk_notebook_append. gtk emits
-       // "switch_page" then and we ask for GetSelection() in the handler for
-       // "switch_page". otherwise m_page should never be NULL. all this
-       // might also be wrong.
+        // "switch_page" then and we ask for GetSelection() in the handler for
+        // "switch_page". otherwise m_page should never be NULL. all this
+        // might also be wrong.
         break;
     }
     node = node->Next();
@@ -216,7 +233,18 @@ int wxNotebook::GetSelection() const
 
 int wxNotebook::GetPageCount() const
 {
-  return m_pages.Number();
+  // count only the pages which were already added to the notebook for MSW
+  // compatibility (and, in fact, this behaviour makes more sense anyhow
+  // because only the added pages are shown)
+  int n = 0;
+  for ( wxNode *node = m_pages.First(); node; node = node->Next() )
+  {
+    wxNotebookPage *page = (wxNotebookPage*)node->Data();
+    if ( page->WasAdded() )
+        n++;
+  }
+
+  return n;
 }
 
 int wxNotebook::GetRowCount() const
@@ -227,7 +255,7 @@ int wxNotebook::GetRowCount() const
 wxString wxNotebook::GetPageText( int page ) const
 {
   wxCHECK_MSG( m_widget != NULL, "", "invalid notebook" );
-  
+
   wxNotebookPage* nb_page = GetNotebookPage(page);
   if (nb_page)
     return nb_page->m_text;
@@ -272,7 +300,7 @@ int wxNotebook::SetSelection( int page )
 
   int selOld = GetSelection();
   wxNotebookPage* nb_page = GetNotebookPage(page);
-  
+
   if (!nb_page) return -1;
 
   int page_num = 0;
@@ -298,7 +326,7 @@ void wxNotebook::AdvanceSelection( bool bForward )
   int sel = GetSelection();
   int max = GetPageCount();
 
-  if (bForward) 
+  if (bForward)
     SetSelection( sel == max ? 0 : sel + 1 );
   else
     SetSelection( sel == 0 ? max : sel - 1 );
@@ -314,7 +342,7 @@ bool wxNotebook::SetPageText( int page, const wxString &text )
   wxCHECK_MSG( m_widget != NULL, FALSE, "invalid notebook" );
 
   wxNotebookPage* nb_page = GetNotebookPage(page);
-  
+
   if (!nb_page) return FALSE;
 
   nb_page->m_text = text;
@@ -325,7 +353,7 @@ bool wxNotebook::SetPageText( int page, const wxString &text )
 bool wxNotebook::SetPageImage( int page, int image )
 {
   wxNotebookPage* nb_page = GetNotebookPage(page);
-  
+
   if (!nb_page) return FALSE;
 
   nb_page->m_image = image;
@@ -424,9 +452,13 @@ bool wxNotebook::AddPage(wxWindow* win, const wxString& text,
     node = node->Next();
   }
 
-  wxCHECK_MSG( page != NULL, FALSE, "Can't add a page whose parent is not the notebook!" );
+  wxCHECK_MSG( page != NULL, FALSE,
+               "Can't add a page whose parent is not the notebook!" );
+
+  wxCHECK_MSG( page->Add(), FALSE,
+               "Can't add the same page twice to a notebook." );
 
-  if (imageId != -1) 
+  if (imageId != -1)
   {
     wxASSERT( m_imageList != NULL );