void DivePlotDataModel::calculateDecompression() { struct divecomputer *dc = select_dc(&displayed_dive); init_decompression(&displayed_dive); calculate_deco_information(&displayed_dive, dc, &pInfo, false); dataChanged(index(0, CEILING), index(pInfo.nr - 1, TISSUE_16)); }
void ProfileGraphicsView::plot(struct dive *d, bool forceRedraw) { struct divecomputer *dc = NULL; if (d) dc = select_dc(&d->dc); if (!forceRedraw && dive == d && (d && dc == diveDC)) return; clear(); dive = d; diveDC = d ? dc : NULL; if (!isVisible() || !dive || !mainWindow()) { return; } setBackgroundBrush(getColor(BACKGROUND)); // best place to put the focus stealer code. setFocusProxy(mainWindow()->dive_list()); scene()->setSceneRect(0,0, viewport()->width()-50, viewport()->height()-50); toolTip = new ToolTipItem(); installEventFilter(toolTip); scene()->addItem(toolTip); if (printMode) toolTip->setVisible(false); // Fix this for printing / screen later. // plot_set_scale(scale_mode_t); if (!dc || !dc->samples) { dc = fake_dc(dc); } QString nick = get_dc_nickname(dc->model, dc->deviceid); if (nick.isEmpty()) nick = QString(dc->model); if (nick.isEmpty()) nick = tr("unknown divecomputer"); if ( tr("unknown divecomputer") == nick) { mode = PLAN; } else { mode = DIVE; } /* * Set up limits that are independent of * the dive computer */ calculate_max_limits(dive, dc, &gc); QRectF profile_grid_area = scene()->sceneRect(); gc.maxx = (profile_grid_area.width() - 2 * profile_grid_area.x()); gc.maxy = (profile_grid_area.height() - 2 * profile_grid_area.y()); /* This is per-dive-computer */ gc.pi = *create_plot_info(dive, dc, &gc); /* Bounding box */ QPen pen = defaultPen; pen.setColor(getColor(TIME_GRID)); QGraphicsRectItem *rect = new QGraphicsRectItem(profile_grid_area); rect->setPen(pen); scene()->addItem(rect); /* Depth profile */ plot_depth_profile(); plot_events(dc); if (rulerEnabled && !printMode) create_ruler(); /* Temperature profile */ plot_temperature_profile(); /* Cylinder pressure plot */ plot_cylinder_pressure(); /* Text on top of all graphs.. */ plot_temperature_text(); plot_depth_text(); plot_cylinder_pressure_text(); plot_deco_text(); /* Put the dive computer name in the lower left corner */ gc.leftx = 0; gc.rightx = 1.0; gc.topy = 0; gc.bottomy = 1.0; text_render_options_t computer = {DC_TEXT_SIZE, TIME_TEXT, LEFT, TOP}; diveComputer = plot_text(&computer, QPointF(gc.leftx, gc.bottomy), nick); // The Time ruler should be right after the DiveComputer: timeMarkers->setPos(0, diveComputer->y()); if (PP_GRAPHS_ENABLED) { plot_pp_gas_profile(); plot_pp_text(); } plot_depth_scale(); #if 0 if (gc->printer) { free(pi->entry); last_pi_entry = pi->entry = NULL; pi->nr = 0; } #endif QRectF r = scene()->itemsBoundingRect(); scene()->setSceneRect(r.x() - 15, r.y() -15, r.width() + 30, r.height() + 30); if (zoomLevel == 0) { fitInView(sceneRect()); } toolTip->readPos(); if(mode == PLAN) { timeEditor = new GraphicsTextEditor(); timeEditor->setPlainText( dive->duration.seconds ? QString::number(dive->duration.seconds/60) : tr("Set Duration: 10 minutes")); timeEditor->setPos(profile_grid_area.width() - timeEditor->boundingRect().width(), timeMarkers->y()); timeEditor->document(); connect(timeEditor, SIGNAL(editingFinished(QString)), this, SLOT(edit_dive_time(QString))); scene()->addItem(timeEditor); } if (!printMode) addControlItems(); if (rulerEnabled && !printMode) add_ruler(); }
/* we try to show the data from the currently selected divecomputer * right now for some values (e.g., surface pressure) we could fall back * to dive data, but for consistency we don't. */ static void show_single_dive_stats(struct dive *dive) { char buf[256]; double value; int decimals; const char *unit; int idx, offset, gas_used, mbar; struct dive *prev_dive; struct tm tm; struct divecomputer *dc; process_all_dives(dive, &prev_dive); if (!dive) return; dc = select_dc(&dive->dc); utc_mkdate(dive->when, &tm); snprintf(buf, sizeof(buf), /*++GETTEXT 80 chars: weekday, monthname, day, year, hour, min */ _("%1$s, %2$s %3$d, %4$d %5$2d:%6$02d"), weekday(tm.tm_wday), monthname(tm.tm_mon), tm.tm_mday, tm.tm_year + 1900, tm.tm_hour, tm.tm_min); set_label(single_w.date, buf); set_label(single_w.dive_time, _("%d min"), (dive->duration.seconds + 30) / 60); if (prev_dive) set_label(single_w.surf_intv, get_time_string(dive->when - (prev_dive->when + prev_dive->duration.seconds), 4)); else set_label(single_w.surf_intv, _("unknown")); value = get_depth_units(dc->maxdepth.mm, &decimals, &unit); set_label(single_w.max_depth, "%.*f %s", decimals, value, unit); value = get_depth_units(dc->meandepth.mm, &decimals, &unit); set_label(single_w.avg_depth, "%.*f %s", decimals, value, unit); set_label(single_w.viz, star_strings[dive->visibility]); if (dc->watertemp.mkelvin) { value = get_temp_units(dc->watertemp.mkelvin, &unit); set_label(single_w.water_temp, "%.1f %s", value, unit); } else { set_label(single_w.water_temp, ""); } if (dc->airtemp.mkelvin) { value = get_temp_units(dc->airtemp.mkelvin, &unit); set_label(single_w.air_temp, "%.1f %s", value, unit); } else { if (dive->airtemp.mkelvin) { value = get_temp_units(dive->airtemp.mkelvin, &unit); set_label(single_w.air_temp, "%.1f %s", value, unit); } else { set_label(single_w.air_temp, ""); } } mbar = dc->surface_pressure.mbar; /* it would be easy to get dive data here: * if (!mbar) * mbar = get_surface_pressure_in_mbar(dive, FALSE); */ if (mbar) { set_label(single_w.air_press, "%d mbar", mbar); } else { set_label(single_w.air_press, ""); } value = get_volume_units(dive->sac, &decimals, &unit); if (value > 0) set_label(single_w.sac, _("%.*f %s/min"), decimals, value, unit); else set_label(single_w.sac, ""); set_label(single_w.otu, "%d", dive->otu); offset = 0; gas_used = 0; buf[0] = '\0'; /* for the O2/He readings just create a list of them */ for (idx = 0; idx < MAX_CYLINDERS; idx++) { cylinder_t *cyl = &dive->cylinder[idx]; pressure_t start, end; start = cyl->start.mbar ? cyl->start : cyl->sample_start; end = cyl->end.mbar ?cyl->sample_end : cyl->sample_end; if (!cylinder_none(cyl)) { /* 0% O2 strangely means air, so 21% - I don't like that at all */ int o2 = get_o2(&cyl->gasmix); int he = get_he(&cyl->gasmix); if (offset > 0) { snprintf(buf+offset, 80-offset, ", "); offset += 2; } snprintf(buf+offset, 80-offset, "%d/%d", (o2 + 5) / 10, (he + 5) / 10); offset = strlen(buf); } /* and if we have size, start and end pressure, we can * calculate the total gas used */ if (start.mbar && end.mbar) gas_used += gas_volume(cyl, start) - gas_volume(cyl, end); } set_label(single_w.o2he, buf); if (gas_used) { value = get_volume_units(gas_used, &decimals, &unit); set_label(single_w.gas_used, "%.*f %s", decimals, value, unit); } else { set_label(single_w.gas_used, ""); } }
void ProfileGraphicsView::plot(struct dive *d, bool forceRedraw) { struct divecomputer *dc; if (d) dc = select_dc(&d->dc); if (!forceRedraw && dive == d && (d && dc == diveDC)) return; clear(); dive = d; diveDC = d ? dc : NULL; if (!isVisible() || !dive) { return; } scene()->setSceneRect(0,0, viewport()->width()-50, viewport()->height()-50); QSettings s; s.beginGroup("ProfileMap"); QPointF toolTipPos = s.value("tooltip_position", QPointF(0,0)).toPointF(); s.endGroup(); toolTip = new ToolTipItem(); toolTip->setPos(toolTipPos); scene()->addItem(toolTip); // Fix this for printing / screen later. // plot_set_scale(scale_mode_t); if (!dc->samples) { static struct sample fake[4]; static struct divecomputer fakedc; fakedc = dive->dc; fakedc.sample = fake; fakedc.samples = 4; /* The dive has no samples, so create a few fake ones. This assumes an ascent/descent rate of 9 m/min, which is just below the limit for FAST. */ int duration = dive->dc.duration.seconds; int maxdepth = dive->dc.maxdepth.mm; int asc_desc_time = dive->dc.maxdepth.mm*60/9000; if (asc_desc_time * 2 >= duration) asc_desc_time = duration / 2; fake[1].time.seconds = asc_desc_time; fake[1].depth.mm = maxdepth; fake[2].time.seconds = duration - asc_desc_time; fake[2].depth.mm = maxdepth; fake[3].time.seconds = duration * 1.00; fakedc.events = dc->events; dc = &fakedc; } /* * Set up limits that are independent of * the dive computer */ calculate_max_limits(dive, dc, &gc); QRectF profile_grid_area = scene()->sceneRect(); gc.maxx = (profile_grid_area.width() - 2 * profile_grid_area.x()); gc.maxy = (profile_grid_area.height() - 2 * profile_grid_area.y()); /* This is per-dive-computer. Right now we just do the first one */ gc.pi = *create_plot_info(dive, dc, &gc); /* Depth profile */ plot_depth_profile(); plot_events(dc); /* Temperature profile */ plot_temperature_profile(); /* Cylinder pressure plot */ plot_cylinder_pressure(dive, dc); /* Text on top of all graphs.. */ plot_temperature_text(); plot_depth_text(); plot_cylinder_pressure_text(); plot_deco_text(); /* Bounding box */ QPen pen = defaultPen; pen.setColor(profile_color[TIME_GRID].at(0)); QGraphicsRectItem *rect = new QGraphicsRectItem(profile_grid_area); rect->setPen(pen); scene()->addItem(rect); /* Put the dive computer name in the lower left corner */ QString nick(get_dc_nickname(dc->model, dc->deviceid)); if (nick.isEmpty()) nick = QString(dc->model); if (nick.isEmpty()) nick = tr("unknown divecomputer"); gc.leftx = 0; gc.rightx = 1.0; gc.topy = 0; gc.bottomy = 1.0; text_render_options_t computer = {DC_TEXT_SIZE, TIME_TEXT, LEFT, TOP}; diveComputer = plot_text(&computer, QPointF(gc.leftx, gc.bottomy), nick); // The Time ruler should be right after the DiveComputer: timeMarkers->setPos(0, diveComputer->y()); if (PP_GRAPHS_ENABLED) { plot_pp_gas_profile(); plot_pp_text(); } /* now shift the translation back by half the margin; * this way we can draw the vertical scales on both sides */ //cairo_translate(gc->cr, -drawing_area->x / 2.0, 0); //gc->maxx += drawing_area->x; //gc->leftx = -(drawing_area->x / drawing_area->width) / 2.0; //gc->rightx = 1.0 - gc->leftx; plot_depth_scale(); #if 0 if (gc->printer) { free(pi->entry); last_pi_entry = pi->entry = NULL; pi->nr = 0; } #endif QRectF r = scene()->itemsBoundingRect(); scene()->setSceneRect(r.x() - 15, r.y() -15, r.width() + 30, r.height() + 30); if (zoomLevel == 0) { fitInView(sceneRect()); } }