Here is the solution I made using Boost Serialization.
It handles new and deleted columns, more or less. Works for my use cases.
// Because QHeaderView sucks struct QHeaderViewState { explicit QHeaderViewState(ssci::CustomTreeView const & view): m_headers(view.header()->count()) { QHeaderView const & headers(*view.header()); // Stored in *visual index* order for(int vi = 0; vi < headers.count();++vi) { int li = headers.logicalIndex(vi); HeaderState & header = m_headers[vi]; header.hidden = headers.isSectionHidden(li); header.size = headers.sectionSize(li); header.logical_index = li; header.visual_index = vi; header.name = view.model()->headerData(li,Qt::Horizontal).toString(); header.view = &view; } m_sort_indicator_shown = headers.isSortIndicatorShown(); if(m_sort_indicator_shown) { m_sort_indicator_section = headers.sortIndicatorSection(); m_sort_order = headers.sortIndicatorOrder(); } } QHeaderViewState(){} template<typename Archive> void serialize(Archive & ar, unsigned int) { ar & m_headers; ar & m_sort_indicator_shown; if(m_sort_indicator_shown) { ar & m_sort_indicator_section; ar & m_sort_order; } } void restoreState(ssci::CustomTreeView & view) const { QHeaderView & headers(*view.header()); const int max_columns = std::min(headers.count(), static_cast<int>(m_headers.size())); std::vector<HeaderState> header_state(m_headers); std::map<QString,HeaderState *> map; for(std::size_t ii = 0; ii < header_state.size(); ++ii) map[header_state[ii].name] = &header_state[ii]; // First set all sections to be hidden and update logical // indexes for(int li = 0; li < headers.count(); ++li) { headers.setSectionHidden(li,true); std::map<QString,HeaderState *>::iterator it = map.find(view.model()->headerData(li,Qt::Horizontal).toString()); if(it != map.end()) it->second->logical_index = li; } // Now restore for(int vi = 0; vi < max_columns; ++vi) { HeaderState const & header = header_state[vi]; const int li = header.logical_index; SSCI_ASSERT_BUG(vi == header.visual_index); headers.setSectionHidden(li,header.hidden); headers.resizeSection(li,header.size); headers.moveSection(headers.visualIndex(li),vi); } if(m_sort_indicator_shown) headers.setSortIndicator(m_sort_indicator_section, m_sort_order); } struct HeaderState { initialize<bool,false> hidden; initialize<int,0> size; initialize<int,0> logical_index; initialize<int,0> visual_index; QString name; CustomTreeView const *view; HeaderState():view(0){} template<typename Archive> void serialize(Archive & ar, unsigned int) { ar & hidden & size & logical_index & visual_index & name; } }; std::vector<HeaderState> m_headers; bool m_sort_indicator_shown; int m_sort_indicator_section; Qt::SortOrder m_sort_order; // iff m_sort_indicator_shown };
source share