kradio4
r778
|
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