void ProfileGraphicsView::plot_depth_scale() { int i, maxdepth, marker; static text_render_options_t tro = {DEPTH_TEXT_SIZE, SAMPLE_DEEP, RIGHT, MIDDLE}; /* Depth markers: every 30 ft or 10 m*/ maxdepth = get_maxdepth(&gc.pi); gc.topy = 0; gc.bottomy = maxdepth; switch (prefs.units.length) { case units::METERS: marker = 10000; break; case units::FEET: marker = 9144; break; /* 30 ft */ } QColor c(getColor(DEPTH_GRID)); /* don't write depth labels all the way to the bottom as * there may be other graphs below the depth plot (like * partial pressure graphs) where this would look out * of place - so we only make sure that we print the next * marker below the actual maxdepth of the dive */ depthMarkers = new QGraphicsRectItem(); for (i = marker; i <= gc.pi.maxdepth + marker; i += marker) { double d = get_depth_units(i, NULL, NULL); plot_text(&tro, QPointF(-0.002, i), QString::number(d), depthMarkers); } scene()->addItem(depthMarkers); depthMarkers->setPos(depthMarkers->pos().x() - 10, 0); }
void ProfileGraphicsView::plot_single_temp_text(int sec, int mkelvin) { double deg; const char *unit; static text_render_options_t tro = {TEMP_TEXT_SIZE, TEMP_TEXT, LEFT, TOP}; deg = get_temp_units(mkelvin, &unit); plot_text(&tro, QPointF(sec, mkelvin), QString("%1%2").arg(deg, 0, 'f', 1).arg(unit)); //"%.2g%s" }
void ProfileGraphicsView::plot_depth_sample(struct plot_data *entry,text_render_options_t *tro) { int sec = entry->sec, decimals; double d; d = get_depth_units(entry->depth, &decimals, NULL); plot_text(tro, QPointF(sec, entry->depth), QString("%1").arg(d, 0, 'f', 1)); }
void ProfileGraphicsView::plot_pressure_value(int mbar, int sec, double xalign, double yalign) { int pressure; const char *unit; pressure = get_pressure_units(mbar, &unit); static text_render_options_t tro = {PRESSURE_TEXT_SIZE, PRESSURE_TEXT, xalign, yalign}; plot_text(&tro, QPointF(sec, mbar), QString("%1 %2").arg(pressure).arg(unit)); }
void ProfileGraphicsView::plot_deco_text() { if (prefs.profile_calc_ceiling) { float x = gc.leftx + (gc.rightx - gc.leftx) / 2; float y = gc.topy = 1.0; static text_render_options_t tro = {PRESSURE_TEXT_SIZE, PRESSURE_TEXT, CENTER, BOTTOM}; gc.bottomy = 0.0; plot_text(&tro, QPointF(x, y), QString("GF %1/%2").arg(prefs.gflow).arg(prefs.gfhigh)); } }
void ProfileGraphicsView::plot_gas_value(int mbar, int sec, double xalign, double yalign, int o2, int he) { QString gas; if (is_air(o2, he)) gas = tr("air"); else if (he == 0) gas = QString(tr("EAN%1")).arg((o2 + 5) / 10); else gas = QString("%1/%2").arg((o2 + 5) / 10).arg((he + 5) / 10); static text_render_options_t tro = {PRESSURE_TEXT_SIZE, PRESSURE_TEXT, xalign, yalign}; plot_text(&tro, QPointF(sec, mbar), gas); }
void ProfileGraphicsView::plot_pp_text() { double pp, dpp, m; int hpos; static text_render_options_t tro = {PP_TEXT_SIZE, PP_LINES, LEFT, MIDDLE}; setup_pp_limits(&gc); pp = floor(gc.pi.maxpp * 10.0) / 10.0 + 0.2; dpp = pp > 4 ? 1.0 : 0.5; hpos = gc.pi.entry[gc.pi.nr - 1].sec; QColor c = profile_color[PP_LINES].first(); for (m = 0.0; m <= pp; m += dpp) { QGraphicsLineItem *item = new QGraphicsLineItem(SCALEGC(0, m), SCALEGC(hpos, m)); QPen pen(defaultPen); pen.setColor(c); item->setPen(pen); scene()->addItem(item); plot_text(&tro, QPointF(hpos + 30, m), QString::number(m)); } }
int PlotArea::do_plot(const char *commands, bool clear) { // Discard all commands up to `G' command, if any int discard = -1; { const char *cmds = commands; while (*cmds != '\0') { if (cmds[0] == 'G' && cmds[1] == '\n') { if (pending_plots > 0) pending_plots--; discard = (cmds - commands); } while (*cmds != '\n' && *cmds != '\0') cmds++; if (*cmds != '\0') cmds++; } } // Process commands const char *cmds = commands; if (discard >= 0) { cmds += discard; assert(cmds[0] == 'G'); assert(cmds[1] == '\n'); } #if 0 // FIXME: Not thoroughly tested yet -AZ if (discard < 0 && pending_plots > 0) return discard; #endif while (cmds[0] != '\0') { const char *command_begin = cmds; // Move CMDS to the next line while (*cmds != '\0' && *cmds != '\n') cmds++; if (*cmds == '\0') break; // Command is incomplete - don't do it assert(*cmds == '\n'); cmds++; // Copy current command to a NULL-terminated string. Otherwise, // sscanf() takes far too much time. const int len_ = cmds-command_begin-1; assert(len_ >= 0); const string command_s(command_begin,len_); const char *command = command_s.chars(); switch (command[0]) { case 'V': if (win) plot_vector(command); break; case 'M': if (win) plot_move(command); break; case 'T': if (win) plot_text(command); break; case 'J': if (win) plot_justify(command); break; case 'L': if (win) plot_linetype(command); break; case 'P': if (win) plot_point(command); break; case 'G': plot_reset(command); if (win && clear) plot_clear(command); break; case 'E': case 'R': if (win) plot_nop(command); break; default: plot_unknown(command); break; } } return discard; }
void ProfileGraphicsView::plot_depth_profile() { int i, incr; int sec, depth; struct plot_data *entry; int maxtime, maxdepth, marker, maxline; int increments[8] = { 10, 20, 30, 60, 5*60, 10*60, 15*60, 30*60 }; /* Get plot scaling limits */ maxtime = get_maxtime(&gc.pi); maxdepth = get_maxdepth(&gc.pi); gc.maxtime = maxtime; /* Time markers: at most every 10 seconds, but no more than 12 markers. * We start out with 10 seconds and increment up to 30 minutes, * depending on the dive time. * This allows for 6h dives - enough (I hope) for even the craziest * divers - but just in case, for those 8h depth-record-breaking dives, * we double the interval if this still doesn't get us to 12 or fewer * time markers */ i = 0; while (maxtime / increments[i] > 12 && i < 7) i++; incr = increments[i]; while (maxtime / incr > 12) incr *= 2; gc.leftx = 0; gc.rightx = maxtime; gc.topy = 0; gc.bottomy = 1.0; last_gc = gc; QColor c = getColor(TIME_GRID); for (i = incr; i < maxtime; i += incr) { QGraphicsLineItem *item = new QGraphicsLineItem(SCALEGC(i, 0), SCALEGC(i, 1)); QPen pen(defaultPen); pen.setColor(c); item->setPen(pen); scene()->addItem(item); } timeMarkers = new QGraphicsRectItem(); /* now the text on the time markers */ struct text_render_options tro = {DEPTH_TEXT_SIZE, TIME_TEXT, CENTER, LINE_DOWN}; if (maxtime < 600) { /* Be a bit more verbose with shorter dives */ for (i = incr; i < maxtime; i += incr) plot_text(&tro, QPointF(i, 0), QString("%1:%2").arg(i/60).arg(i%60, 2, 10, QChar('0')), timeMarkers); } else { /* Only render the time on every second marker for normal dives */ for (i = incr; i < maxtime; i += 2 * incr) plot_text(&tro, QPointF(i, 0), QString("%1").arg(QString::number(i/60)), timeMarkers); } timeMarkers->setPos(0,0); scene()->addItem(timeMarkers); /* Depth markers: every 30 ft or 10 m*/ gc.leftx = 0; gc.rightx = 1.0; gc.topy = 0; gc.bottomy = maxdepth; switch (prefs.units.length) { case units::METERS: marker = 10000; break; case units::FEET: marker = 9144; break; /* 30 ft */ } maxline = qMax(gc.pi.maxdepth + marker, maxdepth * 2 / 3); c = getColor(DEPTH_GRID); for (i = marker; i < maxline; i += marker) { QGraphicsLineItem *item = new QGraphicsLineItem(SCALEGC(0, i), SCALEGC(1, i)); QPen pen(defaultPen); pen.setColor(c); item->setPen(pen); scene()->addItem(item); } gc.leftx = 0; gc.rightx = maxtime; c = getColor(MEAN_DEPTH); /* Show mean depth */ if (! gc.printer) { QGraphicsLineItem *item = new QGraphicsLineItem(SCALEGC(0, gc.pi.meandepth), SCALEGC(gc.pi.entry[gc.pi.nr - 1].sec, gc.pi.meandepth)); QPen pen(defaultPen); pen.setColor(c); item->setPen(pen); scene()->addItem(item); } #if 0 /* * These are good for debugging text placement etc, * but not for actual display.. */ if (0) { plot_smoothed_profile(gc, pi); plot_minmax_profile(gc, pi); } #endif /* Do the depth profile for the neat fill */ gc.topy = 0; gc.bottomy = maxdepth; entry = gc.pi.entry; QPolygonF p; QLinearGradient pat(0.0,0.0,0.0,scene()->height()); QGraphicsPolygonItem *neatFill = NULL; p.append(QPointF(SCALEGC(0, 0))); for (i = 0; i < gc.pi.nr; i++, entry++) p.append(QPointF(SCALEGC(entry->sec, entry->depth))); /* Show any ceiling we may have encountered */ if (prefs.profile_dc_ceiling) { for (i = gc.pi.nr - 1; i >= 0; i--, entry--) { if (!entry->in_deco) { /* not in deco implies this is a safety stop, no ceiling */ p.append(QPointF(SCALEGC(entry->sec, 0))); } else if (entry->stopdepth < entry->depth) { p.append(QPointF(SCALEGC(entry->sec, entry->stopdepth))); } else { p.append(QPointF(SCALEGC(entry->sec, entry->depth))); } } } pat.setColorAt(1, getColor(DEPTH_BOTTOM)); pat.setColorAt(0, getColor(DEPTH_TOP)); neatFill = new QGraphicsPolygonItem(); neatFill->setPolygon(p); neatFill->setBrush(QBrush(pat)); neatFill->setPen(QPen(QBrush(Qt::transparent),0)); scene()->addItem(neatFill); /* if the user wants the deco ceiling more visible, do that here (this * basically draws over the background that we had allowed to shine * through so far) */ if (prefs.profile_dc_ceiling && prefs.profile_red_ceiling) { p.clear(); pat.setColorAt(0, getColor(CEILING_SHALLOW)); pat.setColorAt(1, getColor(CEILING_DEEP)); entry = gc.pi.entry; p.append(QPointF(SCALEGC(0, 0))); for (i = 0; i < gc.pi.nr; i++, entry++) { if (entry->in_deco && entry->stopdepth) { if (entry->stopdepth < entry->depth) { p.append(QPointF(SCALEGC(entry->sec, entry->stopdepth))); } else { p.append(QPointF(SCALEGC(entry->sec, entry->depth))); } } else { p.append(QPointF(SCALEGC(entry->sec, 0))); } } neatFill = new QGraphicsPolygonItem(); neatFill->setBrush(QBrush(pat)); neatFill->setPolygon(p); neatFill->setPen(QPen(QBrush(Qt::NoBrush),0)); scene()->addItem(neatFill); } /* finally, plot the calculated ceiling over all this */ if (prefs.profile_calc_ceiling) { pat.setColorAt(0, getColor(CALC_CEILING_SHALLOW)); pat.setColorAt(1, getColor(CALC_CEILING_DEEP)); entry = gc.pi.entry; p.clear(); p.append(QPointF(SCALEGC(0, 0))); for (i = 0; i < gc.pi.nr; i++, entry++) { if (entry->ceiling) p.append(QPointF(SCALEGC(entry->sec, entry->ceiling))); else p.append(QPointF(SCALEGC(entry->sec, 0))); } p.append(QPointF(SCALEGC((entry-1)->sec, 0))); neatFill = new QGraphicsPolygonItem(); neatFill->setPolygon(p); neatFill->setPen(QPen(QBrush(Qt::NoBrush),0)); neatFill->setBrush(pat); scene()->addItem(neatFill); } /* plot the calculated ceiling for all tissues */ if (prefs.profile_calc_ceiling && prefs.calc_all_tissues) { int k; for (k=0; k<16; k++) { pat.setColorAt(0, getColor(CALC_CEILING_SHALLOW)); pat.setColorAt(1, QColor(100, 100, 100, 50)); entry = gc.pi.entry; p.clear(); p.append(QPointF(SCALEGC(0, 0))); for (i = 0; i < gc.pi.nr; i++, entry++) { if ((entry->ceilings)[k]) p.append(QPointF(SCALEGC(entry->sec, (entry->ceilings)[k]))); else p.append(QPointF(SCALEGC(entry->sec, 0))); } p.append(QPointF(SCALEGC((entry-1)->sec, 0))); neatFill = new QGraphicsPolygonItem(); neatFill->setPolygon(p); neatFill->setBrush(pat); scene()->addItem(neatFill); } } /* next show where we have been bad and crossed the dc's ceiling */ if (prefs.profile_dc_ceiling) { pat.setColorAt(0, getColor(CEILING_SHALLOW)); pat.setColorAt(1, getColor(CEILING_DEEP)); entry = gc.pi.entry; p.clear(); p.append(QPointF(SCALEGC(0, 0))); for (i = 0; i < gc.pi.nr; i++, entry++) p.append(QPointF(SCALEGC(entry->sec, entry->depth))); for (i-- , entry--; i >= 0; i--, entry--) { if (entry->in_deco && entry->stopdepth > entry->depth) { p.append(QPointF(SCALEGC(entry->sec, entry->stopdepth))); } else { p.append(QPointF(SCALEGC(entry->sec, entry->depth))); } } } neatFill = new QGraphicsPolygonItem(); neatFill->setPolygon(p); neatFill->setPen(QPen(QBrush(Qt::NoBrush),0)); neatFill->setBrush(QBrush(pat)); scene()->addItem(neatFill); /* Now do it again for the velocity colors */ entry = gc.pi.entry; for (i = 1; i < gc.pi.nr; i++) { entry++; sec = entry->sec; /* we want to draw the segments in different colors * representing the vertical velocity, so we need to * chop this into short segments */ depth = entry->depth; QGraphicsLineItem *item = new QGraphicsLineItem(SCALEGC(entry[-1].sec, entry[-1].depth), SCALEGC(sec, depth)); QPen pen(defaultPen); pen.setColor(getColor((color_indice_t)(VELOCITY_COLORS_START_IDX + entry->velocity))); item->setPen(pen); scene()->addItem(item); } }
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(); }
void main_loop() { struct colour *board[WIDTH_CELLS][HEIGHT_CELLS]; SDL_Event e = {0}; bool running = false; bool game_over = false; int i = 0; int x = 0; int y = 0; int score = 0; int last_x = 0; int last_y = 1; struct piece held; new_piece(&held); TTF_Font *font = TTF_OpenFont(FONT_FILE, FONT_SIZE); if (!font) { printf("TTF_OpenFont: %s\n", TTF_GetError()); return; } for (y = 0; y < HEIGHT_CELLS; y++) for (x = 0; x < WIDTH_CELLS; x++) board[x][y] = &(palette[0]); running = true; last_x = last_y = x = y = 0; SDL_AddTimer(INTERVAL_NORMAL, &gravity_callback, NULL); char lockout; while (running) { lockout = 0; score += clear_rows(&board); if (hit_side(x, y, &held, &board)) x = last_x; if (hit_floor(x, y, &held, &board)) lockout = 1; draw_board(&board); if (!game_over) draw_piece(x, y, held.colour, held.bitmap); char score_string[16]; snprintf(score_string, sizeof(score_string), "Score: %d", score); score_string[sizeof(score_string) - 1] = '\0'; plot_text(score_string, font, ((SDL_Color){255,255,255,255}), 10, 10); if (game_over) plot_text("Game over", font, ((SDL_Color){255,255,255,255}), 90, 50); plot_update(); SDL_WaitEvent(&e); if (pause_mode) { if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_p) { pause_mode = 0; } continue; } switch (e.type) { case SDL_USEREVENT: if (lockout && !game_over) { drop_piece(x, y, &held, &board); last_x = last_y = x = y = 0; new_piece(&held); if (piece_overlaps(&held, &board, x, y)) { game_over = true; } lockout = 0; } else { last_y = y++; /* gravity */ last_x = x; } break; case SDL_QUIT: fprintf(stderr, "quit\n"); running = false; break; case SDL_KEYDOWN: switch (e.key.keysym.sym) { case SDLK_p: pause_mode = 1; break; case SDLK_a: last_x = x--; break; case SDLK_d: last_x = x++; break; case SDLK_w: i = 0; do { rotate(&held, 1); } while(hit_side(x, y, &held, &board) && i++ < 4); break; case SDLK_s: speed_mode = 1; break; case SDLK_q: running = false; break; default: break; } break; case SDL_KEYUP: switch (e.key.keysym.sym) { case SDLK_s: speed_mode = 0; break; default: break; } default: break; } } }
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()); } }