"Fossies" - the Fresh Open Source Software Archive

Member "MP3Diags-unstable-1.5.01/src/DoubleList.h" (10 Feb 2019, 14825 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.h" 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 #ifndef DoubleListH
   24 #define DoubleListH
   25 
   26 #include  <set>
   27 #include  <vector>
   28 
   29 #include  <QWidget>
   30 
   31 #include  "ui_DoubleListWdg.h"
   32 
   33 #include  "MultiLineTvDelegate.h"
   34 
   35 
   36 
   37 class ListPainter;
   38 
   39 
   40 //=====================================================================================================================
   41 //=====================================================================================================================
   42 //=====================================================================================================================
   43 
   44 
   45 namespace DoubleListImpl {
   46 
   47 
   48 // TableModels and Delegates don't have to be public, but they must be in a header, for the Qt preprocessing to work. // ttt3 perhaps move to separate header
   49 
   50 
   51 class AvailableModel : public QAbstractTableModel
   52 {
   53     Q_OBJECT
   54 public:
   55     //std::vector<const Elem*> m_vpElems; // doesn't own the pointers
   56     const ListPainter& m_listPainter;
   57 public:
   58     AvailableModel(ListPainter& listPainter);
   59     /*override*/ int rowCount(const QModelIndex&) const { return rowCount(); }
   60     /*override*/ int columnCount(const QModelIndex&) const { return columnCount(); }
   61     /*override*/ QVariant data(const QModelIndex&, int nRole) const;
   62 
   63     int columnCount() const;
   64     int rowCount() const;
   65 
   66     /*override*/ QVariant headerData(int nSection, Qt::Orientation eOrientation, int nRole = Qt::DisplayRole) const;
   67 
   68     void emitLayoutChanged();
   69 };
   70 
   71 
   72 class SelectedModel : public QAbstractTableModel
   73 {
   74     Q_OBJECT
   75 public:
   76     //std::vector<const Elem*> m_vpElems; // doesn't own the pointers
   77     const ListPainter& m_listPainter;
   78 public:
   79     SelectedModel(ListPainter& listPainter);
   80     /*override*/ int rowCount(const QModelIndex&) const { return rowCount(); }
   81     /*override*/ int columnCount(const QModelIndex&) const { return columnCount(); }
   82     /*override*/ QVariant data(const QModelIndex&, int nRole) const;
   83 
   84     int columnCount() const;
   85     int rowCount() const;
   86 
   87     /*override*/ QVariant headerData(int nSection, Qt::Orientation eOrientation, int nRole = Qt::DisplayRole) const;
   88 
   89     QTableView* m_pTableView; // needed to retrieve column widths, which are needed for tooltips, which are no longer used but this is an example of how to do it
   90     void emitLayoutChanged();
   91 };
   92 
   93 
   94 //class AvailableModelDelegate : public QItemDelegate
   95 class AvailableModelDelegate : public MultiLineTvDelegate
   96 {
   97     Q_OBJECT
   98 
   99     const ListPainter& m_listPainter;
  100 public:
  101     //AvailableModelDelegate(AvailableModel* pAvailableModel, QObject* pParent) : QItemDelegate(pParent), m_pAvailableModel(pAvailableModel) {}
  102     //AvailableModelDelegate(AvailableModel* pAvailableModel, QTableView* pTableView) : MultiLineTvDelegate(pTableView), m_pAvailableModel(pAvailableModel) {}
  103     AvailableModelDelegate(ListPainter& listPainter, QTableView* pTableView) : MultiLineTvDelegate(pTableView), m_listPainter(listPainter) {}
  104 
  105     /*override*/ void paint(QPainter* pPainter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
  106 
  107     //AvailableModel* m_pAvailableModel;
  108 };
  109 
  110 
  111 class SelectedModelDelegate : public MultiLineTvDelegate
  112 {
  113     Q_OBJECT
  114 
  115     const ListPainter& m_listPainter;
  116 public:
  117     SelectedModelDelegate(ListPainter& listPainter, QTableView* pTableView) : MultiLineTvDelegate(pTableView), m_listPainter(listPainter) {}
  118 
  119     /*override*/ void paint(QPainter* pPainter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
  120 
  121 };
  122 
  123 } // namespace DoubleListImpl
  124 
  125 
  126 //=====================================================================================================================
  127 //=====================================================================================================================
  128 //=====================================================================================================================
  129 
  130 
  131 
  132 class ListElem
  133 {
  134 public:
  135     virtual ~ListElem() {} //
  136 
  137     virtual std::string getText(int nCol) const = 0;
  138 };
  139 
  140 
  141 class DoubleList;
  142 
  143 //ttt2 perhaps have a "mirror" option, where available elems are on the left and selected on the right
  144 
  145 /*
  146 ListPainter has 2 related purposes:
  147     1) it holds vectors and some other data used to describe the contents of the lists;
  148     2) provides data needed by QAbstractTableModel and QItemDelegate to display the tables; to do this it uses the vectors described above, as well as abstract functions, which have to be implemented by derived classes;
  149 
  150 The basic idea is that there are 3 vectors: one with "elements", containing everything that is included in the lists, and two with integers, which are indexes in the vector with "elements". One of these two is used for "selected" items, while the other is for "available" ones. Depending on the settings, elements that are included in "selected" may be removed or not from "available" (this is DoubleList's business, though; ListPainter only provides the storage).
  151 
  152 Actually it's a bit more complex: 2 more vectors are used to support "restore open" and "restore default" functionality.
  153 
  154 "Restore default" is optional. To work, it needs reset() to be implemented and a param must be passed to DoubleList, telling it to show the corresponding button. If reset() is implemented, it should populate m_vpResetAll with pointers to elements and m_vSel with indices into m_vpResetAll. In most cases, reset() would only change m_vpResetAll if it is empty, because "there's only one default"; however, m_vSel should most likely be changed.
  155 
  156 Assuming DoubleList is used in a dialog window that gets closed, if reset() is implemented, the caller should check if m_vpResetAll contains elements regardless of the dialog being closed with OK or Cancel. Then it should probably transfer the information and delete the pointers in both vpOrigAll and vpResetAll (or perhaps only in one of them, based on the dialog result and m_bResultInReset). It's the caller's responsibility to provide reset() and to deal with m_vpResetAll in a compatible way.
  157 
  158 
  159 ListPainter and DoubleList don't delete any pointers from m_vpOrigAll or m_vpResetAll. It is the responsability of the class derived from ListPainter or of its users to release pointers. The reason for this is that no reasonable assumptions can be made about the lifetime of the pointers. They may have to be deleted after DoubleList is destroyed or they may have to live until the program is closed. Also, more things may have to be done besides deleting the pointers.
  160 
  161 
  162 Sometimes it makes sense to consider the fact that nothing is "selected" as meaning that everything is "selected". To make this convention obvious from a visual point of view, m_strNothingSel should be used. If its value is non-empty, when m_vSel is empty the "selected" list switches to using a single column (with no title) and a single row, containing a single data cell, whose text is m_strNothingSel (which should be something like "<<all elements>>". Of course, this is just visual. The user of the class must also make sure that the meaning of an empty m_vSel is the same as that of a m_vSel that contains all the available values.
  163 
  164 */
  165 class ListPainter
  166 {
  167 public:
  168     typedef std::vector<const ListElem*> AllList;
  169     typedef std::vector<int> SubList;
  170 
  171     ListPainter(const std::string& strNothingSel) : m_pDoubleList(0), m_bResultInReset(false), m_strNothingSel(strNothingSel)  {}
  172     virtual ~ListPainter() {}
  173 
  174     virtual int getColCount() const = 0;
  175     virtual std::string getColTitle(int nCol) const = 0;
  176 
  177     enum { ALL_LIST, SUB_LIST };
  178     virtual void getColor(int nIndex, int nColumn, bool bSubList, QColor& bckgColor, QColor& penColor, double& dGradStart, double& dGradEnd) const = 0; // nIndex is an index in the "all" table; color is both input and output param; dGradStart and dGradEnd must be either -1 (in which case no gradient is used) or between 0 and 1, with dGradStart < dGradEnd; they are -1 when the call is made, so can be left alone
  179     virtual int getColWidth(int nCol) const = 0; // positive values are used for fixed widths, while negative ones are for "stretched"
  180     virtual int getHdrHeight() const = 0;
  181 
  182     enum TooltipKey { SELECTED_G, AVAILABLE_G, ADD_B, DELETE_B, ADD_ALL_B, DELETE_ALL_B, RESTORE_DEFAULT_B, RESTORE_OPEN_B };
  183     virtual std::string getTooltip(TooltipKey eTooltipKey) const = 0; // !!! this must return an empty string for buttons that are removed, otherwise deallocated memory gets accessed
  184 
  185     virtual Qt::Alignment getAlignment(int nCol) const = 0;
  186     virtual void reset() = 0; // "restore default" functionality
  187 
  188     const std::string& getNothingSelStr() const { return m_strNothingSel; }
  189 
  190     const SubList& getSel() const { return m_vSel; }
  191     const SubList& getAvailable() const { return m_vAvailable; }
  192 
  193     const AllList& getAll() const { return m_bResultInReset ? m_vpResetAll : m_vpOrigAll; }
  194 
  195 protected:
  196     DoubleList* m_pDoubleList; // widget initialized with "this" as parent; deleted automatically by Qt; put here more as a convenience place to store the pointer, but it doesn't HAVE to be used (unlike the other member variables);
  197 
  198     AllList m_vpOrigAll; // the initial list with "all" elements; the derived class must initialize this;
  199     AllList m_vpResetAll; // the list with "all" elements after reset() got called; the derived class must initialize this when reset() is called;
  200 
  201     SubList m_vOrigSel; // used by on_m_pRestoreOpenB_clicked(); the derived class must initialize this;
  202     SubList m_vSel; // the "selected" elements; the derived class must initialize this; usually it's identical to m_vOrigSel at creation;
  203 
  204     // !!! note that both m_vOrigSel and m_vSel must be initialized (in a previous version m_vSel used to be copied from m_vOrigSel, but the current way is more flexible with cases when a DoubleList is created and deleted dynamically, multiple times, while its parent is alive and visible;)
  205 
  206     bool isResultInReset() const { return m_bResultInReset; }
  207 private:
  208     SubList m_vAvailable; // shouldn't be initialized in the derived class (well, it can't anyway, since it's private); DoubleList takes care of this, making it a sorted vector containing either all the numbers between 0 and "getAll().size() - 1", or only those numbers that aren't in m_vSel
  209 
  210     bool m_bResultInReset; // if m_vSel indexes m_vpResetAll or m_vpOrigAll
  211 
  212     std::string m_strNothingSel;
  213 
  214     friend class DoubleList;
  215 };
  216 
  217 
  218 template<typename T, typename V> void getCastElem(T*& p, V& v, int i)
  219 {
  220     p = dynamic_cast<T*>(v[i]);
  221     CB_ASSERT(0 != p);
  222 }
  223 
  224 
  225 
  226 /*
  227 Widget handling a sublist of elements that are "selected" from a full list.
  228 
  229 It is quite configurable, but more options can be envisioned.
  230 
  231 Most of the data are stored in a ListPainter, which must be passed in the constructor (actually some class derived from ListPainter, which is abstract). This is mainly for convenience and clarity (some vectors could be moved to DoubleList, but some must stay in ListPainter and having them all in one place seems better).
  232 
  233 */
  234 class DoubleList : public QWidget, private Ui::DoubleListWdg
  235 {
  236     Q_OBJECT
  237 
  238     typedef ListPainter::AllList AllList;
  239     typedef ListPainter::SubList SubList;
  240 
  241 public:
  242     enum SelectionMode { SINGLE_UNSORTABLE, SINGLE_SORTABLE, MULTIPLE }; // "SORTABLE" means "sortable by the user"; if the user can't sort the "sel" list, the elements are sorted to match the order they appear in the "all" list"; MULTIPLE is always "sortable" //ttt2 the word "Selection" is confusing in this context
  243 
  244 private:
  245 
  246     ListPainter& m_listPainter;
  247 
  248     SelectionMode m_eSelectionMode; // ttt2 perhaps add "Up" and "Down" buttons
  249 
  250     void setUpGrid(QTableView* pGrid);
  251 
  252     void resizeColumns(QTableView* pGrid); // this should be called after LayoutChanged was sent
  253     void clearSel();
  254     void resizeRows();
  255     void emitLayoutChanged();
  256 
  257     void adjustOnDataChanged();
  258 
  259 
  260     DoubleListImpl::AvailableModel m_availableModel;
  261     DoubleListImpl::SelectedModel m_selectedModel;
  262     friend class DoubleListImpl::AvailableModel;
  263     friend class DoubleListImpl::SelectedModel;
  264     friend class DoubleListImpl::AvailableModelDelegate;
  265     friend class DoubleListImpl::SelectedModelDelegate;
  266 
  267     /*override*/ void resizeEvent(QResizeEvent* pEvent);
  268 
  269     void initAvailable();
  270 
  271     bool m_bSectionMovedLock;
  272 public:
  273     enum UsedButtons { NONE = 0x00, ADD_ALL = 0x01, DEL_ALL = 0x02, RESTORE_OPEN = 0x04, RESTORE_DEFAULT = 0x08 };
  274     DoubleList(
  275         ListPainter& listPainter,
  276         int nButtons, // or/xor of UsedButtons
  277         SelectionMode eSelectionMode,
  278         const std::string& strAvailableLabel,
  279         const std::string& strSelLabel,
  280         QWidget* pParent, Qt::WindowFlags fl = 0);
  281     ~DoubleList();
  282 
  283     void add(const std::set<int>&); // adds elements from the specified indexes
  284     void remove(const std::set<int>&); // removes elements from the specified indexes
  285 
  286 signals:
  287     void dataChanged();
  288     void avlDoubleClicked(int nRow);
  289 
  290 protected slots:
  291     void on_m_pAddB_clicked();
  292     void on_m_pDeleteB_clicked();
  293     void on_m_pAddAllB_clicked();
  294     void on_m_pDeleteAllB_clicked();
  295     void on_m_pRestoreOpenB_clicked();
  296     void on_m_pRestoreDefaultB_clicked();
  297 
  298     void onSelSectionMoved(int nLogicalIndex, int nOldVisualIndex, int nNewVisualIndex);
  299 
  300     void onResizeTimer();
  301 
  302     void onAvlDoubleClicked(const QModelIndex& index);
  303 };
  304 
  305 #endif
  306