コード例 #1
0
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));
}
コード例 #2
0
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();
}
コード例 #3
0
ファイル: statistics.c プロジェクト: TiNkU-dArsHan/subsurface
/* 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, "");
	}
}
コード例 #4
0
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());
	}
}