<commit_before>#include <limits.h>

#include <QTimer>

#include "QGCVehicleConfig.h"
#include "UASManager.h"
#include "QGC.h"
#include "ui_QGCVehicleConfig.h"

QGCVehicleConfig::QGCVehicleConfig(QWidget *parent) :
    QWidget(parent),
    mav(NULL),
    changed(true),
    ui(new Ui::QGCVehicleConfig)
{
    setObjectName("QGC_VEHICLECONFIG");
    ui->setupUi(this);

    requestCalibrationRC();
    if (mav) mav->requestParameter(0, "RC_TYPE");

    connect(ui->rcCalibrationButton, SIGNAL(clicked(bool)), this, SLOT(toggleCalibrationRC(bool)));
    connect(ui->storeButton, SIGNAL(clicked()), this, SLOT(writeParameters()));

    connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)), this, SLOT(setActiveUAS(UASInterface*)));

    setActiveUAS(UASManager::instance()->getActiveUAS());

    for (unsigned int i = 0; i < chanMax; i++)
    {
        rcValue[i] = 1500;
    }

    updateTimer.setInterval(150);
    connect(&updateTimer, SIGNAL(timeout()), this, SLOT(updateView()));
    updateTimer.start();
}

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

void QGCVehicleConfig::toggleCalibrationRC(bool enabled)
{
    if (enabled)
    {
        startCalibrationRC();
    }
    else
    {
        stopCalibrationRC();
    }
}

void QGCVehicleConfig::startCalibrationRC()
{
    ui->rcTypeComboBox->setEnabled(false);
    resetCalibrationRC();
}

void QGCVehicleConfig::stopCalibrationRC()
{
    ui->rcTypeComboBox->setEnabled(true);
}

void QGCVehicleConfig::setActiveUAS(UASInterface* active)
{
    // Do nothing if system is the same or NULL
    if ((active == NULL) || mav == active) return;

    if (mav)
    {
        // Disconnect old system
        disconnect(mav, SIGNAL(remoteControlChannelRawChanged(int,float)), this,
                   SLOT(remoteControlChannelRawChanged(int,float)));
        disconnect(mav, SIGNAL(parameterChanged(int,int,QString,QVariant)), this,
                   SLOT(parameterChanged(int,int,QString,QVariant)));
        resetCalibrationRC();
    }

    // Connect new system
    mav = active;
    connect(active, SIGNAL(remoteControlChannelRawChanged(int,float)), this,
               SLOT(remoteControlChannelRawChanged(int,float)));
    connect(active, SIGNAL(parameterChanged(int,int,QString,QVariant)), this,
               SLOT(parameterChanged(int,int,QString,QVariant)));
}

void QGCVehicleConfig::resetCalibrationRC()
{
    for (unsigned int i = 0; i < chanMax; ++i)
    {
        rcMin[i] = INT_MAX;
        rcMax[i] = INT_MIN;
    }
}

/**
 * Sends the RC calibration to the vehicle and stores it in EEPROM
 */
void QGCVehicleConfig::writeCalibrationRC()
{
    if (!mav) return;

    QString minTpl("RC%1_MIN");
    QString maxTpl("RC%1_MAX");
    QString trimTpl("RC%1_TRIM");
    QString revTpl("RC%1_REV");

    // Do not write the RC type, as these values depend on this
    // active onboard parameter

    for (unsigned int i = 0; i < chanMax; ++i)
    {
        mav->setParameter(0, minTpl.arg(i), rcMin[i]);
        mav->setParameter(0, trimTpl.arg(i), rcTrim[i]);
        mav->setParameter(0, maxTpl.arg(i), rcMax[i]);
        mav->setParameter(0, revTpl.arg(i), (rcRev[i]) ? -1 : 1);
    }

    // Write mappings
    mav->setParameter(0, "RC_MAP_ROLL", rcMapping[0]);
    mav->setParameter(0, "RC_MAP_PITCH", rcMapping[1]);
    mav->setParameter(0, "RC_MAP_THROTTLE", rcMapping[2]);
    mav->setParameter(0, "RC_MAP_YAW", rcMapping[3]);
    mav->setParameter(0, "RC_MAP_MODE_SW", rcMapping[4]);
    mav->setParameter(0, "RC_MAP_AUX1", rcMapping[5]);
    mav->setParameter(0, "RC_MAP_AUX2", rcMapping[6]);
    mav->setParameter(0, "RC_MAP_AUX3", rcMapping[7]);
}

void QGCVehicleConfig::requestCalibrationRC()
{
    if (!mav) return;

    QString minTpl("RC%1_MIN");
    QString maxTpl("RC%1_MAX");
    QString trimTpl("RC%1_TRIM");
    QString revTpl("RC%1_REV");

    // Do not request the RC type, as these values depend on this
    // active onboard parameter

    for (unsigned int i = 0; i < chanMax; ++i)
    {
        mav->requestParameter(0, minTpl.arg(i));
        usleep(5000);
        mav->requestParameter(0, trimTpl.arg(i));
        usleep(5000);
        mav->requestParameter(0, maxTpl.arg(i));
        usleep(5000);
        mav->requestParameter(0, revTpl.arg(i));
        usleep(5000);
    }
}

void QGCVehicleConfig::writeParameters()
{
    updateStatus(tr("Writing all onboard parameters."));
    writeCalibrationRC();
}

void QGCVehicleConfig::remoteControlChannelRawChanged(int chan, float val)
{
//    /* scale around the mid point differently for lower and upper range */
//            if (ppm_buffer[i] > _rc.chan[i].mid + _parameters.dz[i]) {
//                _rc.chan[i].scaled = ((ppm_buffer[i] - _parameters.trim[i]) / (_parameters.max[i] - _parameters.trim[i]));
//            } else if ((ppm_buffer[i] < _rc_chan[i].mid - _parameters.dz[i])) {
//                _rc.chan[i].scaled = -1.0 + ((ppm_buffer[i] - _parameters.min[i]) / (_parameters.trim[i] - _parameters.min[i]));
//            } else {
//                /* in the configured dead zone, output zero */
//                _rc.chan[i].scaled = 0.0f;
//            }

    if (chan < 0 || static_cast<unsigned int>(chan) >= chanMax)
        return;

    if (chan == rcMapping[0])
    {
        // ROLL
        if (rcRoll >= rcTrim[chan])
        {
            rcRoll = (val - rcTrim[chan])/(rcMax[chan] - rcTrim[chan]);
        }
        else
        {
            rcRoll = (val - rcMin[chan])/(rcTrim[chan] - rcMin[chan]);
        }

        rcValue[0] = val;
        rcRoll = qBound(-1.0f, rcRoll, 1.0f);
    }
    else if (chan == rcMapping[1])
    {
        // PITCH
        if (rcPitch >= rcTrim[chan])
        {
            rcPitch = (val - rcTrim[chan])/(rcMax[chan] - rcTrim[chan]);
        }
        else
        {
            rcPitch = (val - rcMin[chan])/(rcTrim[chan] - rcMin[chan]);
        }
        rcValue[1] = val;
        rcPitch = qBound(-1.0f, rcPitch, 1.0f);
    }
    else if (chan == rcMapping[2])
    {
        // YAW
        if (rcYaw >= rcTrim[chan])
        {
            rcYaw = (val - rcTrim[chan])/(rcMax[chan] - rcTrim[chan]);
        }
        else
        {
            rcYaw = (val - rcMin[chan])/(rcTrim[chan] - rcMin[chan]);
        }
        rcValue[2] = val;
        rcYaw = qBound(-1.0f, rcYaw, 1.0f);
    }
    else if (chan == rcMapping[3])
    {
        // THROTTLE
        if (rcThrottle >= rcTrim[chan])
        {
            rcThrottle = (val - rcTrim[chan])/(rcMax[chan] - rcTrim[chan]);
        }
        else
        {
            rcThrottle = (val - rcMin[chan])/(rcTrim[chan] - rcMin[chan]);
        }
        rcValue[3] = val;
        rcThrottle = qBound(-1.0f, rcThrottle, 1.0f);
    }
    else if (chan == rcMapping[4])
    {
        // MODE SWITCH
        if (rcMode >= rcTrim[chan])
        {
            rcMode = (val - rcTrim[chan])/(rcMax[chan] - rcTrim[chan]);
        }
        else
        {
            rcMode = (val - rcMin[chan])/(rcTrim[chan] - rcMin[chan]);
        }
        rcValue[4] = val;
        rcMode = qBound(-1.0f, rcMode, 1.0f);
    }
    else if (chan == rcMapping[5])
    {
        // AUX1
        rcAux1 = val;
    }
    else if (chan == rcMapping[6])
    {
        // AUX2
        rcAux2 = val;
    }
    else if (chan == rcMapping[7])
    {
        // AUX3
        rcAux3 = val;
    }

    changed = true;

    //qDebug() << "RC CHAN:" << chan << "PPM:" << val;
}

void QGCVehicleConfig::parameterChanged(int uas, int component, QString parameterName, QVariant value)
{
    Q_UNUSED(uas);
    Q_UNUSED(component);
    if (rcTypeUpdateRequested > 0 && parameterName == QString("RC_TYPE"))
    {
        rcTypeUpdateRequested = 0;
        updateStatus(tr("Received RC type update, setting parameters based on model."));
        rcType = value.toInt();
        // Request all other parameters as well
        requestCalibrationRC();
    }
}

void QGCVehicleConfig::updateStatus(const QString& str)
{
    ui->statusLabel->setText(str);
    ui->statusLabel->setStyleSheet("");
}

void QGCVehicleConfig::updateError(const QString& str)
{
    ui->statusLabel->setText(str);
    ui->statusLabel->setStyleSheet(QString("QLabel { margin: 0px 2px; font: 14px; color: %1; background-color: %2; }").arg(QGC::colorDarkWhite.name()).arg(QGC::colorMagenta.name()));
}

void QGCVehicleConfig::setRCType(int type)
{
    if (!mav) return;

    // XXX TODO Add handling of RC_TYPE vs non-RC_TYPE here

    mav->setParameter(0, "RC_TYPE", type);
    rcTypeUpdateRequested = QGC::groundTimeMilliseconds();
    QTimer::singleShot(rcTypeTimeout+100, this, SLOT(checktimeOuts()));
}

void QGCVehicleConfig::checktimeOuts()
{
    if (rcTypeUpdateRequested > 0)
    {
        if (QGC::groundTimeMilliseconds() - rcTypeUpdateRequested > rcTypeTimeout)
        {
            updateError(tr("Setting remote control timed out - is the system connected?"));
        }
    }
}

void QGCVehicleConfig::updateView()
{
    if (changed)
    {
        ui->rollSlider->setValue(rcValue[0]);
        ui->pitchSlider->setValue(rcValue[1]);
        ui->yawSlider->setValue(rcValue[2]);
        ui->throttleSlider->setValue(rcValue[3]);
        changed = false;
    }
}
<commit_msg>Fixed windows compilation<commit_after>#include <limits.h>

#include <QTimer>

#include "QGCVehicleConfig.h"
#include "UASManager.h"
#include "QGC.h"
#include "ui_QGCVehicleConfig.h"

QGCVehicleConfig::QGCVehicleConfig(QWidget *parent) :
    QWidget(parent),
    mav(NULL),
    changed(true),
    ui(new Ui::QGCVehicleConfig)
{
    setObjectName("QGC_VEHICLECONFIG");
    ui->setupUi(this);

    requestCalibrationRC();
    if (mav) mav->requestParameter(0, "RC_TYPE");

    connect(ui->rcCalibrationButton, SIGNAL(clicked(bool)), this, SLOT(toggleCalibrationRC(bool)));
    connect(ui->storeButton, SIGNAL(clicked()), this, SLOT(writeParameters()));

    connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)), this, SLOT(setActiveUAS(UASInterface*)));

    setActiveUAS(UASManager::instance()->getActiveUAS());

    for (unsigned int i = 0; i < chanMax; i++)
    {
        rcValue[i] = 1500;
    }

    updateTimer.setInterval(150);
    connect(&updateTimer, SIGNAL(timeout()), this, SLOT(updateView()));
    updateTimer.start();
}

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

void QGCVehicleConfig::toggleCalibrationRC(bool enabled)
{
    if (enabled)
    {
        startCalibrationRC();
    }
    else
    {
        stopCalibrationRC();
    }
}

void QGCVehicleConfig::startCalibrationRC()
{
    ui->rcTypeComboBox->setEnabled(false);
    resetCalibrationRC();
}

void QGCVehicleConfig::stopCalibrationRC()
{
    ui->rcTypeComboBox->setEnabled(true);
}

void QGCVehicleConfig::setActiveUAS(UASInterface* active)
{
    // Do nothing if system is the same or NULL
    if ((active == NULL) || mav == active) return;

    if (mav)
    {
        // Disconnect old system
        disconnect(mav, SIGNAL(remoteControlChannelRawChanged(int,float)), this,
                   SLOT(remoteControlChannelRawChanged(int,float)));
        disconnect(mav, SIGNAL(parameterChanged(int,int,QString,QVariant)), this,
                   SLOT(parameterChanged(int,int,QString,QVariant)));
        resetCalibrationRC();
    }

    // Connect new system
    mav = active;
    connect(active, SIGNAL(remoteControlChannelRawChanged(int,float)), this,
               SLOT(remoteControlChannelRawChanged(int,float)));
    connect(active, SIGNAL(parameterChanged(int,int,QString,QVariant)), this,
               SLOT(parameterChanged(int,int,QString,QVariant)));
}

void QGCVehicleConfig::resetCalibrationRC()
{
    for (unsigned int i = 0; i < chanMax; ++i)
    {
        rcMin[i] = INT_MAX;
        rcMax[i] = INT_MIN;
    }
}

/**
 * Sends the RC calibration to the vehicle and stores it in EEPROM
 */
void QGCVehicleConfig::writeCalibrationRC()
{
    if (!mav) return;

    QString minTpl("RC%1_MIN");
    QString maxTpl("RC%1_MAX");
    QString trimTpl("RC%1_TRIM");
    QString revTpl("RC%1_REV");

    // Do not write the RC type, as these values depend on this
    // active onboard parameter

    for (unsigned int i = 0; i < chanMax; ++i)
    {
        mav->setParameter(0, minTpl.arg(i), rcMin[i]);
        mav->setParameter(0, trimTpl.arg(i), rcTrim[i]);
        mav->setParameter(0, maxTpl.arg(i), rcMax[i]);
        mav->setParameter(0, revTpl.arg(i), (rcRev[i]) ? -1 : 1);
    }

    // Write mappings
    mav->setParameter(0, "RC_MAP_ROLL", rcMapping[0]);
    mav->setParameter(0, "RC_MAP_PITCH", rcMapping[1]);
    mav->setParameter(0, "RC_MAP_THROTTLE", rcMapping[2]);
    mav->setParameter(0, "RC_MAP_YAW", rcMapping[3]);
    mav->setParameter(0, "RC_MAP_MODE_SW", rcMapping[4]);
    mav->setParameter(0, "RC_MAP_AUX1", rcMapping[5]);
    mav->setParameter(0, "RC_MAP_AUX2", rcMapping[6]);
    mav->setParameter(0, "RC_MAP_AUX3", rcMapping[7]);
}

void QGCVehicleConfig::requestCalibrationRC()
{
    if (!mav) return;

    QString minTpl("RC%1_MIN");
    QString maxTpl("RC%1_MAX");
    QString trimTpl("RC%1_TRIM");
    QString revTpl("RC%1_REV");

    // Do not request the RC type, as these values depend on this
    // active onboard parameter

    for (unsigned int i = 0; i < chanMax; ++i)
    {
        mav->requestParameter(0, minTpl.arg(i));
        QGC::SLEEP::usleep(5000);
        mav->requestParameter(0, trimTpl.arg(i));
        QGC::SLEEP::usleep(5000);
        mav->requestParameter(0, maxTpl.arg(i));
        QGC::SLEEP::usleep(5000);
        mav->requestParameter(0, revTpl.arg(i));
        QGC::SLEEP::usleep(5000);
    }
}

void QGCVehicleConfig::writeParameters()
{
    updateStatus(tr("Writing all onboard parameters."));
    writeCalibrationRC();
}

void QGCVehicleConfig::remoteControlChannelRawChanged(int chan, float val)
{
//    /* scale around the mid point differently for lower and upper range */
//            if (ppm_buffer[i] > _rc.chan[i].mid + _parameters.dz[i]) {
//                _rc.chan[i].scaled = ((ppm_buffer[i] - _parameters.trim[i]) / (_parameters.max[i] - _parameters.trim[i]));
//            } else if ((ppm_buffer[i] < _rc_chan[i].mid - _parameters.dz[i])) {
//                _rc.chan[i].scaled = -1.0 + ((ppm_buffer[i] - _parameters.min[i]) / (_parameters.trim[i] - _parameters.min[i]));
//            } else {
//                /* in the configured dead zone, output zero */
//                _rc.chan[i].scaled = 0.0f;
//            }

    if (chan < 0 || static_cast<unsigned int>(chan) >= chanMax)
        return;

    if (chan == rcMapping[0])
    {
        // ROLL
        if (rcRoll >= rcTrim[chan])
        {
            rcRoll = (val - rcTrim[chan])/(rcMax[chan] - rcTrim[chan]);
        }
        else
        {
            rcRoll = (val - rcMin[chan])/(rcTrim[chan] - rcMin[chan]);
        }

        rcValue[0] = val;
        rcRoll = qBound(-1.0f, rcRoll, 1.0f);
    }
    else if (chan == rcMapping[1])
    {
        // PITCH
        if (rcPitch >= rcTrim[chan])
        {
            rcPitch = (val - rcTrim[chan])/(rcMax[chan] - rcTrim[chan]);
        }
        else
        {
            rcPitch = (val - rcMin[chan])/(rcTrim[chan] - rcMin[chan]);
        }
        rcValue[1] = val;
        rcPitch = qBound(-1.0f, rcPitch, 1.0f);
    }
    else if (chan == rcMapping[2])
    {
        // YAW
        if (rcYaw >= rcTrim[chan])
        {
            rcYaw = (val - rcTrim[chan])/(rcMax[chan] - rcTrim[chan]);
        }
        else
        {
            rcYaw = (val - rcMin[chan])/(rcTrim[chan] - rcMin[chan]);
        }
        rcValue[2] = val;
        rcYaw = qBound(-1.0f, rcYaw, 1.0f);
    }
    else if (chan == rcMapping[3])
    {
        // THROTTLE
        if (rcThrottle >= rcTrim[chan])
        {
            rcThrottle = (val - rcTrim[chan])/(rcMax[chan] - rcTrim[chan]);
        }
        else
        {
            rcThrottle = (val - rcMin[chan])/(rcTrim[chan] - rcMin[chan]);
        }
        rcValue[3] = val;
        rcThrottle = qBound(-1.0f, rcThrottle, 1.0f);
    }
    else if (chan == rcMapping[4])
    {
        // MODE SWITCH
        if (rcMode >= rcTrim[chan])
        {
            rcMode = (val - rcTrim[chan])/(rcMax[chan] - rcTrim[chan]);
        }
        else
        {
            rcMode = (val - rcMin[chan])/(rcTrim[chan] - rcMin[chan]);
        }
        rcValue[4] = val;
        rcMode = qBound(-1.0f, rcMode, 1.0f);
    }
    else if (chan == rcMapping[5])
    {
        // AUX1
        rcAux1 = val;
    }
    else if (chan == rcMapping[6])
    {
        // AUX2
        rcAux2 = val;
    }
    else if (chan == rcMapping[7])
    {
        // AUX3
        rcAux3 = val;
    }

    changed = true;

    //qDebug() << "RC CHAN:" << chan << "PPM:" << val;
}

void QGCVehicleConfig::parameterChanged(int uas, int component, QString parameterName, QVariant value)
{
    Q_UNUSED(uas);
    Q_UNUSED(component);
    if (rcTypeUpdateRequested > 0 && parameterName == QString("RC_TYPE"))
    {
        rcTypeUpdateRequested = 0;
        updateStatus(tr("Received RC type update, setting parameters based on model."));
        rcType = value.toInt();
        // Request all other parameters as well
        requestCalibrationRC();
    }
}

void QGCVehicleConfig::updateStatus(const QString& str)
{
    ui->statusLabel->setText(str);
    ui->statusLabel->setStyleSheet("");
}

void QGCVehicleConfig::updateError(const QString& str)
{
    ui->statusLabel->setText(str);
    ui->statusLabel->setStyleSheet(QString("QLabel { margin: 0px 2px; font: 14px; color: %1; background-color: %2; }").arg(QGC::colorDarkWhite.name()).arg(QGC::colorMagenta.name()));
}

void QGCVehicleConfig::setRCType(int type)
{
    if (!mav) return;

    // XXX TODO Add handling of RC_TYPE vs non-RC_TYPE here

    mav->setParameter(0, "RC_TYPE", type);
    rcTypeUpdateRequested = QGC::groundTimeMilliseconds();
    QTimer::singleShot(rcTypeTimeout+100, this, SLOT(checktimeOuts()));
}

void QGCVehicleConfig::checktimeOuts()
{
    if (rcTypeUpdateRequested > 0)
    {
        if (QGC::groundTimeMilliseconds() - rcTypeUpdateRequested > rcTypeTimeout)
        {
            updateError(tr("Setting remote control timed out - is the system connected?"));
        }
    }
}

void QGCVehicleConfig::updateView()
{
    if (changed)
    {
        ui->rollSlider->setValue(rcValue[0]);
        ui->pitchSlider->setValue(rcValue[1]);
        ui->yawSlider->setValue(rcValue[2]);
        ui->throttleSlider->setValue(rcValue[3]);
        changed = false;
    }
}
<|endoftext|>


<commit_before>#include <ui/tag_scroll_view.h>

#include <QWheelEvent>
#include <QScrollBar>

TagScrollView::TagScrollView(
        QWidget* parent
    ) : QScrollArea( parent ), scale_factor_( 1. )
{
    setBackgroundRole( QPalette::Dark );
    setAutoFillBackground( true );
}

TagScrollView::~TagScrollView()
{
}

void TagScrollView::zoom_in()
{
    // safeguard
    if( scale_factor_ > 10. ) {
        return;
    }

    scale_by( 1.25 );
}

void TagScrollView::zoom_out()
{
    // safeguard
    if( scale_factor_ < 0.05 ) {
        return;
    }

    scale_by( 0.8 ); // = 1 / 1.25
}

void TagScrollView::fit_to_view()
{
    widget()->adjustSize();
}

void TagScrollView::scale_by(
        float factor
    )
{
    if( factor <= 0. ) {
        return;
    }

    scale_factor_ *= factor;
    widget()->resize( widget()->size() * factor );

    adjust_scrollbars( factor );
}

void TagScrollView::adjust_scrollbars(
        float factor
    )
{
    horizontalScrollBar()->setValue( int( factor * horizontalScrollBar()->value() + ( ( factor - 1 ) * horizontalScrollBar()->pageStep() / 2 ) ) );
    verticalScrollBar()->setValue( int( factor * verticalScrollBar()->value() + ( ( factor - 1 ) * verticalScrollBar()->pageStep() / 2 ) ) );
}

void TagScrollView::wheelEvent(
        QWheelEvent* e
     )
{
    if( e->modifiers() == Qt::CTRL ) {
        QPoint angle = e->angleDelta();
        if( angle.isNull() ) {
            return;
        }

        if( angle.y() > 0 ) {
            zoom_in();
        } else if( angle.y() < 0 ) {
            zoom_out();
        }
    } else {
        QScrollArea::wheelEvent(e);
    }
}
<commit_msg>implement image fit to scroll view<commit_after>#include <ui/tag_scroll_view.h>

#include <QWheelEvent>
#include <QScrollBar>

TagScrollView::TagScrollView(
        QWidget* parent
    ) : QScrollArea( parent ), scale_factor_( 1. )
{
    setBackgroundRole( QPalette::Dark );
    setAutoFillBackground( true );
}

TagScrollView::~TagScrollView()
{
}

void TagScrollView::zoom_in()
{
    // safeguard
    if( scale_factor_ > 10. ) {
        return;
    }

    scale_by( 1.25 );
}

void TagScrollView::zoom_out()
{
    // safeguard
    if( scale_factor_ < 0.05 ) {
        return;
    }

    scale_by( 0.8 ); // = 1 / 1.25
}

void TagScrollView::fit_to_view()
{
    QSize widget_size = widget()->size();
    widget_size.scale( size(), Qt::KeepAspectRatio );
    widget()->resize( widget_size );
}

void TagScrollView::scale_by(
        float factor
    )
{
    if( factor <= 0. ) {
        return;
    }

    scale_factor_ *= factor;
    widget()->resize( widget()->size() * factor );

    adjust_scrollbars( factor );
}

void TagScrollView::adjust_scrollbars(
        float factor
    )
{
    horizontalScrollBar()->setValue( int( factor * horizontalScrollBar()->value() + ( ( factor - 1 ) * horizontalScrollBar()->pageStep() / 2 ) ) );
    verticalScrollBar()->setValue( int( factor * verticalScrollBar()->value() + ( ( factor - 1 ) * verticalScrollBar()->pageStep() / 2 ) ) );
}

void TagScrollView::wheelEvent(
        QWheelEvent* e
     )
{
    if( e->modifiers() == Qt::CTRL ) {
        QPoint angle = e->angleDelta();
        if( angle.isNull() ) {
            return;
        }

        if( angle.y() > 0 ) {
            zoom_in();
        } else if( angle.y() < 0 ) {
            zoom_out();
        }
    } else {
        QScrollArea::wheelEvent(e);
    }
}
<|endoftext|>


<commit_before>//
// ulib - a collection of useful classes
// Copyright (C) 2000-2017 Michael Fink
//
/// \file CrashReporter.cpp Application crash reporting
//
#include "stdafx.h"
#include <ulib/CrashReporter.hpp>
#include <ulib/Path.hpp>
#include <strsafe.h>
#include <ctime>
#include <memory>

#pragma warning(disable: 4091) // 'typedef ': ignored on left of '' when no variable is declared
#include <dbghelp.h>
#pragma warning(default: 4091)

#pragma comment(lib, "dbghelp.lib")

/// base path for writing minidump file
static TCHAR g_minidumpBasePath[MAX_PATH] = { 0 };

/// function to call to show a crash dialog; may be null
static CrashReporter::T_fnShowCrashDialog g_fnShowCrashDialog = nullptr;

/// writes minidump file
bool WriteMinidump(HANDLE fileHandle, _EXCEPTION_POINTERS* exceptionInfo)
{
   __try
   {
      MINIDUMP_EXCEPTION_INFORMATION miniDumpExceptionInfo = { 0 };
      miniDumpExceptionInfo.ThreadId = GetCurrentThreadId();
      miniDumpExceptionInfo.ExceptionPointers = exceptionInfo;
      miniDumpExceptionInfo.ClientPointers = false;

      BOOL ret = MiniDumpWriteDump(
         GetCurrentProcess(),
         GetCurrentProcessId(),
         fileHandle,
         MiniDumpNormal,
         &miniDumpExceptionInfo,
         nullptr,
         nullptr);

      return ret != FALSE;
   }
   __except (EXCEPTION_EXECUTE_HANDLER)
   {
      return false;
   }
}

/// creates minidump filename in given buffer
void GetMinidumpFilename(LPTSTR minidumpFilename, UINT numMaxChars)
{
   ATLVERIFY(S_OK == StringCchCopy(
      minidumpFilename,
      numMaxChars,
      g_minidumpBasePath));

   size_t lenBasePath = _tcslen(minidumpFilename);
   TCHAR* start = minidumpFilename + lenBasePath;
   unsigned int numRemaining = numMaxChars - lenBasePath;

   // add date
   time_t nowt = ::time(&nowt);

   struct tm now = { 0 };
   localtime_s(&now, &nowt);

   _sntprintf_s(start, numRemaining, numRemaining,
      _T("%04u-%02u-%02u %02u_%02u_%02u.mdmp"),
      now.tm_year + 1900,
      now.tm_mon + 1,
      now.tm_mday,
      now.tm_hour,
      now.tm_min,
      now.tm_sec);
}

/// exception filter function to write minidump file
LONG WINAPI ExceptionFilterWriteMinidump(_EXCEPTION_POINTERS* exceptionInfo)
{
   OutputDebugString(_T("!!! ExceptionFilterWriteMinidump() called!\n"));

   // construct filename
   TCHAR minidumpFilename[MAX_PATH];
   GetMinidumpFilename(minidumpFilename, sizeof(minidumpFilename) / sizeof(*minidumpFilename));

   // write minidump file
   HANDLE fileHandle = CreateFile(
      minidumpFilename,
      GENERIC_WRITE,
      0,
      nullptr,
      CREATE_ALWAYS,
      FILE_ATTRIBUTE_NORMAL,
      nullptr);

   if (INVALID_HANDLE_VALUE == fileHandle)
      return EXCEPTION_CONTINUE_SEARCH;

   std::shared_ptr<void> file(fileHandle, &::CloseHandle);

   OutputDebugString(_T("!!! Writing minidump to file: "));
   OutputDebugString(minidumpFilename);
   OutputDebugString(_T("\n"));

   WriteMinidump(fileHandle, exceptionInfo);

   file.reset();

   ATLTRACE(_T("wrote minidump file: %s\n"), minidumpFilename);

   if (g_fnShowCrashDialog != nullptr)
      g_fnShowCrashDialog(minidumpFilename);

   return EXCEPTION_EXECUTE_HANDLER;
}

/// handler function for std::terminate
void OnStdTerminate()
{
   OutputDebugString(_T("!!! OnStdTerminate() called!\n"));

   // cause an exception, so that we can write a minidump
   EXCEPTION_POINTERS* exceptionInfo = nullptr;
   __try
   {
      throw 42;
   }
   __except ((exceptionInfo = GetExceptionInformation()), EXCEPTION_EXECUTE_HANDLER)
   {
      if (exceptionInfo != nullptr)
         ExceptionFilterWriteMinidump(exceptionInfo);
   }
}

void CrashReporter::Init(const CString& appName, const CString& basePath, T_fnShowCrashDialog fnShowCrashDialog)
{
   g_fnShowCrashDialog = fnShowCrashDialog;

   // set minidump base path
   CString path = basePath;
   Path::AddEndingBackslash(path);

   ::CreateDirectory(path, nullptr);

   path += appName + _T("-");

   ATLVERIFY(S_OK == StringCchCopy(
      g_minidumpBasePath,
      sizeof(g_minidumpBasePath) / sizeof(*g_minidumpBasePath),
      path));

   // set exception filter
   SetUnhandledExceptionFilter(&ExceptionFilterWriteMinidump);

   // catch all std::terminate() calls
   std::set_terminate(&OnStdTerminate);
}
<commit_msg>fixed warning in Release configuration<commit_after>//
// ulib - a collection of useful classes
// Copyright (C) 2000-2017 Michael Fink
//
/// \file CrashReporter.cpp Application crash reporting
//
#include "stdafx.h"
#include <ulib/CrashReporter.hpp>
#include <ulib/Path.hpp>
#include <strsafe.h>
#include <ctime>
#include <memory>

#pragma warning(disable: 4091) // 'typedef ': ignored on left of '' when no variable is declared
#include <dbghelp.h>
#pragma warning(default: 4091)

#pragma comment(lib, "dbghelp.lib")

/// base path for writing minidump file
static TCHAR g_minidumpBasePath[MAX_PATH] = { 0 };

/// function to call to show a crash dialog; may be null
static CrashReporter::T_fnShowCrashDialog g_fnShowCrashDialog = nullptr;

/// writes minidump file
bool WriteMinidump(HANDLE fileHandle, _EXCEPTION_POINTERS* exceptionInfo)
{
   __try
   {
      MINIDUMP_EXCEPTION_INFORMATION miniDumpExceptionInfo = { 0 };
      miniDumpExceptionInfo.ThreadId = GetCurrentThreadId();
      miniDumpExceptionInfo.ExceptionPointers = exceptionInfo;
      miniDumpExceptionInfo.ClientPointers = false;

      BOOL ret = MiniDumpWriteDump(
         GetCurrentProcess(),
         GetCurrentProcessId(),
         fileHandle,
         MiniDumpNormal,
         &miniDumpExceptionInfo,
         nullptr,
         nullptr);

      return ret != FALSE;
   }
   __except (EXCEPTION_EXECUTE_HANDLER)
   {
      return false;
   }
}

/// creates minidump filename in given buffer
void GetMinidumpFilename(LPTSTR minidumpFilename, UINT numMaxChars)
{
   ATLVERIFY(S_OK == StringCchCopy(
      minidumpFilename,
      numMaxChars,
      g_minidumpBasePath));

   size_t lenBasePath = _tcslen(minidumpFilename);
   TCHAR* start = minidumpFilename + lenBasePath;
   size_t numRemaining = numMaxChars - lenBasePath;

   // add date
   time_t nowt = ::time(&nowt);

   struct tm now = { 0 };
   localtime_s(&now, &nowt);

   _sntprintf_s(start, numRemaining, numRemaining,
      _T("%04u-%02u-%02u %02u_%02u_%02u.mdmp"),
      now.tm_year + 1900,
      now.tm_mon + 1,
      now.tm_mday,
      now.tm_hour,
      now.tm_min,
      now.tm_sec);
}

/// exception filter function to write minidump file
LONG WINAPI ExceptionFilterWriteMinidump(_EXCEPTION_POINTERS* exceptionInfo)
{
   OutputDebugString(_T("!!! ExceptionFilterWriteMinidump() called!\n"));

   // construct filename
   TCHAR minidumpFilename[MAX_PATH];
   GetMinidumpFilename(minidumpFilename, sizeof(minidumpFilename) / sizeof(*minidumpFilename));

   // write minidump file
   HANDLE fileHandle = CreateFile(
      minidumpFilename,
      GENERIC_WRITE,
      0,
      nullptr,
      CREATE_ALWAYS,
      FILE_ATTRIBUTE_NORMAL,
      nullptr);

   if (INVALID_HANDLE_VALUE == fileHandle)
      return EXCEPTION_CONTINUE_SEARCH;

   std::shared_ptr<void> file(fileHandle, &::CloseHandle);

   OutputDebugString(_T("!!! Writing minidump to file: "));
   OutputDebugString(minidumpFilename);
   OutputDebugString(_T("\n"));

   WriteMinidump(fileHandle, exceptionInfo);

   file.reset();

   ATLTRACE(_T("wrote minidump file: %s\n"), minidumpFilename);

   if (g_fnShowCrashDialog != nullptr)
      g_fnShowCrashDialog(minidumpFilename);

   return EXCEPTION_EXECUTE_HANDLER;
}

/// handler function for std::terminate
void OnStdTerminate()
{
   OutputDebugString(_T("!!! OnStdTerminate() called!\n"));

   // cause an exception, so that we can write a minidump
   EXCEPTION_POINTERS* exceptionInfo = nullptr;
   __try
   {
      throw 42;
   }
   __except ((exceptionInfo = GetExceptionInformation()), EXCEPTION_EXECUTE_HANDLER)
   {
      if (exceptionInfo != nullptr)
         ExceptionFilterWriteMinidump(exceptionInfo);
   }
}

void CrashReporter::Init(const CString& appName, const CString& basePath, T_fnShowCrashDialog fnShowCrashDialog)
{
   g_fnShowCrashDialog = fnShowCrashDialog;

   // set minidump base path
   CString path = basePath;
   Path::AddEndingBackslash(path);

   ::CreateDirectory(path, nullptr);

   path += appName + _T("-");

   ATLVERIFY(S_OK == StringCchCopy(
      g_minidumpBasePath,
      sizeof(g_minidumpBasePath) / sizeof(*g_minidumpBasePath),
      path));

   // set exception filter
   SetUnhandledExceptionFilter(&ExceptionFilterWriteMinidump);

   // catch all std::terminate() calls
   std::set_terminate(&OnStdTerminate);
}
<|endoftext|>


<commit_before>// Copyright 2010-2014 RethinkDB, all rights reserved.
#include "unittest/gtest.hpp"

#include "arch/timing.hpp"
#include "concurrency/pmap.hpp"
#include "unittest/unittest_utils.hpp"
#include "utils.hpp"

namespace unittest {

int wait_array[2][10] = { { 1, 1, 2, 3, 5, 13, 20, 30, 40, 8 },
                          { 5, 3, 2, 40, 30, 20, 8, 13, 1, 1 } };

void walk_wait_times(int i) {
    ticks_t t = get_ticks();
    for (int j = 0; j < 10; ++j) {
        nap(wait_array[i][j]);
        const ticks_t t2 = get_ticks();
        const int64_t diff = static_cast<int64_t>(t2) - static_cast<int64_t>(t);
        // Asserts that we're off by less than two milliseconds.
        ASSERT_LT(labs(diff - wait_array[i][j] * MILLION), 2 * MILLION);
        t = t2;
    }

}

TPTEST(TimerTest, TestApproximateWaitTimes) {
    pmap(2, walk_wait_times);
}

}  // namespace unittest
<commit_msg>Changed labs to llabs -- an int64_t is best approximated by a long long, not a long.<commit_after>// Copyright 2010-2014 RethinkDB, all rights reserved.
#include "unittest/gtest.hpp"

#include "arch/timing.hpp"
#include "concurrency/pmap.hpp"
#include "unittest/unittest_utils.hpp"
#include "utils.hpp"

namespace unittest {

int wait_array[2][10] = { { 1, 1, 2, 3, 5, 13, 20, 30, 40, 8 },
                          { 5, 3, 2, 40, 30, 20, 8, 13, 1, 1 } };

void walk_wait_times(int i) {
    ticks_t t = get_ticks();
    for (int j = 0; j < 10; ++j) {
        nap(wait_array[i][j]);
        const ticks_t t2 = get_ticks();
        const int64_t diff = static_cast<int64_t>(t2) - static_cast<int64_t>(t);
        // Asserts that we're off by less than two milliseconds.
        ASSERT_LT(llabs(diff - wait_array[i][j] * MILLION), 2 * MILLION);
        t = t2;
    }

}

TPTEST(TimerTest, TestApproximateWaitTimes) {
    pmap(2, walk_wait_times);
}

}  // namespace unittest
<|endoftext|>


<commit_before>#include <random.h>
#include <fs.h>
#include <util/strencodings.h>

fs::path GetUniquePath(const fs::path& base)
{
    FastRandomContext rnd;
    fs::path tmpFile = base / HexStr(rnd.randbytes(8));
    return tmpFile;
}<commit_msg>doc: add missing copyright header to getuniquepath.cpp<commit_after>// Copyright (c) 2021 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <random.h>
#include <fs.h>
#include <util/strencodings.h>

fs::path GetUniquePath(const fs::path& base)
{
    FastRandomContext rnd;
    fs::path tmpFile = base / HexStr(rnd.randbytes(8));
    return tmpFile;
}<|endoftext|>


<commit_before>/*

Copyright (c) 2009, Arvid Norberg
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 the author 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 "libtorrent/utp_stream.hpp"
#include "libtorrent/udp_socket.hpp"

namespace libtorrent
{

	utp_socket_manager::utp_socket_manager(udp_socket& s, incoming_utp_fun cb
		, void* userdata)
		: m_sock(s)
		, m_cb(cb)
		, m_userdata(userdata)
	{}

	void utp_socket_manager::tick()
	{
		for (socket_map_t::iterator i = m_utp_sockets.begin()
			, end(m_utp_sockets.end()); i != end; ++i)
		{
			i->second->tick();
		}
	}

	bool utp_socket_manager::incoming_packet(char const* p, int size)
	{
		if (size < sizeof(utp_header)) return false;

		utp_header const* ph = (utp_header*)p;

		if (ph->ver != 1) return false;

		// parse out connection ID and look for existing
		// connections. If found, forward to the utp_stream.
		boost::uint16_t id = ph->connection_id;
		socket_map_t::iterator i = m_utp_sockets.find(id);

		// if not found, see if it's a SYN packet, if it is,
		// create a new utp_stream
		if (i == m_utp_sockets.end() && ph->type == ST_SYN)
		{
			boost::uint16_t id = rand();
			boost::shared_ptr<utp_stream> c = new utp_stream(*this, id);

			TORRENT_ASSERT(m_utp_sockets.find(id) == m_utp_sockets.end());
			i = m_utp_sockets.insert(std::make_pair(id, c.get()));
			m_cb(m_userdata, c);
		}

		if (i != m_utp_sockets.end())
			return i->second->incoming_packet(p, size);

		return false;
	}

	void utp_socket_manager::remove_socket(boost::uint16_t id)
	{
		socket_map_t::iterator i = m_utp_sockets.find(id);
		if (i == m_utp_sockets.end()) return;
		m_utp_sockets.erase(i);
	}

	void utp_socket_manager::add_socket(boost::uint16_t id, utp_stream* s)
	{
	}
}

<commit_msg>Added passing of io_service to utp_stream constructor in utp_socket_manager::incoming_packet(). Corrected how boost::shared_ptr<utp_stream> c is defined at the same place.<commit_after>/*

Copyright (c) 2009, Arvid Norberg
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 the author 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 "libtorrent/utp_stream.hpp"
#include "libtorrent/udp_socket.hpp"

namespace libtorrent
{

	utp_socket_manager::utp_socket_manager(udp_socket& s, incoming_utp_fun cb
		, void* userdata)
		: m_sock(s)
		, m_cb(cb)
		, m_userdata(userdata)
	{}

	void utp_socket_manager::tick()
	{
		for (socket_map_t::iterator i = m_utp_sockets.begin()
			, end(m_utp_sockets.end()); i != end; ++i)
		{
			i->second->tick();
		}
	}

	bool utp_socket_manager::incoming_packet(char const* p, int size)
	{
		if (size < sizeof(utp_header)) return false;

		utp_header const* ph = (utp_header*)p;

		if (ph->ver != 1) return false;

		// parse out connection ID and look for existing
		// connections. If found, forward to the utp_stream.
		boost::uint16_t id = ph->connection_id;
		socket_map_t::iterator i = m_utp_sockets.find(id);

		// if not found, see if it's a SYN packet, if it is,
		// create a new utp_stream
		if (i == m_utp_sockets.end() && ph->type == ST_SYN)
		{
			boost::uint16_t id = rand();
			boost::shared_ptr<utp_stream> c(new utp_stream(m_sock.get_io_service(), *this, id));

			TORRENT_ASSERT(m_utp_sockets.find(id) == m_utp_sockets.end());
			i = m_utp_sockets.insert(std::make_pair(id, c.get()));
			m_cb(m_userdata, c);
		}

		if (i != m_utp_sockets.end())
			return i->second->incoming_packet(p, size);

		return false;
	}

	void utp_socket_manager::remove_socket(boost::uint16_t id)
	{
		socket_map_t::iterator i = m_utp_sockets.find(id);
		if (i == m_utp_sockets.end()) return;
		m_utp_sockets.erase(i);
	}

	void utp_socket_manager::add_socket(boost::uint16_t id, utp_stream* s)
	{
	}
}

<|endoftext|>


<commit_before>/*
This file is part of WME Lite.
http://dead-code.org/redir.php?target=wmelite

Copyright (c) 2011 Jan Nedoma

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

#include "dcgf.h"
#include "BDiskFile.h"
#include "PathUtil.h"

//////////////////////////////////////////////////////////////////////////
CBDiskFile::CBDiskFile(CBGame* inGame):CBFile(inGame)
{
	m_File = NULL;
	m_Data = NULL;
	m_Compressed = false;
	m_PrefixSize = 0;
}

//////////////////////////////////////////////////////////////////////////
CBDiskFile::~CBDiskFile()
{
	Close();
}

//////////////////////////////////////////////////////////////////////////
HRESULT CBDiskFile::Open(const char* Filename)
{
	Close();

	char FullPath[MAX_PATH];
	ops = PathUtil::GetFileAccessMethod(Filename);

	for(int i=0; i<Game->m_FileManager->m_SinglePaths.GetSize(); i++)
	{
		sprintf(FullPath, "%s%s", Game->m_FileManager->m_SinglePaths[i], Filename);
		CorrectSlashes(FullPath);

		m_File = ops->file_open(FullPath, "rb");
		if(m_File!=NULL) break;
	}

	// if we didn't find it in search paths, try to open directly
	if(!m_File)
	{
		strcpy(FullPath, Filename);
		CorrectSlashes(FullPath);
		m_File = ops->file_open(FullPath, "rb");
	}

	if(m_File)
	{
		DWORD magic1, magic2;
		ops->file_read((char *) (&magic1), sizeof(DWORD), m_File);
		ops->file_read((char *) (&magic2), sizeof(DWORD), m_File);

		if(magic1==DCGF_MAGIC && magic2==COMPRESSED_FILE_MAGIC) m_Compressed = true;

		if(m_Compressed)
		{
			DWORD DataOffset, CompSize, UncompSize;
			ops->file_read((char *) (&DataOffset), sizeof(DWORD), m_File);
			ops->file_read((char *) (&CompSize), sizeof(DWORD), m_File);
			ops->file_read((char *) (&UncompSize), sizeof(DWORD), m_File);

			BYTE* CompBuffer = new BYTE[CompSize];
			if(!CompBuffer)
			{
				Game->LOG(0, "Error allocating memory for compressed file '%s'", Filename);
				Close();
				return E_FAIL;
			}

			m_Data = new BYTE[UncompSize];
			if(!m_Data)
			{
				Game->LOG(0, "Error allocating buffer for file '%s'", Filename);
				delete [] CompBuffer;
				Close();
				return E_FAIL;
			}

			ops->file_seek(m_File, DataOffset + m_PrefixSize, SEEK_SET);
			ops->file_read((char *) CompBuffer, CompSize, m_File);

			if(uncompress(m_Data, (uLongf*)&UncompSize, CompBuffer, CompSize)!=Z_OK)
			{
				Game->LOG(0, "Error uncompressing file '%s'", Filename);
				delete [] CompBuffer;
				Close();
				return E_FAIL;
			}

			delete [] CompBuffer;
			m_Size = UncompSize;
			m_Pos = 0;
			ops->file_close(m_File);
			m_File = NULL;
		}
		else
		{
			m_Pos = 0;
			ops->file_seek(m_File, 0, SEEK_END);
			m_Size = ops->file_tell(m_File) - m_PrefixSize;
			ops->file_seek(m_File, m_PrefixSize, SEEK_SET);
		}

		return S_OK;
	}
	else return E_FAIL;
}

//////////////////////////////////////////////////////////////////////////
HRESULT CBDiskFile::Close()
{
	if(m_File) ops->file_close(m_File);
	m_File = NULL;
	m_Pos = 0;
	m_Size = 0;

	SAFE_DELETE_ARRAY(m_Data);
	m_Compressed = false;

	return S_OK;
}

//////////////////////////////////////////////////////////////////////////
HRESULT CBDiskFile::Read(void *Buffer, DWORD Size)
{
	if(m_Compressed)
	{
		memcpy(Buffer, m_Data+m_Pos, Size);
		m_Pos+=Size;
		return S_OK;
	}
	else
	{
		if(m_File)
		{
			size_t count = ops->file_read((char *) Buffer, Size, m_File);
			m_Pos += count;
			return S_OK;
		}
		else return E_FAIL;
	}
}

//////////////////////////////////////////////////////////////////////////
HRESULT CBDiskFile::Seek(DWORD Pos, TSeek Origin)
{
	if(m_Compressed)
	{
		DWORD NewPos=0;

		switch(Origin)
		{
			case SEEK_TO_BEGIN:   NewPos = Pos;          break;
			case SEEK_TO_END:     NewPos = m_Size + Pos; break;
			case SEEK_TO_CURRENT: NewPos = m_Pos + Pos;  break;
		}

		if(NewPos > m_Size) return E_FAIL;
		else m_Pos = NewPos;
		return S_OK;
	}
	else
	{
		if(!m_File) return E_FAIL;

		int ret=1;

		switch(Origin)
		{
			case SEEK_TO_BEGIN:   ret = ops->file_seek(m_File, m_PrefixSize + Pos, SEEK_SET); break;
			case SEEK_TO_END:     ret = ops->file_seek(m_File, Pos, SEEK_END); break;
			case SEEK_TO_CURRENT: ret = ops->file_seek(m_File, Pos, SEEK_CUR); break;
		}
		if(ret==0)
		{
			m_Pos = ops->file_tell(m_File) - m_PrefixSize;
			return S_OK;
		}
		else return E_FAIL;
	}
}

//////////////////////////////////////////////////////////////////////////
void CBDiskFile::CorrectSlashes(char* fileName)
{
	for (size_t i = 0; i < strlen(fileName); i++)
	{
		if (fileName[i] == '\\') fileName[i] = '/';
	}
}
<commit_msg>Fixed ReadLine() crash<commit_after>/*
This file is part of WME Lite.
http://dead-code.org/redir.php?target=wmelite

Copyright (c) 2011 Jan Nedoma

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

#include "dcgf.h"
#include "BDiskFile.h"
#include "PathUtil.h"

//////////////////////////////////////////////////////////////////////////
CBDiskFile::CBDiskFile(CBGame* inGame):CBFile(inGame)
{
	m_File = NULL;
	m_Data = NULL;
	m_Compressed = false;
	m_PrefixSize = 0;
}

//////////////////////////////////////////////////////////////////////////
CBDiskFile::~CBDiskFile()
{
	Close();
}

//////////////////////////////////////////////////////////////////////////
HRESULT CBDiskFile::Open(const char* Filename)
{
	Close();

	char FullPath[MAX_PATH];
	ops = PathUtil::GetFileAccessMethod(Filename);

	for(int i=0; i<Game->m_FileManager->m_SinglePaths.GetSize(); i++)
	{
		sprintf(FullPath, "%s%s", Game->m_FileManager->m_SinglePaths[i], Filename);
		CorrectSlashes(FullPath);

		m_File = ops->file_open(FullPath, "rb");
		if(m_File!=NULL) break;
	}

	// if we didn't find it in search paths, try to open directly
	if(!m_File)
	{
		strcpy(FullPath, Filename);
		CorrectSlashes(FullPath);
		m_File = ops->file_open(FullPath, "rb");
	}

	if(m_File)
	{
		DWORD magic1, magic2;
		ops->file_read((char *) (&magic1), sizeof(DWORD), m_File);
		ops->file_read((char *) (&magic2), sizeof(DWORD), m_File);

		if(magic1==DCGF_MAGIC && magic2==COMPRESSED_FILE_MAGIC) m_Compressed = true;

		if(m_Compressed)
		{
			DWORD DataOffset, CompSize, UncompSize;
			ops->file_read((char *) (&DataOffset), sizeof(DWORD), m_File);
			ops->file_read((char *) (&CompSize), sizeof(DWORD), m_File);
			ops->file_read((char *) (&UncompSize), sizeof(DWORD), m_File);

			BYTE* CompBuffer = new BYTE[CompSize];
			if(!CompBuffer)
			{
				Game->LOG(0, "Error allocating memory for compressed file '%s'", Filename);
				Close();
				return E_FAIL;
			}

			m_Data = new BYTE[UncompSize];
			if(!m_Data)
			{
				Game->LOG(0, "Error allocating buffer for file '%s'", Filename);
				delete [] CompBuffer;
				Close();
				return E_FAIL;
			}

			ops->file_seek(m_File, DataOffset + m_PrefixSize, SEEK_SET);
			ops->file_read((char *) CompBuffer, CompSize, m_File);

			if(uncompress(m_Data, (uLongf*)&UncompSize, CompBuffer, CompSize)!=Z_OK)
			{
				Game->LOG(0, "Error uncompressing file '%s'", Filename);
				delete [] CompBuffer;
				Close();
				return E_FAIL;
			}

			delete [] CompBuffer;
			m_Size = UncompSize;
			m_Pos = 0;
			ops->file_close(m_File);
			m_File = NULL;
		}
		else
		{
			m_Pos = 0;
			ops->file_seek(m_File, 0, SEEK_END);
			m_Size = ops->file_tell(m_File) - m_PrefixSize;
			ops->file_seek(m_File, m_PrefixSize, SEEK_SET);
		}

		return S_OK;
	}
	else return E_FAIL;
}

//////////////////////////////////////////////////////////////////////////
HRESULT CBDiskFile::Close()
{
	if(m_File) ops->file_close(m_File);
	m_File = NULL;
	m_Pos = 0;
	m_Size = 0;

	SAFE_DELETE_ARRAY(m_Data);
	m_Compressed = false;

	return S_OK;
}

//////////////////////////////////////////////////////////////////////////
HRESULT CBDiskFile::Read(void *Buffer, DWORD Size)
{
	if(m_Compressed)
	{
		memcpy(Buffer, m_Data+m_Pos, Size);
		m_Pos+=Size;
		return S_OK;
	}
	else
	{
		if(m_File)
		{
			size_t count = ops->file_read((char *) Buffer, Size, m_File);
			if (count == 0)
				return E_FAIL;
			m_Pos += count;
			return S_OK;
		}
		else return E_FAIL;
	}
}

//////////////////////////////////////////////////////////////////////////
HRESULT CBDiskFile::Seek(DWORD Pos, TSeek Origin)
{
	if(m_Compressed)
	{
		DWORD NewPos=0;

		switch(Origin)
		{
			case SEEK_TO_BEGIN:   NewPos = Pos;          break;
			case SEEK_TO_END:     NewPos = m_Size + Pos; break;
			case SEEK_TO_CURRENT: NewPos = m_Pos + Pos;  break;
		}

		if(NewPos > m_Size) return E_FAIL;
		else m_Pos = NewPos;
		return S_OK;
	}
	else
	{
		if(!m_File) return E_FAIL;

		int ret=1;

		switch(Origin)
		{
			case SEEK_TO_BEGIN:   ret = ops->file_seek(m_File, m_PrefixSize + Pos, SEEK_SET); break;
			case SEEK_TO_END:     ret = ops->file_seek(m_File, Pos, SEEK_END); break;
			case SEEK_TO_CURRENT: ret = ops->file_seek(m_File, Pos, SEEK_CUR); break;
		}
		if(ret==0)
		{
			m_Pos = ops->file_tell(m_File) - m_PrefixSize;
			return S_OK;
		}
		else return E_FAIL;
	}
}

//////////////////////////////////////////////////////////////////////////
void CBDiskFile::CorrectSlashes(char* fileName)
{
	for (size_t i = 0; i < strlen(fileName); i++)
	{
		if (fileName[i] == '\\') fileName[i] = '/';
	}
}
<|endoftext|>


<commit_before><commit_msg>iOS: fix Node.js build<commit_after><|endoftext|>


<commit_before>#ifndef DUNE_STUFF_RANGES_RANGES_HH
#define DUNE_STUFF_RANGES_RANGES_HH

#ifdef HAVE_CMAKE_CONFIG
 #include "cmake_config.h"
#else
 #include "config.h"
#endif // ifdef HAVE_CMAKE_CONFIG

#include <dune/grid/common/gridview.hh>
#include <boost/serialization/static_warning.hpp>

#if HAVE_DUNE_FEM
#include <dune/fem/version.hh>
#include <dune/fem/function/common/discretefunction.hh>
#include <dune/fem/gridpart/common/gridpart.hh>
#endif
#include <dune/stuff/common/math.hh>

namespace std {

#if HAVE_DUNE_FEM

template < class DiscreteFunctionTraits >
auto begin( const Dune::DiscreteFunctionInterface< DiscreteFunctionTraits >& func )
  -> decltype(func.dbegin())
{
  return func.dbegin();
}

template < class DiscreteFunctionTraits >
auto end( const Dune::DiscreteFunctionInterface< DiscreteFunctionTraits >& func )
  -> decltype(func.dend())
{
  return func.dend();
}

template < class DiscreteFunctionTraits >
auto begin( Dune::DiscreteFunctionInterface< DiscreteFunctionTraits >& func )
  -> decltype(func.dbegin())
{
  return func.dbegin();
}

template < class DiscreteFunctionTraits >
auto end( Dune::DiscreteFunctionInterface< DiscreteFunctionTraits >& func )
  -> decltype(func.dend())
{
  return func.dend();
}

#endif

} //namespace std

namespace Dune {
namespace Stuff {
namespace Common {

//! adapter enabling view usage in range-based for
template < class GridViewType, int codim = 0>
class ViewRange {
  const GridViewType& view_;
public:
  ViewRange(const GridViewType& view)
    :view_(view)
  {
    BOOST_STATIC_WARNING(codim == 0 && "unnecessary ViewRange usage with codim 0");
  }

  typename GridViewType::template Codim< codim >::Iterator
  begin() const {
    return view_.template begin< codim >();
  }
  typename GridViewType::template Codim< codim >::Iterator
  end() const {
    return view_.template end< codim >();
  }
};

/** adapter enabling intersectionniterator usage in range-based for
 * works for GridParts and GridViews
 */
template < class GridAbstractionType, class EntityType >
class IntersectionRange {
  const GridAbstractionType& view_;
  const EntityType& entity_;
public:
  IntersectionRange(const GridAbstractionType& view, const EntityType& entity)
    : view_(view)
    , entity_(entity)
  {}

  auto begin() const -> decltype(view_.ibegin(entity_)) {
    return view_.ibegin(entity_);
  }

  auto end() const -> decltype(view_.iend(entity_)) {
    return view_.iend(entity_);
  }
};

//! Range adpater for lagrane points from lagrange spaces
template < class DiscreteFunctionspaceType, int faceCodim >
class LagrangePointSetRange {
  typedef typename DiscreteFunctionspaceType::LagrangePointSetType
    LagrangePointSetType;
  typedef typename LagrangePointSetType::template Codim< faceCodim >::SubEntityIteratorType
    SubEntityIteratorType;
  const LagrangePointSetType& lp_set_;
  const unsigned int subEntity_;

public:
  /** the template isn't lazyness here, the underlying set is tempalted on it too
   */
  template < class EntityType >
  LagrangePointSetRange(const DiscreteFunctionspaceType& space, const EntityType& entity, const unsigned int subEntity)
    : lp_set_(space.lagrangePointSet(entity))
    , subEntity_(subEntity)
  {}

  SubEntityIteratorType begin() const {
    return lp_set_.template beginSubEntity< faceCodim >(subEntity_);
  }
  SubEntityIteratorType end() const {
    return lp_set_.template endSubEntity< faceCodim >(subEntity_);
  }
};

template < class GridViewTraits>
IntersectionRange<Dune::GridView<GridViewTraits>,
                  typename Dune::GridView<GridViewTraits>::template Codim< 0 >::Entity>
intersectionRange(const Dune::GridView<GridViewTraits>& gridview,
                  const typename Dune::GridView<GridViewTraits>::template Codim< 0 >::Entity& entity)
{
  return IntersectionRange<Dune::GridView<GridViewTraits>,
          typename Dune::GridView<GridViewTraits>::template Codim< 0 >::Entity>(gridview, entity);
}

#if defined(HAVE_DUNE_FEM) && HAVE_DUNE_GRID

template < class GridPartTraits >
IntersectionRange<Dune::GridPartInterface<GridPartTraits>,
                  typename Dune::GridPartInterface<GridPartTraits>::template Codim< 0 >::EntityType>
intersectionRange(const Dune::GridPartInterface<GridPartTraits>& gridpart,
                  const typename Dune::GridPartInterface<GridPartTraits>::template Codim< 0 >::EntityType& entity)
{
  return IntersectionRange<Dune::GridPartInterface<GridPartTraits>,
          typename Dune::GridPartInterface<GridPartTraits>::template Codim< 0 >::EntityType>(gridpart, entity);
}
#endif

template < class GridViewTraits, int codim = 0>
ViewRange<Dune::GridView<GridViewTraits>, codim> viewRange(const Dune::GridView<GridViewTraits>& view)
{
    return ViewRange<Dune::GridView<GridViewTraits>, codim>(view);
}

template < int codim, class DiscreteFunctionspaceType, class EntityType >
LagrangePointSetRange<DiscreteFunctionspaceType,codim>
lagrangePointSetRange(const DiscreteFunctionspaceType& space, const EntityType& entity, const int subEntity) {
  return LagrangePointSetRange<DiscreteFunctionspaceType,codim>(space, entity, subEntity);
}

//! get a vector with values in [start : increment : end)
template < class T, class sequence = std::vector<T> >
sequence valueRange(const T start, const T end, const T increment = Epsilon<T>::value) {
  sequence ret(typename sequence::size_type(std::abs((end-start)/increment)), start);
  typename sequence::size_type i = 0;
  std::generate(std::begin(ret), std::end(ret), [&](){ return start + (increment * i++); });
  return ret;
}

//! get a vector with values in [0 : Epsilon<T> : end)
template < class T, class sequence = std::vector<T> >
sequence valueRange(const T end) {
  return valueRange(T(0),end);
}
} // namespace Common
} // namespace Stuff
} // namespace Dune

#endif // DUNE_STUFF_RANGES_RANGES_HH
/** Copyright (c) 2012, Felix Albrecht, Rene Milk
   * All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions are met:
   *
   * 1. Redistributions of source code must retain the above copyright notice, this
   *    list of conditions and the following disclaimer.
   * 2. 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.
   *
   * 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.
   *
   * The views and conclusions contained in the software and documentation are those
   * of the authors and should not be interpreted as representing official policies,
   * either expressed or implied, of the FreeBSD Project.
   **/
<commit_msg>[common] couple more feature guards for ranges<commit_after>#ifndef DUNE_STUFF_RANGES_RANGES_HH
#define DUNE_STUFF_RANGES_RANGES_HH

#ifdef HAVE_CMAKE_CONFIG
 #include "cmake_config.h"
#else
 #include "config.h"
#endif // ifdef HAVE_CMAKE_CONFIG

#if HAS_STD_BEGIN_END

#if HAVE_DUNE_GRID
#include <dune/grid/common/gridview.hh>
#include <boost/serialization/static_warning.hpp>
#endif

#if HAVE_DUNE_FEM
#include <dune/fem/version.hh>
#include <dune/fem/function/common/discretefunction.hh>
#include <dune/fem/gridpart/common/gridpart.hh>
#endif
#include <dune/stuff/common/math.hh>

namespace std {

#if HAVE_DUNE_FEM

template < class DiscreteFunctionTraits >
auto begin( const Dune::DiscreteFunctionInterface< DiscreteFunctionTraits >& func )
  -> decltype(func.dbegin())
{
  return func.dbegin();
}

template < class DiscreteFunctionTraits >
auto end( const Dune::DiscreteFunctionInterface< DiscreteFunctionTraits >& func )
  -> decltype(func.dend())
{
  return func.dend();
}

template < class DiscreteFunctionTraits >
auto begin( Dune::DiscreteFunctionInterface< DiscreteFunctionTraits >& func )
  -> decltype(func.dbegin())
{
  return func.dbegin();
}

template < class DiscreteFunctionTraits >
auto end( Dune::DiscreteFunctionInterface< DiscreteFunctionTraits >& func )
  -> decltype(func.dend())
{
  return func.dend();
}

#endif

} //namespace std

namespace Dune {
namespace Stuff {
namespace Common {

#if HAVE_DUNE_GRID
//! adapter enabling view usage in range-based for
template < class GridViewType, int codim = 0>
class ViewRange {
  const GridViewType& view_;
public:
  ViewRange(const GridViewType& view)
    :view_(view)
  {
    BOOST_STATIC_WARNING(codim == 0 && "unnecessary ViewRange usage with codim 0");
  }

  typename GridViewType::template Codim< codim >::Iterator
  begin() const {
    return view_.template begin< codim >();
  }
  typename GridViewType::template Codim< codim >::Iterator
  end() const {
    return view_.template end< codim >();
  }
};

template < class GridViewTraits, int codim = 0>
ViewRange<Dune::GridView<GridViewTraits>, codim> viewRange(const Dune::GridView<GridViewTraits>& view)
{
    return ViewRange<Dune::GridView<GridViewTraits>, codim>(view);
}

/** adapter enabling intersectionniterator usage in range-based for
 * works for GridParts and GridViews
 */
template < class GridAbstractionType, class EntityType >
class IntersectionRange {
  const GridAbstractionType& view_;
  const EntityType& entity_;
public:
  IntersectionRange(const GridAbstractionType& view, const EntityType& entity)
    : view_(view)
    , entity_(entity)
  {}

  auto begin() const -> decltype(view_.ibegin(entity_)) {
    return view_.ibegin(entity_);
  }

  auto end() const -> decltype(view_.iend(entity_)) {
    return view_.iend(entity_);
  }
};

template < class GridViewTraits>
IntersectionRange<Dune::GridView<GridViewTraits>,
                  typename Dune::GridView<GridViewTraits>::template Codim< 0 >::Entity>
intersectionRange(const Dune::GridView<GridViewTraits>& gridview,
                  const typename Dune::GridView<GridViewTraits>::template Codim< 0 >::Entity& entity)
{
  return IntersectionRange<Dune::GridView<GridViewTraits>,
          typename Dune::GridView<GridViewTraits>::template Codim< 0 >::Entity>(gridview, entity);
}

#endif //#if HAVE_DUNE_GRID

#if HAVE_DUNE_FEM

//! Range adpater for lagrane points from lagrange spaces
template < class DiscreteFunctionspaceType, int faceCodim >
class LagrangePointSetRange {
  typedef typename DiscreteFunctionspaceType::LagrangePointSetType
    LagrangePointSetType;
  typedef typename LagrangePointSetType::template Codim< faceCodim >::SubEntityIteratorType
    SubEntityIteratorType;
  const LagrangePointSetType& lp_set_;
  const unsigned int subEntity_;

public:
  /** the template isn't lazyness here, the underlying set is templated on it too
   */
  template < class EntityType >
  LagrangePointSetRange(const DiscreteFunctionspaceType& space, const EntityType& entity, const unsigned int subEntity)
    : lp_set_(space.lagrangePointSet(entity))
    , subEntity_(subEntity)
  {}

  SubEntityIteratorType begin() const {
    return lp_set_.template beginSubEntity< faceCodim >(subEntity_);
  }
  SubEntityIteratorType end() const {
    return lp_set_.template endSubEntity< faceCodim >(subEntity_);
  }
};

template < int codim, class DiscreteFunctionspaceType, class EntityType >
LagrangePointSetRange<DiscreteFunctionspaceType,codim>
lagrangePointSetRange(const DiscreteFunctionspaceType& space, const EntityType& entity, const int subEntity) {
  return LagrangePointSetRange<DiscreteFunctionspaceType,codim>(space, entity, subEntity);
}

template < class GridPartTraits >
IntersectionRange<Dune::GridPartInterface<GridPartTraits>,
                  typename Dune::GridPartInterface<GridPartTraits>::template Codim< 0 >::EntityType>
intersectionRange(const Dune::GridPartInterface<GridPartTraits>& gridpart,
                  const typename Dune::GridPartInterface<GridPartTraits>::template Codim< 0 >::EntityType& entity)
{
  return IntersectionRange<Dune::GridPartInterface<GridPartTraits>,
          typename Dune::GridPartInterface<GridPartTraits>::template Codim< 0 >::EntityType>(gridpart, entity);
}
#endif //HAVE_DUNE_FEM

//! get a vector with values in [start : increment : end)
template < class T, class sequence = std::vector<T> >
sequence valueRange(const T start, const T end, const T increment = Epsilon<T>::value) {
  sequence ret(typename sequence::size_type(std::abs((end-start)/increment)), start);
  typename sequence::size_type i = 0;
  std::generate(std::begin(ret), std::end(ret), [&](){ return start + (increment * i++); });
  return ret;
}

//! get a vector with values in [0 : Epsilon<T> : end)
template < class T, class sequence = std::vector<T> >
sequence valueRange(const T end) {
  return valueRange(T(0),end);
}

} // namespace Common
} // namespace Stuff
} // namespace Dune

#endif //HAS_STD_BEGIN_END

#endif // DUNE_STUFF_RANGES_RANGES_HH
/** Copyright (c) 2012, Felix Albrecht, Rene Milk
   * All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions are met:
   *
   * 1. Redistributions of source code must retain the above copyright notice, this
   *    list of conditions and the following disclaimer.
   * 2. 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.
   *
   * 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.
   *
   * The views and conclusions contained in the software and documentation are those
   * of the authors and should not be interpreted as representing official policies,
   * either expressed or implied, of the FreeBSD Project.
   **/
<|endoftext|>


<commit_before>/*
 * 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; version 3 of the License.
 *
 * 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.
 */

#include "resultview.h"

#include "../iconmanager.h"

ResultView::ResultView(QWidget *parent)
  : QWidget(parent)
{
  setupUi(this);
  table->setModel(0);
  currentAction = Browse;
  offset = 0;
  m_mode = QueryMode;
  shortModel = new QStandardItemModel(this);
  table->setModel(shortModel);

  setupMenus();
  setupConnections();

  // loading icons from theme
  firstPageButton->setIcon(IconManager::get("go-first"));
  lastPageButton->setIcon(IconManager::get("go-last"));
  nextPageButton->setIcon(IconManager::get("go-next"));
  prevPageButton->setIcon(IconManager::get("go-previous"));
  reloadButton->setIcon(IconManager::get("view-refresh"));
  insertButton->setIcon(IconManager::get("list-add"));
  deleteButton->setIcon(IconManager::get("list-remove"));
}

void ResultView::contextMenuEvent(QContextMenuEvent *e)
{
  if(e->reason() != QContextMenuEvent::Mouse
     || !table->geometry().contains(e->pos())
     || model == 0)
    return;

  if( model->columnCount() == 0 || model->rowCount() == 0 )
    return;

  actionExport->setEnabled(m_mode == QueryMode);

  contextMenu->move(e->globalPos());
  contextMenu->exec();
}

void ResultView::exportContent()
{
  if( model == 0 )
    return;

  if( model->columnCount() == 0 || model->rowCount() == 0 )
    return;

//  exportWizard = new ExportWizard(model, this);
  exportWizard = new ExportWizard(m_token, this);
  exportWizard->exec();
}

/**
 * Clic sur le bouton supprimer : peut annuler l'opération en cours ou supprimer
 * la ligne en cours.
 */
void ResultView::on_deleteButton_clicked()
{
  if(m_mode != TableMode)
    return;

  QSqlTableModel *tmodel = (QSqlTableModel*) model;

  if (currentAction != Browse) {
    // Annulation de l'opération en cours
    insertButton->setIcon(IconManager::get("list-add"));
    deleteButton->setIcon(IconManager::get("list-remove"));

    currentAction = Browse;
    tmodel->revertAll();
  } else {
    // suppression des lignes sélectionnées
    QSet<int> rows;
    foreach(QModelIndex i, table->selectionModel()->selectedIndexes())
      rows << (i.row() + offset);

    foreach(int r, rows)
      model->removeRow(r);

    tmodel->submitAll();
  }

  updateView();
}

/**
 * Clic sur le bouton d'insertion : peut passer en mode insertion ou valider un
 * ajout/modif.
 */
void ResultView::on_insertButton_clicked()
{
  if(m_mode != TableMode)
    return;

  if (currentAction == Insert || currentAction == Update) {
    insertButton->setIcon(IconManager::get("list-add"));
    deleteButton->setIcon(IconManager::get("list-remove"));

    QSqlTableModel *tmodel = (QSqlTableModel*) model;

    foreach (int row, modifiedRecords.keys()) {
      tmodel->setRecord(row, modifiedRecords[row]);
    }

    if (!tmodel->submitAll()) {
      QMessageBox::critical(this, "Error", tmodel->lastError().text());
    }

    currentAction = Browse;
    tmodel->select();
    updateView();
  } else {
    insertButton->setIcon(QIcon());
    insertButton->setText(tr("Apply"));
    deleteButton->setIcon(QIcon());
    deleteButton->setText(tr("Cancel"));

    model->insertRow(model->rowCount());
    currentAction = Insert;
    updateView();
    table->scrollToBottom();
  }
}

void ResultView::on_reloadButton_clicked()
{
  switch (m_mode) {
  case QueryMode:
    emit reloadRequested();
    break;

  case TableMode:
    ((QSqlTableModel*) model)->select();
    updateView();
    break;
  }
}

void ResultView::resizeColumnsToContents()
{
  table->resizeColumnsToContents();
}

void ResultView::resizeRowsToContents()
{
  table->resizeRowsToContents();
}

void ResultView::scrollBegin()
{
  offset = 0;
  updateView();
}

void ResultView::scrollDown()
{
  offset += resultSpinBox->value();
  updateView();
}

void ResultView::scrollEnd()
{
  double last;
  modf(model->rowCount() / resultSpinBox->value(), &last);

  offset = last * resultSpinBox->value();
  updateView();
}

void ResultView::scrollUp()
{
  offset -= resultSpinBox->value();
  updateView();
}

void ResultView::setAlternatingRowColors(bool enable)
{
  table->setAlternatingRowColors(enable);
}

void ResultView::setMode(Mode m)
{
  m_mode = m;

  switch(m_mode)
  {
  case QueryMode:
    insertButton->setVisible(false);
    deleteButton->setVisible(false);
    break;

  case TableMode:
    insertButton->setVisible(true);
    deleteButton->setVisible(true);
    break;
  }
}

void ResultView::setModel(QSqlQueryModel *model)
{
  this->model = model;
  updateView();
}

void ResultView::setRowsPerPage(int rowPP)
{
  resultSpinBox->setValue(rowPP);
}

void ResultView::setTable(QString table, QSqlDatabase *db)
{
  setMode(TableMode);
  QSqlTableModel *m = new QSqlTableModel(this, *db);
  m->setTable(table);
  m->setEditStrategy(QSqlTableModel::OnManualSubmit);
  m->select();
  if(m->lastError().type() == QSqlError::NoError)
  {
    setModel(m);
  } else {
    QMessageBox::critical(this,
                          tr("Error"),
                          tr("The specified table doesn't exist"),
                          QMessageBox::Ok);
  }
}

void ResultView::setToken(QueryToken *token)
{
  setMode(QueryMode);
  m_token = token;
  offset = 0;

  setModel(m_token->model());
}

void ResultView::setupConnections()
{
  connect(actionAlternateColor, SIGNAL(toggled(bool)),
          this, SLOT(setAlternatingRowColors(bool)));
  connect(actionExport, SIGNAL(triggered()), this, SLOT(exportContent()));

  connect(firstPageButton, SIGNAL(clicked()), this, SLOT(scrollBegin()));
  connect(prevPageButton, SIGNAL(clicked()), this, SLOT(scrollUp()));
  connect(nextPageButton, SIGNAL(clicked()), this, SLOT(scrollDown()));
  connect(lastPageButton, SIGNAL(clicked()), this, SLOT(scrollEnd()));

  connect(reloadButton, SIGNAL(clicked()), this, SLOT(on_reloadButton_clicked()));
  connect(resultSpinBox, SIGNAL(valueChanged(int)), this, SLOT(updateView()));

  connect(deleteButton, SIGNAL(clicked()), this, SLOT(on_deleteButton_clicked()));

  connect(shortModel, SIGNAL(itemChanged(QStandardItem*)),
          this, SLOT(updateItem(QStandardItem*)));
}

void ResultView::setupMenus()
{
  contextMenu = new QMenu(this);

  actionAlternateColor = new QAction(tr("Alternate row colors"), this);
  actionAlternateColor->setCheckable(true);
  actionAlternateColor->setChecked(false);
  contextMenu->addAction(actionAlternateColor);

  actionExport = new QAction(tr("Export"), this);
  actionExport->setIcon(IconManager::get("document-save-as"));
  actionExport->setShortcut(QKeySequence("Ctrl+E"));
  contextMenu->addAction(actionExport);
}

/**
 * Called by the shortmodel's signal dataChanged in order to forward it to the
 * real one.
 */
void ResultView::updateItem(QStandardItem *item)
{
  if (currentAction == Browse) {
    currentAction = Update;
    insertButton->setText(tr("Apply"));
    deleteButton->setText(tr("Cancel"));
  }

  QSqlRecord record;
  int row = item->row() + offset;
  if (modifiedRecords.contains(row)) {
    record = modifiedRecords[row];
  } else {
    record = model->record(row);
  }
  record.setValue(item->column(), item->data(Qt::DisplayRole));
  modifiedRecords[row] = record;
}

void ResultView::updateView()
{
  shortModel->clear();

  if(model->rowCount() == 0)
    return;

  int startIndex;
  startIndex = offset;
  if(startIndex > model->rowCount())
    startIndex = model->rowCount() - resultSpinBox->value();
  if(startIndex < 0)
    startIndex = 0;

  double page, maxpage;
  modf(startIndex / resultSpinBox->value(), &page);
  modf(model->rowCount() / resultSpinBox->value(), &maxpage);
  pageLabel->setText(tr("Page %1/%2")
                     .arg(page+1)
                     .arg(maxpage+1));

  int endIndex;
  endIndex = startIndex + resultSpinBox->value();
  if(endIndex > model->rowCount())
    endIndex = model->rowCount();

  firstPageButton->setEnabled(startIndex > 0);
  prevPageButton->setEnabled(startIndex > 0);
  nextPageButton->setEnabled(endIndex < model->rowCount());
  lastPageButton->setEnabled(endIndex < model->rowCount());

  for(int i=0; i<model->columnCount(); i++)
    shortModel->setHorizontalHeaderItem(i, new QStandardItem(
        model->headerData(i, Qt::Horizontal).toString()));

  QStandardItem *item;
  QStringList vlabels;
  QSqlRecord r;
  QList<QStandardItem*> row;
  for(int i=startIndex; i<endIndex; i++)
  {
    row.clear();
    r = model->record(i);
    for(int j=0; j<model->columnCount(); j++)
    {
      item = new QStandardItem();
      item->setData( r.value( j ), Qt::DisplayRole );
      row << item;
    }
    shortModel->appendRow(row);
    vlabels << QString::number(i+1);
  }
  if(currentAction == Insert)
  {
    vlabels.removeLast();
    vlabels << "*";
  }
  shortModel->setVerticalHeaderLabels(vlabels);

  resizeColumnsToContents();
  resizeRowsToContents();
}
<commit_msg>Petit bogue cosmetique<commit_after>/*
 * 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; version 3 of the License.
 *
 * 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.
 */

#include "resultview.h"

#include "../iconmanager.h"

ResultView::ResultView(QWidget *parent)
  : QWidget(parent)
{
  setupUi(this);
  table->setModel(0);
  currentAction = Browse;
  offset = 0;
  m_mode = QueryMode;
  shortModel = new QStandardItemModel(this);
  table->setModel(shortModel);

  setupMenus();
  setupConnections();

  // loading icons from theme
  firstPageButton->setIcon(IconManager::get("go-first"));
  lastPageButton->setIcon(IconManager::get("go-last"));
  nextPageButton->setIcon(IconManager::get("go-next"));
  prevPageButton->setIcon(IconManager::get("go-previous"));
  reloadButton->setIcon(IconManager::get("view-refresh"));
  insertButton->setIcon(IconManager::get("list-add"));
  deleteButton->setIcon(IconManager::get("list-remove"));
}

void ResultView::contextMenuEvent(QContextMenuEvent *e)
{
  if(e->reason() != QContextMenuEvent::Mouse
     || !table->geometry().contains(e->pos())
     || model == 0)
    return;

  if( model->columnCount() == 0 || model->rowCount() == 0 )
    return;

  actionExport->setEnabled(m_mode == QueryMode);

  contextMenu->move(e->globalPos());
  contextMenu->exec();
}

void ResultView::exportContent()
{
  if( model == 0 )
    return;

  if( model->columnCount() == 0 || model->rowCount() == 0 )
    return;

//  exportWizard = new ExportWizard(model, this);
  exportWizard = new ExportWizard(m_token, this);
  exportWizard->exec();
}

/**
 * Clic sur le bouton supprimer : peut annuler l'opération en cours ou supprimer
 * la ligne en cours.
 */
void ResultView::on_deleteButton_clicked()
{
  if(m_mode != TableMode)
    return;

  QSqlTableModel *tmodel = (QSqlTableModel*) model;

  if (currentAction != Browse) {
    // Annulation de l'opération en cours
    insertButton->setIcon(IconManager::get("list-add"));
    deleteButton->setIcon(IconManager::get("list-remove"));

    currentAction = Browse;
    tmodel->revertAll();
  } else {
    // suppression des lignes sélectionnées
    QSet<int> rows;
    foreach(QModelIndex i, table->selectionModel()->selectedIndexes())
      rows << (i.row() + offset);

    foreach(int r, rows)
      model->removeRow(r);

    tmodel->submitAll();
  }

  updateView();
}

/**
 * Clic sur le bouton d'insertion : peut passer en mode insertion ou valider un
 * ajout/modif.
 */
void ResultView::on_insertButton_clicked()
{
  if(m_mode != TableMode)
    return;

  if (currentAction == Insert || currentAction == Update) {
    insertButton->setIcon(IconManager::get("list-add"));
    deleteButton->setIcon(IconManager::get("list-remove"));

    QSqlTableModel *tmodel = (QSqlTableModel*) model;

    foreach (int row, modifiedRecords.keys()) {
      tmodel->setRecord(row, modifiedRecords[row]);
    }

    if (!tmodel->submitAll()) {
      QMessageBox::critical(this, "Error", tmodel->lastError().text());
    }

    currentAction = Browse;
    tmodel->select();
    updateView();
  } else {
    insertButton->setIcon(QIcon());
    insertButton->setText(tr("Apply"));
    deleteButton->setIcon(QIcon());
    deleteButton->setText(tr("Cancel"));

    model->insertRow(model->rowCount());
    currentAction = Insert;
    updateView();
    table->scrollToBottom();
  }
}

void ResultView::on_reloadButton_clicked()
{
  switch (m_mode) {
  case QueryMode:
    emit reloadRequested();
    break;

  case TableMode:
    ((QSqlTableModel*) model)->select();
    updateView();
    break;
  }
}

void ResultView::resizeColumnsToContents()
{
  table->resizeColumnsToContents();
}

void ResultView::resizeRowsToContents()
{
  table->resizeRowsToContents();
}

void ResultView::scrollBegin()
{
  offset = 0;
  updateView();
}

void ResultView::scrollDown()
{
  offset += resultSpinBox->value();
  updateView();
}

void ResultView::scrollEnd()
{
  double last;
  modf(model->rowCount() / resultSpinBox->value(), &last);

  offset = last * resultSpinBox->value();
  updateView();
}

void ResultView::scrollUp()
{
  offset -= resultSpinBox->value();
  updateView();
}

void ResultView::setAlternatingRowColors(bool enable)
{
  table->setAlternatingRowColors(enable);
}

void ResultView::setMode(Mode m)
{
  m_mode = m;

  switch(m_mode)
  {
  case QueryMode:
    insertButton->setVisible(false);
    deleteButton->setVisible(false);
    break;

  case TableMode:
    insertButton->setVisible(true);
    deleteButton->setVisible(true);
    break;
  }
}

void ResultView::setModel(QSqlQueryModel *model)
{
  this->model = model;
  updateView();
}

void ResultView::setRowsPerPage(int rowPP)
{
  resultSpinBox->setValue(rowPP);
}

void ResultView::setTable(QString table, QSqlDatabase *db)
{
  setMode(TableMode);
  QSqlTableModel *m = new QSqlTableModel(this, *db);
  m->setTable(table);
  m->setEditStrategy(QSqlTableModel::OnManualSubmit);
  m->select();
  if(m->lastError().type() == QSqlError::NoError)
  {
    setModel(m);
  } else {
    QMessageBox::critical(this,
                          tr("Error"),
                          tr("The specified table doesn't exist"),
                          QMessageBox::Ok);
  }
}

void ResultView::setToken(QueryToken *token)
{
  setMode(QueryMode);
  m_token = token;
  offset = 0;

  setModel(m_token->model());
}

void ResultView::setupConnections()
{
  connect(actionAlternateColor, SIGNAL(toggled(bool)),
          this, SLOT(setAlternatingRowColors(bool)));
  connect(actionExport, SIGNAL(triggered()), this, SLOT(exportContent()));

  connect(firstPageButton, SIGNAL(clicked()), this, SLOT(scrollBegin()));
  connect(prevPageButton, SIGNAL(clicked()), this, SLOT(scrollUp()));
  connect(nextPageButton, SIGNAL(clicked()), this, SLOT(scrollDown()));
  connect(lastPageButton, SIGNAL(clicked()), this, SLOT(scrollEnd()));

  connect(reloadButton, SIGNAL(clicked()), this, SLOT(on_reloadButton_clicked()));
  connect(resultSpinBox, SIGNAL(valueChanged(int)), this, SLOT(updateView()));

  connect(deleteButton, SIGNAL(clicked()), this, SLOT(on_deleteButton_clicked()));

  connect(shortModel, SIGNAL(itemChanged(QStandardItem*)),
          this, SLOT(updateItem(QStandardItem*)));
}

void ResultView::setupMenus()
{
  contextMenu = new QMenu(this);

  actionAlternateColor = new QAction(tr("Alternate row colors"), this);
  actionAlternateColor->setCheckable(true);
  actionAlternateColor->setChecked(false);
  contextMenu->addAction(actionAlternateColor);

  actionExport = new QAction(tr("Export"), this);
  actionExport->setIcon(IconManager::get("document-save-as"));
  actionExport->setShortcut(QKeySequence("Ctrl+E"));
  contextMenu->addAction(actionExport);
}

/**
 * Called by the shortmodel's signal dataChanged in order to forward it to the
 * real one.
 */
void ResultView::updateItem(QStandardItem *item)
{
  if (currentAction == Browse) {
    currentAction = Update;
    insertButton->setIcon(QIcon());
    insertButton->setText(tr("Apply"));
    deleteButton->setIcon(QIcon());
    deleteButton->setText(tr("Cancel"));
  }

  QSqlRecord record;
  int row = item->row() + offset;
  if (modifiedRecords.contains(row)) {
    record = modifiedRecords[row];
  } else {
    record = model->record(row);
  }
  record.setValue(item->column(), item->data(Qt::DisplayRole));
  modifiedRecords[row] = record;
}

void ResultView::updateView()
{
  shortModel->clear();

  if(model->rowCount() == 0)
    return;

  int startIndex;
  startIndex = offset;
  if(startIndex > model->rowCount())
    startIndex = model->rowCount() - resultSpinBox->value();
  if(startIndex < 0)
    startIndex = 0;

  double page, maxpage;
  modf(startIndex / resultSpinBox->value(), &page);
  modf(model->rowCount() / resultSpinBox->value(), &maxpage);
  pageLabel->setText(tr("Page %1/%2")
                     .arg(page+1)
                     .arg(maxpage+1));

  int endIndex;
  endIndex = startIndex + resultSpinBox->value();
  if(endIndex > model->rowCount())
    endIndex = model->rowCount();

  firstPageButton->setEnabled(startIndex > 0);
  prevPageButton->setEnabled(startIndex > 0);
  nextPageButton->setEnabled(endIndex < model->rowCount());
  lastPageButton->setEnabled(endIndex < model->rowCount());

  for(int i=0; i<model->columnCount(); i++)
    shortModel->setHorizontalHeaderItem(i, new QStandardItem(
        model->headerData(i, Qt::Horizontal).toString()));

  QStandardItem *item;
  QStringList vlabels;
  QSqlRecord r;
  QList<QStandardItem*> row;
  for(int i=startIndex; i<endIndex; i++)
  {
    row.clear();
    r = model->record(i);
    for(int j=0; j<model->columnCount(); j++)
    {
      item = new QStandardItem();
      item->setData( r.value( j ), Qt::DisplayRole );
      row << item;
    }
    shortModel->appendRow(row);
    vlabels << QString::number(i+1);
  }
  if(currentAction == Insert)
  {
    vlabels.removeLast();
    vlabels << "*";
  }
  shortModel->setVerticalHeaderLabels(vlabels);

  resizeColumnsToContents();
  resizeRowsToContents();
}
<|endoftext|>