From f335950b3a5c4f2a2c0c52a2454b39cb7a0ceb84 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 20 Sep 2012 10:19:54 +0000 Subject: [PATCH] Fix incorrect code sorting pages by their widths in wxRibbon. The "sneaky obj array trickery" wasn't very sneaky but was just plain wrong and misused object array of pages in a way that was invalid and didn't crash just because of sheer luck. Rewrite this code to use a temporary wxVector of pages that can be sorted independently of the main m_pages array. This is 100% safe and also more clear. Closes #14625. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@72516 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/ribbon/bar.cpp | 46 +++++++++++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/src/ribbon/bar.cpp b/src/ribbon/bar.cpp index 0970d3b43b..34ee1d4d5e 100644 --- a/src/ribbon/bar.cpp +++ b/src/ribbon/bar.cpp @@ -21,6 +21,7 @@ #include "wx/ribbon/art.h" #include "wx/dcbuffer.h" #include "wx/app.h" +#include "wx/vector.h" #ifndef WX_PRECOMP #endif @@ -465,10 +466,21 @@ void wxRibbonBar::SetTabCtrlMargins(int left, int right) RecalculateTabSizes(); } -static int OrderPageTabInfoBySmallWidthAsc(wxRibbonPageTabInfo **first, wxRibbonPageTabInfo **second) +struct PageComparedBySmallWidthAsc { - return (**first).small_must_have_separator_width - (**second).small_must_have_separator_width; -} + wxEXPLICIT PageComparedBySmallWidthAsc(wxRibbonPageTabInfo* page) + : m_page(page) + { + } + + bool operator<(const PageComparedBySmallWidthAsc& other) const + { + return m_page->small_must_have_separator_width + < other.m_page->small_must_have_separator_width; + } + + wxRibbonPageTabInfo *m_page; +}; void wxRibbonBar::RecalculateTabSizes() { @@ -624,30 +636,27 @@ void wxRibbonBar::RecalculateTabSizes() if(width >= total_small_width) { // Do (2) - wxRibbonPageTabInfoArray sorted_pages; - for(i = 0; i < numtabs; ++i) - { - // Sneaky obj array trickery to not copy the tab descriptors - if (!m_pages.Item(i).shown) - continue; - sorted_pages.Add(&m_pages.Item(i)); - } - sorted_pages.Sort(OrderPageTabInfoBySmallWidthAsc); + wxVector sorted_pages; + sorted_pages.reserve(numtabs); + for ( i = 0; i < numtabs; ++i ) + sorted_pages.push_back(PageComparedBySmallWidthAsc(&m_pages.Item(i))); + + wxVectorSort(sorted_pages); width -= tabsep * (numtabs - 1); for(i = 0; i < numtabs; ++i) { - wxRibbonPageTabInfo& info = sorted_pages.Item(i); - if (!info.shown) + wxRibbonPageTabInfo* info = sorted_pages[i].m_page; + if (!info->shown) continue; - if(info.small_must_have_separator_width * (int)(numtabs - i) <= width) + if(info->small_must_have_separator_width * (int)(numtabs - i) <= width) { - info.rect.width = info.small_must_have_separator_width;; + info->rect.width = info->small_must_have_separator_width;; } else { - info.rect.width = width / (numtabs - i); + info->rect.width = width / (numtabs - i); } - width -= info.rect.width; + width -= info->rect.width; } for(i = 0; i < numtabs; ++i) { @@ -658,7 +667,6 @@ void wxRibbonBar::RecalculateTabSizes() info.rect.y = y; info.rect.height = m_tab_height; x += info.rect.width + tabsep; - sorted_pages.Detach(numtabs - (i + 1)); } } else -- 2.47.2