<commit_before>/**
 * \file
 * <!--
 * Copyright 2015 Develer S.r.l. (http://www.develer.com/)
 * -->
 *
 * \brief Serial port connection and settings dialog
 *
 * \author Aurelien Rainone <aurelien@develer.org>
 */

#include "connectdialog.h"
#include "ui_connectdialog.h"

#include <QList>
#include <QHash>
#include <QtSerialPort>
#include <QSerialPortInfo>

ConnectDialog::ConnectDialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::ConnectDialog)
{
    ui->setupUi(this);

    // fill the combo box values
    fillSettingsLists();

    // for device take 1st device listed (if any)
    QString default_device;
    if (ui->deviceList->count() > 0)
        default_device = ui->deviceList->itemText(0);

    // define a default configuration
    QHash<QString, QString> default_cfg;
    default_cfg[QStringLiteral("device")] = default_device;
    default_cfg[QStringLiteral("baud_rate")] = QString::number(QSerialPort::Baud115200);
    default_cfg[QStringLiteral("data_bits")] = QString::number(QSerialPort::Data8);
    default_cfg[QStringLiteral("stop_bits")] = QStringLiteral("1");
    default_cfg[QStringLiteral("parity")] = QStringLiteral("None");
    default_cfg[QStringLiteral("flow_control")] = QStringLiteral("None");

    // define the default values for output dump
    default_cfg[QStringLiteral("dump_enabled")] = QString::number(0);
    default_cfg[QStringLiteral("dump_file")] = QStringLiteral("cutecom-ng.dump");
    default_cfg[QStringLiteral("dump_format")] = QString::number(Raw);

    preselectPortConfig(default_cfg);
}

ConnectDialog::~ConnectDialog()
{
    delete ui;
}

void ConnectDialog::fillSettingsLists()
{
    // fill devices combo box
    QList<QSerialPortInfo> ports(QSerialPortInfo::availablePorts());
    for (int idx = 0; idx < ports.length(); ++idx)
    {
        const QSerialPortInfo& port_info = ports.at(idx);
        ui->deviceList->addItem(port_info.portName());

        // construct description tooltip
        QString tooltip;

        // add decription if not empty
        if (!port_info.description().isEmpty())
            tooltip.append(port_info.description());
        if (!port_info.manufacturer().isEmpty())
        {
            // add ' / manufacturer' if not empty
            if (!tooltip.isEmpty())
                tooltip.push_back(QStringLiteral(" / "));
            tooltip.append(port_info.description());
        }
        // assign portName
        if (tooltip.isEmpty())
            tooltip = port_info.portName();

        ui->deviceList->setItemData(idx, tooltip, Qt::ToolTipRole);
    }

    // fill baud rates combo box
    QStringList baud_rates;
    baud_rates <<
        QString::number(QSerialPort::Baud1200) << QString::number(QSerialPort::Baud2400);
    baud_rates <<
        QString::number(QSerialPort::Baud4800) << QString::number(QSerialPort::Baud9600);
    baud_rates <<
        QString::number(QSerialPort::Baud19200) << QString::number(QSerialPort::Baud38400);
    baud_rates <<
        QString::number(QSerialPort::Baud57600) << QString::number(QSerialPort::Baud115200);
    ui->baudRateList->addItems(baud_rates);

    // fill data bits combo box
    QStringList data_bits;
    data_bits <<
        QString::number(QSerialPort::Data5) << QString::number(QSerialPort::Data6);
    data_bits <<
        QString::number(QSerialPort::Data7) << QString::number(QSerialPort::Data8);
    ui->dataBitsList->addItems(data_bits);

    // fill stop bits combo box
    ui->stopBitsList->addItem("1", QSerialPort::OneStop);
#ifdef Q_WS_WIN
    ui->stopBitsList->addItem("1.5", QSerialPort::OneAndHalfStop);
#endif
    ui->stopBitsList->addItem("2", QSerialPort::TwoStop);

    // fill parity combo box
    ui->parityList->addItem("None", QSerialPort::NoParity);
    ui->parityList->addItem("Even", QSerialPort::EvenParity);
    ui->parityList->addItem("Odd", QSerialPort::OddParity);
    ui->parityList->addItem("Space", QSerialPort::SpaceParity);
    ui->parityList->addItem("Mark", QSerialPort::MarkParity);

    // fill flow control
    ui->flowControlList->addItem("None", QSerialPort::NoFlowControl);
    ui->flowControlList->addItem("Hardware", QSerialPort::HardwareControl);
    ui->flowControlList->addItem("Software", QSerialPort::SoftwareControl);
}

void ConnectDialog::preselectPortConfig(const QHash<QString, QString>& settings)
{
    ui->deviceList->setCurrentText(settings[QStringLiteral("device")]);
    ui->baudRateList->setCurrentText(settings[QStringLiteral("baud_rate")]);
    ui->dataBitsList->setCurrentText(settings[QStringLiteral("data_bits")]);
    ui->stopBitsList->setCurrentText(settings[QStringLiteral("stop_bits")]);

    ui->parityList->setCurrentText(settings[QStringLiteral("parity")]);
    ui->flowControlList->setCurrentText(settings[QStringLiteral("flow_control")]);

    ui->dumpFile->setChecked(settings[QStringLiteral("dump_enabled")] == "1");
    ui->dumpPath->setText(settings[QStringLiteral("dump_file")]);
    ui->dumpRawFmt->setChecked(settings["dump_format"] == QString::number(Raw));
    ui->dumpTextFmt->setChecked(settings["dump_format"] == QString::number(Ascii));
}

void ConnectDialog::accept()
{
    // create a serial port config object from current selection
    QHash<QString, QString> cfg;
    cfg["device"] = ui->deviceList->currentText();
    cfg["baud_rate"] = ui->baudRateList->currentText();
    cfg["data_bits"] = ui->dataBitsList->currentText();
    cfg["stop_bits"] = ui->stopBitsList->itemData(
                ui->stopBitsList->currentIndex()).toString();
    cfg["parity"] = ui->parityList->itemData(
                ui->parityList->currentIndex()).toString();
    cfg["flow_control"] = ui->flowControlList->itemData(
                ui->flowControlList->currentIndex()).toString();
    cfg["dump_enabled"] = ui->dumpFile->isChecked() ? "1" : "0";
    cfg["dump_file"] = ui->dumpPath->text();
    cfg["dump_format"] = QString::number(ui->dumpRawFmt->isChecked() ? Raw : Ascii);

    hide();

    emit openDeviceClicked(cfg);
}
<commit_msg>copy-paste typo<commit_after>/**
 * \file
 * <!--
 * Copyright 2015 Develer S.r.l. (http://www.develer.com/)
 * -->
 *
 * \brief Serial port connection and settings dialog
 *
 * \author Aurelien Rainone <aurelien@develer.org>
 */

#include "connectdialog.h"
#include "ui_connectdialog.h"

#include <QList>
#include <QHash>
#include <QtSerialPort>
#include <QSerialPortInfo>

ConnectDialog::ConnectDialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::ConnectDialog)
{
    ui->setupUi(this);

    // fill the combo box values
    fillSettingsLists();

    // for device take 1st device listed (if any)
    QString default_device;
    if (ui->deviceList->count() > 0)
        default_device = ui->deviceList->itemText(0);

    // define a default configuration
    QHash<QString, QString> default_cfg;
    default_cfg[QStringLiteral("device")] = default_device;
    default_cfg[QStringLiteral("baud_rate")] = QString::number(QSerialPort::Baud115200);
    default_cfg[QStringLiteral("data_bits")] = QString::number(QSerialPort::Data8);
    default_cfg[QStringLiteral("stop_bits")] = QStringLiteral("1");
    default_cfg[QStringLiteral("parity")] = QStringLiteral("None");
    default_cfg[QStringLiteral("flow_control")] = QStringLiteral("None");

    // define the default values for output dump
    default_cfg[QStringLiteral("dump_enabled")] = QString::number(0);
    default_cfg[QStringLiteral("dump_file")] = QStringLiteral("cutecom-ng.dump");
    default_cfg[QStringLiteral("dump_format")] = QString::number(Raw);

    preselectPortConfig(default_cfg);
}

ConnectDialog::~ConnectDialog()
{
    delete ui;
}

void ConnectDialog::fillSettingsLists()
{
    // fill devices combo box
    QList<QSerialPortInfo> ports(QSerialPortInfo::availablePorts());
    for (int idx = 0; idx < ports.length(); ++idx)
    {
        const QSerialPortInfo& port_info = ports.at(idx);
        ui->deviceList->addItem(port_info.portName());

        // construct description tooltip
        QString tooltip;

        // add decription if not empty
        if (!port_info.description().isEmpty())
            tooltip.append(port_info.description());
        if (!port_info.manufacturer().isEmpty())
        {
            // add ' / manufacturer' if not empty
            if (!tooltip.isEmpty())
                tooltip.push_back(QStringLiteral(" / "));
            tooltip.append(port_info.manufacturer());
        }
        // assign portName
        if (tooltip.isEmpty())
            tooltip = port_info.portName();

        ui->deviceList->setItemData(idx, tooltip, Qt::ToolTipRole);
    }

    // fill baud rates combo box
    QStringList baud_rates;
    baud_rates <<
        QString::number(QSerialPort::Baud1200) << QString::number(QSerialPort::Baud2400);
    baud_rates <<
        QString::number(QSerialPort::Baud4800) << QString::number(QSerialPort::Baud9600);
    baud_rates <<
        QString::number(QSerialPort::Baud19200) << QString::number(QSerialPort::Baud38400);
    baud_rates <<
        QString::number(QSerialPort::Baud57600) << QString::number(QSerialPort::Baud115200);
    ui->baudRateList->addItems(baud_rates);

    // fill data bits combo box
    QStringList data_bits;
    data_bits <<
        QString::number(QSerialPort::Data5) << QString::number(QSerialPort::Data6);
    data_bits <<
        QString::number(QSerialPort::Data7) << QString::number(QSerialPort::Data8);
    ui->dataBitsList->addItems(data_bits);

    // fill stop bits combo box
    ui->stopBitsList->addItem("1", QSerialPort::OneStop);
#ifdef Q_WS_WIN
    ui->stopBitsList->addItem("1.5", QSerialPort::OneAndHalfStop);
#endif
    ui->stopBitsList->addItem("2", QSerialPort::TwoStop);

    // fill parity combo box
    ui->parityList->addItem("None", QSerialPort::NoParity);
    ui->parityList->addItem("Even", QSerialPort::EvenParity);
    ui->parityList->addItem("Odd", QSerialPort::OddParity);
    ui->parityList->addItem("Space", QSerialPort::SpaceParity);
    ui->parityList->addItem("Mark", QSerialPort::MarkParity);

    // fill flow control
    ui->flowControlList->addItem("None", QSerialPort::NoFlowControl);
    ui->flowControlList->addItem("Hardware", QSerialPort::HardwareControl);
    ui->flowControlList->addItem("Software", QSerialPort::SoftwareControl);
}

void ConnectDialog::preselectPortConfig(const QHash<QString, QString>& settings)
{
    ui->deviceList->setCurrentText(settings[QStringLiteral("device")]);
    ui->baudRateList->setCurrentText(settings[QStringLiteral("baud_rate")]);
    ui->dataBitsList->setCurrentText(settings[QStringLiteral("data_bits")]);
    ui->stopBitsList->setCurrentText(settings[QStringLiteral("stop_bits")]);

    ui->parityList->setCurrentText(settings[QStringLiteral("parity")]);
    ui->flowControlList->setCurrentText(settings[QStringLiteral("flow_control")]);

    ui->dumpFile->setChecked(settings[QStringLiteral("dump_enabled")] == "1");
    ui->dumpPath->setText(settings[QStringLiteral("dump_file")]);
    ui->dumpRawFmt->setChecked(settings["dump_format"] == QString::number(Raw));
    ui->dumpTextFmt->setChecked(settings["dump_format"] == QString::number(Ascii));
}

void ConnectDialog::accept()
{
    // create a serial port config object from current selection
    QHash<QString, QString> cfg;
    cfg["device"] = ui->deviceList->currentText();
    cfg["baud_rate"] = ui->baudRateList->currentText();
    cfg["data_bits"] = ui->dataBitsList->currentText();
    cfg["stop_bits"] = ui->stopBitsList->itemData(
                ui->stopBitsList->currentIndex()).toString();
    cfg["parity"] = ui->parityList->itemData(
                ui->parityList->currentIndex()).toString();
    cfg["flow_control"] = ui->flowControlList->itemData(
                ui->flowControlList->currentIndex()).toString();
    cfg["dump_enabled"] = ui->dumpFile->isChecked() ? "1" : "0";
    cfg["dump_file"] = ui->dumpPath->text();
    cfg["dump_format"] = QString::number(ui->dumpRawFmt->isChecked() ? Raw : Ascii);

    hide();

    emit openDeviceClicked(cfg);
}
<|endoftext|>


<commit_before>#include "libisbn.hpp"
#include <algorithm>
#include <iostream>
#include <stdexcept>

//enum class ReturnCode;

constexpr int to_int(char x) noexcept {
    return x - '0';
}

constexpr char to_char(int x) noexcept {
    return x + '0';
}

char _digit13(const std::string &twelve) {

    static int weights[12] = {1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3};

    int digit = 0;

    for (std::size_t i = 0; i < 12; ++i) {
        digit += to_int(twelve[i]) * weights[i];
    }
    digit = 10 - (digit % 10);
    return digit == 10 ? '0' : to_char(digit);

}

char _digit10(const std::string &nine) {
    static int weights[9] = {10, 9, 8, 7, 6, 5, 4, 3, 2};

    int digit = 0;

    for (int i = 0; i < 9; ++i) {
        digit += to_int(nine[i]) * weights[i];
    }

    digit = (11 - (digit % 11)) % 11;

    return digit == 10 ? 'X' : to_char(digit);

}

bool libisbn::is_isbn13(std::string string) {
    static std::string a1{"978"}, a2{"979"};

    clean(string);
    if (string.length() != 13) {
        return false;
    }

    std::string p = string.substr(0, 3);

    if (p != a1 && p != a2) {

        return false;
    }

    return _digit13(string.substr(0, 12)) == string.back();

}

bool libisbn::is_isbn10(std::string string) {

    clean(string);

    if (string.length() != 10) {
        return false;
    }

    int i, s = 0, t = 0;

    for (i = 0; i < 10; ++i) {
        char c = string[i];
        int d = c == 'X' ? 10 : to_int(c);
        t += d;
        s += t;
    }
    return (11 - (s % 11)) % 11 == 0;

}

void libisbn::clean(std::string &s) {

    s.erase(std::remove_if(s.begin(), s.end(), [](char x) {
        return !std::isdigit(x) && !(x == 'x' || x == 'X');
    }), s.end());

    // if isbn10 make last character uppercase
    if (s.back() == 'x' && s.length() == 10) {
        s.back() = 'X';

    }

}

bool libisbn::validate(std::string string) {
    return is_isbn10(string) || is_isbn13(string);
}

std::string libisbn::to_isbn10(std::string isbn) {

    static std::string valid_prefix{"978"};

    clean(isbn);

    if (is_isbn10(isbn)) {
        return isbn;
    }

    if (!is_isbn13(isbn) || isbn.substr(0, 3) != valid_prefix) {

        throw std::invalid_argument(std::string(isbn + std::string{" is not a valid ISBN13"}));

    }

    std::string isbn10{isbn, 3, 9};

    isbn10.append(1, _digit10(isbn10));

    return isbn10;
}

std::string libisbn::to_isbn13(std::string isbn) {

    clean(isbn);

    if (is_isbn13(isbn)) {
        return isbn;
    }

    if (!is_isbn10(isbn)) {
        throw std::invalid_argument(std::string(isbn + std::string{" is not a valid ISBN10"}));
    }

    std::string isbn13{"978" + isbn.substr(0, 9)};

    isbn13.append(1, _digit13(isbn13));

    return isbn13;

}
<commit_msg>extract some constants go back to original ISBN10 verification algorithm<commit_after>#include "libisbn.hpp"
#include <algorithm>
#include <iostream>
#include <stdexcept>
#include <array>

constexpr int to_int(char x) noexcept {
    return x - '0';
}

constexpr char to_char(int x) noexcept {
    return x + '0';
}

constexpr std::array<int, 12> ISBN13_W {{1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3}};

constexpr std::array<int, 9> ISBN10_W {{10, 9, 8, 7, 6, 5, 4, 3, 2}};

constexpr auto VALID_ISBN13_PREFIX = "978"; // only ISBN13 with this prefix can be converted to ISBN10

char _digit13(const std::string &twelve) {
    int digit = 0;

    for (std::size_t i = 0; i < 12; ++i) {
        digit += to_int(twelve[i]) * ISBN13_W[i];
    }
    digit = 10 - (digit % 10);
    return digit == 10 ? '0' : to_char(digit);

}

char _digit10(const std::string &nine) {
    int digit = 0;

    for (int i = 0; i < 9; ++i) {
        digit += to_int(nine[i]) * ISBN10_W[i];
    }

    digit = (11 - (digit % 11)) % 11;

    return digit == 10 ? 'X' : to_char(digit);

}

bool libisbn::is_isbn13(std::string string) {
    static std::string a1{VALID_ISBN13_PREFIX}, a2{"979"};

    clean(string);
    if (string.length() != 13) {
        return false;
    }

    std::string p = string.substr(0, 3);

    if (p != a1 && p != a2) {

        return false;
    }

    return _digit13(string.substr(0, 12)) == string.back();

}

bool libisbn::is_isbn10(std::string string) {

    clean(string);

    if (string.length() != 10) {
        return false;
    }

    return _digit10(string.substr(0, 9)) == string.back();

}

void libisbn::clean(std::string &s) {

    s.erase(std::remove_if(s.begin(), s.end(), [](char x) {
        return !std::isdigit(x) && !(x == 'x' || x == 'X');
    }), s.end());

    // if isbn10 make last character uppercase
    if (s.back() == 'x' && s.length() == 10) {
        s.back() = 'X';

    }

}

bool libisbn::validate(std::string string) {
    return is_isbn10(string) || is_isbn13(string);
}

std::string libisbn::to_isbn10(std::string isbn) {

    static std::string valid_prefix{VALID_ISBN13_PREFIX};

    clean(isbn);

    if (is_isbn10(isbn)) {
        return isbn;
    }

    if (!is_isbn13(isbn) || isbn.substr(0, 3) != valid_prefix) {

        throw std::invalid_argument(std::string(isbn + std::string{" is not a valid ISBN13"}));

    }

    std::string isbn10{isbn, 3, 9};

    isbn10.append(1, _digit10(isbn10));

    return isbn10;
}

std::string libisbn::to_isbn13(std::string isbn) {

    clean(isbn);

    if (is_isbn13(isbn)) {
        return isbn;
    }

    if (!is_isbn10(isbn)) {
        throw std::invalid_argument(std::string(isbn + std::string{" is not a valid ISBN10"}));
    }

    std::string isbn13{"978" + isbn.substr(0, 9)};

    isbn13.append(1, _digit13(isbn13));

    return isbn13;

}
<|endoftext|>


<commit_before>// Copyright (C) 2008 Till Busch buti@bux.at
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

#ifdef HAVE_CONFIG_H
#  include <simgear_config.h>
#endif

#include <osgDB/ReadFile>
#include <osgDB/Input>
#include <osgDB/ParameterOutput>
#include <osgDB/DatabasePager>

#include <simgear/debug/logstream.hxx>
#include <simgear/structure/OSGVersion.hxx>

#include "modellib.hxx"
#include "SGReaderWriterXMLOptions.hxx"
#include "SGPagedLOD.hxx"

#include <simgear/math/SGMath.hxx>

using namespace osg;
using namespace simgear;

SGPagedLOD::SGPagedLOD()
        : PagedLOD()
{
}

SGPagedLOD::~SGPagedLOD()
{
    //SG_LOG(SG_GENERAL, SG_ALERT, "SGPagedLOD::~SGPagedLOD(" << getFileName(0) << ")");
}

SGPagedLOD::SGPagedLOD(const SGPagedLOD& plod,const CopyOp& copyop)
        : osg::PagedLOD(plod, copyop),
        _readerWriterOptions(plod._readerWriterOptions)
{
}

bool SGPagedLOD::addChild(osg::Node *child)
{
    if (!PagedLOD::addChild(child))
        return false;

    setRadius(getBound().radius());
    setCenter(getBound().center());
    return true;
}

void SGPagedLOD::forceLoad(osgDB::DatabasePager *dbp, osg::FrameStamp* framestamp)
{
    //SG_LOG(SG_GENERAL, SG_ALERT, "SGPagedLOD::forceLoad(" <<
    //getFileName(getNumChildren()) << ")");
    unsigned childNum = getNumChildren();
    setTimeStamp(childNum, 0);
    double priority=1.0;
    dbp->requestNodeFile(getFileName(childNum),this,priority,framestamp,
                         getDatabaseRequest(childNum),
                         _readerWriterOptions.get());
}

bool SGPagedLOD_writeLocalData(const Object& obj, osgDB::Output& fw)
{
    return true;
}

namespace
{
osgDB::RegisterDotOsgWrapperProxy sgPagedLODProxy
(
    new SGPagedLOD,
    "simgear::SGPagedLOD",
    "Object Node LOD PagedLOD SGPagedLOD Group",
    0,
    &SGPagedLOD_writeLocalData
    );
}
<commit_msg>Temporary warning when compiling against OSG 2.9.11. Current OSG development isn't supported by FG yet, so add a warning for now...<commit_after>// Copyright (C) 2008 Till Busch buti@bux.at
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

#ifdef HAVE_CONFIG_H
#  include <simgear_config.h>
#endif

#include <osgDB/ReadFile>
#include <osgDB/Input>
#include <osgDB/ParameterOutput>
#include <osgDB/DatabasePager>

#include <simgear/debug/logstream.hxx>
#include <simgear/structure/OSGVersion.hxx>

#include "modellib.hxx"
#include "SGReaderWriterXMLOptions.hxx"
#include "SGPagedLOD.hxx"

#include <simgear/math/SGMath.hxx>

using namespace osg;
using namespace simgear;

SGPagedLOD::SGPagedLOD()
        : PagedLOD()
{
}

SGPagedLOD::~SGPagedLOD()
{
    //SG_LOG(SG_GENERAL, SG_ALERT, "SGPagedLOD::~SGPagedLOD(" << getFileName(0) << ")");
}

SGPagedLOD::SGPagedLOD(const SGPagedLOD& plod,const CopyOp& copyop)
        : osg::PagedLOD(plod, copyop),
        _readerWriterOptions(plod._readerWriterOptions)
{
}

bool SGPagedLOD::addChild(osg::Node *child)
{
    if (!PagedLOD::addChild(child))
        return false;

    setRadius(getBound().radius());
    setCenter(getBound().center());
    return true;
}

void SGPagedLOD::forceLoad(osgDB::DatabasePager *dbp, osg::FrameStamp* framestamp)
{
    //SG_LOG(SG_GENERAL, SG_ALERT, "SGPagedLOD::forceLoad(" <<
    //getFileName(getNumChildren()) << ")");
    unsigned childNum = getNumChildren();
    setTimeStamp(childNum, 0);
    double priority=1.0;
#if SG_OSG_MIN_VERSION_REQUIRED(2,9,11)
    // osgDB::DatabasePager::requestNodeFile changed with OSG 2.9.11

    #ifdef __GNUC__
        #warning !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        #warning !! Your version of OpenSceneGraph is currently unsupported.
        #warning !! Use latest stable OSG (2.8.3) or a OSG developer release up to 2.9.10.
        #warning !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    #else
        // Alas! Why is MSVC different (again)? :)
        #pragma WARNING( Your version of OpenSceneGraph is currently unsupported. )
        #pragma WARNING( Use latest stable OSG (2.8.3) or a OSG developer release up to 2.9.10. )
    #endif

    //TODO We need to adapt to OSG 2.9.11 (and future releases). This doesn't work yet...
    dbp->requestNodeFile(getFileName(childNum),this,priority,framestamp,
                         getDatabaseRequest(childNum),
                         _readerWriterOptions.get());
#else
    // OSG revisions up to 2.9.10
    dbp->requestNodeFile(getFileName(childNum),this,priority,framestamp,
                         getDatabaseRequest(childNum),
                         _readerWriterOptions.get());
#endif
}

bool SGPagedLOD_writeLocalData(const Object& obj, osgDB::Output& fw)
{
    return true;
}

namespace
{
osgDB::RegisterDotOsgWrapperProxy sgPagedLODProxy
(
    new SGPagedLOD,
    "simgear::SGPagedLOD",
    "Object Node LOD PagedLOD SGPagedLOD Group",
    0,
    &SGPagedLOD_writeLocalData
    );
}
<|endoftext|>


<commit_before>/*
    Copyright (C) 2014  David Edmundson <kde@davidedmundson.co.uk>
    Copyright (C) 2014  Alexandr Akulich <akulichalexander@gmail.com>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
*/

#include "contact-cache.h"

#include <KTp/core.h>
#include <KTp/contact.h>

#include <TelepathyQt/Account>
#include <TelepathyQt/AccountManager>
#include <TelepathyQt/AvatarData>
#include <TelepathyQt/Connection>
#include <TelepathyQt/ContactManager>
#include <TelepathyQt/PendingOperation>
#include <TelepathyQt/PendingReady>

#include <KDebug>
#include <KGlobal>
#include <KStandardDirs>

#include <QSqlQuery>
#include <QSqlDriver>
#include <QSqlField>

/*
 * This class waits for a connection to load then saves the pernament
 * data from all contacts into a database that can be loaded by the kpeople plugin
 * It will not stay up-to-date, applications should load from the database, then
 * fetch volatile and up-to-date data from TpQt
 *
 * We don't hold a reference to the contact to keep things light
 */

inline QString formatString(const QSqlQuery &query, const QString &str)
{
    QSqlField f(QLatin1String(""), QVariant::String);
    f.setValue(str);
    return query.driver()->formatValue(f);
}

ContactCache::ContactCache(QObject *parent):
    QObject(parent),
    m_db(QSqlDatabase::addDatabase(QLatin1String("QSQLITE")))
{
    m_db.setDatabaseName(KGlobal::dirs()->locateLocal("data", QLatin1String("ktp/cache.db")));
    m_db.open();

    if (!m_db.tables().contains(QLatin1String("contacts"))) {
        QSqlQuery createTables(m_db);
        createTables.exec(QLatin1String("CREATE TABLE contacts (accountID VARCHAR NOT NULL, contactID VARCHAR NOT NULL, alias VARCHAR, avatarFileName VARCHAR);"));
        createTables.exec(QLatin1String("CREATE UNIQUE INDEX idIndex ON contacts (accountId, contactId);"));
    }

    connect(KTp::accountManager()->becomeReady(), SIGNAL(finished(Tp::PendingOperation*)), SLOT(onAccountManagerReady(Tp::PendingOperation*)));
}

void ContactCache::onAccountManagerReady(Tp::PendingOperation *op)
{
    if (!op || op->isError()) {
        kWarning() << "ContactCache: Failed to initialize AccountManager:" << op->errorName();
        kWarning() << op->errorMessage();

        return;
    }

    connect(KTp::accountManager().data(), SIGNAL(newAccount(Tp::AccountPtr)), SLOT(onNewAccount(Tp::AccountPtr)));

    QSqlQuery purgeQuery(m_db);
    QStringList formattedAccountsIds;

    Q_FOREACH (const Tp::AccountPtr &account, KTp::accountManager()->allAccounts()) {
        if (!accountIsInteresting(account)) {
            continue;
        }

        connectToAccount(account);
        if (!account->connection().isNull()) {
            onAccountConnectionChanged(account->connection());
        }

        formattedAccountsIds.append(formatString(purgeQuery, account->uniqueIdentifier()));
    }

    if (formattedAccountsIds.isEmpty()) {
        purgeQuery.prepare(QLatin1String("DELETE * FROM contacts;"));
    } else {
        purgeQuery.prepare(QString(QLatin1String("DELETE FROM contacts WHERE accountID not in (%1);")).arg(formattedAccountsIds.join(QLatin1String(","))));
    }
    purgeQuery.exec();
}

void ContactCache::onNewAccount(const Tp::AccountPtr &account)
{
    if (!accountIsInteresting(account)) {
        return;
    }

    connectToAccount(account);
    if (!account->connection().isNull()) {
        onAccountConnectionChanged(account->connection());
    }
}

void ContactCache::onAccountRemoved()
{
    Tp::Account *account = qobject_cast<Tp::Account*>(sender());

    if (!account) {
        return;
    }

    QSqlQuery purgeQuery(m_db);
    purgeQuery.prepare(QLatin1String("DELETE FROM contacts WHERE accountID = ?;"));
    purgeQuery.bindValue(0, account->uniqueIdentifier());
    purgeQuery.exec();
}

void ContactCache::onContactManagerStateChanged()
{
    Tp::ContactManagerPtr contactManager(qobject_cast<Tp::ContactManager*>(sender()));
    checkContactManagerState(Tp::ContactManagerPtr(contactManager));
}

void ContactCache::onAccountConnectionChanged(const Tp::ConnectionPtr &connection)
{
    if (connection.isNull() || (connection->status() != Tp::ConnectionStatusConnected)) {
        return;
    }

    if (connect(connection->contactManager().data(), SIGNAL(stateChanged(Tp::ContactListState)), this, SLOT(onContactManagerStateChanged()), Qt::UniqueConnection)) {
        /* Check current contactManager state and do sync contact only if it is not performed due to already connected contactManager. */
        checkContactManagerState(connection->contactManager());
    }
}

void ContactCache::onAllKnownContactsChanged(const Tp::Contacts &added, const Tp::Contacts &removed)
{
    /* Delete both added and removed contacts, because it's faster than accurate comparsion and partial update of exist contacts. */
    Tp::Contacts toBeRemoved = added;
    toBeRemoved.unite(removed);

    m_db.transaction();
    QSqlQuery removeQuery(m_db);
    removeQuery.prepare(QLatin1String("DELETE FROM contacts WHERE accountId = ? AND contactId = ?;"));
    Q_FOREACH (const Tp::ContactPtr &c, toBeRemoved) {
        const KTp::ContactPtr &contact = KTp::ContactPtr::qObjectCast(c);
        removeQuery.bindValue(0, contact->accountUniqueIdentifier());
        removeQuery.bindValue(1, contact->id());
        removeQuery.exec();
    }

    QSqlQuery insertQuery(m_db);
    insertQuery.prepare(QLatin1String("INSERT INTO contacts (accountId, contactId, alias, avatarFileName) VALUES (?, ?, ?, ?);"));
    Q_FOREACH (const Tp::ContactPtr &c, added) {
        if (c->manager()->connection()->protocolName() == QLatin1String("local-xmpp")) {
            continue;
        }

        const KTp::ContactPtr &contact = KTp::ContactPtr::qObjectCast(c);
        insertQuery.bindValue(0, contact->accountUniqueIdentifier());
        insertQuery.bindValue(1, contact->id());
        insertQuery.bindValue(2, contact->alias());
        insertQuery.bindValue(3, contact->avatarData().fileName);
        insertQuery.exec();
    }

    m_db.commit();
}

void ContactCache::connectToAccount(const Tp::AccountPtr &account)
{
    connect(account.data(), SIGNAL(removed()), SLOT(onAccountRemoved()));
    connect(account.data(), SIGNAL(connectionChanged(Tp::ConnectionPtr)), SLOT(onAccountConnectionChanged(Tp::ConnectionPtr)));
}

bool ContactCache::accountIsInteresting(const Tp::AccountPtr &account) const
{
    if (account->protocolName() == QLatin1String("local-xmpp")) {// We don't want to cache local-xmpp contacts
        return false;
    }

    /* There may be more filters. */

    return true;
}

void ContactCache::syncContactsOfAccount(const Tp::AccountPtr &account)
{
    m_db.transaction();
    QSqlQuery purgeQuery(m_db);
    purgeQuery.prepare(QLatin1String("DELETE FROM contacts WHERE accountID = ?;"));
    purgeQuery.bindValue(0, account->uniqueIdentifier());
    purgeQuery.exec();

    QSqlQuery insertQuery(m_db);
    insertQuery.prepare(QLatin1String("INSERT INTO contacts (accountId, contactId, alias, avatarFileName) VALUES (?, ?, ?, ?);"));
    Q_FOREACH (const Tp::ContactPtr &c, account->connection()->contactManager()->allKnownContacts()) {
        const KTp::ContactPtr &contact = KTp::ContactPtr::qObjectCast(c);
        insertQuery.bindValue(0, contact->accountUniqueIdentifier());
        insertQuery.bindValue(1, contact->id());
        insertQuery.bindValue(2, contact->alias());
        insertQuery.bindValue(3, contact->avatarData().fileName);
        insertQuery.exec();
    }

    m_db.commit();

    connect(account->connection()->contactManager().data(),
            SIGNAL(allKnownContactsChanged(Tp::Contacts,Tp::Contacts,Tp::Channel::GroupMemberChangeDetails)),
            SLOT(onAllKnownContactsChanged(Tp::Contacts,Tp::Contacts)), Qt::UniqueConnection);
}

void ContactCache::checkContactManagerState(const Tp::ContactManagerPtr &contactManager)
{
    if (contactManager->state() == Tp::ContactListStateSuccess) {
        const QString accountPath = TP_QT_ACCOUNT_OBJECT_PATH_BASE + QLatin1Char('/') + contactManager->connection()->property("accountUID").toString();
        Tp::AccountPtr account = KTp::accountManager()->accountForObjectPath(accountPath);
        if (!account.isNull()) {
            syncContactsOfAccount(account);
        } else {
            kWarning() << "Can't access to account by contactManager";
        }
    }
}
<commit_msg>Enforce roster is loaded<commit_after>/*
    Copyright (C) 2014  David Edmundson <kde@davidedmundson.co.uk>
    Copyright (C) 2014  Alexandr Akulich <akulichalexander@gmail.com>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
*/

#include "contact-cache.h"

#include <KTp/core.h>
#include <KTp/contact.h>

#include <TelepathyQt/Account>
#include <TelepathyQt/AccountManager>
#include <TelepathyQt/AvatarData>
#include <TelepathyQt/Connection>
#include <TelepathyQt/ContactManager>
#include <TelepathyQt/PendingOperation>
#include <TelepathyQt/PendingReady>

#include <KDebug>
#include <KGlobal>
#include <KStandardDirs>

#include <QSqlQuery>
#include <QSqlDriver>
#include <QSqlField>

/*
 * This class waits for a connection to load then saves the pernament
 * data from all contacts into a database that can be loaded by the kpeople plugin
 * It will not stay up-to-date, applications should load from the database, then
 * fetch volatile and up-to-date data from TpQt
 *
 * We don't hold a reference to the contact to keep things light
 */

inline QString formatString(const QSqlQuery &query, const QString &str)
{
    QSqlField f(QLatin1String(""), QVariant::String);
    f.setValue(str);
    return query.driver()->formatValue(f);
}

ContactCache::ContactCache(QObject *parent):
    QObject(parent),
    m_db(QSqlDatabase::addDatabase(QLatin1String("QSQLITE")))
{
    m_db.setDatabaseName(KGlobal::dirs()->locateLocal("data", QLatin1String("ktp/cache.db")));
    m_db.open();

    if (!m_db.tables().contains(QLatin1String("contacts"))) {
        QSqlQuery createTables(m_db);
        createTables.exec(QLatin1String("CREATE TABLE contacts (accountID VARCHAR NOT NULL, contactID VARCHAR NOT NULL, alias VARCHAR, avatarFileName VARCHAR);"));
        createTables.exec(QLatin1String("CREATE UNIQUE INDEX idIndex ON contacts (accountId, contactId);"));
    }

    connect(KTp::accountManager()->becomeReady(), SIGNAL(finished(Tp::PendingOperation*)), SLOT(onAccountManagerReady(Tp::PendingOperation*)));
}

void ContactCache::onAccountManagerReady(Tp::PendingOperation *op)
{
    if (!op || op->isError()) {
        kWarning() << "ContactCache: Failed to initialize AccountManager:" << op->errorName();
        kWarning() << op->errorMessage();

        return;
    }

    connect(KTp::accountManager().data(), SIGNAL(newAccount(Tp::AccountPtr)), SLOT(onNewAccount(Tp::AccountPtr)));

    QSqlQuery purgeQuery(m_db);
    QStringList formattedAccountsIds;

    Q_FOREACH (const Tp::AccountPtr &account, KTp::accountManager()->allAccounts()) {
        if (!accountIsInteresting(account)) {
            continue;
        }

        connectToAccount(account);
        if (!account->connection().isNull()) {
            onAccountConnectionChanged(account->connection());
        }

        formattedAccountsIds.append(formatString(purgeQuery, account->uniqueIdentifier()));
    }

    if (formattedAccountsIds.isEmpty()) {
        purgeQuery.prepare(QLatin1String("DELETE * FROM contacts;"));
    } else {
        purgeQuery.prepare(QString(QLatin1String("DELETE FROM contacts WHERE accountID not in (%1);")).arg(formattedAccountsIds.join(QLatin1String(","))));
    }
    purgeQuery.exec();
}

void ContactCache::onNewAccount(const Tp::AccountPtr &account)
{
    if (!accountIsInteresting(account)) {
        return;
    }

    connectToAccount(account);
    if (!account->connection().isNull()) {
        onAccountConnectionChanged(account->connection());
    }
}

void ContactCache::onAccountRemoved()
{
    Tp::Account *account = qobject_cast<Tp::Account*>(sender());

    if (!account) {
        return;
    }

    QSqlQuery purgeQuery(m_db);
    purgeQuery.prepare(QLatin1String("DELETE FROM contacts WHERE accountID = ?;"));
    purgeQuery.bindValue(0, account->uniqueIdentifier());
    purgeQuery.exec();
}

void ContactCache::onContactManagerStateChanged()
{
    Tp::ContactManagerPtr contactManager(qobject_cast<Tp::ContactManager*>(sender()));
    checkContactManagerState(Tp::ContactManagerPtr(contactManager));
}

void ContactCache::onAccountConnectionChanged(const Tp::ConnectionPtr &connection)
{
    if (connection.isNull() || (connection->status() != Tp::ConnectionStatusConnected)) {
        return;
    }

    //this is needed to make the contact manager roster
    //when this finishes the contact manager will change state
    connection->becomeReady(Tp::Connection::FeatureRoster);

    if (connect(connection->contactManager().data(), SIGNAL(stateChanged(Tp::ContactListState)), this, SLOT(onContactManagerStateChanged()), Qt::UniqueConnection)) {
        /* Check current contactManager state and do sync contact only if it is not performed due to already connected contactManager. */
        checkContactManagerState(connection->contactManager());
    }
}

void ContactCache::onAllKnownContactsChanged(const Tp::Contacts &added, const Tp::Contacts &removed)
{
    /* Delete both added and removed contacts, because it's faster than accurate comparsion and partial update of exist contacts. */
    Tp::Contacts toBeRemoved = added;
    toBeRemoved.unite(removed);

    m_db.transaction();
    QSqlQuery removeQuery(m_db);
    removeQuery.prepare(QLatin1String("DELETE FROM contacts WHERE accountId = ? AND contactId = ?;"));
    Q_FOREACH (const Tp::ContactPtr &c, toBeRemoved) {
        const KTp::ContactPtr &contact = KTp::ContactPtr::qObjectCast(c);
        removeQuery.bindValue(0, contact->accountUniqueIdentifier());
        removeQuery.bindValue(1, contact->id());
        removeQuery.exec();
    }

    QSqlQuery insertQuery(m_db);
    insertQuery.prepare(QLatin1String("INSERT INTO contacts (accountId, contactId, alias, avatarFileName) VALUES (?, ?, ?, ?);"));
    Q_FOREACH (const Tp::ContactPtr &c, added) {
        if (c->manager()->connection()->protocolName() == QLatin1String("local-xmpp")) {
            continue;
        }

        const KTp::ContactPtr &contact = KTp::ContactPtr::qObjectCast(c);
        insertQuery.bindValue(0, contact->accountUniqueIdentifier());
        insertQuery.bindValue(1, contact->id());
        insertQuery.bindValue(2, contact->alias());
        insertQuery.bindValue(3, contact->avatarData().fileName);
        insertQuery.exec();
    }

    m_db.commit();
}

void ContactCache::connectToAccount(const Tp::AccountPtr &account)
{
    connect(account.data(), SIGNAL(removed()), SLOT(onAccountRemoved()));
    connect(account.data(), SIGNAL(connectionChanged(Tp::ConnectionPtr)), SLOT(onAccountConnectionChanged(Tp::ConnectionPtr)));
}

bool ContactCache::accountIsInteresting(const Tp::AccountPtr &account) const
{
    if (account->protocolName() == QLatin1String("local-xmpp")) {// We don't want to cache local-xmpp contacts
        return false;
    }

    /* There may be more filters. */

    return true;
}

void ContactCache::syncContactsOfAccount(const Tp::AccountPtr &account)
{
    m_db.transaction();
    QSqlQuery purgeQuery(m_db);
    purgeQuery.prepare(QLatin1String("DELETE FROM contacts WHERE accountID = ?;"));
    purgeQuery.bindValue(0, account->uniqueIdentifier());
    purgeQuery.exec();

    QSqlQuery insertQuery(m_db);
    insertQuery.prepare(QLatin1String("INSERT INTO contacts (accountId, contactId, alias, avatarFileName) VALUES (?, ?, ?, ?);"));
    Q_FOREACH (const Tp::ContactPtr &c, account->connection()->contactManager()->allKnownContacts()) {
        const KTp::ContactPtr &contact = KTp::ContactPtr::qObjectCast(c);
        insertQuery.bindValue(0, contact->accountUniqueIdentifier());
        insertQuery.bindValue(1, contact->id());
        insertQuery.bindValue(2, contact->alias());
        insertQuery.bindValue(3, contact->avatarData().fileName);
        insertQuery.exec();
    }

    m_db.commit();

    connect(account->connection()->contactManager().data(),
            SIGNAL(allKnownContactsChanged(Tp::Contacts,Tp::Contacts,Tp::Channel::GroupMemberChangeDetails)),
            SLOT(onAllKnownContactsChanged(Tp::Contacts,Tp::Contacts)), Qt::UniqueConnection);
}

void ContactCache::checkContactManagerState(const Tp::ContactManagerPtr &contactManager)
{
    if (contactManager->state() == Tp::ContactListStateSuccess) {
        const QString accountPath = TP_QT_ACCOUNT_OBJECT_PATH_BASE + QLatin1Char('/') + contactManager->connection()->property("accountUID").toString();
        Tp::AccountPtr account = KTp::accountManager()->accountForObjectPath(accountPath);
        if (!account.isNull()) {
            syncContactsOfAccount(account);
        } else {
            kWarning() << "Can't access to account by contactManager";
        }
    }
}
<|endoftext|>


<commit_before>/*
  This file is provided under a dual BSD/GPLv2 license.  When using or
  redistributing this file, you may do so under either license.

  GPL LICENSE SUMMARY

  Copyright(c) 2005-2012 Intel Corporation. All rights reserved.

  This program is free software; you can redistribute it and/or modify
  it under the terms of version 2 of the GNU General Public License as
  published by the Free Software Foundation.

  This program is distributed in the hope that it will be useful, but
  WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  The full GNU General Public License is included in this distribution
  in the file called LICENSE.GPL.

  Contact Information:
  http://software.intel.com/en-us/articles/intel-vtune-amplifier-xe/

  BSD LICENSE

  Copyright(c) 2005-2012 Intel Corporation. All rights reserved.
  All rights reserved.

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions
  are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the
      distribution.
    * Neither the name of Intel Corporation nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <string.h>

#ifdef WIN32
#include <hash_map>
using namespace std;
#else
// To avoid GCC 4.4 compilation warning about hash_map being deprecated.
#define OLD_DEPRECATED __DEPRECATED
#undef __DEPRECATED
#include <ext/hash_map>
#define __DEPRECATED OLD_DEPRECATED
using namespace __gnu_cxx;
#endif

#include <list>

#include "v8-vtune.h"
#include "vtune-jit.h"

namespace vTune {
namespace internal {

// This class is used to record the JITted code position info for JIT
// code profiling.
class JITCodeLineInfo {
 public:
  JITCodeLineInfo() { }

  void SetPosition(intptr_t pc, int pos) {
    AddCodeLineInfo(LineNumInfo(pc, pos));
  }

  struct LineNumInfo {
    LineNumInfo(intptr_t pc, int pos)
        : pc_(pc), pos_(pos) { }

    intptr_t pc_;
    int pos_;
  };

  std::list<LineNumInfo>* GetLineNumInfo() {
    return &line_num_info_;
  }

 private:
  void AddCodeLineInfo(const LineNumInfo& line_info) {
	  line_num_info_.push_back(line_info);
  }
  std::list<LineNumInfo> line_num_info_;
};

struct SameCodeObjects {
  bool operator () (void* key1, void* key2) const {
    return key1 == key2;
  }
};

struct HashForCodeObject {
  uint32_t operator () (void* code) const {
    static const uintptr_t kGoldenRatio = 2654435761u;
    uintptr_t hash = reinterpret_cast<uintptr_t>(code);
    return static_cast<uint32_t>(hash * kGoldenRatio);
  }
};

#ifdef WIN32
typedef hash_map<void*, void*> JitInfoMap;
#else
typedef hash_map<void*, void*, HashForCodeObject, SameCodeObjects> JitInfoMap;
#endif

static JitInfoMap* GetEntries() {
  static JitInfoMap* entries;
  if (entries == NULL) {
    entries = new JitInfoMap();
  }
  return entries;
}

static bool IsLineInfoTagged(void* ptr) {
  return 0 != (reinterpret_cast<intptr_t>(ptr));
}

static JITCodeLineInfo* UntagLineInfo(void* ptr) {
  return reinterpret_cast<JITCodeLineInfo*>(
    reinterpret_cast<intptr_t>(ptr));
}

// The parameter str is a mixed pattern which contains the
// function name and some other info. It comes from all the
// Logger::CodeCreateEvent(...) function. This funtion get the
// pure function name from the input parameter.
static char* GetFunctionNameFromMixedName(const char* str, int length) {
  int index = 0;
  int count = 0;
  char* start_ptr = NULL;

  while (str[index++] != ':' && (index < length)) {}

  if (str[index] == '*' || str[index] == '~' ) index++;
  if (index >= length) return NULL;

  start_ptr = const_cast<char*>(str + index);

  while (index < length && str[index++] != ' ') {
    count++;
  }

  char* result = new char[count + 1];
  memcpy(result, start_ptr, count);
  result[count] = '\0';

  return result;
}

// The JitCodeEventHandler for Vtune.
void VTUNEJITInterface::event_handler(const v8::JitCodeEvent* event) {
  if (VTUNERUNNING && event != NULL) {
    switch (event->type) {
      case v8::JitCodeEvent::CODE_ADDED: {
        char* temp_file_name = NULL;
        char* temp_method_name =
            GetFunctionNameFromMixedName(event->name.str,
                                         static_cast<int>(event->name.len));
        iJIT_Method_Load jmethod;
        memset(&jmethod, 0, sizeof jmethod);
        jmethod.method_id = iJIT_GetNewMethodID();
        jmethod.method_load_address = event->code_start;
        jmethod.method_size = static_cast<unsigned int>(event->code_len);
        jmethod.method_name = temp_method_name;

        Handle<Script> script = event->script;

        if (*script != NULL) {
          // Get the source file name and set it to jmethod.source_file_name
         if ((*script->GetScriptName())->IsString()) {
            Handle<String> script_name = script->GetScriptName()->ToString();
            temp_file_name = new char[script_name->Utf8Length() + 1];
            script_name->WriteUtf8(temp_file_name);
            jmethod.source_file_name = temp_file_name;
          }

          JitInfoMap::iterator entry =
              GetEntries()->find(event->code_start);
          if (entry != GetEntries()->end() && IsLineInfoTagged(entry->first)) {
            JITCodeLineInfo* line_info = UntagLineInfo(entry->second);
            // Get the line_num_info and set it to jmethod.line_number_table
            std::list<JITCodeLineInfo::LineNumInfo>* vtunelineinfo =
                line_info->GetLineNumInfo();

            jmethod.line_number_size = (unsigned int)vtunelineinfo->size();
            jmethod.line_number_table =
                reinterpret_cast<LineNumberInfo*>(
                    malloc(sizeof(LineNumberInfo)*jmethod.line_number_size));

            std::list<JITCodeLineInfo::LineNumInfo>::iterator Iter;
            int index = 0;
            for (Iter = vtunelineinfo->begin();
                 Iter != vtunelineinfo->end();
                 Iter++) {
              jmethod.line_number_table[index].Offset =
                  static_cast<unsigned int>(Iter->pc_);
              jmethod.line_number_table[index++].LineNumber =
				  script->GetLineNumber(Iter->pos_)+1;
            }
            GetEntries()->erase(event->code_start);
          }
        }

        iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED,
                         reinterpret_cast<void*>(&jmethod));
        if (temp_method_name)
          delete []temp_method_name;
        if (temp_file_name)
          delete []temp_file_name;
        break;
      }
      // TODO(chunyang.dai@intel.com): code_move will be supported.
      case v8::JitCodeEvent::CODE_MOVED:
        break;
      // Currently the CODE_REMOVED event is not issued.
      case v8::JitCodeEvent::CODE_REMOVED:
        break;
      case v8::JitCodeEvent::CODE_ADD_LINE_POS_INFO: {
        JITCodeLineInfo* line_info =
            reinterpret_cast<JITCodeLineInfo*>(event->user_data);
        if (line_info != NULL) {
          line_info->SetPosition(static_cast<intptr_t>(event->line_info.offset),
                                 static_cast<int>(event->line_info.pos));
        }
        break;
      }
      case v8::JitCodeEvent::CODE_START_LINE_INFO_RECORDING: {
        v8::JitCodeEvent* temp_event = const_cast<v8::JitCodeEvent*>(event);
        temp_event->user_data = new JITCodeLineInfo();
        break;
      }
      case v8::JitCodeEvent::CODE_END_LINE_INFO_RECORDING: {
        GetEntries()->insert(std::pair <void*, void*>(event->code_start, event->user_data));
        break;
      }
      default:
        break;
    }
  }
  return;
}

}  // namespace internal

void InitializeVtuneForV8() {
  if (v8::V8::Initialize()) {
    v8::V8::SetFlagsFromString("--nocompact_code_space",
                              (int)strlen("--nocompact_code_space"));
    v8::V8::SetJitCodeEventHandler(v8::kJitCodeEventDefault,
        vTune::internal::VTUNEJITInterface::event_handler);
  }
}

}  // namespace vTune
<commit_msg>This patch is to support Vtune on Android platform.<commit_after>/*
  This file is provided under a dual BSD/GPLv2 license.  When using or
  redistributing this file, you may do so under either license.

  GPL LICENSE SUMMARY

  Copyright(c) 2005-2012 Intel Corporation. All rights reserved.

  This program is free software; you can redistribute it and/or modify
  it under the terms of version 2 of the GNU General Public License as
  published by the Free Software Foundation.

  This program is distributed in the hope that it will be useful, but
  WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  The full GNU General Public License is included in this distribution
  in the file called LICENSE.GPL.

  Contact Information:
  http://software.intel.com/en-us/articles/intel-vtune-amplifier-xe/

  BSD LICENSE

  Copyright(c) 2005-2012 Intel Corporation. All rights reserved.
  All rights reserved.

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions
  are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the
      distribution.
    * Neither the name of Intel Corporation nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <string.h>

#ifdef WIN32
#include <hash_map>
using namespace std;
#else
// To avoid GCC 4.4 compilation warning about hash_map being deprecated.
#define OLD_DEPRECATED __DEPRECATED
#undef __DEPRECATED
#if defined (ANDROID)
#include <hash_map>
using namespace std;
#else
#include <ext/hash_map>
using namespace __gnu_cxx;
#endif
#define __DEPRECATED OLD_DEPRECATED
#endif

#include <list>

#include "v8-vtune.h"
#include "vtune-jit.h"

namespace vTune {
namespace internal {

// This class is used to record the JITted code position info for JIT
// code profiling.
class JITCodeLineInfo {
 public:
  JITCodeLineInfo() { }

  void SetPosition(intptr_t pc, int pos) {
    AddCodeLineInfo(LineNumInfo(pc, pos));
  }

  struct LineNumInfo {
    LineNumInfo(intptr_t pc, int pos)
        : pc_(pc), pos_(pos) { }

    intptr_t pc_;
    int pos_;
  };

  std::list<LineNumInfo>* GetLineNumInfo() {
    return &line_num_info_;
  }

 private:
  void AddCodeLineInfo(const LineNumInfo& line_info) {
	  line_num_info_.push_back(line_info);
  }
  std::list<LineNumInfo> line_num_info_;
};

struct SameCodeObjects {
  bool operator () (void* key1, void* key2) const {
    return key1 == key2;
  }
};

struct HashForCodeObject {
  uint32_t operator () (void* code) const {
    static const uintptr_t kGoldenRatio = 2654435761u;
    uintptr_t hash = reinterpret_cast<uintptr_t>(code);
    return static_cast<uint32_t>(hash * kGoldenRatio);
  }
};

#ifdef WIN32
typedef hash_map<void*, void*> JitInfoMap;
#else
typedef hash_map<void*, void*, HashForCodeObject, SameCodeObjects> JitInfoMap;
#endif

static JitInfoMap* GetEntries() {
  static JitInfoMap* entries;
  if (entries == NULL) {
    entries = new JitInfoMap();
  }
  return entries;
}

static bool IsLineInfoTagged(void* ptr) {
  return 0 != (reinterpret_cast<intptr_t>(ptr));
}

static JITCodeLineInfo* UntagLineInfo(void* ptr) {
  return reinterpret_cast<JITCodeLineInfo*>(
    reinterpret_cast<intptr_t>(ptr));
}

// The parameter str is a mixed pattern which contains the
// function name and some other info. It comes from all the
// Logger::CodeCreateEvent(...) function. This funtion get the
// pure function name from the input parameter.
static char* GetFunctionNameFromMixedName(const char* str, int length) {
  int index = 0;
  int count = 0;
  char* start_ptr = NULL;

  while (str[index++] != ':' && (index < length)) {}

  if (str[index] == '*' || str[index] == '~' ) index++;
  if (index >= length) return NULL;

  start_ptr = const_cast<char*>(str + index);

  while (index < length && str[index++] != ' ') {
    count++;
  }

  char* result = new char[count + 1];
  memcpy(result, start_ptr, count);
  result[count] = '\0';

  return result;
}

// The JitCodeEventHandler for Vtune.
void VTUNEJITInterface::event_handler(const v8::JitCodeEvent* event) {
  if (VTUNERUNNING && event != NULL) {
    switch (event->type) {
      case v8::JitCodeEvent::CODE_ADDED: {
        char* temp_file_name = NULL;
        char* temp_method_name =
            GetFunctionNameFromMixedName(event->name.str,
                                         static_cast<int>(event->name.len));
        iJIT_Method_Load jmethod;
        memset(&jmethod, 0, sizeof jmethod);
        jmethod.method_id = iJIT_GetNewMethodID();
        jmethod.method_load_address = event->code_start;
        jmethod.method_size = static_cast<unsigned int>(event->code_len);
        jmethod.method_name = temp_method_name;

        Handle<Script> script = event->script;

        if (*script != NULL) {
          // Get the source file name and set it to jmethod.source_file_name
         if ((*script->GetScriptName())->IsString()) {
            Handle<String> script_name = script->GetScriptName()->ToString();
            temp_file_name = new char[script_name->Utf8Length() + 1];
            script_name->WriteUtf8(temp_file_name);
            jmethod.source_file_name = temp_file_name;
          }

          JitInfoMap::iterator entry =
              GetEntries()->find(event->code_start);
          if (entry != GetEntries()->end() && IsLineInfoTagged(entry->first)) {
            JITCodeLineInfo* line_info = UntagLineInfo(entry->second);
            // Get the line_num_info and set it to jmethod.line_number_table
            std::list<JITCodeLineInfo::LineNumInfo>* vtunelineinfo =
                line_info->GetLineNumInfo();

            jmethod.line_number_size = (unsigned int)vtunelineinfo->size();
            jmethod.line_number_table =
                reinterpret_cast<LineNumberInfo*>(
                    malloc(sizeof(LineNumberInfo)*jmethod.line_number_size));

            std::list<JITCodeLineInfo::LineNumInfo>::iterator Iter;
            int index = 0;
            for (Iter = vtunelineinfo->begin();
                 Iter != vtunelineinfo->end();
                 Iter++) {
              jmethod.line_number_table[index].Offset =
                  static_cast<unsigned int>(Iter->pc_);
              jmethod.line_number_table[index++].LineNumber =
				  script->GetLineNumber(Iter->pos_)+1;
            }
            GetEntries()->erase(event->code_start);
          }
        }

        iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED,
                         reinterpret_cast<void*>(&jmethod));
        if (temp_method_name)
          delete []temp_method_name;
        if (temp_file_name)
          delete []temp_file_name;
        break;
      }
      // TODO(chunyang.dai@intel.com): code_move will be supported.
      case v8::JitCodeEvent::CODE_MOVED:
        break;
      // Currently the CODE_REMOVED event is not issued.
      case v8::JitCodeEvent::CODE_REMOVED:
        break;
      case v8::JitCodeEvent::CODE_ADD_LINE_POS_INFO: {
        JITCodeLineInfo* line_info =
            reinterpret_cast<JITCodeLineInfo*>(event->user_data);
        if (line_info != NULL) {
          line_info->SetPosition(static_cast<intptr_t>(event->line_info.offset),
                                 static_cast<int>(event->line_info.pos));
        }
        break;
      }
      case v8::JitCodeEvent::CODE_START_LINE_INFO_RECORDING: {
        v8::JitCodeEvent* temp_event = const_cast<v8::JitCodeEvent*>(event);
        temp_event->user_data = new JITCodeLineInfo();
        break;
      }
      case v8::JitCodeEvent::CODE_END_LINE_INFO_RECORDING: {
        GetEntries()->insert(std::pair <void*, void*>(event->code_start, event->user_data));
        break;
      }
      default:
        break;
    }
  }
  return;
}

}  // namespace internal

void InitializeVtuneForV8() {
  if (v8::V8::Initialize()) {
    v8::V8::SetFlagsFromString("--nocompact_code_space",
                              (int)strlen("--nocompact_code_space"));
    v8::V8::SetJitCodeEventHandler(v8::kJitCodeEventDefault,
        vTune::internal::VTUNEJITInterface::event_handler);
  }
}

}  // namespace vTune
<|endoftext|>


<commit_before>/*
    This file is part of KOrganizer.

    Copyright (c) 1998 Preston Brown <pbrown@kde.org>
    Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include <QStackedWidget>
#include <QGroupBox>
#include <QButtonGroup>
#include <QRadioButton>
#include <QLayout>
#include <QPushButton>
#include <QComboBox>
#include <QLabel>
#include <QSplitter>
#include <QGridLayout>
#include <QGroupBox>

#include <kvbox.h>
#include <kprinter.h>
#include <ksimpleconfig.h>
#include <kdebug.h>
#include <kdeversion.h>
#include <kstandardguiitem.h>

#include "korganizer/corehelper.h"

#include "calprinter.h"
#ifndef KORG_NOPRINTER
#include "calprinter.moc"

#include "calprintdefaultplugins.h"

CalPrinter::CalPrinter( QWidget *parent, Calendar *calendar, KOrg::CoreHelper *helper )
  : QObject( parent )
{
  mParent = parent;
  mConfig = new KSimpleConfig( "korganizer_printing.rc" );
  mCoreHelper = helper;

  init( calendar );
}

CalPrinter::~CalPrinter()
{
  kDebug(5850) << "~CalPrinter()" << endl;

  mPrintPlugins.clear();

  delete mConfig;
}

void CalPrinter::init( Calendar *calendar )
{
  mCalendar = calendar;

  mPrintPlugins.clear();

  mPrintPlugins = mCoreHelper->loadPrintPlugins();
  mPrintPlugins.prepend( new CalPrintTodos() );
  mPrintPlugins.prepend( new CalPrintMonth() );
  mPrintPlugins.prepend( new CalPrintWeek() );
  mPrintPlugins.prepend( new CalPrintDay() );
  mPrintPlugins.prepend( new CalPrintIncidence() );

  KOrg::PrintPlugin::List::Iterator it = mPrintPlugins.begin();
  for ( ; it != mPrintPlugins.end(); ++it ) {
    if ( *it ) {
      (*it)->setConfig( mConfig );
      (*it)->setCalendar( mCalendar );
      (*it)->setKOrgCoreHelper( mCoreHelper );
      (*it)->doLoadConfig();
    }
  }
}

void CalPrinter::setDateRange( const QDate &fd, const QDate &td )
{
  KOrg::PrintPlugin::List::Iterator it = mPrintPlugins.begin();
  for ( ; it != mPrintPlugins.end(); ++it ) {
    (*it)->setDateRange( fd, td );
  }
}

void CalPrinter::print( int type, const QDate &fd, const QDate &td,
                        Incidence::List selectedIncidences, bool preview )
{
  KOrg::PrintPlugin::List::Iterator it = mPrintPlugins.begin();
  for ( it = mPrintPlugins.begin(); it != mPrintPlugins.end(); ++it ) {
    (*it)->setSelectedIncidences( selectedIncidences );
  }
  CalPrintDialog printDialog( mPrintPlugins, mParent );
  printDialog.setOrientation( CalPrinter::ePrintOrientation( mConfig->readEntry("Orientation", 1 ) ) );
  printDialog.setPreview( preview );
  printDialog.setPrintType( type );
  setDateRange( fd, td );

  if ( printDialog.exec() == QDialog::Accepted ) {
    mConfig->writeEntry( "Orientation", (int)printDialog.orientation() );

    // Save all changes in the dialog
    for ( it = mPrintPlugins.begin(); it != mPrintPlugins.end(); ++it ) {
      (*it)->doSaveConfig();
    }
    doPrint( printDialog.selectedPlugin(), printDialog.orientation(), preview );
  }
  for ( it = mPrintPlugins.begin(); it != mPrintPlugins.end(); ++it ) {
    (*it)->setSelectedIncidences( Incidence::List() );
  }
}

void CalPrinter::doPrint( KOrg::PrintPlugin *selectedStyle,
                          CalPrinter::ePrintOrientation dlgorientation, bool preview )
{
  if ( !selectedStyle ) {
    KMessageBox::error( mParent,
                 i18n("Unable to print, no valid print style was returned."),
                 i18n("Printing error") );
    return;
  }
  KPrinter printer;

  printer.setPreviewOnly( preview );
  switch ( dlgorientation ) {
    case eOrientPlugin:
      printer.setOrientation( selectedStyle->defaultOrientation() );
      break;
    case eOrientPortrait:
      printer.setOrientation( KPrinter::Portrait );
      break;
    case eOrientLandscape:
      printer.setOrientation( KPrinter::Landscape );
      break;
    case eOrientPrinter:
    default:
      break;
  }

  if ( preview || printer.setup( mParent, i18n("Print Calendar") ) ) {
    selectedStyle->doPrint( &printer );
  }
}

///////////////////////////////////////////////////////////////////////////////

void CalPrinter::updateConfig()
{
}

/****************************************************************************/

CalPrintDialog::CalPrintDialog( KOrg::PrintPlugin::List plugins,
                                QWidget *parent )
  : KDialog( parent )
{
  setCaption( i18n( "Print" ) );
  setButtons( Ok | Cancel );
  setModal( true );
  KVBox *page = new KVBox( this );
  setMainWidget( page );

  QSplitter *splitter = new QSplitter( page );
  splitter->setOrientation( Qt::Horizontal );

  QGroupBox *typeBox = new QGroupBox( i18n( "Print Style" ), splitter );
  QBoxLayout *typeLayout = new QVBoxLayout( typeBox );
  mTypeGroup = new QButtonGroup( typeBox );
  // use the minimal width possible = max width of the radio buttons, not extensible
/*  mTypeGroup->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)4,
    (QSizePolicy::SizeType)5, 0, 0,
      mTypeGroup->sizePolicy().hasHeightForWidth() ) );*/

  QWidget *splitterRight = new QWidget( splitter );
  QGridLayout *splitterRightLayout = new QGridLayout( splitterRight );
  splitterRightLayout->setMargin( marginHint() );
  splitterRightLayout->setSpacing( spacingHint() );

  mConfigArea = new QStackedWidget( splitterRight );
  splitterRightLayout->addMultiCellWidget( mConfigArea, 0,0, 0, 1 );
  QLabel *orientationLabel = new QLabel( i18n("Page &orientation:"),
                                         splitterRight );
  splitterRightLayout->addWidget( orientationLabel, 1, 0 );

  mOrientationSelection = new QComboBox( splitterRight );
  mOrientationSelection->addItem( i18n("Use Default Orientation of Selected Style") );
  mOrientationSelection->addItem( i18n("Use Printer Default") );
  mOrientationSelection->addItem( i18n("Portrait") );
  mOrientationSelection->addItem( i18n("Landscape") );
  splitterRightLayout->addWidget( mOrientationSelection, 1, 1 );

  // signals and slots connections
  connect( mTypeGroup, SIGNAL( clicked( int ) ), SLOT( setPrintType( int ) ) );
  orientationLabel->setBuddy( mOrientationSelection );

  // First insert the config widgets into the widget stack. This possibly assigns
  // proper ids (when two plugins have the same sortID), so store them in a map
  // and use these new IDs to later sort the plugins for the type selection.
  for ( KOrg::PrintPlugin::List::Iterator it = plugins.begin();
        it != plugins.end(); ++it ) {
    int newid = mConfigArea->insertWidget( (*it)->sortID(), (*it)->configWidget( mConfigArea ) );
    mPluginIDs[newid] = (*it);
  }
  // Insert all plugins with in sorted order; plugins with clashing IDs will be first...
  QMap<int, KOrg::PrintPlugin*>::ConstIterator mapit;
  for ( mapit = mPluginIDs.begin(); mapit != mPluginIDs.end(); ++mapit ) {
    KOrg::PrintPlugin *p = mapit.value();
    QRadioButton *radioButton = new QRadioButton( p->description() );
    radioButton->setEnabled( p->enabled() );
//     radioButton->setMinimumHeight( radioButton->sizeHint().height() - 5 );
    mTypeGroup->addButton( radioButton, mapit.key() );
    typeLayout->addWidget( radioButton );
    kDebug() << p->description() << " is " << p->enabled() << endl;
  }

  setMinimumSize( minimumSizeHint() );
  resize( minimumSizeHint() );
}

CalPrintDialog::~CalPrintDialog()
{
}

void CalPrintDialog::setPreview(bool preview)
{
  if ( preview ) {
    setButtonText( Ok, i18n("&Preview") );
  } else {
    setButtonText( Ok, KStandardGuiItem::print().text() );
  }
}

void CalPrintDialog::setPrintType( int i )
{
  mConfigArea->setCurrentIndex( i );
  mConfigArea->currentWidget()->raise();
}

void CalPrintDialog::setOrientation( CalPrinter::ePrintOrientation orientation )
{
  mOrientation = orientation;
  mOrientationSelection->setCurrentIndex( mOrientation );
}

KOrg::PrintPlugin *CalPrintDialog::selectedPlugin()
{
  int id = mConfigArea->currentIndex();
  if ( mPluginIDs.contains( id ) ) {
    return mPluginIDs[id];
  } else {
    return 0;
  }
}

void CalPrintDialog::slotOk()
{
  mOrientation = (CalPrinter::ePrintOrientation)mOrientationSelection->currentIndex();

  QMap<int, KOrg::PrintPlugin*>::Iterator it = mPluginIDs.begin();
  for ( ; it != mPluginIDs.end(); ++it ) {
    if ( it.value() )
      it.value()->readSettingsWidget();
  }
}

#endif
<commit_msg>Forward port of SVN commit 618667 by kainhofe:<commit_after>/*
    This file is part of KOrganizer.

    Copyright (c) 1998 Preston Brown <pbrown@kde.org>
    Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include <QStackedWidget>
#include <QGroupBox>
#include <QButtonGroup>
#include <QRadioButton>
#include <QLayout>
#include <QPushButton>
#include <QComboBox>
#include <QLabel>
#include <QSplitter>
#include <QGridLayout>
#include <QGroupBox>

#include <kvbox.h>
#include <kprinter.h>
#include <ksimpleconfig.h>
#include <kdebug.h>
#include <kdeversion.h>
#include <kstandardguiitem.h>

#include "korganizer/corehelper.h"

#include "calprinter.h"
#ifndef KORG_NOPRINTER
#include "calprinter.moc"

#include "calprintdefaultplugins.h"

CalPrinter::CalPrinter( QWidget *parent, Calendar *calendar, KOrg::CoreHelper *helper )
  : QObject( parent )
{
  mParent = parent;
  mConfig = new KSimpleConfig( "korganizer_printing.rc" );
  mCoreHelper = helper;

  init( calendar );
}

CalPrinter::~CalPrinter()
{
  kDebug(5850) << "~CalPrinter()" << endl;

  mPrintPlugins.clear();

  delete mConfig;
}

void CalPrinter::init( Calendar *calendar )
{
  mCalendar = calendar;

  mPrintPlugins.clear();

  mPrintPlugins = mCoreHelper->loadPrintPlugins();
  mPrintPlugins.prepend( new CalPrintTodos() );
  mPrintPlugins.prepend( new CalPrintMonth() );
  mPrintPlugins.prepend( new CalPrintWeek() );
  mPrintPlugins.prepend( new CalPrintDay() );
  mPrintPlugins.prepend( new CalPrintIncidence() );

  KOrg::PrintPlugin::List::Iterator it = mPrintPlugins.begin();
  for ( ; it != mPrintPlugins.end(); ++it ) {
    if ( *it ) {
      (*it)->setConfig( mConfig );
      (*it)->setCalendar( mCalendar );
      (*it)->setKOrgCoreHelper( mCoreHelper );
      (*it)->doLoadConfig();
    }
  }
}

void CalPrinter::setDateRange( const QDate &fd, const QDate &td )
{
  KOrg::PrintPlugin::List::Iterator it = mPrintPlugins.begin();
  for ( ; it != mPrintPlugins.end(); ++it ) {
    (*it)->setDateRange( fd, td );
  }
}

void CalPrinter::print( int type, const QDate &fd, const QDate &td,
                        Incidence::List selectedIncidences, bool preview )
{
  KOrg::PrintPlugin::List::Iterator it = mPrintPlugins.begin();
  for ( it = mPrintPlugins.begin(); it != mPrintPlugins.end(); ++it ) {
    (*it)->setSelectedIncidences( selectedIncidences );
  }
  CalPrintDialog printDialog( mPrintPlugins, mParent );
  printDialog.setOrientation( CalPrinter::ePrintOrientation( mConfig->readEntry("Orientation", 1 ) ) );
  printDialog.setPreview( preview );
  printDialog.setPrintType( type );
  setDateRange( fd, td );

  if ( printDialog.exec() == QDialog::Accepted ) {
    mConfig->writeEntry( "Orientation", (int)printDialog.orientation() );

    // Save all changes in the dialog
    for ( it = mPrintPlugins.begin(); it != mPrintPlugins.end(); ++it ) {
      (*it)->doSaveConfig();
    }
    doPrint( printDialog.selectedPlugin(), printDialog.orientation(), preview );
  }
  for ( it = mPrintPlugins.begin(); it != mPrintPlugins.end(); ++it ) {
    (*it)->setSelectedIncidences( Incidence::List() );
  }
}

void CalPrinter::doPrint( KOrg::PrintPlugin *selectedStyle,
                          CalPrinter::ePrintOrientation dlgorientation, bool preview )
{
  if ( !selectedStyle ) {
    KMessageBox::error( mParent,
                 i18n("Unable to print, no valid print style was returned."),
                 i18n("Printing error") );
    return;
  }
  KPrinter printer;

  printer.setPreviewOnly( preview );
  switch ( dlgorientation ) {
    case eOrientPlugin:
      printer.setOrientation( selectedStyle->defaultOrientation() );
      break;
    case eOrientPortrait:
      printer.setOrientation( KPrinter::Portrait );
      break;
    case eOrientLandscape:
      printer.setOrientation( KPrinter::Landscape );
      break;
    case eOrientPrinter:
    default:
      break;
  }

  if ( preview || printer.setup( mParent, i18n("Print Calendar") ) ) {
    selectedStyle->doPrint( &printer );
  }
}

///////////////////////////////////////////////////////////////////////////////

void CalPrinter::updateConfig()
{
}

/****************************************************************************/

CalPrintDialog::CalPrintDialog( KOrg::PrintPlugin::List plugins,
                                QWidget *parent )
  : KDialog( parent )
{
  setCaption( i18n( "Print" ) );
  setButtons( Ok | Cancel );
  setModal( true );
  KVBox *page = new KVBox( this );
  setMainWidget( page );

  QSplitter *splitter = new QSplitter( page );
  splitter->setOrientation( Qt::Horizontal );

  QGroupBox *typeBox = new QGroupBox( i18n( "Print Style" ), splitter );
  QBoxLayout *typeLayout = new QVBoxLayout( typeBox );
  mTypeGroup = new QButtonGroup( typeBox );
  // use the minimal width possible = max width of the radio buttons, not extensible
/*  mTypeGroup->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)4,
    (QSizePolicy::SizeType)5, 0, 0,
      mTypeGroup->sizePolicy().hasHeightForWidth() ) );*/

  QWidget *splitterRight = new QWidget( splitter );
  QGridLayout *splitterRightLayout = new QGridLayout( splitterRight );
  splitterRightLayout->setMargin( marginHint() );
  splitterRightLayout->setSpacing( spacingHint() );

  mConfigArea = new QStackedWidget( splitterRight );
  splitterRightLayout->addMultiCellWidget( mConfigArea, 0,0, 0, 1 );
  QLabel *orientationLabel = new QLabel( i18n("Page &orientation:"),
                                         splitterRight );
  splitterRightLayout->addWidget( orientationLabel, 1, 0 );

  mOrientationSelection = new QComboBox( splitterRight );
  mOrientationSelection->addItem( i18n("Use Default Orientation of Selected Style") );
  mOrientationSelection->addItem( i18n("Use Printer Default") );
  mOrientationSelection->addItem( i18n("Portrait") );
  mOrientationSelection->addItem( i18n("Landscape") );
  splitterRightLayout->addWidget( mOrientationSelection, 1, 1 );

  // signals and slots connections
  connect( mTypeGroup, SIGNAL( clicked( int ) ), SLOT( setPrintType( int ) ) );
  orientationLabel->setBuddy( mOrientationSelection );

  // First insert the config widgets into the widget stack. This possibly assigns
  // proper ids (when two plugins have the same sortID), so store them in a map
  // and use these new IDs to later sort the plugins for the type selection.
  for ( KOrg::PrintPlugin::List::Iterator it = plugins.begin();
        it != plugins.end(); ++it ) {
    int newid = mConfigArea->insertWidget( (*it)->sortID(), (*it)->configWidget( mConfigArea ) );
    mPluginIDs[newid] = (*it);
  }
  // Insert all plugins with in sorted order; plugins with clashing IDs will be first...
  QMap<int, KOrg::PrintPlugin*>::ConstIterator mapit;
  for ( mapit = mPluginIDs.begin(); mapit != mPluginIDs.end(); ++mapit ) {
    KOrg::PrintPlugin *p = mapit.value();
    QRadioButton *radioButton = new QRadioButton( p->description() );
    radioButton->setEnabled( p->enabled() );
//     radioButton->setMinimumHeight( radioButton->sizeHint().height() - 5 );
    mTypeGroup->addButton( radioButton, mapit.key() );
    typeLayout->addWidget( radioButton );
  }

  setMinimumSize( minimumSizeHint() );
  resize( minimumSizeHint() );
}

CalPrintDialog::~CalPrintDialog()
{
}

void CalPrintDialog::setPreview(bool preview)
{
  if ( preview ) {
    setButtonText( Ok, i18n("&Preview") );
  } else {
    setButtonText( Ok, KStandardGuiItem::print().text() );
  }
}

void CalPrintDialog::setPrintType( int i )
{
  mConfigArea->setCurrentIndex( i );
  mConfigArea->currentWidget()->raise();
}

void CalPrintDialog::setOrientation( CalPrinter::ePrintOrientation orientation )
{
  mOrientation = orientation;
  mOrientationSelection->setCurrentIndex( mOrientation );
}

KOrg::PrintPlugin *CalPrintDialog::selectedPlugin()
{
  int id = mConfigArea->currentIndex();
  if ( mPluginIDs.contains( id ) ) {
    return mPluginIDs[id];
  } else {
    return 0;
  }
}

void CalPrintDialog::slotOk()
{
  mOrientation = (CalPrinter::ePrintOrientation)mOrientationSelection->currentIndex();

  QMap<int, KOrg::PrintPlugin*>::Iterator it = mPluginIDs.begin();
  for ( ; it != mPluginIDs.end(); ++it ) {
    if ( it.value() )
      it.value()->readSettingsWidget();
  }
}

#endif
<|endoftext|>


<commit_before>/**
 * This file is part of the "libfnord" project
 *   Copyright (c) 2015 Paul Asmuth
 *
 * FnordMetric is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License v3.0. You should have received a
 * copy of the GNU General Public License along with this program. If not, see
 * <http://www.gnu.org/licenses/>.
 */
#include <fnord-base/StringUtil.h>
#include <fnord-base/exception.h>
#include <fnord-msg/MessageSchema.h>

namespace fnord {
namespace msg {

static void schemaNodeToString(
    size_t level,
    const MessageSchemaField& field,
    String* str) {
  String ws(level * 2, ' ');
  String type_name;
  String attrs;

  String type_prefix = "";
  String type_suffix = "";

  if (field.optional) {
    type_prefix += "optional[";
    type_suffix += "]";
  }

  if (field.repeated) {
    type_prefix += "list[";
    type_suffix += "]";
  }

  switch (field.type) {

    case FieldType::OBJECT:
      str->append(StringUtil::format(
          "$0$1object$2 $3 = $4 {\n",
          ws,
          type_prefix,
          type_suffix,
          field.name,
          field.id));

      for (const auto& f : field.fields) {
        schemaNodeToString(level + 1, f, str);
      }

      str->append(ws + "}\n");
      return;

    case FieldType::BOOLEAN:
      type_name = "bool";
      break;

    case FieldType::UINT32:
      type_name = "uint32";
      attrs += StringUtil::format(" @maxval=$0", field.type_size);
      break;

    case FieldType::STRING:
      type_name = "string";
      attrs += StringUtil::format(" @maxlen=$0", field.type_size);
      break;

  }

  switch (field.encoding) {

    case EncodingHint::NONE:
      break;

    case EncodingHint::BITPACK:
      attrs += " @encoding=BITPACK";
      break;

  }

  str->append(StringUtil::format(
      "$0$1$2$3 $4 = $5$6;\n",
      ws,
      type_prefix,
      type_name,
      type_suffix,
      field.name,
      field.id,
      attrs));
}

static void sortSchemaFields(Vector<MessageSchemaField>* fields) {
  std::sort(fields->begin(), fields->end(), [] (
      const MessageSchemaField& a,
      const MessageSchemaField& b) {
    return a.id < b.id;
  });

  for (auto& f : *fields) {
    if (!f.fields.empty()) {
      sortSchemaFields(&f.fields);
    }
  }
}

MessageSchema::MessageSchema(
    const String& _name,
    Vector<MessageSchemaField> _fields) :
    name(_name),
    fields(_fields) {
  sortSchemaFields(&fields);
}

String MessageSchema::toString() const {
  String str = StringUtil::format("object $0 {\n", name);

  for (const auto& f : fields) {
    schemaNodeToString(1, f, &str);
  }

  str += "}";
  return str;
}

uint32_t MessageSchema::id(const String& path) {
  String p = path;
  String k;
  size_t s = 0;

  const Vector<MessageSchemaField>* fs = &fields;
  while (s != String::npos) {
    s = StringUtil::find(p, '.');
    if (s == String::npos) {
      k = p;
    } else {
      k = p.substr(0, s);
      p = p.substr(s + 1);
    }

    for (const auto& f : *fs) {
      if (f.name == k) {
        if (s == String::npos) {
          return f.id;
        } else {
          fs = &f.fields;
        }

        break;
      }
    }
  }

  RAISEF(kIndexError, "unknown field: $0", path);
}

} // namespace msg
} // namespace fnord
<commit_msg>cleaning up<commit_after>/**
 * This file is part of the "libfnord" project
 *   Copyright (c) 2015 Paul Asmuth
 *
 * FnordMetric is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License v3.0. You should have received a
 * copy of the GNU General Public License along with this program. If not, see
 * <http://www.gnu.org/licenses/>.
 */
#include <fnord-base/StringUtil.h>
#include <fnord-base/exception.h>
#include <fnord-msg/MessageSchema.h>

namespace fnord {
namespace msg {

static void schemaNodeToString(
    size_t level,
    const MessageSchemaField& field,
    String* str) {
  String ws(level * 2, ' ');
  String type_name;
  String attrs;

  String type_prefix = "";
  String type_suffix = "";

  if (field.optional) {
    type_prefix += "optional[";
    type_suffix += "]";
  }

  if (field.repeated) {
    type_prefix += "list[";
    type_suffix += "]";
  }

  switch (field.type) {

    case FieldType::OBJECT:
      str->append(StringUtil::format(
          "$0$1object$2 $3 = $4 {\n",
          ws,
          type_prefix,
          type_suffix,
          field.name,
          field.id));

      for (const auto& f : field.fields) {
        schemaNodeToString(level + 1, f, str);
      }

      str->append(ws + "}\n");
      return;

    case FieldType::BOOLEAN:
      type_name = "bool";
      break;

    case FieldType::UINT32:
      type_name = "uint32";
      attrs += StringUtil::format(" @maxval=$0", field.type_size);
      break;

    case FieldType::STRING:
      type_name = "string";
      attrs += StringUtil::format(" @maxlen=$0", field.type_size);
      break;

  }

  switch (field.encoding) {

    case EncodingHint::NONE:
      break;

    case EncodingHint::BITPACK:
      attrs += " @encoding=BITPACK";
      break;

  }

  str->append(StringUtil::format(
      "$0$1$2$3 $4 = $5$6;\n",
      ws,
      type_prefix,
      type_name,
      type_suffix,
      field.name,
      field.id,
      attrs));
}

MessageSchema::MessageSchema(
    const String& _name,
    Vector<MessageSchemaField> _fields) :
    name(_name),
    fields(_fields) {}

String MessageSchema::toString() const {
  String str = StringUtil::format("object $0 {\n", name);

  for (const auto& f : fields) {
    schemaNodeToString(1, f, &str);
  }

  str += "}";
  return str;
}

uint32_t MessageSchema::id(const String& path) {
  String p = path;
  String k;
  size_t s = 0;

  const Vector<MessageSchemaField>* fs = &fields;
  while (s != String::npos) {
    s = StringUtil::find(p, '.');
    if (s == String::npos) {
      k = p;
    } else {
      k = p.substr(0, s);
      p = p.substr(s + 1);
    }

    for (const auto& f : *fs) {
      if (f.name == k) {
        if (s == String::npos) {
          return f.id;
        } else {
          fs = &f.fields;
        }

        break;
      }
    }
  }

  RAISEF(kIndexError, "unknown field: $0", path);
}

} // namespace msg
} // namespace fnord
<|endoftext|>