2014-01-16 17:02:32 +00:00
|
|
|
#include "diveeventitem.h"
|
|
|
|
#include "diveplotdatamodel.h"
|
|
|
|
#include "divecartesianaxis.h"
|
2014-02-15 23:05:47 +00:00
|
|
|
#include "animationfunctions.h"
|
2014-02-25 20:27:12 +00:00
|
|
|
#include "libdivecomputer.h"
|
2014-01-16 17:02:32 +00:00
|
|
|
#include "dive.h"
|
2014-07-01 19:07:38 +00:00
|
|
|
#include "planner.h"
|
2014-03-16 04:12:34 +00:00
|
|
|
#include "profile.h"
|
2014-01-16 17:02:32 +00:00
|
|
|
#include <QDebug>
|
2014-04-30 05:37:19 +00:00
|
|
|
#include "gettextfromc.h"
|
2014-10-19 14:15:18 +00:00
|
|
|
#include "metrics.h"
|
2014-01-16 17:02:32 +00:00
|
|
|
|
2014-03-16 04:12:34 +00:00
|
|
|
extern struct ev_select *ev_namelist;
|
|
|
|
extern int evn_used;
|
|
|
|
|
2014-02-28 04:09:57 +00:00
|
|
|
DiveEventItem::DiveEventItem(QObject *parent) : DivePixmapItem(parent),
|
|
|
|
vAxis(NULL),
|
|
|
|
hAxis(NULL),
|
|
|
|
dataModel(NULL),
|
|
|
|
internalEvent(NULL)
|
2014-01-16 17:02:32 +00:00
|
|
|
{
|
|
|
|
setFlag(ItemIgnoresTransformations);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-02-28 04:09:57 +00:00
|
|
|
void DiveEventItem::setHorizontalAxis(DiveCartesianAxis *axis)
|
2014-01-16 17:02:32 +00:00
|
|
|
{
|
|
|
|
hAxis = axis;
|
2014-02-15 23:05:47 +00:00
|
|
|
recalculatePos(true);
|
2014-01-16 17:02:32 +00:00
|
|
|
}
|
|
|
|
|
2014-02-28 04:09:57 +00:00
|
|
|
void DiveEventItem::setModel(DivePlotDataModel *model)
|
2014-01-16 17:02:32 +00:00
|
|
|
{
|
|
|
|
dataModel = model;
|
2014-02-15 23:05:47 +00:00
|
|
|
recalculatePos(true);
|
2014-01-16 17:02:32 +00:00
|
|
|
}
|
|
|
|
|
2014-02-28 04:09:57 +00:00
|
|
|
void DiveEventItem::setVerticalAxis(DiveCartesianAxis *axis)
|
2014-01-16 17:02:32 +00:00
|
|
|
{
|
|
|
|
vAxis = axis;
|
2014-02-15 23:05:47 +00:00
|
|
|
recalculatePos(true);
|
|
|
|
connect(vAxis, SIGNAL(sizeChanged()), this, SLOT(recalculatePos()));
|
2014-01-16 17:02:32 +00:00
|
|
|
}
|
|
|
|
|
2014-02-25 20:27:12 +00:00
|
|
|
struct event *DiveEventItem::getEvent()
|
|
|
|
{
|
|
|
|
return internalEvent;
|
|
|
|
}
|
|
|
|
|
2014-02-28 04:09:57 +00:00
|
|
|
void DiveEventItem::setEvent(struct event *ev)
|
2014-01-16 17:02:32 +00:00
|
|
|
{
|
2014-02-23 16:35:06 +00:00
|
|
|
if (!ev)
|
|
|
|
return;
|
2014-01-16 17:02:32 +00:00
|
|
|
internalEvent = ev;
|
|
|
|
setupPixmap();
|
|
|
|
setupToolTipString();
|
2014-02-15 23:05:47 +00:00
|
|
|
recalculatePos(true);
|
2014-01-16 17:02:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void DiveEventItem::setupPixmap()
|
|
|
|
{
|
2014-10-19 14:15:18 +00:00
|
|
|
const IconMetrics& metrics = defaultIconMetrics();
|
|
|
|
int sz_bigger = metrics.sz_med + metrics.sz_small; // ex 40px
|
|
|
|
int sz_pix = sz_bigger/2; // ex 20px
|
|
|
|
|
|
|
|
#define EVENT_PIXMAP(PIX) QPixmap(QString(PIX)).scaled(sz_pix, sz_pix, Qt::KeepAspectRatio, Qt::SmoothTransformation)
|
|
|
|
#define EVENT_PIXMAP_BIGGER(PIX) QPixmap(QString(PIX)).scaled(sz_bigger, sz_bigger, Qt::KeepAspectRatio, Qt::SmoothTransformation)
|
2014-01-16 23:30:47 +00:00
|
|
|
if (!internalEvent->name) {
|
2014-01-16 17:02:32 +00:00
|
|
|
setPixmap(EVENT_PIXMAP(":warning"));
|
2014-04-03 19:16:15 +00:00
|
|
|
} else if (internalEvent->type == SAMPLE_EVENT_BOOKMARK) {
|
2014-01-16 17:02:32 +00:00
|
|
|
setPixmap(EVENT_PIXMAP(":flag"));
|
2014-02-21 21:29:35 +00:00
|
|
|
} else if (strcmp(internalEvent->name, "heading") == 0) {
|
2014-11-14 18:39:18 +00:00
|
|
|
// some dive computers have heading in every sample...
|
|
|
|
// set an "almost invisible" pixmap
|
|
|
|
// so we get the tooltip but not the clutter
|
2014-11-14 19:52:55 +00:00
|
|
|
// create a narrow but somewhat tall, basically transparent pixmap
|
|
|
|
// that allows tooltips to work when we don't want to show a specific
|
|
|
|
// pixmap for an event, but want to show the event value in the tooltip
|
|
|
|
// (e.g. if there is heading data in every sample)
|
|
|
|
QPixmap transparentPixmap(4, 20);
|
|
|
|
transparentPixmap.fill(QColor::fromRgbF(1.0, 1.0, 1.0, 0.01));
|
|
|
|
setPixmap(transparentPixmap);
|
2014-08-17 18:26:21 +00:00
|
|
|
} else if (event_is_gaschange(internalEvent)) {
|
|
|
|
if (internalEvent->gas.mix.he.permille)
|
2014-07-10 17:54:05 +00:00
|
|
|
setPixmap(EVENT_PIXMAP_BIGGER(":gaschangeTrimix"));
|
2014-08-17 18:26:21 +00:00
|
|
|
else if (gasmix_is_air(&internalEvent->gas.mix))
|
2014-07-10 17:54:05 +00:00
|
|
|
setPixmap(EVENT_PIXMAP_BIGGER(":gaschangeAir"));
|
|
|
|
else
|
|
|
|
setPixmap(EVENT_PIXMAP_BIGGER(":gaschangeNitrox"));
|
2014-01-16 17:02:32 +00:00
|
|
|
} else {
|
|
|
|
setPixmap(EVENT_PIXMAP(":warning"));
|
|
|
|
}
|
|
|
|
#undef EVENT_PIXMAP
|
|
|
|
}
|
|
|
|
|
|
|
|
void DiveEventItem::setupToolTipString()
|
|
|
|
{
|
2014-02-25 20:27:12 +00:00
|
|
|
// we display the event on screen - so translate
|
2014-04-30 05:37:19 +00:00
|
|
|
QString name = gettextFromC::instance()->tr(internalEvent->name);
|
2014-02-25 20:27:12 +00:00
|
|
|
int value = internalEvent->value;
|
2014-04-30 05:37:19 +00:00
|
|
|
int type = internalEvent->type;
|
2014-02-25 20:27:12 +00:00
|
|
|
if (value) {
|
2014-08-17 18:26:21 +00:00
|
|
|
if (event_is_gaschange(internalEvent)) {
|
2014-01-16 17:02:32 +00:00
|
|
|
name += ": ";
|
2015-01-03 06:09:01 +00:00
|
|
|
name += gasname(&internalEvent->gas.mix);
|
|
|
|
|
|
|
|
/* Do we have an explicit cylinder index? Show it. */
|
|
|
|
if (internalEvent->gas.index >= 0)
|
2015-01-04 01:21:05 +00:00
|
|
|
name += QString(" (cyl %1)").arg(internalEvent->gas.index+1);
|
2014-05-05 16:28:58 +00:00
|
|
|
} else if (type == SAMPLE_EVENT_PO2 && name == "SP change") {
|
2014-02-28 04:09:57 +00:00
|
|
|
name += QString(":%1").arg((double)value / 1000);
|
2014-01-16 17:02:32 +00:00
|
|
|
} else {
|
2014-02-25 20:27:12 +00:00
|
|
|
name += QString(":%1").arg(value);
|
2014-01-16 17:02:32 +00:00
|
|
|
}
|
2014-05-05 16:28:58 +00:00
|
|
|
} else if (type == SAMPLE_EVENT_PO2 && name == "SP change") {
|
|
|
|
// this is a bad idea - we are abusing an existing event type that is supposed to
|
2014-06-22 14:41:44 +00:00
|
|
|
// warn of high or low pO₂ and are turning it into a set point change event
|
2014-01-16 17:02:32 +00:00
|
|
|
name += "\n" + tr("Bailing out to OC");
|
|
|
|
} else {
|
2014-02-25 20:27:12 +00:00
|
|
|
name += internalEvent->flags == SAMPLE_FLAGS_BEGIN ? tr(" begin", "Starts with space!") :
|
|
|
|
internalEvent->flags == SAMPLE_FLAGS_END ? tr(" end", "Starts with space!") : "";
|
2014-01-16 17:02:32 +00:00
|
|
|
}
|
2014-02-25 20:27:12 +00:00
|
|
|
// qDebug() << name;
|
|
|
|
setToolTip(name);
|
2014-01-16 17:02:32 +00:00
|
|
|
}
|
|
|
|
|
2014-02-28 04:09:57 +00:00
|
|
|
void DiveEventItem::eventVisibilityChanged(const QString &eventName, bool visible)
|
2014-01-16 17:02:32 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2014-03-16 22:10:03 +00:00
|
|
|
bool DiveEventItem::shouldBeHidden()
|
|
|
|
{
|
2014-07-01 19:07:38 +00:00
|
|
|
struct event *event = internalEvent;
|
|
|
|
|
|
|
|
/*
|
2014-10-28 20:48:15 +00:00
|
|
|
* Some gas change events are special. Some dive computers just tell us the initial gas this way.
|
|
|
|
* Don't bother showing those
|
2014-07-01 19:07:38 +00:00
|
|
|
*/
|
2014-10-28 20:48:15 +00:00
|
|
|
struct sample *first_sample = &get_dive_dc(&displayed_dive, dc_number)->sample[0];
|
2014-11-03 15:50:30 +00:00
|
|
|
if (!strcmp(event->name, "gaschange") && first_sample && event->time.seconds == first_sample->time.seconds)
|
2014-10-28 20:48:15 +00:00
|
|
|
return true;
|
|
|
|
|
2014-03-16 22:10:03 +00:00
|
|
|
for (int i = 0; i < evn_used; i++) {
|
2014-07-01 19:07:38 +00:00
|
|
|
if (!strcmp(event->name, ev_namelist[i].ev_name) && ev_namelist[i].plot_ev == false)
|
2014-03-16 22:10:03 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-02-15 23:05:47 +00:00
|
|
|
void DiveEventItem::recalculatePos(bool instant)
|
2014-01-16 17:02:32 +00:00
|
|
|
{
|
2014-02-23 16:35:06 +00:00
|
|
|
if (!vAxis || !hAxis || !internalEvent || !dataModel)
|
2014-01-16 17:02:32 +00:00
|
|
|
return;
|
2014-02-23 16:35:06 +00:00
|
|
|
|
2014-02-28 04:09:57 +00:00
|
|
|
QModelIndexList result = dataModel->match(dataModel->index(0, DivePlotDataModel::TIME), Qt::DisplayRole, internalEvent->time.seconds);
|
2014-01-16 23:30:47 +00:00
|
|
|
if (result.isEmpty()) {
|
2014-02-23 16:35:06 +00:00
|
|
|
Q_ASSERT("can't find a spot in the dataModel");
|
2014-01-16 17:02:32 +00:00
|
|
|
hide();
|
|
|
|
return;
|
|
|
|
}
|
2014-03-16 22:10:03 +00:00
|
|
|
if (!isVisible() && !shouldBeHidden())
|
2014-01-16 17:02:32 +00:00
|
|
|
show();
|
|
|
|
int depth = dataModel->data(dataModel->index(result.first().row(), DivePlotDataModel::DEPTH)).toInt();
|
|
|
|
qreal x = hAxis->posAtValue(internalEvent->time.seconds);
|
|
|
|
qreal y = vAxis->posAtValue(depth);
|
2014-02-23 16:35:06 +00:00
|
|
|
if (!instant)
|
2014-03-11 20:27:05 +00:00
|
|
|
Animations::moveTo(this, x, y);
|
2014-02-23 16:35:06 +00:00
|
|
|
else
|
2014-02-28 04:09:57 +00:00
|
|
|
setPos(x, y);
|
2014-03-16 22:10:03 +00:00
|
|
|
if (isVisible() && shouldBeHidden())
|
2014-03-16 04:12:34 +00:00
|
|
|
hide();
|
2014-01-16 17:02:32 +00:00
|
|
|
}
|