"Fossies" - the Fresh Open Source Software Archive

Member "MP3Diags-unstable-1.5.01/src/DoubleList.cpp" (16 Feb 2019, 24854 Bytes) of package /linux/privat/MP3Diags-unstable-1.5.01.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "DoubleList.cpp" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 1.3.04_vs_1.5.01.

    1 /***************************************************************************
    2  *   MP3 Diags - diagnosis, repairs and tag editing for MP3 files          *
    3  *                                                                         *
    4  *   Copyright (C) 2009 by Marian Ciobanu                                  *
    5  *   ciobi@inbox.com                                                       *
    6  *                                                                         *
    7  *   This program is free software; you can redistribute it and/or modify  *
    8  *   it under the terms of the GNU General Public License version 2 as     *
    9  *   published by the Free Software Foundation.                            *
   10  *                                                                         *
   11  *   This program is distributed in the hope that it will be useful,       *
   12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
   13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
   14  *   GNU General Public License for more details.                          *
   15  *                                                                         *
   16  *   You should have received a copy of the GNU General Public License     *
   17  *   along with this program; if not, write to the                         *
   18  *   Free Software Foundation, Inc.,                                       *
   19  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
   20  ***************************************************************************/
   21 
   22 
   23 #include  <algorithm>
   24 
   25 #include  <QPainter>
   26 #include  <QTimer>
   27 #include  <QHeaderView>
   28 
   29 #include  "DoubleList.h"
   30 
   31 #include  "Helpers.h"
   32 #include  "CommonData.h"
   33 
   34 
   35 using namespace std;
   36 
   37 using namespace DoubleListImpl;
   38 
   39 
   40 
   41 
   42 //=====================================================================================================================
   43 //=====================================================================================================================
   44 //=====================================================================================================================
   45 
   46 
   47 
   48 AvailableModel::AvailableModel(ListPainter& listPainter) : m_listPainter(listPainter)
   49 {
   50 }
   51 
   52 
   53 int AvailableModel::rowCount() const
   54 {
   55     int n (cSize(m_listPainter.getAvailable()));
   56     return n;
   57 }
   58 
   59 
   60 int AvailableModel::columnCount() const
   61 {
   62     return m_listPainter.getColCount();
   63 }
   64 
   65 
   66 /*override*/ QVariant AvailableModel::data(const QModelIndex& index, int nRole) const
   67 {
   68 //LAST_STEP("AvailableModel::data()");
   69     if (!index.isValid()) { return QVariant(); }
   70 
   71     if (nRole != Qt::DisplayRole) { return QVariant(); }
   72 
   73     int nRow (index.row());
   74     int nAllIndex (m_listPainter.getAvailable()[nRow]);
   75     return convStr(m_listPainter.getAll()[nAllIndex]->getText(index.column()));
   76 }
   77 
   78 
   79 /*override*/ QVariant AvailableModel::headerData(int nSection, Qt::Orientation eOrientation, int nRole /* = Qt::DisplayRole*/) const
   80 {
   81 //LAST_STEP("AvailableModel::headerData");
   82     if (nRole == Qt::SizeHintRole)
   83     {
   84         return getNumVertHdrSize(cSize(m_listPainter.getAvailable()), eOrientation);
   85     }
   86 
   87     if (nRole != Qt::DisplayRole) { return QVariant(); }
   88     if (Qt::Horizontal == eOrientation)
   89     {
   90         return convStr(m_listPainter.getColTitle(nSection));
   91     }
   92 
   93     return nSection + 1;
   94 }
   95 
   96 
   97 
   98 void AvailableModel::emitLayoutChanged()
   99 {
  100     emit layoutChanged();
  101 }
  102 
  103 //---------------------------------------------------------------------------------------------------------------------
  104 //---------------------------------------------------------------------------------------------------------------------
  105 
  106 
  107 
  108 /*override*/ void AvailableModelDelegate::paint(QPainter* pPainter, const QStyleOptionViewItem& option, const QModelIndex& index) const
  109 {
  110     pPainter->save();
  111 
  112     //pPainter->fillRect(option.rect, QBrush(m_listPainter.getColor(m_listPainter.getAvailable()[index.row()], index.column(), pPainter->background().color()))); //ttt2 make sure background() is the option to use
  113     QColor bckgCol (pPainter->background().color());
  114     QColor penCol (pPainter->pen().color());
  115     double dGradStart (-1), dGradEnd (-1);
  116     m_listPainter.getColor(m_listPainter.getAvailable()[index.row()], index.column(), ListPainter::ALL_LIST, bckgCol, penCol, dGradStart, dGradEnd);
  117     QLinearGradient grad (0, option.rect.y(), 0, option.rect.y() + option.rect.height());
  118     configureGradient(grad, bckgCol, dGradStart, dGradEnd);
  119     pPainter->fillRect(option.rect, grad);
  120 
  121     QStyleOptionViewItemV2 myOption (option);
  122     myOption.displayAlignment = m_listPainter.getAlignment(index.column());
  123     myOption.palette.setColor(QPalette::Text, penCol);
  124     QItemDelegate::paint(pPainter, myOption, index);
  125 
  126     pPainter->restore();
  127 }
  128 
  129 
  130 //=====================================================================================================================
  131 //=====================================================================================================================
  132 //=====================================================================================================================
  133 
  134 
  135 
  136 SelectedModel::SelectedModel(ListPainter& listPainter) : m_listPainter(listPainter)
  137 {
  138 }
  139 
  140 
  141 int SelectedModel::rowCount() const
  142 {
  143     int n (cSize(m_listPainter.getSel()));
  144     if (0 == n && !m_listPainter.getNothingSelStr().empty()) { return 1; }
  145     return n;
  146 }
  147 
  148 
  149 int SelectedModel::columnCount() const
  150 {
  151     if (m_listPainter.getSel().empty() && !m_listPainter.getNothingSelStr().empty())
  152     {
  153         return 1;
  154     }
  155     return m_listPainter.getColCount();
  156 }
  157 
  158 
  159 
  160 /*override*/ QVariant SelectedModel::data(const QModelIndex& index, int nRole) const
  161 {
  162 //LAST_STEP("SelectedModel::data()");
  163 
  164     if (!index.isValid()) { return QVariant(); }
  165 
  166     if (nRole != Qt::DisplayRole && nRole != Qt::ToolTipRole) { return QVariant(); }
  167 
  168     int nRow (index.row());
  169 
  170     QString qstrRes;
  171     if (m_listPainter.getSel().empty())
  172     {
  173         CB_ASSERT(0 == nRow);
  174         //qstrRes = 0 == index.column() ? "" : "<all notes>";
  175         qstrRes = convStr(m_listPainter.getNothingSelStr()); // !!! in this case there's only 1 column
  176     }
  177     else
  178     {
  179         int nAllIndex (m_listPainter.getSel()[nRow]);
  180         qstrRes = convStr(m_listPainter.getAll()[nAllIndex]->getText(index.column()));
  181     }
  182 
  183     if (nRole == Qt::ToolTipRole)
  184     {
  185 #if 0
  186         // works but tooltip is no longer needed here
  187         //QFontMetrics fm (QApplication::fontMetrics());
  188         QFontMetrics fm (m_pTableView->fontMetrics()); // !!! no need to use "QApplication::fontMetrics()", because m_pTableView is needed anyway to get the column widths
  189         int nWidth (fm.width(qstrRes));
  190 
  191         if (nWidth + 10 < m_pTableView->horizontalHeader()->sectionSize(index.column())) // ttt2 "10" is hard-coded
  192         {
  193             return QVariant();
  194         }//*/
  195 #else
  196         return QVariant();
  197 #endif
  198     }
  199 
  200     return qstrRes;
  201 }
  202 
  203 
  204 /*override*/ QVariant SelectedModel::headerData(int nSection, Qt::Orientation eOrientation, int nRole /* = Qt::DisplayRole*/) const
  205 {
  206 //LAST_STEP("SelectedModel::headerData");
  207     if (nRole == Qt::SizeHintRole)
  208     {
  209         return getNumVertHdrSize(cSize(m_listPainter.getSel()), eOrientation);
  210     }
  211 
  212     if (nRole != Qt::DisplayRole) { return QVariant(); }
  213     if (Qt::Horizontal == eOrientation)
  214     {
  215         if (m_listPainter.getSel().empty() && !m_listPainter.getNothingSelStr().empty())
  216         {
  217             return "";
  218         }
  219         return convStr(m_listPainter.getColTitle(nSection));
  220     }
  221 
  222     if (m_listPainter.getSel().empty())
  223     {
  224         return "";
  225     }
  226 
  227     return nSection + 1;
  228 }
  229 
  230 
  231 
  232 void SelectedModel::emitLayoutChanged()
  233 {
  234     emit layoutChanged();
  235 }
  236 
  237 
  238 //---------------------------------------------------------------------------------------------------------------------
  239 //---------------------------------------------------------------------------------------------------------------------
  240 
  241 
  242 /*override*/ void SelectedModelDelegate::paint(QPainter* pPainter, const QStyleOptionViewItem& option, const QModelIndex& index) const
  243 {
  244     if (m_listPainter.getSel().empty())
  245     {
  246         QItemDelegate::paint(pPainter, option, index);
  247         return;
  248     }
  249 
  250     pPainter->save();
  251     //int nRow (index.row());
  252     //int nCol (index.column());
  253     //const Note* pNote (m_pSelectedModel->m_vpNotes[nRow]);
  254 
  255     /*
  256     // first approach; works, but it's more complicated
  257     QStyleOptionViewItemV2 myOption (option);
  258     if (0 == index.column())
  259     {
  260         myOption.displayAlignment |= Qt::AlignHCenter;
  261     }
  262 
  263     pPainter->fillRect(myOption.rect, QBrush(noteColor(*pNote)));
  264 
  265     QString qstrText (index.model()->data(index, Qt::DisplayRole).toString());
  266 
  267     drawDisplay(pPainter, myOption, myOption.rect, qstrText);
  268     drawFocus(pPainter, myOption, myOption.rect);*/
  269 
  270     // second approach
  271     //pPainter->fillRect(option.rect, QBrush(m_listPainter.getColor(m_listPainter.getSel()[nRow], nCol, option.palette.color(QPalette::Active, QPalette::Base)))); //ttt3 " Active" not right if the window is inactive
  272 
  273     QColor bckgCol (option.palette.color(QPalette::Active, QPalette::Base)); //ttt3 compare to avl, where it's "QColor bckgCol (pPainter->background().color());" see why // 2009.07.15 - probably "option..." is better; the other one relies on the painter to be initialized to what's in option, but not sure that is required; so penCol is not quite right as well; however, the painter probably comes initialized correctly
  274 
  275     QColor penCol (pPainter->pen().color());
  276     double dGradStart (-1), dGradEnd (-1);
  277     m_listPainter.getColor(m_listPainter.getSel()[index.row()], index.column(), ListPainter::SUB_LIST, bckgCol, penCol, dGradStart, dGradEnd);
  278     QLinearGradient grad (0, option.rect.y(), 0, option.rect.y() + option.rect.height());
  279     configureGradient(grad, bckgCol, dGradStart, dGradEnd);
  280     pPainter->fillRect(option.rect, grad);
  281 
  282     QStyleOptionViewItemV2 myOption (option);
  283     myOption.displayAlignment = m_listPainter.getAlignment(index.column());
  284     myOption.palette.setColor(QPalette::Text, penCol);
  285     QItemDelegate::paint(pPainter, myOption, index);
  286 
  287     pPainter->restore();
  288 }
  289 
  290 
  291 
  292 
  293 //=====================================================================================================================
  294 //=====================================================================================================================
  295 //=====================================================================================================================
  296 
  297 //#include <iostream>
  298 
  299 
  300 
  301 DoubleList::DoubleList(
  302         ListPainter& listPainter,
  303         int nButtons,
  304         //bool bAllowMultipleSel,
  305         //bool bUserSortSel,
  306         SelectionMode eSelectionMode,
  307         const std::string& strAvailableLabel,
  308         const std::string& strSelLabel,
  309         QWidget* pParent, Qt::WindowFlags fl /* =0*/) :
  310 
  311         QWidget(pParent, fl), Ui::DoubleListWdg(),
  312 
  313         m_listPainter(listPainter),
  314         //m_bAllowMultipleSel(bAllowMultipleSel),
  315         //m_bUserSortSel(bUserSortSel),
  316         m_eSelectionMode(eSelectionMode),
  317         m_availableModel(listPainter),
  318         m_selectedModel(listPainter),
  319         m_bSectionMovedLock(false)
  320 {
  321     setupUi(this);
  322 //printContainer(listPainter.m_vOrigSel, cout);
  323     if (SINGLE_UNSORTABLE == eSelectionMode)
  324     {
  325         for (int i = 0, n = cSize(listPainter.m_vOrigSel); i < n - 1; ++i)
  326         {
  327             CB_ASSERT(listPainter.m_vOrigSel[i] < listPainter.m_vOrigSel[i + 1]);
  328         }
  329     }
  330 
  331     m_pAvailableL->setText(convStr(strAvailableLabel));
  332     m_pSelL->setText(convStr(strSelLabel));
  333 
  334     if (0 == (nButtons & ADD_ALL)) { delete m_pAddAllB; }
  335     if (0 == (nButtons & DEL_ALL)) { delete m_pDeleteAllB; }
  336     if (0 == (nButtons & RESTORE_OPEN)) { delete m_pRestoreOpenB; }
  337     if (0 == (nButtons & RESTORE_DEFAULT)) { delete m_pRestoreDefaultB; }
  338 
  339     //m_listPainter.m_vSel = m_listPainter.m_vOrigSel;
  340 
  341     initAvailable();
  342 
  343     m_pAvailableG->setModel(&m_availableModel);
  344     m_pSelectedG->setModel(&m_selectedModel);
  345 
  346     AvailableModelDelegate* pAvDel = new AvailableModelDelegate(m_listPainter, m_pAvailableG);
  347     m_pAvailableG->setItemDelegate(pAvDel);
  348 
  349     SelectedModelDelegate* pSelDel = new SelectedModelDelegate(m_listPainter, m_pSelectedG);
  350     m_pSelectedG->setItemDelegate(pSelDel);
  351 
  352     setUpGrid(m_pAvailableG);
  353     setUpGrid(m_pSelectedG);
  354 
  355     {
  356         string s;
  357         s = m_listPainter.getTooltip(ListPainter::SELECTED_G); if (!s.empty()) { m_pSelectedG->setToolTip(convStr(s)); }
  358         s = m_listPainter.getTooltip(ListPainter::AVAILABLE_G); if (!s.empty()) { m_pAvailableG->setToolTip(convStr(s)); }
  359         s = m_listPainter.getTooltip(ListPainter::ADD_B); if (!s.empty()) { m_pAddB->setToolTip(convStr(s)); }
  360         s = m_listPainter.getTooltip(ListPainter::DELETE_B); if (!s.empty()) { m_pDeleteB->setToolTip(convStr(s)); }
  361         s = m_listPainter.getTooltip(ListPainter::ADD_ALL_B); if (!s.empty()) { m_pAddAllB->setToolTip(convStr(s)); }
  362         s = m_listPainter.getTooltip(ListPainter::DELETE_ALL_B); if (!s.empty()) { m_pDeleteAllB->setToolTip(convStr(s)); }
  363         s = m_listPainter.getTooltip(ListPainter::RESTORE_DEFAULT_B); if (!s.empty()) { m_pRestoreDefaultB->setToolTip(convStr(s)); }
  364         s = m_listPainter.getTooltip(ListPainter::RESTORE_OPEN_B); if (!s.empty()) { m_pRestoreOpenB->setToolTip(convStr(s)); }
  365     }
  366 
  367     if (SINGLE_UNSORTABLE != m_eSelectionMode)
  368     {
  369         m_pSelectedG->verticalHeader()->setSectionsMovable(true);
  370     }
  371 
  372     connect(m_pSelectedG->verticalHeader(), SIGNAL(sectionMoved(int, int, int)), this, SLOT(onSelSectionMoved(int, int, int)));
  373 
  374     connect(m_pAvailableG, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(onAvlDoubleClicked(const QModelIndex&)));
  375 
  376     decreaseRowHeaderFont(*m_pSelectedG);
  377     decreaseRowHeaderFont(*m_pAvailableG);
  378 
  379     //ttt2 perhaps use QAction::shortcutContext(Qt::WidgetShortcut) to set up shortcuts, if it works well enough
  380 }
  381 
  382 
  383 DoubleList::~DoubleList()
  384 {
  385 }
  386 
  387 
  388 void DoubleList::onSelSectionMoved(int /*nLogicalIndex*/, int nOldVisualIndex, int nNewVisualIndex)
  389 {
  390     CB_ASSERT(SINGLE_SORTABLE == m_eSelectionMode || MULTIPLE == m_eSelectionMode);
  391     NonblockingGuard sectionMovedGuard (m_bSectionMovedLock);
  392 
  393     if (!sectionMovedGuard)
  394     {
  395         return;
  396     }
  397 
  398     //m_pSelectedG->verticalHeader()->headerDataChanged(Qt::Vertical, 0, 4);
  399     m_pSelectedG->verticalHeader()->moveSection(nNewVisualIndex, nOldVisualIndex);
  400 
  401     SubList& vSel (m_listPainter.m_vSel);
  402     int x (vSel[nOldVisualIndex]);
  403     vSel.erase(vSel.begin() + nOldVisualIndex);
  404     vSel.insert(vSel.begin() + nNewVisualIndex, x);
  405 
  406     adjustOnDataChanged();
  407 }
  408 
  409 
  410 void DoubleList::initAvailable()
  411 {
  412     m_listPainter.m_vAvailable.clear();
  413 
  414     switch (m_eSelectionMode)
  415     {
  416     case MULTIPLE:
  417         for (int i = 0, n = cSize(m_listPainter.getAll()); i < n; ++i)
  418         {
  419             m_listPainter.m_vAvailable.push_back(i); // in a sense, m_listPainter.m_vAvailable shouldn't be used at all in this case, and it isn't in the DoubleList code; however, it makes AvailableModel easier, because while DoubleList always has to check the value of m_eSelectionMode anyway, AvailableModel doesn't have to do this, but an empty m_listPainter.m_vAvailable in the MULTIPLE case would force it to do so;
  420         }
  421         break;
  422 
  423     case SINGLE_UNSORTABLE:
  424         {
  425             int n (cSize(m_listPainter.getAll()));
  426             m_listPainter.m_vSel.push_back(n);
  427             for (int i = 0, j = 0; i < n; ++i)
  428             {
  429                 if (i < m_listPainter.m_vSel[j])
  430                 {
  431                     m_listPainter.m_vAvailable.push_back(i);
  432                 }
  433                 else
  434                 {
  435                     ++j;
  436                 }
  437             }
  438             m_listPainter.m_vSel.pop_back();
  439         }
  440         break;
  441 
  442     case SINGLE_SORTABLE:
  443         {
  444             SubList v (m_listPainter.m_vSel.begin(), m_listPainter.m_vSel.end());
  445             sort(v.begin(), v.end());
  446             int n (cSize(m_listPainter.getAll()));
  447             v.push_back(n);
  448             for (int i = 0, j = 0; i < n; ++i)
  449             {
  450                 if (i < v[j])
  451                 {
  452                     m_listPainter.m_vAvailable.push_back(i);
  453                 }
  454                 else
  455                 {
  456                     ++j;
  457                 }
  458             }
  459         }
  460         break;
  461 
  462     }
  463 }
  464 
  465 
  466 void DoubleList::setUpGrid(QTableView* pGrid)
  467 {
  468     pGrid->verticalHeader()->setMinimumSectionSize(m_listPainter.getHdrHeight());
  469 
  470     pGrid->verticalHeader()->setDefaultSectionSize(m_listPainter.getHdrHeight());
  471     pGrid->verticalHeader()->setSectionResizeMode(QHeaderView::Interactive);
  472     pGrid->verticalHeader()->setDefaultAlignment(Qt::AlignRight | Qt::AlignVCenter);
  473 
  474     resizeColumns(pGrid);
  475 }
  476 
  477 void DoubleList::resizeColumns(QTableView* pGrid)
  478 {
  479     if (1 == pGrid->horizontalHeader()->count())
  480     {
  481         pGrid->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);
  482     }
  483     else
  484     {
  485         for (int i = 0, n = m_listPainter.getColCount(); i < n; ++i)
  486         {
  487             int w (m_listPainter.getColWidth(i));
  488             if (w >= 0)
  489             {
  490                 pGrid->horizontalHeader()->setSectionResizeMode(i, QHeaderView::Interactive);
  491                 pGrid->horizontalHeader()->resizeSection(i, w);
  492             }
  493             else
  494             {
  495                 pGrid->horizontalHeader()->setSectionResizeMode(i, QHeaderView::Stretch);
  496             }
  497         }
  498     }
  499 }
  500 
  501 
  502 
  503 void DoubleList::clearSel()
  504 {
  505     m_pSelectedG->selectionModel()->clear();
  506     m_pAvailableG->selectionModel()->clear();
  507 }
  508 
  509 
  510 
  511 void DoubleList::resizeRows()
  512 {
  513     m_pAvailableG->resizeRowsToContents();
  514     m_pSelectedG->resizeRowsToContents();
  515 }
  516 
  517 
  518 
  519 void DoubleList::emitLayoutChanged()
  520 {
  521     m_availableModel.emitLayoutChanged();
  522     m_selectedModel.emitLayoutChanged();
  523 }
  524 
  525 
  526 
  527 
  528 void DoubleList::adjustOnDataChanged()
  529 {
  530     emitLayoutChanged();
  531     resizeColumns(m_pSelectedG); // ttt2 too much: this should only be done when switching between 1 and multiple columns; and even then, going from 1 to many, it should use the "previous" column widths, rather than the "default" ones
  532     resizeRows();
  533     clearSel();
  534 
  535     emit dataChanged();
  536 }
  537 
  538 
  539 
  540 
  541 void DoubleList::on_m_pAddB_clicked()
  542 {
  543     QItemSelectionModel* pSelMdl (m_pAvailableG->selectionModel());
  544     QModelIndexList lSel (pSelMdl->selection().indexes());
  545 
  546     set<int> sSelPos; // the rows must be sorted
  547 
  548     for (QModelIndexList::iterator it = lSel.begin(), end = lSel.end(); it != end; ++it)
  549     {
  550         int nRow (it->row());
  551         CB_ASSERT (nRow >= 0);
  552         sSelPos.insert(nRow);
  553     }
  554 
  555     add(sSelPos);
  556 }
  557 
  558 void DoubleList::add(const std::set<int>& sSelPos) // adds elements from the specified indexes
  559 {
  560     switch (m_eSelectionMode)
  561     {
  562     case SINGLE_UNSORTABLE:
  563         for (set<int>::const_reverse_iterator it = sSelPos.rbegin(), end = sSelPos.rend(); it != end; ++it) // the last must be processed first, so removal of elements doesn't change the row number for the remaining ones
  564         {
  565             int nRow (*it);
  566             int nIndex (m_listPainter.m_vAvailable[nRow]);
  567             vector<int>::iterator it1 (lower_bound(m_listPainter.m_vSel.begin(), m_listPainter.m_vSel.end(), nIndex));
  568             m_listPainter.m_vSel.insert(it1, nIndex);
  569             m_listPainter.m_vAvailable.erase(m_listPainter.m_vAvailable.begin() + nRow);
  570         }
  571         break;
  572 
  573     case SINGLE_SORTABLE:
  574         for (set<int>::const_iterator it = sSelPos.begin(), end = sSelPos.end(); it != end; ++it)
  575         {
  576             int nRow (*it);
  577             int nIndex (m_listPainter.m_vAvailable[nRow]);
  578             m_listPainter.m_vSel.push_back(nIndex);
  579         }
  580         for (set<int>::const_reverse_iterator it = sSelPos.rbegin(), end = sSelPos.rend(); it != end; ++it)
  581         {
  582             int nRow (*it);
  583             m_listPainter.m_vAvailable.erase(m_listPainter.m_vAvailable.begin() + nRow);
  584         }
  585         break;
  586 
  587     case MULTIPLE:
  588         for (set<int>::const_iterator it = sSelPos.begin(), end = sSelPos.end(); it != end; ++it)
  589         {
  590             int nRow (*it);
  591             //int nIndex (m_listPainter.m_vAvailable[nRow]);
  592             //m_listPainter.getSel_().push_back(nIndex);
  593             m_listPainter.m_vSel.push_back(nRow);
  594         }
  595         break;
  596 
  597     default:
  598         CB_ASSERT(false);
  599     }
  600 
  601     adjustOnDataChanged();
  602 }
  603 
  604 
  605 
  606 
  607 void DoubleList::on_m_pDeleteB_clicked()
  608 {
  609     if (m_listPainter.m_vSel.empty()) { return; }
  610     QItemSelectionModel* pSelMdl (m_pSelectedG->selectionModel());
  611     QModelIndexList lSel (pSelMdl->selection().indexes());
  612 
  613     set<int> sSelPos; // the rows must be sorted and the last must be processed first, so removal of elements doesn't change the row number for the remaining ones
  614 
  615     for (QModelIndexList::iterator it = lSel.begin(), end = lSel.end(); it != end; ++it)
  616     {
  617         int nRow (it->row());
  618         CB_ASSERT (nRow >= 0);
  619         sSelPos.insert(nRow);
  620     }
  621 
  622     remove(sSelPos);
  623 }
  624 
  625 
  626 void DoubleList::remove(const std::set<int>& sSelPos) // removes elements from the specified indexes
  627 {
  628     for (set<int>::const_reverse_iterator it = sSelPos.rbegin(), end = sSelPos.rend(); it != end; ++it)
  629     {
  630         int nRow (*it);
  631         int nIndex (m_listPainter.m_vSel[nRow]);
  632         if (MULTIPLE != m_eSelectionMode)
  633         {
  634             vector<int>::iterator it1 (lower_bound(m_listPainter.m_vAvailable.begin(), m_listPainter.m_vAvailable.end(), nIndex));
  635             m_listPainter.m_vAvailable.insert(it1, nIndex);
  636         }
  637         m_listPainter.m_vSel.erase(m_listPainter.m_vSel.begin() + nRow);
  638     }
  639 
  640     adjustOnDataChanged();
  641 }
  642 
  643 
  644 void DoubleList::on_m_pAddAllB_clicked()
  645 {
  646     switch (m_eSelectionMode)
  647     {
  648     case SINGLE_UNSORTABLE:
  649         m_listPainter.m_vAvailable.clear();
  650         m_listPainter.m_vSel.clear();
  651         for (int i = 0, n = cSize(m_listPainter.getAll()); i < n; ++i)
  652         {
  653             m_listPainter.m_vSel.push_back(i);
  654         }
  655         break;
  656 
  657     case SINGLE_SORTABLE:
  658         m_listPainter.m_vSel.insert(m_listPainter.m_vSel.end(), m_listPainter.m_vAvailable.begin(), m_listPainter.m_vAvailable.end());
  659         m_listPainter.m_vAvailable.clear();
  660         break;
  661 
  662     case MULTIPLE:
  663         m_listPainter.m_vSel.insert(m_listPainter.m_vSel.end(), m_listPainter.m_vAvailable.begin(), m_listPainter.m_vAvailable.end());
  664         break;
  665 
  666     default:
  667         CB_ASSERT(false);
  668     }
  669 
  670     adjustOnDataChanged();
  671 }
  672 
  673 
  674 void DoubleList::on_m_pDeleteAllB_clicked()
  675 {
  676     m_listPainter.m_vSel.clear();
  677     if (MULTIPLE != m_eSelectionMode)
  678     {
  679         m_listPainter.m_vAvailable.clear();
  680         for (int i = 0, n = cSize(m_listPainter.getAll()); i < n; ++i)
  681         {
  682             m_listPainter.m_vAvailable.push_back(i);
  683         }
  684     }
  685 
  686     adjustOnDataChanged();
  687 }
  688 
  689 
  690 void DoubleList::on_m_pRestoreDefaultB_clicked()
  691 {
  692     m_listPainter.reset();
  693     m_listPainter.m_bResultInReset = true;
  694     initAvailable();
  695 
  696     adjustOnDataChanged();
  697 }
  698 
  699 
  700 void DoubleList::on_m_pRestoreOpenB_clicked()
  701 {
  702     m_listPainter.m_vSel = m_listPainter.m_vOrigSel;
  703     m_listPainter.m_bResultInReset = false;
  704     initAvailable();
  705 
  706     adjustOnDataChanged();
  707 }
  708 
  709 
  710 
  711 /*override*/ void DoubleList::resizeEvent(QResizeEvent*)
  712 {
  713 //return;
  714 //QDialog::resizeEvent(pEvent);
  715 /*cout << this << ": size: " << width() << "x" << height() << " m_pAvailableG: " << m_pAvailableG->width() << "x" << m_pAvailableG->height() << " m_pSelectedG: " << m_pSelectedG->width() << "x" << m_pSelectedG->height() << " sel hdr: " << m_pSelectedG->horizontalHeader()->sectionSize(0) << ", " << m_pSelectedG->horizontalHeader()->sectionSize(1) << endl;
  716 
  717     m_pAvailableG->resizeRowsToContents();
  718     m_pSelectedG->resizeRowsToContents();*/
  719 
  720     QTimer::singleShot(1, this, SLOT(onResizeTimer())); // !!! 2008.10.27 - this is a workaround for what appears to be a bug in Qt: resizeEvent() doesn't get called after applying a layout; as a result, resizeRowsToContents() uses incorrect sizes to figure line heights; perhaps there's no bug and there's some other way to achieve a QTableView that adjusts the row heights such that all rows fit on the screen (perhaps after Qt 4.3.1), but for now this approach seems good enough; (calling layout()->activate() might do something similar, but it's cumbersome to use)
  721 }
  722 
  723 
  724 
  725 
  726 void DoubleList::onResizeTimer()
  727 {
  728 //cout << this << ": size: " << width() << "x" << height() << " m_pAvailableG: " << m_pAvailableG->width() << "x" << m_pAvailableG->height() << " m_pSelectedG: " << m_pSelectedG->width() << "x" << m_pSelectedG->height() << " sel hdr: " << m_pSelectedG->horizontalHeader()->sectionSize(0) << ", " << m_pSelectedG->horizontalHeader()->sectionSize(1) << endl;
  729 
  730     resizeRows();
  731 }
  732 
  733 
  734 void DoubleList::onAvlDoubleClicked(const QModelIndex& index)
  735 {
  736     emit avlDoubleClicked(index.row());
  737 }
  738