Ejemplo n.º 1
0
void Scene::paintGL()
{
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();

    glOrtho( 0, RESOLUTION_WIDTH, 0, RESOLUTION_HEIGHT, 1, 1000 );

    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();

    // Inicio: Gráfico de cámara

    glEnable( GL_TEXTURE_2D );
    glColor3f( 1, 1, 1 );
    glBindTexture( GL_TEXTURE_2D, textures->at( 0 )->id );
    glBegin( GL_QUADS );

        glTexCoord2f( 0, 0 ); glVertex3f( 0, RESOLUTION_HEIGHT, -999 );
        glTexCoord2f( 1, 0 ); glVertex3f( RESOLUTION_WIDTH, RESOLUTION_HEIGHT, -999 );
        glTexCoord2f( 1, 1 ); glVertex3f( RESOLUTION_WIDTH, 0, -999 );
        glTexCoord2f( 0, 1 ); glVertex3f( 0, 0, -999 );

    glEnd();
    glDisable( GL_TEXTURE_2D );

    // Fin: Gráfico de cámara

    glMatrixMode( GL_PROJECTION );
    double projectionMatrix[16];

    cv::Size2i sceneSize( RESOLUTION_WIDTH, RESOLUTION_HEIGHT );
    cv::Size2i openGlSize( RESOLUTION_WIDTH, RESOLUTION_HEIGHT );
    cameraParameters->glGetProjectionMatrix( sceneSize, openGlSize, projectionMatrix, 0.05, 10 );

    glLoadMatrixd( projectionMatrix );
    glMatrixMode( GL_MODELVIEW );
    double modelview_matrix[16];

    // Inicio: Gráfico en marcadores

    bool musicDetected = false;
    ThreeDWriter textoParaCredencial(80, "Arial", -0.04f, 0.045f, -0.001f, 0.3f, 0.02f, 0.0001f);
    QString comando_sql;
    QString textoParaMostrar;
    QVector<QStringList> vDatos;

    for( int i = 0 ; i < detectedMarkers.size() ; i++ )
    {
        detectedMarkers.operator []( i ).glGetModelViewMatrix( modelview_matrix );
        glLoadMatrixd( modelview_matrix );

        glTranslatef( xTranslationOption, yTranslationOption, zTranslationOption );
        if( rotateOption )
        {
            emit message( "Rotando" );
            zRotationOption += rotationVelocityOption;
        }
        glRotatef( xRotationOption, 1, 0, 0 );
        glRotatef( yRotationOption, 0, 1, 0 );
        glRotatef( zRotationOption, 0, 0, 1 );
                                                                                                                /*
||**************************************************************************************************************||
||                                                                                                              ||
||                                   MÉTODOS LISTOS PARA USAR EN MARCADORES:                                    ||
||                                                                                                              ||
||    DrawSheet - DrawBox - DrawCamera - DrawCameraBox - DrawModel - DrawVideo - DrawWebImage - ListenWebMusic  ||
||         Siempre agregar "+ scaleOption" al parámetro percentage para que la escala pueda ser modificada      ||
||                                                                                                              ||
|| *************************************************************************************************************||
||                                                                                                              ||
|| RECORDAR:   Ajustar la escala que se envía como parámetro ( percentage ).                                    ||
|| IMPORTANTE: Para que los modelos se vean bien, las imagenes y el sonido, agregar antes de usar:              ||
||                                                                                                              ||
|| DrawBox:        glRotatef( -90, 0, 1, 0 );                                                                   ||
|| DrawCamera:     glRotatef( 90, 0, 1, 0 );                                                                    ||
|| DrawCameraBox:  glRotatef( 90, 0, 1, 0 );                                                                    ||
|| DrawSheet:      glRotatef( 90, 0, 1, 0 );                                                                    ||
|| DrawWebImage:   glRotatef( 180, 0, 0, 1 ); glRotatef( -90, 0, 1, 0 );                                        ||
|| DrawVideo:      glRotatef( 90, 0, 1, 0 ); glRotatef( 180, 0, 0, 1 );                                         ||
|| ListenWebMusic: glRotatef( 180, 0, 0, 1 ); drawWebImage();                                                   ||
||                 musicDetected = true; webMusicPlayer->setVolume( detectedMarkers.at( i ).getArea() / 1000 ); ||
||                                                                                                              ||
|| House:          glRotatef( -90, 0, 1, 0 );                                                                   ||
|| IPhone:         glTranslatef( 0.032, 0, -0.025 ); glRotatef( 90, 1, 0, 0 );                                  ||
|| Man:            glTranslatef( 0, 0, -0.012 ); glRotatef( -90, 1, 0, 0 ); glRotatef( 90, 0, 0, 1 );           ||
|| Oil:            glRotatef( 90, 1, 0, 0 );                                                                    ||
|| Wagen:          glRotatef( 90, 1, 0, 0 ); glRotatef( 90, 0, 0, 1 );                                          ||
|| Woman:          glRotatef( 90, 1, 0, 0 ); glRotatef( 90, 0, 0, 1 );                                          ||
||                                                                                                              ||
|| *************************************************************************************************************||
                                                                                                                */

        switch( detectedMarkers.at( i ).id )
        {
            case 0: { glRotatef( 270, 1, 0, 0 );
                      glRotatef( 90, 0, 1, 0 );
                      drawCamera( 130 + scaleOption );
                      emit message( "Dibujando Cámara" );
                      break; }

            case 1: { glRotatef( 90, 1, 0, 0 );
                      glRotatef( 90, 0, 1, 0 );
                      drawCameraBox( 130 + scaleOption );
                      emit message( "Dibujando Cubo de la Cámara" );
                      break; }

            case 2: { glRotatef( 90+180, 1, 0, 0 );
                      glRotatef( 90, 0, 1, 0 );
                      drawWebImage( 150 + scaleOption );
                      break; }

            case 3: { glRotatef( -90, 1, 0, 0 );
                      glRotatef( 90, 0, 1, 0 );
                      drawWebMusicImage( 150 + scaleOption );
                      musicDetected = true;
                      int volume = detectedMarkers.at( i ).getArea() / 150;
                      if( volume > 100 ) volume = 100;
                      webMusicPlayer->setVolume( volume );
                      emit message( "Volumen audio: " +  QString::number( volume ) );
                      listenWebMusic(); break; }

            case 4: { glRotatef( 90, 1, 0, 0 );
                      glRotatef( 90, 0, 1, 0 );
                      drawBox( "Danger.jpg", 100 + scaleOption );
                      emit message( "Dibujando la Famosa Caja Danger" );
                      break; }

            case 5: { glRotatef( 180, 1, 0, 0 );
                      glRotatef( 90, 0, 1, 0 );
                      glTranslatef( -0.03, 0.05, 0);
                      drawModel( "IPhone.3ds", 70 + scaleOption );
                      emit message( "Dibujando Modelo 3d: IPhone" );
                      break;}

            case 6: { glTranslatef( 0, 0.02, 0 );
                      glRotatef( -90, 1, 0, 0 );
                      glRotatef( 90, 0, 1, 0 );
                      glRotatef( 90+180, 1, 0, 0 );
                      drawModel( "Man.3ds", 3 + scaleOption );
                      emit message( "Dibujando Modelo 3d: Man" );
                      break; }

            case 7: { glRotatef( 90, 0, 1, 0 );
                      glRotatef( 90, 1, 0, 0 );
                      glRotatef( 90, 0, 1, 0 );
                      drawModel( "Oil.3ds", 150 + scaleOption );
                      emit message( "Dibujando Modelo 3d: Oil" );
                      break; }

            case 8: { glRotatef( 270, 1, 0, 0 );
                      glRotatef( 90, 0, 1, 0 );
                      int volume = detectedMarkers.at( i ).getArea() / 150;
                      if( volume > 100 ) volume = 100;
                      emit message( "Volumen video: " +  QString::number( volume ) );
                      drawVideo( "trailer-RF7.mp4", volume, 200 + 2*scaleOption );
                      break; }

            case 9: { glRotatef( 90, 1, 0, 0 );
                       glRotatef( 90, 0, 1, 0 );
                       drawBox( "Ubp.png", 150 + scaleOption );
                       emit message( "Dibujando Cubo de la UBP" );
                       break; }

            case 10: {
                       if ( ! seguirRostroOption)
                           actualizaServoSiCorresponde(detectedMarkers.at( i ).getCenter().x, 50);
                       glBegin(GL_LINES);
                            glColor3f (1, 0, 0);
                            glVertex3f( 0, 0,  0);
                            glVertex3f( 0, 100,  0);
                            glColor3f (0, 0, 1);
                            glVertex3f( 0, 0,  0);
                            glVertex3f( -100, 0,  0);
                       glEnd();
                       emit message( "Control de Servo" );
                       break; }

            case 11: { glRotatef( 270, 1, 0, 0 );
                      glRotatef( 90, 0, 1, 0 );
                      int volume = detectedMarkers.at( i ).getArea() / 150;
                      if( volume > 100 ) volume = 100;
                      emit message( "Volumen video: " +  QString::number( volume ) );
                      drawVideo( "stic.mp4", volume, 200 + 2*scaleOption );
                      break; }

            case 12: { glRotatef( 270, 1, 0, 0 );
                      glRotatef( 90, 0, 1, 0 );
                      int volume = detectedMarkers.at( i ).getArea() / 150;
                      if( volume > 100 ) volume = 100;
                      emit message( "Volumen video: " +  QString::number( volume ) );
                      drawVideo( "trailer-relato.mp4", volume, 200 + 2*scaleOption );
                      break; }

            case 13:
                comando_sql = "SELECT sorteo FROM invitados WHERE apellido = 'House'";
                vDatos = adminDB.ejecutarComandoSelect(comando_sql);

                for (int i=0 ; i<vDatos.size() ; i++)  {
                    textoParaMostrar = vDatos.at(i).at(0);
                }

                glRotatef( 90, 1, 0, 0 );
                glRotatef( 270, 0, 1, 0 );
                glTranslatef( 0, 0, 0.005 );
                drawSheet( "drhouse.jpg", 130 + scaleOption );

                glLoadMatrixd( modelview_matrix );  // Cargamos la matriz inicial
                glRotatef( 90, 0, 0, 1 );
                glRotated(180, 0, 0, 5);
                textoParaCredencial.writeText(textoParaMostrar);

                break;

            case 14:
                comando_sql = "SELECT sorteo FROM invitados WHERE apellido = 'Messi'";
                vDatos = adminDB.ejecutarComandoSelect(comando_sql);

                for (int i=0 ; i<vDatos.size() ; i++)  {
                    textoParaMostrar = vDatos.at(i).at(0);
                }

                glRotatef( 90, 1, 0, 0 );
                glRotatef( 270, 0, 1, 0 );
                glTranslatef( 0, 0, 0.005 );
                drawSheet( "messi.png", 130 + scaleOption );

                glLoadMatrixd( modelview_matrix );  // Cargamos la matriz inicial
                glRotatef( 90, 0, 0, 1 );
                glRotated(180, 0, 0, 5);
                textoParaCredencial.writeText(textoParaMostrar);

                break;

            case 17: {
                    glRotatef( -90, 0, 0, 1 );
                    glRotatef( 90, 1, 0, 0 );
                    drawModel( "House.3ds", 40 + scaleOption );
                    emit message( "Dibujando Modelo 3d: Casa" );
                    break; }

            case 15: { glRotatef( 90, 1, 0, 0 );
                   glRotatef( 90, 0, 1, 0 );
                   drawBox( "caja.bmp", 100 + scaleOption );
                   emit message( "Dibujando Cubo de la UBP" );
                   break; }

            case 16: { glRotatef( 90, 1, 0, 0 );
                   glRotatef( 90, 0, 1, 0 );
                   drawBox( "caja.bmp", 100 + scaleOption );
                   emit message( "Dibujando Cubo de la UBP" );
                   break; }

            case 18: { glRotatef( 90, 1, 0, 0 );
                   glRotatef( 90, 0, 1, 0 );
                   drawBox( "caja.bmp", 100 + scaleOption );
                   emit message( "Dibujando Cubo de la UBP" );
                   break; }

            case 19: { glRotatef( 90, 1, 0, 0 );
                   glRotatef( 90, 0, 1, 0 );
                   drawBox( "caja.bmp", 100 + scaleOption );
                   emit message( "Dibujando Cubo de la UBP" );
                   break; }


            default:  { break; }
        }
    }

    if( musicDetected ) musicActive = true;
    else if( musicActive )
         {
            emit message( "<div style=\"color:red;\">Marcador no detectado, la música se pausará</div>" );
             webMusicPlayer->setVolume( webMusicPlayer->volume() - 1 );
             if( webMusicPlayer->volume() <= 0 )
             {
                 emit message( "Musica pausada" );
                 webMusicPlayer->pause();
                 musicActive = false;
             }
         }

    // La siguiente linea se ejecuta siempre. Habria que ingeniarsela de otra forma para bajar el volumen
    decreaseVideosVolume();

    // Fin: Gráfico en marcadores

    glFlush();
}
Ejemplo n.º 2
0
int KReportItemCheckBox::renderSimpleData(OROPage *page, OROSection *section, const QPointF &offset,
                                        const QVariant &data, KReportScriptHandler *script)
{
    OROCheckBox *chk = new OROCheckBox();

    chk->setPosition(scenePosition(position()) + offset);
    chk->setSize(sceneSize(size()));

    chk->setLineStyle(lineStyle());
    chk->setForegroundColor(m_foregroundColor->value().value<QColor>());
    if (m_checkStyle->value().toString() == QLatin1String("Cross")) {
        chk->setCheckType(OROCheckBox::Cross);
    } else if (m_checkStyle->value().toString() == QLatin1String("Dot")) {
        chk->setCheckType(OROCheckBox::Dot);
    } else {
        chk->setCheckType(OROCheckBox::Tick);
    }
                
    QString str;
    bool v = false;
    QString cs = itemDataSource();

    //kreportpluginDebug() << "ControlSource:" << cs;
    if (!cs.isEmpty()) {
#ifdef KREPORT_SCRIPTING
        if (cs.left(1) == QLatin1String("=") && script) {
            str = script->evaluate(cs.mid(1)).toString();
        } else
#else
        Q_UNUSED(script);
#endif
        {
            str = data.toString();
        }

        str = str.toLower();

        //kreportpluginDebug() << "Check Value:" << str;
        if (str == QLatin1String("t") || str == QLatin1String("y") || str == QLatin1String("true") || str == QLatin1String("1"))
            v = true;

    } else {
        v = value();
    }

    chk->setValue(v);

    if (page) {
        page->insertPrimitive(chk);
    }

    if (section) {
        OROCheckBox *chk2 = dynamic_cast<OROCheckBox*>(chk->clone());
        chk2->setPosition(scenePosition(position()));
        section->addPrimitive(chk2);
    }

    if (!page) {
        delete chk;
    }

    return 0; //Item doesn't stretch the section height
}
Ejemplo n.º 3
0
void ExportWizard::setWallpaper()
{
    // find a new path
    QString wFilePath;
    int fileNumber = 0;
    while (wFilePath.isEmpty() || QFile::exists(wFilePath))
#if defined(Q_OS_WIN) || defined(Q_OS_OS2)
        wFilePath = QDir::toNativeSeparators(QDir::homePath()) + QDir::separator() + "fotowall-background" + QString::number(++fileNumber) + ".bmp";
#else
        wFilePath = QDir::toNativeSeparators(QDir::homePath()) + QDir::separator() + "fotowall-background" + QString::number(++fileNumber) + ".jpg";
#endif

    // render the image
    QImage image;
    QSize sceneSize(m_canvas->width(), m_canvas->height());
    QSize desktopSize = QApplication::desktop()->screenGeometry().size();
    if (m_ui->wbZoom->isChecked())
        image = m_canvas->renderedImage(desktopSize, Qt::KeepAspectRatioByExpanding);
    else if (m_ui->wbScaleKeep->isChecked())
        image = m_canvas->renderedImage(desktopSize, Qt::KeepAspectRatio);
    else if (m_ui->wbScaleIgnore->isChecked())
        image = m_canvas->renderedImage(desktopSize, Qt::IgnoreAspectRatio);
    else
        image = m_canvas->renderedImage(sceneSize);

    // save the right kind of image into the home dir
#if defined(Q_OS_WIN) || defined(Q_OS_OS2)
    if (!image.save(wFilePath, "BMP")) {
#else
    if (!image.save(wFilePath, "JPG", 100)) {
#endif
        QMessageBox::warning(this, tr("Wallpaper Error"), tr("Can't save the image to disk."));
        return;
    }

#if defined(Q_OS_WIN)
    //Set new background path
    {QSettings appSettings("HKEY_CURRENT_USER\\Control Panel\\Desktop", QSettings::NativeFormat);
    appSettings.setValue("ConvertedWallpaper", wFilePath);
    appSettings.setValue("Wallpaper", wFilePath);}

    //Notification to windows refresh desktop
    SystemParametersInfoA(SPI_SETDESKWALLPAPER, true, (void*)qPrintable(wFilePath), SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE);
#elif defined(Q_OS_LINUX)
    // KDE4
    if (QString(qgetenv("KDE_SESSION_VERSION")).startsWith("4"))
        QMessageBox::warning(this, tr("Manual Wallpaper Change"), tr("KDE4 doesn't yet support changing wallpaper automatically.\nGo to the Desktop Settings and select the file:\n  %1").arg(wFilePath));

    // KDE3
    QString kde3cmd = "dcop kdesktop KBackgroundIface setWallpaper '" + wFilePath + "' 6";
    QProcess::startDetached(kde3cmd);

    // Gnome2
    QString gnome2Cmd = "gconftool -t string -s /desktop/gnome/background/picture_filename " + wFilePath ;
    QProcess::startDetached(gnome2Cmd);
#else
#warning "Implement background change for this OS"
#endif
}

void ExportWizard::saveImage()
{
    if (m_ui->filePath->text().isEmpty()) {
        QMessageBox::warning(this, tr("No file selected !"), tr("You need to choose a file path for saving."));
        return;
    }
    QString imgFilePath = m_ui->filePath->text();

    // get the rendering size
    QSize imageSize(m_ui->saveWidth->value(), m_ui->saveHeight->value());

    // render the image
    QImage image;
    bool hideTools = !m_ui->imgAsIsBox->isChecked();
    if (m_ui->ibZoom->isChecked())
        image = m_canvas->renderedImage(imageSize, Qt::KeepAspectRatioByExpanding, hideTools);
    else if (m_ui->ibScaleKeep->isChecked())
        image = m_canvas->renderedImage(imageSize, Qt::KeepAspectRatio, hideTools);
    else
        image = m_canvas->renderedImage(imageSize, Qt::IgnoreAspectRatio, hideTools);

    // rotate image if requested
    if (m_ui->saveLandscape->isChecked()) {
        // Save in landscape mode, so rotate
        QMatrix matrix;
        matrix.rotate(90);
        image = image.transformed(matrix);
    }

    // save image
    if (image.save(imgFilePath) && QFile::exists(imgFilePath)) {
        int size = QFileInfo(imgFilePath).size();
        QMessageBox::information(this, tr("Done"), tr("The target image is %1 bytes long").arg(size));
    } else
        QMessageBox::warning(this, tr("Rendering Error"), tr("Error rendering to the file '%1'").arg(imgFilePath));
}

void ExportWizard::startPosterazor()
{
    static const quint32 posterPixels = 6 * 1000000; // Megapixels * 3 bytes!
    // We will use up the whole posterPixels for the render, respecting the aspect ratio.
    const qreal widthToHeightRatio = m_canvas->width() / m_canvas->height();
    // Thanks to colleague Oswald for some of the math :)
    const int posterPixelWidth = int(sqrt(widthToHeightRatio * posterPixels));
    const int posterPixelHeight = posterPixels / posterPixelWidth;

    static const QLatin1String settingsGroup("posterazor");
    App::settings->beginGroup(settingsGroup);

    // TODO: Eliminate Poster size in %
    ImageLoaderQt loader;
    loader.setQImage(m_canvas->renderedImage(QSize(posterPixelWidth, posterPixelHeight)));
    PosteRazorCore posterazor(&loader);
    posterazor.readSettings(App::settings);
    Wizard *wizard = new Wizard;
    Controller controller(&posterazor, wizard);
    controller.setImageLoadingAvailable(false);
    controller.setPosterSizeModeAvailable(Types::PosterSizeModePercentual, false);
    QDialog dialog(this, Qt::CustomizeWindowHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint);
    dialog.setWindowTitle(tr("Export poster"));
    dialog.setLayout(new QVBoxLayout);
    dialog.layout()->addWidget(wizard);
    dialog.resize(640, 480);
    dialog.exec();
    App::settings->sync();
    posterazor.writeSettings(App::settings);
    App::settings->endGroup();
}

bool ExportWizard::printPaper()
{
    // update the realsizeinches, just in case..
    slotPrintSizeChanged();

    // get dpi, compute printed size
    int printDpi = m_ui->printDpi->value();
    int printWidth = (int)(m_printSizeInches.width() * (float)printDpi);
    int printHeight = (int)(m_printSizeInches.height() * (float)printDpi);
    QSize printSize(printWidth, printHeight);
    Qt::AspectRatioMode printRatio = m_ui->printKeepRatio->isChecked() ? Qt::KeepAspectRatio : Qt::IgnoreAspectRatio;

    // check if print params differ from the 'Exact Size' stuff
    if (m_printPreferred) {
        if (printDpi != m_canvas->modeInfo()->printDpi()) {
            qWarning("ExportWizard::print: dpi changed to %d from the default %d", printDpi, (int)m_canvas->modeInfo()->printDpi());
        } else {
            QSize exactPrintSize = m_canvas->modeInfo()->fixedPrinterPixels();
            if (printSize != exactPrintSize)
                qWarning("ExportWizard::print: size changed to %dx%d from the default %dx%d", printWidth, printHeight, exactPrintSize.width(), exactPrintSize.height());
        }
    }

    // setup printer
    QPrinter printer;
    printer.setResolution(printDpi);
    printer.setPaperSize(QPrinter::A4);

    // configure printer via the print dialog
    QPrintDialog printDialog(&printer);
    if (printDialog.exec() != QDialog::Accepted)
        return false;

    // TODO: use different ratio modes?
    QImage image = m_canvas->renderedImage(printSize, printRatio);
    if (m_ui->printLandscape->isChecked()) {
        // Print in landscape mode, so rotate
        QMatrix matrix;
        matrix.rotate(90);
        image = image.transformed(matrix);
    }

    // And then print
    QPainter painter;
    painter.drawImage(image.rect(), image);
    painter.end();
    return true;
}
Ejemplo n.º 4
0
int KReportItemField::renderSimpleData(OROPage *page, OROSection *section, const QPointF &offset,
                                        const QVariant &data, KReportScriptHandler *script)
{
    OROTextBox * tb = new OROTextBox();
    tb->setPosition(scenePosition(position()) + offset);
    tb->setSize(sceneSize(size()));
    tb->setFont(font());
    tb->setFlags(textFlags());
    tb->setTextStyle(textStyle());
    tb->setLineStyle(lineStyle());
    tb->setCanGrow(m_canGrow->value().toBool());
    tb->setWordWrap(m_wordWrap->value().toBool());

    QString str;

    QString ids = itemDataSource();
    if (!ids.isEmpty()) {
#ifdef KREPORT_SCRIPTING
        if (ids.left(1) == QLatin1String("=") && script) { //Everything after = is treated as code
            if (!ids.contains(QLatin1String("PageTotal()"))) {
                QVariant v = script->evaluate(ids.mid(1));
                str = v.toString();
            } else {
                str = ids.mid(1);
                tb->setRequiresPostProcessing(true);
            }
        } else
#else
        Q_UNUSED(script);
#endif
        if (ids.left(1) == QLatin1String("$")) { //Everything past $ is treated as a string
            str = ids.mid(1);
        } else {
            str = data.toString();
        }
    } else {
            str = m_itemValue->value().toString();
    }

    tb->setText(str);

    //Work out the size of the text
    if (tb->canGrow()) {
        QRect r;
        if (tb->wordWrap()) {
            //Grow vertically
            QFontMetrics metrics(font());
            QRect temp(tb->position().x(), tb->position().y(), tb->size().width(), 5000); // a large vertical height
            r = metrics.boundingRect(temp, tb->flags(), str);
        } else {
            //Grow Horizontally
            QFontMetrics metrics(font());
            QRect temp(tb->position().x(), tb->position().y(), 5000, tb->size().height()); // a large vertical height
            r = metrics.boundingRect(temp, tb->flags(), str);
        }
        tb->setSize(r.size() + QSize(4,4));
    }

    if (page) {
        page->insertPrimitive(tb);
    }

    if (section) {
        OROPrimitive *clone = tb->clone();
        clone->setPosition(scenePosition(position()));
        section->addPrimitive(clone);
    }
    int height = scenePosition(position()).y() + tb->size().height();
    //If there is no page to add the item to, delete it now because it wont be deleted later
    if (!page) {
        delete tb;
    }
    return height;
}