From: Vadim Zeitlin Date: Thu, 20 Sep 2012 10:19:54 +0000 (+0000) Subject: Fix incorrect code sorting pages by their widths in wxRibbon. X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/f335950b3a5c4f2a2c0c52a2454b39cb7a0ceb84?ds=inline 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 --- 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