<commit_before>/*
 * VapourSynth D2V Plugin
 *
 * Copyright (c) 2012 Derek Buitenhuis
 *
 * This file is part of d2vsource.
 *
 * d2vsource 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.
 *
 * d2vsource 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 d2vsource; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include <iostream>
#include <string>
#include <vector>

extern "C" {
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <stdio.h>
}

#include "compat.hpp"
#include "d2v.hpp"
#include "decode.hpp"
#include "gop.hpp"

using namespace std;

/*
 * AVIO seek function to handle GOP offsets and multi-file support
 * in libavformat without it knowing about it.
 */
static int64_t file_seek(void *opaque, int64_t offset, int whence)
{
    decodecontext *ctx = (decodecontext *) opaque;

    switch(whence) {
    case SEEK_SET: {
        /*
         * This mutli-file seek is likely very broken, but I don't
         * really care much, since it is only used in avformat_find_stream_info,
         * which does its job fine as-is.
         */
        int64_t real_offset = offset + ctx->orig_file_offset;
        unsigned int i;

        for(i = ctx->orig_file; i < ctx->cur_file; i++)
            real_offset -= ctx->file_sizes[i];

        while(real_offset > ctx->file_sizes[ctx->cur_file] && ctx->cur_file != ctx->files.size() - 1) {
            real_offset -= ctx->file_sizes[ctx->cur_file];
            ctx->cur_file++;
        }

        while(real_offset < 0 && ctx->cur_file) {
            ctx->cur_file--;
            real_offset += ctx->file_sizes[ctx->cur_file];
        }

        fseeko(ctx->files[ctx->cur_file], real_offset, SEEK_SET);

        return offset;
    }
    case AVSEEK_SIZE: {
        /*
         * Return the total filesize of all files combined,
         * adjusted for GOP offset.
         */
        int64_t size = -(ctx->orig_file_offset);
        unsigned int i;

        for(i = ctx->orig_file; i < ctx->file_sizes.size(); i++)
            size += ctx->file_sizes[i];

        return size;
    }
    default:
        /* Shouldn't need to support anything else for our use case. */
        cout << "Unsupported seek!" << endl;
        return -1;
    }
}

/*
 * AVIO packet reading function to handle GOP offsets and multi-file support
 * in libavformat without it knowing about it.
 */
static int read_packet(void *opaque, uint8_t *buf, int size)
{
    decodecontext *ctx = (decodecontext *) opaque;
    int ret;

    /*
     * If we read in less than we got asked for, and we're
     * not on the last file, then start reading seamlessly
     * on the next file.
     */
    ret = fread(buf, 1, size, ctx->files[ctx->cur_file]);
    if (ret < size && ctx->cur_file != ctx->files.size() - 1) {
        ctx->cur_file++;
        fseeko(ctx->files[ctx->cur_file], 0, SEEK_SET);
        fread(buf + ret, 1, size - ret, ctx->files[ctx->cur_file]);
    } else {
        return ret;
    }

    return size;
}

/* Conditionally free all memebers of decodecontext. */
void decodefreep(decodecontext **ctx)
{
    decodecontext *lctx = *ctx;
    unsigned int i;

    if (!lctx)
        return;

    av_freep(&lctx->in);
    av_free_packet(&lctx->inpkt);

    if (lctx->fctx) {
        if (lctx->fctx->pb)
            av_freep(&lctx->fctx->pb);

        avformat_close_input(&lctx->fctx);
    }

    for(i = 0; i < lctx->files.size(); i++)
        fclose(lctx->files[i]);

    lctx->files.clear();
    lctx->file_sizes.clear();

    if (lctx->avctx) {
        avcodec_close(lctx->avctx);
        av_freep(&lctx->avctx);
    }

    delete lctx->fakename;
    delete lctx;

    *ctx = NULL;
}

/* Initialize everything we can with regards to decoding */
decodecontext *decodeinit(d2vcontext *dctx, string& err)
{
    decodecontext *ret;
    int i, av_ret;

    ret = new decodecontext;

    /* Zero the context to aid in conditional freeing later. */
    memset(ret, 0, sizeof(*ret));

    /* Holds our "filename" we pass to libavformat. */
    ret->fakename = new string;

    /* Set our stream index to -1 (uninitialized). */
    ret->stream_index = -1;

    /* Open each file and stash its size. */
    for(i = 0; i < dctx->num_files; i++) {
        FILE *in;
        int64_t size;

        in = fopen(dctx->files[i].c_str(), "rb");
        if (!in) {
            err  = "Cannot open file: ";
            err += dctx->files[i];
            goto fail;
        }

        fseeko(in, 0, SEEK_END);
        size = ftello(in);
        fseeko(in, 0, SEEK_SET);

        ret->file_sizes.push_back(size);
        ret->files.push_back(in);
    }

    /*
     * Register all of our demuxers, parsers, and decoders.
     * Ideally, to create a smaller binary, we only enable the
     * following:
     *
     * Demuxers: mpegvideo, mpegps, mpegts.
     * Parsers: mpegvideo, mpegaudio.
     * Decoders: mpeg1video, mpeg2video.
     */
    avcodec_register_all();
    av_register_all();

    /* Set the correct decoder. */
    if (dctx->mpeg_type == 1) {
        ret->incodec = avcodec_find_decoder(AV_CODEC_ID_MPEG1VIDEO);
    } else if (dctx->mpeg_type == 2) {
        ret->incodec = avcodec_find_decoder(AV_CODEC_ID_MPEG2VIDEO);
    } else {
        err = "Invalid MPEG Type.";
        goto fail;
    }

    /* Allocate the codec's context. */
    ret->avctx = avcodec_alloc_context3(ret->incodec);
    if (!ret->avctx) {
        err = "Cannot allocate AVCodecContext.";
        goto fail;
    }

    /* Set the IDCT algorithm. */
    ret->avctx->idct_algo = dctx->idct_algo;

    /*
     * Enable EMU_EDGE so that we can use buffers that are
     * not padded by 32 pixels.
     */
    ret->avctx->flags |= CODEC_FLAG_EMU_EDGE;

    /* Open it. */
    av_ret = avcodec_open2(ret->avctx, ret->incodec, NULL);
    if (av_ret < 0) {
        err = "Cannot open decoder.";
        goto fail;
    }

    /* Allocate the scratch buffer for our custom AVIO context. */
    ret->in = (uint8_t *) av_malloc(32 * 1024);
    if (!ret->in) {
        err = "Cannot alloc inbuf.";
        goto fail;
    }

    /* We don't want to hear all the info it has. */
    av_log_set_level(AV_LOG_PANIC);

    return ret;

fail:
    decodefreep(&ret);
    return NULL;
}

int decodeframe(int frame_num, d2vcontext *ctx, decodecontext *dctx, AVFrame *out, string& err)
{
    frame f;
    gop g;
    unsigned int i;
    int o, j, av_ret, offset;
    bool next;

    /* Get our frame and the GOP its in. */
    f = ctx->frames[frame_num];
    g = ctx->gops[f.gop];

    /*
     * The offset is how many frames we have to decode from our
     * current position in order to get to the frame we want.
     * The initial offset is obtaiend during the parsing of the
     * D2V file, but it may be more in an open GOP situation,
     * which we handle below.
     */
    offset = f.offset;

    /*
     * If we're in a open GOP situation, then start decoding
     * from the previous GOP (one at most is needed), and adjust
     * out offset accordingly.
     */
    if (!(g.info & GOP_FLAG_CLOSED) && (f.gop - 1 > 0)) {
        int n = frame_num;
        frame t = ctx->frames[n];

        g = ctx->gops[f.gop - 1];

        /*
         * Find the offset of the last frame in the
         * previous GOP and add it to our offset.
         */
        while(t.offset)
            t = ctx->frames[--n];

        t = ctx->frames[--n];

        /*
         * Subtract one from the offset to compensate for
         * libavcodec delay, I think.
         */
        offset += t.offset - 1;
    }

    /*
     * Check if we're decoding linearly, and if the GOP
     * of the current frame and previous frame are either
     * the same, or also linear. If so, we can decode
     * linearly.
     */
    next = (dctx->last_gop == f.gop || dctx->last_gop == f.gop - 1) && dctx->last_frame == frame_num - 1;

    /* Skip GOP initialization if we're decoding linearly. */
    if (!next) {
        /* Free out format and AVIO contexts from the previous seek. */
        if (dctx->fctx) {
            if (dctx->fctx->pb)
                av_freep(&dctx->fctx->pb);

            avformat_close_input(&dctx->fctx);
        }

        /* Seek to our GOP offset and stash the info. */
        fseeko(dctx->files[g.file], g.pos, SEEK_SET);
        dctx->orig_file_offset = g.pos;
        dctx->orig_file        = g.file;
        dctx->cur_file         = g.file;

        /* Allocate format context. */
        dctx->fctx = avformat_alloc_context();
        if (!dctx->fctx) {
            err = "Cannot allocate AVFormatContext.";
            goto dfail;
        }

        /*
         * Find the demuxer for our input type, and also set
         * the "filename" that we pass to libavformat when
         * we open the demuxer with our custom AVIO context.
         */
        if (ctx->stream_type == ELEMENTARY) {
            dctx->fctx->iformat = av_find_input_format("mpegvideo");
            *dctx->fakename      = "fakevideo.m2v";
        } else if (ctx->stream_type == PROGRAM) {
            dctx->fctx->iformat = av_find_input_format("mpeg");
            *dctx->fakename      = "fakevideo.vob";
        } else if (ctx->stream_type == TRANSPORT) {
            dctx->fctx->iformat = av_find_input_format("mpegts");
            *dctx->fakename      = "fakevideo.ts";
        } else {
            err = "Unsupported format.";
            goto dfail;
        }

        /*
         * Initialize out custom AVIO context that libavformat
         * will use instead of a file. It uses our custom packet
         * reading and seeking functions that transparently work
         * with our indexed GOP offsets and multiple files.
         */
        dctx->fctx->pb = avio_alloc_context(dctx->in, 32 * 1024, 0, dctx, read_packet, NULL, file_seek);

        /* Open the demuxer. */
        av_ret = avformat_open_input(&dctx->fctx, (*dctx->fakename).c_str(), NULL, NULL);
        if (av_ret < 0) {
            err = "Cannot open buffer in libavformat.";
            goto dfail;
        }

        /*
         * Flush the buffers of our codec's context so we
         * don't need to re-initialize it.
         */
        avcodec_flush_buffers(dctx->avctx);

        /*
         * Call the abomination function to find out
         * how many streams we have.
         */
        avformat_find_stream_info(dctx->fctx, NULL);

        /* Free and re-initialize any existing packet. */
        av_free_packet(&dctx->inpkt);
        av_init_packet(&dctx->inpkt);
    }

    /* Set our stream index if we need to. */
    if (dctx->stream_index == -1) {
        for(i = 0; i < dctx->fctx->nb_streams; i++) {
            if (dctx->fctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
                dctx->stream_index = (int) i;
                break;
            }
        }
    }

    /*
     * We don't need to read a new packet in if we are decoding
     * linearly, since it's still there from the previous iteration.
     */
    if (!next)
        av_read_frame(dctx->fctx, &dctx->inpkt);

    /* If we're decoding linearly, there is obviously no offset. */
    o = next ? 0 : offset;
    for(j = 0; j <= o; j++) {
        while(dctx->inpkt.stream_index != dctx->stream_index) {
            av_free_packet(&dctx->inpkt);
            av_read_frame(dctx->fctx, &dctx->inpkt);
        }

        /*
         * Loop until we have a whole frame, since there can be
         * multi-packet frames.
         */
        av_ret = 0;
        while(!av_ret) {
            AVPacket orig = dctx->inpkt;

            /*
             * Decoding might not consume out whole packet, so
             * stash the original packet info, loop until it
             * is all consumed, and then restore it, it so
             * we can free it properly.
             */
            while(dctx->inpkt.size > 0) {
                int r = avcodec_decode_video2(dctx->avctx, out, &av_ret, &dctx->inpkt);

                dctx->inpkt.size -= r;
                dctx->inpkt.data += r;
            }

            dctx->inpkt = orig;
            av_free_packet(&dctx->inpkt);

            av_read_frame(dctx->fctx, &dctx->inpkt);
        }
    }

    /*
     * Stash the frame number we just decoded, and the GOP it
     * is a part of so we can check if we're decoding linearly
     * later on.
     */
    dctx->last_gop   = f.gop;
    dctx->last_frame = frame_num;

    return 0;

dfail:
    avformat_close_input(&dctx->fctx);
    return -1;
}
<commit_msg>Account for interleaved streams while decoding frames<commit_after>/*
 * VapourSynth D2V Plugin
 *
 * Copyright (c) 2012 Derek Buitenhuis
 *
 * This file is part of d2vsource.
 *
 * d2vsource 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.
 *
 * d2vsource 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 d2vsource; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include <iostream>
#include <string>
#include <vector>

extern "C" {
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <stdio.h>
}

#include "compat.hpp"
#include "d2v.hpp"
#include "decode.hpp"
#include "gop.hpp"

using namespace std;

/*
 * AVIO seek function to handle GOP offsets and multi-file support
 * in libavformat without it knowing about it.
 */
static int64_t file_seek(void *opaque, int64_t offset, int whence)
{
    decodecontext *ctx = (decodecontext *) opaque;

    switch(whence) {
    case SEEK_SET: {
        /*
         * This mutli-file seek is likely very broken, but I don't
         * really care much, since it is only used in avformat_find_stream_info,
         * which does its job fine as-is.
         */
        int64_t real_offset = offset + ctx->orig_file_offset;
        unsigned int i;

        for(i = ctx->orig_file; i < ctx->cur_file; i++)
            real_offset -= ctx->file_sizes[i];

        while(real_offset > ctx->file_sizes[ctx->cur_file] && ctx->cur_file != ctx->files.size() - 1) {
            real_offset -= ctx->file_sizes[ctx->cur_file];
            ctx->cur_file++;
        }

        while(real_offset < 0 && ctx->cur_file) {
            ctx->cur_file--;
            real_offset += ctx->file_sizes[ctx->cur_file];
        }

        fseeko(ctx->files[ctx->cur_file], real_offset, SEEK_SET);

        return offset;
    }
    case AVSEEK_SIZE: {
        /*
         * Return the total filesize of all files combined,
         * adjusted for GOP offset.
         */
        int64_t size = -(ctx->orig_file_offset);
        unsigned int i;

        for(i = ctx->orig_file; i < ctx->file_sizes.size(); i++)
            size += ctx->file_sizes[i];

        return size;
    }
    default:
        /* Shouldn't need to support anything else for our use case. */
        cout << "Unsupported seek!" << endl;
        return -1;
    }
}

/*
 * AVIO packet reading function to handle GOP offsets and multi-file support
 * in libavformat without it knowing about it.
 */
static int read_packet(void *opaque, uint8_t *buf, int size)
{
    decodecontext *ctx = (decodecontext *) opaque;
    int ret;

    /*
     * If we read in less than we got asked for, and we're
     * not on the last file, then start reading seamlessly
     * on the next file.
     */
    ret = fread(buf, 1, size, ctx->files[ctx->cur_file]);
    if (ret < size && ctx->cur_file != ctx->files.size() - 1) {
        ctx->cur_file++;
        fseeko(ctx->files[ctx->cur_file], 0, SEEK_SET);
        fread(buf + ret, 1, size - ret, ctx->files[ctx->cur_file]);
    } else {
        return ret;
    }

    return size;
}

/* Conditionally free all memebers of decodecontext. */
void decodefreep(decodecontext **ctx)
{
    decodecontext *lctx = *ctx;
    unsigned int i;

    if (!lctx)
        return;

    av_freep(&lctx->in);
    av_free_packet(&lctx->inpkt);

    if (lctx->fctx) {
        if (lctx->fctx->pb)
            av_freep(&lctx->fctx->pb);

        avformat_close_input(&lctx->fctx);
    }

    for(i = 0; i < lctx->files.size(); i++)
        fclose(lctx->files[i]);

    lctx->files.clear();
    lctx->file_sizes.clear();

    if (lctx->avctx) {
        avcodec_close(lctx->avctx);
        av_freep(&lctx->avctx);
    }

    delete lctx->fakename;
    delete lctx;

    *ctx = NULL;
}

/* Initialize everything we can with regards to decoding */
decodecontext *decodeinit(d2vcontext *dctx, string& err)
{
    decodecontext *ret;
    int i, av_ret;

    ret = new decodecontext;

    /* Zero the context to aid in conditional freeing later. */
    memset(ret, 0, sizeof(*ret));

    /* Holds our "filename" we pass to libavformat. */
    ret->fakename = new string;

    /* Set our stream index to -1 (uninitialized). */
    ret->stream_index = -1;

    /* Open each file and stash its size. */
    for(i = 0; i < dctx->num_files; i++) {
        FILE *in;
        int64_t size;

        in = fopen(dctx->files[i].c_str(), "rb");
        if (!in) {
            err  = "Cannot open file: ";
            err += dctx->files[i];
            goto fail;
        }

        fseeko(in, 0, SEEK_END);
        size = ftello(in);
        fseeko(in, 0, SEEK_SET);

        ret->file_sizes.push_back(size);
        ret->files.push_back(in);
    }

    /*
     * Register all of our demuxers, parsers, and decoders.
     * Ideally, to create a smaller binary, we only enable the
     * following:
     *
     * Demuxers: mpegvideo, mpegps, mpegts.
     * Parsers: mpegvideo, mpegaudio.
     * Decoders: mpeg1video, mpeg2video.
     */
    avcodec_register_all();
    av_register_all();

    /* Set the correct decoder. */
    if (dctx->mpeg_type == 1) {
        ret->incodec = avcodec_find_decoder(AV_CODEC_ID_MPEG1VIDEO);
    } else if (dctx->mpeg_type == 2) {
        ret->incodec = avcodec_find_decoder(AV_CODEC_ID_MPEG2VIDEO);
    } else {
        err = "Invalid MPEG Type.";
        goto fail;
    }

    /* Allocate the codec's context. */
    ret->avctx = avcodec_alloc_context3(ret->incodec);
    if (!ret->avctx) {
        err = "Cannot allocate AVCodecContext.";
        goto fail;
    }

    /* Set the IDCT algorithm. */
    ret->avctx->idct_algo = dctx->idct_algo;

    /*
     * Enable EMU_EDGE so that we can use buffers that are
     * not padded by 32 pixels.
     */
    ret->avctx->flags |= CODEC_FLAG_EMU_EDGE;

    /* Open it. */
    av_ret = avcodec_open2(ret->avctx, ret->incodec, NULL);
    if (av_ret < 0) {
        err = "Cannot open decoder.";
        goto fail;
    }

    /* Allocate the scratch buffer for our custom AVIO context. */
    ret->in = (uint8_t *) av_malloc(32 * 1024);
    if (!ret->in) {
        err = "Cannot alloc inbuf.";
        goto fail;
    }

    /* We don't want to hear all the info it has. */
    av_log_set_level(AV_LOG_PANIC);

    return ret;

fail:
    decodefreep(&ret);
    return NULL;
}

int decodeframe(int frame_num, d2vcontext *ctx, decodecontext *dctx, AVFrame *out, string& err)
{
    frame f;
    gop g;
    unsigned int i;
    int o, j, av_ret, offset;
    bool next;

    /* Get our frame and the GOP its in. */
    f = ctx->frames[frame_num];
    g = ctx->gops[f.gop];

    /*
     * The offset is how many frames we have to decode from our
     * current position in order to get to the frame we want.
     * The initial offset is obtaiend during the parsing of the
     * D2V file, but it may be more in an open GOP situation,
     * which we handle below.
     */
    offset = f.offset;

    /*
     * If we're in a open GOP situation, then start decoding
     * from the previous GOP (one at most is needed), and adjust
     * out offset accordingly.
     */
    if (!(g.info & GOP_FLAG_CLOSED) && (f.gop - 1 > 0)) {
        int n = frame_num;
        frame t = ctx->frames[n];

        g = ctx->gops[f.gop - 1];

        /*
         * Find the offset of the last frame in the
         * previous GOP and add it to our offset.
         */
        while(t.offset)
            t = ctx->frames[--n];

        t = ctx->frames[--n];

        /*
         * Subtract one from the offset to compensate for
         * libavcodec delay, I think.
         */
        offset += t.offset - 1;
    }

    /*
     * Check if we're decoding linearly, and if the GOP
     * of the current frame and previous frame are either
     * the same, or also linear. If so, we can decode
     * linearly.
     */
    next = (dctx->last_gop == f.gop || dctx->last_gop == f.gop - 1) && dctx->last_frame == frame_num - 1;

    /* Skip GOP initialization if we're decoding linearly. */
    if (!next) {
        /* Free out format and AVIO contexts from the previous seek. */
        if (dctx->fctx) {
            if (dctx->fctx->pb)
                av_freep(&dctx->fctx->pb);

            avformat_close_input(&dctx->fctx);
        }

        /* Seek to our GOP offset and stash the info. */
        fseeko(dctx->files[g.file], g.pos, SEEK_SET);
        dctx->orig_file_offset = g.pos;
        dctx->orig_file        = g.file;
        dctx->cur_file         = g.file;

        /* Allocate format context. */
        dctx->fctx = avformat_alloc_context();
        if (!dctx->fctx) {
            err = "Cannot allocate AVFormatContext.";
            goto dfail;
        }

        /*
         * Find the demuxer for our input type, and also set
         * the "filename" that we pass to libavformat when
         * we open the demuxer with our custom AVIO context.
         */
        if (ctx->stream_type == ELEMENTARY) {
            dctx->fctx->iformat = av_find_input_format("mpegvideo");
            *dctx->fakename      = "fakevideo.m2v";
        } else if (ctx->stream_type == PROGRAM) {
            dctx->fctx->iformat = av_find_input_format("mpeg");
            *dctx->fakename      = "fakevideo.vob";
        } else if (ctx->stream_type == TRANSPORT) {
            dctx->fctx->iformat = av_find_input_format("mpegts");
            *dctx->fakename      = "fakevideo.ts";
        } else {
            err = "Unsupported format.";
            goto dfail;
        }

        /*
         * Initialize out custom AVIO context that libavformat
         * will use instead of a file. It uses our custom packet
         * reading and seeking functions that transparently work
         * with our indexed GOP offsets and multiple files.
         */
        dctx->fctx->pb = avio_alloc_context(dctx->in, 32 * 1024, 0, dctx, read_packet, NULL, file_seek);

        /* Open the demuxer. */
        av_ret = avformat_open_input(&dctx->fctx, (*dctx->fakename).c_str(), NULL, NULL);
        if (av_ret < 0) {
            err = "Cannot open buffer in libavformat.";
            goto dfail;
        }

        /*
         * Flush the buffers of our codec's context so we
         * don't need to re-initialize it.
         */
        avcodec_flush_buffers(dctx->avctx);

        /*
         * Call the abomination function to find out
         * how many streams we have.
         */
        avformat_find_stream_info(dctx->fctx, NULL);

        /* Free and re-initialize any existing packet. */
        av_free_packet(&dctx->inpkt);
        av_init_packet(&dctx->inpkt);
    }

    /* Set our stream index if we need to. */
    if (dctx->stream_index == -1) {
        for(i = 0; i < dctx->fctx->nb_streams; i++) {
            if (dctx->fctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
                dctx->stream_index = (int) i;
                break;
            }
        }
    }

    /*
     * We don't need to read a new packet in if we are decoding
     * linearly, since it's still there from the previous iteration.
     */
    if (!next)
        av_read_frame(dctx->fctx, &dctx->inpkt);

    /* If we're decoding linearly, there is obviously no offset. */
    o = next ? 0 : offset;
    for(j = 0; j <= o; j++) {
        while(dctx->inpkt.stream_index != dctx->stream_index) {
            av_free_packet(&dctx->inpkt);
            av_read_frame(dctx->fctx, &dctx->inpkt);
        }

        /*
         * Loop until we have a whole frame, since there can be
         * multi-packet frames.
         */
        av_ret = 0;
        while(!av_ret) {
            AVPacket orig = dctx->inpkt;

            /*
             * Decoding might not consume out whole packet, so
             * stash the original packet info, loop until it
             * is all consumed, and then restore it, it so
             * we can free it properly.
             */
            while(dctx->inpkt.size > 0) {
                int r = avcodec_decode_video2(dctx->avctx, out, &av_ret, &dctx->inpkt);

                dctx->inpkt.size -= r;
                dctx->inpkt.data += r;
            }

            dctx->inpkt = orig;

            do {
                av_free_packet(&dctx->inpkt);
                av_read_frame(dctx->fctx, &dctx->inpkt);
            } while(dctx->inpkt.stream_index != dctx->stream_index);
        }
    }

    /*
     * Stash the frame number we just decoded, and the GOP it
     * is a part of so we can check if we're decoding linearly
     * later on.
     */
    dctx->last_gop   = f.gop;
    dctx->last_frame = frame_num;

    return 0;

dfail:
    avformat_close_input(&dctx->fctx);
    return -1;
}
<|endoftext|>


<commit_before>// This file is part of the dune-stuff project:
//   https://users.dune-project.org/projects/dune-stuff
// Copyright holders: Rene Milk, Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#include "test_common.hh"

#include <dune/stuff/common/string.hh>
#include <dune/stuff/common/logstreams.hh>
#include <dune/stuff/common/exceptions.hh>
#include <boost/lexical_cast.hpp>
#include <bits/functexcept.h>
#include <vector>

using namespace Dune::Stuff::Common;
using namespace std;

TEST(StringTest, ConvertTo) {
  EXPECT_EQ("9",toString(fromString<int>("9")));
  EXPECT_EQ("P",toString(fromString<char>("P")));
  EXPECT_EQ(double(0.1),
            fromString<double>(toString<double>(0.1)));
  EXPECT_EQ("0.100006",
            toString(fromString<double>("0.1000055511151231257827021181583404541015625")));
  EXPECT_EQ("1",toString(fromString<bool>("1")));
  EXPECT_EQ("0",toString(fromString<bool>("0")));
  EXPECT_EQ("-1",toString(fromString<long>("-1")));
}

TEST(StringTest, Hex) {
  EXPECT_GT(boost::lexical_cast<HexToString<unsigned long> >(cout), 0u);
  EXPECT_EQ(boost::lexical_cast<HexToString<unsigned long> >("0x00000F"), 15u);
}

TEST(StringTest, ConvertFrom) {
  EXPECT_EQ(9,fromString<int>("9"));
  EXPECT_EQ(0,fromString<int>("0"));
  EXPECT_EQ('p',fromString<char>(toString('p')));
  EXPECT_EQ(-1,fromString<char>(toString<char>(-1)));
  EXPECT_THROW(fromString<char>("sd"),Dune::Stuff::Exceptions::wrong_input_given);
  EXPECT_EQ(true,fromString<bool>("1"));
  EXPECT_EQ(false,fromString<bool>("0"));
  EXPECT_THROW(fromString<int>(""), std::invalid_argument);
}

TEST(StringTest, Whitespace) {
  EXPECT_EQ("---------", whitespaceify("\t\t\t\t\t\t\t\t\t", '-'));
}

TEST(StringTest, Tokenizer) {
  const string seps(" \t;");
  const string msg("a t\tkk;;g");
  const vector<string> tokens_default     = {"a", "t", "kk", "", "g"};
  const vector<string> tokens_compressed  = {"a", "t", "kk", "g"};
  EXPECT_EQ(tokens_default,    tokenize(msg, seps, boost::algorithm::token_compress_off));
  EXPECT_EQ(tokens_compressed, tokenize(msg, seps, boost::algorithm::token_compress_on));
  const string num_msg("-1 2;;4");
  vector<int> numbers_default = {-1,2,0,4};
  vector<int> numbers_compressed = {-1,2,4};
  EXPECT_EQ(numbers_default,    tokenize<int>(num_msg, seps, boost::algorithm::token_compress_off));
  EXPECT_EQ(numbers_compressed, tokenize<int>(num_msg, seps, boost::algorithm::token_compress_on));
}

TEST(StringTest, TimeString) {
  string ts = stringFromTime(-1);
}

int main(int argc, char** argv)
{
  test_init(argc, argv);
  return RUN_ALL_TESTS();
}
<commit_msg>[test.common_string] add some tests for fromString/toString<commit_after>// This file is part of the dune-stuff project:
//   https://users.dune-project.org/projects/dune-stuff
// Copyright holders: Rene Milk, Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#include "test_common.hh"

#include <dune/stuff/common/string.hh>
#include <dune/stuff/common/logstreams.hh>
#include <vector>

#include <dune/stuff/common/disable_warnings.hh>
# include <dune/common/fmatrix.hh>
# include <dune/common/densematrix.hh>
# include <dune/common/fvector.hh>
# include <dune/common/dynmatrix.hh>
#include <dune/stuff/common/reenable_warnings.hh>
#include <dune/common/dynvector.hh>
#include <dune/common/densevector.hh>

#include <dune/stuff/common/exceptions.hh>
#include <dune/stuff/common/fvector.hh>
#include <dune/stuff/common/fmatrix.hh>
#include <dune/stuff/la/container/common.hh>
#if HAVE_EIGEN
# include <dune/stuff/la/container/eigen.hh>
#endif
#if HAVE_DUNE_ISTL
# include <dune/stuff/la/container/istl.hh>
#endif

using namespace Dune::Stuff::Common;
using namespace std;

//define types and expected values for the typed tests
template< class MatrixType >
struct MatrixStringTestDouble
  : public ::testing::Test
{
  void check() const
  {
    EXPECT_EQ("[1.000000 2.000000; 3.000000 4.000000]", toString(fromString<MatrixType>("[1.0 2; 3.0 4]")));
    EXPECT_THROW(fromString<MatrixType>("[1 2; 3 4]", 3, 3), Dune::Stuff::Exceptions::configuration_error);
  }
};

template< class MatrixType >
struct MatrixStringTestChar
  : public ::testing::Test
{
  void check() const
  {
    EXPECT_EQ("[1 2; 3 4]", toString(fromString<MatrixType>("[1 2; 3 4]")));
    EXPECT_THROW(fromString<MatrixType>("[1 2; 3 4]", 3, 3), Dune::Stuff::Exceptions::configuration_error);
  }
};

template< class VectorType >
struct VectorStringTestDouble
  : public ::testing::Test
{
  void check() const
  {
    EXPECT_EQ("[1.000000 2.000000 3.000000]", toString(fromString<VectorType>("[1.0 2 3.0]")));
    EXPECT_THROW(fromString<VectorType>("[1.0 2 3.0]", 4), Dune::Stuff::Exceptions::configuration_error);
  }
};

template< class VectorType >
struct VectorStringTestInt
  : public ::testing::Test
{
  void check() const
  {
    EXPECT_EQ("[1 2 3]", toString(fromString<VectorType>("[1 2 3]")));
    EXPECT_THROW(fromString<VectorType>("[1 2 3]", 4), Dune::Stuff::Exceptions::configuration_error);
  }
};

typedef testing::Types< std::vector< double >
                    , Dune::Stuff::LA::CommonDenseVector< double >
                    , Dune::DynamicVector< double >
                    , Dune::FieldVector< double, 3 >
                    , Dune::Stuff::Common::FieldVector< double, 3 >
#if HAVE_EIGEN
                    , Dune::Stuff::LA::EigenDenseVector< double >
                    , Dune::Stuff::LA::EigenMappedDenseVector< double >
#endif
#if HAVE_DUNE_ISTL
                    , Dune::Stuff::LA::IstlDenseVector< double >
#endif
                    > VectorTypesDouble;

typedef testing::Types< std::vector< int >
                    , Dune::Stuff::LA::CommonDenseVector< int >
                    , Dune::DynamicVector< int >
                    , Dune::FieldVector< int, 3 >
                    , Dune::Stuff::Common::FieldVector< int, 3 >
#if HAVE_DUNE_ISTL
                    , Dune::Stuff::LA::IstlDenseVector< int >
#endif
                    > VectorTypesInt;

typedef testing::Types< Dune::DynamicMatrix< double >
                    , Dune::Stuff::LA::CommonDenseMatrix< double >
                    , Dune::Stuff::Common::FieldMatrix< double, 2, 2 >
                    , Dune::FieldMatrix< double, 2, 2 >
#if HAVE_EIGEN
                    , Dune::Stuff::LA::EigenDenseMatrix< double >
#endif
                    > MatrixTypesDouble;

typedef testing::Types< Dune::DynamicMatrix< char >
                    , Dune::Stuff::LA::CommonDenseMatrix< char >
                    , Dune::Stuff::Common::FieldMatrix< char, 2, 2 >
                    , Dune::FieldMatrix< char, 2, 2 >
#if HAVE_EIGEN
                    , Dune::Stuff::LA::EigenDenseMatrix< char >
#endif
                    > MatrixTypesChar;

// fromString/toString tests for vector and matrix types
TYPED_TEST_CASE(MatrixStringTestDouble, MatrixTypesDouble);
TYPED_TEST(MatrixStringTestDouble, CheckDouble) {
  this->check();
}

TYPED_TEST_CASE(MatrixStringTestChar, MatrixTypesChar);
TYPED_TEST(MatrixStringTestChar, CheckChar) {
  this->check();
}

TYPED_TEST_CASE(VectorStringTestDouble, VectorTypesDouble);
TYPED_TEST(VectorStringTestDouble, CheckDouble) {
  this->check();
}

TYPED_TEST_CASE(VectorStringTestInt, VectorTypesInt);
TYPED_TEST(VectorStringTestInt, CheckInt) {
  this->check();
}

// Additional fromString/toString tests
TEST(StringTest, ConvertTo) {
  EXPECT_EQ("9",toString(fromString<int>("9")));
  EXPECT_EQ("P",toString(fromString<char>("P")));
  EXPECT_EQ(double(0.1),
            fromString<double>(toString<double>(0.1)));
  EXPECT_EQ("0.100006",
            toString(fromString<double>("0.1000055511151231257827021181583404541015625")));
  EXPECT_EQ("1",toString(fromString<bool>("1")));
  EXPECT_EQ("0",toString(fromString<bool>("0")));
  EXPECT_EQ("-1",toString(fromString<long>("-1")));
  EXPECT_THROW(fromString<std::vector<std::vector<double>>>("[[1 2] [3 4]]"), Dune::Stuff::Exceptions::wrong_input_given);
}

TEST(StringTest, ConvertFrom) {
  EXPECT_EQ(9,fromString<int>("9"));
  EXPECT_EQ(0,fromString<int>("0"));
  EXPECT_EQ('p',fromString<char>(toString('p')));
  EXPECT_EQ(-1,fromString<char>(toString(char(-1))));
  EXPECT_THROW(fromString<char>("sd"),Dune::Stuff::Exceptions::wrong_input_given);
  EXPECT_EQ(true,fromString<bool>("1"));
  EXPECT_EQ(false,fromString<bool>("0"));
  EXPECT_THROW(fromString<int>(""), std::invalid_argument);
}

// Hex, whitespacify, tokenize, stringFromTime tests
TEST(StringTest, Hex) {
  EXPECT_GT(boost::lexical_cast<HexToString<unsigned long> >(cout), 0u);
  EXPECT_EQ(boost::lexical_cast<HexToString<unsigned long> >("0x00000F"), 15u);
}

TEST(StringTest, Whitespace) {
  EXPECT_EQ("---------", whitespaceify("\t\t\t\t\t\t\t\t\t", '-'));
}

TEST(StringTest, Tokenizer) {
  const string seps(" \t;");
  const string msg("a t\tkk;;g");
  const vector<string> tokens_default     = {"a", "t", "kk", "", "g"};
  const vector<string> tokens_compressed  = {"a", "t", "kk", "g"};
  EXPECT_EQ(tokens_default,    tokenize(msg, seps, boost::algorithm::token_compress_off));
  EXPECT_EQ(tokens_compressed, tokenize(msg, seps, boost::algorithm::token_compress_on));
  const string num_msg("-1 2;;4");
  vector<int> numbers_default = {-1,2,0,4};
  vector<int> numbers_compressed = {-1,2,4};
  EXPECT_EQ(numbers_default,    tokenize<int>(num_msg, seps, boost::algorithm::token_compress_off));
  EXPECT_EQ(numbers_compressed, tokenize<int>(num_msg, seps, boost::algorithm::token_compress_on));
}

TEST(StringTest, TimeString) {
  string ts = stringFromTime(-1);
}

// Run tests
int main(int argc, char** argv)
{
  test_init(argc, argv);
  return RUN_ALL_TESTS();
}
<|endoftext|>


<commit_before>// AddTaskChargedJetsHadronCF.C

AliAnalysisTaskChargedJetsHadronCF* AddTaskChargedJetsHadronCF(
  UInt_t physSel                 = 0,
  const char *trackArray         = "tracks",
  const char *jetArray           = "jets",
  const char *rhoObject          = "Rho",
  Double_t    jetRadius          = 0.2,
  Double_t    minJetEta          = 0.7,
  Double_t    minLeadingHadronPt = 0.0,
  Double_t    minJetPt           = 0.15,
  Double_t    minTrackPt         = 0.15,
  Double_t    minJetAreaPerc     = 0.557,
  const char *suffix             = ""
)
{
  cout << " ############ MACRO EXECUTION STARTED: AddTaskChargedJetsHadronCF.C ############\n";
  //==============================================================================
  // Prepare analysis manager, containers, etc.
  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
  if (!mgr)
  {
    ::Error("AddTaskChargedJetsHadronCF", "No analysis manager to connect to.");
    return NULL;
  }
  if (!mgr->GetInputEventHandler())
  {
    ::Error("AddTaskChargedJetsHadronCF", "This task requires an input event handler");
    return NULL;
  }

  TString name("AliAnalysisTaskChargedJetsHadronCF");
  if (strcmp(jetArray,"")) {
    name += "_";
    name += jetArray;
  }
  if (strcmp(rhoObject,"")) {
    name += "_";
    name += rhoObject;
  }
  if (strcmp(suffix,"")) {
    name += "_";
    name += suffix;
  }

  AliAnalysisDataContainer* contHistos = mgr->CreateContainer(Form("%s_histos", name.Data()), TList::Class(), AliAnalysisManager::kOutputContainer, Form("%s:ChargedJetsHadronCF", AliAnalysisManager::GetCommonFileName()));

  //==============================================================================
  // Adding and configuring tasks

  AliAnalysisTaskChargedJetsHadronCF* jetTask = new AliAnalysisTaskChargedJetsHadronCF(name);
  jetTask->SetNeedEmcalGeom(kFALSE);
  jetTask->SetVzRange(-10.,10.);
  jetTask->SetOffTrigger(physSel);

  AliParticleContainer *trackCont = jetTask->AddParticleContainer(trackArray);
  trackCont->SetFilterHybridTracks(kTRUE);
  trackCont->SetParticlePtCut(minTrackPt);

  AliJetContainer *jetCont = jetTask->AddJetContainer(jetArray,0,jetRadius);
  if (jetCont) {
    jetCont->SetRhoName(rhoObject);
    jetCont->SetPercAreaCut(minJetAreaPerc);
    jetCont->SetJetPtCut(minJetPt);
    jetCont->SetLeadingHadronType(0);
    jetCont->SetPtBiasJetTrack(minLeadingHadronPt);
    jetCont->SetJetEtaLimits(-minJetEta, +minJetEta);
    jetCont->ConnectParticleContainer(trackCont);
    jetCont->SetMaxTrackPt(1000);
  }

  mgr->AddTask(jetTask);

  //==============================================================================
  // Finalization

  mgr->ConnectInput  (jetTask, 0,  mgr->GetCommonInputContainer() );
  mgr->ConnectOutput (jetTask, 1, contHistos );

  cout << " ############ MACRO EXECUTION DONE: AddTaskChargedJetsHadronCF.C ############\n";

  return jetTask;
}
<commit_msg>Changed default jet cuts<commit_after>// AddTaskChargedJetsHadronCF.C

AliAnalysisTaskChargedJetsHadronCF* AddTaskChargedJetsHadronCF(
  UInt_t physSel                 = 0,
  const char *trackArray         = "tracks",
  const char *jetArray           = "jets",
  const char *rhoObject          = "Rho",
  Double_t    jetRadius          = 0.2,
  Double_t    minJetEta          = 0.7,
  Double_t    minLeadingHadronPt = 0.0,
  Double_t    minJetPt           = 0.15,
  Double_t    minTrackPt         = 0.15,
  Double_t    minJetAreaPerc     = 0.557,
  const char *suffix             = ""
)
{
  cout << " ############ MACRO EXECUTION STARTED: AddTaskChargedJetsHadronCF.C ############\n";
  //==============================================================================
  // Prepare analysis manager, containers, etc.
  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
  if (!mgr)
  {
    ::Error("AddTaskChargedJetsHadronCF", "No analysis manager to connect to.");
    return NULL;
  }
  if (!mgr->GetInputEventHandler())
  {
    ::Error("AddTaskChargedJetsHadronCF", "This task requires an input event handler");
    return NULL;
  }

  TString name("AliAnalysisTaskChargedJetsHadronCF");
  if (strcmp(jetArray,"")) {
    name += "_";
    name += jetArray;
  }
  if (strcmp(rhoObject,"")) {
    name += "_";
    name += rhoObject;
  }
  if (strcmp(suffix,"")) {
    name += "_";
    name += suffix;
  }

  AliAnalysisDataContainer* contHistos = mgr->CreateContainer(Form("%s_histos", name.Data()), TList::Class(), AliAnalysisManager::kOutputContainer, Form("%s:ChargedJetsHadronCF", AliAnalysisManager::GetCommonFileName()));

  //==============================================================================
  // Adding and configuring tasks

  AliAnalysisTaskChargedJetsHadronCF* jetTask = new AliAnalysisTaskChargedJetsHadronCF(name);
  jetTask->SetNeedEmcalGeom(kFALSE);
  jetTask->SetVzRange(-10.,10.);
  jetTask->SetOffTrigger(physSel);

  AliParticleContainer *trackCont = jetTask->AddParticleContainer(trackArray);
  trackCont->SetFilterHybridTracks(kTRUE);
  trackCont->SetParticlePtCut(minTrackPt);

  AliJetContainer *jetCont = jetTask->AddJetContainer(jetArray,6,jetRadius);
  if (jetCont) {
    jetCont->SetRhoName(rhoObject);
    jetCont->SetPercAreaCut(minJetAreaPerc);
    jetCont->SetJetPtCut(minJetPt);
    jetCont->SetLeadingHadronType(0);
    jetCont->SetPtBiasJetTrack(minLeadingHadronPt);
    jetCont->SetJetEtaLimits(-minJetEta, +minJetEta);
    jetCont->ConnectParticleContainer(trackCont);
    jetCont->SetMaxTrackPt(1000);
  }

  mgr->AddTask(jetTask);

  //==============================================================================
  // Finalization

  mgr->ConnectInput  (jetTask, 0,  mgr->GetCommonInputContainer() );
  mgr->ConnectOutput (jetTask, 1, contHistos );

  cout << " ############ MACRO EXECUTION DONE: AddTaskChargedJetsHadronCF.C ############\n";

  return jetTask;
}
<|endoftext|>


<commit_before>#include <iomanip>
#include <cassert>
#include "SDShared.hpp"
#include "exception/exception.hpp"

SDShared::SDShared(const std::vector< std::pair<int, int> >& coords,
        const CoordConverter& coordConverter,
        unsigned int index):
    std::vector< std::pair<int ,int> >(coords),
    _coordConverter(coordConverter),
    _id(index) {
}

void SDShared::execEquation(eqType& eqFunc,
        const std::map< std::string, Quantity<real>* >& quantityMap) {

    eqFunc(*this, quantityMap);
}

void SDShared::addDirichletCell(std::pair < std::pair<int, int>, std::map<std::string, real> > d) {
    for (auto p : d.second)
        _dirichletCellMap[p.first][convert(d.first.first, d.first.second)] = p.second;
}

void SDShared::addTimeVaryingCell(std::pair < std::pair<int, int>, std::map<std::string, real> > d) {
    for (auto p : d.second)
        _timeVaryingCellMap[p.first][convert(d.first.first, d.first.second)] = p.second;
}

void SDShared::addNeumannCell(std::pair< std::pair<int, int>, std::pair< std::pair<int, int>, std::map<std::string, real> > > n) {
    for (auto p : n.second.second)
        _neumannCellMap[p.first][convert(n.first.first, n.first.second)] = std::make_pair(convert(n.second.first.first, n.second.first.second), p.second);
}

size_t SDShared::getOverlapCellNumber(unsigned int sddId) const {
    if (_sendIndexMap.find(sddId) == _sendIndexMap.end())
        return 0;

    return _sendIndexMap.at(sddId).size();
}

void SDShared::addOverlapCell(unsigned int sddId, size_t sendIndex, size_t recvIndex) {
    _sendIndexMap[sddId].push_back(sendIndex);
    _recvIndexMap[sddId].push_back(recvIndex);
}

void SDShared::updateBoundaryCells(Quantity<real>* quantity, const real& t) const {
    updateDirichletCells(quantity);
    updateNeumannCells(quantity);
    updateTimeVaryingCells(quantity, t);
}

void SDShared::updateDirichletCells(Quantity<real>* quantity) const {
    auto& qty(*quantity);

    // No dirichlet values stored for this quantity.
    std::map<std::string, std::unordered_map< size_t, real >>::const_iterator it = _dirichletCellMap.find(qty.getName());
    if (it == _dirichletCellMap.end())
        return;

    const std::unordered_map< size_t, real>& dirichletValue = it->second;

    // This cannot be.
    assert(dirichletValue.size() != 0);

    for (auto it = dirichletValue.begin(); it != dirichletValue.end(); ++it)
        qty.set0(it->second, it->first);
}

void SDShared::updateTimeVaryingCells(Quantity<real>* quantity, const real& t) const {
    auto& qty(*quantity);

    // No dirichlet values stored for this quantity.
    std::map<std::string, std::unordered_map< size_t, real >>::const_iterator it = _timeVaryingCellMap.find(qty.getName());
    if (it == _timeVaryingCellMap.end())
        return;

    const std::unordered_map< size_t, real>& parameterValue = it->second;

    // This cannot be.
    assert(parameterValue.size() != 0);

    for (auto it = parameterValue.begin(); it != parameterValue.end(); ++it) {
        real v = 1. - it->second * t;
        //std::cout << "v: " << std::defaultfloat << std::setprecision(Number::max_digits10) << v << std::endl;
        qty.set0(v, it->first);
    }
}

void SDShared::updateNeumannCells(Quantity<real>* quantity) const {

    auto& qty(*quantity);

    // No dirichlet values stored for this quantity.
    std::map<std::string, std::unordered_map< size_t, std::pair<size_t, real>>>::const_iterator cit = _neumannCellMap.find(qty.getName());
    if (cit == _neumannCellMap.end())
        return;

    const std::unordered_map< size_t, std::pair<size_t, real>>& neumannCoeff = cit->second;

    // This cannot be.
    assert(neumannCoeff.size() != 0);

    for (auto it = neumannCoeff.begin(); it != neumannCoeff.end(); ++it) {
        qty.set0(it->second.second * qty.get0(it->second.first), it->first);
    }
}

void SDShared::copyOverlapCellIn(const std::map< std::string, Quantity<real>* >& quantityMap, const std::unordered_map<unsigned int, real* >& buffer) const {

    const size_t plus(quantityMap.size());
    for (auto const& it: _sendIndexMap) {
        size_t startPos(_bufferStartPos.at(it.first) * quantityMap.size());
        real* sddBuffer(buffer.at(it.first));
        for (const auto p: quantityMap) {
            auto& qty(*p.second);
            size_t index(startPos++);
            for (const unsigned int i : it.second) {
                sddBuffer[index] = qty.get0(i);
                index += plus;
            }
        }
    }
}

void SDShared::copyOverlapCellFrom(const std::map< std::string, Quantity<real>* >& quantityMap, const std::unordered_map<unsigned int, real* >& buffer) const {
    const size_t plus(quantityMap.size());
    for (auto const& it: _recvIndexMap) {
        real* sddBuffer(buffer.at(it.first));
        size_t startPos(_bufferStartPos.at(it.first) * plus);
        for (const auto p: quantityMap) {
            auto& qty(*p.second);
            size_t index(startPos++);
            for (const unsigned int i : it.second) {
                qty.set0(sddBuffer[index], i);
                index += plus;
            }
        }
    }
}
<commit_msg>sign correction<commit_after>#include <iomanip>
#include <cassert>
#include "SDShared.hpp"
#include "exception/exception.hpp"

SDShared::SDShared(const std::vector< std::pair<int, int> >& coords,
        const CoordConverter& coordConverter,
        unsigned int index):
    std::vector< std::pair<int ,int> >(coords),
    _coordConverter(coordConverter),
    _id(index) {
}

void SDShared::execEquation(eqType& eqFunc,
        const std::map< std::string, Quantity<real>* >& quantityMap) {

    eqFunc(*this, quantityMap);
}

void SDShared::addDirichletCell(std::pair < std::pair<int, int>, std::map<std::string, real> > d) {
    for (auto p : d.second)
        _dirichletCellMap[p.first][convert(d.first.first, d.first.second)] = p.second;
}

void SDShared::addTimeVaryingCell(std::pair < std::pair<int, int>, std::map<std::string, real> > d) {
    for (auto p : d.second)
        _timeVaryingCellMap[p.first][convert(d.first.first, d.first.second)] = p.second;
}

void SDShared::addNeumannCell(std::pair< std::pair<int, int>, std::pair< std::pair<int, int>, std::map<std::string, real> > > n) {
    for (auto p : n.second.second)
        _neumannCellMap[p.first][convert(n.first.first, n.first.second)] = std::make_pair(convert(n.second.first.first, n.second.first.second), p.second);
}

size_t SDShared::getOverlapCellNumber(unsigned int sddId) const {
    if (_sendIndexMap.find(sddId) == _sendIndexMap.end())
        return 0;

    return _sendIndexMap.at(sddId).size();
}

void SDShared::addOverlapCell(unsigned int sddId, size_t sendIndex, size_t recvIndex) {
    _sendIndexMap[sddId].push_back(sendIndex);
    _recvIndexMap[sddId].push_back(recvIndex);
}

void SDShared::updateBoundaryCells(Quantity<real>* quantity, const real& t) const {
    updateDirichletCells(quantity);
    updateNeumannCells(quantity);
    updateTimeVaryingCells(quantity, t);
}

void SDShared::updateDirichletCells(Quantity<real>* quantity) const {
    auto& qty(*quantity);

    // No dirichlet values stored for this quantity.
    std::map<std::string, std::unordered_map< size_t, real >>::const_iterator it = _dirichletCellMap.find(qty.getName());
    if (it == _dirichletCellMap.end())
        return;

    const std::unordered_map< size_t, real>& dirichletValue = it->second;

    // This cannot be.
    assert(dirichletValue.size() != 0);

    for (auto it = dirichletValue.begin(); it != dirichletValue.end(); ++it)
        qty.set0(it->second, it->first);
}

void SDShared::updateTimeVaryingCells(Quantity<real>* quantity, const real& t) const {
    auto& qty(*quantity);

    // No dirichlet values stored for this quantity.
    std::map<std::string, std::unordered_map< size_t, real >>::const_iterator it = _timeVaryingCellMap.find(qty.getName());
    if (it == _timeVaryingCellMap.end())
        return;

    const std::unordered_map< size_t, real>& parameterValue = it->second;

    // This cannot be.
    assert(parameterValue.size() != 0);

    for (auto it = parameterValue.begin(); it != parameterValue.end(); ++it) {
        real v = 1. + it->second * t;
        //std::cout << "v: " << std::defaultfloat << std::setprecision(Number::max_digits10) << v << std::endl;
        qty.set0(v, it->first);
    }
}

void SDShared::updateNeumannCells(Quantity<real>* quantity) const {

    auto& qty(*quantity);

    // No dirichlet values stored for this quantity.
    std::map<std::string, std::unordered_map< size_t, std::pair<size_t, real>>>::const_iterator cit = _neumannCellMap.find(qty.getName());
    if (cit == _neumannCellMap.end())
        return;

    const std::unordered_map< size_t, std::pair<size_t, real>>& neumannCoeff = cit->second;

    // This cannot be.
    assert(neumannCoeff.size() != 0);

    for (auto it = neumannCoeff.begin(); it != neumannCoeff.end(); ++it) {
        qty.set0(it->second.second * qty.get0(it->second.first), it->first);
    }
}

void SDShared::copyOverlapCellIn(const std::map< std::string, Quantity<real>* >& quantityMap, const std::unordered_map<unsigned int, real* >& buffer) const {

    const size_t plus(quantityMap.size());
    for (auto const& it: _sendIndexMap) {
        size_t startPos(_bufferStartPos.at(it.first) * quantityMap.size());
        real* sddBuffer(buffer.at(it.first));
        for (const auto p: quantityMap) {
            auto& qty(*p.second);
            size_t index(startPos++);
            for (const unsigned int i : it.second) {
                sddBuffer[index] = qty.get0(i);
                index += plus;
            }
        }
    }
}

void SDShared::copyOverlapCellFrom(const std::map< std::string, Quantity<real>* >& quantityMap, const std::unordered_map<unsigned int, real* >& buffer) const {
    const size_t plus(quantityMap.size());
    for (auto const& it: _recvIndexMap) {
        real* sddBuffer(buffer.at(it.first));
        size_t startPos(_bufferStartPos.at(it.first) * plus);
        for (const auto p: quantityMap) {
            auto& qty(*p.second);
            size_t index(startPos++);
            for (const unsigned int i : it.second) {
                qty.set0(sddBuffer[index], i);
                index += plus;
            }
        }
    }
}
<|endoftext|>


<commit_before>#if !defined(__CINT__) || defined(__MAKECINT__)
#include <Rtypes.h>
#include <TString.h>
#include "AliAnalysisTaskHypertriton3.h"
#include "AliAnalysisManager.h"
#include "AliAnalysisDataContainer.h"
#include "AliMCEventHandler.h"
#include "AliPID.h"
#endif

AliAnalysisTaskHypertriton3 *AddTaskHypertriton3(Bool_t readMC=kFALSE,
						 Bool_t fillTree=kFALSE,
						 TString suffix = ""){

  // Creates, configures and attaches to the train the task for pi, K , p spectra
  // with ITS standalone tracks
  // Get the pointer to the existing analysis manager via the static access method.
  //==============================================================================
  ::Info("AddTaskHypertriton3","Adding a new task with this settings readMC = %i",readMC);

  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
  if (!mgr) {
    ::Error("AddTaskHypertriton3", "No analysis manager to connect to.");
    return NULL;
  }

  // Check the analysis type using the event handlers connected to the analysis manager.
  //==============================================================================
  if (!mgr->GetInputEventHandler()) {
    ::Error("AddTaskHypertriton3", "This task requires an input event handler");
    return NULL;
  }

  TString type = mgr->GetInputEventHandler()->GetDataType(); // can be "ESD" or "AOD"
  if(type.Contains("AOD")){
    ::Error("AddTaskHypertriton3", "This task requires to run on ESD");
    return NULL;
  }

  // Add MC handler (for kinematics)
  if(readMC){
    AliMCEventHandler* handler = new AliMCEventHandler;
    handler->SetReadTR(kFALSE);
    mgr->SetMCtruthEventHandler(handler);
  }

  // Create and configure the task

  TString tskname = "hypertriton";
  tskname.Append(Form("%s",suffix.Data()));
  AliAnalysisTaskHypertriton3 *taskhyp = new AliAnalysisTaskHypertriton3();
  taskhyp->SetReadMC(readMC);
  taskhyp->SetFillTree(fillTree);

  mgr->AddTask(taskhyp);

  // Create ONLY the output containers for the data produced by the task.
  // Get and connect other common input/output containers via the manager as below
  //==============================================================================
  TString outputFileName = AliAnalysisManager::GetCommonFileName();
  outputFileName += ":ESDHypertriton";

  AliAnalysisDataContainer *coutput =0x0;

  coutput = mgr->CreateContainer(Form("strogolo_%s",tskname.Data()),
				 TList::Class(),
				 AliAnalysisManager::kOutputContainer,
				 AliAnalysisManager::GetCommonFileName());

  mgr->ConnectInput(taskhyp, 0, mgr->GetCommonInputContainer());
  mgr->ConnectOutput(taskhyp, 1, coutput);

  if(fillTree){
  AliAnalysisDataContainer *coutput2 = mgr->CreateContainer("trogolo_HyperTree", TTree::Class(),
							    AliAnalysisManager::kOutputContainer,
							    "trogolo_Hyper3.root");
  coutput2->SetSpecialOutput();
  mgr->ConnectOutput(taskhyp, 2, coutput2);

  }

  return taskhyp;
}
<commit_msg>Change output name<commit_after>#if !defined(__CINT__) || defined(__MAKECINT__)
#include <Rtypes.h>
#include <TString.h>
#include "AliAnalysisTaskHypertriton3.h"
#include "AliAnalysisManager.h"
#include "AliAnalysisDataContainer.h"
#include "AliMCEventHandler.h"
#include "AliPID.h"
#endif

AliAnalysisTaskHypertriton3 *AddTaskHypertriton3(Bool_t readMC=kFALSE,
						 Bool_t fillTree=kFALSE,
						 TString suffix = ""){

  // Creates, configures and attaches to the train the task for pi, K , p spectra
  // with ITS standalone tracks
  // Get the pointer to the existing analysis manager via the static access method.
  //==============================================================================
  ::Info("AddTaskHypertriton3","Adding a new task with this settings readMC = %i",readMC);

  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
  if (!mgr) {
    ::Error("AddTaskHypertriton3", "No analysis manager to connect to.");
    return NULL;
  }

  // Check the analysis type using the event handlers connected to the analysis manager.
  //==============================================================================
  if (!mgr->GetInputEventHandler()) {
    ::Error("AddTaskHypertriton3", "This task requires an input event handler");
    return NULL;
  }

  TString type = mgr->GetInputEventHandler()->GetDataType(); // can be "ESD" or "AOD"
  if(type.Contains("AOD")){
    ::Error("AddTaskHypertriton3", "This task requires to run on ESD");
    return NULL;
  }

  // Add MC handler (for kinematics)
  if(readMC){
    AliMCEventHandler* handler = new AliMCEventHandler;
    handler->SetReadTR(kFALSE);
    mgr->SetMCtruthEventHandler(handler);
  }

  // Create and configure the task

  TString tskname = "hypertriton";
  tskname.Append(Form("%s",suffix.Data()));
  AliAnalysisTaskHypertriton3 *taskhyp = new AliAnalysisTaskHypertriton3();
  taskhyp->SetReadMC(readMC);
  taskhyp->SetFillTree(fillTree);

  mgr->AddTask(taskhyp);

  // Create ONLY the output containers for the data produced by the task.
  // Get and connect other common input/output containers via the manager as below
  //==============================================================================
  TString outputFileName = AliAnalysisManager::GetCommonFileName();
  outputFileName += ":ESDHypertriton";

  AliAnalysisDataContainer *coutput =0x0;

  coutput = mgr->CreateContainer(Form("strogolo_%s",tskname.Data()),
				 TList::Class(),
				 AliAnalysisManager::kOutputContainer,
				 AliAnalysisManager::GetCommonFileName());

  mgr->ConnectInput(taskhyp, 0, mgr->GetCommonInputContainer());
  mgr->ConnectOutput(taskhyp, 1, coutput);

  if(fillTree){
  AliAnalysisDataContainer *coutput2 = mgr->CreateContainer("trogolo_HyperTree", TTree::Class(),
							    AliAnalysisManager::kOutputContainer,
							    AliAnalysisManager::GetCommonFileName());
  coutput2->SetSpecialOutput();
  mgr->ConnectOutput(taskhyp, 2, coutput2);

  }

  return taskhyp;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: hldoctp.cxx,v $
 * $Revision: 1.28 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_cui.hxx"

#include "cuihyperdlg.hxx"
#include <unotools/localfilehelper.hxx>
#include <sfx2/filedlghelper.hxx>
#include "com/sun/star/ui/dialogs/TemplateDescription.hpp"

#include "hldoctp.hxx"
#include "hyperdlg.hrc"
#include "hlmarkwn_def.hxx" //ADD CHINA001

sal_Char __READONLY_DATA sHash[]                = "#";
sal_Char __READONLY_DATA sFileScheme[]          = INET_FILE_SCHEME;
sal_Char __READONLY_DATA sPortalFileScheme[]    = "vnd.sun.star.wfs://";
sal_Char __READONLY_DATA sNewsSRVScheme[] = "news://";
    // TODO news:// is nonsense
sal_Char __READONLY_DATA sHTTPScheme[]    = INET_HTTP_SCHEME;

/*************************************************************************
|*
|* Contructor / Destructor
|*
|************************************************************************/

SvxHyperlinkDocTp::SvxHyperlinkDocTp ( Window *pParent, const SfxItemSet& rItemSet)
    : SvxHyperlinkTabPageBase ( pParent, CUI_RES( RID_SVXPAGE_HYPERLINK_DOCUMENT ), rItemSet ),
    maGrpDocument   ( this, CUI_RES (GRP_DOCUMENT) ),
    maFtPath        ( this, CUI_RES (FT_PATH_DOC) ),
    maCbbPath       ( this, INET_PROT_FILE ),
    maBtFileopen    ( this, CUI_RES (BTN_FILEOPEN) ),
    maGrpTarget     ( this, CUI_RES (GRP_TARGET) ),
    maFtTarget      ( this, CUI_RES (FT_TARGET_DOC) ),
    maEdTarget      ( this, CUI_RES (ED_TARGET_DOC) ),
    maFtURL         ( this, CUI_RES (FT_URL) ),
    maFtFullURL     ( this, CUI_RES (FT_FULL_URL) ),
    maBtBrowse      ( this, CUI_RES (BTN_BROWSE) ),
    mbMarkWndOpen   ( FALSE )
{
    // Set HC bitmaps and disable display of bitmap names.
    maBtBrowse.SetModeImage( Image( CUI_RES( IMG_BROWSE_HC ) ), BMP_COLOR_HIGHCONTRAST );
    maBtBrowse.EnableTextDisplay (FALSE);
    maBtFileopen.SetModeImage( Image( CUI_RES( IMG_FILEOPEN_HC ) ), BMP_COLOR_HIGHCONTRAST );
    maBtFileopen.EnableTextDisplay (FALSE);

    InitStdControls();
    FreeResource();

    // Init URL-Box (pos&size, Open-Handler)
    maCbbPath.SetPosSizePixel ( LogicToPixel( Point( COL_2, 15 ), MAP_APPFONT ),
                                LogicToPixel( Size ( 176 - COL_DIFF, 60), MAP_APPFONT ) );
    maCbbPath.Show();
    String aFileScheme( INET_FILE_SCHEME, RTL_TEXTENCODING_ASCII_US );
    maCbbPath.SetBaseURL(aFileScheme);
    maCbbPath.SetHelpId( HID_HYPERDLG_DOC_PATH );

    SetExchangeSupport ();

    // overload handlers
    maBtFileopen.SetClickHdl ( LINK ( this, SvxHyperlinkDocTp, ClickFileopenHdl_Impl ) );
    maBtBrowse.SetClickHdl   ( LINK ( this, SvxHyperlinkDocTp, ClickTargetHdl_Impl ) );
    maCbbPath.SetModifyHdl   ( LINK ( this, SvxHyperlinkDocTp, ModifiedPathHdl_Impl ) );
    maEdTarget.SetModifyHdl  ( LINK ( this, SvxHyperlinkDocTp, ModifiedTargetHdl_Impl ) );

    maCbbPath.SetLoseFocusHdl( LINK ( this, SvxHyperlinkDocTp, LostFocusPathHdl_Impl ) );

    maTimer.SetTimeoutHdl ( LINK ( this, SvxHyperlinkDocTp, TimeoutHdl_Impl ) );
}

SvxHyperlinkDocTp::~SvxHyperlinkDocTp ()
{
}

/*************************************************************************
|*
|* Fill all dialog-controls except controls in groupbox "more..."
|*
|************************************************************************/

void SvxHyperlinkDocTp::FillDlgFields ( String& aStrURL )
{
    INetURLObject aURL ( aStrURL );

    String aStrMark;
    xub_StrLen nPos = aStrURL.SearchAscii( sHash );
    // path
    maCbbPath.SetText ( aStrURL.Copy( 0, ( nPos == STRING_NOTFOUND ? aStrURL.Len() : nPos ) ) );

    // set target in document at editfield
    if ( nPos != STRING_NOTFOUND && nPos<aStrURL.Len()-1 )
        aStrMark = aStrURL.Copy( nPos+1, aStrURL.Len() );
     maEdTarget.SetText ( aStrMark );

    ModifiedPathHdl_Impl ( NULL );
}

/*************************************************************************
|*
|* retrieve current url-string
|*
|************************************************************************/

String SvxHyperlinkDocTp::GetCurrentURL ()
{
    // get data from dialog-controls
    String aStrURL;
    String aStrPath ( maCbbPath.GetText() );
    const String aBaseURL ( maCbbPath.GetBaseURL() );
    String aStrMark( maEdTarget.GetText() );

    if ( aStrPath != aEmptyStr )
    {
        INetURLObject aURL( aStrPath );
        if ( aURL.GetProtocol() != INET_PROT_NOT_VALID )    // maybe the path is already a valid
            aStrURL = aStrPath;                             // hyperlink, then we can use this path directly
        else
            utl::LocalFileHelper::ConvertSystemPathToURL( aStrPath, aBaseURL, aStrURL );

        //#105788# always create a URL even if it is not valid
        if( aStrURL == aEmptyStr )
            aStrURL = aStrPath;
    }

    if( aStrMark != aEmptyStr )
    {
        aStrURL.AppendAscii( sHash );
        aStrURL += aStrMark;
    }

    return aStrURL;
}

/*************************************************************************
|*
|* retrieve and prepare data from dialog-fields
|*
|************************************************************************/

void SvxHyperlinkDocTp::GetCurentItemData ( String& aStrURL, String& aStrName,
                                            String& aStrIntName, String& aStrFrame,
                                            SvxLinkInsertMode& eMode )
{
    // get data from standard-fields
    aStrURL = GetCurrentURL();

    if( aStrURL.EqualsIgnoreCaseAscii( sFileScheme ) ||
        aStrURL.EqualsIgnoreCaseAscii( sPortalFileScheme ) )
         aStrURL=aEmptyStr;

    GetDataFromCommonFields( aStrName, aStrIntName, aStrFrame, eMode );
}

/*************************************************************************
|*
|* static method to create Tabpage
|*
|************************************************************************/

IconChoicePage* SvxHyperlinkDocTp::Create( Window* pWindow, const SfxItemSet& rItemSet )
{
    return( new SvxHyperlinkDocTp( pWindow, rItemSet ) );
}

/*************************************************************************
|*
|* Set initial focus
|*
|************************************************************************/

void SvxHyperlinkDocTp::SetInitFocus()
{
    maCbbPath.GrabFocus();
}

/*************************************************************************
|*
|* Click on imagebutton : fileopen
|*
|************************************************************************/

IMPL_LINK ( SvxHyperlinkDocTp, ClickFileopenHdl_Impl, void *, EMPTYARG )
{
    // Open Fileopen-Dialog
       ::sfx2::FileDialogHelper aDlg(
        com::sun::star::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE, 0,
        GetParent() );
    String aOldURL( GetCurrentURL() );
    if( aOldURL.EqualsIgnoreCaseAscii( sFileScheme, 0, sizeof( sFileScheme ) - 1 ) ||
        aOldURL.EqualsIgnoreCaseAscii( sPortalFileScheme, 0, sizeof( sFileScheme ) - 1 ) )
    {
        aDlg.SetDisplayDirectory( aOldURL );
    }

    DisableClose( sal_True );
    ErrCode nError = aDlg.Execute();
    DisableClose( sal_False );

    if ( ERRCODE_NONE == nError )
    {
        String aURL( aDlg.GetPath() );
        String aPath;

        utl::LocalFileHelper::ConvertURLToSystemPath( aURL, aPath );

        maCbbPath.SetBaseURL( aURL );
        maCbbPath.SetText( aPath );

        if ( aOldURL != GetCurrentURL() )
            ModifiedPathHdl_Impl (NULL);
    }

    return( 0L );
}

/*************************************************************************
|*
|* Click on imagebutton : target
|*
|************************************************************************/

IMPL_LINK ( SvxHyperlinkDocTp, ClickTargetHdl_Impl, void *, EMPTYARG )
{
    if ( GetPathType ( maStrURL ) == Type_ExistsFile  ||
         maStrURL == aEmptyStr                        ||
         maStrURL.EqualsIgnoreCaseAscii( sFileScheme ) ||
         maStrURL.EqualsIgnoreCaseAscii( sPortalFileScheme ) ||
         maStrURL.SearchAscii( sHash ) == 0 )
    {
        mpMarkWnd->SetError( LERR_NOERROR );

        EnterWait();

        if ( maStrURL.EqualsIgnoreCaseAscii( sFileScheme ) ||
             maStrURL.EqualsIgnoreCaseAscii( sPortalFileScheme ) )
            mpMarkWnd->RefreshTree ( aEmptyStr );
        else
            mpMarkWnd->RefreshTree ( maStrURL );

        LeaveWait();
    }
    else
        mpMarkWnd->SetError( LERR_DOCNOTOPEN );

    ShowMarkWnd ();

    return( 0L );
}

/*************************************************************************
|*
|* Contens of combobox "Path" modified
|*
|************************************************************************/

IMPL_LINK ( SvxHyperlinkDocTp, ModifiedPathHdl_Impl, void *, EMPTYARG )
{
    maStrURL = GetCurrentURL();

    maTimer.SetTimeout( 2500 );
    maTimer.Start();

    maFtFullURL.SetText( maStrURL );

    return( 0L );
}

/*************************************************************************
|*
|* If path-field was modify, to browse the new doc after timeout
|*
|************************************************************************/

IMPL_LINK ( SvxHyperlinkDocTp, TimeoutHdl_Impl, Timer *, EMPTYARG )
{
    if ( IsMarkWndVisible() && ( GetPathType( maStrURL )==Type_ExistsFile ||
                                  maStrURL == aEmptyStr                   ||
                                  maStrURL.EqualsIgnoreCaseAscii( sFileScheme ) ) )
    {
        EnterWait();

        if ( maStrURL.EqualsIgnoreCaseAscii( sFileScheme ) ||
             maStrURL.EqualsIgnoreCaseAscii( sPortalFileScheme ) )
            mpMarkWnd->RefreshTree ( aEmptyStr );
        else
            mpMarkWnd->RefreshTree ( maStrURL );

        LeaveWait();
    }

    return( 0L );
}

/*************************************************************************
|*
|* Contens of editfield "Target" modified
|*
|************************************************************************/

IMPL_LINK ( SvxHyperlinkDocTp, ModifiedTargetHdl_Impl, void *, EMPTYARG )
{
    maStrURL = GetCurrentURL();

    if ( IsMarkWndVisible() )
        mpMarkWnd->SelectEntry ( maEdTarget.GetText() );

    maFtFullURL.SetText( maStrURL );

    return( 0L );
}

/*************************************************************************
|*
|* editfield "Target" lost focus
|*
|************************************************************************/

IMPL_LINK ( SvxHyperlinkDocTp, LostFocusPathHdl_Impl, void *, EMPTYARG )
{
    maStrURL = GetCurrentURL();

    maFtFullURL.SetText( maStrURL );

    return (0L);
}

/*************************************************************************
|*
|* Get String from Bookmark-Wnd
|*
|************************************************************************/

void SvxHyperlinkDocTp::SetMarkStr ( String& aStrMark )
{
    maEdTarget.SetText ( aStrMark );

    ModifiedTargetHdl_Impl ( NULL );
}

/*************************************************************************
|*
|* retrieve kind of pathstr
|*
|************************************************************************/

SvxHyperlinkDocTp::EPathType SvxHyperlinkDocTp::GetPathType ( String& aStrPath )
{
    INetURLObject aURL( aStrPath, INET_PROT_FILE );

    if( aURL.HasError() )
        return Type_Invalid;
    else
        return Type_ExistsFile;
}
<commit_msg>#161490# removed scheme vnd.sun.star.wfs<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: hldoctp.cxx,v $
 * $Revision: 1.28 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_cui.hxx"

#include "cuihyperdlg.hxx"
#include <unotools/localfilehelper.hxx>
#include <sfx2/filedlghelper.hxx>
#include "com/sun/star/ui/dialogs/TemplateDescription.hpp"

#include "hldoctp.hxx"
#include "hyperdlg.hrc"
#include "hlmarkwn_def.hxx" //ADD CHINA001

sal_Char __READONLY_DATA sHash[]                = "#";
sal_Char __READONLY_DATA sFileScheme[]          = INET_FILE_SCHEME;
sal_Char __READONLY_DATA sNewsSRVScheme[] = "news://";
    // TODO news:// is nonsense
sal_Char __READONLY_DATA sHTTPScheme[]    = INET_HTTP_SCHEME;

/*************************************************************************
|*
|* Contructor / Destructor
|*
|************************************************************************/

SvxHyperlinkDocTp::SvxHyperlinkDocTp ( Window *pParent, const SfxItemSet& rItemSet)
    : SvxHyperlinkTabPageBase ( pParent, CUI_RES( RID_SVXPAGE_HYPERLINK_DOCUMENT ), rItemSet ),
    maGrpDocument   ( this, CUI_RES (GRP_DOCUMENT) ),
    maFtPath        ( this, CUI_RES (FT_PATH_DOC) ),
    maCbbPath       ( this, INET_PROT_FILE ),
    maBtFileopen    ( this, CUI_RES (BTN_FILEOPEN) ),
    maGrpTarget     ( this, CUI_RES (GRP_TARGET) ),
    maFtTarget      ( this, CUI_RES (FT_TARGET_DOC) ),
    maEdTarget      ( this, CUI_RES (ED_TARGET_DOC) ),
    maFtURL         ( this, CUI_RES (FT_URL) ),
    maFtFullURL     ( this, CUI_RES (FT_FULL_URL) ),
    maBtBrowse      ( this, CUI_RES (BTN_BROWSE) ),
    mbMarkWndOpen   ( FALSE )
{
    // Set HC bitmaps and disable display of bitmap names.
    maBtBrowse.SetModeImage( Image( CUI_RES( IMG_BROWSE_HC ) ), BMP_COLOR_HIGHCONTRAST );
    maBtBrowse.EnableTextDisplay (FALSE);
    maBtFileopen.SetModeImage( Image( CUI_RES( IMG_FILEOPEN_HC ) ), BMP_COLOR_HIGHCONTRAST );
    maBtFileopen.EnableTextDisplay (FALSE);

    InitStdControls();
    FreeResource();

    // Init URL-Box (pos&size, Open-Handler)
    maCbbPath.SetPosSizePixel ( LogicToPixel( Point( COL_2, 15 ), MAP_APPFONT ),
                                LogicToPixel( Size ( 176 - COL_DIFF, 60), MAP_APPFONT ) );
    maCbbPath.Show();
    String aFileScheme( INET_FILE_SCHEME, RTL_TEXTENCODING_ASCII_US );
    maCbbPath.SetBaseURL(aFileScheme);
    maCbbPath.SetHelpId( HID_HYPERDLG_DOC_PATH );

    SetExchangeSupport ();

    // overload handlers
    maBtFileopen.SetClickHdl ( LINK ( this, SvxHyperlinkDocTp, ClickFileopenHdl_Impl ) );
    maBtBrowse.SetClickHdl   ( LINK ( this, SvxHyperlinkDocTp, ClickTargetHdl_Impl ) );
    maCbbPath.SetModifyHdl   ( LINK ( this, SvxHyperlinkDocTp, ModifiedPathHdl_Impl ) );
    maEdTarget.SetModifyHdl  ( LINK ( this, SvxHyperlinkDocTp, ModifiedTargetHdl_Impl ) );

    maCbbPath.SetLoseFocusHdl( LINK ( this, SvxHyperlinkDocTp, LostFocusPathHdl_Impl ) );

    maTimer.SetTimeoutHdl ( LINK ( this, SvxHyperlinkDocTp, TimeoutHdl_Impl ) );
}

SvxHyperlinkDocTp::~SvxHyperlinkDocTp ()
{
}

/*************************************************************************
|*
|* Fill all dialog-controls except controls in groupbox "more..."
|*
|************************************************************************/

void SvxHyperlinkDocTp::FillDlgFields ( String& aStrURL )
{
    INetURLObject aURL ( aStrURL );

    String aStrMark;
    xub_StrLen nPos = aStrURL.SearchAscii( sHash );
    // path
    maCbbPath.SetText ( aStrURL.Copy( 0, ( nPos == STRING_NOTFOUND ? aStrURL.Len() : nPos ) ) );

    // set target in document at editfield
    if ( nPos != STRING_NOTFOUND && nPos<aStrURL.Len()-1 )
        aStrMark = aStrURL.Copy( nPos+1, aStrURL.Len() );
     maEdTarget.SetText ( aStrMark );

    ModifiedPathHdl_Impl ( NULL );
}

/*************************************************************************
|*
|* retrieve current url-string
|*
|************************************************************************/

String SvxHyperlinkDocTp::GetCurrentURL ()
{
    // get data from dialog-controls
    String aStrURL;
    String aStrPath ( maCbbPath.GetText() );
    const String aBaseURL ( maCbbPath.GetBaseURL() );
    String aStrMark( maEdTarget.GetText() );

    if ( aStrPath != aEmptyStr )
    {
        INetURLObject aURL( aStrPath );
        if ( aURL.GetProtocol() != INET_PROT_NOT_VALID )    // maybe the path is already a valid
            aStrURL = aStrPath;                             // hyperlink, then we can use this path directly
        else
            utl::LocalFileHelper::ConvertSystemPathToURL( aStrPath, aBaseURL, aStrURL );

        //#105788# always create a URL even if it is not valid
        if( aStrURL == aEmptyStr )
            aStrURL = aStrPath;
    }

    if( aStrMark != aEmptyStr )
    {
        aStrURL.AppendAscii( sHash );
        aStrURL += aStrMark;
    }

    return aStrURL;
}

/*************************************************************************
|*
|* retrieve and prepare data from dialog-fields
|*
|************************************************************************/

void SvxHyperlinkDocTp::GetCurentItemData ( String& aStrURL, String& aStrName,
                                            String& aStrIntName, String& aStrFrame,
                                            SvxLinkInsertMode& eMode )
{
    // get data from standard-fields
    aStrURL = GetCurrentURL();

    if( aStrURL.EqualsIgnoreCaseAscii( sFileScheme ) )
         aStrURL=aEmptyStr;

    GetDataFromCommonFields( aStrName, aStrIntName, aStrFrame, eMode );
}

/*************************************************************************
|*
|* static method to create Tabpage
|*
|************************************************************************/

IconChoicePage* SvxHyperlinkDocTp::Create( Window* pWindow, const SfxItemSet& rItemSet )
{
    return( new SvxHyperlinkDocTp( pWindow, rItemSet ) );
}

/*************************************************************************
|*
|* Set initial focus
|*
|************************************************************************/

void SvxHyperlinkDocTp::SetInitFocus()
{
    maCbbPath.GrabFocus();
}

/*************************************************************************
|*
|* Click on imagebutton : fileopen
|*
|************************************************************************/

IMPL_LINK ( SvxHyperlinkDocTp, ClickFileopenHdl_Impl, void *, EMPTYARG )
{
    // Open Fileopen-Dialog
       ::sfx2::FileDialogHelper aDlg(
        com::sun::star::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE, 0,
        GetParent() );
    String aOldURL( GetCurrentURL() );
    if( aOldURL.EqualsIgnoreCaseAscii( sFileScheme, 0, sizeof( sFileScheme ) - 1 ) )
    {
        aDlg.SetDisplayDirectory( aOldURL );
    }

    DisableClose( sal_True );
    ErrCode nError = aDlg.Execute();
    DisableClose( sal_False );

    if ( ERRCODE_NONE == nError )
    {
        String aURL( aDlg.GetPath() );
        String aPath;

        utl::LocalFileHelper::ConvertURLToSystemPath( aURL, aPath );

        maCbbPath.SetBaseURL( aURL );
        maCbbPath.SetText( aPath );

        if ( aOldURL != GetCurrentURL() )
            ModifiedPathHdl_Impl (NULL);
    }

    return( 0L );
}

/*************************************************************************
|*
|* Click on imagebutton : target
|*
|************************************************************************/

IMPL_LINK ( SvxHyperlinkDocTp, ClickTargetHdl_Impl, void *, EMPTYARG )
{
    if ( GetPathType ( maStrURL ) == Type_ExistsFile  ||
         maStrURL == aEmptyStr                        ||
         maStrURL.EqualsIgnoreCaseAscii( sFileScheme ) ||
         maStrURL.SearchAscii( sHash ) == 0 )
    {
        mpMarkWnd->SetError( LERR_NOERROR );

        EnterWait();

        if ( maStrURL.EqualsIgnoreCaseAscii( sFileScheme ) )
            mpMarkWnd->RefreshTree ( aEmptyStr );
        else
            mpMarkWnd->RefreshTree ( maStrURL );

        LeaveWait();
    }
    else
        mpMarkWnd->SetError( LERR_DOCNOTOPEN );

    ShowMarkWnd ();

    return( 0L );
}

/*************************************************************************
|*
|* Contens of combobox "Path" modified
|*
|************************************************************************/

IMPL_LINK ( SvxHyperlinkDocTp, ModifiedPathHdl_Impl, void *, EMPTYARG )
{
    maStrURL = GetCurrentURL();

    maTimer.SetTimeout( 2500 );
    maTimer.Start();

    maFtFullURL.SetText( maStrURL );

    return( 0L );
}

/*************************************************************************
|*
|* If path-field was modify, to browse the new doc after timeout
|*
|************************************************************************/

IMPL_LINK ( SvxHyperlinkDocTp, TimeoutHdl_Impl, Timer *, EMPTYARG )
{
    if ( IsMarkWndVisible() && ( GetPathType( maStrURL )==Type_ExistsFile ||
                                  maStrURL == aEmptyStr                   ||
                                  maStrURL.EqualsIgnoreCaseAscii( sFileScheme ) ) )
    {
        EnterWait();

        if ( maStrURL.EqualsIgnoreCaseAscii( sFileScheme ) )
            mpMarkWnd->RefreshTree ( aEmptyStr );
        else
            mpMarkWnd->RefreshTree ( maStrURL );

        LeaveWait();
    }

    return( 0L );
}

/*************************************************************************
|*
|* Contens of editfield "Target" modified
|*
|************************************************************************/

IMPL_LINK ( SvxHyperlinkDocTp, ModifiedTargetHdl_Impl, void *, EMPTYARG )
{
    maStrURL = GetCurrentURL();

    if ( IsMarkWndVisible() )
        mpMarkWnd->SelectEntry ( maEdTarget.GetText() );

    maFtFullURL.SetText( maStrURL );

    return( 0L );
}

/*************************************************************************
|*
|* editfield "Target" lost focus
|*
|************************************************************************/

IMPL_LINK ( SvxHyperlinkDocTp, LostFocusPathHdl_Impl, void *, EMPTYARG )
{
    maStrURL = GetCurrentURL();

    maFtFullURL.SetText( maStrURL );

    return (0L);
}

/*************************************************************************
|*
|* Get String from Bookmark-Wnd
|*
|************************************************************************/

void SvxHyperlinkDocTp::SetMarkStr ( String& aStrMark )
{
    maEdTarget.SetText ( aStrMark );

    ModifiedTargetHdl_Impl ( NULL );
}

/*************************************************************************
|*
|* retrieve kind of pathstr
|*
|************************************************************************/

SvxHyperlinkDocTp::EPathType SvxHyperlinkDocTp::GetPathType ( String& aStrPath )
{
    INetURLObject aURL( aStrPath, INET_PROT_FILE );

    if( aURL.HasError() )
        return Type_Invalid;
    else
        return Type_ExistsFile;
}
<|endoftext|>


<commit_before>#include <algorithm>

#include "ParamRenderArea.h"

#include <QPainter>
#include <QKeyEvent>
#include <iostream>

ParamRenderArea::ParamRenderArea(const QPainterPath &path, QWidget *parent)
        : QWidget(parent), path(path) {
    penWidth = 0.1f;
    rotationAngle = 0;
    offset.setX(50);
    offset.setY(50);
    triangulation = std::vector<ParameterTriangle *>();
    setBackgroundRole(QPalette::Base);
    std::random_shuffle(colors.begin(), colors.end());
}

QSize ParamRenderArea::minimumSizeHint() const {
    return QSize(50, 50);
}

QSize ParamRenderArea::sizeHint() const {
    return QSize(100, 100);
}

void ParamRenderArea::setPenWidth(float width) {
    penWidth = width;
    update();
}

void ParamRenderArea::setPenColor(const QColor &color) {
    penColor = color;
    update();
}

void ParamRenderArea::paintEvent(QPaintEvent *) {
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.scale(width() / 100.0, height() / 100.0);
    painter.translate(offset);
    painter.rotate(-rotationAngle);
    painter.translate(-offset);
    painter.setPen(QPen(penColor, penWidth, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));

    int colorID = 0;
    // draw all outer shapes
    for (QPainterPath p : outerShapes) {
        QLinearGradient g(0, 0, 0, 100);
        g.setColorAt(0.0, colors.at(colorID));
        g.setColorAt(1.0, colors.at(colorID));
        painter.setBrush(g);
        painter.drawPath(p);
        colorID = (colorID + 1) % colors.size();
    }
    // draw all inner shapes
    for (QPainterPath p : innerShapes) {
        QLinearGradient g(0, 0, 0, 100);
        g.setColorAt(0.0, colors.at(colorID));
        g.setColorAt(1.0, colors.at(colorID));
        painter.setBrush(g);
        painter.drawPath(p);
        colorID = (colorID + 1) % colors.size();
    }
    // draw current path
    QLinearGradient gradient(0, 0, 0, 100);
    gradient.setColorAt(0.0, colors.at(colorID));
    gradient.setColorAt(1.0, colors.at(colorID));
    painter.setBrush(gradient);
    painter.drawPath(path);

    // draw parameter triangulation
    QPainter trip(this);
    trip.setRenderHint(QPainter::Antialiasing);
    trip.scale(width() / 100.0, height() / 100.0);
    trip.translate(offset);
    trip.rotate(-rotationAngle);
    trip.translate(-offset);
    trip.setPen(QPen(Qt::black, 1.0f * penWidth, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
    for (ParameterTriangle *t : triangulation) {
        QPainterPath tP;
        tP.moveTo(denormalize(t->getPoint(0)));
        tP.lineTo(denormalize(t->getPoint(1)));
        tP.lineTo(denormalize(t->getPoint(2)));
        tP.lineTo(denormalize(t->getPoint(0)));
        trip.drawPath(tP);
    }
}

void ParamRenderArea::mousePressEvent(QMouseEvent *event) {
    QPointF pos = convertPos(event);
    if (event->button() == Qt::RightButton) {
        QList<QPointF> shape;
        std::copy(waypoints.begin(), waypoints.end(), std::back_inserter(shape));
        path = QPainterPath();
        waypoints.clear();
    } else {
        waypoints.push_back(pos);
        path = QPainterPath();
        path.moveTo(waypoints[0]);
        for (int i = 1; i < waypoints.size(); ++i) {
            path.lineTo(waypoints[i]);
        }
        path.closeSubpath();
    }
    update();
}

QPointF ParamRenderArea::convertPos(QMouseEvent *e) {
    return QPointF(100 * e->x() / width(), 100 * e->y() / height());
}

QList<QList<QPointF> > ParamRenderArea::getShapes() {
    return shapeList;
}

void ParamRenderArea::setShapeType(ShapeType type) {
    currentType = type;
}

void ParamRenderArea::keyPressEvent(QKeyEvent *event) {
    switch (event->key()) {
        case Qt::Key_Backspace:
            removeLastWaypoint();
            break;
        case Qt::Key_Return:
            saveCurrentShape();
            break;
        default:
            break;
    }
}

void ParamRenderArea::removeLastWaypoint() {
    if (!waypoints.empty()) {
        waypoints.pop_back();
    }
    if (!waypoints.empty()) {
        path = QPainterPath();
        path.moveTo(waypoints[0]);
        for (int i = 1; i < waypoints.size(); ++i) {
            path.lineTo(waypoints[i]);
        }
        path.closeSubpath();
    }
    update();
}

void ParamRenderArea::saveCurrentShape() {
    QPainterPath p;
    if (!waypoints.empty()) {
        p.moveTo(waypoints[0]);
        for (int i = 1; i < waypoints.size(); ++i) {
            p.lineTo(waypoints[i]);
        }
        p.closeSubpath();
    }
    QList<QPointF> wp;
    for (QPointF po : waypoints) {
        wp.push_back(po);
    }
    shapeList.append(wp);
    waypoints.clear();
    switch (currentType) {
        case ShapeType::INNER:
            innerShapes.append(p);
            break;
        case ShapeType::OUTER:
            outerShapes.append(p);
            break;
        default:
            break;
    }
}

void ParamRenderArea::clearShapes() {
    innerShapes.clear();
    outerShapes.clear();
    waypoints.clear();
    update();
}

void ParamRenderArea::mouseDoubleClickEvent(QMouseEvent *event) {
    if (event->button() == Qt::LeftButton) {
        removeLastWaypoint(); // undo first click
        removeLastWaypoint(); // undo second click
    }
}

void ParamRenderArea::drawTriangulation(std::vector<ParameterTriangle *> triangulation_) {
    triangulation = triangulation_;
    update();
}

QPointF ParamRenderArea::denormalize(QVector2D v) {
    return QPointF(100.0f * v.x(), 100.0f - 100.f * v.y());
}

<commit_msg>Removing double clicking things.<commit_after>#include <algorithm>

#include "ParamRenderArea.h"

#include <QPainter>
#include <QKeyEvent>
#include <iostream>

ParamRenderArea::ParamRenderArea(const QPainterPath &path, QWidget *parent)
        : QWidget(parent), path(path) {
    penWidth = 0.1f;
    rotationAngle = 0;
    offset.setX(50);
    offset.setY(50);
    triangulation = std::vector<ParameterTriangle *>();
    setBackgroundRole(QPalette::Base);
    std::random_shuffle(colors.begin(), colors.end());
}

QSize ParamRenderArea::minimumSizeHint() const {
    return QSize(50, 50);
}

QSize ParamRenderArea::sizeHint() const {
    return QSize(100, 100);
}

void ParamRenderArea::setPenWidth(float width) {
    penWidth = width;
    update();
}

void ParamRenderArea::setPenColor(const QColor &color) {
    penColor = color;
    update();
}

void ParamRenderArea::paintEvent(QPaintEvent *) {
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.scale(width() / 100.0, height() / 100.0);
    painter.translate(offset);
    painter.rotate(-rotationAngle);
    painter.translate(-offset);
    painter.setPen(QPen(penColor, penWidth, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));

    int colorID = 0;
    // draw all outer shapes
    for (QPainterPath p : outerShapes) {
        QLinearGradient g(0, 0, 0, 100);
        g.setColorAt(0.0, colors.at(colorID));
        g.setColorAt(1.0, colors.at(colorID));
        painter.setBrush(g);
        painter.drawPath(p);
        colorID = (colorID + 1) % colors.size();
    }
    // draw all inner shapes
    for (QPainterPath p : innerShapes) {
        QLinearGradient g(0, 0, 0, 100);
        g.setColorAt(0.0, colors.at(colorID));
        g.setColorAt(1.0, colors.at(colorID));
        painter.setBrush(g);
        painter.drawPath(p);
        colorID = (colorID + 1) % colors.size();
    }
    // draw current path
    QLinearGradient gradient(0, 0, 0, 100);
    gradient.setColorAt(0.0, colors.at(colorID));
    gradient.setColorAt(1.0, colors.at(colorID));
    painter.setBrush(gradient);
    painter.drawPath(path);

    // draw parameter triangulation
    QPainter trip(this);
    trip.setRenderHint(QPainter::Antialiasing);
    trip.scale(width() / 100.0, height() / 100.0);
    trip.translate(offset);
    trip.rotate(-rotationAngle);
    trip.translate(-offset);
    trip.setPen(QPen(Qt::black, 1.0f * penWidth, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
    for (ParameterTriangle *t : triangulation) {
        QPainterPath tP;
        tP.moveTo(denormalize(t->getPoint(0)));
        tP.lineTo(denormalize(t->getPoint(1)));
        tP.lineTo(denormalize(t->getPoint(2)));
        tP.lineTo(denormalize(t->getPoint(0)));
        trip.drawPath(tP);
    }
}

void ParamRenderArea::mousePressEvent(QMouseEvent *event) {
    QPointF pos = convertPos(event);
    if (event->button() == Qt::RightButton) {
        QList<QPointF> shape;
        std::copy(waypoints.begin(), waypoints.end(), std::back_inserter(shape));
        path = QPainterPath();
        waypoints.clear();
    } else {
        waypoints.push_back(pos);
        path = QPainterPath();
        path.moveTo(waypoints[0]);
        for (int i = 1; i < waypoints.size(); ++i) {
            path.lineTo(waypoints[i]);
        }
        path.closeSubpath();
    }
    update();
}

QPointF ParamRenderArea::convertPos(QMouseEvent *e) {
    return QPointF(100 * e->x() / width(), 100 * e->y() / height());
}

QList<QList<QPointF> > ParamRenderArea::getShapes() {
    return shapeList;
}

void ParamRenderArea::setShapeType(ShapeType type) {
    currentType = type;
}

void ParamRenderArea::keyPressEvent(QKeyEvent *event) {
    switch (event->key()) {
        case Qt::Key_Backspace:
            removeLastWaypoint();
            break;
        case Qt::Key_Return:
            saveCurrentShape();
            break;
        default:
            break;
    }
}

void ParamRenderArea::removeLastWaypoint() {
    if (!waypoints.empty()) {
        waypoints.pop_back();
    }
    if (!waypoints.empty()) {
        path = QPainterPath();
        path.moveTo(waypoints[0]);
        for (int i = 1; i < waypoints.size(); ++i) {
            path.lineTo(waypoints[i]);
        }
        path.closeSubpath();
    }
    update();
}

void ParamRenderArea::saveCurrentShape() {
    QPainterPath p;
    if (!waypoints.empty()) {
        p.moveTo(waypoints[0]);
        for (int i = 1; i < waypoints.size(); ++i) {
            p.lineTo(waypoints[i]);
        }
        p.closeSubpath();
    }
    QList<QPointF> wp;
    for (QPointF po : waypoints) {
        wp.push_back(po);
    }
    shapeList.append(wp);
    waypoints.clear();
    switch (currentType) {
        case ShapeType::INNER:
            innerShapes.append(p);
            break;
        case ShapeType::OUTER:
            outerShapes.append(p);
            break;
        default:
            break;
    }
}

void ParamRenderArea::clearShapes() {
    innerShapes.clear();
    outerShapes.clear();
    waypoints.clear();
    update();
}

void ParamRenderArea::mouseDoubleClickEvent(QMouseEvent *event) {
//    if (event->button() == Qt::LeftButton) {
//        removeLastWaypoint(); // undo first click
//        removeLastWaypoint(); // undo second click
//    }
}

void ParamRenderArea::drawTriangulation(std::vector<ParameterTriangle *> triangulation_) {
    triangulation = triangulation_;
    update();
}

QPointF ParamRenderArea::denormalize(QVector2D v) {
    return QPointF(100.0f * v.x(), 100.0f - 100.f * v.y());
}

<|endoftext|>


<commit_before>/*
 * Copyright 2015 - 2018 gtalent2@gmail.com
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#pragma once

#ifdef OX_USE_STDLIB
#include <cstddef>
#else
#define offsetof(type, member) __builtin_offsetof(type, member)
#endif

#ifdef _MSC_VER
#define OX_PACKED
#else
#define OX_PACKED __attribute__((packed))
#endif
<commit_msg>[ox/std] Add OX_ALIGN4<commit_after>/*
 * Copyright 2015 - 2018 gtalent2@gmail.com
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#pragma once

#ifdef OX_USE_STDLIB
#include <cstddef>
#else
#define offsetof(type, member) __builtin_offsetof(type, member)
#endif

#ifdef _MSC_VER
#define OX_PACKED
#else
#define OX_PACKED __attribute__((packed))
#endif

#ifdef _MSC_VER
#define OX_ALIGN4
#else
#define OX_ALIGN4 __attribute__((aligned(4)))
#endif
<|endoftext|>