gui_list_helper.h

Go to the documentation of this file.
00001 /***************************************************************************
00002                               gui_list_helper.h
00003                              -------------------
00004     begin                : Son Sep 26 2004
00005     copyright            : (C) 2004 by Martin Witte
00006     email                : emw-kradio@nocabal.de
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU General Public License as published by  *
00013  *   the Free Software Foundation; either version 2 of the License, or     *
00014  *   (at your option) any later version.                                   *
00015  *                                                                         *
00016  ***************************************************************************/
00017 
00018 #ifndef _KRADIO_LIBKRADIO_GUI_GUI_LIST_HELPER_H_
00019 #define _KRADIO_LIBKRADIO_GUI_GUI_LIST_HELPER_H_
00020 
00021 #ifdef HAVE_CONFIG_H
00022 #include <config.h>
00023 #endif
00024 
00025 #include <kdemacros.h>
00026 
00027 #include <QtCore/QMap>
00028 #include <QtCore/QList>
00029 #include <QtCore/QString>
00030 #include <QtCore/QObject>
00031 #include <QtCore/QVariant>
00032 #include <QtCore/QObject>
00033 
00034 class KDE_EXPORT GUIListHelperQObjectBase : public QObject
00035 {
00036 Q_OBJECT
00037 
00038 public:
00039     GUIListHelperQObjectBase         ();
00040     virtual ~GUIListHelperQObjectBase();
00041 
00042 public slots:
00043 
00044     virtual void    slotOK()            = 0;
00045     virtual void    slotCancel()        = 0;
00046 
00047 protected slots:
00048     virtual void    slotUserSelection() = 0;
00049 
00050 protected:
00051     void            emitSigDirtyChanged(bool d);
00052 
00053 signals:
00054     void            sigDirtyChanged (bool dirty);
00055 };
00056 
00057 
00058 template <class TLIST, class TID> class KDE_EXPORT GUIListHelper : public GUIListHelperQObjectBase
00059 {
00060 public:
00061     enum SORT_KEY { SORT_BY_ID, SORT_BY_DESCR, SORT_NONE };
00062 
00063     GUIListHelper (TLIST *list, SORT_KEY skey);
00064     GUIListHelper (TLIST *list, const QMap<TID, QString> &data, SORT_KEY skey);
00065     GUIListHelper (TLIST *list, const QList<QString> &data, SORT_KEY skey);
00066     ~GUIListHelper() {}
00067 
00068     void          setList(TLIST *list)                { m_List = list; }
00069 
00070     void          setCurrentItemID(const TID &id);
00071     void          setOrgItemID    (const TID &id);
00072 
00073     template<class TData>
00074     void          alternativesChanged(const TData &data);
00075 
00076     const TID     getCurrentItemID() const;
00077 
00078     int           count() const                       { return m_List ? m_List->count() : 0; }
00079 
00080 public:
00081 
00082     virtual void  slotOK();
00083     virtual void  slotCancel();
00084     virtual void  slotUserSelection();
00085 
00086 protected:
00087     void          setData(const QMap<TID, QString> &data);  // only updates list elements, no setting/update of current element
00088     void          setData(const QList<QString>     &data);  // only updates list elements, no setting/update of current element
00089     bool          containsItemID(const TID &id) const { return m_List && m_List->findData(id) >= 0; }
00090 
00091     void          setUserDirty()                  { setDirty(true,  m_alternativeDirty); }
00092     void          setUserDirty(bool dirty)        { setDirty(dirty, m_alternativeDirty); }
00093     void          setAlternativeDirty()           { setDirty(m_userDirty, true);  }
00094     void          setAlternativeDirty(bool dirty) { setDirty(m_userDirty, dirty); }
00095     void          setDirty(bool userDirty, bool alternativesDirty)
00096                                                   { m_userDirty        = userDirty;
00097                                                     m_alternativeDirty = alternativesDirty;
00098                                                     emitSigDirtyChanged(m_userDirty || m_alternativeDirty); }
00099 
00100 protected:
00101     SORT_KEY      m_skey;
00102     TLIST        *m_List;
00103     bool          m_userDirty;
00104     bool          m_alternativeDirty;
00105 
00106     TID           m_orgID;
00107     TID           m_userSelID;
00108 
00109     bool          m_ignoreGUIChange;
00110 
00111     struct THelpData {
00112         TID         id;
00113         QString     descr;
00114         SORT_KEY    skey;
00115 
00116         THelpData()
00117             : id(),
00118               descr(),
00119               skey(SORT_BY_ID)
00120           {}
00121 
00122         THelpData(TID _id, const QString &_descr, SORT_KEY _skey)
00123             : id(_id),
00124               descr(_descr),
00125               skey(_skey)
00126           {}
00127 
00128         bool operator > (const THelpData &d) const { return (skey == SORT_BY_ID) ? id > d.id : descr > d.descr; }
00129         bool operator < (const THelpData &d) const { return (skey == SORT_BY_ID) ? id < d.id : descr < d.descr; }
00130     };
00131 };
00132 
00133 
00134 
00135 template <class TLIST, class TID>
00136 GUIListHelper<TLIST, TID>::GUIListHelper(TLIST *list, SORT_KEY skey)
00137   : m_skey(skey),
00138     m_List(list),
00139     m_userDirty(false),
00140     m_alternativeDirty(false),
00141     m_ignoreGUIChange(false)
00142 {
00143     if (list)
00144         QObject::connect(list, SIGNAL(activated(int)), this, SLOT(slotUserSelection()));
00145 }
00146 
00147 
00148 template <class TLIST, class TID>
00149 GUIListHelper<TLIST, TID>::GUIListHelper(TLIST *list, const QMap<TID, QString> &data, SORT_KEY skey)
00150   : m_skey(skey),
00151     m_List(list),
00152     m_userDirty(false),
00153     m_alternativeDirty(false),
00154     m_ignoreGUIChange(false)
00155 {
00156     if (list)
00157         QObject::connect(list, SIGNAL(activated(int)), this, SLOT(slotUserSelection()));
00158     setData(data);
00159 }
00160 
00161 template <class TLIST, class TID>
00162 GUIListHelper<TLIST, TID>::GUIListHelper(TLIST *list, const QList<QString> &data, SORT_KEY skey)
00163   : m_skey(skey),
00164     m_List(list),
00165     m_userDirty(false),
00166     m_alternativeDirty(false),
00167     m_ignoreGUIChange(false)
00168 {
00169     if (list)
00170         QObject::connect(list, SIGNAL(activated(int)), this, SLOT(slotUserSelection()));
00171     setData(data);
00172 }
00173 
00174 
00175 
00176 
00177 template <class TLIST, class TID>
00178 void GUIListHelper<TLIST, TID>::slotOK()
00179 {
00180     if (m_userDirty) {
00181         setOrgItemID(getCurrentItemID());
00182     }
00183     setDirty(false, !m_userDirty && m_alternativeDirty);
00184 }
00185 
00186 template <class TLIST, class TID>
00187 void GUIListHelper<TLIST, TID>::slotCancel()
00188 {
00189     setDirty(false, false);
00190     setCurrentItemID(m_orgID);  // will set alternativeDirty if org is not available
00191 }
00192 
00193 template <class TLIST, class TID>
00194 void GUIListHelper<TLIST, TID>::slotUserSelection()
00195 {
00196     if (m_ignoreGUIChange)
00197         return;
00198     m_userSelID = getCurrentItemID();
00199     setDirty(true, false);
00200 }
00201 
00202 template <class TLIST, class TID>
00203 template <class TData>
00204 void GUIListHelper<TLIST, TID>::alternativesChanged(const TData &data)
00205 {
00206     setData(data);
00207 
00208     // m_userDirty is not touched
00209     setAlternativeDirty(false); // will be set if no alternative is available
00210 
00211     if (!m_userDirty) {
00212         // try to set original, alternativeDirty will be set if not possible
00213         setCurrentItemID(m_orgID);
00214     } else {
00215         // try to keep user selection. alternativeDirty will be set if not possible
00216         setCurrentItemID(m_userSelID);
00217     }
00218 }
00219 
00220 
00221 
00222 template <class TLIST, class TID>
00223 void GUIListHelper<TLIST, TID>::setData(const QMap<TID, QString> &data) {
00224     m_List->clear();
00225 
00226     QList<THelpData> help_list;
00227     for (typename QMap<TID, QString>::const_iterator it = data.begin(); it != data.end(); ++it) {
00228         help_list.push_back(THelpData(it.key(), it.value(), m_skey));
00229     }
00230     if (m_skey != SORT_NONE) {
00231         qSort(help_list);
00232     }
00233 
00234     THelpData  item;
00235     foreach (item, help_list) {
00236         m_List->addItem(item.descr, item.id);
00237     }
00238 }
00239 
00240 
00241 template <class TLIST, class TID>
00242 void GUIListHelper<TLIST, TID>::setData (const QList<QString> &_data)
00243 {
00244     m_List->clear();
00245     QList<QString> data = _data;
00246     if (m_skey != SORT_NONE) {
00247         qSort(data);
00248     }
00249 
00250     QString item;
00251     foreach (item, data) {
00252         m_List->addItem(item, item);
00253     }
00254 }
00255 
00256 
00257 template <class TLIST, class TID>
00258 void GUIListHelper<TLIST, TID>::setCurrentItemID(const TID &id)
00259 {
00260     bool oldIgnoreGUIChange = m_ignoreGUIChange;
00261     m_ignoreGUIChange = true;
00262 
00263     int idx = m_List->findData(id);
00264     if (idx >= 0) {
00265         m_List->setCurrentIndex(idx);
00266     } else {
00267         m_List->setCurrentIndex(0);
00268         setAlternativeDirty();
00269     }
00270 
00271     m_ignoreGUIChange = oldIgnoreGUIChange;
00272 }
00273 
00274 template <class TLIST, class TID>
00275 void GUIListHelper<TLIST, TID>::setOrgItemID(const TID &id)
00276 {
00277     m_orgID = id;
00278     if (!m_userDirty) {
00279         setCurrentItemID(m_orgID);
00280     }
00281 }
00282 
00283 template <class TLIST, class TID>
00284 const TID GUIListHelper<TLIST, TID>::getCurrentItemID() const
00285 {
00286     int idx = m_List->currentIndex();
00287     if (idx >= 0) {
00288         const QVariant &data = m_List->itemData(idx);
00289         return data.value<TID>();
00290     } else {
00291         return TID();
00292     }
00293 }
00294 
00295 
00296 
00297 #endif
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines