<commit_before> /**
  * Copyright (C) 2014, Jaguar Land Rover
  *
  * Author: Jonatan Palsson <jonatan.palsson@pelagicore.com>
  *
  * This file is part of the GENIVI Media Manager Proof-of-Concept
  * For further information, see http://genivi.org/
  *
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */

#include <iostream>
#include <sstream>
#include "string.h"

#include "playerprovider.h"

static char* PLAYER_PATH = "/com/intel/dLeynaRenderer/server/0";

char *PlayerProvider::findFirstPlayer(MmError **e) {
    char *path = NULL;
    dleynaRendererOrgFreedesktopDBusPeer *peer = NULL;
    int slashPos = -1;
    for (int i = strlen(PLAYER_PATH); i > 0; i--) {
        if (PLAYER_PATH[i] == '/') {
            slashPos = i;
            break;
        }
    }

    path = g_strndup(PLAYER_PATH, slashPos);

    for (int i = 0; i < 50; i++) {
        char *newpath = g_strdup_printf("%s/%d", path, i);

        GError *error = NULL;
        GDBusProxy *proxy = NULL;
        GDBusConnection *conn = g_bus_get_sync (G_BUS_TYPE_SESSION,
                                                NULL,
                                                &error);

        if (error) {
            if (e)
                (*e)->message = "Unable to get connection to bus";
            return NULL;
        }

        proxy = g_dbus_proxy_new_sync (conn,
                                       G_DBUS_PROXY_FLAGS_NONE,
                                       NULL,
                                       "com.intel.dleyna-renderer",
                                       newpath,
                                       "org.freedesktop.DBus.Properties",
                                       NULL,
                                       &error);

        if (error) {
            if (e)
                (*e)->message = std::string("Unable to create proxy for ") + newpath;
            return NULL;
        }

        GVariant *ret = g_dbus_proxy_call_sync (proxy,
                                                "Get",
                                                g_variant_new("(ss)",
                                                              "org.mpris.MediaPlayer2",
                                                              "Identity"),
                                                G_DBUS_CALL_FLAGS_NONE,
                                                -1,
                                                NULL,
                                                &error);
        if (!error) {
            g_printerr ("Found player on %s\n", newpath);
            return newpath;
            break;
        } else {
            g_printerr ("No player found on %s\n", newpath);
        }
    }

    g_free (path);
    return NULL;
}

void PlayerProvider::openURI(std::string uri,
                             MmError **e)
{
    GError                           *error  = NULL;

    if (!PlayerProvider::connectMediaPlayer(PLAYER_PATH, &mp, e))
        return;
    dleyna_renderer_media_player2_player_call_open_uri_sync (mp,
                                                             uri.c_str(),
                                                             NULL,
                                                             &error);

    checkError (error, e);
}

void PlayerProvider::pause(MmError **e) {
    GError                           *error = NULL;

    if (!PlayerProvider::connectMediaPlayer(PLAYER_PATH, &mp, e))
        return;
    dleyna_renderer_media_player2_player_call_pause_sync (mp,
                                                             NULL,
                                                             &error);

    checkError (error, e);
}

void PlayerProvider::play(MmError **e) {
    GError                           *error = NULL;

    if (!PlayerProvider::connectMediaPlayer(PLAYER_PATH, &mp, e))
        return;
    dleyna_renderer_media_player2_player_call_play_sync (mp,
                                                         NULL,
                                                         &error);

    checkError (error, e);
}

void PlayerProvider::playPause(MmError **e) {
    GError                           *error = NULL;

    if (!PlayerProvider::connectMediaPlayer(PLAYER_PATH, &mp, e))
        return;
    dleyna_renderer_media_player2_player_call_play_pause_sync (mp,
                                                               NULL,
                                                               &error);

    checkError (error, e);
}

void PlayerProvider::openPlaylist (std::string playlistPath, MmError **e) {
    std::cout << "In function: " << __FUNCTION__ << std::endl;
    GError                           *error = NULL;
    GVariant *out = NULL;

    std::vector<std::string> filter;
    filter.push_back("*");

    int offset = 0;
    int count = 100;
    gchar **filterStrv = stdStrvToStrv(filter);

    if (!PlayerProvider::connectMediaContainer (playlistPath, &mc, e))
        return;

    dleyna_server_media_container2_call_list_items_sync (mc, offset, count,
                                                  filterStrv, &out, NULL,
                                                  &error);

    if (error) {
        std::cout << "Unable to open playlist: " << error->message << std::endl;
        return;
    }

    std::string containers;
    std::cout << "Setting play queue to: " << playlistPath << std::endl;

    json_decref (playqueue);
    playqueue = DLNADictToJSON (out);

    playQueuePosition = 0;
    changePlayQueuePosition (0, e);

    checkError (error, e);
}

bool PlayerProvider::connectMediaPlayer (const std::string path,
                                             dleynaRendererMediaPlayer2Player **mp,
                                             MmError **e) {
    GError *error = NULL;

    char *foundpath = findFirstPlayer(NULL);
    if (!foundpath) {
        g_printerr ("Unable to find any player");
        return false;
    }

    if (!g_variant_is_object_path (foundpath)) {
        std::string error = "Path is invalid";
        std::cout << error << std::endl;
        if (e)
            (*e)->message = error;
        return false;
    }

    *mp = dleyna_renderer_media_player2_player_proxy_new_for_bus_sync (
                                    G_BUS_TYPE_SESSION,
                                    G_DBUS_PROXY_FLAGS_NONE,
                                    "com.intel.dleyna-renderer",
                                    foundpath,
                                    NULL,
                                    &error);
    if (error) {
        std::cout << "Error creating MediaPlayer2 proxy: " << error->message << std::endl;
        if (e)
            (*e)->message = error->message;
        return false;
    }

    if (!registerSignalListener(foundpath)) {
        std::cout << "Failed to set up signal listener";
        return false;
    }

    return true;
}

void playerprovider_dbus_properties_changed_cb (GDBusConnection *connection,
                                                const gchar *sender_name,
                                                const gchar *object_path,
                                                const gchar *interface_name,
                                                const gchar *signal_name,
                                                GVariant *parameters,
                                                gpointer user_data) {
    PlayerProvider *_this = ((PlayerProvider *) user_data);
    GVariantIter iter;
    GVariant *child;

    std::cout << "Caught signal: " << signal_name << std::endl;
    GVariant *inner = g_variant_get_child_value(parameters, 1);

    g_variant_iter_init (&iter, inner);
    while ((child = g_variant_iter_next_value (&iter)))
      {
        if (g_variant_is_of_type(child, G_VARIANT_TYPE_STRING)) {
        } if (g_variant_is_of_type (child, G_VARIANT_TYPE_DICT_ENTRY)) {
            GVariant *key = g_variant_get_child_value(child, 0);
            GVariant *value = g_variant_get_variant(g_variant_get_child_value(child, 1));
            std::string keyStr = std::string(g_variant_get_string (key, NULL));
            _this->handlePropertyChangedSignal (keyStr, value);

            g_variant_unref (key);
            g_variant_unref (value);
        }

        g_variant_unref (child);
      }
}

void PlayerProvider::handlePropertyChangedSignal (std::string key, GVariant *value) {
    if (!this->stub) {
            std::cout << "Can't send notification: No stub" << std::endl;
    }

    if (key == "PlaybackStatus") {
        std::cout << "Key: " << key << std::endl;
        std::cout << "Value: " << g_variant_get_string (value, NULL) << std::endl;
        if (g_strcmp0(g_variant_get_string(value,NULL), "Playing") == 0)
            this->stub->setPlaybackStatusAttribute(org::genivi::MediaManager::Player::PlaybackStatus::PLAYING);
        else if (g_strcmp0(g_variant_get_string(value,NULL), "Paused") == 0)
            this->stub->setPlaybackStatusAttribute(org::genivi::MediaManager::Player::PlaybackStatus::PAUSED);
        else if (g_strcmp0(g_variant_get_string(value,NULL), "Stopped") == 0) {
            next(NULL);
        } else {
            std::cout << "Unhandled playback state" << std::endl;
        }
    } else if (key == "Metadata") {
        std::cout << "Key: " << key << std::endl;
        this->stub->setCurrentTrackAttribute(playQueuePosition);
    } else {
        std::cout << "Unhandled key: " << key << std::endl;
    }
}

bool PlayerProvider::registerSignalListener(std::string objectPath) {
    GError *error = NULL;

    GDBusConnection *connection = g_bus_get_sync (
        G_BUS_TYPE_SESSION,
        NULL,
        &error);

    if (error) {
        std::cout << "Failed to set up connection for signal listener:" << error->message <<std::endl;
        return false;
    }

    if (!m_signalHandlerId) {
        m_signalHandlerId = g_dbus_connection_signal_subscribe (connection,
                                    "com.intel.dleyna-renderer",
                                    "org.freedesktop.DBus.Properties",
                                    "PropertiesChanged",
                                    NULL,
                                    NULL,
                                    G_DBUS_SIGNAL_FLAGS_NONE,
                                    playerprovider_dbus_properties_changed_cb,
                                    this,
                                    NULL);
    }

    return true;
}

/*TODO: Move to some common place */
bool PlayerProvider::connectMediaContainer (const std::string path,
                                             dleynaServerMediaContainer2 **mc,
                                             MmError **e) {
    GError *error = NULL;

    if (!g_variant_is_object_path (path.c_str())) {
        std::string error = "Path is invalid";
        std::cout << error << std::endl;
        if (e)
            (*e)->message = error;
        return false;
    }

    *mc = dleyna_server_media_container2_proxy_new_for_bus_sync (
                                    G_BUS_TYPE_SESSION,
                                    G_DBUS_PROXY_FLAGS_NONE,
                                    "com.intel.dleyna-server",
                                    path.c_str(),
                                    NULL,
                                    &error);
    if (error) {
        std::cout << "Error creating MediaContainer2 proxy: " << error->message << std::endl;
        if (e)
            (*e)->message = error->message;
        return false;
    }

    return true;
}

std::string PlayerProvider::getDisplayName (json_t *item, bool &ok) {
    if (!item) {
        std::cout << "Item is null" << std::endl;
        ok = false;
        return "";
    }

    json_t *displayName = json_object_get (item, "DisplayName");
    if (!displayName) {
        std::cout << "Key 'DisplayName' not found" << std::endl;
        ok = false;
        return "";
    }

    const char *displayNameStr = json_string_value(displayName);
    if (!displayNameStr) {
        std::cout << "DisplayName is not a string" << std::endl;
        ok = false;
        return "";
    }

    ok = true;
    return std::string(displayNameStr);
}

std::string PlayerProvider::getLocalURL (json_t *item, bool &ok) {
    if (!item) {
        std::cout << "Item is null" << std::endl;
        ok = false;
        return "";
    }

    json_t *resources = json_object_get (item, "Resources");
    if (!resources) {
        std::cout << "Key 'Resources' not found" << std::endl;
        ok = false;
        return "";
    }

    for (int i = 0; i < json_array_size (resources); i++) {
        json_t *url = json_object_get (json_array_get(resources, i), "URL");
        if (!url) {
            std::cout << "Unable to find URL property in Resource" << std::endl;
            ok = false;
            return "";
        }

        const char *urlStr = json_string_value(url);
        if (!urlStr) {
            std::cout << "URL is not a string" << std::endl;
            ok = false;
            return "";
        }
        if (g_str_has_prefix (urlStr, "file://")) {
            std::cout << "Found local URL: " << urlStr << std::endl;
            ok = true;
            return urlStr;
        }
    }

    ok = false;
    return "";
}

void PlayerProvider::next(MmError **e) {
    changePlayQueuePosition(1, e);
}

void PlayerProvider::previous(MmError **e) {
    changePlayQueuePosition(-1, e);
}

void PlayerProvider::setRate (double rate, MmError **e) {
    std::cout << "In function: " << __FUNCTION__ << std::endl;
    GError                           *error = NULL;
    dleynaRendererMediaPlayer2Player *mp    = NULL;

    if (!mp && !PlayerProvider::connectMediaPlayer(PLAYER_PATH, &mp, e))
        return;
    dleyna_renderer_media_player2_player_set_rate (mp, rate);

    checkError (error, e);
}

bool PlayerProvider::changePlayQueuePosition (int increment, MmError **e) {
    GError                           *error = NULL;
    dleynaRendererMediaPlayer2Player *mp    = NULL;

    if (playqueue) {
        json_t *currentItem = NULL;
        int playQueueSize = json_array_size (playqueue);
        bool ok;
        std::string displayName, localURL;
        int newPlayQueuePosition;

        newPlayQueuePosition = playQueuePosition + increment;

        if (playQueueSize < newPlayQueuePosition) {
            std::cout << "Play queue is smaller than " << playQueuePosition << " elements" << std::endl;
            return false;
        }

        if (newPlayQueuePosition < 0) {
            std::cout << "Illegal play queue position: " << playQueuePosition << std::endl;
            return false;
        }

        playQueuePosition = newPlayQueuePosition;

        std::cout << "Playlist contains " << playQueueSize << " items" << std::endl;
        currentItem = json_array_get(playqueue, playQueuePosition);

        displayName = getDisplayName(currentItem, ok);
        if (ok)
            std::cout << "Current item is: " << displayName << std::endl;
        else
            std::cout << "Failed to get DisplayName for current item" << std::endl;

        localURL = getLocalURL(currentItem, ok);
        if (ok)
            std::cout << "Local URL for item is: " << localURL << std::endl;
        else
            std::cout << "Failed to get localURL for current item" << std::endl;

        openURI (localURL, e);
        return true;

    } else {
        std::cout << "No play queue has been loaded";
        return false;
    }

    return false;
}
<commit_msg>Handle 'no more tracks' in dLeyna like a queue to signal PAUSED to client<commit_after> /**
  * Copyright (C) 2014, Jaguar Land Rover
  *
  * Author: Jonatan Palsson <jonatan.palsson@pelagicore.com>
  *
  * This file is part of the GENIVI Media Manager Proof-of-Concept
  * For further information, see http://genivi.org/
  *
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */

#include <iostream>
#include <sstream>
#include "string.h"

#include "playerprovider.h"

static char* PLAYER_PATH = "/com/intel/dLeynaRenderer/server/0";

char *PlayerProvider::findFirstPlayer(MmError **e) {
    char *path = NULL;
    dleynaRendererOrgFreedesktopDBusPeer *peer = NULL;
    int slashPos = -1;
    for (int i = strlen(PLAYER_PATH); i > 0; i--) {
        if (PLAYER_PATH[i] == '/') {
            slashPos = i;
            break;
        }
    }

    path = g_strndup(PLAYER_PATH, slashPos);

    for (int i = 0; i < 50; i++) {
        char *newpath = g_strdup_printf("%s/%d", path, i);

        GError *error = NULL;
        GDBusProxy *proxy = NULL;
        GDBusConnection *conn = g_bus_get_sync (G_BUS_TYPE_SESSION,
                                                NULL,
                                                &error);

        if (error) {
            if (e)
                (*e)->message = "Unable to get connection to bus";
            return NULL;
        }

        proxy = g_dbus_proxy_new_sync (conn,
                                       G_DBUS_PROXY_FLAGS_NONE,
                                       NULL,
                                       "com.intel.dleyna-renderer",
                                       newpath,
                                       "org.freedesktop.DBus.Properties",
                                       NULL,
                                       &error);

        if (error) {
            if (e)
                (*e)->message = std::string("Unable to create proxy for ") + newpath;
            return NULL;
        }

        GVariant *ret = g_dbus_proxy_call_sync (proxy,
                                                "Get",
                                                g_variant_new("(ss)",
                                                              "org.mpris.MediaPlayer2",
                                                              "Identity"),
                                                G_DBUS_CALL_FLAGS_NONE,
                                                -1,
                                                NULL,
                                                &error);
        if (!error) {
            g_printerr ("Found player on %s\n", newpath);
            return newpath;
            break;
        } else {
            g_printerr ("No player found on %s\n", newpath);
        }
    }

    g_free (path);
    return NULL;
}

void PlayerProvider::openURI(std::string uri,
                             MmError **e)
{
    GError                           *error  = NULL;

    if (!PlayerProvider::connectMediaPlayer(PLAYER_PATH, &mp, e))
        return;
    dleyna_renderer_media_player2_player_call_open_uri_sync (mp,
                                                             uri.c_str(),
                                                             NULL,
                                                             &error);

    checkError (error, e);
}

void PlayerProvider::pause(MmError **e) {
    GError                           *error = NULL;

    if (!PlayerProvider::connectMediaPlayer(PLAYER_PATH, &mp, e))
        return;
    dleyna_renderer_media_player2_player_call_pause_sync (mp,
                                                             NULL,
                                                             &error);

    // dLeyna says we failed to pause, but PAUSED to the client anyway
    if (!checkError (error, e)) {
        this->stub->setPlaybackStatusAttribute(org::genivi::MediaManager::Player::PlaybackStatus::PAUSED);
    }
}

void PlayerProvider::play(MmError **e) {
    GError                           *error = NULL;

    if (!PlayerProvider::connectMediaPlayer(PLAYER_PATH, &mp, e))
        return;
    dleyna_renderer_media_player2_player_call_play_sync (mp,
                                                         NULL,
                                                         &error);

    checkError (error, e);
}

void PlayerProvider::playPause(MmError **e) {
    GError                           *error = NULL;

    if (!PlayerProvider::connectMediaPlayer(PLAYER_PATH, &mp, e))
        return;
    dleyna_renderer_media_player2_player_call_play_pause_sync (mp,
                                                               NULL,
                                                               &error);

    checkError (error, e);
}

void PlayerProvider::openPlaylist (std::string playlistPath, MmError **e) {
    std::cout << "In function: " << __FUNCTION__ << std::endl;
    GError                           *error = NULL;
    GVariant *out = NULL;

    std::vector<std::string> filter;
    filter.push_back("*");

    int offset = 0;
    int count = 100;
    gchar **filterStrv = stdStrvToStrv(filter);

    if (!PlayerProvider::connectMediaContainer (playlistPath, &mc, e))
        return;

    dleyna_server_media_container2_call_list_items_sync (mc, offset, count,
                                                  filterStrv, &out, NULL,
                                                  &error);

    if (error) {
        std::cout << "Unable to open playlist: " << error->message << std::endl;
        return;
    }

    std::string containers;
    std::cout << "Setting play queue to: " << playlistPath << std::endl;

    json_decref (playqueue);
    playqueue = DLNADictToJSON (out);

    playQueuePosition = 0;
    changePlayQueuePosition (0, e);

    checkError (error, e);
}

bool PlayerProvider::connectMediaPlayer (const std::string path,
                                             dleynaRendererMediaPlayer2Player **mp,
                                             MmError **e) {
    GError *error = NULL;

    char *foundpath = findFirstPlayer(NULL);
    if (!foundpath) {
        g_printerr ("Unable to find any player");
        return false;
    }

    if (!g_variant_is_object_path (foundpath)) {
        std::string error = "Path is invalid";
        std::cout << error << std::endl;
        if (e)
            (*e)->message = error;
        return false;
    }

    *mp = dleyna_renderer_media_player2_player_proxy_new_for_bus_sync (
                                    G_BUS_TYPE_SESSION,
                                    G_DBUS_PROXY_FLAGS_NONE,
                                    "com.intel.dleyna-renderer",
                                    foundpath,
                                    NULL,
                                    &error);
    if (error) {
        std::cout << "Error creating MediaPlayer2 proxy: " << error->message << std::endl;
        if (e)
            (*e)->message = error->message;
        return false;
    }

    if (!registerSignalListener(foundpath)) {
        std::cout << "Failed to set up signal listener";
        return false;
    }

    return true;
}

void playerprovider_dbus_properties_changed_cb (GDBusConnection *connection,
                                                const gchar *sender_name,
                                                const gchar *object_path,
                                                const gchar *interface_name,
                                                const gchar *signal_name,
                                                GVariant *parameters,
                                                gpointer user_data) {
    PlayerProvider *_this = ((PlayerProvider *) user_data);
    GVariantIter iter;
    GVariant *child;

    std::cout << "Caught signal: " << signal_name << std::endl;
    GVariant *inner = g_variant_get_child_value(parameters, 1);

    g_variant_iter_init (&iter, inner);
    while ((child = g_variant_iter_next_value (&iter)))
      {
        if (g_variant_is_of_type(child, G_VARIANT_TYPE_STRING)) {
        } if (g_variant_is_of_type (child, G_VARIANT_TYPE_DICT_ENTRY)) {
            GVariant *key = g_variant_get_child_value(child, 0);
            GVariant *value = g_variant_get_variant(g_variant_get_child_value(child, 1));
            std::string keyStr = std::string(g_variant_get_string (key, NULL));
            _this->handlePropertyChangedSignal (keyStr, value);

            g_variant_unref (key);
            g_variant_unref (value);
        }

        g_variant_unref (child);
      }
}

void PlayerProvider::handlePropertyChangedSignal (std::string key, GVariant *value) {
    if (!this->stub) {
            std::cout << "Can't send notification: No stub" << std::endl;
    }

    if (key == "PlaybackStatus") {
        std::cout << "Key: " << key << std::endl;
        std::cout << "Value: " << g_variant_get_string (value, NULL) << std::endl;
        if (g_strcmp0(g_variant_get_string(value,NULL), "Playing") == 0)
            this->stub->setPlaybackStatusAttribute(org::genivi::MediaManager::Player::PlaybackStatus::PLAYING);
        else if (g_strcmp0(g_variant_get_string(value,NULL), "Paused") == 0)
            this->stub->setPlaybackStatusAttribute(org::genivi::MediaManager::Player::PlaybackStatus::PAUSED);
        else if (g_strcmp0(g_variant_get_string(value,NULL), "Stopped") == 0) {
            next(NULL);
        } else {
            std::cout << "Unhandled playback state" << std::endl;
        }
    } else if (key == "Metadata") {
        std::cout << "Key: " << key << std::endl;
        this->stub->setCurrentTrackAttribute(playQueuePosition);
    } else {
        std::cout << "Unhandled key: " << key << std::endl;
    }
}

bool PlayerProvider::registerSignalListener(std::string objectPath) {
    GError *error = NULL;

    GDBusConnection *connection = g_bus_get_sync (
        G_BUS_TYPE_SESSION,
        NULL,
        &error);

    if (error) {
        std::cout << "Failed to set up connection for signal listener:" << error->message <<std::endl;
        return false;
    }

    if (!m_signalHandlerId) {
        m_signalHandlerId = g_dbus_connection_signal_subscribe (connection,
                                    "com.intel.dleyna-renderer",
                                    "org.freedesktop.DBus.Properties",
                                    "PropertiesChanged",
                                    NULL,
                                    NULL,
                                    G_DBUS_SIGNAL_FLAGS_NONE,
                                    playerprovider_dbus_properties_changed_cb,
                                    this,
                                    NULL);
    }

    return true;
}

/*TODO: Move to some common place */
bool PlayerProvider::connectMediaContainer (const std::string path,
                                             dleynaServerMediaContainer2 **mc,
                                             MmError **e) {
    GError *error = NULL;

    if (!g_variant_is_object_path (path.c_str())) {
        std::string error = "Path is invalid";
        std::cout << error << std::endl;
        if (e)
            (*e)->message = error;
        return false;
    }

    *mc = dleyna_server_media_container2_proxy_new_for_bus_sync (
                                    G_BUS_TYPE_SESSION,
                                    G_DBUS_PROXY_FLAGS_NONE,
                                    "com.intel.dleyna-server",
                                    path.c_str(),
                                    NULL,
                                    &error);
    if (error) {
        std::cout << "Error creating MediaContainer2 proxy: " << error->message << std::endl;
        if (e)
            (*e)->message = error->message;
        return false;
    }

    return true;
}

std::string PlayerProvider::getDisplayName (json_t *item, bool &ok) {
    if (!item) {
        std::cout << "Item is null" << std::endl;
        ok = false;
        return "";
    }

    json_t *displayName = json_object_get (item, "DisplayName");
    if (!displayName) {
        std::cout << "Key 'DisplayName' not found" << std::endl;
        ok = false;
        return "";
    }

    const char *displayNameStr = json_string_value(displayName);
    if (!displayNameStr) {
        std::cout << "DisplayName is not a string" << std::endl;
        ok = false;
        return "";
    }

    ok = true;
    return std::string(displayNameStr);
}

std::string PlayerProvider::getLocalURL (json_t *item, bool &ok) {
    if (!item) {
        std::cout << "Item is null" << std::endl;
        ok = false;
        return "";
    }

    json_t *resources = json_object_get (item, "Resources");
    if (!resources) {
        std::cout << "Key 'Resources' not found" << std::endl;
        ok = false;
        return "";
    }

    for (int i = 0; i < json_array_size (resources); i++) {
        json_t *url = json_object_get (json_array_get(resources, i), "URL");
        if (!url) {
            std::cout << "Unable to find URL property in Resource" << std::endl;
            ok = false;
            return "";
        }

        const char *urlStr = json_string_value(url);
        if (!urlStr) {
            std::cout << "URL is not a string" << std::endl;
            ok = false;
            return "";
        }
        if (g_str_has_prefix (urlStr, "file://")) {
            std::cout << "Found local URL: " << urlStr << std::endl;
            ok = true;
            return urlStr;
        }
    }

    ok = false;
    return "";
}

void PlayerProvider::next(MmError **e) {
    if (!changePlayQueuePosition(1, e)) {
        pause(e);
    }
}

void PlayerProvider::previous(MmError **e) {
    changePlayQueuePosition(-1, e);
}

void PlayerProvider::setRate (double rate, MmError **e) {
    std::cout << "In function: " << __FUNCTION__ << std::endl;
    GError                           *error = NULL;
    dleynaRendererMediaPlayer2Player *mp    = NULL;

    if (!mp && !PlayerProvider::connectMediaPlayer(PLAYER_PATH, &mp, e))
        return;
    dleyna_renderer_media_player2_player_set_rate (mp, rate);

    checkError (error, e);
}

bool PlayerProvider::changePlayQueuePosition (int increment, MmError **e) {
    GError                           *error = NULL;
    dleynaRendererMediaPlayer2Player *mp    = NULL;

    if (playqueue) {
        json_t *currentItem = NULL;
        int playQueueSize = json_array_size (playqueue);
        bool ok;
        std::string displayName, localURL;
        int newPlayQueuePosition;

        newPlayQueuePosition = playQueuePosition + increment;

        if (playQueueSize < newPlayQueuePosition) {
            std::cout << "Play queue is smaller than " << playQueuePosition << " elements" << std::endl;
            return false;
        }

        if (newPlayQueuePosition < 0) {
            std::cout << "Illegal play queue position: " << playQueuePosition << std::endl;
            return false;
        }

        playQueuePosition = newPlayQueuePosition;

        std::cout << "Playlist contains " << playQueueSize << " items" << std::endl;
        currentItem = json_array_get(playqueue, playQueuePosition);

        displayName = getDisplayName(currentItem, ok);
        if (ok)
            std::cout << "Current item is: " << displayName << std::endl;
        else
            std::cout << "Failed to get DisplayName for current item" << std::endl;

        localURL = getLocalURL(currentItem, ok);
        if (ok)
            std::cout << "Local URL for item is: " << localURL << std::endl;
        else
            std::cout << "Failed to get localURL for current item" << std::endl;

        openURI (localURL, e);
        return true;

    } else {
        std::cout << "No play queue has been loaded";
        return false;
    }

    return false;
}
<|endoftext|>


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

    Copyright (c) 2009 Tobias Koenig <tokoe@kde.org>

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

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

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

#include "contactitemeditor.h"

#include <QtGui/QVBoxLayout>
#include <QtGui/QMessageBox>

#include <kabc/addressee.h>
#include <akonadi/itemcreatejob.h>
#include <akonadi/itemfetchjob.h>
#include <akonadi/itemfetchscope.h>
#include <akonadi/itemmodifyjob.h>
#include <akonadi/monitor.h>
#include <akonadi/session.h>

#include <klocale.h>
#include <kdebug.h>

class ContactItemEditor::Private
{
  public:
    Private( ContactItemEditor *parent )
      : mParent( parent ), mMonitor( 0 )
    {
    }

    ~Private()
    {
      delete mMonitor;
    }

    void fetchDone( KJob* );
    void storeDone( KJob* );
    void itemChanged( const Akonadi::Item &item, const QSet<QByteArray>& );

    void loadContact( const KABC::Addressee &addr );
    void storeContact( KABC::Addressee &addr );
    void setupMonitor();

    ContactItemEditor *mParent;
    ContactItemEditor::Mode mMode;
    Akonadi::Item mItem;
    Akonadi::Monitor *mMonitor;
    Akonadi::Collection mDefaultCollection;
    AbstractContactEditorWidget *mEditorWidget;
};

void ContactItemEditor::Private::fetchDone( KJob *job )
{
  if ( job->error() )
    return;

  Akonadi::ItemFetchJob *fetchJob = qobject_cast<Akonadi::ItemFetchJob*>( job );
  if ( !fetchJob )
    return;

  if ( fetchJob->items().isEmpty() )
    return;

  mItem = fetchJob->items().first();

  const KABC::Addressee addr = mItem.payload<KABC::Addressee>();
  loadContact( addr );
}

void ContactItemEditor::Private::storeDone( KJob *job )
{
  if ( job->error() ) {
    emit mParent->error( job->errorString() );
    return;
  }

  if ( mMode == EditMode )
    emit mParent->contactStored( mItem );
  else if ( mMode == CreateMode )
    emit mParent->contactStored( static_cast<Akonadi::ItemCreateJob*>( job )->item() );
}

void ContactItemEditor::Private::itemChanged( const Akonadi::Item&, const QSet<QByteArray>& )
{
  QMessageBox dlg( mParent );

  dlg.setInformativeText( QLatin1String( "The contact has been changed by anyone else\nWhat shall be done?" ) );
  dlg.addButton( i18n( "Take over changes" ), QMessageBox::AcceptRole );
  dlg.addButton( i18n( "Ignore and Overwrite changes" ), QMessageBox::RejectRole );

  if ( dlg.exec() == QMessageBox::AcceptRole ) {
    Akonadi::ItemFetchJob *job = new Akonadi::ItemFetchJob( mItem );
    job->fetchScope().fetchFullPayload();

    mParent->connect( job, SIGNAL( result( KJob* ) ), mParent, SLOT( fetchDone( KJob* ) ) );
  }
}

void ContactItemEditor::Private::loadContact( const KABC::Addressee &addr )
{
  mEditorWidget->loadContact( addr );
}

void ContactItemEditor::Private::storeContact( KABC::Addressee &addr )
{
  mEditorWidget->storeContact( addr );
}

void ContactItemEditor::Private::setupMonitor()
{
  delete mMonitor;
  mMonitor = new Akonadi::Monitor;
  mMonitor->ignoreSession( Akonadi::Session::defaultSession() );

  connect( mMonitor, SIGNAL( itemChanged( const Akonadi::Item&, const QSet<QByteArray>& ) ),
           mParent, SLOT( itemChanged( const Akonadi::Item&, const QSet<QByteArray>& ) ) );
}

ContactItemEditor::ContactItemEditor( Mode mode, AbstractContactEditorWidget *editorWidget, QWidget *parent )
  : QWidget( parent ), d( new Private( this ) )
{
  d->mMode = mode;
  d->mEditorWidget = editorWidget;

  QVBoxLayout *layout = new QVBoxLayout( this );
  layout->setMargin( 0 );
  layout->setSpacing( 0 );
  layout->addWidget( d->mEditorWidget );
}

ContactItemEditor::~ContactItemEditor()
{
  delete d;
}

void ContactItemEditor::loadContact( const Akonadi::Item &item )
{
  if ( d->mMode == CreateMode )
    Q_ASSERT_X( false, "ContactItemEditor::loadContact", "You are calling loadContact in CreateMode!" );

  Akonadi::ItemFetchJob *job = new Akonadi::ItemFetchJob( item );
  job->fetchScope().fetchFullPayload();

  connect( job, SIGNAL( result( KJob* ) ), SLOT( fetchDone( KJob* ) ) );

  d->setupMonitor();
  d->mMonitor->setItemMonitored( item );
}

void ContactItemEditor::saveContact()
{
  KJob *job = 0;

  if ( d->mMode == EditMode ) {
    if ( !d->mItem.isValid() )
      return;

    KABC::Addressee addr = d->mItem.payload<KABC::Addressee>();
    d->storeContact( addr );
    d->mItem.setPayload<KABC::Addressee>( addr );

    job = new Akonadi::ItemModifyJob( d->mItem );
  } else if ( d->mMode == CreateMode ) {
    Q_ASSERT_X( d->mDefaultCollection.isValid(), "ContactItemEditor::saveContact", "Using invalid default collection for saving!" );

    KABC::Addressee addr;
    d->storeContact( addr );

    Akonadi::Item item;
    item.setPayload<KABC::Addressee>( addr );
    item.setMimeType( KABC::Addressee::mimeType() );

    job = new Akonadi::ItemCreateJob( item, d->mDefaultCollection );
  }

  connect( job, SIGNAL( result( KJob* ) ), SLOT( storeDone( KJob* ) ) );

  if ( ! job->exec() )
    kDebug() << "Error occurred: " << job->errorText();
}

void ContactItemEditor::setDefaultCollection( const Akonadi::Collection &collection )
{
  d->mDefaultCollection = collection;
}

#include "contactitemeditor.moc"
<commit_msg>better solution then r961778; it's async (thx krake & volker) + refresh-conidition in fetchDone() was wrong.<commit_after>/*
    This file is part of KContactManager.

    Copyright (c) 2009 Tobias Koenig <tokoe@kde.org>

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

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

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

#include "contactitemeditor.h"

#include <QtGui/QVBoxLayout>
#include <QtGui/QMessageBox>

#include <kabc/addressee.h>
#include <akonadi/itemcreatejob.h>
#include <akonadi/itemfetchjob.h>
#include <akonadi/itemfetchscope.h>
#include <akonadi/itemmodifyjob.h>
#include <akonadi/monitor.h>
#include <akonadi/session.h>

#include <klocale.h>

class ContactItemEditor::Private
{
  public:
    Private( ContactItemEditor *parent )
      : mParent( parent ), mMonitor( 0 )
    {
    }

    ~Private()
    {
      delete mMonitor;
    }

    void fetchDone( KJob* );
    void storeDone( KJob* );
    void itemChanged( const Akonadi::Item &item, const QSet<QByteArray>& );

    void loadContact( const KABC::Addressee &addr );
    void storeContact( KABC::Addressee &addr );
    void setupMonitor();

    ContactItemEditor *mParent;
    ContactItemEditor::Mode mMode;
    Akonadi::Item mItem;
    Akonadi::Monitor *mMonitor;
    Akonadi::Collection mDefaultCollection;
    AbstractContactEditorWidget *mEditorWidget;
};

void ContactItemEditor::Private::fetchDone( KJob *job )
{
  if ( job->error() != KJob::NoError )
    return;

  Akonadi::ItemFetchJob *fetchJob = qobject_cast<Akonadi::ItemFetchJob*>( job );
  if ( !fetchJob )
    return;

  if ( fetchJob->items().isEmpty() )
    return;

  mItem = fetchJob->items().first();

  const KABC::Addressee addr = mItem.payload<KABC::Addressee>();
  loadContact( addr );
}

void ContactItemEditor::Private::storeDone( KJob *job )
{
  if ( job->error() ) {
    emit mParent->error( job->errorString() );
    return;
  }

  if ( mMode == EditMode )
    emit mParent->contactStored( mItem );
  else if ( mMode == CreateMode )
    emit mParent->contactStored( static_cast<Akonadi::ItemCreateJob*>( job )->item() );
}

void ContactItemEditor::Private::itemChanged( const Akonadi::Item&, const QSet<QByteArray>& )
{
  QMessageBox dlg( mParent );

  dlg.setInformativeText( QLatin1String( "The contact has been changed by anyone else\nWhat shall be done?" ) );
  dlg.addButton( i18n( "Take over changes" ), QMessageBox::AcceptRole );
  dlg.addButton( i18n( "Ignore and Overwrite changes" ), QMessageBox::RejectRole );

  if ( dlg.exec() == QMessageBox::AcceptRole ) {
    Akonadi::ItemFetchJob *job = new Akonadi::ItemFetchJob( mItem );
    job->fetchScope().fetchFullPayload();

    mParent->connect( job, SIGNAL( result( KJob* ) ), mParent, SLOT( fetchDone( KJob* ) ) );
  }
}

void ContactItemEditor::Private::loadContact( const KABC::Addressee &addr )
{
  mEditorWidget->loadContact( addr );
}

void ContactItemEditor::Private::storeContact( KABC::Addressee &addr )
{
  mEditorWidget->storeContact( addr );
}

void ContactItemEditor::Private::setupMonitor()
{
  delete mMonitor;
  mMonitor = new Akonadi::Monitor;
  mMonitor->ignoreSession( Akonadi::Session::defaultSession() );

  connect( mMonitor, SIGNAL( itemChanged( const Akonadi::Item&, const QSet<QByteArray>& ) ),
           mParent, SLOT( itemChanged( const Akonadi::Item&, const QSet<QByteArray>& ) ) );
}

ContactItemEditor::ContactItemEditor( Mode mode, AbstractContactEditorWidget *editorWidget, QWidget *parent )
  : QWidget( parent ), d( new Private( this ) )
{
  d->mMode = mode;
  d->mEditorWidget = editorWidget;

  QVBoxLayout *layout = new QVBoxLayout( this );
  layout->setMargin( 0 );
  layout->setSpacing( 0 );
  layout->addWidget( d->mEditorWidget );
}

ContactItemEditor::~ContactItemEditor()
{
  delete d;
}

void ContactItemEditor::loadContact( const Akonadi::Item &item )
{
  if ( d->mMode == CreateMode )
    Q_ASSERT_X( false, "ContactItemEditor::loadContact", "You are calling loadContact in CreateMode!" );

  Akonadi::ItemFetchJob *job = new Akonadi::ItemFetchJob( item );
  job->fetchScope().fetchFullPayload();

  connect( job, SIGNAL( result( KJob* ) ), SLOT( fetchDone( KJob* ) ) );

  d->setupMonitor();
  d->mMonitor->setItemMonitored( item );
}

void ContactItemEditor::saveContact()
{
  if ( d->mMode == EditMode ) {
    if ( !d->mItem.isValid() )
      return;

    KABC::Addressee addr = d->mItem.payload<KABC::Addressee>();

    d->storeContact( addr );

    d->mItem.setPayload<KABC::Addressee>( addr );

    Akonadi::ItemModifyJob *job = new Akonadi::ItemModifyJob( d->mItem );
    connect( job, SIGNAL( result( KJob* ) ), SLOT( storeDone( KJob* ) ) );
  } else if ( d->mMode == CreateMode ) {
    Q_ASSERT_X( d->mDefaultCollection.isValid(), "ContactItemEditor::saveContact", "Using invalid default collection for saving!" );

    KABC::Addressee addr;
    d->storeContact( addr );

    Akonadi::Item item;
    item.setPayload<KABC::Addressee>( addr );
    item.setMimeType( KABC::Addressee::mimeType() );

    Akonadi::ItemCreateJob *job = new Akonadi::ItemCreateJob( item, d->mDefaultCollection );
    connect( job, SIGNAL( result( KJob* ) ), SLOT( storeDone( KJob* ) ) );
  }
}

void ContactItemEditor::setDefaultCollection( const Akonadi::Collection &collection )
{
  d->mDefaultCollection = collection;
}

#include "contactitemeditor.moc"
<|endoftext|>


<commit_before>/*
    This file is part of KAddressbook.
    Copyright (c) 2000 Cornelius Schumacher <schumacher@kde.org>

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

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

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

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

#include <qlayout.h>

#include <kapplication.h>
#include <kinstance.h>
#include <klocale.h>
#include <kaboutdata.h>
#include <kiconloader.h>
#include <kaction.h>
#include <kdebug.h>
#include <kparts/genericfactory.h>

#include "kaddressbook.h"
#include "kaddressbooktableview.h"
#include "viewmanager.h"
#include "kaddressbookiface.h"
#include "actionmanager.h"

#include "kaddressbook_part.h"

typedef KParts::GenericFactory< KAddressbookPart > KAddressbookFactory;
K_EXPORT_COMPONENT_FACTORY( libkaddressbookpart, KAddressbookFactory );

KAddressbookPart::KAddressbookPart(QWidget *parentWidget, const char *widgetName,
                               QObject *parent, const char *name, const QStringList &) :
  KParts::ReadOnlyPart(parent, name), DCOPObject("KAddressBookIface")
{
  kdDebug() << "KAddressbookPart()" << endl;
  kdDebug() << "  InstanceName: " << kapp->instanceName() << endl;

  setInstance(KAddressbookFactory::instance());

  kdDebug() << "KAddressbookPart()..." << endl;
  kdDebug() << "  InstanceName: " << kapp->instanceName() << endl;

  // create a canvas to insert our widget
  QWidget *canvas = new QWidget(parentWidget, widgetName);
  canvas->setFocusPolicy(QWidget::ClickFocus);
  setWidget(canvas);

  m_extension = new KAddressbookBrowserExtension(this);

  QVBoxLayout *topLayout = new QVBoxLayout(canvas);

  KGlobal::iconLoader()->addAppDir("kaddressbook");

  widget = new KAddressBook(canvas);
  widget->readConfig();
  topLayout->addWidget(widget);
  widget->viewManager()->showFeatures( 0 );

  widget->show();

  mActionManager = new ActionManager(this, widget, false, this);

  setXMLFile( "kaddressbook_part.rc" );
}

KAddressbookPart::~KAddressbookPart()
{
  closeURL();
}

KAboutData *KAddressbookPart::createAboutData()
{
  KAboutData *about = new KAboutData("kaddressbook", I18N_NOOP("KAddressBook"),
                                     "3.1beta1", I18N_NOOP("The KDE Address Book"),
                                     KAboutData::License_BSD,
                                     I18N_NOOP("(c) 1997-2002, The KDE PIM Team"));
  about->addAuthor("Tobias Koenig", I18N_NOOP("Current maintainer"), "tokoe@kde.org");
  about->addAuthor("Don Sanders",I18N_NOOP("Original author"));
  about->addAuthor("Cornelius Schumacher",
                  I18N_NOOP("Co-maintainer, libkabc port, csv import/export"),
                  "schumacher@kde.org");
  about->addAuthor("Mike Pilone", I18N_NOOP( "GUI and framework redesign" ),
                  "mpilone@slac.com" );
  about->addAuthor("Greg Stern", I18N_NOOP("DCOP interface"));
  about->addAuthor("Mark Westcott",I18N_NOOP("Contact pinning"));
  about->addAuthor("Mischel Boyer de la Giroday", I18N_NOOP("LDAP Lookup"),
		   "michel@klaralvdalens-datakonsult.se");
  about->addAuthor("Steffen Hansen", I18N_NOOP("LDAP Lookup"), "hansen@kde.org");

  return about;
}

bool KAddressbookPart::openFile()
{
  kdDebug() << "KAddressbookPart:openFile()" << endl;

  widget->show();
  return true;
}

void KAddressbookPart::guiActivateEvent(KParts::GUIActivateEvent *e)
{
  kdDebug() << "KAddressbookPart::guiActivateEvent" << endl;
  KParts::ReadOnlyPart::guiActivateEvent(e);

  mActionManager->initActionViewList();
}

KAddressbookBrowserExtension::KAddressbookBrowserExtension(KAddressbookPart *parent) :
  KParts::BrowserExtension(parent, "KAddressbookBrowserExtension")
{
}

KAddressbookBrowserExtension::~KAddressbookBrowserExtension()
{
}

using namespace KParts;
#include "kaddressbook_part.moc"
<commit_msg><commit_after>/*
    This file is part of KAddressbook.
    Copyright (c) 2000 Cornelius Schumacher <schumacher@kde.org>

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

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

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

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

#include <qlayout.h>

#include <kapplication.h>
#include <kinstance.h>
#include <klocale.h>
#include <kaboutdata.h>
#include <kiconloader.h>
#include <kaction.h>
#include <kdebug.h>
#include <kparts/genericfactory.h>

#include "kaddressbook.h"
#include "kaddressbooktableview.h"
#include "viewmanager.h"
#include "kaddressbookiface.h"
#include "actionmanager.h"

#include "kaddressbook_part.h"

typedef KParts::GenericFactory< KAddressbookPart > KAddressbookFactory;
K_EXPORT_COMPONENT_FACTORY( libkaddressbookpart, KAddressbookFactory );

KAddressbookPart::KAddressbookPart(QWidget *parentWidget, const char *widgetName,
                               QObject *parent, const char *name, const QStringList &) :
  KParts::ReadOnlyPart(parent, name), DCOPObject("KAddressBookIface")
{
  kdDebug() << "KAddressbookPart()" << endl;
  kdDebug() << "  InstanceName: " << kapp->instanceName() << endl;

  setInstance(KAddressbookFactory::instance());

  kdDebug() << "KAddressbookPart()..." << endl;
  kdDebug() << "  InstanceName: " << kapp->instanceName() << endl;

  // create a canvas to insert our widget
  QWidget *canvas = new QWidget(parentWidget, widgetName);
  canvas->setFocusPolicy(QWidget::ClickFocus);
  setWidget(canvas);

  m_extension = new KAddressbookBrowserExtension(this);

  QVBoxLayout *topLayout = new QVBoxLayout(canvas);

  KGlobal::iconLoader()->addAppDir("kaddressbook");

  widget = new KAddressBook(canvas);
  widget->readConfig();
  topLayout->addWidget(widget);
  widget->viewManager()->showFeatures( 0 );

  widget->show();

  mActionManager = new ActionManager(this, widget, false, this);

  setXMLFile( "kaddressbook_part.rc" );
}

KAddressbookPart::~KAddressbookPart()
{
  closeURL();
}

KAboutData *KAddressbookPart::createAboutData()
{
  KAboutData *about = new KAboutData("kaddressbook", I18N_NOOP("KAddressBook"),
                                     "3.1", I18N_NOOP("The KDE Address Book"),
                                     KAboutData::License_BSD,
                                     I18N_NOOP("(c) 1997-2002, The KDE PIM Team"));
  about->addAuthor("Tobias Koenig", I18N_NOOP("Current maintainer"), "tokoe@kde.org");
  about->addAuthor("Don Sanders",I18N_NOOP("Original author"));
  about->addAuthor("Cornelius Schumacher",
                  I18N_NOOP("Co-maintainer, libkabc port, csv import/export"),
                  "schumacher@kde.org");
  about->addAuthor("Mike Pilone", I18N_NOOP( "GUI and framework redesign" ),
                  "mpilone@slac.com" );
  about->addAuthor("Greg Stern", I18N_NOOP("DCOP interface"));
  about->addAuthor("Mark Westcott",I18N_NOOP("Contact pinning"));
  about->addAuthor("Mischel Boyer de la Giroday", I18N_NOOP("LDAP Lookup"),
		   "michel@klaralvdalens-datakonsult.se");
  about->addAuthor("Steffen Hansen", I18N_NOOP("LDAP Lookup"), "hansen@kde.org");

  return about;
}

bool KAddressbookPart::openFile()
{
  kdDebug() << "KAddressbookPart:openFile()" << endl;

  widget->show();
  return true;
}

void KAddressbookPart::guiActivateEvent(KParts::GUIActivateEvent *e)
{
  kdDebug() << "KAddressbookPart::guiActivateEvent" << endl;
  KParts::ReadOnlyPart::guiActivateEvent(e);

  mActionManager->initActionViewList();
}

KAddressbookBrowserExtension::KAddressbookBrowserExtension(KAddressbookPart *parent) :
  KParts::BrowserExtension(parent, "KAddressbookBrowserExtension")
{
}

KAddressbookBrowserExtension::~KAddressbookBrowserExtension()
{
}

using namespace KParts;
#include "kaddressbook_part.moc"
<|endoftext|>


<commit_before>#include "image.h"

Nan::Persistent<FunctionTemplate> LwipImage::constructor;

void LwipImage::Init(Handle<Object> exports) {
    // Prepare constructor template
    Local<FunctionTemplate> tpl = Nan::New<FunctionTemplate>(New);
    tpl->InstanceTemplate()->SetInternalFieldCount(1);
    tpl->SetClassName(Nan::New("LwipImage").ToLocalChecked());
    Nan::SetPrototypeMethod(tpl, "width", width);
    Nan::SetPrototypeMethod(tpl, "height", height);
    Nan::SetPrototypeMethod(tpl, "getPixel", getPixel);
    Nan::SetPrototypeMethod(tpl, "buffer", buffer);
    Nan::SetPrototypeMethod(tpl, "resize", resize);
    Nan::SetPrototypeMethod(tpl, "rotate", rotate);
    Nan::SetPrototypeMethod(tpl, "blur", blur);
    Nan::SetPrototypeMethod(tpl, "crop", crop);
    Nan::SetPrototypeMethod(tpl, "mirror", mirror);
    Nan::SetPrototypeMethod(tpl, "pad", pad);
    Nan::SetPrototypeMethod(tpl, "sharpen", sharpen);
    Nan::SetPrototypeMethod(tpl, "hslaAdj", hslaAdj);
    Nan::SetPrototypeMethod(tpl, "opacify", opacify);
    Nan::SetPrototypeMethod(tpl, "paste", paste);
    Nan::SetPrototypeMethod(tpl, "setPixel", setPixel);
    constructor.Reset(tpl);
    exports->Set(
        Nan::New("LwipImage").ToLocalChecked(),
        Nan::New<FunctionTemplate>(constructor)->GetFunction()
    );
}

LwipImage::LwipImage(unsigned char * data, size_t width, size_t height, int channels) {
    // TODO: CImg constructor may throw an exception. handle it in LwipImage::New.
    _cimg = new CImg<unsigned char>(data, width, height, 1, channels, false);
}

LwipImage::~LwipImage() {
    //Causes  malloc: *** error for object 0x105c44000: pointer being freed was not allocated on Nan 2+
    //delete _cimg;
};

Handle<Value> LwipImage::NewInstance() {
    Nan::EscapableHandleScope scope;
    Local<FunctionTemplate> constructorHandle = Nan::New<FunctionTemplate>(constructor);
    Local<Object> instance = constructorHandle->GetFunction()->NewInstance();
    return scope.Escape(instance);
}

NAN_METHOD(LwipImage::New) {
    Nan::HandleScope();
    // info[0] - pixels buffer
    // info[1,2] - width and height
    Local<Object> pixBuff = info[0].As<Object>();
    size_t width = Nan::To<uint32_t>(info[1]).FromJust();
	size_t height = Nan::To<uint32_t>(info[2]).FromJust();
    uint32_t channels = Nan::To<uint32_t>(info[3]).FromJust();

	unsigned char * pixels = (unsigned char *)Buffer::Data(pixBuff);
	size_t len = Buffer::Length(pixBuff);

	//CImg expects the size of the buffer to match width*height as it will memcpy this much from buffer.
    //If it doesnt' match buffer length then throw so that CImg does not read past our buffer.
	int expectedSize = sizeof(unsigned char) * width * height * 1 * channels;
	if (expectedSize != len)
	{
		Nan::ThrowError(Nan::New<String>("Invalid image size, channels or buffer provided.").ToLocalChecked());
		return;
	}

    // TODO: handle CImg exception
    LwipImage * obj = new LwipImage(pixels, width, height, channels);
    obj->Wrap(info.This());
    info.GetReturnValue().Set(info.This());
}

// IMAGE JS OBJECT METHODS:
// ========================

// image.width():
// --------------
NAN_METHOD(LwipImage::width) {
    Nan::HandleScope();
    LwipImage * obj = ObjectWrap::Unwrap<LwipImage>(info.Holder());
    info.GetReturnValue().Set(Nan::New<Number>(obj->_cimg->width()));
}

// image.height():
// ---------------
NAN_METHOD(LwipImage::height) {
    Nan::HandleScope();
    LwipImage * obj = ObjectWrap::Unwrap<LwipImage>(info.Holder());
    info.GetReturnValue().Set(Nan::New<Number>(obj->_cimg->height()));
}

// image.getPixel(left, top):
// ---------------
NAN_METHOD(LwipImage::getPixel) {
    Nan::HandleScope();
    size_t left = (size_t) info[0].As<Number>()->Value();
    size_t top = (size_t) info[1].As<Number>()->Value();
    LwipImage * obj = ObjectWrap::Unwrap<LwipImage>(info.Holder());
    Local<Array> rgba = Nan::New<Array>(4);
    rgba->Set(0, Nan::New((*(obj->_cimg))(left, top, 0, 0))); // red
    rgba->Set(1, Nan::New((*(obj->_cimg))(left, top, 0, 1))); // green
    rgba->Set(2, Nan::New((*(obj->_cimg))(left, top, 0, 2))); // blue
    rgba->Set(3, Nan::New((*(obj->_cimg))(left, top, 0, 3))); // alpha
    info.GetReturnValue().Set(rgba);
}

// image.buffer():
// ---------------
NAN_METHOD(LwipImage::buffer) {
    Nan::HandleScope();
    LwipImage * obj = ObjectWrap::Unwrap<LwipImage>(info.Holder());
    // return a new buffer. don't use same memory an image. make a copy.
    // image object may be gc'ed, but buffer needs to stay alive.
    info.GetReturnValue().Set(Nan::CopyBuffer((char *)obj->_cimg->data(), obj->_cimg->size()).ToLocalChecked());
}

// image.resize(width, height, inter, callback):
// ---------------------------------------------

// info[0] - width
// info[1] - height
// info[2] - inter(polation)
// info[3] - callback
NAN_METHOD(LwipImage::resize) {
    Nan::HandleScope();

    size_t width = info[0].As<Integer>()->Value();
    size_t height = info[1].As<Integer>()->Value();
    int inter = info[2].As<Integer>()->Value();
    Nan::Callback * callback = new Nan::Callback(info[3].As<Function>());
    CImg<unsigned char> * cimg = ObjectWrap::Unwrap<LwipImage>(info.This())->_cimg;

    Nan::AsyncQueueWorker(
        new ResizeWorker(
            width,
            height,
            inter,
            cimg,
            callback
        )
    );

    return;
}

// image.rotate(degs, inter, callback):
// ------------------------------------

// info[0] - degs
// info[1] - R
// info[2] - G
// info[3] - B
// info[4] - A
// info[5] - callback
NAN_METHOD(LwipImage::rotate) {
    Nan::HandleScope();

    float degs = (float) info[0].As<Number>()->Value();
    unsigned char r = (unsigned char) info[1].As<Integer>()->Value();
    unsigned char g = (unsigned char) info[2].As<Integer>()->Value();
    unsigned char b = (unsigned char) info[3].As<Integer>()->Value();
    unsigned char a = (unsigned char) info[4].As<Integer>()->Value();
    Nan::Callback * callback = new Nan::Callback(info[5].As<Function>());
    CImg<unsigned char> * cimg = ObjectWrap::Unwrap<LwipImage>(info.This())->_cimg;

    Nan::AsyncQueueWorker(
        new RotateWorker(
            degs,
            r,
            g,
            b,
            a,
            cimg,
            callback
        )
    );

    return;
}

// image.blur(sigma, callback):
// ----------------------------

// info[0] - sigma
// info[1] - callback
NAN_METHOD(LwipImage::blur) {
    Nan::HandleScope();

    float sigma = (float) info[0].As<Number>()->Value();
    Nan::Callback * callback = new Nan::Callback(info[1].As<Function>());
    CImg<unsigned char> * cimg = ObjectWrap::Unwrap<LwipImage>(info.This())->_cimg;

    Nan::AsyncQueueWorker(
        new BlurWorker(
            sigma,
            cimg,
            callback
        )
    );

    return;
}

// image.crop(left, top, right, bottom, callback):
// -----------------------------------------------

// info[0] - left
// info[1] - top
// info[2] - right
// info[3] - bottom
// info[4] - callback
NAN_METHOD(LwipImage::crop) {
    Nan::HandleScope();

    size_t left = (size_t) info[0].As<Number>()->Value();
    size_t top = (size_t) info[1].As<Number>()->Value();
    size_t right = (size_t) info[2].As<Number>()->Value();
    size_t bottom = (size_t) info[3].As<Number>()->Value();
    Nan::Callback * callback = new Nan::Callback(info[4].As<Function>());
    CImg<unsigned char> * cimg = ObjectWrap::Unwrap<LwipImage>(info.This())->_cimg;

    Nan::AsyncQueueWorker(
        new CropWorker(
            left,
            top,
            right,
            bottom,
            cimg,
            callback
        )
    );

    return;
}

// image.mirror(xaxis, yaxis, callback):
// -----------------------------------------------

// info[0] - xaxis (boolean)
// info[1] - yaxis (boolean)
// info[2] - callback
NAN_METHOD(LwipImage::mirror) {
    Nan::HandleScope();

    bool xaxis = info[0]->BooleanValue();
    bool yaxis = info[1]->BooleanValue();
    Nan::Callback * callback = new Nan::Callback(info[2].As<Function>());
    CImg<unsigned char> * cimg = ObjectWrap::Unwrap<LwipImage>(info.This())->_cimg;

    Nan::AsyncQueueWorker(
        new MirrorWorker(
            xaxis,
            yaxis,
            cimg,
            callback
        )
    );

    return;
}

// image.pad(left, top, right, bottom, color, callback):
// -----------------------------------------------------

// info[0] - left
// info[1] - top
// info[2] - right
// info[3] - bottom
// info[4] - r
// info[5] - g
// info[6] - b
// info[7] - a
// info[8] - callback
NAN_METHOD(LwipImage::pad) {
    Nan::HandleScope();

    size_t left = (size_t) info[0].As<Number>()->Value();
    size_t top = (size_t) info[1].As<Number>()->Value();
    size_t right = (size_t) info[2].As<Number>()->Value();
    size_t bottom = (size_t) info[3].As<Number>()->Value();
    unsigned char r = (unsigned char) info[4].As<Integer>()->Value(),
                  g = (unsigned char) info[5].As<Integer>()->Value(),
                  b = (unsigned char) info[6].As<Integer>()->Value(),
                  a = (unsigned char) info[7].As<Integer>()->Value();
    Nan::Callback * callback = new Nan::Callback(info[8].As<Function>());
    CImg<unsigned char> * cimg = ObjectWrap::Unwrap<LwipImage>(info.This())->_cimg;

    Nan::AsyncQueueWorker(
        new PadWorker(
            left,
            top,
            right,
            bottom,
            r,
            g,
            b,
            a,
            cimg,
            callback
        )
    );

    return;
}

// image.sharpen(amplitude, callback):
// -----------------------------------

// info[0] - amplitude
// info[1] - callback
NAN_METHOD(LwipImage::sharpen) {
    Nan::HandleScope();

    float amp = (float) info[0].As<Number>()->Value();
    Nan::Callback * callback = new Nan::Callback(info[1].As<Function>());
    CImg<unsigned char> * cimg = ObjectWrap::Unwrap<LwipImage>(info.This())->_cimg;

    Nan::AsyncQueueWorker(
        new SharpenWorker(
            amp,
            cimg,
            callback
        )
    );

    return;
}

// image.hslaAdj(hd, sd, ld, callback):
// ------------------------------------

// info[0] - hue delta
// info[1] - saturation delta
// info[2] - lightness delta
// info[3] - alpha delta
// info[4] - callback
NAN_METHOD(LwipImage::hslaAdj) {
    Nan::HandleScope();

    float hd = (float) info[0].As<Number>()->Value();
    float sd = (float) info[1].As<Number>()->Value();
    float ld = (float) info[2].As<Number>()->Value();
    float ad = (float) info[3].As<Number>()->Value();
    Nan::Callback * callback = new Nan::Callback(info[4].As<Function>());
    CImg<unsigned char> * cimg = ObjectWrap::Unwrap<LwipImage>(info.This())->_cimg;

    Nan::AsyncQueueWorker(
        new HSLAWorker(
            hd,
            sd,
            ld,
            ad,
            cimg,
            callback
        )
    );

    return;
}

// image.opacify(callback):
// ------------------------------------

// info[0] - callback
NAN_METHOD(LwipImage::opacify) {
    Nan::HandleScope();

    Nan::Callback * callback = new Nan::Callback(info[0].As<Function>());
    CImg<unsigned char> * cimg = ObjectWrap::Unwrap<LwipImage>(info.This())->_cimg;

    Nan::AsyncQueueWorker(
        new OpacifyWorker(
            cimg,
            callback
        )
    );

    return;
}

// image.paste(callback):
// ------------------------------------

// info[0] - left
// info[1] - top
// info[2] - buffer
// info[3] - width
// info[4] - height
// info[5] - callback
NAN_METHOD(LwipImage::paste) {
    Nan::HandleScope();

    size_t left = (size_t) info[0].As<Number>()->Value();
    size_t top = (size_t) info[1].As<Number>()->Value();
    Local<Object> pixBuff = info[2].As<Object>();
    size_t width = (size_t) info[3].As<Number>()->Value();
    size_t height = (size_t) info[4].As<Number>()->Value();
    Nan::Callback * callback = new Nan::Callback(info[5].As<Function>());
    CImg<unsigned char> * cimg = ObjectWrap::Unwrap<LwipImage>(info.This())->_cimg;

    Nan::AsyncQueueWorker(
        new PasteWorker(
            left,
            top,
            pixBuff,
            width,
            height,
            cimg,
            callback
        )
    );

    return;
}

// image.setPixel(left, top, color, callback):
// -------------------------------------------

// info[0] - left
// info[1] - top
// info[2] - red
// info[3] - green
// info[4] - blue
// info[5] - alpha
// info[6] - callback
NAN_METHOD(LwipImage::setPixel) {
    Nan::HandleScope();

    size_t left = (size_t) info[0].As<Number>()->Value();
    size_t top = (size_t) info[1].As<Number>()->Value();
    unsigned char r = (unsigned char) info[2].As<Integer>()->Value();
    unsigned char g = (unsigned char) info[3].As<Integer>()->Value();
    unsigned char b = (unsigned char) info[4].As<Integer>()->Value();
    unsigned char a = (unsigned char) info[5].As<Integer>()->Value();
    Nan::Callback * callback = new Nan::Callback(info[6].As<Function>());
    CImg<unsigned char> * cimg = ObjectWrap::Unwrap<LwipImage>(info.This())->_cimg;

    Nan::AsyncQueueWorker(
        new SetPixelWorker(
            left,
            top,
            r,
            g,
            b,
            a,
            cimg,
            callback
        )
    );

    return;
}
<commit_msg>Copy of Buffer so that Nan does not free it post Nan 2.0.0<commit_after>#include "image.h"

Nan::Persistent<FunctionTemplate> LwipImage::constructor;

void LwipImage::Init(Handle<Object> exports) {
    // Prepare constructor template
    Local<FunctionTemplate> tpl = Nan::New<FunctionTemplate>(New);
    tpl->InstanceTemplate()->SetInternalFieldCount(1);
    tpl->SetClassName(Nan::New("LwipImage").ToLocalChecked());
    Nan::SetPrototypeMethod(tpl, "width", width);
    Nan::SetPrototypeMethod(tpl, "height", height);
    Nan::SetPrototypeMethod(tpl, "getPixel", getPixel);
    Nan::SetPrototypeMethod(tpl, "buffer", buffer);
    Nan::SetPrototypeMethod(tpl, "resize", resize);
    Nan::SetPrototypeMethod(tpl, "rotate", rotate);
    Nan::SetPrototypeMethod(tpl, "blur", blur);
    Nan::SetPrototypeMethod(tpl, "crop", crop);
    Nan::SetPrototypeMethod(tpl, "mirror", mirror);
    Nan::SetPrototypeMethod(tpl, "pad", pad);
    Nan::SetPrototypeMethod(tpl, "sharpen", sharpen);
    Nan::SetPrototypeMethod(tpl, "hslaAdj", hslaAdj);
    Nan::SetPrototypeMethod(tpl, "opacify", opacify);
    Nan::SetPrototypeMethod(tpl, "paste", paste);
    Nan::SetPrototypeMethod(tpl, "setPixel", setPixel);
    constructor.Reset(tpl);
    exports->Set(
        Nan::New("LwipImage").ToLocalChecked(),
        Nan::New<FunctionTemplate>(constructor)->GetFunction()
    );
}

LwipImage::LwipImage(unsigned char * data, size_t width, size_t height, int channels) {
    // TODO: CImg constructor may throw an exception. handle it in LwipImage::New.
    _cimg = new CImg<unsigned char>(data, width, height, 1, channels, false);
}

LwipImage::~LwipImage() {
    delete _cimg;
};

Handle<Value> LwipImage::NewInstance() {
    Nan::EscapableHandleScope scope;
    Local<FunctionTemplate> constructorHandle = Nan::New<FunctionTemplate>(constructor);
    Local<Object> instance = constructorHandle->GetFunction()->NewInstance();
    return scope.Escape(instance);
}

NAN_METHOD(LwipImage::New) {
    Nan::HandleScope();
    // info[0] - pixels buffer
    // info[1,2] - width and height
    Local<Object> pixBuff = info[0].As<Object>();
    size_t width = Nan::To<uint32_t>(info[1]).FromJust();
	size_t height = Nan::To<uint32_t>(info[2]).FromJust();
    uint32_t channels = Nan::To<uint32_t>(info[3]).FromJust();

	unsigned char * pixels = (unsigned char *)Buffer::Data(pixBuff);
	size_t len = Buffer::Length(pixBuff);

	//CImg expects the size of the buffer to match width*height as it will memcpy this much from buffer.
    //If it doesnt' match buffer length then throw so that CImg does not read past our buffer.
	int expectedSize = sizeof(unsigned char) * width * height * 1 * channels;
	if (expectedSize != len)
	{
		Nan::ThrowError(Nan::New<String>("Invalid image size, channels or buffer provided.").ToLocalChecked());
		return;
	}

    // TODO: handle CImg exception
    LwipImage * obj = new LwipImage(pixels, width, height, channels);
    obj->Wrap(info.This());
    info.GetReturnValue().Set(info.This());
}

// IMAGE JS OBJECT METHODS:
// ========================

// image.width():
// --------------
NAN_METHOD(LwipImage::width) {
    Nan::HandleScope();
    LwipImage * obj = ObjectWrap::Unwrap<LwipImage>(info.Holder());
    info.GetReturnValue().Set(Nan::New<Number>(obj->_cimg->width()));
}

// image.height():
// ---------------
NAN_METHOD(LwipImage::height) {
    Nan::HandleScope();
    LwipImage * obj = ObjectWrap::Unwrap<LwipImage>(info.Holder());
    info.GetReturnValue().Set(Nan::New<Number>(obj->_cimg->height()));
}

// image.getPixel(left, top):
// ---------------
NAN_METHOD(LwipImage::getPixel) {
    Nan::HandleScope();
    size_t left = (size_t) info[0].As<Number>()->Value();
    size_t top = (size_t) info[1].As<Number>()->Value();
    LwipImage * obj = ObjectWrap::Unwrap<LwipImage>(info.Holder());
    Local<Array> rgba = Nan::New<Array>(4);
    rgba->Set(0, Nan::New((*(obj->_cimg))(left, top, 0, 0))); // red
    rgba->Set(1, Nan::New((*(obj->_cimg))(left, top, 0, 1))); // green
    rgba->Set(2, Nan::New((*(obj->_cimg))(left, top, 0, 2))); // blue
    rgba->Set(3, Nan::New((*(obj->_cimg))(left, top, 0, 3))); // alpha
    info.GetReturnValue().Set(rgba);
}

// image.buffer():
// ---------------
NAN_METHOD(LwipImage::buffer) {
    Nan::HandleScope();
    LwipImage * obj = ObjectWrap::Unwrap<LwipImage>(info.Holder());
    // return a new buffer. don't use same memory an image. make a copy.
    // image object may be gc'ed, but buffer needs to stay alive.
    info.GetReturnValue().Set(Nan::CopyBuffer((char *)obj->_cimg->data(), obj->_cimg->size()).ToLocalChecked());
}

// image.resize(width, height, inter, callback):
// ---------------------------------------------

// info[0] - width
// info[1] - height
// info[2] - inter(polation)
// info[3] - callback
NAN_METHOD(LwipImage::resize) {
    Nan::HandleScope();

    size_t width = info[0].As<Integer>()->Value();
    size_t height = info[1].As<Integer>()->Value();
    int inter = info[2].As<Integer>()->Value();
    Nan::Callback * callback = new Nan::Callback(info[3].As<Function>());
    CImg<unsigned char> * cimg = ObjectWrap::Unwrap<LwipImage>(info.This())->_cimg;

    Nan::AsyncQueueWorker(
        new ResizeWorker(
            width,
            height,
            inter,
            cimg,
            callback
        )
    );

    return;
}

// image.rotate(degs, inter, callback):
// ------------------------------------

// info[0] - degs
// info[1] - R
// info[2] - G
// info[3] - B
// info[4] - A
// info[5] - callback
NAN_METHOD(LwipImage::rotate) {
    Nan::HandleScope();

    float degs = (float) info[0].As<Number>()->Value();
    unsigned char r = (unsigned char) info[1].As<Integer>()->Value();
    unsigned char g = (unsigned char) info[2].As<Integer>()->Value();
    unsigned char b = (unsigned char) info[3].As<Integer>()->Value();
    unsigned char a = (unsigned char) info[4].As<Integer>()->Value();
    Nan::Callback * callback = new Nan::Callback(info[5].As<Function>());
    CImg<unsigned char> * cimg = ObjectWrap::Unwrap<LwipImage>(info.This())->_cimg;

    Nan::AsyncQueueWorker(
        new RotateWorker(
            degs,
            r,
            g,
            b,
            a,
            cimg,
            callback
        )
    );

    return;
}

// image.blur(sigma, callback):
// ----------------------------

// info[0] - sigma
// info[1] - callback
NAN_METHOD(LwipImage::blur) {
    Nan::HandleScope();

    float sigma = (float) info[0].As<Number>()->Value();
    Nan::Callback * callback = new Nan::Callback(info[1].As<Function>());
    CImg<unsigned char> * cimg = ObjectWrap::Unwrap<LwipImage>(info.This())->_cimg;

    Nan::AsyncQueueWorker(
        new BlurWorker(
            sigma,
            cimg,
            callback
        )
    );

    return;
}

// image.crop(left, top, right, bottom, callback):
// -----------------------------------------------

// info[0] - left
// info[1] - top
// info[2] - right
// info[3] - bottom
// info[4] - callback
NAN_METHOD(LwipImage::crop) {
    Nan::HandleScope();

    size_t left = (size_t) info[0].As<Number>()->Value();
    size_t top = (size_t) info[1].As<Number>()->Value();
    size_t right = (size_t) info[2].As<Number>()->Value();
    size_t bottom = (size_t) info[3].As<Number>()->Value();
    Nan::Callback * callback = new Nan::Callback(info[4].As<Function>());
    CImg<unsigned char> * cimg = ObjectWrap::Unwrap<LwipImage>(info.This())->_cimg;

    Nan::AsyncQueueWorker(
        new CropWorker(
            left,
            top,
            right,
            bottom,
            cimg,
            callback
        )
    );

    return;
}

// image.mirror(xaxis, yaxis, callback):
// -----------------------------------------------

// info[0] - xaxis (boolean)
// info[1] - yaxis (boolean)
// info[2] - callback
NAN_METHOD(LwipImage::mirror) {
    Nan::HandleScope();

    bool xaxis = info[0]->BooleanValue();
    bool yaxis = info[1]->BooleanValue();
    Nan::Callback * callback = new Nan::Callback(info[2].As<Function>());
    CImg<unsigned char> * cimg = ObjectWrap::Unwrap<LwipImage>(info.This())->_cimg;

    Nan::AsyncQueueWorker(
        new MirrorWorker(
            xaxis,
            yaxis,
            cimg,
            callback
        )
    );

    return;
}

// image.pad(left, top, right, bottom, color, callback):
// -----------------------------------------------------

// info[0] - left
// info[1] - top
// info[2] - right
// info[3] - bottom
// info[4] - r
// info[5] - g
// info[6] - b
// info[7] - a
// info[8] - callback
NAN_METHOD(LwipImage::pad) {
    Nan::HandleScope();

    size_t left = (size_t) info[0].As<Number>()->Value();
    size_t top = (size_t) info[1].As<Number>()->Value();
    size_t right = (size_t) info[2].As<Number>()->Value();
    size_t bottom = (size_t) info[3].As<Number>()->Value();
    unsigned char r = (unsigned char) info[4].As<Integer>()->Value(),
                  g = (unsigned char) info[5].As<Integer>()->Value(),
                  b = (unsigned char) info[6].As<Integer>()->Value(),
                  a = (unsigned char) info[7].As<Integer>()->Value();
    Nan::Callback * callback = new Nan::Callback(info[8].As<Function>());
    CImg<unsigned char> * cimg = ObjectWrap::Unwrap<LwipImage>(info.This())->_cimg;

    Nan::AsyncQueueWorker(
        new PadWorker(
            left,
            top,
            right,
            bottom,
            r,
            g,
            b,
            a,
            cimg,
            callback
        )
    );

    return;
}

// image.sharpen(amplitude, callback):
// -----------------------------------

// info[0] - amplitude
// info[1] - callback
NAN_METHOD(LwipImage::sharpen) {
    Nan::HandleScope();

    float amp = (float) info[0].As<Number>()->Value();
    Nan::Callback * callback = new Nan::Callback(info[1].As<Function>());
    CImg<unsigned char> * cimg = ObjectWrap::Unwrap<LwipImage>(info.This())->_cimg;

    Nan::AsyncQueueWorker(
        new SharpenWorker(
            amp,
            cimg,
            callback
        )
    );

    return;
}

// image.hslaAdj(hd, sd, ld, callback):
// ------------------------------------

// info[0] - hue delta
// info[1] - saturation delta
// info[2] - lightness delta
// info[3] - alpha delta
// info[4] - callback
NAN_METHOD(LwipImage::hslaAdj) {
    Nan::HandleScope();

    float hd = (float) info[0].As<Number>()->Value();
    float sd = (float) info[1].As<Number>()->Value();
    float ld = (float) info[2].As<Number>()->Value();
    float ad = (float) info[3].As<Number>()->Value();
    Nan::Callback * callback = new Nan::Callback(info[4].As<Function>());
    CImg<unsigned char> * cimg = ObjectWrap::Unwrap<LwipImage>(info.This())->_cimg;

    Nan::AsyncQueueWorker(
        new HSLAWorker(
            hd,
            sd,
            ld,
            ad,
            cimg,
            callback
        )
    );

    return;
}

// image.opacify(callback):
// ------------------------------------

// info[0] - callback
NAN_METHOD(LwipImage::opacify) {
    Nan::HandleScope();

    Nan::Callback * callback = new Nan::Callback(info[0].As<Function>());
    CImg<unsigned char> * cimg = ObjectWrap::Unwrap<LwipImage>(info.This())->_cimg;

    Nan::AsyncQueueWorker(
        new OpacifyWorker(
            cimg,
            callback
        )
    );

    return;
}

// image.paste(callback):
// ------------------------------------

// info[0] - left
// info[1] - top
// info[2] - buffer
// info[3] - width
// info[4] - height
// info[5] - callback
NAN_METHOD(LwipImage::paste) {
    Nan::HandleScope();

    size_t left = (size_t) info[0].As<Number>()->Value();
    size_t top = (size_t) info[1].As<Number>()->Value();
    Local<Object> pixBuff = info[2].As<Object>();
    size_t width = (size_t) info[3].As<Number>()->Value();
    size_t height = (size_t) info[4].As<Number>()->Value();
    Nan::Callback * callback = new Nan::Callback(info[5].As<Function>());
    CImg<unsigned char> * cimg = ObjectWrap::Unwrap<LwipImage>(info.This())->_cimg;

    Nan::AsyncQueueWorker(
        new PasteWorker(
            left,
            top,
            pixBuff,
            width,
            height,
            cimg,
            callback
        )
    );

    return;
}

// image.setPixel(left, top, color, callback):
// -------------------------------------------

// info[0] - left
// info[1] - top
// info[2] - red
// info[3] - green
// info[4] - blue
// info[5] - alpha
// info[6] - callback
NAN_METHOD(LwipImage::setPixel) {
    Nan::HandleScope();

    size_t left = (size_t) info[0].As<Number>()->Value();
    size_t top = (size_t) info[1].As<Number>()->Value();
    unsigned char r = (unsigned char) info[2].As<Integer>()->Value();
    unsigned char g = (unsigned char) info[3].As<Integer>()->Value();
    unsigned char b = (unsigned char) info[4].As<Integer>()->Value();
    unsigned char a = (unsigned char) info[5].As<Integer>()->Value();
    Nan::Callback * callback = new Nan::Callback(info[6].As<Function>());
    CImg<unsigned char> * cimg = ObjectWrap::Unwrap<LwipImage>(info.This())->_cimg;

    Nan::AsyncQueueWorker(
        new SetPixelWorker(
            left,
            top,
            r,
            g,
            b,
            a,
            cimg,
            callback
        )
    );

    return;
}
<|endoftext|>


<commit_before>/*
 *
 *
 *  Copyright (c) 2000 Barak Weichselbaum <barak@komodia.com>
 *  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *
 * Contact info:
 * Site: http://www.komodia.com
 * Email: barak@komodia.com
 */

#include "stdafx.h"
#include "UDPSocket.h"

#ifdef _MEMORY_DEBUG
	#define new	   DEBUG_NEW
	#define malloc DEBUG_MALLOC
    static char THIS_FILE[] = __FILE__;
#endif

	KOMODIA_NAMESPACE_START

#define CUDPSocket_Class "CUDPSocket"

CUDPSocket::CUDPSocket() : CSpoofSocket()
{
	try
	{
		SetName(CUDPSocket_Class);
	}
	ERROR_HANDLER("CUDPSocket")
}

CUDPSocket::~CUDPSocket()
{
}

BOOL CUDPSocket::Create()
{
	try
	{
		SetProtocol(IPPROTO_UDP);
		return CSpoofSocket::Create(IPPROTO_UDP);
	}
	ERROR_HANDLER_RETURN("Create",FALSE)
}

BOOL CUDPSocket::Send(int iSourcePort,
					  IP aDestinationAddress,
					  int iDestinationPort,
					  const char* buf,
					  int BufLength)
{
	try
	{
		//Quit if not ok
		if (!CheckSocketValid())
			return FALSE;

		if (isRaw())
		{
			//We can construct the UDP here
			LPUDPHeader lpUDP;
			lpUDP=new UDPHeader;

			//Set the ports
			lpUDP->SourcePort=htons(iSourcePort);
			lpUDP->DestinationPort=htons(iDestinationPort);

			//Set the length
			lpUDP->Length=htons(UDPHeaderLength);

			//Check sum
			lpUDP->Checksum=0;

			BOOL bResult;

			if (BufLength)
			{
				//Create the buffer
				int iTotalLength;
				iTotalLength=UDPHeaderLength+BufLength;

				char* tmpBuf;
				tmpBuf=new char[iTotalLength];

				//Set the length
				lpUDP->Length=htons(iTotalLength);

				memcpy(tmpBuf,lpUDP,UDPHeaderLength);
				memcpy(tmpBuf+UDPHeaderLength,buf,BufLength);

				//Update it
				lpUDP->Checksum=CalculatePseudoChecksum(tmpBuf,iTotalLength,aDestinationAddress,iTotalLength);

				//Recopy it
				memcpy(tmpBuf,lpUDP,UDPHeaderLength);

				//Set the new checksum (if applicateable)
				FinalUDPHeader(lpUDP);

				//Send it
				bResult=CSpoofSocket::Send(aDestinationAddress,tmpBuf,iTotalLength,iDestinationPort);

				//Delete
				delete tmpBuf;
			}
			else
			{
				//Update it
				lpUDP->Checksum=CalculatePseudoChecksum((char*)lpUDP,UDPHeaderLength,aDestinationAddress,UDPHeaderLength);

				//Set the new checksum (if applicateable)
				FinalUDPHeader(lpUDP);

				//Send it
				bResult=CSpoofSocket::Send(aDestinationAddress,(char*)lpUDP,UDPHeaderLength,iDestinationPort);
			}

			//Clean up
			delete lpUDP;

			return bResult;
		}
		else
			return CSpoofSocket::Send(aDestinationAddress,buf,BufLength,iDestinationPort);
	}
	ERROR_HANDLER_RETURN("Send",FALSE)
}

BOOL CUDPSocket::Send(int iSourcePort,
					  LPCSTR lpDestinationAddress,
					  int iDestinationPort,
					  const char* buf,
					  int BufLength)
{
	try
	{
		//Quit if not ok
		if (!CheckSocketValid())
			return FALSE;

		return Send(iSourcePort,inet_addr(lpDestinationAddress),iDestinationPort,buf,BufLength);
	}
	ERROR_HANDLER_RETURN("Send",FALSE)
}

BOOL CUDPSocket::CreateRegular()
{
	try
	{
		SetProtocol(IPPROTO_UDP);
		return CSpoofSocket::Create(IPPROTO_UDP);
	}
	ERROR_HANDLER_RETURN("CreateRegular",FALSE)
}

void CUDPSocket::FinalUDPHeader(LPUDPHeader lpHeader)
{
	//Nothing to do
}

KOMODIA_NAMESPACE_END
<commit_msg>Update UDPSocket.cpp<commit_after>/*
 *
 *  Copyright (c) 2000 Barak Weichselbaum <barak@komodia.com>
 *  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *
 * Contact info:
 * Site: http://www.komodia.com
 * Email: barak@komodia.com
 */

#include "stdafx.h"
#include "UDPSocket.h"

#ifdef _MEMORY_DEBUG
	#define new	   DEBUG_NEW
	#define malloc DEBUG_MALLOC
    static char THIS_FILE[] = __FILE__;
#endif

	KOMODIA_NAMESPACE_START

#define CUDPSocket_Class "CUDPSocket"

CUDPSocket::CUDPSocket() : CSpoofSocket()
{
	try
	{
		SetName(CUDPSocket_Class);
	}
	ERROR_HANDLER("CUDPSocket")
}

CUDPSocket::~CUDPSocket()
{
}

BOOL CUDPSocket::Create()
{
	try
	{
		SetProtocol(IPPROTO_UDP);
		return CSpoofSocket::Create(IPPROTO_UDP);
	}
	ERROR_HANDLER_RETURN("Create",FALSE)
}

BOOL CUDPSocket::Send(int iSourcePort,
					  IP aDestinationAddress,
					  int iDestinationPort,
					  const char* buf,
					  int BufLength)
{
	try
	{
		//Quit if not ok
		if (!CheckSocketValid())
			return FALSE;

		if (isRaw())
		{
			//We can construct the UDP here
			LPUDPHeader lpUDP;
			lpUDP=new UDPHeader;

			//Set the ports
			lpUDP->SourcePort=htons(iSourcePort);
			lpUDP->DestinationPort=htons(iDestinationPort);

			//Set the length
			lpUDP->Length=htons(UDPHeaderLength);

			//Check sum
			lpUDP->Checksum=0;

			BOOL bResult;

			if (BufLength)
			{
				//Create the buffer
				int iTotalLength;
				iTotalLength=UDPHeaderLength+BufLength;

				char* tmpBuf;
				tmpBuf=new char[iTotalLength];

				//Set the length
				lpUDP->Length=htons(iTotalLength);

				memcpy(tmpBuf,lpUDP,UDPHeaderLength);
				memcpy(tmpBuf+UDPHeaderLength,buf,BufLength);

				//Update it
				lpUDP->Checksum=CalculatePseudoChecksum(tmpBuf,iTotalLength,aDestinationAddress,iTotalLength);

				//Recopy it
				memcpy(tmpBuf,lpUDP,UDPHeaderLength);

				//Set the new checksum (if applicateable)
				FinalUDPHeader(lpUDP);

				//Send it
				bResult=CSpoofSocket::Send(aDestinationAddress,tmpBuf,iTotalLength,iDestinationPort);

				//Delete
				delete tmpBuf;
			}
			else
			{
				//Update it
				lpUDP->Checksum=CalculatePseudoChecksum((char*)lpUDP,UDPHeaderLength,aDestinationAddress,UDPHeaderLength);

				//Set the new checksum (if applicateable)
				FinalUDPHeader(lpUDP);

				//Send it
				bResult=CSpoofSocket::Send(aDestinationAddress,(char*)lpUDP,UDPHeaderLength,iDestinationPort);
			}

			//Clean up
			delete lpUDP;

			return bResult;
		}
		else
			return CSpoofSocket::Send(aDestinationAddress,buf,BufLength,iDestinationPort);
	}
	ERROR_HANDLER_RETURN("Send",FALSE)
}

BOOL CUDPSocket::Send(int iSourcePort,
					  LPCSTR lpDestinationAddress,
					  int iDestinationPort,
					  const char* buf,
					  int BufLength)
{
	try
	{
		//Quit if not ok
		if (!CheckSocketValid())
			return FALSE;

		return Send(iSourcePort,inet_addr(lpDestinationAddress),iDestinationPort,buf,BufLength);
	}
	ERROR_HANDLER_RETURN("Send",FALSE)
}

BOOL CUDPSocket::CreateRegular()
{
	try
	{
		SetProtocol(IPPROTO_UDP);
		return CSpoofSocket::Create(IPPROTO_UDP);
	}
	ERROR_HANDLER_RETURN("CreateRegular",FALSE)
}

void CUDPSocket::FinalUDPHeader(LPUDPHeader lpHeader)
{
	//Nothing to do
}

KOMODIA_NAMESPACE_END
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: emfwr.hxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: ihi $ $Date: 2006-11-14 15:41:54 $
 *
 *  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
 *
 ************************************************************************/

#ifndef _EMFWR_HXX
#define _EMFWR_HXX

#include <tools/debug.hxx>
#include <vcl/metaact.hxx>
#include <vcl/graph.hxx>
#include <vcl/gdimtf.hxx>
#include <vcl/virdev.hxx>
#include "fltcall.hxx"

// -------------
// - EMFWriter -
// -------------

class EMFWriter
{
private:

    VirtualDevice       maVDev;
    FilterConfigItem*   mpFilterConfigItem;
    SvStream*           mpStm;
    BOOL*               mpHandlesUsed;
    ULONG               mnHandleCount;
    ULONG               mnLastPercent;
    ULONG               mnRecordCount;
    ULONG               mnRecordPos;
    BOOL                mbRecordOpen;
    BOOL                mbLineChanged;
    sal_uInt32          mnLineHandle;
    BOOL                mbFillChanged;
    sal_uInt32          mnFillHandle;
    BOOL                mbTextChanged;
    sal_uInt32          mnTextHandle;

    void                ImplBeginRecord( sal_uInt32 nType );
    void                ImplEndRecord();

    ULONG               ImplAcquireHandle();
    void                ImplReleaseHandle( ULONG nHandle );

    BOOL                ImplPrepareHandleSelect( sal_uInt32& rHandle, ULONG nSelectType );
    void                ImplCheckLineAttr();
    void                ImplCheckFillAttr();
    void                ImplCheckTextAttr();

    void                ImplWriteColor( const Color& rColor );
    void                ImplWriteRasterOp( RasterOp eRop );
    void                ImplWriteExtent( long nExtent );
    void                ImplWritePoint( const Point& rPoint );
    void                ImplWriteSize( const Size& rSize);
    void                ImplWriteRect( const Rectangle& rRect );
    void                ImplWritePath( const PolyPolygon& rPolyPoly, sal_Bool bClose );
    void                ImplWritePolygonRecord( const Polygon& rPoly, BOOL bClose );
    void                ImplWritePolyPolygonRecord( const PolyPolygon& rPolyPoly );
    void                ImplWriteBmpRecord( const Bitmap& rBmp, const Point& rPt, const Size& rSz, UINT32 nROP );
    void                ImplWriteTextRecord( const Point& rPos, const String rText, const sal_Int32* pDXArray, sal_uInt32 nWidth );

    void                ImplWrite( const GDIMetaFile& rMtf );

public:

                        EMFWriter() {}

    BOOL                WriteEMF( const GDIMetaFile& rMtf, SvStream& rOStm, FilterConfigItem* pConfigItem = NULL );
};

#endif // _EMFWR_HXX
<commit_msg>INTEGRATION: CWS vgbugs07 (1.6.160); FILE MERGED 2007/06/04 13:31:37 vg 1.6.160.1: #i76605# Remove -I .../inc/module hack introduced by hedaburemove01<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: emfwr.hxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: hr $ $Date: 2007-06-27 21:36:42 $
 *
 *  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
 *
 ************************************************************************/

#ifndef _EMFWR_HXX
#define _EMFWR_HXX

#include <tools/debug.hxx>
#include <vcl/metaact.hxx>
#include <vcl/graph.hxx>
#include <vcl/gdimtf.hxx>
#include <vcl/virdev.hxx>
#include <svtools/fltcall.hxx>

// -------------
// - EMFWriter -
// -------------

class EMFWriter
{
private:

    VirtualDevice       maVDev;
    FilterConfigItem*   mpFilterConfigItem;
    SvStream*           mpStm;
    BOOL*               mpHandlesUsed;
    ULONG               mnHandleCount;
    ULONG               mnLastPercent;
    ULONG               mnRecordCount;
    ULONG               mnRecordPos;
    BOOL                mbRecordOpen;
    BOOL                mbLineChanged;
    sal_uInt32          mnLineHandle;
    BOOL                mbFillChanged;
    sal_uInt32          mnFillHandle;
    BOOL                mbTextChanged;
    sal_uInt32          mnTextHandle;

    void                ImplBeginRecord( sal_uInt32 nType );
    void                ImplEndRecord();

    ULONG               ImplAcquireHandle();
    void                ImplReleaseHandle( ULONG nHandle );

    BOOL                ImplPrepareHandleSelect( sal_uInt32& rHandle, ULONG nSelectType );
    void                ImplCheckLineAttr();
    void                ImplCheckFillAttr();
    void                ImplCheckTextAttr();

    void                ImplWriteColor( const Color& rColor );
    void                ImplWriteRasterOp( RasterOp eRop );
    void                ImplWriteExtent( long nExtent );
    void                ImplWritePoint( const Point& rPoint );
    void                ImplWriteSize( const Size& rSize);
    void                ImplWriteRect( const Rectangle& rRect );
    void                ImplWritePath( const PolyPolygon& rPolyPoly, sal_Bool bClose );
    void                ImplWritePolygonRecord( const Polygon& rPoly, BOOL bClose );
    void                ImplWritePolyPolygonRecord( const PolyPolygon& rPolyPoly );
    void                ImplWriteBmpRecord( const Bitmap& rBmp, const Point& rPt, const Size& rSz, UINT32 nROP );
    void                ImplWriteTextRecord( const Point& rPos, const String rText, const sal_Int32* pDXArray, sal_uInt32 nWidth );

    void                ImplWrite( const GDIMetaFile& rMtf );

public:

                        EMFWriter() {}

    BOOL                WriteEMF( const GDIMetaFile& rMtf, SvStream& rOStm, FilterConfigItem* pConfigItem = NULL );
};

#endif // _EMFWR_HXX
<|endoftext|>