00001 #ifndef FAITH__LISTVIEW_H
00002 #define FAITH__LISTVIEW_H
00003
00004 #include <faith/scrollview.h>
00005 #include <list>
00006 #include <faith/ui.h>
00007
00008
00009 namespace Faith
00010 {
00011
00012 class GListViewThing;
00013 class GListView;
00014
00015 class FAITH_UI_EXPORT GItemView
00016 {
00017 public:
00018 GItemView();
00019 virtual ~GItemView();
00020 virtual void gInserted(void *item)=0;
00021 virtual void gRemoved(void *item)=0;
00022 virtual void gChanged()=0;
00023
00024 };
00025
00026 class FAITH_UI_EXPORT GListItemSet : public Faith::Object
00027 {
00028 Q_OBJECT
00029 struct GListItemSetPrivate;
00030 GListItemSetPrivate *d;
00031
00032 friend class GItemView;
00033 friend class GListView;
00034
00035 public:
00036 class GIterator
00037 {
00038 struct GListItemSetIteratorPrivate;
00039 GListItemSetIteratorPrivate *d;
00040 friend class GListItemSet;
00041 public:
00042 GIterator();
00043 GIterator(const GIterator ©);
00044 ~GIterator();
00045
00046 GIterator & operator=(const GIterator ©);
00047 bool operator==(const GIterator &other) const;
00048 bool operator!=(const GIterator &other) const
00049 { return !operator==(other); }
00050
00051 GIterator &operator++();
00052 void *operator *();
00053 };
00054
00055 GListItemSet(Faith::Object *parent, const char *name);
00056 ~GListItemSet();
00057
00058 protected:
00059 void gAppend(void *item);
00060 void gPrepend(void *item);
00061 void gInsert(const GIterator &before, void *item);
00062 void gRemove(void *item);
00063 void gChanged();
00064
00065 GIterator gBegin();
00066 GIterator gEnd();
00067
00068 private:
00069 void addedTo(GItemView *);
00070 void removedFrom(GItemView *);
00071 };
00072
00076 class FAITH_UI_EXPORT GListView : public Faith::ScrollView, public GItemView
00077 {
00078 Q_OBJECT
00079 struct GListViewPrivate;
00080 GListViewPrivate *d;
00081
00082 friend class GListItemSet;
00083
00084 public:
00085 GListView(GListItemSet *set, Widget *parent, const char *name);
00086 ~GListView();
00087
00088 protected:
00089 void gSetListItemSet(GListItemSet *set);
00090 GListItemSet *gListItemSet();
00091
00092 std::list<void*> gSelectedItems();
00093 void *gCurrentItem();
00094 void *gFirstChild();
00095 void *gFirstChild(void *of);
00096 void *gNextSibling(void *after);
00097 void *gItemAt(const Faith::Point &pt);
00098
00099 void gSetCurrent(void *g);
00100
00101 void gSetSelected(void *item, bool sel);
00102 bool gIsSelected(const void *item) const;
00103 void gClearSelection();
00104
00105 void gAddColumn(const Faith::String &name);
00106
00107 void contentsPaintEvent(Faith::PaintEvent *e);
00108 void contentsMousePressEvent(Faith::MouseEvent *e);
00109 void contentsKeyPressEvent(Faith::KeyPressEvent *e);
00110
00111 void gEnsureVisible(void *item);
00112
00113 Faith::Rect itemRect(void *item);
00114
00115 private:
00116 virtual GListViewThing *thing()=0;
00117
00118 void gInserted(void *item);
00119 void gRemoved(void *item);
00120 void gChanged();
00121 Faith::Size gCalculateSize();
00122
00123 virtual void gCurrentChanged()=0;
00124 virtual void gSelectionChanged()=0;
00125 };
00126
00127 class FAITH_UI_EXPORT GListViewThing
00128 {
00129 GListView *mList;
00130 public:
00131 GListViewThing();
00132 virtual ~GListViewThing() { }
00133
00134 GListView *gList() { return mList; }
00135 void gSetList(GListView *list) { mList = list; }
00136
00137 virtual void gPaint(void *item, Faith::Painter *p, unsigned int column)=0;
00138 virtual int gHeight(void *item) const=0;
00139 virtual int gWidth(void *item, unsigned int column) const=0;
00140 };
00141
00142 class ListItem;
00143
00144 template <typename Item=ListItem>
00145 class FAITH_UI_EXPORT ListItemSet : public GListItemSet
00146 {
00147 public:
00148 class Iterator;
00149
00150 class ConstIterator : private GListItemSet::GIterator
00151 {
00152 inline ConstIterator() { }
00153 friend class ListItemSet;
00154 friend class Iterator;
00155
00156 static ConstIterator fromG(const GListItemSet::GIterator &g) { ConstIterator x; x = g; return x; }
00157
00158 public:
00159 ConstIterator(const ConstIterator ©)
00160 : GIterator(copy) { }
00161
00162 ConstIterator & operator=(const ConstIterator ©)
00163 { GIterator::operator=(copy); return *this; }
00164 ConstIterator & operator=(const Iterator ©)
00165 { GIterator::operator=(copy); return *this; }
00166
00167 bool operator==(const ConstIterator &other) const
00168 { return GIterator::operator==(other); }
00169 bool operator!=(const ConstIterator &other) const
00170 { return GIterator::operator!=(other); }
00171
00172 ConstIterator &operator++()
00173 { GIterator::operator++(); return *this; }
00174 const Item *operator *() const
00175 {
00176 return static_cast<const Item*>(
00177 const_cast<ConstIterator*>(this)->GIterator::operator*()
00178 );
00179 }
00180
00181 };
00182
00183 class Iterator : private GListItemSet::GIterator
00184 {
00185 inline Iterator() { }
00186 Iterator(const GIterator ©)
00187 : GIterator(copy) { }
00188 friend class ListItemSet;
00189 friend class ConstIterator;
00190 public:
00191 Iterator(const Iterator ©)
00192 : GIterator(copy) { }
00193
00194 Iterator & operator=(const Iterator ©)
00195 { GIterator::operator=(copy); return *this; }
00196
00197 bool operator==(const Iterator &other) const
00198 { return GIterator::operator==(other); }
00199 bool operator!=(const Iterator &other) const
00200 { return GIterator::operator!=(other); }
00201
00202 Iterator &operator++()
00203 { GIterator::operator++(); return *this; }
00204 Item *operator *()
00205 { return static_cast<Item*>(GIterator::operator*()); }
00206
00207 operator ConstIterator () const { return ConstIterator::fromG(*this); }
00208 };
00209
00210
00211 ListItemSet(Faith::Object *parent, const char *name=0)
00212 : GListItemSet(parent, name)
00213 {
00214 }
00215
00216 void append(Item *item)
00217 {
00218 gAppend(item);
00219 }
00220
00221 void prepend(Item *item)
00222 {
00223 gPrepend(item);
00224 }
00225
00226 void insert(const Iterator &before, Item *item)
00227 {
00228 gInsert(before, item);
00229 }
00230
00231 void remove(Item *item)
00232 {
00233 gRemove(item);
00234 }
00235
00236 void changed()
00237 {
00238 gChanged();
00239 }
00240
00241
00242 Iterator begin() { return Iterator(gBegin()); }
00243 Iterator end() { return Iterator(gEnd()); }
00244
00245 ConstIterator begin() const { return ConstIterator(gBegin()); }
00246 ConstIterator end() const { return ConstIterator(gEnd()); }
00247
00248 };
00249
00250 template <typename Item=ListItem>
00251 class FAITH_UI_EXPORT ListView : public GListView
00252 {
00253 Q_OBJECT
00254
00255 public:
00256 ListView(Faith::Widget *parent, const char *name=0)
00257 : GListView(0, parent, name)
00258 {
00259 }
00260
00261 ListView(ListItemSet<Item> *set, Faith::Widget *parent, const char *name=0)
00262 : GListView(set, parent, name)
00263 {
00264 }
00265
00266 std::list<Item*> selectedItems()
00267 {
00268 std::list<Item*> l;
00269 std::list<void*> s = gSelectedItems();
00270 for (std::list<void*>::iterator i(s.begin()); i != s.end(); ++i)
00271 l.push_back(static_cast<Item*>(*i));
00272 return l;
00273 }
00274
00275 std::list<const Item*> selectedItems() const
00276 {
00277 std::list<const Item*> l;
00278 std::list<void*> s = const_cast<ListView*>(this)->gSelectedItems();
00279 for (std::list<void*>::iterator i(s.begin()); i != s.end(); ++i)
00280 l.push_back(static_cast<Item*>(*i));
00281 return l;
00282 }
00283
00284 void setSet(ListItemSet<Item> *set)
00285 {
00286 gSetListItemSet(set);
00287 }
00288
00289 Item *currentItem()
00290 {
00291 return static_cast<Item*>(gCurrentItem());
00292 }
00293
00294 const Item *currentItem() const
00295 {
00296 return static_cast<const Item*>(const_cast<ListView*>(this)->gCurrentItem());
00297 }
00298
00299 Item *gItemAt(const Faith::Point &pt)
00300 {
00301 return static_cast<Item*>(gItemAt(pt));
00302 }
00303
00304 const Item *gItemAt(const Faith::Point &pt) const
00305 {
00306 return static_cast<Item*>(const_cast<GListView*>(this)->gItemAt(pt));
00307 }
00308
00309 void setCurrent(Item *g)
00310 {
00311 gSetCurrent(g);
00312 }
00313
00314 void setSelected(Item *item, bool sel)
00315 {
00316 gSetSelected(item, sel);
00317 }
00318
00319 bool isSelected(const Item *item) const
00320 {
00321 return gIsSelected(item);
00322 }
00323
00324 void clearSelection()
00325 {
00326 gClearSelection();
00327 }
00328
00329 Item *firstChild()
00330 { return static_cast<Item*>(gFirstChild()); }
00331 Item *firstChild(Item *of)
00332 { return static_cast<Item*>(gFirstChild(of)); }
00333 Item *nextSibling()
00334 { return static_cast<Item*>(gNextSibling()); }
00335
00336 void ensureVisible(Item *item)
00337 { gEnsureVisible(item); }
00338
00339 void addColumn(const Faith::String &name)
00340 {
00341 gAddColumn(name);
00342 }
00343
00344 signals:
00345 void currentChanged();
00346 void selectionChanged();
00347
00348 private:
00349 GListViewThing *thing();
00350
00351 virtual void gCurrentChanged()
00352 {
00353 emit currentChanged();
00354 }
00355
00356 virtual void gSelectionChanged()
00357 {
00358 emit selectionChanged();
00359 }
00360
00361 };
00362
00363
00364 template<class Item=ListItem>
00365 class FAITH_UI_EXPORT ListViewThing : public GListViewThing
00366 {
00367 public:
00368 ListViewThing()
00369 {
00370 }
00371
00372 virtual ~ListViewThing() { }
00373
00374 ListView<Item> *list() { return static_cast<ListView<Item>*>(gList()); }
00375 const ListView<Item> *list() const
00376 { return const_cast<ListViewThing*>(this)->list(); }
00377
00378 virtual void paint(Item *item, Faith::Painter *p, unsigned int column)=0;
00379 virtual int height(Item *item) const=0;
00380 virtual int width(Item *item, unsigned int column) const=0;
00381
00382 private:
00383 virtual void gPaint(void *item, Faith::Painter *p, unsigned int column)
00384 {
00385 return paint(static_cast<Item*>(item), p, column);
00386 }
00387 virtual int gHeight(void *item) const
00388 {
00389 return height(static_cast<Item*>(item));
00390 }
00391 virtual int gWidth(void *item, unsigned int column) const
00392 {
00393 return width(static_cast<Item*>(item), column);
00394 }
00395
00396 };
00397
00398
00399 class FAITH_UI_EXPORT ListItem
00400 {
00401 std::vector<Faith::String> mText;
00402
00403 public:
00404 ListItem(const Faith::String &text);
00405 ListItem(const std::vector<Faith::String> &text);
00406 virtual ~ListItem() { }
00407
00408 Faith::String text(unsigned int c) const;
00409 void setText(unsigned int c, const Faith::String &);
00410 void setText(const std::vector<Faith::String> &text);
00411
00412 class ListViewThing : public Faith::ListViewThing<ListItem>
00413 {
00414 public:
00415 ListViewThing();
00416 virtual void paint(ListItem *item, Faith::Painter *p, unsigned int column);
00417 virtual int height(ListItem *item) const;
00418 virtual int width(ListItem *item, unsigned int column) const;
00419 };
00420 };
00421
00422 template<class Item>
00423 inline GListViewThing* ListView<Item>::thing()
00424 {
00425 GListViewThing *th = new typename ListItem::ListViewThing();
00426 th->gSetList(this);
00427 return th;
00428 }
00429
00430 }
00431
00432 #include <faith/listview.magna.tcc>
00433
00434
00435
00436 #endif
00437