<commit_before>#include <stdio.h>
#include <stdexcept>

#include <QMutexLocker>

#include <Utils.hpp>
#include "USBRadio.hpp"
#include "Geometry2d/Util.hpp"

// Include this file for base station usb vendor/product ids
#include "firmware-common/base2015/usb-interface.hpp"
// included for kicer status enum
#include "firmware-common/robot2015/cpu/status.h"

using namespace std;
using namespace Packet;

// Timeout for control transfers, in milliseconds
static const int Control_Timeout = 1000;

USBRadio::USBRadio() : _mutex(QMutex::Recursive) {
    _printedError = false;
    _device = nullptr;
    _usb_context = nullptr;
    libusb_init(&_usb_context);

    for (int i = 0; i < NumRXTransfers; ++i) {
        _rxTransfers[i] = libusb_alloc_transfer(0);
    }
}

USBRadio::~USBRadio() {
    if (_device) {
        libusb_close(_device);
    }

    for (int i = 0; i < NumRXTransfers; ++i) {
        libusb_free_transfer(_rxTransfers[i]);
    }

    libusb_exit(_usb_context);
}

bool USBRadio::open() {
    libusb_device** devices = nullptr;
    ssize_t numDevices = libusb_get_device_list(_usb_context, &devices);

    if (numDevices < 0) {
        fprintf(stderr, "libusb_get_device_list failed\n");
        return false;
    }

    int numRadios = 0;
    for (int i = 0; i < numDevices; ++i) {
        struct libusb_device_descriptor desc;
        int err = libusb_get_device_descriptor(devices[i], &desc);
        if (err == 0 && desc.idVendor == RJ_BASE2015_VENDOR_ID &&
            desc.idProduct == RJ_BASE2015_PRODUCT_ID) {
            ++numRadios;
            int err = libusb_open(devices[i], &_device);
            if (err == 0) {
                break;
            }
        }
    }

    libusb_free_device_list(devices, 1);

    if (!numRadios) {
        if (!_printedError) {
            fprintf(stderr, "USBRadio: No radio is connected\n");
            _printedError = true;
        }
        return false;
    }

    if (!_device) {
        if (!_printedError) {
            fprintf(stderr, "USBRadio: All radios are in use\n");
            _printedError = true;
        }
        return false;
    }

    if (libusb_set_configuration(_device, 1)) {
        if (!_printedError) {
            fprintf(stderr, "USBRadio: Can't set configuration\n");
            _printedError = true;
        }
        return false;
    }

    if (libusb_claim_interface(_device, 0)) {
        if (!_printedError) {
            fprintf(stderr, "USBRadio: Can't claim interface\n");
            _printedError = true;
        }
        return false;
    }

    channel(_channel);

    // Start the receive transfers
    for (int i = 0; i < NumRXTransfers; ++i) {
        // Populate the required libusb_transfer fields for a bulk transfer.
        libusb_fill_bulk_transfer(
            _rxTransfers[i],  // the transfer to populate
            _device,  // handle of the device that will handle the transfer
            LIBUSB_ENDPOINT_IN |
                2,  // address of the endpoint where this transfer will be sent
            _rxBuffers[i],      // data buffer
            rtp::ReverseSize,  // length of data buffer
            rxCompleted,        // callback function to be invoked on transfer
                                // completion
            this,               // user data to pass to callback function
            0);                 // timeout for the transfer in milliseconds
        libusb_submit_transfer(_rxTransfers[i]);
    }

    _printedError = false;

    return true;
}

void USBRadio::rxCompleted(libusb_transfer* transfer) {
    USBRadio* radio = (USBRadio*)transfer->user_data;

    if (transfer->status == LIBUSB_TRANSFER_COMPLETED &&
        transfer->actual_length == rtp::ReverseSize) {
        // Parse the packet and add to the list of RadioRx's
        radio->handleRxData(transfer->buffer);
    }

    // Restart the transfer
    libusb_submit_transfer(transfer);
}

void USBRadio::command(uint8_t cmd) {
    if (libusb_control_transfer(_device,
                                LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR,
                                Base2015ControlCommand::RadioStrobe, 0, cmd,
                                nullptr, 0, Control_Timeout)) {
        throw runtime_error("USBRadio::command control write failed");
    }
}

void USBRadio::write(uint8_t reg, uint8_t value) {
    if (libusb_control_transfer(_device,
                                LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR,
                                Base2015ControlCommand::RadioWriteRegister,
                                value, reg, nullptr, 0, Control_Timeout)) {
        throw runtime_error("USBRadio::write control write failed");
    }
}

uint8_t USBRadio::read(uint8_t reg) {
    uint8_t value = 0;
    if (libusb_control_transfer(_device,
                                LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR,
                                Base2015ControlCommand::RadioReadRegister, 0,
                                reg, &value, 1, Control_Timeout)) {
        throw runtime_error("USBRadio::read control write failed");
    }

    return value;
}

bool USBRadio::isOpen() const { return _device; }

void USBRadio::send(Packet::RadioTx& packet) {
    QMutexLocker lock(&_mutex);
    if (!_device) {
        if (!open()) {
            return;
        }
    }

    uint8_t forward_packet[rtp::ForwardSize];

    // ensure Forward_Size is correct
    static_assert(sizeof(rtp::Header) + 6 * sizeof(rtp::RobotTxMessage) ==
                      rtp::ForwardSize,
                  "Forward packet contents exceeds buffer size");

    // Unit conversions
    static const float Seconds_Per_Cycle = 0.005f;
    static const float Meters_Per_Tick = 0.026f * 2 * M_PI / 6480.0f;
    static const float Radians_Per_Tick = 0.026f * M_PI / (0.0812f * 3240.0f);

    rtp::Header* header = (rtp::Header*)forward_packet;
    header->port = rtp::PortType::CONTROL;
    header->address = rtp::BROADCAST_ADDRESS;
    header->type = rtp::MessageType::CONTROL;

    // Build a forward packet
    for (int slot = 0; slot < 6; ++slot) {
        // Calculate the offset into the @forward_packet for this robot's
        // control message and cast it to a ControlMessage pointer for easy
        // access
        size_t offset =
            sizeof(rtp::Header) + slot * sizeof(rtp::RobotTxMessage);
        rtp::RobotTxMessage* msg =
            (rtp::RobotTxMessage*)(forward_packet + offset);

        if (slot < packet.robots_size()) {
            const Packet::Control& robot = packet.robots(slot).control();

            msg->uid = packet.robots(slot).uid();
            msg->messageType = rtp::RobotTxMessage::ControlMessageType;

            auto &controlMessage = msg->message.controlMessage;

            controlMessage.bodyX = static_cast<int16_t >(robot.xvelocity() * rtp::ControlMessage::VELOCITY_SCALE_FACTOR);
            controlMessage.bodyY = static_cast<int16_t >(robot.yvelocity() * rtp::ControlMessage::VELOCITY_SCALE_FACTOR);
            controlMessage.bodyW = static_cast<int16_t >(robot.avelocity() * rtp::ControlMessage::VELOCITY_SCALE_FACTOR);

            controlMessage.dribbler = clamp(static_cast<uint16_t>(robot.dvelocity()) * 2, 0, 255);

            controlMessage.kickStrength = robot.kcstrength();
            controlMessage.shootMode = robot.shootmode();
            controlMessage.triggerMode = robot.triggermode();
            controlMessage.song = robot.song();
        } else {
            // empty slot
            msg->uid = rtp::INVALID_ROBOT_UID;
        }
    }

//    int numRobotTXMessages = packet.robots_size();
//
//    for (int configStartIndex=0; configStartIndex<packet.configs_size(); configStartIndex+=rtp::ConfMessage::length) {
//        if (numRobotTXMessages<6) {
//            auto slot = numRobotTXMessages;
//            size_t offset =
//                    sizeof(rtp::Header) + slot * sizeof(rtp::RobotTxMessage);
//            rtp::RobotTxMessage* msg =
//                    (rtp::RobotTxMessage*)(forward_packet + offset);
//
//            msg->uid = rtp::ANY_ROBOT_UID;
//            msg->messageType = rtp::RobotTxMessage::ConfMessageType;
//
//            auto &confMessage = msg->message.confMessage;
//
//
//            auto numToCopy = std::min(static_cast<int>(rtp::ConfMessage::length), packet.configs_size()-configStartIndex);
//            for (int i=0; i<numToCopy; i++) {
//                const auto &config = packet.configs(i+configStartIndex);
//                auto key = static_cast<DebugCommunication::ConfigCommunication>(config.key());
//                confMessage.keys[i] = key;
//                confMessage.values[i] = DebugCommunication::configToValue(key, config.value());
//            }
//            numRobotTXMessages++;
//        }
//    }
//    {
//        std::lock_guard<std::mutex> lock(current_receive_debug_mutex);
//        current_receive_debug.clear();
//        for (auto debugMessages : packet.debug_communication()) {
//            current_receive_debug.push_back(static_cast<DebugCommunication::DebugResponse>(debugMessages.key()));
//        }
//    }
//    if (numRobotTXMessages<6) {
//        auto slot = numRobotTXMessages;
//        size_t offset =
//            sizeof(rtp::Header) + slot * sizeof(rtp::RobotTxMessage);
//        rtp::RobotTxMessage* msg =
//            (rtp::RobotTxMessage*)(forward_packet + offset);
//
//        msg->uid = rtp::ANY_ROBOT_UID;
//        msg->messageType = rtp::RobotTxMessage::DebugMessageType;
//
//        auto &debugMessage = msg->message.debugMessage;
//        std::copy_n(current_receive_debug.begin(), std::min(current_receive_debug.size(), debugMessage.keys.size()), debugMessage.keys.begin());
//
//        numRobotTXMessages++;
//    }

    // Send the forward packet
    int sent = 0;
    int transferRetCode =
        libusb_bulk_transfer(_device, LIBUSB_ENDPOINT_OUT | 2, forward_packet,
                             sizeof(forward_packet), &sent, Control_Timeout);
    if (transferRetCode != LIBUSB_SUCCESS || sent != sizeof(forward_packet)) {
        fprintf(stderr, "USBRadio: Bulk write failed. sent = %d, size = %lu\n",
                sent, (unsigned long int)sizeof(forward_packet));
        if (transferRetCode != LIBUSB_SUCCESS)
            fprintf(stderr, "  Error: '%s'\n",
                    libusb_error_name(transferRetCode));

        int ret = libusb_clear_halt(_device, LIBUSB_ENDPOINT_OUT | 2);
        if (ret != 0) {
            printf("tried to clear halt, error = %s\n. closing device\n",
                   libusb_error_name(ret));
            libusb_close(_device);
            _device = nullptr;
        }
    }
}

void USBRadio::receive() {
    QMutexLocker lock(&_mutex);

    if (!_device) {
        if (!open()) {
            return;
        }
    }

    // Handle USB events.  This will call callbacks.
    struct timeval tv = {0, 0};
    libusb_handle_events_timeout(_usb_context, &tv);
}

// Note: this method assumes that sizeof(buf) == rtp::ReverseSize
void USBRadio::handleRxData(uint8_t* buf) {
    RadioRx packet = RadioRx();

    rtp::Header* header = (rtp::Header*)buf;
    rtp::RobotStatusMessage* msg =
        (rtp::RobotStatusMessage*)(buf + sizeof(rtp::Header));

    packet.set_timestamp(RJ::timestamp());
    packet.set_robot_id(msg->uid);

    // Hardware version
    packet.set_hardware_version(RJ2015);

    // battery voltage
    packet.set_battery(msg->battVoltage *
                       rtp::RobotStatusMessage::BATTERY_SCALE_FACTOR);

    // ball sense
    if (BallSenseStatus_IsValid(msg->ballSenseStatus)) {
        packet.set_ball_sense_status(BallSenseStatus(msg->ballSenseStatus));
    }

    // Using same flags as 2011 robot. See firmware/robot2011/cpu/status.h.
    // Report that everything is good b/c the bot currently has no way of
    // detecting kicker issues
    packet.set_kicker_status((msg->kickStatus ? Kicker_Charged : 0) |
                             (msg->kickHealthy ? Kicker_Enabled : 0) | Kicker_I2C_OK);

    // motor errors
    for (int i = 0; i < 5; i++) {
        bool err = msg->motorErrors & (1 << i);
        packet.add_motor_status(err ? MotorStatus::Hall_Failure
                                    : MotorStatus::Good);
    }

    // fpga status
    if (FpgaStatus_IsValid(msg->fpgaStatus)) {
        packet.set_fpga_status(FpgaStatus(msg->fpgaStatus));
    }

    {
        std::lock_guard<std::mutex> lock(current_receive_debug_mutex);
        for (int index = 0; index < current_receive_debug.size(); ++index) {
            auto debugResponse = current_receive_debug[index];
            const auto &name = DebugCommunication::DEBUGRESPONSE_TO_STRING.at(debugResponse);
//            auto value = msg->debug_data[index];
//
//            auto packet_debug_response = packet.add_debug_responses();
//            packet_debug_response->set_key(name);
//            packet_debug_response->set_value(DebugCommunication::debugResponseValueToFloat(debugResponse, value));
        }
    }
    _reversePackets.push_back(packet);
}

void USBRadio::channel(int n) {
    QMutexLocker lock(&_mutex);

    if (_device) {
        if (libusb_control_transfer(
                _device, LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR,
                Base2015ControlCommand::RadioSetChannel, n, 0, nullptr, 0,
                Control_Timeout)) {
            throw runtime_error("USBRadio::channel control write failed");
        }
    }

    Radio::channel(n);
}
<commit_msg>"Fix" radio issues<commit_after>#include <stdio.h>
#include <stdexcept>

#include <QMutexLocker>

#include <Utils.hpp>
#include "USBRadio.hpp"
#include "Geometry2d/Util.hpp"

// Include this file for base station usb vendor/product ids
#include "firmware-common/base2015/usb-interface.hpp"
// included for kicer status enum
#include "firmware-common/robot2015/cpu/status.h"

using namespace std;
using namespace Packet;

// Timeout for control transfers, in milliseconds
static const int Control_Timeout = 1000;

USBRadio::USBRadio() : _mutex(QMutex::Recursive) {
    _printedError = false;
    _device = nullptr;
    _usb_context = nullptr;
    libusb_init(&_usb_context);

    for (int i = 0; i < NumRXTransfers; ++i) {
        _rxTransfers[i] = libusb_alloc_transfer(0);
    }
}

USBRadio::~USBRadio() {
    if (_device) {
        libusb_close(_device);
    }

    for (int i = 0; i < NumRXTransfers; ++i) {
        libusb_free_transfer(_rxTransfers[i]);
    }

    libusb_exit(_usb_context);
}

bool USBRadio::open() {
    libusb_device** devices = nullptr;
    ssize_t numDevices = libusb_get_device_list(_usb_context, &devices);

    if (numDevices < 0) {
        fprintf(stderr, "libusb_get_device_list failed\n");
        return false;
    }

    int numRadios = 0;
    for (int i = 0; i < numDevices; ++i) {
        struct libusb_device_descriptor desc;
        int err = libusb_get_device_descriptor(devices[i], &desc);
        if (err == 0 && desc.idVendor == RJ_BASE2015_VENDOR_ID &&
            desc.idProduct == RJ_BASE2015_PRODUCT_ID) {
            ++numRadios;
            int err = libusb_open(devices[i], &_device);
            if (err == 0) {
                break;
            }
        }
    }

    libusb_free_device_list(devices, 1);

    if (!numRadios) {
        if (!_printedError) {
            fprintf(stderr, "USBRadio: No radio is connected\n");
            _printedError = true;
        }
        return false;
    }

    if (!_device) {
        if (!_printedError) {
            fprintf(stderr, "USBRadio: All radios are in use\n");
            _printedError = true;
        }
        return false;
    }

    if (libusb_set_configuration(_device, 1)) {
        if (!_printedError) {
            fprintf(stderr, "USBRadio: Can't set configuration\n");
            _printedError = true;
        }
        return false;
    }

    if (libusb_claim_interface(_device, 0)) {
        if (!_printedError) {
            fprintf(stderr, "USBRadio: Can't claim interface\n");
            _printedError = true;
        }
        return false;
    }

    channel(_channel);

    // Start the receive transfers
    for (int i = 0; i < NumRXTransfers; ++i) {
        // Populate the required libusb_transfer fields for a bulk transfer.
        libusb_fill_bulk_transfer(
            _rxTransfers[i],  // the transfer to populate
            _device,  // handle of the device that will handle the transfer
            LIBUSB_ENDPOINT_IN |
                2,  // address of the endpoint where this transfer will be sent
            _rxBuffers[i],      // data buffer
            rtp::ReverseSize,  // length of data buffer
            rxCompleted,        // callback function to be invoked on transfer
                                // completion
            this,               // user data to pass to callback function
            0);                 // timeout for the transfer in milliseconds
        libusb_submit_transfer(_rxTransfers[i]);
    }

    _printedError = false;

    return true;
}

void USBRadio::rxCompleted(libusb_transfer* transfer) {
    USBRadio* radio = (USBRadio*)transfer->user_data;

    if (transfer->status == LIBUSB_TRANSFER_COMPLETED &&
        transfer->actual_length == rtp::ReverseSize) {
        // Parse the packet and add to the list of RadioRx's
        radio->handleRxData(transfer->buffer);
    }

    // Restart the transfer
    libusb_submit_transfer(transfer);
}

void USBRadio::command(uint8_t cmd) {
    if (libusb_control_transfer(_device,
                                LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR,
                                Base2015ControlCommand::RadioStrobe, 0, cmd,
                                nullptr, 0, Control_Timeout)) {
        throw runtime_error("USBRadio::command control write failed");
    }
}

void USBRadio::write(uint8_t reg, uint8_t value) {
    if (libusb_control_transfer(_device,
                                LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR,
                                Base2015ControlCommand::RadioWriteRegister,
                                value, reg, nullptr, 0, Control_Timeout)) {
        throw runtime_error("USBRadio::write control write failed");
    }
}

uint8_t USBRadio::read(uint8_t reg) {
    uint8_t value = 0;
    if (libusb_control_transfer(_device,
                                LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR,
                                Base2015ControlCommand::RadioReadRegister, 0,
                                reg, &value, 1, Control_Timeout)) {
        throw runtime_error("USBRadio::read control write failed");
    }

    return value;
}

bool USBRadio::isOpen() const { return _device; }

void USBRadio::send(Packet::RadioTx& packet) {
    QMutexLocker lock(&_mutex);
    if (!_device) {
        if (!open()) {
            return;
        }
    }

    uint8_t forward_packet[rtp::ForwardSize];

    // ensure Forward_Size is correct
    static_assert(sizeof(rtp::Header) + 6 * sizeof(rtp::RobotTxMessage) ==
                      rtp::ForwardSize,
                  "Forward packet contents exceeds buffer size");

    // Unit conversions
    static const float Seconds_Per_Cycle = 0.005f;
    static const float Meters_Per_Tick = 0.026f * 2 * M_PI / 6480.0f;
    static const float Radians_Per_Tick = 0.026f * M_PI / (0.0812f * 3240.0f);

    rtp::Header* header = (rtp::Header*)forward_packet;
    header->port = rtp::PortType::CONTROL;
    header->address = rtp::BROADCAST_ADDRESS;
    header->type = rtp::MessageType::CONTROL;

    // Build a forward packet
    for (int slot = 0; slot < 6; ++slot) {
        // Calculate the offset into the @forward_packet for this robot's
        // control message and cast it to a ControlMessage pointer for easy
        // access
        size_t offset =
            sizeof(rtp::Header) + slot * sizeof(rtp::RobotTxMessage);
        rtp::RobotTxMessage* msg =
            (rtp::RobotTxMessage*)(forward_packet + offset);

        if (slot < packet.robots_size()) {
            const Packet::Control& robot = packet.robots(slot).control();

            msg->uid = packet.robots(slot).uid();
            msg->messageType = rtp::RobotTxMessage::ControlMessageType;

            auto &controlMessage = msg->message.controlMessage;

            controlMessage.bodyX = static_cast<int16_t >(robot.xvelocity() * rtp::ControlMessage::VELOCITY_SCALE_FACTOR);
            controlMessage.bodyY = static_cast<int16_t >(robot.yvelocity() * rtp::ControlMessage::VELOCITY_SCALE_FACTOR);
            controlMessage.bodyW = static_cast<int16_t >(robot.avelocity() * rtp::ControlMessage::VELOCITY_SCALE_FACTOR);

            controlMessage.dribbler = clamp(static_cast<uint16_t>(robot.dvelocity()) * 2, 0, 255);

            controlMessage.kickStrength = robot.kcstrength();
            controlMessage.shootMode = robot.shootmode();
            controlMessage.triggerMode = robot.triggermode();
            controlMessage.song = robot.song();
        } else {
            // empty slot
            msg->uid = rtp::INVALID_ROBOT_UID;
        }
    }

//    int numRobotTXMessages = packet.robots_size();
//
//    for (int configStartIndex=0; configStartIndex<packet.configs_size(); configStartIndex+=rtp::ConfMessage::length) {
//        if (numRobotTXMessages<6) {
//            auto slot = numRobotTXMessages;
//            size_t offset =
//                    sizeof(rtp::Header) + slot * sizeof(rtp::RobotTxMessage);
//            rtp::RobotTxMessage* msg =
//                    (rtp::RobotTxMessage*)(forward_packet + offset);
//
//            msg->uid = rtp::ANY_ROBOT_UID;
//            msg->messageType = rtp::RobotTxMessage::ConfMessageType;
//
//            auto &confMessage = msg->message.confMessage;
//
//
//            auto numToCopy = std::min(static_cast<int>(rtp::ConfMessage::length), packet.configs_size()-configStartIndex);
//            for (int i=0; i<numToCopy; i++) {
//                const auto &config = packet.configs(i+configStartIndex);
//                auto key = static_cast<DebugCommunication::ConfigCommunication>(config.key());
//                confMessage.keys[i] = key;
//                confMessage.values[i] = DebugCommunication::configToValue(key, config.value());
//            }
//            numRobotTXMessages++;
//        }
//    }
//    {
//        std::lock_guard<std::mutex> lock(current_receive_debug_mutex);
//        current_receive_debug.clear();
//        for (auto debugMessages : packet.debug_communication()) {
//            current_receive_debug.push_back(static_cast<DebugCommunication::DebugResponse>(debugMessages.key()));
//        }
//    }
//    if (numRobotTXMessages<6) {
//        auto slot = numRobotTXMessages;
//        size_t offset =
//            sizeof(rtp::Header) + slot * sizeof(rtp::RobotTxMessage);
//        rtp::RobotTxMessage* msg =
//            (rtp::RobotTxMessage*)(forward_packet + offset);
//
//        msg->uid = rtp::ANY_ROBOT_UID;
//        msg->messageType = rtp::RobotTxMessage::DebugMessageType;
//
//        auto &debugMessage = msg->message.debugMessage;
//        std::copy_n(current_receive_debug.begin(), std::min(current_receive_debug.size(), debugMessage.keys.size()), debugMessage.keys.begin());
//
//        numRobotTXMessages++;
//    }

    // Send the forward packet
    int sent = 0;
    // TODO FIXME remove this hack, which increases the size of data packets by 2.
    // See +2 on sizeof's below.
    int transferRetCode =
        libusb_bulk_transfer(_device, LIBUSB_ENDPOINT_OUT | 2, forward_packet,
                             sizeof(forward_packet) + 2, &sent, Control_Timeout);
    if (transferRetCode != LIBUSB_SUCCESS || sent != sizeof(forward_packet) + 2) {
        fprintf(stderr, "USBRadio: Bulk write failed. sent = %d, size = %lu\n",
                sent, (unsigned long int)sizeof(forward_packet));
        if (transferRetCode != LIBUSB_SUCCESS)
            fprintf(stderr, "  Error: '%s'\n",
                    libusb_error_name(transferRetCode));

        int ret = libusb_clear_halt(_device, LIBUSB_ENDPOINT_OUT | 2);
        if (ret != 0) {
            printf("tried to clear halt, error = %s\n. closing device\n",
                   libusb_error_name(ret));
            libusb_close(_device);
            _device = nullptr;
        }
    }
}

void USBRadio::receive() {
    QMutexLocker lock(&_mutex);

    if (!_device) {
        if (!open()) {
            return;
        }
    }

    // Handle USB events.  This will call callbacks.
    struct timeval tv = {0, 0};
    libusb_handle_events_timeout(_usb_context, &tv);
}

// Note: this method assumes that sizeof(buf) == rtp::ReverseSize
void USBRadio::handleRxData(uint8_t* buf) {
    RadioRx packet = RadioRx();

    rtp::Header* header = (rtp::Header*)buf;
    rtp::RobotStatusMessage* msg =
        (rtp::RobotStatusMessage*)(buf + sizeof(rtp::Header));

    packet.set_timestamp(RJ::timestamp());
    packet.set_robot_id(msg->uid);

    // Hardware version
    packet.set_hardware_version(RJ2015);

    // battery voltage
    packet.set_battery(msg->battVoltage *
                       rtp::RobotStatusMessage::BATTERY_SCALE_FACTOR);

    // ball sense
    if (BallSenseStatus_IsValid(msg->ballSenseStatus)) {
        packet.set_ball_sense_status(BallSenseStatus(msg->ballSenseStatus));
    }

    // Using same flags as 2011 robot. See firmware/robot2011/cpu/status.h.
    // Report that everything is good b/c the bot currently has no way of
    // detecting kicker issues
    packet.set_kicker_status((msg->kickStatus ? Kicker_Charged : 0) |
                             (msg->kickHealthy ? Kicker_Enabled : 0) | Kicker_I2C_OK);

    // motor errors
    for (int i = 0; i < 5; i++) {
        bool err = msg->motorErrors & (1 << i);
        packet.add_motor_status(err ? MotorStatus::Hall_Failure
                                    : MotorStatus::Good);
    }

    // fpga status
    if (FpgaStatus_IsValid(msg->fpgaStatus)) {
        packet.set_fpga_status(FpgaStatus(msg->fpgaStatus));
    }

    {
        std::lock_guard<std::mutex> lock(current_receive_debug_mutex);
        for (int index = 0; index < current_receive_debug.size(); ++index) {
            auto debugResponse = current_receive_debug[index];
            const auto &name = DebugCommunication::DEBUGRESPONSE_TO_STRING.at(debugResponse);
//            auto value = msg->debug_data[index];
//
//            auto packet_debug_response = packet.add_debug_responses();
//            packet_debug_response->set_key(name);
//            packet_debug_response->set_value(DebugCommunication::debugResponseValueToFloat(debugResponse, value));
        }
    }
    _reversePackets.push_back(packet);
}

void USBRadio::channel(int n) {
    QMutexLocker lock(&_mutex);

    if (_device) {
        if (libusb_control_transfer(
                _device, LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR,
                Base2015ControlCommand::RadioSetChannel, n, 0, nullptr, 0,
                Control_Timeout)) {
            throw runtime_error("USBRadio::channel control write failed");
        }
    }

    Radio::channel(n);
}
<|endoftext|>


<commit_before>#include "NFComm/NFPluginModule/NFPlatform.h"

#if NF_PLATFORM == NF_PLATFORM_WIN
#endif

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

#ifdef NF_DEBUG_MODE

#if NF_PLATFORM == NF_PLATFORM_WIN

#ifdef NF_DYNAMIC_PLUGIN
#pragma comment( lib, "NFCore_d.lib" )
#pragma comment( lib, "Theron_d.lib" )

#else
#pragma comment( lib, "NFCore_d.lib" )
#pragma comment( lib, "Theron_d.lib" )
#endif

//#pragma comment( lib, "Theron_d.lib" )
#pragma comment( lib, "libglog_static_d.lib" )
#elif NF_PLATFORM == NF_PLATFORM_LINUX || NF_PLATFORM == NF_PLATFORM_ANDROID
#pragma comment( lib, "NFCore_d.a" )
#pragma comment( lib, "libglog_d.a" )
#pragma comment( lib, "libtherond.a")
#elif NF_PLATFORM == NF_PLATFORM_APPLE || NF_PLATFORM == NF_PLATFORM_APPLE_IOS
#endif

#else

#if NF_PLATFORM == NF_PLATFORM_WIN
#ifdef NF_DYNAMIC_PLUGIN
#pragma comment( lib, "NFCore.lib" )
#pragma comment( lib, "Theron.lib" )
#else
#pragma comment( lib, "NFCorec.lib" )
#pragma comment( lib, "Theron.lib" )
#endif

//#pragma comment( lib, "Theron.lib" )
#pragma comment( lib, "libglog_static.lib" )
#elif NF_PLATFORM == NF_PLATFORM_LINUX || NF_PLATFORM == NF_PLATFORM_ANDROID
#pragma comment( lib, "NFCore.a" )
#pragma comment( lib, "libglog.a" )
#pragma comment( lib, "libtherond.a")
#elif NF_PLATFORM == NF_PLATFORM_APPLE || NF_PLATFORM == NF_PLATFORM_APPLE_IOS
#endif

#endif
<commit_msg>Modify complile error of NFLogPlugin<commit_after>#include "NFComm/NFPluginModule/NFPlatform.h"

#if NF_PLATFORM == NF_PLATFORM_WIN
#endif

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

#ifdef NF_DEBUG_MODE

#if NF_PLATFORM == NF_PLATFORM_WIN

#ifdef NF_DYNAMIC_PLUGIN
#pragma comment( lib, "NFCore_d.lib" )
#pragma comment( lib, "Theron_d.lib" )

#else
#pragma comment( lib, "NFCore_d.lib" )
#pragma comment( lib, "Theron_d.lib" )
#endif

//#pragma comment( lib, "Theron_d.lib" )
//#pragma comment( lib, "libglog_static_d.lib" )
#elif NF_PLATFORM == NF_PLATFORM_LINUX || NF_PLATFORM == NF_PLATFORM_ANDROID
#pragma comment( lib, "NFCore_d.a" )
#pragma comment( lib, "libglog_d.a" )
#pragma comment( lib, "libtherond.a")
#elif NF_PLATFORM == NF_PLATFORM_APPLE || NF_PLATFORM == NF_PLATFORM_APPLE_IOS
#endif

#else

#if NF_PLATFORM == NF_PLATFORM_WIN
#ifdef NF_DYNAMIC_PLUGIN
#pragma comment( lib, "NFCore.lib" )
#pragma comment( lib, "Theron.lib" )
#else
#pragma comment( lib, "NFCorec.lib" )
#pragma comment( lib, "Theron.lib" )
#endif

//#pragma comment( lib, "Theron.lib" )
#pragma comment( lib, "libglog_static.lib" )
#elif NF_PLATFORM == NF_PLATFORM_LINUX || NF_PLATFORM == NF_PLATFORM_ANDROID
#pragma comment( lib, "NFCore.a" )
#pragma comment( lib, "libglog.a" )
#pragma comment( lib, "libtherond.a")
#elif NF_PLATFORM == NF_PLATFORM_APPLE || NF_PLATFORM == NF_PLATFORM_APPLE_IOS
#endif

#endif
<|endoftext|>


<commit_before>/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserve.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */

#include "paddle/memory/memory.h"
#include "paddle/memory/detail/buddy_allocator.h"
#include "paddle/memory/detail/system_allocator.h"

#include <cstring>  // for memcpy

namespace paddle {
namespace memory {

detail::BuddyAllocator* GetCPUBuddyAllocator() {
  static detail::BuddyAllocator* a = nullptr;
  if (a == nullptr) {
    a = new detail::BuddyAllocator(new detail::CPUAllocator,
                                   platform::CpuMinChunkSize(),
                                   platform::CpuMaxChunkSize());
  }
  return a;
}

template <>
void* Alloc<platform::CPUPlace>(platform::CPUPlace place, size_t size) {
  return GetCPUBuddyAllocator()->Alloc(size);
}

template <>
void Free<platform::CPUPlace>(platform::CPUPlace place, void* p) {
  GetCPUBuddyAllocator()->Free(p);
}

template <>
size_t Used<platform::CPUPlace>(platform::CPUPlace place) {
  return GetCPUBuddyAllocator()->Used();
}

#ifndef PADDLE_ONLY_CPU

detail::BuddyAllocator* GetGPUBuddyAllocator(int gpu_id) {
  static detail::BuddyAllocator** as = NULL;
  if (as == NULL) {
    int gpu_num = platform::GetDeviceCount();
    as = new detail::BuddyAllocator*[gpu_num];
    for (int gpu = 0; gpu < gpu_num; gpu++) {
      platform::SetDeviceId(gpu);
      as[gpu] = new detail::BuddyAllocator(new detail::GPUAllocator,
                                           platform::GpuMinChunkSize(),
                                           platform::GpuMaxChunkSize());
    }
  }
  platform::SetDeviceId(gpu_id);
  return as[gpu_id];
}

template <>
void* Alloc<platform::GPUPlace>(platform::GPUPlace place, size_t size) {
  return GetGPUBuddyAllocator(place.device)->Alloc(size);
}

template <>
void Free<platform::GPUPlace>(platform::GPUPlace place, void* p) {
  GetGPUBuddyAllocator(place.device)->Free(p);
}

template <>
size_t Used<platform::GPUPlace>(platform::GPUPlace place) {
  return GetGPUBuddyAllocator(place.device)->Used();
}

#endif  // PADDLE_ONLY_CPU

}  // namespace memory
}  // namespace paddle
<commit_msg>FIX: Release CPU/GPU memory via deleter<commit_after>/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserve.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */

#include "paddle/memory/memory.h"
#include "paddle/memory/detail/buddy_allocator.h"
#include "paddle/memory/detail/system_allocator.h"

#include <algorithm>  // for transfrom
#include <cstring>    // for memcpy
#include <mutex>      // for call_once

#include "glog/logging.h"

namespace paddle {
namespace memory {

using BuddyAllocator = detail::BuddyAllocator;

std::once_flag cpu_alloctor_flag;
std::once_flag gpu_alloctor_flag;

BuddyAllocator* GetCPUBuddyAllocator() {
  static std::unique_ptr<BuddyAllocator, void (*)(BuddyAllocator*)> a{
      nullptr, [](BuddyAllocator* p) { delete p; }};

  std::call_once(cpu_alloctor_flag, [&]() {
    a.reset(new BuddyAllocator(new detail::CPUAllocator,
                               platform::CpuMinChunkSize(),
                               platform::CpuMaxChunkSize()));
  });

  return a.get();
}

template <>
void* Alloc<platform::CPUPlace>(platform::CPUPlace place, size_t size) {
  return GetCPUBuddyAllocator()->Alloc(size);
}

template <>
void Free<platform::CPUPlace>(platform::CPUPlace place, void* p) {
  GetCPUBuddyAllocator()->Free(p);
}

template <>
size_t Used<platform::CPUPlace>(platform::CPUPlace place) {
  return GetCPUBuddyAllocator()->Used();
}

#ifndef PADDLE_ONLY_CPU

BuddyAllocator* GetGPUBuddyAllocator(int gpu_id) {
  using BuddyAllocVec = std::vector<BuddyAllocator*>;
  static std::unique_ptr<BuddyAllocVec, void (*)(BuddyAllocVec * p)> as{
      new std::vector<BuddyAllocator*>, [](BuddyAllocVec* p) {
        std::for_each(p->begin(), p->end(),
                      [](BuddyAllocator* p) { delete p; });
      }};

  // GPU buddy alloctors
  auto& alloctors = *as.get();

  // GPU buddy allocator initialization
  std::call_once(gpu_alloctor_flag, [&]() {
    int gpu_num = platform::GetDeviceCount();
    alloctors.reserve(gpu_num);
    for (int gpu = 0; gpu < gpu_num; gpu++) {
      platform::SetDeviceId(gpu);
      alloctors.emplace_back(new BuddyAllocator(new detail::GPUAllocator,
                                                platform::GpuMinChunkSize(),
                                                platform::GpuMaxChunkSize()));
    }
  });

  platform::SetDeviceId(gpu_id);
  return alloctors[gpu_id];
}

template <>
void* Alloc<platform::GPUPlace>(platform::GPUPlace place, size_t size) {
  return GetGPUBuddyAllocator(place.device)->Alloc(size);
}

template <>
void Free<platform::GPUPlace>(platform::GPUPlace place, void* p) {
  GetGPUBuddyAllocator(place.device)->Free(p);
}

template <>
size_t Used<platform::GPUPlace>(platform::GPUPlace place) {
  return GetGPUBuddyAllocator(place.device)->Used();
}

#endif  // PADDLE_ONLY_CPU

}  // namespace memory
}  // namespace paddle
<|endoftext|>


<commit_before><commit_msg>Use better web app icons.<commit_after><|endoftext|>


<commit_before>#include "stdafx.h"
#include "AutoFilterTest.h"
#include "AutoPacket.h"
#include "AutoPacketFactory.h"
#include "TestFixtures/Decoration.h"

TEST_F(AutoFilterTest, VerifyDescendentAwareness) {
  AutoCurrentContext()->Initiate();

  // Create a packet while the factory has no subscribers:
  AutoRequired<AutoPacketFactory> parentFactory;
  auto packet1 = parentFactory->NewPacket();

  // Verify subscription-free status:
  EXPECT_FALSE(packet1->HasSubscribers<Decoration<0>>()) << "Subscription exists where one should not have existed";

  std::shared_ptr<AutoPacket> packet2;
  std::weak_ptr<AutoPacket> packet3;
  std::weak_ptr<FilterA> filterChecker;

  // Create a subcontext
  {
    AutoCreateContext subContext;
    {
      CurrentContextPusher pusher(subContext);

      //add a filter in the subcontext
      AutoRequired<FilterA> subFilter;
      filterChecker = subFilter;
    }

    //Create a packet where a subscriber exists only in a subcontext
    packet2 = parentFactory->NewPacket();
    auto strongPacket3 = parentFactory->NewPacket();
    packet3 = strongPacket3;
    EXPECT_TRUE(packet2->HasSubscribers<Decoration<0>>()) << "Packet lacked expected subscription from subcontext";
    EXPECT_TRUE(packet3.lock()->HasSubscribers<Decoration<0>>()) << "Packet lacked expected subscription from subcontext";
  }
  EXPECT_TRUE(packet3.expired()) << "Packet was not destroyed when it's subscribers were removed";
  EXPECT_FALSE(filterChecker.expired()) << "Packet keeping subcontext member alive";

  // Create a packet after the subcontext has been destroyed
  auto packet4 = parentFactory->NewPacket();
  EXPECT_FALSE(packet4->HasSubscribers<Decoration<0>>()) << "Subscription exists where one should not have existed";

  // Verify the first packet still does not have subscriptions:
  EXPECT_FALSE(packet1->HasSubscribers<Decoration<0>>()) << "Subscription was incorrectly, retroactively added to a packet";

  packet2->Decorate(Decoration<0>());

  // Verify the second one will no longe have subscriptions  -
  // normally removing a subscriber would mean the packet still has the subscriber, but
  // in this case, the subscriber was actually destroyed so the packet has lost a subscriber.
  EXPECT_TRUE(packet2->HasSubscribers<Decoration<0>>()) << "Packet lacked an expected subscription";

  // Verify the third one does not:
  EXPECT_FALSE(packet4->HasSubscribers<Decoration<0>>()) << "Subscription was incorrectly, retroactively added to a packet";

  packet2.reset();
  EXPECT_TRUE(filterChecker.expired()) << "Subscriber didn't expire after packet was reset.";
}

TEST_F(AutoFilterTest, VerifySimpleFilter) {
  AutoCurrentContext()->Initiate();

  AutoRequired<AutoPacketFactory> factory;
  AutoRequired<FilterA> filterA;

  // Verify that the subscriber has been properly detected:
  bool bFound = false;
  for(const auto& cur : factory->GetSubscriberVector())
    if(cur.GetAutoFilter() == filterA) {
      bFound = true;
      break;
    }
  ASSERT_TRUE(bFound) << "Failed to find an added subscriber ";

  // Obtain a packet from the factory:
  auto packet = factory->NewPacket();

  // Decorate with one instance:
  packet->Decorate(Decoration<0>());

  // Verify that no hit takes place with inadequate decoration:
  EXPECT_FALSE(filterA->m_called) << "Filter called prematurely with insufficient decoration";

  // Now decorate with the other requirement of the filter:
  packet->Decorate(Decoration<1>());

  // A hit should have taken place at this point:
  EXPECT_TRUE(filterA->m_called) << "Filter was not called even though it was fully satisfied";
}

TEST_F(AutoFilterTest, VerifyNoMultiDecorate) {
  AutoCurrentContext()->Initiate();

  AutoRequired<FilterA> filterA;
  AutoRequired<AutoPacketFactory> factory;

  // Obtain a packet and attempt redundant introduction:
  auto packet = factory->NewPacket();
  packet->Decorate(Decoration<0>());
  EXPECT_ANY_THROW(packet->Decorate(Decoration<0>())) << "Redundant decoration did not throw an exception as expected";

  // Verify that a call has not yet been made
  EXPECT_FALSE(filterA->m_called) << "A call made on an idempotent packet decoration";

  // Now finish saturating the filter and ensure we get a call:
  packet->Decorate(Decoration<1>());
  EXPECT_TRUE(filterA->m_called) << "Filter was not called after being fully satisfied";
}

TEST_F(AutoFilterTest, VerifyInterThreadDecoration) {
  AutoRequired<FilterB> filterB;
  AutoRequired<AutoPacketFactory> factory;
  AutoCurrentContext ctxt;

  // Kick off all threads:
  ctxt->Initiate();

  // Obtain a packet for processing and decorate it:
  auto packet = factory->NewPacket();
  packet->Decorate(Decoration<0>());
  packet->Decorate(Decoration<1>());

  // Verify that the recipient has NOT yet received the message:
  EXPECT_FALSE(filterB->m_called) << "A call was made to a thread which should not have been able to process it";

  // Wake up the barrier and post a quit message:
  filterB->m_barr.wait();
  *filterB += [&filterB] { filterB->Stop(); };
  filterB->Wait();

  // Verify that the filter method has been called
  EXPECT_TRUE(filterB->m_called) << "A deferred filter method was not called as expected";
}

TEST_F(AutoFilterTest, VerifyTeardownArrangement) {
  AutoCurrentContext()->Initiate();
  AutoRequired<AutoPacketFactory> factory;

  std::weak_ptr<FilterA> filterAWeak;

  {
    std::shared_ptr<AutoPacket> packet;
    {
      // Create the filter and subscribe it
      std::shared_ptr<FilterA> filterA(new FilterA);
      filterAWeak = filterA;
      factory->AddSubscriber(filterA);

      // Create the packet--this should lock in references to all subscribers:
      packet = factory->NewPacket();
    }

    // Verify that the subscription has not expired:
    ASSERT_FALSE(filterAWeak.expired()) << "A subscriber while it was still registered";

    {
      std::shared_ptr<FilterA> filterA = filterAWeak.lock();

      // Unsubscribe the filter:
      factory->RemoveSubscriber(filterA);
    }

    // Verify that unsubscription STILL does not result in expiration:
    ASSERT_FALSE(filterAWeak.expired()) << "A subscriber expired before all packets on that subscriber were satisfied";

    //Create a new packet after having removed the only filter on it.
    auto packet2 = factory->NewPacket();
    ASSERT_FALSE(packet2->HasSubscribers<Decoration<0>>()) << "A packet had subscriptions after the only subscriber was removed.";

    // Satisfy the packet:
    packet->Decorate(Decoration<0>());
    packet->Decorate(Decoration<1>());

    auto packet3 = factory->NewPacket();
    ASSERT_FALSE(packet3->HasSubscribers<Decoration<0>>()) << "A packet had subscriptions after the only subscriber was removed.";
  }

  // Filter should be expired now:
  ASSERT_TRUE(filterAWeak.expired()) << "Subscriber was still left outstanding even though all references should be gone";
}

TEST_F(AutoFilterTest, VerifyCheckout) {
  AutoCurrentContext()->Initiate();
  AutoRequired<FilterA> filterA;
  AutoRequired<AutoPacketFactory> factory;

  // Obtain a packet for use with deferred decoration:
  auto packet = factory->NewPacket();

  {
    // Verify that an unsubscribed decoration returns a correct checkout:
    auto unused = packet->Checkout<Decoration<4>>();
    EXPECT_FALSE(unused) << "Checkout incorrectly generated for unsubscribed decoration";
  }

  // Satisfy the other decoration:
  packet->Decorate(Decoration<1>());

  {
    AutoCheckout<Decoration<0>> exterior;

    {
      AutoCheckout<Decoration<0>> checkout = packet->Checkout<Decoration<0>>();

      // Verify we can move the original type:
      AutoCheckout<Decoration<0>> checkoutMoved(std::move(checkout));

      // Verify no hits yet:
      EXPECT_FALSE(filterA->m_called) << "Filter called as a consequence of a checkout move operation";

      // Move the checkout a second time:
      exterior = std::move(checkoutMoved);
    }

    // Still no hits
    EXPECT_FALSE(filterA->m_called) << "Filter called before a decoration checkout expired";

    // Mark ready so we get committed:
    exterior.Ready();
  }

  // Verify a hit took place now
  EXPECT_TRUE(filterA->m_called) << "Filter was not called after all decorations were installed";
}

TEST_F(AutoFilterTest, RollbackCorrectness) {
  AutoCurrentContext()->Initiate();
  AutoRequired<FilterA> filterA;
  AutoRequired<AutoPacketFactory> factory;

  // Obtain a packet for use with deferred decoration:
  auto packet = factory->NewPacket();
  packet->Decorate(Decoration<1>());

  // Request and immediately allow the destruction of a checkout:
  packet->Checkout<Decoration<0>>();

  // Verify no hit took place--the checkout should have been cancelled:
  EXPECT_FALSE(filterA->m_called) << "Filter was called even though one decoration shouldn't have been available";

  // We should not be able to obtain another checkout of this decoration on this packet:
  EXPECT_ANY_THROW(packet->Checkout<Decoration<0>>()) << "An attempt to check out a decoration a second time should have failed";

  // We shouldn't be able to manually decorate, either:
  EXPECT_ANY_THROW(packet->Decorate(Decoration<0>())) << "An attempt to manually add a previously failed decoration succeeded where it should not have";
}

TEST_F(AutoFilterTest, VerifyAntiDecorate) {
  AutoCurrentContext()->Initiate();

  AutoRequired<FilterA> filterA;
  AutoRequired<AutoPacketFactory> factory;

  {
    // Obtain a new packet and mark an unsatisfiable decoration:
    auto packet = factory->NewPacket();
    packet->Unsatisfiable<Decoration<0>>();
    EXPECT_ANY_THROW(packet->Decorate(Decoration<0>())) << "Decoration succeeded on a decoration marked unsatisfiable";
  }

  {
    // Obtain a new packet and try to make a satisfied decoration unsatisfiable.
    auto packet = factory->NewPacket();
    packet->Decorate(Decoration<0>());
    EXPECT_ANY_THROW(packet->Unsatisfiable<Decoration<0>>()) << "Succeeded in marking an already-existing decoration as unsatisfiable";
  }
}

TEST_F(AutoFilterTest, VerifyReflexiveReciept) {
  AutoRequired<FilterA> filterA;
  AutoRequired<FilterC> filterC;
  AutoRequired<FilterD> filterD;
  AutoRequired<AutoPacketFactory> factory;

  AutoCurrentContext()->Initiate();

  // Obtain a packet first:
  auto packet = factory->NewPacket();

  // The mere act of obtaining a packet should have triggered filterD to be fired:
  EXPECT_TRUE(filterD->m_called) << "Trivial filter was not called as expected";

  // Decorate--should satisfy filterC
  packet->Decorate(Decoration<0>());
  EXPECT_TRUE(filterC->m_called) << "FilterC should have been satisfied with one decoration";

  // FilterC should have also satisfied filterA:
  EXPECT_TRUE(filterA->m_called) << "FilterA should have been satisfied by FilterC";
}

TEST_F(AutoFilterTest, VerifyReferenceBasedInput) {
  std::shared_ptr<AutoPacket> packet;

  {
    AutoCreateContext sub;
    CurrentContextPusher pshr(sub);
    sub->Initiate();

    AutoRequired<AutoPacketFactory> factory;
    AutoRequired<FilterGen<Decoration<0>, Decoration<1>&>> makesDec1;

    // Create a packet and put decoration 0 on it:
    packet = factory->NewPacket();

    // No early call
    ASSERT_FALSE(makesDec1->m_called) << "Single-input autofilter was invoked prematurely";

    // Now we decorate, after ensuring an early call did not happen
    packet->Decorate(Decoration<0>());

    // Verify that our filter got called when its sole input was satisfied
    ASSERT_TRUE(makesDec1->m_called) << "Single-input autofilter was not called as expected";

    // Now make sure that the packet has the expected decoration:
    ASSERT_TRUE(packet->Has<Decoration<1>>());
    sub->SignalShutdown(false);
  }
}<commit_msg>Adding unit test to guard against leaks caused by deferred AutoFilter recipients in subcontexts<commit_after>#include "stdafx.h"
#include "AutoFilterTest.h"
#include "AutoPacket.h"
#include "AutoPacketFactory.h"
#include "TestFixtures/Decoration.h"

TEST_F(AutoFilterTest, VerifyDescendentAwareness) {
  AutoCurrentContext()->Initiate();

  // Create a packet while the factory has no subscribers:
  AutoRequired<AutoPacketFactory> parentFactory;
  auto packet1 = parentFactory->NewPacket();

  // Verify subscription-free status:
  EXPECT_FALSE(packet1->HasSubscribers<Decoration<0>>()) << "Subscription exists where one should not have existed";

  std::shared_ptr<AutoPacket> packet2;
  std::weak_ptr<AutoPacket> packet3;
  std::weak_ptr<FilterA> filterChecker;

  // Create a subcontext
  {
    AutoCreateContext subContext;
    {
      CurrentContextPusher pusher(subContext);

      //add a filter in the subcontext
      AutoRequired<FilterA> subFilter;
      filterChecker = subFilter;
    }

    //Create a packet where a subscriber exists only in a subcontext
    packet2 = parentFactory->NewPacket();
    auto strongPacket3 = parentFactory->NewPacket();
    packet3 = strongPacket3;
    EXPECT_TRUE(packet2->HasSubscribers<Decoration<0>>()) << "Packet lacked expected subscription from subcontext";
    EXPECT_TRUE(packet3.lock()->HasSubscribers<Decoration<0>>()) << "Packet lacked expected subscription from subcontext";
  }
  EXPECT_TRUE(packet3.expired()) << "Packet was not destroyed when it's subscribers were removed";
  EXPECT_FALSE(filterChecker.expired()) << "Packet keeping subcontext member alive";

  // Create a packet after the subcontext has been destroyed
  auto packet4 = parentFactory->NewPacket();
  EXPECT_FALSE(packet4->HasSubscribers<Decoration<0>>()) << "Subscription exists where one should not have existed";

  // Verify the first packet still does not have subscriptions:
  EXPECT_FALSE(packet1->HasSubscribers<Decoration<0>>()) << "Subscription was incorrectly, retroactively added to a packet";

  packet2->Decorate(Decoration<0>());

  // Verify the second one will no longe have subscriptions  -
  // normally removing a subscriber would mean the packet still has the subscriber, but
  // in this case, the subscriber was actually destroyed so the packet has lost a subscriber.
  EXPECT_TRUE(packet2->HasSubscribers<Decoration<0>>()) << "Packet lacked an expected subscription";

  // Verify the third one does not:
  EXPECT_FALSE(packet4->HasSubscribers<Decoration<0>>()) << "Subscription was incorrectly, retroactively added to a packet";

  packet2.reset();
  EXPECT_TRUE(filterChecker.expired()) << "Subscriber didn't expire after packet was reset.";
}

TEST_F(AutoFilterTest, VerifySimpleFilter) {
  AutoCurrentContext()->Initiate();

  AutoRequired<AutoPacketFactory> factory;
  AutoRequired<FilterA> filterA;

  // Verify that the subscriber has been properly detected:
  bool bFound = false;
  for(const auto& cur : factory->GetSubscriberVector())
    if(cur.GetAutoFilter() == filterA) {
      bFound = true;
      break;
    }
  ASSERT_TRUE(bFound) << "Failed to find an added subscriber ";

  // Obtain a packet from the factory:
  auto packet = factory->NewPacket();

  // Decorate with one instance:
  packet->Decorate(Decoration<0>());

  // Verify that no hit takes place with inadequate decoration:
  EXPECT_FALSE(filterA->m_called) << "Filter called prematurely with insufficient decoration";

  // Now decorate with the other requirement of the filter:
  packet->Decorate(Decoration<1>());

  // A hit should have taken place at this point:
  EXPECT_TRUE(filterA->m_called) << "Filter was not called even though it was fully satisfied";
}

TEST_F(AutoFilterTest, VerifyNoMultiDecorate) {
  AutoCurrentContext()->Initiate();

  AutoRequired<FilterA> filterA;
  AutoRequired<AutoPacketFactory> factory;

  // Obtain a packet and attempt redundant introduction:
  auto packet = factory->NewPacket();
  packet->Decorate(Decoration<0>());
  EXPECT_ANY_THROW(packet->Decorate(Decoration<0>())) << "Redundant decoration did not throw an exception as expected";

  // Verify that a call has not yet been made
  EXPECT_FALSE(filterA->m_called) << "A call made on an idempotent packet decoration";

  // Now finish saturating the filter and ensure we get a call:
  packet->Decorate(Decoration<1>());
  EXPECT_TRUE(filterA->m_called) << "Filter was not called after being fully satisfied";
}

TEST_F(AutoFilterTest, VerifyInterThreadDecoration) {
  AutoRequired<FilterB> filterB;
  AutoRequired<AutoPacketFactory> factory;
  AutoCurrentContext ctxt;

  // Kick off all threads:
  ctxt->Initiate();

  // Obtain a packet for processing and decorate it:
  auto packet = factory->NewPacket();
  packet->Decorate(Decoration<0>());
  packet->Decorate(Decoration<1>());

  // Verify that the recipient has NOT yet received the message:
  EXPECT_FALSE(filterB->m_called) << "A call was made to a thread which should not have been able to process it";

  // Wake up the barrier and post a quit message:
  filterB->m_barr.wait();
  *filterB += [&filterB] { filterB->Stop(); };
  filterB->Wait();

  // Verify that the filter method has been called
  EXPECT_TRUE(filterB->m_called) << "A deferred filter method was not called as expected";
}

TEST_F(AutoFilterTest, VerifyTeardownArrangement) {
  AutoCurrentContext()->Initiate();
  AutoRequired<AutoPacketFactory> factory;

  std::weak_ptr<FilterA> filterAWeak;

  {
    std::shared_ptr<AutoPacket> packet;
    {
      // Create the filter and subscribe it
      std::shared_ptr<FilterA> filterA(new FilterA);
      filterAWeak = filterA;
      factory->AddSubscriber(filterA);

      // Create the packet--this should lock in references to all subscribers:
      packet = factory->NewPacket();
    }

    // Verify that the subscription has not expired:
    ASSERT_FALSE(filterAWeak.expired()) << "A subscriber while it was still registered";

    {
      std::shared_ptr<FilterA> filterA = filterAWeak.lock();

      // Unsubscribe the filter:
      factory->RemoveSubscriber(filterA);
    }

    // Verify that unsubscription STILL does not result in expiration:
    ASSERT_FALSE(filterAWeak.expired()) << "A subscriber expired before all packets on that subscriber were satisfied";

    //Create a new packet after having removed the only filter on it.
    auto packet2 = factory->NewPacket();
    ASSERT_FALSE(packet2->HasSubscribers<Decoration<0>>()) << "A packet had subscriptions after the only subscriber was removed.";

    // Satisfy the packet:
    packet->Decorate(Decoration<0>());
    packet->Decorate(Decoration<1>());

    auto packet3 = factory->NewPacket();
    ASSERT_FALSE(packet3->HasSubscribers<Decoration<0>>()) << "A packet had subscriptions after the only subscriber was removed.";
  }

  // Filter should be expired now:
  ASSERT_TRUE(filterAWeak.expired()) << "Subscriber was still left outstanding even though all references should be gone";
}

TEST_F(AutoFilterTest, VerifyCheckout) {
  AutoCurrentContext()->Initiate();
  AutoRequired<FilterA> filterA;
  AutoRequired<AutoPacketFactory> factory;

  // Obtain a packet for use with deferred decoration:
  auto packet = factory->NewPacket();

  {
    // Verify that an unsubscribed decoration returns a correct checkout:
    auto unused = packet->Checkout<Decoration<4>>();
    EXPECT_FALSE(unused) << "Checkout incorrectly generated for unsubscribed decoration";
  }

  // Satisfy the other decoration:
  packet->Decorate(Decoration<1>());

  {
    AutoCheckout<Decoration<0>> exterior;

    {
      AutoCheckout<Decoration<0>> checkout = packet->Checkout<Decoration<0>>();

      // Verify we can move the original type:
      AutoCheckout<Decoration<0>> checkoutMoved(std::move(checkout));

      // Verify no hits yet:
      EXPECT_FALSE(filterA->m_called) << "Filter called as a consequence of a checkout move operation";

      // Move the checkout a second time:
      exterior = std::move(checkoutMoved);
    }

    // Still no hits
    EXPECT_FALSE(filterA->m_called) << "Filter called before a decoration checkout expired";

    // Mark ready so we get committed:
    exterior.Ready();
  }

  // Verify a hit took place now
  EXPECT_TRUE(filterA->m_called) << "Filter was not called after all decorations were installed";
}

TEST_F(AutoFilterTest, RollbackCorrectness) {
  AutoCurrentContext()->Initiate();
  AutoRequired<FilterA> filterA;
  AutoRequired<AutoPacketFactory> factory;

  // Obtain a packet for use with deferred decoration:
  auto packet = factory->NewPacket();
  packet->Decorate(Decoration<1>());

  // Request and immediately allow the destruction of a checkout:
  packet->Checkout<Decoration<0>>();

  // Verify no hit took place--the checkout should have been cancelled:
  EXPECT_FALSE(filterA->m_called) << "Filter was called even though one decoration shouldn't have been available";

  // We should not be able to obtain another checkout of this decoration on this packet:
  EXPECT_ANY_THROW(packet->Checkout<Decoration<0>>()) << "An attempt to check out a decoration a second time should have failed";

  // We shouldn't be able to manually decorate, either:
  EXPECT_ANY_THROW(packet->Decorate(Decoration<0>())) << "An attempt to manually add a previously failed decoration succeeded where it should not have";
}

TEST_F(AutoFilterTest, VerifyAntiDecorate) {
  AutoCurrentContext()->Initiate();

  AutoRequired<FilterA> filterA;
  AutoRequired<AutoPacketFactory> factory;

  {
    // Obtain a new packet and mark an unsatisfiable decoration:
    auto packet = factory->NewPacket();
    packet->Unsatisfiable<Decoration<0>>();
    EXPECT_ANY_THROW(packet->Decorate(Decoration<0>())) << "Decoration succeeded on a decoration marked unsatisfiable";
  }

  {
    // Obtain a new packet and try to make a satisfied decoration unsatisfiable.
    auto packet = factory->NewPacket();
    packet->Decorate(Decoration<0>());
    EXPECT_ANY_THROW(packet->Unsatisfiable<Decoration<0>>()) << "Succeeded in marking an already-existing decoration as unsatisfiable";
  }
}

TEST_F(AutoFilterTest, VerifyReflexiveReciept) {
  AutoRequired<FilterA> filterA;
  AutoRequired<FilterC> filterC;
  AutoRequired<FilterD> filterD;
  AutoRequired<AutoPacketFactory> factory;

  AutoCurrentContext()->Initiate();

  // Obtain a packet first:
  auto packet = factory->NewPacket();

  // The mere act of obtaining a packet should have triggered filterD to be fired:
  EXPECT_TRUE(filterD->m_called) << "Trivial filter was not called as expected";

  // Decorate--should satisfy filterC
  packet->Decorate(Decoration<0>());
  EXPECT_TRUE(filterC->m_called) << "FilterC should have been satisfied with one decoration";

  // FilterC should have also satisfied filterA:
  EXPECT_TRUE(filterA->m_called) << "FilterA should have been satisfied by FilterC";
}

TEST_F(AutoFilterTest, VerifyReferenceBasedInput) {
  std::shared_ptr<AutoPacket> packet;

  {
    AutoCreateContext sub;
    CurrentContextPusher pshr(sub);
    sub->Initiate();

    AutoRequired<AutoPacketFactory> factory;
    AutoRequired<FilterGen<Decoration<0>, Decoration<1>&>> makesDec1;

    // Create a packet and put decoration 0 on it:
    packet = factory->NewPacket();

    // No early call
    ASSERT_FALSE(makesDec1->m_called) << "Single-input autofilter was invoked prematurely";

    // Now we decorate, after ensuring an early call did not happen
    packet->Decorate(Decoration<0>());

    // Verify that our filter got called when its sole input was satisfied
    ASSERT_TRUE(makesDec1->m_called) << "Single-input autofilter was not called as expected";

    // Now make sure that the packet has the expected decoration:
    ASSERT_TRUE(packet->Has<Decoration<1>>());
    sub->SignalShutdown(false);
  }
}

class DeferredAutoFilter:
  public CoreThread
{
public:
  DeferredAutoFilter(void) :
    nReceived(0)
  {}

  Deferred AutoFilter(const Decoration<0>& dec) {
    nReceived++;
    return Deferred(this);
  }

  size_t nReceived;
};

TEST_F(AutoFilterTest, DeferredRecieptInSubContext) {
  AutoCurrentContext()->Initiate();

  static const size_t nPackets = 5;
  AutoRequired<AutoPacketFactory> factory;

  std::vector<std::weak_ptr<AutoPacket>> allPackets;

  // Issue a packet before the subcontext is created, hold it for awhile:
  auto preissued = factory->NewPacket();
  allPackets.push_back(preissued);

  {
    // Create subcontext
    AutoCreateContext ctxt;
    ctxt->Initiate();
    CurrentContextPusher pshr(ctxt);
    AutoRequired<DeferredAutoFilter> daf;

    // Issue a few packets, have them get picked up by the subcontext:
    for(size_t i = nPackets; i--;)
    {
      auto packet = factory->NewPacket();
      packet->Decorate(Decoration<0>());
      allPackets.push_back(packet);
    }

    // Terminate the subcontext, release references
    ctxt->SignalShutdown(true);
    ctxt->Wait();

    // Verify that the filter got all of the packets that it should have gotten:
    ASSERT_EQ(nPackets, daf->nReceived) << "AutoFilter did not get all packets that were pended to it";
  }

  // Release the preissued packet:
  preissued.reset();

  // Now verify that all of our packets are expired:
  for(auto cur : allPackets)
    ASSERT_TRUE(cur.expired()) << "Packet did not expire after all recipients went out of scope";
}<|endoftext|>


<commit_before><commit_msg>Implement "indent_size = tab" support.<commit_after><|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <QtGui>

#include "scribblearea.h"

//! [0]
ScribbleArea::ScribbleArea(QWidget *parent)
    : QWidget(parent)
{
    setAttribute(Qt::WA_StaticContents);
    modified = false;
    scribbling = false;
    myPenWidth = 1;
    myPenColor = Qt::blue;
}
//! [0]

//! [1]
bool ScribbleArea::openImage(const QString &fileName)
//! [1] //! [2]
{
    QImage loadedImage;
    if (!loadedImage.load(fileName))
        return false;

    QSize newSize = loadedImage.size().expandedTo(size());
    resizeImage(&loadedImage, newSize);
    image = loadedImage;
    modified = false;
    update();
    return true;
}
//! [2]

//! [3]
bool ScribbleArea::saveImage(const QString &fileName, const char *fileFormat)
//! [3] //! [4]
{
    QImage visibleImage = image;
    resizeImage(&visibleImage, size());

    if (visibleImage.save(fileName, fileFormat)) {
        modified = false;
        return true;
    } else {
        return false;
    }
}
//! [4]

//! [5]
void ScribbleArea::setPenColor(const QColor &newColor)
//! [5] //! [6]
{
    myPenColor = newColor;
}
//! [6]

//! [7]
void ScribbleArea::setPenWidth(int newWidth)
//! [7] //! [8]
{
    myPenWidth = newWidth;
}
//! [8]

//! [9]
void ScribbleArea::clearImage()
//! [9] //! [10]
{
    image.fill(qRgb(255, 255, 255));
    modified = true;
    update();
}
//! [10]

//! [11]
void ScribbleArea::mousePressEvent(QMouseEvent *event)
//! [11] //! [12]
{
    if (event->button() == Qt::LeftButton) {
        lastPoint = event->pos();
        scribbling = true;
    }
}

void ScribbleArea::mouseMoveEvent(QMouseEvent *event)
{
    if ((event->buttons() & Qt::LeftButton) && scribbling)
        drawLineTo(event->pos());
}

void ScribbleArea::mouseReleaseEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton && scribbling) {
        drawLineTo(event->pos());
        scribbling = false;
    }
}

//! [12] //! [13]
void ScribbleArea::paintEvent(QPaintEvent * /* event */)
//! [13] //! [14]
{
    QPainter painter(this);
    painter.drawImage(QPoint(0, 0), image);
}
//! [14]

//! [15]
void ScribbleArea::resizeEvent(QResizeEvent *event)
//! [15] //! [16]
{
    if (width() > image.width() || height() > image.height()) {
        int newWidth = qMax(width() + 128, image.width());
        int newHeight = qMax(height() + 128, image.height());
        resizeImage(&image, QSize(newWidth, newHeight));
        update();
    }
    QWidget::resizeEvent(event);
}
//! [16]

//! [17]
void ScribbleArea::drawLineTo(const QPoint &endPoint)
//! [17] //! [18]
{
    QPainter painter(&image);
    painter.setPen(QPen(myPenColor, myPenWidth, Qt::SolidLine, Qt::RoundCap,
                        Qt::RoundJoin));
    painter.drawLine(lastPoint, endPoint);
    modified = true;

    int rad = (myPenWidth / 2) + 2;
    update(QRect(lastPoint, endPoint).normalized()
                                     .adjusted(-rad, -rad, +rad, +rad));
    lastPoint = endPoint;
}
//! [18]

//! [19]
void ScribbleArea::resizeImage(QImage *image, const QSize &newSize)
//! [19] //! [20]
{
    if (image->size() == newSize)
        return;

    QImage newImage(newSize, QImage::Format_RGB32);
    newImage.fill(qRgb(255, 255, 255));
    QPainter painter(&newImage);
    painter.drawImage(QPoint(0, 0), *image);
    *image = newImage;
}
//! [20]

//! [21]
void ScribbleArea::print()
{
#ifndef QT_NO_PRINTER
    QPrinter printer(QPrinter::HighResolution);

    QPrintDialog *printDialog = new QPrintDialog(&printer, this);
//! [21] //! [22]
    if (printDialog->exec() == QDialog::Accepted) {
        QPainter painter(&printer);
        QRect rect = painter.viewport();
        QSize size = image.size();
        size.scale(rect.size(), Qt::KeepAspectRatio);
        painter.setViewport(rect.x(), rect.y(), size.width(), size.height());
        painter.setWindow(image.rect());
        painter.drawImage(0, 0, image);
    }
#endif // QT_NO_PRINTER
}
//! [22]
<commit_msg>Fixes performance problem with scribble avoiding to redraw whole screen on every MotionNotify event.<commit_after>/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <QtGui>

#include "scribblearea.h"

//! [0]
ScribbleArea::ScribbleArea(QWidget *parent)
    : QWidget(parent)
{
    setAttribute(Qt::WA_StaticContents);
    modified = false;
    scribbling = false;
    myPenWidth = 1;
    myPenColor = Qt::blue;
}
//! [0]

//! [1]
bool ScribbleArea::openImage(const QString &fileName)
//! [1] //! [2]
{
    QImage loadedImage;
    if (!loadedImage.load(fileName))
        return false;

    QSize newSize = loadedImage.size().expandedTo(size());
    resizeImage(&loadedImage, newSize);
    image = loadedImage;
    modified = false;
    update();
    return true;
}
//! [2]

//! [3]
bool ScribbleArea::saveImage(const QString &fileName, const char *fileFormat)
//! [3] //! [4]
{
    QImage visibleImage = image;
    resizeImage(&visibleImage, size());

    if (visibleImage.save(fileName, fileFormat)) {
        modified = false;
        return true;
    } else {
        return false;
    }
}
//! [4]

//! [5]
void ScribbleArea::setPenColor(const QColor &newColor)
//! [5] //! [6]
{
    myPenColor = newColor;
}
//! [6]

//! [7]
void ScribbleArea::setPenWidth(int newWidth)
//! [7] //! [8]
{
    myPenWidth = newWidth;
}
//! [8]

//! [9]
void ScribbleArea::clearImage()
//! [9] //! [10]
{
    image.fill(qRgb(255, 255, 255));
    modified = true;
    update();
}
//! [10]

//! [11]
void ScribbleArea::mousePressEvent(QMouseEvent *event)
//! [11] //! [12]
{
    if (event->button() == Qt::LeftButton) {
        lastPoint = event->pos();
        scribbling = true;
    }
}

void ScribbleArea::mouseMoveEvent(QMouseEvent *event)
{
    if ((event->buttons() & Qt::LeftButton) && scribbling)
        drawLineTo(event->pos());
}

void ScribbleArea::mouseReleaseEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton && scribbling) {
        drawLineTo(event->pos());
        scribbling = false;
    }
}

//! [12] //! [13]
void ScribbleArea::paintEvent(QPaintEvent *event)
//! [13] //! [14]
{
    QPainter painter(this);
    QRect dirtyRect = event->rect();
    painter.drawImage(dirtyRect, image, dirtyRect);
}
//! [14]

//! [15]
void ScribbleArea::resizeEvent(QResizeEvent *event)
//! [15] //! [16]
{
    if (width() > image.width() || height() > image.height()) {
        int newWidth = qMax(width() + 128, image.width());
        int newHeight = qMax(height() + 128, image.height());
        resizeImage(&image, QSize(newWidth, newHeight));
        update();
    }
    QWidget::resizeEvent(event);
}
//! [16]

//! [17]
void ScribbleArea::drawLineTo(const QPoint &endPoint)
//! [17] //! [18]
{
    QPainter painter(&image);
    painter.setPen(QPen(myPenColor, myPenWidth, Qt::SolidLine, Qt::RoundCap,
                        Qt::RoundJoin));
    painter.drawLine(lastPoint, endPoint);
    modified = true;

    int rad = (myPenWidth / 2) + 2;
    update(QRect(lastPoint, endPoint).normalized()
                                     .adjusted(-rad, -rad, +rad, +rad));
    lastPoint = endPoint;
}
//! [18]

//! [19]
void ScribbleArea::resizeImage(QImage *image, const QSize &newSize)
//! [19] //! [20]
{
    if (image->size() == newSize)
        return;

    QImage newImage(newSize, QImage::Format_RGB32);
    newImage.fill(qRgb(255, 255, 255));
    QPainter painter(&newImage);
    painter.drawImage(QPoint(0, 0), *image);
    *image = newImage;
}
//! [20]

//! [21]
void ScribbleArea::print()
{
#ifndef QT_NO_PRINTER
    QPrinter printer(QPrinter::HighResolution);

    QPrintDialog *printDialog = new QPrintDialog(&printer, this);
//! [21] //! [22]
    if (printDialog->exec() == QDialog::Accepted) {
        QPainter painter(&printer);
        QRect rect = painter.viewport();
        QSize size = image.size();
        size.scale(rect.size(), Qt::KeepAspectRatio);
        painter.setViewport(rect.x(), rect.y(), size.width(), size.height());
        painter.setWindow(image.rect());
        painter.drawImage(0, 0, image);
    }
#endif // QT_NO_PRINTER
}
//! [22]
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: abpfinalpage.cxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: obo $ $Date: 2006-10-12 10:37:12 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

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

#ifndef EXTENSIONS_ABP_ABPFINALPAGE_HXX
#include "abpfinalpage.hxx"
#endif
#ifndef EXTENSIONS_ABP_ADDRESSSETTINGS_HXX
#include "addresssettings.hxx"
#endif
#ifndef EXTENSIONS_ABSPILOT_HXX
#include "abspilot.hxx"
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef _URLOBJ_HXX
#include <tools/urlobj.hxx>
#endif
#ifndef _UNOTOOLS_UCBHELPER_HXX
#include <unotools/ucbhelper.hxx>
#endif
#ifndef _FILEDLGHELPER_HXX
#include <sfx2/filedlghelper.hxx>
#endif
#ifndef INCLUDED_SVTOOLS_PATHOPTIONS_HXX
#include <svtools/pathoptions.hxx>
#endif
#ifndef SVTOOLS_FILENOTATION_HXX_
#include <svtools/filenotation.hxx>
#endif
#ifndef _SFX_DOCFILT_HACK_HXX
#include <sfx2/docfilt.hxx>
#endif
#ifndef _SV_MSGBOX_HXX
#include <vcl/msgbox.hxx>
#endif
#include "com/sun/star/ui/dialogs/TemplateDescription.hpp"

//.........................................................................
namespace abp
{
//.........................................................................
    using namespace ::svt;
    using namespace ::utl;

    const SfxFilter* lcl_getBaseFilter()
    {
        static const String s_sDatabaseType = String::CreateFromAscii("StarOffice XML (Base)");
        const SfxFilter* pFilter = SfxFilter::GetFilterByName( s_sDatabaseType);
        OSL_ENSURE(pFilter,"Filter: StarOffice XML (Base) could not be found!");
        return pFilter;
    }
    //=====================================================================
    //= FinalPage
    //=====================================================================
    //---------------------------------------------------------------------
    FinalPage::FinalPage( OAddessBookSourcePilot* _pParent )
        :AddressBookSourcePage(_pParent, ModuleRes(RID_PAGE_FINAL))
        ,m_aExplanation         ( this, ResId( FT_FINISH_EXPL ) )
        ,m_aLocationLabel       ( this, ResId( FT_LOCATION ) )
        ,m_aLocation            ( this, ResId( CBB_LOCATION ) )
        ,m_aBrowse              ( this, ResId( PB_BROWSE ) )
        ,m_aRegisterName        ( this, ResId( CB_REGISTER_DS ) )
        ,m_aNameLabel           ( this, ResId( FT_NAME_EXPL ) )
        ,m_aName                ( this, ResId( ET_DATASOURCENAME ) )
        ,m_aDuplicateNameError  ( this, ResId( FT_DUPLICATENAME ) )
        ,m_bCheckFileName       (sal_True)
    {
        FreeResource();

        m_aName.SetModifyHdl( LINK(this, FinalPage, OnNameModified) );
        m_aLocation.SetModifyHdl( LINK(this, FinalPage, OnNameModified) );
        m_aBrowse.SetClickHdl( LINK( this, FinalPage, OnBrowse ) );
        m_aRegisterName.SetClickHdl( LINK( this, FinalPage, OnRegister ) );
        m_aRegisterName.Check(TRUE);

        const SfxFilter* pFilter = lcl_getBaseFilter();
        if ( pFilter )
        {
            m_aLocation.SetFilter(pFilter->GetDefaultExtension());
        }
    }

    //---------------------------------------------------------------------
    sal_Bool FinalPage::isValidName() const
    {
        ::rtl::OUString sCurrentName(m_aName.GetText());

        if (0 == sCurrentName.getLength())
            // the name must not be empty
            return sal_False;

        if ( m_aInvalidDataSourceNames.find( sCurrentName ) != m_aInvalidDataSourceNames.end() )
            // there already is a data source with this name
            return sal_False;

        return sal_True;
    }

    //---------------------------------------------------------------------
    void FinalPage::setFields()
    {
        AddressSettings& rSettings = getSettings();

        INetURLObject aURL( rSettings.sDataSourceName );
        if( aURL.GetProtocol() == INET_PROT_NOT_VALID )
        {
            String sPath = SvtPathOptions().GetWorkPath();
            sPath += '/';
            sPath += String(rSettings.sDataSourceName);

            const SfxFilter* pFilter = lcl_getBaseFilter();
            if ( pFilter )
            {
                String sExt = pFilter->GetDefaultExtension();
                sPath += sExt.GetToken(1,'*');
            }

            aURL.SetURL(sPath);
        }
        OSL_ENSURE( aURL.GetProtocol() != INET_PROT_NOT_VALID ,"No valid file name!");
        rSettings.sDataSourceName = aURL.GetMainURL( INetURLObject::NO_DECODE );
        OFileNotation aFileNotation( rSettings.sDataSourceName );
        m_aLocation.SetText(aFileNotation.get(OFileNotation::N_SYSTEM));
        String sName = aURL.getName( );
        xub_StrLen nPos = sName.Search(String(aURL.GetExtension()));
        if ( nPos != STRING_NOTFOUND )
        {
            sName.Erase(nPos-1,4);
        }
        m_aName.SetText(sName);

        OnRegister(&m_aRegisterName);
    }

    //---------------------------------------------------------------------
    void FinalPage::initializePage()
    {
        AddressBookSourcePage::initializePage();

        setFields();
    }

    //---------------------------------------------------------------------
    sal_Bool FinalPage::commitPage(COMMIT_REASON _eReason)
    {
        if (!AddressBookSourcePage::commitPage(_eReason))
            return sal_False;

        OFileNotation aFileNotation( m_aLocation.GetText() );
        ::rtl::OUString sURL = aFileNotation.get(OFileNotation::N_URL);
        // check if the name exists
        if ( m_bCheckFileName )
        {
            if ( ::utl::UCBContentHelper::Exists( sURL ) )
            {
                QueryBox aBox( this, WB_YES_NO, ModuleRes( RID_STR_ALREADYEXISTOVERWRITE ) );
                if ( aBox.Execute() != RET_YES )
                    return sal_False;
            }
        }

        AddressSettings& rSettings = getSettings();
        rSettings.sDataSourceName = sURL;
        rSettings.bRegisterDataSource = m_aRegisterName.IsChecked();
        if ( rSettings.bRegisterDataSource )
            rSettings.sRegisteredDataSourceName = m_aName.GetText();

        return sal_True;
    }

    //---------------------------------------------------------------------
    void FinalPage::ActivatePage()
    {
        AddressBookSourcePage::ActivatePage();

        // get the names of all data sources
        ODataSourceContext aContext( getORB() );
        aContext.getDataSourceNames( m_aInvalidDataSourceNames );

        // in real, the data source which this dialog should create, is already part of the context
        // as it's name is - of course - a valid name, we have to remove it from the bag
//      DBG_ASSERT( getDialog()->getDataSource().getName() == getSettings().sDataSourceName,
//          "FinalPage::ActivatePage: inconsistent names!" );

        // give the name edit the focus
        m_aLocation.GrabFocus();

        // default the finish button
        getDialog()->defaultButton( WZB_FINISH );
    }

    //---------------------------------------------------------------------
    void FinalPage::DeactivatePage()
    {
        AddressBookSourcePage::DeactivatePage();

        // default the "next" button, again
        getDialog()->defaultButton( WZB_NEXT );
        // disable the finish button
        getDialog()->enableButtons( WZB_FINISH, sal_False );
    }

    //---------------------------------------------------------------------
    sal_Bool FinalPage::determineNextButtonState()
    {
        return sal_False;
    }

    //---------------------------------------------------------------------
    void FinalPage::implCheckName()
    {
        sal_Bool bValidName = isValidName();
        sal_Bool bEmptyName = 0 == m_aName.GetText().Len();
        sal_Bool bEmptyLocation = 0 == m_aLocation.GetText().Len();

        // enable or disable the finish button
        getDialog()->enableButtons( WZB_FINISH, !bEmptyLocation && (!m_aRegisterName.IsChecked() || bValidName) );

        // show the error message for an invalid name
        m_aDuplicateNameError.Show( !bValidName && !bEmptyName );
    }

    //---------------------------------------------------------------------
    IMPL_LINK( FinalPage, OnNameModified, Edit*, _pEdit)
    {
        if ( _pEdit == &m_aLocation )
            m_bCheckFileName = sal_True;

        implCheckName();
        return 0L;
    }
    // -----------------------------------------------------------------------------
    IMPL_LINK( FinalPage, OnBrowse, PushButton*, EMPTYARG )
    {
        OFileNotation aOldFile( m_aLocation.GetText() );
        WinBits nBits(WB_STDMODAL|WB_SAVEAS);
        ::sfx2::FileDialogHelper aFileDlg( com::sun::star::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION,static_cast<sal_uInt32>(nBits) ,this);
        aFileDlg.SetDisplayDirectory( aOldFile.get(OFileNotation::N_URL) );

        static const String s_sDatabaseType = String::CreateFromAscii("StarOffice XML (Base)");
        const SfxFilter* pFilter = SfxFilter::GetFilterByName( s_sDatabaseType);
        OSL_ENSURE(pFilter,"Filter: StarOffice XML (Base) could not be found!");
        if ( pFilter )
        {
            aFileDlg.AddFilter(pFilter->GetFilterName(),pFilter->GetDefaultExtension());
            aFileDlg.SetCurrentFilter(pFilter->GetFilterName());
        }

        if ( aFileDlg.Execute() == ERRCODE_NONE )
        {
            INetURLObject aURL( aFileDlg.GetPath() );
            if( aURL.GetProtocol() != INET_PROT_NOT_VALID )
            {
                OFileNotation aFileNotation( aURL.GetMainURL( INetURLObject::NO_DECODE ) );
                m_aLocation.SetText(aFileNotation.get(OFileNotation::N_SYSTEM));
                implCheckName();
                m_bCheckFileName = sal_False;
            }
        }

        return 0L;
    }
    // -----------------------------------------------------------------------------
    IMPL_LINK( FinalPage, OnRegister, CheckBox*, EMPTYARG )
    {
        BOOL bEnable = m_aRegisterName.IsChecked();
        m_aNameLabel.Enable(bEnable);
        m_aName.Enable(bEnable);
        implCheckName();
        return 0L;
    }
//.........................................................................
}   // namespace abp
//.........................................................................

<commit_msg>INTEGRATION: CWS residcleanup (1.8.98); FILE MERGED 2007/02/28 20:46:08 pl 1.8.98.1: #i74635# no more ResMgr fallback<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: abpfinalpage.cxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: rt $ $Date: 2007-04-26 08:04:13 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

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

#ifndef EXTENSIONS_ABP_ABPFINALPAGE_HXX
#include "abpfinalpage.hxx"
#endif
#ifndef EXTENSIONS_ABP_ADDRESSSETTINGS_HXX
#include "addresssettings.hxx"
#endif
#ifndef EXTENSIONS_ABSPILOT_HXX
#include "abspilot.hxx"
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef _URLOBJ_HXX
#include <tools/urlobj.hxx>
#endif
#ifndef _UNOTOOLS_UCBHELPER_HXX
#include <unotools/ucbhelper.hxx>
#endif
#ifndef _FILEDLGHELPER_HXX
#include <sfx2/filedlghelper.hxx>
#endif
#ifndef INCLUDED_SVTOOLS_PATHOPTIONS_HXX
#include <svtools/pathoptions.hxx>
#endif
#ifndef SVTOOLS_FILENOTATION_HXX_
#include <svtools/filenotation.hxx>
#endif
#ifndef _SFX_DOCFILT_HACK_HXX
#include <sfx2/docfilt.hxx>
#endif
#ifndef _SV_MSGBOX_HXX
#include <vcl/msgbox.hxx>
#endif
#include "com/sun/star/ui/dialogs/TemplateDescription.hpp"

//.........................................................................
namespace abp
{
//.........................................................................
    using namespace ::svt;
    using namespace ::utl;

    const SfxFilter* lcl_getBaseFilter()
    {
        static const String s_sDatabaseType = String::CreateFromAscii("StarOffice XML (Base)");
        const SfxFilter* pFilter = SfxFilter::GetFilterByName( s_sDatabaseType);
        OSL_ENSURE(pFilter,"Filter: StarOffice XML (Base) could not be found!");
        return pFilter;
    }
    //=====================================================================
    //= FinalPage
    //=====================================================================
    //---------------------------------------------------------------------
    FinalPage::FinalPage( OAddessBookSourcePilot* _pParent )
        :AddressBookSourcePage(_pParent, ModuleRes(RID_PAGE_FINAL))
        ,m_aExplanation         ( this, ModuleRes( FT_FINISH_EXPL ) )
        ,m_aLocationLabel       ( this, ModuleRes( FT_LOCATION ) )
        ,m_aLocation            ( this, ModuleRes( CBB_LOCATION ) )
        ,m_aBrowse              ( this, ModuleRes( PB_BROWSE ) )
        ,m_aRegisterName        ( this, ModuleRes( CB_REGISTER_DS ) )
        ,m_aNameLabel           ( this, ModuleRes( FT_NAME_EXPL ) )
        ,m_aName                ( this, ModuleRes( ET_DATASOURCENAME ) )
        ,m_aDuplicateNameError  ( this, ModuleRes( FT_DUPLICATENAME ) )
        ,m_bCheckFileName       (sal_True)
    {
        FreeResource();

        m_aName.SetModifyHdl( LINK(this, FinalPage, OnNameModified) );
        m_aLocation.SetModifyHdl( LINK(this, FinalPage, OnNameModified) );
        m_aBrowse.SetClickHdl( LINK( this, FinalPage, OnBrowse ) );
        m_aRegisterName.SetClickHdl( LINK( this, FinalPage, OnRegister ) );
        m_aRegisterName.Check(TRUE);

        const SfxFilter* pFilter = lcl_getBaseFilter();
        if ( pFilter )
        {
            m_aLocation.SetFilter(pFilter->GetDefaultExtension());
        }
    }

    //---------------------------------------------------------------------
    sal_Bool FinalPage::isValidName() const
    {
        ::rtl::OUString sCurrentName(m_aName.GetText());

        if (0 == sCurrentName.getLength())
            // the name must not be empty
            return sal_False;

        if ( m_aInvalidDataSourceNames.find( sCurrentName ) != m_aInvalidDataSourceNames.end() )
            // there already is a data source with this name
            return sal_False;

        return sal_True;
    }

    //---------------------------------------------------------------------
    void FinalPage::setFields()
    {
        AddressSettings& rSettings = getSettings();

        INetURLObject aURL( rSettings.sDataSourceName );
        if( aURL.GetProtocol() == INET_PROT_NOT_VALID )
        {
            String sPath = SvtPathOptions().GetWorkPath();
            sPath += '/';
            sPath += String(rSettings.sDataSourceName);

            const SfxFilter* pFilter = lcl_getBaseFilter();
            if ( pFilter )
            {
                String sExt = pFilter->GetDefaultExtension();
                sPath += sExt.GetToken(1,'*');
            }

            aURL.SetURL(sPath);
        }
        OSL_ENSURE( aURL.GetProtocol() != INET_PROT_NOT_VALID ,"No valid file name!");
        rSettings.sDataSourceName = aURL.GetMainURL( INetURLObject::NO_DECODE );
        OFileNotation aFileNotation( rSettings.sDataSourceName );
        m_aLocation.SetText(aFileNotation.get(OFileNotation::N_SYSTEM));
        String sName = aURL.getName( );
        xub_StrLen nPos = sName.Search(String(aURL.GetExtension()));
        if ( nPos != STRING_NOTFOUND )
        {
            sName.Erase(nPos-1,4);
        }
        m_aName.SetText(sName);

        OnRegister(&m_aRegisterName);
    }

    //---------------------------------------------------------------------
    void FinalPage::initializePage()
    {
        AddressBookSourcePage::initializePage();

        setFields();
    }

    //---------------------------------------------------------------------
    sal_Bool FinalPage::commitPage(COMMIT_REASON _eReason)
    {
        if (!AddressBookSourcePage::commitPage(_eReason))
            return sal_False;

        OFileNotation aFileNotation( m_aLocation.GetText() );
        ::rtl::OUString sURL = aFileNotation.get(OFileNotation::N_URL);
        // check if the name exists
        if ( m_bCheckFileName )
        {
            if ( ::utl::UCBContentHelper::Exists( sURL ) )
            {
                QueryBox aBox( this, WB_YES_NO, ModuleRes( RID_STR_ALREADYEXISTOVERWRITE ) );
                if ( aBox.Execute() != RET_YES )
                    return sal_False;
            }
        }

        AddressSettings& rSettings = getSettings();
        rSettings.sDataSourceName = sURL;
        rSettings.bRegisterDataSource = m_aRegisterName.IsChecked();
        if ( rSettings.bRegisterDataSource )
            rSettings.sRegisteredDataSourceName = m_aName.GetText();

        return sal_True;
    }

    //---------------------------------------------------------------------
    void FinalPage::ActivatePage()
    {
        AddressBookSourcePage::ActivatePage();

        // get the names of all data sources
        ODataSourceContext aContext( getORB() );
        aContext.getDataSourceNames( m_aInvalidDataSourceNames );

        // in real, the data source which this dialog should create, is already part of the context
        // as it's name is - of course - a valid name, we have to remove it from the bag
//      DBG_ASSERT( getDialog()->getDataSource().getName() == getSettings().sDataSourceName,
//          "FinalPage::ActivatePage: inconsistent names!" );

        // give the name edit the focus
        m_aLocation.GrabFocus();

        // default the finish button
        getDialog()->defaultButton( WZB_FINISH );
    }

    //---------------------------------------------------------------------
    void FinalPage::DeactivatePage()
    {
        AddressBookSourcePage::DeactivatePage();

        // default the "next" button, again
        getDialog()->defaultButton( WZB_NEXT );
        // disable the finish button
        getDialog()->enableButtons( WZB_FINISH, sal_False );
    }

    //---------------------------------------------------------------------
    sal_Bool FinalPage::determineNextButtonState()
    {
        return sal_False;
    }

    //---------------------------------------------------------------------
    void FinalPage::implCheckName()
    {
        sal_Bool bValidName = isValidName();
        sal_Bool bEmptyName = 0 == m_aName.GetText().Len();
        sal_Bool bEmptyLocation = 0 == m_aLocation.GetText().Len();

        // enable or disable the finish button
        getDialog()->enableButtons( WZB_FINISH, !bEmptyLocation && (!m_aRegisterName.IsChecked() || bValidName) );

        // show the error message for an invalid name
        m_aDuplicateNameError.Show( !bValidName && !bEmptyName );
    }

    //---------------------------------------------------------------------
    IMPL_LINK( FinalPage, OnNameModified, Edit*, _pEdit)
    {
        if ( _pEdit == &m_aLocation )
            m_bCheckFileName = sal_True;

        implCheckName();
        return 0L;
    }
    // -----------------------------------------------------------------------------
    IMPL_LINK( FinalPage, OnBrowse, PushButton*, EMPTYARG )
    {
        OFileNotation aOldFile( m_aLocation.GetText() );
        WinBits nBits(WB_STDMODAL|WB_SAVEAS);
        ::sfx2::FileDialogHelper aFileDlg( com::sun::star::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION,static_cast<sal_uInt32>(nBits) ,this);
        aFileDlg.SetDisplayDirectory( aOldFile.get(OFileNotation::N_URL) );

        static const String s_sDatabaseType = String::CreateFromAscii("StarOffice XML (Base)");
        const SfxFilter* pFilter = SfxFilter::GetFilterByName( s_sDatabaseType);
        OSL_ENSURE(pFilter,"Filter: StarOffice XML (Base) could not be found!");
        if ( pFilter )
        {
            aFileDlg.AddFilter(pFilter->GetFilterName(),pFilter->GetDefaultExtension());
            aFileDlg.SetCurrentFilter(pFilter->GetFilterName());
        }

        if ( aFileDlg.Execute() == ERRCODE_NONE )
        {
            INetURLObject aURL( aFileDlg.GetPath() );
            if( aURL.GetProtocol() != INET_PROT_NOT_VALID )
            {
                OFileNotation aFileNotation( aURL.GetMainURL( INetURLObject::NO_DECODE ) );
                m_aLocation.SetText(aFileNotation.get(OFileNotation::N_SYSTEM));
                implCheckName();
                m_bCheckFileName = sal_False;
            }
        }

        return 0L;
    }
    // -----------------------------------------------------------------------------
    IMPL_LINK( FinalPage, OnRegister, CheckBox*, EMPTYARG )
    {
        BOOL bEnable = m_aRegisterName.IsChecked();
        m_aNameLabel.Enable(bEnable);
        m_aName.Enable(bEnable);
        implCheckName();
        return 0L;
    }
//.........................................................................
}   // namespace abp
//.........................................................................

<|endoftext|>