[PATCH] Add dive list view to main window

Dirk Hohndel dirk at hohndel.org
Fri Apr 12 12:58:33 PDT 2013


Ok, I took this version. Did some more white space cleanups:

watch for "( " and " )" -- we almost never have spaces on the inside of
parenthesis. Also, when logical terms span multiple lines end with the
logical operator, so  

if (a == 1 && b == 2 &&
    (c == 3 || c == 4))

also look at the indentation of the second line - this is the major
exception from the "always indent with tabs" rule.

But the changes were tiny and things are now in the Qt branch.

Tomaz, don't bother merging this with your work. Just send me a patch
(or pull request) with your code and I'll figure it out.

Thanks

/D

amit.k.chaudhuri at gmail.com writes:

> 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.
>
> Amend member names for dive list view components
>
> Various naming changes to conform to coding style. Required changes to
> members (remove prefix) and methods (avoid clash with members).
>
> Clean up indentation (swap spaces for tabs). Code for model/view was
> written with a different editor which had different settings :-/
>
> 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 |  136 +++++++++++++++++++++++++++++++++++++++++++++++
>  qt-ui/divetripmodel.h   |   80 ++++++++++++++++++++++++++++
>  qt-ui/mainwindow.cpp    |   29 ++++++++++
>  qt-ui/mainwindow.h      |    2 +
>  qt-ui/mainwindow.ui     |    7 ++-
>  8 files changed, 278 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..3ac123a
> --- /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..5b38320
> --- /dev/null
> +++ b/qt-ui/divetripmodel.cpp
> @@ -0,0 +1,136 @@
> +#include "divetripmodel.h"
> +
> +
> +DiveItem::DiveItem(int num, QString dt, float dur, float dep, QString loc, DiveItem *p):
> +	number(num), dateTime(dt), duration(dur), depth(dep), location(loc), parentItem(p)
> +{
> +	if (parentItem)
> +		parentItem->addChild(this);
> +}
> +
> +
> +DiveTripModel::DiveTripModel(const QString &filename, QObject *parent) : QAbstractItemModel(parent), filename(filename)
> +{
> +	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->diveDateTime());
> +		break;
> +	case DIVE_DURATION:
> +		retVal = QVariant(item->diveDuration());
> +		break;
> +	case DIVE_DEPTH:
> +		retVal = QVariant(item->diveDepth());
> +		break;
> +	case DIVE_LOCATION:
> +		retVal = QVariant(item->diveLocation());
> +		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 (!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 == 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 rootItem;
> +}
> diff --git a/qt-ui/divetripmodel.h b/qt-ui/divetripmodel.h
> new file mode 100644
> index 0000000..8c8a829
> --- /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(): number(0), dateTime(QString()), duration(0.0), depth(0.0), location(QString()) {parentItem = 0;}
> +	explicit DiveItem(int num, QString dt, float, float, QString loc, DiveItem *parent = 0);
> +	~DiveItem() { qDeleteAll(childlist); }
> +
> +	int diveNumber() const { return number; }
> +	QString diveDateTime() const { return dateTime; }
> +	float diveDuration() const { return duration; }
> +	float diveDepth() const { return depth; }
> +	QString diveLocation() const { return location; }
> +
> +	DiveItem *parent() const { return parentItem; }
> +	DiveItem *childAt(int row) const { return childlist.value(row); }
> +	int rowOfChild(DiveItem *child) const { return childlist.indexOf(child); }
> +	int childCount() const { return childlist.count(); }
> +	bool hasChildren() const { return !childlist.isEmpty(); }
> +	QList<DiveItem *> children() const { return childlist; }
> +	void addChild(DiveItem* item) { item->parentItem = this; childlist << item; } /* parent = self */
> +
> +
> +private:
> +
> +	int number;
> +	QString dateTime;
> +	float duration;
> +	float depth;
> +	QString location;
> +
> +	DiveItem *parentItem;
> +	QList <DiveItem*> childlist;
> +
> +};
> +
> +
> +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 *rootItem;
> +	QString filename;
> +
> +};
> +
> +#endif // DIVETRIPMODEL_H
> diff --git a/qt-ui/mainwindow.cpp b/qt-ui/mainwindow.cpp
> index 56c3901..03f6b6c 100644
> --- a/qt-ui/mainwindow.cpp
> +++ b/qt-ui/mainwindow.cpp
> @@ -4,9 +4,38 @@
>  #include <QVBoxLayout>
>  #include <QtDebug>
>  
> +#include "divelistview.h"
> +#include "divetripmodel.h"
> +
>  MainWindow::MainWindow() : ui(new Ui::MainWindow())
>  {
>  	ui->setupUi(this);
> +
> +	/* may want to change ctor to avoid filename as 1st param.
> +	 * here we just use an empty string
> +	 */
> +	model = new DiveTripModel("",this);
> +	if (model){
> +		ui->ListWidget->setModel(model);
> +	}
> +	/* add in dives here.
> +	 * we need to root to parent all top level dives
> +	 * trips need more work as it complicates parent/child stuff.
> +	 *
> +	 * We show how to obtain the root and add a demo dive
> +	 *
> +	 * Todo: work through integration with current list of dives/trips
> +	 * Todo: look at alignment/format of e.g. duration in view
> +	 */
> +	DiveItem *dive = 0;
> +	DiveItem *root = model->itemForIndex(QModelIndex());
> +	if (root){
> +		dive = new DiveItem(1,QString("01/03/13"),14.2, 29.0,QString("Wraysbury"),root);
> +
> +		Q_UNUSED(dive)
> +	}
> +
> +
>  }
>  
>  void MainWindow::on_actionNew_triggered()
> diff --git a/qt-ui/mainwindow.h b/qt-ui/mainwindow.h
> index 51b428c..662d07c 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 *model;
>  };
>  
>  #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
>
> _______________________________________________
> subsurface mailing list
> subsurface at hohndel.org
> http://lists.hohndel.org/cgi-bin/mailman/listinfo/subsurface

-- 
Dirk Hohndel
Intel Open Source Technology Center


More information about the subsurface mailing list