summaryrefslogtreecommitdiffstats
path: root/src/gui/listview.cpp
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-03-01 19:17:32 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-03-01 19:17:32 +0000
commite38d2351b83fa65c66ccde443777647ef5cb6cff (patch)
tree1897fc20e9f73a81c520a5b9f76f8ed042124883 /src/gui/listview.cpp
downloadtellico-e38d2351b83fa65c66ccde443777647ef5cb6cff.tar.gz
tellico-e38d2351b83fa65c66ccde443777647ef5cb6cff.zip
Added KDE3 version of Tellico
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/tellico@1097620 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'src/gui/listview.cpp')
-rw-r--r--src/gui/listview.cpp347
1 files changed, 347 insertions, 0 deletions
diff --git a/src/gui/listview.cpp b/src/gui/listview.cpp
new file mode 100644
index 0000000..d93174c
--- /dev/null
+++ b/src/gui/listview.cpp
@@ -0,0 +1,347 @@
+/***************************************************************************
+ copyright : (C) 2001-2006 by Robby Stephenson
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "listview.h"
+#include "../controller.h"
+#include "../tellico_utils.h"
+#include "../tellico_debug.h"
+
+#include <kapplication.h>
+
+#include <qpainter.h>
+#include <qpixmap.h>
+#include <qheader.h>
+
+using Tellico::GUI::ListView;
+using Tellico::GUI::ListViewItem;
+
+ListView::ListView(QWidget* parent_, const char* name_) : KListView(parent_, name_/*=0*/),
+ m_sortStyle(SortByText), m_isClear(true) {
+ setSelectionMode(QListView::Extended);
+ connect(this, SIGNAL(selectionChanged()),
+ SLOT(slotSelectionChanged()));
+ connect(this, SIGNAL(doubleClicked(QListViewItem*)),
+ SLOT(slotDoubleClicked(QListViewItem*)));
+#if !KDE_IS_VERSION(3,3,90)
+ m_shadeSortColumn = false;
+ // call it once to initialize
+ slotUpdateColors();
+#endif
+ connect(kapp, SIGNAL(kdisplayPaletteChanged()), SLOT(slotUpdateColors()));
+ m_comparisons.setAutoDelete(true);
+}
+
+ListView::~ListView() {
+}
+
+void ListView::clearSelection() {
+ if(m_selectedItems.isEmpty()) {
+ // nothing to do;
+ return;
+ }
+ bool b = signalsBlocked();
+ blockSignals(true);
+ selectAll(false);
+ blockSignals(b);
+ emit selectionChanged();
+}
+
+void ListView::updateSelected(ListViewItem* item_, bool selected_) {
+ if(selected_) {
+ m_selectedItems.append(item_);
+ } else {
+ m_selectedItems.removeRef(item_);
+ }
+}
+
+bool ListView::isSelectable(ListViewItem* item_) const {
+ // don't allow hidden items to be selected
+ if(!item_->isVisible()) {
+ return false;
+ }
+
+ // selecting multiple items is ok
+ // only when parent is open. Be careful to check for existence of parent
+ if(item_->parent() && !item_->parent()->isOpen()) {
+ return false;
+ }
+
+ // just selecting a single item is always ok
+ if(m_selectedItems.isEmpty()) {
+ return true;
+ }
+
+ // not allowed is something other than an entry is selected and current is entry
+ if(m_selectedItems.getFirst()->isEntryItem() != item_->isEntryItem()) {
+ return false;
+ }
+
+ return true;
+}
+
+int ListView::firstVisibleColumn() const {
+ int col = 0;
+ while(col < columns() && columnWidth(header()->mapToSection(col)) == 0) {
+ ++col;
+ }
+ if(col == columns()) {
+ return -1;
+ }
+ return header()->mapToSection(col);
+}
+
+int ListView::lastVisibleColumn() const {
+ int col = columns()-1;
+ while(col < columns() && columnWidth(header()->mapToSection(col)) == 0) {
+ --col;
+ }
+ if(col == columns()) {
+ return -1;
+ }
+ return header()->mapToSection(col);
+}
+
+void ListView::setColumnText(int column, const QString& label) {
+ ListViewComparison* comp = m_comparisons.take(columnText(column));
+ KListView::setColumnText(column, label);
+ if(comp) {
+ m_comparisons.insert(columnText(column), comp);
+ }
+}
+
+void ListView::setComparison(int column, ListViewComparison* comp) {
+ if(comp) {
+ m_comparisons.replace(columnText(column), comp);
+ }
+}
+
+void ListView::removeComparison(int column) {
+ m_comparisons.remove(columnText(column));
+}
+
+void ListView::clearComparisons() {
+ m_comparisons.clear();
+}
+
+int ListView::compare(int col, const GUI::ListViewItem* item1, GUI::ListViewItem* item2, bool asc) {
+ if(col >= 0 && col < static_cast<int>(m_comparisons.count())) {
+ ListViewComparison* com = m_comparisons.find(columnText(col));
+ if(com) {
+ return com->compare(col, item1, item2, asc);
+ }
+ }
+ return 0;
+}
+
+#if !KDE_IS_VERSION(3,3,90)
+void ListView::setShadeSortColumn(bool shade_) {
+ if(m_shadeSortColumn != shade_) {
+ m_shadeSortColumn = shade_;
+ repaint();
+ }
+}
+#endif
+
+void ListView::slotUpdateColors() {
+#if !KDE_IS_VERSION(3,3,90)
+ m_backColor2 = viewport()->colorGroup().base();
+ if(m_backColor2 == Qt::black) {
+ m_backColor2 = QColor(50, 50, 50); // dark gray
+ } else {
+ int h,s,v;
+ m_backColor2.hsv(&h, &s, &v);
+ if(v > 175) {
+ m_backColor2 = m_backColor2.dark(105);
+ } else {
+ m_backColor2 = m_backColor2.light(120);
+ }
+ }
+
+ m_altColor2 = alternateBackground();
+ if(m_altColor2 == Qt::black) {
+ m_altColor2 = QColor(50, 50, 50); // dark gray
+ } else {
+ int h,s,v;
+ m_altColor2.hsv(&h, &s, &v);
+ if(v > 175) {
+ m_altColor2 = m_altColor2.dark(105);
+ } else {
+ m_altColor2 = m_altColor2.light(120);
+ }
+ }
+#endif
+ Tellico::updateContrastColor(viewport()->colorGroup());
+ repaint();
+}
+
+void ListView::slotSelectionChanged() {
+ if(m_selectedItems.isEmpty()) {
+ if(m_isClear) {
+ return; // nothing to do
+ }
+ m_isClear = true;
+ Controller::self()->slotClearSelection();
+ return;
+ }
+ m_isClear = false;
+
+ Data::EntryVec entries;
+ // now just find all the children or grandchildren that are entry items
+ for(GUI::ListViewItemListIt it(m_selectedItems); it.current(); ++it) {
+ Data::EntryVec more = it.current()->entries();
+ for(Data::EntryVecIt entry = more.begin(); entry != more.end(); ++entry) {
+ if(!entries.contains(entry)) {
+ entries.append(entry);
+ }
+ }
+ }
+// Controller::self()->slotUpdateCurrent(entries); // just update current, don't change selection
+ Controller::self()->slotUpdateSelection(this, entries);
+}
+
+void ListView::slotDoubleClicked(QListViewItem* item_) {
+ if(!item_) {
+ return;
+ }
+
+ // if it has children, just open it
+ // but some items delay children creation
+ if(static_cast<ListViewItem*>(item_)->realChildCount() > 0) {
+ item_->setOpen(!item_->isOpen());
+ }
+
+ GUI::ListViewItem* item = static_cast<GUI::ListViewItem*>(item_);
+ item->doubleClicked();
+}
+
+void ListView::drawContentsOffset(QPainter* p, int ox, int oy, int cx, int cy, int cw, int ch) {
+ bool oldUpdatesEnabled = isUpdatesEnabled();
+ setUpdatesEnabled(false);
+ KListView::drawContentsOffset(p, ox, oy, cx, cy, cw, ch);
+ setUpdatesEnabled(oldUpdatesEnabled);
+}
+
+/* ****************** ListViewItem ********************* */
+
+ListViewItem::~ListViewItem() {
+ // I think there's a bug in qt where the children of this item are deleted after the item itself
+ // as a result, there is no listView() pointer for the children, that obvious causes
+ // a problem with updating the selection. So we MUST call clear() here ourselves!
+ clear();
+ // be sure to remove from selected list when it's deleted
+ ListView* lv = listView();
+ if(lv) {
+ lv->updateSelected(this, false);
+ }
+}
+
+void ListViewItem::clear() {
+ QListViewItem* item = firstChild();
+ while(item) {
+ delete item;
+ item = firstChild();
+ }
+}
+
+int ListViewItem::compare(QListViewItem* item_, int col_, bool asc_) const {
+ int res = compareWeight(item_, col_, asc_);
+ if(res != 0) {
+ return res;
+ }
+ res = listView()->compare(col_, this, static_cast<GUI::ListViewItem*>(item_), asc_);
+ return res == 0 ? KListViewItem::compare(item_, col_, asc_) : res;
+}
+
+int ListViewItem::compareWeight(QListViewItem* item_, int col_, bool asc_) const {
+ Q_UNUSED(col_);
+ // I want the sorting to be independent of sort order
+ GUI::ListViewItem* i = static_cast<GUI::ListViewItem*>(item_);
+ int res = 0;
+ if(m_sortWeight < i->sortWeight()) {
+ res = -1;
+ } else if(m_sortWeight > i->sortWeight()) {
+ res = 1;
+ }
+ if(asc_) {
+ res *= -1; // reverse, heavier weights will come first always
+ }
+ return res;
+}
+
+void ListViewItem::setSelected(bool s_) {
+ ListView* lv = listView();
+ if(!lv) {
+ return;
+ }
+ if(s_ && !lv->isSelectable(this)) {
+ return;
+ }
+ if(s_ != isSelected()) {
+ lv->updateSelected(this, s_);
+ KListViewItem::setSelected(s_);
+ }
+}
+
+QColor ListViewItem::backgroundColor(int column_) {
+#if KDE_IS_VERSION(3,3,90)
+ return KListViewItem::backgroundColor(column_);
+#else
+ ListView* view = listView();
+ if(view->columns() > 1 && view->shadeSortColumn() && column_ == view->sortColumn()) {
+ return isAlternate() ? view->alternateBackground2() : view->background2();
+ }
+ return isAlternate() ? view->alternateBackground() : view->viewport()->colorGroup().base();
+#endif
+}
+
+void ListViewItem::paintCell(QPainter* p_, const QColorGroup& cg_,
+ int column_, int width_, int align_) {
+ // taken from klistview.cpp
+ // I can't call KListViewItem::paintCell since KListViewItem::backgroundCOlor(int) is
+ // not virtual. I need to be sure to call ListViewItem::backgroundColor(int);
+ QColorGroup cg = cg_;
+ const QPixmap* pm = listView()->viewport()->backgroundPixmap();
+ if(pm && !pm->isNull()) {
+ cg.setBrush(QColorGroup::Base, QBrush(backgroundColor(column_), *pm));
+ QPoint o = p_->brushOrigin();
+ p_->setBrushOrigin(o.x()-listView()->contentsX(), o.y()-listView()->contentsY());
+ } else {
+ cg.setColor(listView()->viewport()->backgroundMode() == Qt::FixedColor ?
+ QColorGroup::Background : QColorGroup::Base,
+ backgroundColor(column_));
+ }
+
+ // don't call KListViewItem::paintCell() since that also does alternate painting, etc...
+ QListViewItem::paintCell(p_, cg, column_, width_, align_);
+
+ // borrowed from amarok, draw line to left of cell
+ if(!isSelected()) {
+ p_->setPen(QPen(listView()->alternateBackground(), 0, Qt::SolidLine));
+ p_->drawLine(width_-1, 0, width_-1, height()-1);
+ }
+}
+
+Tellico::Data::EntryVec ListViewItem::entries() const {
+ Data::EntryVec entries;
+ for(QListViewItem* child = firstChild(); child; child = child->nextSibling()) {
+ Data::EntryVec more = static_cast<GUI::ListViewItem*>(child)->entries();
+ for(Data::EntryVecIt entry = more.begin(); entry != more.end(); ++entry) {
+ if(!entries.contains(entry)) {
+ entries.append(entry);
+ }
+ }
+ }
+ return entries;
+}
+
+#include "listview.moc"