[PATCH] Add dive list view to main window

amit.k.chaudhuri at gmail.com amit.k.chaudhuri at gmail.com
Thu Apr 11 09:06:53 PDT 2013


From: Amit Chaudhuri <amit.k.chaudhuri at gmail.com>

Add files for dive list model/view implementation. Replace TableView
with the custom list view.  Amendments to makefile to match.

Note: we don't yet handle trips and may want to add additional columns
to describe the dive.

A single, dummy dive is added to show how this works (get root; item is
child of root). Purely to illustrate - needs proper integration etc.

Signed-off-by: Amit Chaudhuri <amit.k.chaudhuri at gmail.com>
---
 Makefile                |    2 +-
 qt-ui/divelistview.cpp  |    5 ++
 qt-ui/divelistview.h    |   19 +++++++
 qt-ui/divetripmodel.cpp |  139 +++++++++++++++++++++++++++++++++++++++++++++++
 qt-ui/divetripmodel.h   |   80 +++++++++++++++++++++++++++
 qt-ui/mainwindow.cpp    |    9 +++
 qt-ui/mainwindow.h      |    2 +
 qt-ui/mainwindow.ui     |    7 ++-
 8 files changed, 261 insertions(+), 2 deletions(-)
 create mode 100644 qt-ui/divelistview.cpp
 create mode 100644 qt-ui/divelistview.h
 create mode 100644 qt-ui/divetripmodel.cpp
 create mode 100644 qt-ui/divetripmodel.h

diff --git a/Makefile b/Makefile
index c89816d..9e8e69b 100644
--- a/Makefile
+++ b/Makefile
@@ -183,7 +183,7 @@ MSGLANGS=$(notdir $(wildcard po/*.po))
 MSGOBJS=$(addprefix share/locale/,$(MSGLANGS:.po=.UTF-8/LC_MESSAGES/subsurface.mo))
 
 
-QTOBJS = qt-ui/maintab.o  qt-ui/mainwindow.o  qt-ui/plotareascene.o
+QTOBJS = qt-ui/maintab.o  qt-ui/mainwindow.o  qt-ui/plotareascene.o qt-ui/divelistview.o qt-ui/divetripmodel.o
 
 OBJS =	main.o dive.o time.o profile.o info.o equipment.o divelist.o divelist-gtk.o deco.o \
 	planner.o planner-gtk.o \
diff --git a/qt-ui/divelistview.cpp b/qt-ui/divelistview.cpp
new file mode 100644
index 0000000..eafbdd3
--- /dev/null
+++ b/qt-ui/divelistview.cpp
@@ -0,0 +1,5 @@
+#include "divelistview.h"
+
+DiveListView::DiveListView(QWidget *parent) : QTreeView(parent)
+{
+}
diff --git a/qt-ui/divelistview.h b/qt-ui/divelistview.h
new file mode 100644
index 0000000..75ad2e0
--- /dev/null
+++ b/qt-ui/divelistview.h
@@ -0,0 +1,19 @@
+#ifndef DIVELISTVIEW_H
+#define DIVELISTVIEW_H
+
+/*! A view subclass for use with dives
+
+  Note: calling this a list view might be misleading?
+
+
+*/
+
+#include <QTreeView>
+
+class DiveListView : public QTreeView
+{
+public:
+    DiveListView(QWidget * parent = 0);
+};
+
+#endif // DIVELISTVIEW_H
diff --git a/qt-ui/divetripmodel.cpp b/qt-ui/divetripmodel.cpp
new file mode 100644
index 0000000..6ccf31b
--- /dev/null
+++ b/qt-ui/divetripmodel.cpp
@@ -0,0 +1,139 @@
+#include "divetripmodel.h"
+
+
+DiveItem::DiveItem(int num, QString dt, float dur, float dep, QString loc, DiveItem *p):
+    m_number(num), m_dateTime(dt), m_duration(dur), m_depth(dep), m_location(loc), m_parent(p)
+{
+    if (m_parent)
+        m_parent->addChild(this);
+}
+
+
+DiveTripModel::DiveTripModel(const QString &filename, QObject *parent) : QAbstractItemModel(parent), m_Filename(filename)
+{
+    m_RootItem = new DiveItem;
+}
+
+
+Qt::ItemFlags DiveTripModel::flags(const QModelIndex &index) const
+{
+    Qt::ItemFlags diveFlags = QAbstractItemModel::flags(index);
+    if(index.isValid()){
+        diveFlags |= Qt::ItemIsSelectable|Qt::ItemIsEnabled;
+    }
+    return diveFlags;
+}
+
+
+QVariant DiveTripModel::data(const QModelIndex &index, int role) const
+{
+    if (!index.isValid())
+        return QVariant();
+
+    if (role != Qt::DisplayRole)
+        return QVariant();
+
+    DiveItem *item = static_cast<DiveItem*>(index.internalPointer());
+
+    QVariant retVal;
+    switch( index.column())
+    {
+    case DIVE_NUMBER:
+        retVal = QVariant(item->diveNumber());
+        break;
+    case DIVE_DATE_TIME:
+        retVal = QVariant(item->dateTime());
+        break;
+    case DIVE_DURATION:
+        retVal = QVariant(item->duration());
+        break;
+    case DIVE_DEPTH:
+        retVal = QVariant(item->depth());
+        break;
+    case DIVE_LOCATION:
+        retVal = QVariant(item->location());
+        break;
+    default:
+        return QVariant();
+    };
+    return retVal;
+}
+
+
+QVariant DiveTripModel::headerData(int section, Qt::Orientation orientation, int role) const
+{
+    if(orientation == Qt::Horizontal && role == Qt::DisplayRole){
+        if( section == DIVE_NUMBER){
+            return tr("Dive number");
+        } else if (section == DIVE_DATE_TIME) {
+            return tr("Date");
+        } else if (section == DIVE_DURATION) {
+            return tr("Duration");
+        } else if (section == DIVE_DEPTH) {
+            return tr("Depth");
+        } else if (section == DIVE_LOCATION){
+            return tr("Location");
+        }
+    }
+    return QVariant();
+}
+
+int DiveTripModel::rowCount(const QModelIndex &parent) const
+{
+    /* only allow kids in column 0 */
+    if (parent.isValid() && parent.column() > 0){
+        return 0;
+    }
+    DiveItem * item = itemForIndex(parent);
+    return item ? item->childCount() : 0;
+}
+
+
+
+int DiveTripModel::columnCount(const QModelIndex &parent) const
+{
+    return parent.isValid() && parent.column() != 0 ? 0 : COLUMNS;
+
+}
+
+
+QModelIndex DiveTripModel::index(int row, int column, const QModelIndex &parent) const
+{
+
+    if (!m_RootItem || row < 0 || column < 0 || column >= COLUMNS
+            || ( parent.isValid() && parent.column() != 0) )
+        return QModelIndex();
+
+    DiveItem *parentItem = itemForIndex(parent);
+    Q_ASSERT(parentItem);
+    if ( DiveItem *item = parentItem->childAt(row) ){
+        return createIndex(row, column, item);
+    }
+    return QModelIndex();
+
+}
+
+
+QModelIndex DiveTripModel::parent(const QModelIndex &childIndex) const
+{
+    if (!childIndex.isValid())
+        return QModelIndex();
+
+    DiveItem *child = static_cast<DiveItem*>(childIndex.internalPointer());
+    DiveItem *parent = child->parent();
+
+    if (parent == m_RootItem)
+        return QModelIndex();
+
+    return createIndex(parent->rowOfChild(child), 0, parent);
+}
+
+
+DiveItem * DiveTripModel::itemForIndex(const QModelIndex &index) const
+{
+    if (index.isValid()) {
+        DiveItem * item = static_cast<DiveItem*>(index.internalPointer());
+        return item;
+    }
+    return m_RootItem;
+}
diff --git a/qt-ui/divetripmodel.h b/qt-ui/divetripmodel.h
new file mode 100644
index 0000000..b80591b
--- /dev/null
+++ b/qt-ui/divetripmodel.h
@@ -0,0 +1,80 @@
+#ifndef DIVETRIPMODEL_H
+#define DIVETRIPMODEL_H
+
+#include <QAbstractItemModel>
+
+/*! A DiveItem for use with a DiveTripModel
+ *
+ * A simple class which wraps basic stats for a dive (e.g. duration, depth) and
+ * tidies up after it's children. This is done manually as we don't inherit from
+ * QObject.
+ *
+*/
+class DiveItem
+{
+public:
+    explicit DiveItem(): m_number(0), m_dateTime(QString()), m_duration(0.0), m_depth(0.0), m_location(QString()) {m_parent = 0;}
+    explicit DiveItem(int num, QString dt, float, float, QString loc, DiveItem *parent = 0);
+    ~DiveItem() { qDeleteAll(m_children); }
+
+    int diveNumber() const {return m_number;}
+    QString dateTime() const {return m_dateTime;}
+    float duration() const {return m_duration;}
+    float depth() const {return m_depth;}
+    QString location() const {return m_location;}
+
+    DiveItem *parent() const {return m_parent;}
+    DiveItem *childAt(int row) const {return m_children.value(row);}
+    int rowOfChild(DiveItem *child) const {return m_children.indexOf(child);}
+    int childCount() const {return m_children.count();}
+    bool hasChildren() const {return !m_children.isEmpty();}
+    QList<DiveItem *> children() const {return m_children;}
+    void addChild(DiveItem*item) {item->m_parent = this; m_children << item;} /* parent = self */
+
+
+private:
+
+    int m_number;
+    QString m_dateTime;
+    float m_duration;
+    float m_depth;
+    QString m_location;
+
+    DiveItem *m_parent;
+    QList <DiveItem*> m_children;
+
+};
+
+
+enum Column {DIVE_NUMBER, DIVE_DATE_TIME, DIVE_DURATION, DIVE_DEPTH, DIVE_LOCATION, COLUMNS};
+
+
+/*! An AbstractItemModel for recording dive trip information such as a list of dives.
+ *
+*/
+class DiveTripModel : public QAbstractItemModel
+{
+public:
+
+    DiveTripModel(const QString &filename, QObject *parent = 0);
+
+    Qt::ItemFlags flags(const QModelIndex &index) const;
+    QVariant data(const QModelIndex &index, int role) const;
+    QVariant headerData(int section, Qt::Orientation orientation, int role) const;
+    int rowCount(const QModelIndex &parent) const;
+
+    int columnCount(const QModelIndex &parent = QModelIndex()) const;
+    virtual QModelIndex index(int row, int column,
+                              const QModelIndex &parent = QModelIndex()) const;
+    virtual QModelIndex parent(const QModelIndex &child) const;
+
+    DiveItem * itemForIndex(const QModelIndex &) const;
+
+private:
+
+    DiveItem * m_RootItem;
+    QString m_Filename;
+
+};
+
+#endif // DIVETRIPMODEL_H
diff --git a/qt-ui/mainwindow.cpp b/qt-ui/mainwindow.cpp
index 56c3901..f41bb0d 100644
--- a/qt-ui/mainwindow.cpp
+++ b/qt-ui/mainwindow.cpp
@@ -4,9 +4,18 @@
 #include <QVBoxLayout>
 #include <QtDebug>
 
+#include "divelistview.h"
+#include "divetripmodel.h"
+
 MainWindow::MainWindow() : ui(new Ui::MainWindow())
 {
 	ui->setupUi(this);
+
+	mModel = new DiveTripModel("",this);
+	if(mModel){
+		ui->ListWidget->setModel(mModel);
+	}
+
 }
 
 void MainWindow::on_actionNew_triggered()
diff --git a/qt-ui/mainwindow.h b/qt-ui/mainwindow.h
index 51b428c..a6894ad 100644
--- a/qt-ui/mainwindow.h
+++ b/qt-ui/mainwindow.h
@@ -3,6 +3,7 @@
 
 #include <QMainWindow>
 
+class DiveTripModel;
 
 namespace Ui
 {
@@ -60,6 +61,7 @@ private Q_SLOTS:
 
 private:
 	Ui::MainWindow *ui;
+	DiveTripModel *mModel;
 };
 
 #endif
diff --git a/qt-ui/mainwindow.ui b/qt-ui/mainwindow.ui
index 65b18c7..6ece13f 100644
--- a/qt-ui/mainwindow.ui
+++ b/qt-ui/mainwindow.ui
@@ -27,7 +27,7 @@
        <widget class="MainTab" name="InfoWidget" native="true"/>
        <widget class="QGraphicsView" name="ProfileWidget"/>
       </widget>
-      <widget class="QTableView" name="ListWidget"/>
+      <widget class="DiveListView" name="ListWidget"/>
      </widget>
     </item>
     <item>
@@ -291,6 +291,11 @@
    <header>maintab.h</header>
    <container>1</container>
   </customwidget>
+  <customwidget>
+   <class>DiveListView</class>
+   <extends>QTreeView</extends>
+   <header>divelistview.h</header>
+  </customwidget>
  </customwidgets>
  <resources/>
  <connections/>
-- 
1.7.10.4



More information about the subsurface mailing list