Example #1
0
void HookManager::connectHook(QByteArray eventSpec, HookFormatter* formatter)
{
    /// Remove keyword before key sequence, indicated by colon, check if
    /// valid specifier.
    QStringList specifier =  QString::fromUtf8(eventSpec).split(":");

    if(specifier.count() != 2)
    {
        IpcChannel* channel = dynamic_cast<IpcChannel*>(formatter->parent());
        if (channel) channel->sendMessage(QByteArray("Error: Hook event specifier must be of the form 'key:x+y'.\n"));
        delete formatter;
        return;
    }
    else if(specifier[0] != "key")
    {
        IpcChannel* channel = dynamic_cast<IpcChannel*>(formatter->parent());
        if (channel) channel->sendMessage(QByteArray("Error: Hook event specifier must be of the form 'key:x+y'.\n"));
        delete formatter;
        return;
    }


    QKeySequence requestedSpec = QKeySequence::fromString(specifier[1], QKeySequence::PortableText);

    /// Go through all shortcuts, see if one exists, if not create it and connect it to HookFormatter
    int numberEvents = m_events.count();
    bool taken = false;
    for(int i=0; i<numberEvents; i++)
    {
        if(m_eventSpecs[i] == requestedSpec)
        {
            taken = true;
            m_hooksSignedUp[i]+=1;
            /// In case it was in use earlier and got disabled in deactivateEvent.
            m_events[i]->setEnabled(true);
            connect(m_events[i], SIGNAL(activated()), formatter, SLOT(hookActivated()));
            formatter->setEventId(i);
        }
    }

    if(!taken)
    {
        m_eventSpecs.append(requestedSpec);
        m_events.append(new QShortcut(m_eventSpecs[numberEvents], qobject_cast<QWidget*>(this->parent())));
        m_hooksSignedUp.append(1);
        connect(m_events[numberEvents], SIGNAL(activated()), formatter, SLOT(hookActivated()));
        formatter->setEventId(numberEvents);
    }

    connect(formatter, SIGNAL(hookRemoved(int)), this, SLOT(deactivateEvent(int)));
}
void PointViewerMainWindow::handleMessage(QByteArray message)
{
    QList<QByteArray> commandTokens = message.split('\n');
    if (commandTokens.empty())
        return;
    if (commandTokens[0] == "OPEN_FILES")
    {
        QList<QByteArray> flags = commandTokens[1].split('\0');
        bool replaceLabel = flags.contains("REPLACE_LABEL");
        bool deleteAfterLoad = flags.contains("DELETE_AFTER_LOAD");
        bool mutateExisting = flags.contains("MUTATE_EXISTING");
        for (int i = 2; i < commandTokens.size(); ++i)
        {
            QList<QByteArray> pathAndLabel = commandTokens[i].split('\0');
            if (pathAndLabel.size() != 2)
            {
                g_logger.error("Unrecognized OPEN_FILES token: %s",
                               QString(commandTokens[i]));
                continue;
            }
            FileLoadInfo loadInfo(pathAndLabel[0], pathAndLabel[1], replaceLabel);
            loadInfo.deleteAfterLoad = deleteAfterLoad;
            loadInfo.mutateExisting = mutateExisting;
            m_fileLoader->loadFile(loadInfo);
        }
    }
    else if (commandTokens[0] == "CLEAR_FILES")
    {
        m_geometries->clear();
    }
    else if (commandTokens[0] == "UNLOAD_FILES")
    {
        QString regex_str = commandTokens[1];
        QRegExp regex(regex_str, Qt::CaseSensitive, QRegExp::WildcardUnix);
        if (!regex.isValid())
        {
            g_logger.error("Invalid pattern in -unload command: '%s': %s",
                           regex_str, regex.errorString());
            return;
        }
        m_geometries->unloadFiles(regex);
        m_pointView->removeAnnotations(regex);
    }
    else if (commandTokens[0] == "SET_VIEW_LABEL")
    {
        QString regex_str = commandTokens[1];
        QRegExp regex(regex_str, Qt::CaseSensitive, QRegExp::FixedString);
        if (!regex.isValid())
        {
            g_logger.error("Invalid pattern in -unload command: '%s': %s",
                           regex_str, regex.errorString());
            return;
        }
        QModelIndex index = m_geometries->findLabel(regex);
        if (index.isValid())
            m_pointView->centerOnGeometry(index);
    }
    else if (commandTokens[0] == "ANNOTATE")
    {
        if (commandTokens.size() - 1 != 5)
        {
            tfm::format(std::cerr, "Expected five arguments, got %d\n",
                        commandTokens.size() - 1);
            return;
        }
        QString label = commandTokens[1];
        QString text = commandTokens[2];
        bool xOk = false, yOk = false, zOk = false;
        double x = commandTokens[3].toDouble(&xOk);
        double y = commandTokens[4].toDouble(&yOk);
        double z = commandTokens[5].toDouble(&zOk);
        if (!zOk || !yOk || !zOk)
        {
            std::cerr << "Could not parse XYZ coordinates for position\n";
            return;
        }
        m_pointView->addAnnotation(label, text, Imath::V3d(x, y, z));
    }
    else if (commandTokens[0] == "SET_VIEW_POSITION")
    {
        if (commandTokens.size()-1 != 3)
        {
            tfm::format(std::cerr, "Expected three coordinates, got %d\n",
                        commandTokens.size()-1);
            return;
        }
        bool xOk = false, yOk = false, zOk = false;
        double x = commandTokens[1].toDouble(&xOk);
        double y = commandTokens[2].toDouble(&yOk);
        double z = commandTokens[3].toDouble(&zOk);
        if (!zOk || !yOk || !zOk)
        {
            std::cerr << "Could not parse XYZ coordinates for position\n";
            return;
        }
        m_pointView->setExplicitCursorPos(Imath::V3d(x, y, z));
    }
    else if (commandTokens[0] == "SET_VIEW_ANGLES")
    {
        if (commandTokens.size()-1 != 3)
        {
            tfm::format(std::cerr, "Expected three view angles, got %d\n",
                        commandTokens.size()-1);
            return;
        }
        bool yawOk = false, pitchOk = false, rollOk = false;
        double yaw   = commandTokens[1].toDouble(&yawOk);
        double pitch = commandTokens[2].toDouble(&pitchOk);
        double roll  = commandTokens[3].toDouble(&rollOk);
        if (!yawOk || !pitchOk || !rollOk)
        {
            std::cerr << "Could not parse Euler angles for view\n";
            return;
        }
        m_pointView->camera().setRotation(
            QQuaternion::fromAxisAndAngle(0,0,1, roll)  *
            QQuaternion::fromAxisAndAngle(1,0,0, pitch-90) *
            QQuaternion::fromAxisAndAngle(0,0,1, yaw)
        );
    }
    else if (commandTokens[0] == "SET_VIEW_ROTATION")
    {
        if (commandTokens.size()-1 != 9)
        {
            tfm::format(std::cerr, "Expected 9 rotation matrix components, got %d\n",
                        commandTokens.size()-1);
            return;
        }
#       ifdef DISPLAZ_USE_QT4
        qreal rot[9] = {0};
#       else
        float rot[9] = {0};
#       endif
        for (int i = 0; i < 9; ++i)
        {
            bool ok = true;
            rot[i] = commandTokens[i+1].toDouble(&ok);
            if(!ok)
            {
                tfm::format(std::cerr, "badly formatted view matrix message:\n%s", message.constData());
                return;
            }
        }
        m_pointView->camera().setRotation(QMatrix3x3(rot));
    }
    else if (commandTokens[0] == "SET_VIEW_RADIUS")
    {
        bool ok = false;
        double viewRadius = commandTokens[1].toDouble(&ok);
        if (!ok)
        {
            std::cerr << "Could not parse view radius";
            return;
        }
        m_pointView->camera().setEyeToCenterDistance(viewRadius);
    }
    else if (commandTokens[0] == "QUERY_CURSOR")
    {
        // Yuck!
        IpcChannel* channel = dynamic_cast<IpcChannel*>(sender());
        if (!channel)
        {
            qWarning() << "Signalling object not a IpcChannel!\n";
            return;
        }
        V3d p = m_pointView->cursorPos();
        std::string response = tfm::format("%.15g %.15g %.15g", p.x, p.y, p.z);
        channel->sendMessage(QByteArray(response.data(), (int)response.size()));
    }
    else if (commandTokens[0] == "QUIT")
    {
        close();
    }
    else if (commandTokens[0] == "SET_MAX_POINT_COUNT")
    {
        m_maxPointCount = commandTokens[1].toLongLong();
    }
    else if (commandTokens[0] == "OPEN_SHADER")
    {
        openShaderFile(commandTokens[1]);
    }
    else if (commandTokens[0] == "NOTIFY")
    {
        if (commandTokens.size() < 3)
        {
            g_logger.error("Could not parse NOTIFY message: %s", QString::fromUtf8(message));
            return;
        }
        QString spec = QString::fromUtf8(commandTokens[1]);
        QList<QString> specList = spec.split(':');
        if (specList[0].toLower() != "log")
        {
            g_logger.error("Could not parse NOTIFY spec: %s", spec);
            return;
        }

        Logger::LogLevel level = Logger::Info;
        if (specList.size() > 1)
            level = Logger::parseLogLevel(specList[1].toLower().toStdString());

        // Ugh, reassemble message from multiple lines.  Need a better
        // transport serialization!
        QByteArray message;
        for (int i = 2; i < commandTokens.size(); ++i)
        {
            if (i > 2)
                message += "\n";
            message += commandTokens[i];
        }

        g_logger.log(level, "%s", tfm::makeFormatList(message.constData()));
    }
    else if(commandTokens[0] == "HOOK")
    {
        IpcChannel* channel = dynamic_cast<IpcChannel*>(sender());
        if (!channel)
        {
            qWarning() << "Signalling object not a IpcChannel!\n";
            return;
        }
        for(int i=1; i<commandTokens.count(); i+=2)
        {
            HookFormatter* formatter = new HookFormatter(this, commandTokens[i], commandTokens[i+1], channel);
            m_hookManager->connectHook(commandTokens[i], formatter);
        }
    }
    else
    {
        g_logger.error("Unkown remote message:\n%s", QString::fromUtf8(message));
    }
}
void PointViewerMainWindow::handleMessage(QByteArray message)
{
    QList<QByteArray> commandTokens = message.split('\n');
    if (commandTokens.empty())
        return;
    if (commandTokens[0] == "OPEN_FILES")
    {
        QList<QByteArray> flags = commandTokens[1].split('\0');
        if (flags.contains("CLEAR"))
            m_geometries->clear();
        bool rmTemp = flags.contains("RMTEMP");
        for (int i = 2; i < commandTokens.size(); ++i)
        {
            QList<QByteArray> pathAndLabel = commandTokens[i].split('\0');
            if (pathAndLabel.size() != 2)
            {
                g_logger.error("Unrecognized OPEN_FILES token: %s",
                               QString(commandTokens[i]));
                continue;
            }
            m_fileLoader->loadFile(FileLoadInfo(pathAndLabel[0], pathAndLabel[1], rmTemp));
        }
    }
    else if (commandTokens[0] == "CLEAR_FILES")
    {
        m_geometries->clear();
    }
    else if (commandTokens[0] == "UNLOAD_FILES")
    {
        QString regex_str = commandTokens[1];
        QRegExp regex(regex_str, Qt::CaseSensitive, QRegExp::WildcardUnix);
        if (!regex.isValid())
        {
            g_logger.error("Invalid pattern in -unload command: '%s': %s",
                           regex_str, regex.errorString());
            return;
        }
        m_geometries->unloadFiles(regex);
    }
    else if (commandTokens[0] == "SET_VIEW_POSITION")
    {
        if (commandTokens.size()-1 != 3)
        {
            tfm::format(std::cerr, "Expected three coordinates, got %d\n",
                        commandTokens.size()-1);
            return;
        }
        bool xOk = false, yOk = false, zOk = false;
        double x = commandTokens[1].toDouble(&xOk);
        double y = commandTokens[2].toDouble(&yOk);
        double z = commandTokens[3].toDouble(&zOk);
        if (!zOk || !yOk || !zOk)
        {
            std::cerr << "Could not parse XYZ coordinates for position\n";
            return;
        }
        m_pointView->setExplicitCursorPos(Imath::V3d(x, y, z));
    }
    else if (commandTokens[0] == "SET_VIEW_ANGLES")
    {
        if (commandTokens.size()-1 != 3)
        {
            tfm::format(std::cerr, "Expected three view angles, got %d\n",
                        commandTokens.size()-1);
            return;
        }
        bool yawOk = false, pitchOk = false, rollOk = false;
        double yaw   = commandTokens[1].toDouble(&yawOk);
        double pitch = commandTokens[2].toDouble(&pitchOk);
        double roll  = commandTokens[3].toDouble(&rollOk);
        if (!yawOk || !pitchOk || !rollOk)
        {
            std::cerr << "Could not parse Euler angles for view\n";
            return;
        }
        m_pointView->camera().setRotation(
            QQuaternion::fromAxisAndAngle(0,0,1, roll)  *
            QQuaternion::fromAxisAndAngle(1,0,0, pitch-90) *
            QQuaternion::fromAxisAndAngle(0,0,1, yaw)
        );
    }
    else if (commandTokens[0] == "SET_VIEW_RADIUS")
    {
        bool ok = false;
        double viewRadius = commandTokens[1].toDouble(&ok);
        if (!ok)
        {
            std::cerr << "Could not parse view radius";
            return;
        }
        m_pointView->camera().setEyeToCenterDistance(viewRadius);
    }
    else if (commandTokens[0] == "QUERY_CURSOR")
    {
        // Yuck!
        IpcChannel* channel = dynamic_cast<IpcChannel*>(sender());
        if (!channel)
        {
            qWarning() << "Signalling object not a IpcChannel!\n";
            return;
        }
        V3d p = m_pointView->cursorPos();
        std::string response = tfm::format("%.15g %.15g %.15g", p.x, p.y, p.z);
        channel->sendMessage(QByteArray(response.data(), (int)response.size()));
    }
    else if (commandTokens[0] == "QUIT")
    {
        close();
    }
    else if (commandTokens[0] == "SET_MAX_POINT_COUNT")
    {
        m_maxPointCount = commandTokens[1].toLongLong();
    }
    else if (commandTokens[0] == "OPEN_SHADER")
    {
        openShaderFile(commandTokens[1]);
    }
    else
    {
        g_logger.error("Unkown remote message:\n%s", QString::fromUtf8(message));
    }
}