AbstractPidHandler::AbstractPidHandler(bool a, QObject *parent) :
    QObject(parent),
    d(new AbstractPidHandlerPrivate(this))
{
    if (a)
        attach();

    connect(this, SIGNAL(discontinuity()),
            this, SLOT(deleteCurrentSection()));
}
Beispiel #2
0
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // Menu
    QMenu* modelMenu = menuBar()->addMenu("&Model");
    modelMenu->addAction("&Open model...",  this, SLOT(openModel()) );
    modelMenu->addSeparator();
    modelMenu->addAction("&Close model",    this, SLOT(closeModel()) );

    QMenu* markMenu = menuBar()->addMenu("&Bookmarks");
    markMenu->addAction("&New file...",     this, SLOT(closeBookmarksFile()) );
    markMenu->addAction("&Open file...",    this, SLOT(openBookmarksFile()) );
    markMenu->addSeparator();
    markMenu->addAction("&Close file",      this, SLOT(closeBookmarksFile()) );
    markMenu->addSeparator();
    markMenu->addAction("&Save file", this, SLOT(saveBookmarksFile()));
    markMenu->addAction("&Save file as...", this, SLOT(saveAsBookmarksFile()));

    QMenu* viewMenu = menuBar()->addMenu("&View");
    viewMenu->addAction("&View as points",    this,       SLOT(viewAsPoints()) );
    viewMenu->addAction("&View as wired",    this,       SLOT(viewAsWired()) );
    viewMenu->addAction("&View as solid",  this,        SLOT(viewAsSolid()) );
    viewMenu->addAction("&View as solid + wired",this,   SLOT(viewAsSolidWire()) );

    QMenu* modeMenu = menuBar()->addMenu("&Mode");
    modeMenu->addAction("&Viewer",    this,             SLOT(viewerMode()) );
    modeMenu->addAction("&Editor",    this,             SLOT(editorMode()) );
    modeMenu->addAction("&Ask Me!",      this,             SLOT(testMode()) );


    // Section list panel buttons.
    QObject::connect(ui->addButton, SIGNAL(clicked()), this, SLOT(showAddSectionPanel()));
    QObject::connect(ui->editButton, SIGNAL(clicked()), this, SLOT(showEditSectionPanel()));
    QObject::connect(ui->deleteButton, SIGNAL(clicked()), this, SLOT(deleteCurrentSection()));
    QObject::connect(ui->infoButton, SIGNAL(clicked()), this, SLOT(showInfoSectionPanel()));
    QObject::connect(ui->listWidget, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)),
                     this, SLOT(listWidgetItemClicked(QListWidgetItem*)));

    // Add bookmark panel buttons.
    QObject::connect(ui->addModeButton, SIGNAL(clicked()), this, SLOT(setAddSelectionMode()));
    QObject::connect(ui->removeModeButton, SIGNAL(clicked()), this, SLOT(setRemoveSelectionMode()));
    QObject::connect(ui->saveButton, SIGNAL(clicked()), this, SLOT(saveBookmark()));
    QObject::connect(ui->discardButton, SIGNAL(clicked()), this, SLOT(discardBookmark()));
    QObject::connect(ui->brushSizeSlider, SIGNAL(valueChanged(int)), this, SLOT(setBrushSize(int)));

    // Information panel buttons
    QObject::connect(ui->backButton, SIGNAL(clicked()), this, SLOT(showListPanel()));

    // Test panel buttons
    QObject::connect(ui->nextQuestionButton, SIGNAL(clicked()), this, SLOT(nextQuestion()));
    QObject::connect(ui->glwidget, SIGNAL(pickResult(std::set<unsigned int>)), this, SLOT(checkResponse(std::set<unsigned int>)));


    // Set window title.
    setWindowTitle("untitled.txt");

    // Initialize variables.
    _bookmarkList = new BookmarkList();
    clearBookmarkList();
    _model = new Model();
    _indexTest = 0;

    // Set viewer mode.
    viewerMode();

    // Show welcome message
    statusBar()->showMessage("Welcome to 3D Marker.");
}
void AbstractPidHandler::parse(const QByteArray &packet)
{
    // If the packet is empty return
    if (packet.isNull())
        return;

    // Build pointer to packet content
    const quint8 *data = (quint8 *)packet.constData(), *p = 0;

    // Return if the packet does not start with 0x47
    if (data[0] != 0x47) {
        qWarning() << "Not a TS packet!";
        return;
    }

    // Check validity of continuity counter
    quint8 ccc = data[3] & 0x0F;
    if (d->ecc == INVALID_CC) { // Conintuity counter has not been yet initialized
        d->ecc = ccc; // Initialize continuity counter with currrent value
    } else {
        // Check if packet is duplicate and just ignore it if it the case
        if (d->ecc == ccc) {
            qWarning() << "Duplicate TS packet?!?!?!";
            return;
        }

        // Compute next continuity counter
        d->ecc = ++d->ecc & 0x0F;

        // Check if discontinuity
        if (d->ecc != ccc) {
            qDebug() << "Discontinuity!\n";
            d->ecc = ccc;
            emit discontinuity();
        }
    }

    // Return if no payload in the TS packet
    if (!data[3] & 0x10)
        return;

    // Skip the adaptation field if present
    if (data[3] & 0x20) //  Check if "Adaptation field exists" bit is set
        p = data + 5 + data[4]; // Point after adaptation field
    else
        p = data + 4; // Point to first byte after header

    // Compute Payload Start Unit Indicator
    quint8 pusi = data[1] & 0x40;

    // Skip new section begins if present
    if (pusi) // Check if "Payload unit start" bit is set
        p = p + *p + 1;


    // If no section yet started and the current packet contains the start of a new section then build a new one
    if (!d->section) {
        if (!pusi)
            return;

        d->section = new Section(this);
    }

    // Compute availability of data
    quint8 available = 188 + data - p;

    while (available) {
        // Check if there is enough bytes in the current data buffer to complete the need of the section
        if (available >= d->section->need) {

            // Add the needed bytes to the data buffer of the section
            d->section->data += QByteArray((const char *)p, (int)d->section->need);
            p += d->section->need;
            available -= d->section->need;

            // Check if the section's header has been parsed so far
            if (!d->section->headerComplete) {
                // Apparently not! So let's do the job
                d->section->need = d->section->sectionLength = (((quint16)d->section->data[1] & 0x0F) << 8) | ((quint16)d->section->data[2] & 0xFF);

                // Done! Let's indicate it
                d->section->headerComplete = true;

                // We still need to check if the section isn't too long
                if (d->section->need > sectionMaxSize() - 3) {
                    qWarning() << "Section too long!";
                    deleteCurrentSection();
                    return;

                    // What about remaining bytes? What do we do if there is other sections in the packet?
                    // ...
                }
            } else {
                // Apparently the header is parsed already. We can take care of the payload now and we
                // will start with checking the CRC if there is one
                if (hasCRC()) {
                    d->section->validCRC = checkCRC();
                }

                d->section->tableID = d->section->data[0];
                d->section->sectionSyntaxIndicator = (d->section->data[1] & 0x80) >> 7;
                d->section->serviceID = (((quint16)d->section->data[3] & 0xFF) << 8) | ((quint16)d->section->data[4] & 0xFF);
                d->section->versionNumber = (d->section->data[5] & 0x3E) >> 1;
                d->section->currentNextIndicator = d->section->data[5] & 0x01;
                d->section->sectionNumber = d->section->data[6];
                d->section->lastSectionNumber = d->section->data[7];

                d->section->payload = (const quint8 *)&d->section->data.constData()[8];
                d->section->payloadSize = d->section->data.size() - 8;
                tableComplete();

                // We can now dispose of the current section
                deleteCurrentSection();

                // A TS packet may contain any number of sections, only the first
                // new one is flagged by the pointer_field. If the next payload
                // byte isn't 0xff then a new section starts.
                if (available && *p != 0xff) {
                    d->section = new Section(this);
                } else {
                    available = 0;
                }
            }
        } else {