<commit_before>// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/basictypes.h"
#include "base/json/json_reader.h"
#include "base/memory/scoped_ptr.h"
#include "content/browser/devtools/renderer_overrides_handler.h"
#include "content/public/browser/devtools_agent_host.h"
#include "content/public/browser/web_contents.h"
#include "content/shell/browser/shell.h"
#include "content/test/content_browser_test.h"
#include "content/test/content_browser_test_utils.h"

namespace content {

class RendererOverridesHandlerTest : public ContentBrowserTest {
 protected:
  scoped_refptr<DevToolsProtocol::Response> SendCommand(
      const std::string& method,
      DictionaryValue* params) {
    scoped_ptr<RendererOverridesHandler> handler(CreateHandler());
    scoped_refptr<DevToolsProtocol::Command> command(
        DevToolsProtocol::CreateCommand(1, method, params));
    return handler->HandleCommand(command);
  }

  void SendAsyncCommand(const std::string& method, DictionaryValue* params) {
    scoped_ptr<RendererOverridesHandler> handler(CreateHandler());
    scoped_refptr<DevToolsProtocol::Command> command(
        DevToolsProtocol::CreateCommand(1, method, params));
    scoped_refptr<DevToolsProtocol::Response> response =
        handler->HandleCommand(command);
    EXPECT_TRUE(response->is_async_promise());
    base::MessageLoop::current()->Run();
  }

  bool HasValue(const std::string& path) {
    base::Value* value = 0;
    return result_->Get(path, &value);
  }

  bool HasListItem(const std::string& path_to_list,
                   const std::string& name,
                   const std::string& value) {
    base::ListValue* list;
    if (!result_->GetList(path_to_list, &list))
      return false;

    for (size_t i = 0; i != list->GetSize(); i++) {
      base::DictionaryValue* item;
      if (!list->GetDictionary(i, &item))
        return false;
      std::string id;
      if (!item->GetString(name, &id))
        return false;
      if (id == value)
        return true;
    }
    return false;
  }

  scoped_ptr<base::DictionaryValue> result_;

 private:
  RendererOverridesHandler* CreateHandler() {
    RenderViewHost* rvh = shell()->web_contents()->GetRenderViewHost();
    DevToolsAgentHost* agent = DevToolsAgentHost::GetOrCreateFor(rvh).get();
    scoped_ptr<RendererOverridesHandler> handler(
        new RendererOverridesHandler(agent));
    handler->SetNotifier(base::Bind(
        &RendererOverridesHandlerTest::OnMessageSent, base::Unretained(this)));
    return handler.release();
  }

  void OnMessageSent(const std::string& message) {
    base::DictionaryValue* root =
        static_cast<base::DictionaryValue*>(base::JSONReader::Read(message));
    base::DictionaryValue* result;
    root->GetDictionary("result", &result);
    result_.reset(result);
    base::MessageLoop::current()->QuitNow();
  }
};

IN_PROC_BROWSER_TEST_F(RendererOverridesHandlerTest, QueryUsageAndQuota) {
  DictionaryValue* params = new DictionaryValue();
  params->SetString("securityOrigin", "http://example.com");
  SendAsyncCommand("Page.queryUsageAndQuota", params);

  EXPECT_TRUE(HasValue("quota.persistent"));
  EXPECT_TRUE(HasValue("quota.temporary"));
  EXPECT_TRUE(HasListItem("usage.temporary", "id", "appcache"));
  EXPECT_TRUE(HasListItem("usage.temporary", "id", "database"));
  EXPECT_TRUE(HasListItem("usage.temporary", "id", "indexeddatabase"));
  EXPECT_TRUE(HasListItem("usage.temporary", "id", "filesystem"));
  EXPECT_TRUE(HasListItem("usage.persistent", "id", "filesystem"));
}

}  // namespace content
<commit_msg>Do not leak a DictionaryValue from RendererOverridesHandlerTest.QueryUsageAndQuota.<commit_after>// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/basictypes.h"
#include "base/json/json_reader.h"
#include "base/memory/scoped_ptr.h"
#include "content/browser/devtools/renderer_overrides_handler.h"
#include "content/public/browser/devtools_agent_host.h"
#include "content/public/browser/web_contents.h"
#include "content/shell/browser/shell.h"
#include "content/test/content_browser_test.h"
#include "content/test/content_browser_test_utils.h"

namespace content {

class RendererOverridesHandlerTest : public ContentBrowserTest {
 protected:
  scoped_refptr<DevToolsProtocol::Response> SendCommand(
      const std::string& method,
      DictionaryValue* params) {
    scoped_ptr<RendererOverridesHandler> handler(CreateHandler());
    scoped_refptr<DevToolsProtocol::Command> command(
        DevToolsProtocol::CreateCommand(1, method, params));
    return handler->HandleCommand(command);
  }

  void SendAsyncCommand(const std::string& method, DictionaryValue* params) {
    scoped_ptr<RendererOverridesHandler> handler(CreateHandler());
    scoped_refptr<DevToolsProtocol::Command> command(
        DevToolsProtocol::CreateCommand(1, method, params));
    scoped_refptr<DevToolsProtocol::Response> response =
        handler->HandleCommand(command);
    EXPECT_TRUE(response->is_async_promise());
    base::MessageLoop::current()->Run();
  }

  bool HasValue(const std::string& path) {
    base::Value* value = 0;
    return result_->Get(path, &value);
  }

  bool HasListItem(const std::string& path_to_list,
                   const std::string& name,
                   const std::string& value) {
    base::ListValue* list;
    if (!result_->GetList(path_to_list, &list))
      return false;

    for (size_t i = 0; i != list->GetSize(); i++) {
      base::DictionaryValue* item;
      if (!list->GetDictionary(i, &item))
        return false;
      std::string id;
      if (!item->GetString(name, &id))
        return false;
      if (id == value)
        return true;
    }
    return false;
  }

  scoped_ptr<base::DictionaryValue> result_;

 private:
  RendererOverridesHandler* CreateHandler() {
    RenderViewHost* rvh = shell()->web_contents()->GetRenderViewHost();
    DevToolsAgentHost* agent = DevToolsAgentHost::GetOrCreateFor(rvh).get();
    scoped_ptr<RendererOverridesHandler> handler(
        new RendererOverridesHandler(agent));
    handler->SetNotifier(base::Bind(
        &RendererOverridesHandlerTest::OnMessageSent, base::Unretained(this)));
    return handler.release();
  }

  void OnMessageSent(const std::string& message) {
    scoped_ptr<base::DictionaryValue> root(
        static_cast<base::DictionaryValue*>(base::JSONReader::Read(message)));
    base::DictionaryValue* result;
    root->GetDictionary("result", &result);
    result_.reset(result->DeepCopy());
    base::MessageLoop::current()->QuitNow();
  }
};

IN_PROC_BROWSER_TEST_F(RendererOverridesHandlerTest, QueryUsageAndQuota) {
  DictionaryValue* params = new DictionaryValue();
  params->SetString("securityOrigin", "http://example.com");
  SendAsyncCommand("Page.queryUsageAndQuota", params);

  EXPECT_TRUE(HasValue("quota.persistent"));
  EXPECT_TRUE(HasValue("quota.temporary"));
  EXPECT_TRUE(HasListItem("usage.temporary", "id", "appcache"));
  EXPECT_TRUE(HasListItem("usage.temporary", "id", "database"));
  EXPECT_TRUE(HasListItem("usage.temporary", "id", "indexeddatabase"));
  EXPECT_TRUE(HasListItem("usage.temporary", "id", "filesystem"));
  EXPECT_TRUE(HasListItem("usage.persistent", "id", "filesystem"));
}

}  // namespace content
<|endoftext|>


<commit_before>// Copyright (c) 2011, Cornell University
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright notice,
//       this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//     * Neither the name of HyperDex nor the names of its contributors may be
//       used to endorse or promote products derived from this software without
//       specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

// POSIX
#include <netinet/in.h>
#include <signal.h>
#include <sys/socket.h>

// Google Log
#include <glog/logging.h>

// po6
#include <po6/net/location.h>

// HyperDex
#include <hyperdex/network_constants.h>

// HyperDaemon
#include "datalayer.h"
#include "logical.h"
#include "network_worker.h"
#include "replication_manager.h"
#include "searches.h"

using hyperdex::entityid;
using hyperdex::network_msgtype;
using hyperdex::network_returncode;

hyperdaemon :: network_worker :: network_worker(datalayer* data,
                                                logical* comm,
                                                searches* ssss,
                                                replication_manager* repl)
    : m_continue(true)
    , m_data(data)
    , m_comm(comm)
    , m_ssss(ssss)
    , m_repl(repl)
{
}

hyperdaemon :: network_worker :: ~network_worker()
{
    if (m_continue)
    {
        m_continue = false;
        LOG(INFO) << "Network worker object not cleanly shutdown.";
    }
}

void
hyperdaemon :: network_worker :: run()
{
    sigset_t ss;

    if (sigfillset(&ss) < 0)
    {
        PLOG(ERROR) << "sigfillset";
        return;
    }

    if (pthread_sigmask(SIG_BLOCK, &ss, NULL) < 0)
    {
        PLOG(ERROR) << "pthread_sigmask";
        return;
    }

    entityid from;
    entityid to;
    network_msgtype type;
    e::buffer msg;
    uint32_t nonce;

    while (m_continue && m_comm->recv(&from, &to, &type, &msg))
    {
        try
        {
            if (type == hyperdex::REQ_GET)
            {
                e::buffer key;
                std::vector<e::buffer> value;
                uint64_t version;
                e::unpacker up(msg.unpack());
                up >> nonce;
                up.leftovers(&key);
                network_returncode result;

                switch (m_data->get(to.get_region(), key, &value, &version))
                {
                    case hyperdisk::SUCCESS:
                        result = hyperdex::NET_SUCCESS;
                        break;
                    case hyperdisk::NOTFOUND:
                        result = hyperdex::NET_NOTFOUND;
                        break;
                    case hyperdisk::WRONGARITY:
                        result = hyperdex::NET_WRONGARITY;
                        break;
                    case hyperdisk::MISSINGDISK:
                        LOG(ERROR) << "GET caused a MISSINGDISK at the data layer.";
                        result = hyperdex::NET_SERVERERROR;
                        break;
                    case hyperdisk::HASHFULL:
                    case hyperdisk::DATAFULL:
                    case hyperdisk::SEARCHFULL:
                    case hyperdisk::SYNCFAILED:
                    case hyperdisk::DROPFAILED:
                    default:
                        LOG(ERROR) << "GET returned unacceptable error code.";
                        result = hyperdex::NET_SERVERERROR;
                        break;
                }

                msg.clear();
                msg.pack() << nonce << static_cast<uint16_t>(result) << value;
                m_comm->send(to, from, hyperdex::RESP_GET, msg);
            }
            else if (type == hyperdex::REQ_PUT)
            {
                e::buffer key;
                std::vector<e::buffer> value;
                msg.unpack() >> nonce >> key >> value;
                m_repl->client_put(from, to.get_region(), nonce, key, value);
            }
            else if (type == hyperdex::REQ_DEL)
            {
                e::buffer key;
                e::unpacker up(msg.unpack());
                up >> nonce;
                up.leftovers(&key);
                m_repl->client_del(from, to.get_region(), nonce, key);
            }
            else if (type == hyperdex::REQ_UPDATE)
            {
                e::buffer key;
                e::bitfield value_mask(0); // This will resize on unpack
                std::vector<e::buffer> value;
                msg.unpack() >> nonce >> key >> value_mask >> value;
                m_repl->client_update(from, to.get_region(), nonce, key, value_mask, value);
            }
            else if (type == hyperdex::REQ_SEARCH_START)
            {
                hyperdex::search s;
                msg.unpack() >> nonce >> s;
                m_ssss->start(from, nonce, to.get_region(), s);
            }
            else if (type == hyperdex::REQ_SEARCH_NEXT)
            {
                msg.unpack() >> nonce;
                m_ssss->next(from, nonce);
            }
            else if (type == hyperdex::REQ_SEARCH_STOP)
            {
                msg.unpack() >> nonce;
                m_ssss->stop(from, nonce);
            }
            else if (type == hyperdex::CHAIN_PUT)
            {
                e::buffer key;
                std::vector<e::buffer> value;
                uint64_t version;
                uint8_t fresh;
                msg.unpack() >> version >> fresh >> key >> value;
                m_repl->chain_put(from, to, version, fresh == 1, key, value);
            }
            else if (type == hyperdex::CHAIN_DEL)
            {
                e::buffer key;
                uint64_t version;
                msg.unpack() >> version >> key;
                m_repl->chain_del(from, to, version, key);
            }
            else if (type == hyperdex::CHAIN_PENDING)
            {
                e::buffer key;
                uint64_t version;
                msg.unpack() >> version >> key;
                m_repl->chain_pending(from, to, version, key);
            }
            else if (type == hyperdex::CHAIN_SUBSPACE)
            {
                uint64_t version;
                e::buffer key;
                std::vector<e::buffer> value;
                uint64_t nextpoint;
                msg.unpack() >> version >> key >> value >> nextpoint;
                m_repl->chain_subspace(from, to, version, key, value, nextpoint);
            }
            else if (type == hyperdex::CHAIN_ACK)
            {
                e::buffer key;
                uint64_t version;
                msg.unpack() >> version >> key;
                m_repl->chain_ack(from, to, version, key);
            }
            else if (type == hyperdex::XFER_MORE)
            {
                m_repl->region_transfer(from, to);
            }
            else if (type == hyperdex::XFER_DONE)
            {
                m_repl->region_transfer_done(from, to);
            }
            else if (type == hyperdex::XFER_DATA)
            {
                uint64_t xfer_num;
                uint8_t op;
                uint64_t version;
                e::buffer key;
                std::vector<e::buffer> value;
                msg.unpack() >> xfer_num >> op >> version >> key >> value;
                m_repl->region_transfer(from, to.subspace, xfer_num,
                                        op == 1, version, key, value);
            }
            else
            {
                LOG(INFO) << "Message of unknown type received.";
            }
        }
        catch (std::out_of_range& e)
        {
            // Unpack error
        }
    }
}

void
hyperdaemon :: network_worker :: shutdown()
{
    // TODO:  This is not the proper shutdown method.  Proper shutdown is a
    // two-stage process, and requires global coordination.
    m_continue = false;
}
<commit_msg>Call trickle from network_workers.<commit_after>// Copyright (c) 2011, Cornell University
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright notice,
//       this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//     * Neither the name of HyperDex nor the names of its contributors may be
//       used to endorse or promote products derived from this software without
//       specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

// POSIX
#include <netinet/in.h>
#include <signal.h>
#include <sys/socket.h>

// Google Log
#include <glog/logging.h>

// po6
#include <po6/net/location.h>

// HyperDex
#include <hyperdex/network_constants.h>

// HyperDaemon
#include "datalayer.h"
#include "logical.h"
#include "network_worker.h"
#include "replication_manager.h"
#include "searches.h"

using hyperdex::entityid;
using hyperdex::network_msgtype;
using hyperdex::network_returncode;

hyperdaemon :: network_worker :: network_worker(datalayer* data,
                                                logical* comm,
                                                searches* ssss,
                                                replication_manager* repl)
    : m_continue(true)
    , m_data(data)
    , m_comm(comm)
    , m_ssss(ssss)
    , m_repl(repl)
{
}

hyperdaemon :: network_worker :: ~network_worker()
{
    if (m_continue)
    {
        m_continue = false;
        LOG(INFO) << "Network worker object not cleanly shutdown.";
    }
}

void
hyperdaemon :: network_worker :: run()
{
    sigset_t ss;

    if (sigfillset(&ss) < 0)
    {
        PLOG(ERROR) << "sigfillset";
        return;
    }

    if (pthread_sigmask(SIG_BLOCK, &ss, NULL) < 0)
    {
        PLOG(ERROR) << "pthread_sigmask";
        return;
    }

    entityid from;
    entityid to;
    network_msgtype type;
    e::buffer msg;
    uint32_t nonce;
    uint64_t count = 0;

    while (m_continue && m_comm->recv(&from, &to, &type, &msg))
    {
        try
        {
            bool trickle = false;

            if (type == hyperdex::REQ_GET)
            {
                e::buffer key;
                std::vector<e::buffer> value;
                uint64_t version;
                e::unpacker up(msg.unpack());
                up >> nonce;
                up.leftovers(&key);
                network_returncode result;

                switch (m_data->get(to.get_region(), key, &value, &version))
                {
                    case hyperdisk::SUCCESS:
                        result = hyperdex::NET_SUCCESS;
                        break;
                    case hyperdisk::NOTFOUND:
                        result = hyperdex::NET_NOTFOUND;
                        break;
                    case hyperdisk::WRONGARITY:
                        result = hyperdex::NET_WRONGARITY;
                        break;
                    case hyperdisk::MISSINGDISK:
                        LOG(ERROR) << "GET caused a MISSINGDISK at the data layer.";
                        result = hyperdex::NET_SERVERERROR;
                        break;
                    case hyperdisk::HASHFULL:
                    case hyperdisk::DATAFULL:
                    case hyperdisk::SEARCHFULL:
                    case hyperdisk::SYNCFAILED:
                    case hyperdisk::DROPFAILED:
                    default:
                        LOG(ERROR) << "GET returned unacceptable error code.";
                        result = hyperdex::NET_SERVERERROR;
                        break;
                }

                msg.clear();
                msg.pack() << nonce << static_cast<uint16_t>(result) << value;
                m_comm->send(to, from, hyperdex::RESP_GET, msg);
            }
            else if (type == hyperdex::REQ_PUT)
            {
                e::buffer key;
                std::vector<e::buffer> value;
                msg.unpack() >> nonce >> key >> value;
                m_repl->client_put(from, to.get_region(), nonce, key, value);
            }
            else if (type == hyperdex::REQ_DEL)
            {
                e::buffer key;
                e::unpacker up(msg.unpack());
                up >> nonce;
                up.leftovers(&key);
                m_repl->client_del(from, to.get_region(), nonce, key);
            }
            else if (type == hyperdex::REQ_UPDATE)
            {
                e::buffer key;
                e::bitfield value_mask(0); // This will resize on unpack
                std::vector<e::buffer> value;
                msg.unpack() >> nonce >> key >> value_mask >> value;
                m_repl->client_update(from, to.get_region(), nonce, key, value_mask, value);
            }
            else if (type == hyperdex::REQ_SEARCH_START)
            {
                hyperdex::search s;
                msg.unpack() >> nonce >> s;
                m_ssss->start(from, nonce, to.get_region(), s);
            }
            else if (type == hyperdex::REQ_SEARCH_NEXT)
            {
                msg.unpack() >> nonce;
                m_ssss->next(from, nonce);
            }
            else if (type == hyperdex::REQ_SEARCH_STOP)
            {
                msg.unpack() >> nonce;
                m_ssss->stop(from, nonce);
            }
            else if (type == hyperdex::CHAIN_PUT)
            {
                e::buffer key;
                std::vector<e::buffer> value;
                uint64_t version;
                uint8_t fresh;
                msg.unpack() >> version >> fresh >> key >> value;
                m_repl->chain_put(from, to, version, fresh == 1, key, value);
            }
            else if (type == hyperdex::CHAIN_DEL)
            {
                e::buffer key;
                uint64_t version;
                msg.unpack() >> version >> key;
                m_repl->chain_del(from, to, version, key);
            }
            else if (type == hyperdex::CHAIN_PENDING)
            {
                e::buffer key;
                uint64_t version;
                msg.unpack() >> version >> key;
                m_repl->chain_pending(from, to, version, key);
            }
            else if (type == hyperdex::CHAIN_SUBSPACE)
            {
                uint64_t version;
                e::buffer key;
                std::vector<e::buffer> value;
                uint64_t nextpoint;
                msg.unpack() >> version >> key >> value >> nextpoint;
                m_repl->chain_subspace(from, to, version, key, value, nextpoint);
            }
            else if (type == hyperdex::CHAIN_ACK)
            {
                e::buffer key;
                uint64_t version;
                msg.unpack() >> version >> key;
                m_repl->chain_ack(from, to, version, key);
                trickle = true;
            }
            else if (type == hyperdex::XFER_MORE)
            {
                m_repl->region_transfer(from, to);
            }
            else if (type == hyperdex::XFER_DONE)
            {
                m_repl->region_transfer_done(from, to);
            }
            else if (type == hyperdex::XFER_DATA)
            {
                uint64_t xfer_num;
                uint8_t op;
                uint64_t version;
                e::buffer key;
                std::vector<e::buffer> value;
                msg.unpack() >> xfer_num >> op >> version >> key >> value;
                m_repl->region_transfer(from, to.subspace, xfer_num,
                                        op == 1, version, key, value);
            }
            else
            {
                LOG(INFO) << "Message of unknown type received.";
            }

            if (trickle)
            {
                ++count;

                if (count % 100000 == 0)
                {
                    m_data->trickle(to.get_region());
                }
            }
        }
        catch (std::out_of_range& e)
        {
            // Unpack error
        }
    }
}

void
hyperdaemon :: network_worker :: shutdown()
{
    // TODO:  This is not the proper shutdown method.  Proper shutdown is a
    // two-stage process, and requires global coordination.
    m_continue = false;
}
<|endoftext|>


<commit_before>#include "deconvolve.hpp"
#include "least-sq.hpp"
#include "util.hpp"
#include "regularizer.hpp"
#include <lbfgs.h>

namespace deconvolution{

template <int D>
struct DeconvolveData {

};

template <int D>
static double deconvolveEvaluate(
        void* instance,
        const double* dualVars,
        double* grad,
        const int n,
        const double step) {
    return 0;
}

static int deconvolveProgress(
        void *instance,
        const double *x,
        const double *g,
        const double fx,
        const double xnorm,
        const double gnorm,
        const double step,
        int n,
        int k,
        int ls) {
    printf("Deconvolve Iteration %d:\n", k);
    printf("  fx = %f", fx);
    printf("  xnorm = %f, gnorm = %f, step = %f\n", xnorm, gnorm, step);
    printf("\n");
    return 0;
}

template <int D>
Array<D> Deconvolve(const Array<D>& y, const LinearSystem<D>& H, const LinearSystem<D>& Ht, const Regularizer<D>& R) {
    Array<D> Ht_y = Ht(y);
    Array<D> x = Ht_y;
    int numPrimalVars = x.num_elements();
    int numLambda = numPrimalVars*R.numSubproblems()*R.numLabels();
    int numDualVars = numLambda + numPrimalVars; // Including all lambda vars + vector nu
    auto dualVars = std::unique_ptr<double>(new double[numDualVars]);
    double* lambda = dualVars.get();
    double* nu = dualVars.get() + numLambda;
    for (int i = 0; i < numLambda; ++i)
        lambda[i] = 0;
    for (int i = 0; i < numPrimalVars; ++i)
        nu[i] = 0;
    LinearSystem<D> Q = [&](const Array<D>& x) -> Array<D> { return Ht(H(x)) + 0.03*x; };
    for (size_t i = 0; i < x.num_elements(); ++i) {
        x.data()[i] = 0;
    }
    leastSquares<D>(Q, Ht_y, x);

    lbfgs_parameter_t params;
    double fVal = 0;
    lbfgs_parameter_init(&params);
    auto algData = DeconvolveData<D>{};
    auto retCode = lbfgs(numDualVars, dualVars.get(), &fVal, deconvolveEvaluate<D>, deconvolveProgress, &algData, &params);
    std::cout << "Deconvolve finished: " << retCode << "\n";

    return x;
}

#define INSTANTIATE_DECONVOLVE(d) \
    template Array<d> Deconvolve<d>(const Array<d>& y, const LinearSystem<d>& H, const LinearSystem<d>& Q, const Regularizer<d>& R);
INSTANTIATE_DECONVOLVE(1)
INSTANTIATE_DECONVOLVE(2)
INSTANTIATE_DECONVOLVE(3)
#undef INSTANTIATE_DECONVOLVE
}
<commit_msg>More filling out definitions in Deconvolve<commit_after>#include "deconvolve.hpp"
#include "least-sq.hpp"
#include "util.hpp"
#include "regularizer.hpp"
#include <lbfgs.h>

namespace deconvolution{

template <int D>
struct DeconvolveData {
    Array<D>& x;
    const Array<D>& Ht_y;
    const LinearSystem<D>& Q;
    const Regularizer<D>& R;
    int numLambda;
};

template <int D>
static double deconvolveEvaluate(
        void* instance,
        const double* dualVars,
        double* grad,
        const int n,
        const double step) {
    auto value = 0.0;
    auto* data = static_cast<DeconvolveData<D>*>(instance);
    const auto& R = data->R;
    auto& x = data->x;
    const auto numPrimalVars = x.num_elements();
    const auto numPerSubproblem = numPrimalVars*R.numSubproblems();

    for (int i = 0; i < n; ++i)
        grad[i] = 0;

    for (int i = 0; i < R.numSubproblems(); ++i)
        value += R.evaluate(i, dualVars+i*numPerSubproblem, 0.001, grad+i*numPerSubproblem);

    return value;
}

static int deconvolveProgress(
        void *instance,
        const double *x,
        const double *g,
        const double fx,
        const double xnorm,
        const double gnorm,
        const double step,
        int n,
        int k,
        int ls) {
    printf("Deconvolve Iteration %d:\n", k);
    printf("  fx = %f", fx);
    printf("  xnorm = %f, gnorm = %f, step = %f\n", xnorm, gnorm, step);
    printf("\n");
    return 0;
}

template <int D>
Array<D> Deconvolve(const Array<D>& y, const LinearSystem<D>& H, const LinearSystem<D>& Ht, const Regularizer<D>& R) {
    Array<D> Ht_y = Ht(y);
    Array<D> x = Ht_y;
    int numPrimalVars = x.num_elements();
    int numLambda = numPrimalVars*R.numSubproblems()*R.numLabels();
    int numDualVars = numLambda + numPrimalVars; // Including all lambda vars + vector nu
    auto dualVars = std::unique_ptr<double>(new double[numDualVars]);
    double* lambda = dualVars.get();
    double* nu = dualVars.get() + numLambda;
    for (int i = 0; i < numLambda; ++i)
        lambda[i] = 0;
    for (int i = 0; i < numPrimalVars; ++i)
        nu[i] = 0;
    LinearSystem<D> Q = [&](const Array<D>& x) -> Array<D> { return Ht(H(x)) + 0.03*x; };
    for (size_t i = 0; i < x.num_elements(); ++i) {
        x.data()[i] = 0;
    }
    leastSquares<D>(Q, Ht_y, x);

    lbfgs_parameter_t params;
    double fVal = 0;
    lbfgs_parameter_init(&params);
    auto algData = DeconvolveData<D>{x, Ht_y, Q, R, numLambda};
    auto retCode = lbfgs(numDualVars, dualVars.get(), &fVal, deconvolveEvaluate<D>, deconvolveProgress, &algData, &params);
    std::cout << "Deconvolve finished: " << retCode << "\n";

    return x;
}

#define INSTANTIATE_DECONVOLVE(d) \
    template Array<d> Deconvolve<d>(const Array<d>& y, const LinearSystem<d>& H, const LinearSystem<d>& Q, const Regularizer<d>& R);
INSTANTIATE_DECONVOLVE(1)
INSTANTIATE_DECONVOLVE(2)
INSTANTIATE_DECONVOLVE(3)
#undef INSTANTIATE_DECONVOLVE
}
<|endoftext|>


<commit_before>// Copyright (C) 2016 xaizek <xaizek@openmailbox.org>
//
// This file is part of uncov.
//
// uncov is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// uncov 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 Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with uncov.  If not, see <http://www.gnu.org/licenses/>.

#include "decoration.hpp"

#include <ostream>

#include "integration.hpp"

namespace {

class Colors
{
public:
    void disable() { isAscii = false; }

    const char * bold () { return isAscii ? "\033[1m" : ""; }
    const char * inv  () { return isAscii ? "\033[7m" : ""; }
    const char * def  () { return isAscii ? "\033[1m\033[0m" : ""; }

    const char * black_fg   () { return isAscii ? "\033[30m" : ""; }
    const char * red_fg     () { return isAscii ? "\033[31m" : ""; }
    const char * green_fg   () { return isAscii ? "\033[32m" : ""; }
    const char * yellow_fg  () { return isAscii ? "\033[33m" : ""; }
    const char * blue_fg    () { return isAscii ? "\033[34m" : ""; }
    const char * magenta_fg () { return isAscii ? "\033[35m" : ""; }
    const char * cyan_fg    () { return isAscii ? "\033[36m" : ""; }
    const char * white_fg   () { return isAscii ? "\033[37m" : ""; }

    const char * black_bg   () { return isAscii ? "\033[40m" : ""; }
    const char * red_bg     () { return isAscii ? "\033[41m" : ""; }
    const char * green_bg   () { return isAscii ? "\033[42m" : ""; }
    const char * yellow_bg  () { return isAscii ? "\033[43m" : ""; }
    const char * blue_bg    () { return isAscii ? "\033[44m" : ""; }
    const char * magenta_bg () { return isAscii ? "\033[45m" : ""; }
    const char * cyan_bg    () { return isAscii ? "\033[46m" : ""; }
    const char * white_bg   () { return isAscii ? "\033[47m" : ""; }

private:
    bool isAscii = isOutputToTerminal();
} C;

}

// Shorten type name to fit into 80 columns limit.
using ostr = std::ostream;

using namespace decor;

const Decoration
    decor::none,
    decor::bold       ([](ostr &os) -> ostr & { return os << C.bold();       }),
    decor::inv        ([](ostr &os) -> ostr & { return os << C.inv();        }),
    decor::def        ([](ostr &os) -> ostr & { return os << C.def();        }),

    decor::black_fg   ([](ostr &os) -> ostr & { return os << C.black_fg();   }),
    decor::red_fg     ([](ostr &os) -> ostr & { return os << C.red_fg();     }),
    decor::green_fg   ([](ostr &os) -> ostr & { return os << C.green_fg();   }),
    decor::yellow_fg  ([](ostr &os) -> ostr & { return os << C.yellow_fg();  }),
    decor::blue_fg    ([](ostr &os) -> ostr & { return os << C.blue_fg();    }),
    decor::magenta_fg ([](ostr &os) -> ostr & { return os << C.magenta_fg(); }),
    decor::cyan_fg    ([](ostr &os) -> ostr & { return os << C.cyan_fg();    }),
    decor::white_fg   ([](ostr &os) -> ostr & { return os << C.white_fg();   }),

    decor::black_bg   ([](ostr &os) -> ostr & { return os << C.black_bg();   }),
    decor::red_bg     ([](ostr &os) -> ostr & { return os << C.red_bg();     }),
    decor::green_bg   ([](ostr &os) -> ostr & { return os << C.green_bg();   }),
    decor::yellow_bg  ([](ostr &os) -> ostr & { return os << C.yellow_bg();  }),
    decor::blue_bg    ([](ostr &os) -> ostr & { return os << C.blue_bg();    }),
    decor::magenta_bg ([](ostr &os) -> ostr & { return os << C.magenta_bg(); }),
    decor::cyan_bg    ([](ostr &os) -> ostr & { return os << C.cyan_bg();    }),
    decor::white_bg   ([](ostr &os) -> ostr & { return os << C.white_bg();   });

Decoration::Decoration(const Decoration &rhs)
    : decorator(rhs.decorator),
      lhs(rhs.lhs == nullptr ? nullptr : new Decoration(*rhs.lhs)),
      rhs(rhs.rhs == nullptr ? nullptr : new Decoration(*rhs.rhs))
{
}

Decoration::Decoration(decorFunc decorator) : decorator(decorator)
{
}

Decoration::Decoration(const Decoration &lhs, const Decoration &rhs)
    : lhs(new Decoration(lhs)),
      rhs(new Decoration(rhs))
{
}

std::ostream &
Decoration::decorate(std::ostream &os) const
{
    if (decorator != nullptr) {
        // Reset and preserve width field, so printing escape sequence doesn't
        // mess up formatting.
        const auto width = os.width({});
        os << decorator;
        static_cast<void>(os.width(width));
        return os;
    }
    if (lhs != nullptr && rhs != nullptr) {
        return os << *lhs << *rhs;
    }
    return os;
}

void
decor::disableDecorations()
{
    C.disable();
}
<commit_msg>Simplify implementation in decoration.cpp<commit_after>// Copyright (C) 2016 xaizek <xaizek@openmailbox.org>
//
// This file is part of uncov.
//
// uncov is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// uncov 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 Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with uncov.  If not, see <http://www.gnu.org/licenses/>.

#include "decoration.hpp"

#include <ostream>

#include "integration.hpp"

namespace {

class ColorsState
{
public:
    void disable() { isAscii = false; }

    const char * operator()(const char text[]) const
    {
        return isAscii ? text : "";
    }

private:
    bool isAscii = isOutputToTerminal();
};

}

// Shorten type name to fit into 80 columns limit.
using ostr = std::ostream;

using namespace decor;

static ColorsState S;

const Decoration
    decor::none,
    decor::bold       ([](ostr &os) -> ostr & { return os << S("\033[1m"); }),
    decor::inv        ([](ostr &os) -> ostr & { return os << S("\033[7m"); }),
    decor::def        ([](ostr &os) -> ostr & { return os << S("\033[0m"); }),

    decor::black_fg   ([](ostr &os) -> ostr & { return os << S("\033[30m"); }),
    decor::red_fg     ([](ostr &os) -> ostr & { return os << S("\033[31m"); }),
    decor::green_fg   ([](ostr &os) -> ostr & { return os << S("\033[32m"); }),
    decor::yellow_fg  ([](ostr &os) -> ostr & { return os << S("\033[33m"); }),
    decor::blue_fg    ([](ostr &os) -> ostr & { return os << S("\033[34m"); }),
    decor::magenta_fg ([](ostr &os) -> ostr & { return os << S("\033[35m"); }),
    decor::cyan_fg    ([](ostr &os) -> ostr & { return os << S("\033[36m"); }),
    decor::white_fg   ([](ostr &os) -> ostr & { return os << S("\033[37m"); }),

    decor::black_bg   ([](ostr &os) -> ostr & { return os << S("\033[40m"); }),
    decor::red_bg     ([](ostr &os) -> ostr & { return os << S("\033[41m"); }),
    decor::green_bg   ([](ostr &os) -> ostr & { return os << S("\033[42m"); }),
    decor::yellow_bg  ([](ostr &os) -> ostr & { return os << S("\033[43m"); }),
    decor::blue_bg    ([](ostr &os) -> ostr & { return os << S("\033[44m"); }),
    decor::magenta_bg ([](ostr &os) -> ostr & { return os << S("\033[45m"); }),
    decor::cyan_bg    ([](ostr &os) -> ostr & { return os << S("\033[46m"); }),
    decor::white_bg   ([](ostr &os) -> ostr & { return os << S("\033[47m"); });

Decoration::Decoration(const Decoration &rhs)
    : decorator(rhs.decorator),
      lhs(rhs.lhs == nullptr ? nullptr : new Decoration(*rhs.lhs)),
      rhs(rhs.rhs == nullptr ? nullptr : new Decoration(*rhs.rhs))
{
}

Decoration::Decoration(decorFunc decorator) : decorator(decorator)
{
}

Decoration::Decoration(const Decoration &lhs, const Decoration &rhs)
    : lhs(new Decoration(lhs)),
      rhs(new Decoration(rhs))
{
}

std::ostream &
Decoration::decorate(std::ostream &os) const
{
    if (decorator != nullptr) {
        // Reset and preserve width field, so printing escape sequence doesn't
        // mess up formatting.
        const auto width = os.width({});
        os << decorator;
        static_cast<void>(os.width(width));
        return os;
    }
    if (lhs != nullptr && rhs != nullptr) {
        return os << *lhs << *rhs;
    }
    return os;
}

void
decor::disableDecorations()
{
    S.disable();
}
<|endoftext|>


<commit_before>/*
 * Diameter.cpp
 *
 *  Created on: 19.02.2014
 *      Author: Daniel Hoske, Christian Staudt
 */

#include <numeric>

#include "Diameter.h"
#include "Eccentricity.h"
#include "../graph/BFS.h"
#include "../graph/Dijkstra.h"
#include "../components/ConnectedComponents.h"
#include "../structures/Partition.h"
#include "../graph/BFS.h"
#include "../auxiliary/Parallel.h"

namespace NetworKit {

edgeweight Diameter::exactDiameter(const Graph& G) {
	using namespace std;

	Aux::SignalHandler handler;

	edgeweight diameter = 0.0;

	if (! G.isWeighted()) {
		std::tie(diameter, std::ignore) = estimatedDiameterRange(G, 0);
	} else {
		 G.forNodes([&](node v) {
			handler.assureRunning();
		 	Dijkstra dijkstra(G, v);
		 	dijkstra.run();
		 	auto distances = dijkstra.getDistances();
		 	for (auto distance : distances) {
		 		if (diameter < distance) {
		 			diameter = distance;
		 		}
		 	}
//			DEBUG("ecc(", v, "): ", *std::max_element(distances.begin(), distances.end()), " of ", distances);
		 });
	}

	if (diameter == std::numeric_limits<edgeweight>::max()) {
		throw std::runtime_error("Graph not connected - diameter is infinite");
	}
	return diameter;
}

std::pair<edgeweight, edgeweight> Diameter::estimatedDiameterRange(const NetworKit::Graph &G, double error) {
	// TODO: make abortable with ctrl+c using SignalHandling code
	if (G.isDirected()) {
		throw std::runtime_error("Error, the diameter of directed graphs cannot be computed yet.");
	}

	Aux::SignalHandler handler;
	/*
	 * This is an implementation of a slightly modified version of the exactSumSweep algorithm as presented in
	 * Fast diameter and radius BFS-based computation in (weakly connected) real-world graphs: With an application to the six degrees of separation games
	 * by Michele Borassi, Pierluigi Crescenzi, Michel Habib, Walter A. Kosters, Andrea Marino, Frank W. Takes
	 * http://www.sciencedirect.com/science/article/pii/S0304397515001644
	 */

	std::vector<count> sum(G.upperNodeIdBound(), 0);
	std::vector<count> eccLowerBound(G.upperNodeIdBound(), 0), eccUpperBound(G.upperNodeIdBound(), std::numeric_limits<count>::max());

	#pragma omp parallel for
	for (node u = 0; u < G.upperNodeIdBound(); ++u) {
		if (!G.hasNode(u)) {
			eccUpperBound[u] = 0;
		}
	}

	std::vector<count> distances(G.upperNodeIdBound(), 0);
	std::vector<bool> finished(G.upperNodeIdBound(), false);
	count k = 4;

	ConnectedComponents comp(G);
	comp.run();
	count numberOfComponents = comp.numberOfComponents();
	std::vector<node> startNodes(numberOfComponents, 0), maxDist(numberOfComponents, 0);
	std::vector<node> firstDeg2Node(numberOfComponents, none);
	std::vector<node> distFirst(numberOfComponents, 0);
	std::vector<node> ecc(numberOfComponents, 0);

	auto updateBounds = [&]() {
		G.parallelForNodes([&](node u) {
			if (finished[u]) return;

			auto c = comp.componentOfNode(u);

			if (distances[u] <= distFirst[c]) {
				eccUpperBound[u] = std::max(distances[u], ecc[c] - distances[u]);
				eccLowerBound[u] = eccUpperBound[u];
				finished[u] = true;
			} else {
				eccUpperBound[u] = std::min(distances[u] + ecc[c] - 2 * distFirst[c], eccUpperBound[u]);
				eccLowerBound[u] = std::max(eccLowerBound[u], distances[u]);
				finished[u] = (eccUpperBound[u] == eccLowerBound[u]);
			}
		});

		ecc.clear();
		ecc.resize(numberOfComponents, 0);
		distFirst.clear();
		distFirst.resize(numberOfComponents, 0);
	};

	auto diameterBounds = [&]() {
		auto maxExact = *Aux::Parallel::max_element(eccLowerBound.begin(), eccLowerBound.end());
		auto maxPotential = *Aux::Parallel::max_element(eccUpperBound.begin(), eccUpperBound.end());
		return std::make_pair(maxExact, maxPotential);
	};

	auto visitNode = [&](node v, count dist) {
		sum[v] += dist;
		distances[v] = dist;

		index c = comp.componentOfNode(v);
		ecc[c] = std::max(dist, ecc[c]);
		if (firstDeg2Node[c] == none && G.degree(v) > 1) {
			firstDeg2Node[c] = v;
			distFirst[c] = dist;
		}
	};

	for (index i = 0; i < k; ++i) {
		handler.assureRunning();
		if (i == 0) {
			std::vector<count> minDeg(numberOfComponents, G.numberOfNodes());

			// for each component, find the node with the minimum degreee and add it as start node
			G.forNodes([&](node v) {
				count d = G.degree(v);
				count c = comp.componentOfNode(v);
				if (d < minDeg[c]) {
					startNodes[c] = v;
					minDeg[c] = d;
				}
			});
		}

		G.BFSfrom(startNodes, [&](node v, count dist) {
			visitNode(v, dist);
			index c = comp.componentOfNode(v);
			if (sum[v] >= maxDist[c]) {
				maxDist[c] = sum[v];
				startNodes[c] = v;
			}
		});

		updateBounds();
	}

	handler.assureRunning();

	std::vector<count> minDist(numberOfComponents, G.numberOfNodes());
	G.forNodes([&](node u) {
		auto c = comp.componentOfNode(u);
		if (sum[u] < minDist[c]) {
			minDist[c] = sum[u];
			startNodes[c] = u;
		}
	});

	handler.assureRunning();

	G.BFSfrom(startNodes, visitNode);
	updateBounds();

	count lb, ub;
	std::tie(lb, ub) = diameterBounds();

	for (index i = 0; i < G.numberOfNodes() && ub > (lb + error*lb); ++i) {
		handler.assureRunning();
		startNodes.clear();
		startNodes.resize(numberOfComponents, none);

		if ((i % 2) == 0) {
			G.forNodes([&](node u) {
				auto c = comp.componentOfNode(u);
				if (startNodes[c] == none || std::tie(eccUpperBound[u], sum[u]) > std::tie(eccUpperBound[startNodes[c]], sum[startNodes[c]])) {
					startNodes[c] = u;
				}
			});
		} else {
			G.forNodes([&](node u) {
				auto c = comp.componentOfNode(u);
				if (startNodes[c] == none || std::tie(eccLowerBound[u], sum[u]) < std::tie(eccLowerBound[startNodes[c]], sum[startNodes[c]])) {
					startNodes[c] = u;
				}
			});
		}

		handler.assureRunning();

		G.BFSfrom(startNodes, visitNode);

		handler.assureRunning();

		updateBounds();

		std::tie(lb, ub) = diameterBounds();
	}

	return {lb, ub};
}

edgeweight Diameter::estimatedVertexDiameter(const Graph& G, count samples) {

	edgeweight infDist = std::numeric_limits<edgeweight>::max();

	// TODO: consider weights

	auto estimateFrom = [&](node v) -> count {
		BFS bfs(G, v);
		bfs.run();
		auto distances = bfs.getDistances();

		// get two largest path lengths
		edgeweight maxD = 0;
		edgeweight maxD2 = 0; // second largest distance
		for (auto d : distances) {
			if ((d != infDist) && (d >= maxD)) {
				maxD2 = maxD;
				maxD = d;
			}
		}

		edgeweight dMax = maxD + maxD2;
		count vd = (count) dMax + 1; 	// count the nodes, not the edges
		return vd;
	};

	edgeweight vdMax = 0;
	#pragma omp parallel for
	for (count i = 0; i < samples; ++i) {
		node u = G.randomNode();
		edgeweight vd = estimateFrom(u);
		DEBUG("sampled vertex diameter from node ", u, ": ", vd);
		#pragma omp critical
		{
			if (vd > vdMax) {
				vdMax = vd;
			}
		}
	}

	return vdMax;

}

edgeweight Diameter::estimatedVertexDiameterPedantic(const Graph& G) {
	count vd = 0;
	if (!G.isWeighted()) {
		std::vector<bool> visited(G.upperNodeIdBound(), false);
		// perform breadth-first searches
		G.forNodes([&](node u) {
			if (visited[u] == false) {
				count maxDist = 0, maxDist2 = 0;
				G.BFSfrom(u, [&](node v, count dist) {
					visited[v] = true;
					if (dist > maxDist) {
						maxDist2 = maxDist;
						maxDist = dist;
					}
					else if (dist > maxDist2) {
						maxDist2 = dist;
					}
				});
				if (maxDist + maxDist2 > vd) {
					vd = maxDist + maxDist2;
				}
				assert (visited[u] == true);
			}
		});
		vd ++; //we need the number of nodes, not the number of edges
	}
	else {
		ConnectedComponents cc(G);
		DEBUG("finding connected components");
		cc.run();
		INFO("Number of components ", cc.numberOfComponents());
		DEBUG("Estimating size of the largest component");
		std::map<count, count> sizes = cc.getComponentSizes();
		count largest_comp_size = 0;
		for(auto it = sizes.cbegin(); it != sizes.cend(); ++it) {
			DEBUG(it->second);
			if (it->second > largest_comp_size) {
				largest_comp_size = it->second;
			}
		}
		INFO("Largest component size: ", largest_comp_size);
		vd = largest_comp_size;
	}
	return vd;
}

} /* namespace NetworKit */
<commit_msg>Diameter: throw on weighted networks<commit_after>/*
 * Diameter.cpp
 *
 *  Created on: 19.02.2014
 *      Author: Daniel Hoske, Christian Staudt
 */

#include <numeric>

#include "Diameter.h"
#include "Eccentricity.h"
#include "../graph/BFS.h"
#include "../graph/Dijkstra.h"
#include "../components/ConnectedComponents.h"
#include "../structures/Partition.h"
#include "../graph/BFS.h"
#include "../auxiliary/Parallel.h"

namespace NetworKit {

edgeweight Diameter::exactDiameter(const Graph& G) {
	using namespace std;

	Aux::SignalHandler handler;

	edgeweight diameter = 0.0;

	if (! G.isWeighted()) {
		std::tie(diameter, std::ignore) = estimatedDiameterRange(G, 0);
	} else {
		 G.forNodes([&](node v) {
			handler.assureRunning();
		 	Dijkstra dijkstra(G, v);
		 	dijkstra.run();
		 	auto distances = dijkstra.getDistances();
		 	for (auto distance : distances) {
		 		if (diameter < distance) {
		 			diameter = distance;
		 		}
		 	}
//			DEBUG("ecc(", v, "): ", *std::max_element(distances.begin(), distances.end()), " of ", distances);
		 });
	}

	if (diameter == std::numeric_limits<edgeweight>::max()) {
		throw std::runtime_error("Graph not connected - diameter is infinite");
	}
	return diameter;
}

std::pair<edgeweight, edgeweight> Diameter::estimatedDiameterRange(const NetworKit::Graph &G, double error) {
	if (G.isDirected() || G.isWeighted()) {
		throw std::runtime_error("Error, the diameter of directed or weighted graphs cannot be computed yet.");
	}

	Aux::SignalHandler handler;
	/*
	 * This is an implementation of a slightly modified version of the exactSumSweep algorithm as presented in
	 * Fast diameter and radius BFS-based computation in (weakly connected) real-world graphs: With an application to the six degrees of separation games
	 * by Michele Borassi, Pierluigi Crescenzi, Michel Habib, Walter A. Kosters, Andrea Marino, Frank W. Takes
	 * http://www.sciencedirect.com/science/article/pii/S0304397515001644
	 */

	std::vector<count> sum(G.upperNodeIdBound(), 0);
	std::vector<count> eccLowerBound(G.upperNodeIdBound(), 0), eccUpperBound(G.upperNodeIdBound(), std::numeric_limits<count>::max());

	#pragma omp parallel for
	for (node u = 0; u < G.upperNodeIdBound(); ++u) {
		if (!G.hasNode(u)) {
			eccUpperBound[u] = 0;
		}
	}

	std::vector<count> distances(G.upperNodeIdBound(), 0);
	std::vector<bool> finished(G.upperNodeIdBound(), false);
	count k = 4;

	ConnectedComponents comp(G);
	comp.run();
	count numberOfComponents = comp.numberOfComponents();
	std::vector<node> startNodes(numberOfComponents, 0), maxDist(numberOfComponents, 0);
	std::vector<node> firstDeg2Node(numberOfComponents, none);
	std::vector<node> distFirst(numberOfComponents, 0);
	std::vector<node> ecc(numberOfComponents, 0);

	auto updateBounds = [&]() {
		G.parallelForNodes([&](node u) {
			if (finished[u]) return;

			auto c = comp.componentOfNode(u);

			if (distances[u] <= distFirst[c]) {
				eccUpperBound[u] = std::max(distances[u], ecc[c] - distances[u]);
				eccLowerBound[u] = eccUpperBound[u];
				finished[u] = true;
			} else {
				eccUpperBound[u] = std::min(distances[u] + ecc[c] - 2 * distFirst[c], eccUpperBound[u]);
				eccLowerBound[u] = std::max(eccLowerBound[u], distances[u]);
				finished[u] = (eccUpperBound[u] == eccLowerBound[u]);
			}
		});

		ecc.clear();
		ecc.resize(numberOfComponents, 0);
		distFirst.clear();
		distFirst.resize(numberOfComponents, 0);
	};

	auto diameterBounds = [&]() {
		auto maxExact = *Aux::Parallel::max_element(eccLowerBound.begin(), eccLowerBound.end());
		auto maxPotential = *Aux::Parallel::max_element(eccUpperBound.begin(), eccUpperBound.end());
		return std::make_pair(maxExact, maxPotential);
	};

	auto visitNode = [&](node v, count dist) {
		sum[v] += dist;
		distances[v] = dist;

		index c = comp.componentOfNode(v);
		ecc[c] = std::max(dist, ecc[c]);
		if (firstDeg2Node[c] == none && G.degree(v) > 1) {
			firstDeg2Node[c] = v;
			distFirst[c] = dist;
		}
	};

	for (index i = 0; i < k; ++i) {
		handler.assureRunning();
		if (i == 0) {
			std::vector<count> minDeg(numberOfComponents, G.numberOfNodes());

			// for each component, find the node with the minimum degreee and add it as start node
			G.forNodes([&](node v) {
				count d = G.degree(v);
				count c = comp.componentOfNode(v);
				if (d < minDeg[c]) {
					startNodes[c] = v;
					minDeg[c] = d;
				}
			});
		}

		G.BFSfrom(startNodes, [&](node v, count dist) {
			visitNode(v, dist);
			index c = comp.componentOfNode(v);
			if (sum[v] >= maxDist[c]) {
				maxDist[c] = sum[v];
				startNodes[c] = v;
			}
		});

		updateBounds();
	}

	handler.assureRunning();

	std::vector<count> minDist(numberOfComponents, G.numberOfNodes());
	G.forNodes([&](node u) {
		auto c = comp.componentOfNode(u);
		if (sum[u] < minDist[c]) {
			minDist[c] = sum[u];
			startNodes[c] = u;
		}
	});

	handler.assureRunning();

	G.BFSfrom(startNodes, visitNode);
	updateBounds();

	count lb, ub;
	std::tie(lb, ub) = diameterBounds();

	for (index i = 0; i < G.numberOfNodes() && ub > (lb + error*lb); ++i) {
		handler.assureRunning();
		startNodes.clear();
		startNodes.resize(numberOfComponents, none);

		if ((i % 2) == 0) {
			G.forNodes([&](node u) {
				auto c = comp.componentOfNode(u);
				if (startNodes[c] == none || std::tie(eccUpperBound[u], sum[u]) > std::tie(eccUpperBound[startNodes[c]], sum[startNodes[c]])) {
					startNodes[c] = u;
				}
			});
		} else {
			G.forNodes([&](node u) {
				auto c = comp.componentOfNode(u);
				if (startNodes[c] == none || std::tie(eccLowerBound[u], sum[u]) < std::tie(eccLowerBound[startNodes[c]], sum[startNodes[c]])) {
					startNodes[c] = u;
				}
			});
		}

		handler.assureRunning();

		G.BFSfrom(startNodes, visitNode);

		handler.assureRunning();

		updateBounds();

		std::tie(lb, ub) = diameterBounds();
	}

	return {lb, ub};
}

edgeweight Diameter::estimatedVertexDiameter(const Graph& G, count samples) {

	edgeweight infDist = std::numeric_limits<edgeweight>::max();

	// TODO: consider weights

	auto estimateFrom = [&](node v) -> count {
		BFS bfs(G, v);
		bfs.run();
		auto distances = bfs.getDistances();

		// get two largest path lengths
		edgeweight maxD = 0;
		edgeweight maxD2 = 0; // second largest distance
		for (auto d : distances) {
			if ((d != infDist) && (d >= maxD)) {
				maxD2 = maxD;
				maxD = d;
			}
		}

		edgeweight dMax = maxD + maxD2;
		count vd = (count) dMax + 1; 	// count the nodes, not the edges
		return vd;
	};

	edgeweight vdMax = 0;
	#pragma omp parallel for
	for (count i = 0; i < samples; ++i) {
		node u = G.randomNode();
		edgeweight vd = estimateFrom(u);
		DEBUG("sampled vertex diameter from node ", u, ": ", vd);
		#pragma omp critical
		{
			if (vd > vdMax) {
				vdMax = vd;
			}
		}
	}

	return vdMax;

}

edgeweight Diameter::estimatedVertexDiameterPedantic(const Graph& G) {
	count vd = 0;
	if (!G.isWeighted()) {
		std::vector<bool> visited(G.upperNodeIdBound(), false);
		// perform breadth-first searches
		G.forNodes([&](node u) {
			if (visited[u] == false) {
				count maxDist = 0, maxDist2 = 0;
				G.BFSfrom(u, [&](node v, count dist) {
					visited[v] = true;
					if (dist > maxDist) {
						maxDist2 = maxDist;
						maxDist = dist;
					}
					else if (dist > maxDist2) {
						maxDist2 = dist;
					}
				});
				if (maxDist + maxDist2 > vd) {
					vd = maxDist + maxDist2;
				}
				assert (visited[u] == true);
			}
		});
		vd ++; //we need the number of nodes, not the number of edges
	}
	else {
		ConnectedComponents cc(G);
		DEBUG("finding connected components");
		cc.run();
		INFO("Number of components ", cc.numberOfComponents());
		DEBUG("Estimating size of the largest component");
		std::map<count, count> sizes = cc.getComponentSizes();
		count largest_comp_size = 0;
		for(auto it = sizes.cbegin(); it != sizes.cend(); ++it) {
			DEBUG(it->second);
			if (it->second > largest_comp_size) {
				largest_comp_size = it->second;
			}
		}
		INFO("Largest component size: ", largest_comp_size);
		vd = largest_comp_size;
	}
	return vd;
}

} /* namespace NetworKit */
<|endoftext|>


<commit_before>// Copyright (c) 2014 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include "atom/browser/web_view_manager.h"

#include "atom/browser/atom_browser_context.h"
#include "content/public/browser/render_process_host.h"

namespace atom {

WebViewManager::WebViewManager() {
}

WebViewManager::~WebViewManager() {
}

void WebViewManager::AddGuest(int guest_instance_id,
                              int element_instance_id,
                              content::WebContents* embedder,
                              content::WebContents* web_contents) {
  web_contents_embedder_map_[guest_instance_id] = { web_contents, embedder };

  // Map the element in embedder to guest.
  int owner_process_id = embedder->GetRenderProcessHost()->GetID();
  ElementInstanceKey key(owner_process_id, element_instance_id);
  element_instance_id_to_guest_map_[key] = guest_instance_id;
}

void WebViewManager::RemoveGuest(int guest_instance_id) {
  if (!ContainsKey(web_contents_embedder_map_, guest_instance_id))
    return;

  web_contents_embedder_map_.erase(guest_instance_id);

  // Remove the record of element in embedder too.
  for (const auto& element : element_instance_id_to_guest_map_)
    if (element.second == guest_instance_id) {
      element_instance_id_to_guest_map_.erase(element.first);
      break;
    }
}

content::WebContents* WebViewManager::GetEmbedder(int guest_instance_id) {
  if (ContainsKey(web_contents_embedder_map_, guest_instance_id))
    return web_contents_embedder_map_[guest_instance_id].embedder;
  else
    return nullptr;
}

content::WebContents* WebViewManager::GetGuestByInstanceID(
    int owner_process_id,
    int element_instance_id) {
  ElementInstanceKey key(owner_process_id, element_instance_id);
  if (!ContainsKey(element_instance_id_to_guest_map_, key))
    return nullptr;

  int guest_instance_id = element_instance_id_to_guest_map_[key];
  if (ContainsKey(web_contents_embedder_map_, guest_instance_id))
    return web_contents_embedder_map_[guest_instance_id].web_contents;
  else
    return nullptr;
}

bool WebViewManager::ForEachGuest(content::WebContents* embedder_web_contents,
                                  const GuestCallback& callback) {
  for (auto& item : web_contents_embedder_map_)
    if (item.second.embedder == embedder_web_contents &&
        callback.Run(item.second.web_contents))
      return true;
  return false;
}

// static
WebViewManager* WebViewManager::GetWebViewManager(
    content::WebContents* web_contents) {
  auto context = web_contents->GetBrowserContext();
  if (context) {
    auto manager = context->GetGuestManager();
    return static_cast<atom::WebViewManager*>(manager);
  } else {
    return nullptr;
  }
}

}  // namespace atom
<commit_msg>Remove redundant atom:: namespace use<commit_after>// Copyright (c) 2014 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include "atom/browser/web_view_manager.h"

#include "atom/browser/atom_browser_context.h"
#include "content/public/browser/render_process_host.h"

namespace atom {

WebViewManager::WebViewManager() {
}

WebViewManager::~WebViewManager() {
}

void WebViewManager::AddGuest(int guest_instance_id,
                              int element_instance_id,
                              content::WebContents* embedder,
                              content::WebContents* web_contents) {
  web_contents_embedder_map_[guest_instance_id] = { web_contents, embedder };

  // Map the element in embedder to guest.
  int owner_process_id = embedder->GetRenderProcessHost()->GetID();
  ElementInstanceKey key(owner_process_id, element_instance_id);
  element_instance_id_to_guest_map_[key] = guest_instance_id;
}

void WebViewManager::RemoveGuest(int guest_instance_id) {
  if (!ContainsKey(web_contents_embedder_map_, guest_instance_id))
    return;

  web_contents_embedder_map_.erase(guest_instance_id);

  // Remove the record of element in embedder too.
  for (const auto& element : element_instance_id_to_guest_map_)
    if (element.second == guest_instance_id) {
      element_instance_id_to_guest_map_.erase(element.first);
      break;
    }
}

content::WebContents* WebViewManager::GetEmbedder(int guest_instance_id) {
  if (ContainsKey(web_contents_embedder_map_, guest_instance_id))
    return web_contents_embedder_map_[guest_instance_id].embedder;
  else
    return nullptr;
}

content::WebContents* WebViewManager::GetGuestByInstanceID(
    int owner_process_id,
    int element_instance_id) {
  ElementInstanceKey key(owner_process_id, element_instance_id);
  if (!ContainsKey(element_instance_id_to_guest_map_, key))
    return nullptr;

  int guest_instance_id = element_instance_id_to_guest_map_[key];
  if (ContainsKey(web_contents_embedder_map_, guest_instance_id))
    return web_contents_embedder_map_[guest_instance_id].web_contents;
  else
    return nullptr;
}

bool WebViewManager::ForEachGuest(content::WebContents* embedder_web_contents,
                                  const GuestCallback& callback) {
  for (auto& item : web_contents_embedder_map_)
    if (item.second.embedder == embedder_web_contents &&
        callback.Run(item.second.web_contents))
      return true;
  return false;
}

// static
WebViewManager* WebViewManager::GetWebViewManager(
    content::WebContents* web_contents) {
  auto context = web_contents->GetBrowserContext();
  if (context) {
    auto manager = context->GetGuestManager();
    return static_cast<WebViewManager*>(manager);
  } else {
    return nullptr;
  }
}

}  // namespace atom
<|endoftext|>


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

    Copyright (c) 2003 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, 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 "koeditorattachments.h"

#include "kocore.h"
#include "urihandler.h"

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

#include <qlayout.h>
#include <qlistview.h>
#include <qpushbutton.h>

KOEditorAttachments::KOEditorAttachments( int spacing, QWidget *parent,
                                          const char *name )
  : QWidget( parent, name )
{
  QBoxLayout *topLayout = new QVBoxLayout( this );
  topLayout->setSpacing( spacing );

  mAttachments = new QListView( this );
  mAttachments->addColumn( i18n("URI") );
  mAttachments->addColumn( i18n("MIME Type") );
  topLayout->addWidget( mAttachments );
  connect( mAttachments, SIGNAL( doubleClicked( QListViewItem * ) ),
           SLOT( showAttachment( QListViewItem * ) ) );

  QBoxLayout *buttonLayout = new QHBoxLayout( topLayout );

  QPushButton *button = new QPushButton( i18n("Add..."), this );
  buttonLayout->addWidget( button );
  connect( button, SIGNAL( clicked() ), SLOT( slotAdd() ) );

  button = new QPushButton( i18n("Edit..."), this );
  buttonLayout->addWidget( button );
  connect( button, SIGNAL( clicked() ), SLOT( slotEdit() ) );

  button = new QPushButton( i18n("Remove"), this );
  buttonLayout->addWidget( button );
  connect( button, SIGNAL( clicked() ), SLOT( slotRemove() ) );

  button = new QPushButton( i18n("Show"), this );
  buttonLayout->addWidget( button );
  connect( button, SIGNAL( clicked() ), SLOT( slotShow() ) );
}

KOEditorAttachments::~KOEditorAttachments()
{
}

void KOEditorAttachments::showAttachment( QListViewItem *item )
{
  if ( !item ) return;

  QString uri = item->text( 0 );

  UriHandler::process( uri );
}

void KOEditorAttachments::slotAdd()
{
  QString uri = KFileDialog::getOpenFileName( QString::null, QString::null,
      0, i18n("Add Attachment") );
  if ( !uri.isEmpty() ) {
    new QListViewItem( mAttachments, uri );
  }
}

void KOEditorAttachments::slotEdit()
{
  QListViewItem *item = mAttachments->currentItem();
  if ( !item ) return;

  QString uri = KFileDialog::getOpenFileName( item->text( 0 ), QString::null,
      0, i18n("Edit Attachment") );

  if ( !uri.isEmpty() ) item->setText( 0, uri );
}

void KOEditorAttachments::slotRemove()
{
  QListViewItem *item = mAttachments->currentItem();
  if ( !item ) return;

  if ( KMessageBox::warningContinueCancel(this,
        i18n("This item will be permanently deleted."),
        i18n("KOrganizer Confirmation"),KGuiItem(i18n("Delete"),"editdelete")) == KMessageBox::Continue )
    delete item;
}

void KOEditorAttachments::slotShow()
{
  showAttachment( mAttachments->currentItem() );
}

void KOEditorAttachments::setDefaults()
{
  mAttachments->clear();
}

void KOEditorAttachments::addAttachment( const QString &uri,
                                         const QString &mimeType )
{
  new QListViewItem( mAttachments, uri, mimeType );
}

void KOEditorAttachments::readIncidence( Incidence *i )
{
  mAttachments->clear();

  Attachment::List attachments = i->attachments();
  Attachment::List::ConstIterator it;
  for( it = attachments.begin(); it != attachments.end(); ++it ) {
    QString uri;
    if ( (*it)->isUri() ) uri = (*it)->uri();
    else uri = i18n("[Binary data]");
    addAttachment( uri, (*it)->mimeType() );
  }
}

void KOEditorAttachments::writeIncidence( Incidence *i )
{
  i->clearAttachments();

  QListViewItem *item;
  for( item = mAttachments->firstChild(); item; item = item->nextSibling() ) {
    i->addAttachment( new Attachment( item->text( 0 ), item->text( 1 ) ) );
  }
}

#include "koeditorattachments.moc"
<commit_msg>Use getOpenURL instead of getOpenFile, which makes it possible to attach remote files.<commit_after>/*
    This file is part of KOrganizer.

    Copyright (c) 2003 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, 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 "koeditorattachments.h"

#include "kocore.h"
#include "urihandler.h"

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

#include <qlayout.h>
#include <qlistview.h>
#include <qpushbutton.h>

KOEditorAttachments::KOEditorAttachments( int spacing, QWidget *parent,
                                          const char *name )
  : QWidget( parent, name )
{
  QBoxLayout *topLayout = new QVBoxLayout( this );
  topLayout->setSpacing( spacing );

  mAttachments = new QListView( this );
  mAttachments->addColumn( i18n("URI") );
  mAttachments->addColumn( i18n("MIME Type") );
  topLayout->addWidget( mAttachments );
  connect( mAttachments, SIGNAL( doubleClicked( QListViewItem * ) ),
           SLOT( showAttachment( QListViewItem * ) ) );

  QBoxLayout *buttonLayout = new QHBoxLayout( topLayout );

  QPushButton *button = new QPushButton( i18n("Add..."), this );
  buttonLayout->addWidget( button );
  connect( button, SIGNAL( clicked() ), SLOT( slotAdd() ) );

  button = new QPushButton( i18n("Edit..."), this );
  buttonLayout->addWidget( button );
  connect( button, SIGNAL( clicked() ), SLOT( slotEdit() ) );

  button = new QPushButton( i18n("Remove"), this );
  buttonLayout->addWidget( button );
  connect( button, SIGNAL( clicked() ), SLOT( slotRemove() ) );

  button = new QPushButton( i18n("Show"), this );
  buttonLayout->addWidget( button );
  connect( button, SIGNAL( clicked() ), SLOT( slotShow() ) );
}

KOEditorAttachments::~KOEditorAttachments()
{
}

void KOEditorAttachments::showAttachment( QListViewItem *item )
{
  if ( !item ) return;

  QString uri = item->text( 0 );

  UriHandler::process( uri );
}

void KOEditorAttachments::slotAdd()
{
  KURL uri = KFileDialog::getOpenURL( QString::null, QString::null,
      0, i18n("Add Attachment") );
  if ( !uri.isEmpty() ) {
    new QListViewItem( mAttachments, uri.url() );
  }
}

void KOEditorAttachments::slotEdit()
{
  QListViewItem *item = mAttachments->currentItem();
  if ( !item ) return;

  KURL uri = KFileDialog::getOpenURL( item->text( 0 ), QString::null,
      0, i18n("Edit Attachment") );

  if ( !uri.isEmpty() ) item->setText( 0, uri.url() );
}

void KOEditorAttachments::slotRemove()
{
  QListViewItem *item = mAttachments->currentItem();
  if ( !item ) return;

  if ( KMessageBox::warningContinueCancel(this,
        i18n("This item will be permanently deleted."),
        i18n("KOrganizer Confirmation"),KGuiItem(i18n("Delete"),"editdelete")) == KMessageBox::Continue )
    delete item;
}

void KOEditorAttachments::slotShow()
{
  showAttachment( mAttachments->currentItem() );
}

void KOEditorAttachments::setDefaults()
{
  mAttachments->clear();
}

void KOEditorAttachments::addAttachment( const QString &uri,
                                         const QString &mimeType )
{
  new QListViewItem( mAttachments, uri, mimeType );
}

void KOEditorAttachments::readIncidence( Incidence *i )
{
  mAttachments->clear();

  Attachment::List attachments = i->attachments();
  Attachment::List::ConstIterator it;
  for( it = attachments.begin(); it != attachments.end(); ++it ) {
    QString uri;
    if ( (*it)->isUri() ) uri = (*it)->uri();
    else uri = i18n("[Binary data]");
    addAttachment( uri, (*it)->mimeType() );
  }
}

void KOEditorAttachments::writeIncidence( Incidence *i )
{
  i->clearAttachments();

  QListViewItem *item;
  for( item = mAttachments->firstChild(); item; item = item->nextSibling() ) {
    i->addAttachment( new Attachment( item->text( 0 ), item->text( 1 ) ) );
  }
}

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


<commit_before>
#pragma once

#include "gmock/gmock.h"
#include "ksp_plugin/manœuvre.hpp"

namespace principia {
namespace ksp_plugin {

template <typename InertialFrame, typename Frame>
class MockManœuvre : public Manœuvre<InertialFrame, Frame>{
 public:
  MockManœuvre(
      Force const& thrust,
      Mass const& initial_mass,
      SpecificImpulse const& specific_impulse,
      Vector<double, Frenet<Frame>> const& direction,
      not_null<std::unique_ptr<DynamicFrame<InertialFrame, Frame> const>> frame)
      : Manœuvre(thrust,
                 initial_mass,
                 specific_impulse,
                 direction,
                 std::move(frame)) {}

  MOCK_CONST_METHOD0_T(InertialDirection, Vector<double, InertialFrame>());

  MOCK_CONST_METHOD0_T(FrenetFrame,
                       OrthogonalMap<Frenet<Frame>, InertialFrame>());
};

}  // namespace ksp_plugin
}  // namespace principia
<commit_msg>standardize<commit_after>
#pragma once

#include "gmock/gmock.h"
#include "ksp_plugin/manœuvre.hpp"

namespace principia {
namespace ksp_plugin {

template <typename InertialFrame, typename Frame>
class MockManœuvre : public Manœuvre<InertialFrame, Frame>{
 public:
  MockManœuvre(
      Force const& thrust,
      Mass const& initial_mass,
      SpecificImpulse const& specific_impulse,
      Vector<double, Frenet<Frame>> const& direction,
      not_null<std::unique_ptr<DynamicFrame<InertialFrame, Frame> const>> frame)
      : Manœuvre<InertialFrame, Frame>(thrust,
                                       initial_mass,
                                       specific_impulse,
                                       direction,
                                       std::move(frame)) {}

  MOCK_CONST_METHOD0_T(InertialDirection, Vector<double, InertialFrame>());

  MOCK_CONST_METHOD0_T(FrenetFrame,
                       OrthogonalMap<Frenet<Frame>, InertialFrame>());
};

}  // namespace ksp_plugin
}  // namespace principia
<|endoftext|>


<commit_before>#include <cmath>
#include <cstdlib>
#include <iostream>
#include <vector>
#include <map>
using namespace std;

const int element_shape_x = 5;
const int element_shape_y = 6;

const int mpi_shape_x = 4;
const int mpi_shape_y = 3;

const int shape_x = element_shape_x * mpi_shape_x;
const int shape_y = element_shape_y * mpi_shape_y;
const int shape_t = 30;

int wrap_x(const int x) {
  return (x+shape_x)%shape_x;
}
int wrap_y(const int y) {
  return (y+shape_y)%shape_y;
}
int irand(const int hi) {
  return floor(rand()/double(RAND_MAX)*hi);
}
enum Direction{
  TP,
  XP,
  XM,
  YP,
  YM
};

struct Region{
  int t,x,y;
  Region(int t,int x,int y) : t(t), x(wrap_x(x)), y(wrap_y(y)) {}

  bool operator==(const Region &other) {
    return other.t==t && other.x==x && other.y==y;
  }
  bool operator!=(const Region &other) {
    return !(*this == other);
  }
  bool operator<(const Region &other) {
    return t<other.t || (t==other.t && (x<other.x || (x==other.x && y<other.y)));
  }
};

ostream& operator<<(ostream& ostr, const Region& r) {
  ostr << "("
       << r.t << ","
       << r.x << ","
       << r.y << ")";
  return ostr;
}

struct Facet{
  Direction d;
  int t,x,y;
  Facet(Direction d,int t,int x,int y) : d(d), t(t), x(wrap_x(x)), y(wrap_y(y)) {}
};

Region random_region() {
  return Region(irand(shape_t), irand(shape_x), irand(shape_y));
}

Region prev_region(const Facet &f) {
  return Region(f.t, f.x, f.y);
}
Region next_region(const Facet &f) {
  switch(f.d) {
  case TP:
    return Region(f.t + 1, f.x, f.y);
  case XP:
    return Region(f.t, f.x + 1, f.y);
  case XM:
    return Region(f.t, f.x - 1, f.y);
  case YP:
    return Region(f.t, f.x, f.y + 1);
  case YM:
    return Region(f.t, f.x, f.y - 1);
  }
}

vector<Facet> prev_facets(const Region &r) {
  vector<Facet> ret(1, Facet(TP, r.t-1, r.x, r.y));
  if (r.t%2 != r.x%2) {
    ret.push_back( Facet(XP, r.t, r.x-1, r.y) );
    ret.push_back( Facet(XM, r.t, r.x+1, r.y) );
  }
  if (r.t%2 != r.y%2) {
    ret.push_back( Facet(YP, r.t, r.x, r.y-1) );
    ret.push_back( Facet(YM, r.t, r.x, r.y+1) );
  }
  return ret;
}
vector<Facet> next_facets(const Region &r) {
  vector<Facet> ret(1, Facet(TP, r.t, r.x, r.y));
  if (r.t%2 == r.x%2) {
    ret.push_back( Facet(XP, r.t, r.x, r.y) );
    ret.push_back( Facet(XM, r.t, r.x, r.y) );
  }
  if (r.t%2 == r.y%2) {
    ret.push_back( Facet(YP, r.t, r.x, r.y) );
    ret.push_back( Facet(YM, r.t, r.x, r.y) );
  }
  return ret;
}

int rank_assingment(const Region &r) {
  int rx = r.x / element_shape_x;
  int ry = r.y / element_shape_y;
  return ry * mpi_shape_x + rx;
}

int main(){
  cout << "ping" << endl;
  cout << "pong" << endl;

  cout << sizeof(Region) << endl;
  cout << sizeof(Facet) << endl;

  for(int i=0;i<1000000; ++i) {
    Region r = random_region();
    vector<Facet> fs = next_facets(r);
    for (int j=0; j< fs.size(); ++j) {
      Facet &f=fs[j];
      if(prev_region(f) != r) {
        cout << "wrong facet " << endl;
        cout << r << endl;
      }
    }
  }

  for(int i=0;i<1000000; ++i) {
    Region r = random_region();
    vector<Facet> fs = prev_facets(r);
    for (int j=0; j< fs.size(); ++j) {
      Facet &f=fs[j];
      if(next_region(f) != r) {
        cout << "wrong facet " << endl;
        cout << r << endl;
        cout << next_region(f) << endl;
        return -1;
      }
    }
  }

  {
    map<int, int> ctr;
    for(int j=0;j<shape_y; ++j) {
      for(int i=0;i<shape_x; ++i) {
        Region r(0,i,j);
        ctr[rank_assingment(r)]++;
      }
    }
    for(map<int,int>::iterator it=ctr.begin(); it!=ctr.end();++it) {
      cout << it->first << " " << it->second << endl;
    }

  }
  return 0;
}
<commit_msg>implemented tests.<commit_after>#include <cmath>
#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>
#include <map>
using namespace std;

const int element_shape_x = 5;
const int element_shape_y = 6;

const int mpi_shape_x = 4;
const int mpi_shape_y = 3;

const int shape_x = element_shape_x * mpi_shape_x;
const int shape_y = element_shape_y * mpi_shape_y;
const int shape_t = 30;

int wrap_x(const int x) {
  return (x+shape_x)%shape_x;
}
int wrap_y(const int y) {
  return (y+shape_y)%shape_y;
}
int irand(const int hi) {
  return floor(rand()/double(RAND_MAX)*hi);
}
enum Direction{
  TP,
  XP,
  XM,
  YP,
  YM
};

struct Region{
  int t,x,y;
  Region(int t,int x,int y) : t(t), x(wrap_x(x)), y(wrap_y(y)) {}

  bool operator==(const Region &other) {
    return other.t==t && other.x==x && other.y==y;
  }
  bool operator!=(const Region &other) {
    return !(*this == other);
  }
  bool operator<(const Region &other) {
    return t<other.t || (t==other.t && (x<other.x || (x==other.x && y<other.y)));
  }
};

ostream& operator<<(ostream& ostr, const Region& r) {
  ostr << "("
       << r.t << ","
       << r.x << ","
       << r.y << ")";
  return ostr;
}

struct Facet{
  Direction d;
  int t,x,y;
  Facet(Direction d,int t,int x,int y) : d(d), t(t), x(wrap_x(x)), y(wrap_y(y)) {}
};

Region random_region() {
  return Region(irand(shape_t), irand(shape_x), irand(shape_y));
}

Region prev_region(const Facet &f) {
  return Region(f.t, f.x, f.y);
}
Region next_region(const Facet &f) {
  switch(f.d) {
  case TP:
    return Region(f.t + 1, f.x, f.y);
  case XP:
    return Region(f.t, f.x + 1, f.y);
  case XM:
    return Region(f.t, f.x - 1, f.y);
  case YP:
    return Region(f.t, f.x, f.y + 1);
  case YM:
    return Region(f.t, f.x, f.y - 1);
  }
}

vector<Facet> prev_facets(const Region &r) {
  vector<Facet> ret;
  if (r.t < shape_t) ret.push_back(Facet(TP, r.t - 1, r.x, r.y));
  if (r.t%2 != r.x%2) {
    ret.push_back( Facet(XP, r.t, r.x-1, r.y) );
    ret.push_back( Facet(XM, r.t, r.x+1, r.y) );
  }
  if (r.t%2 != r.y%2) {
    ret.push_back( Facet(YP, r.t, r.x, r.y-1) );
    ret.push_back( Facet(YM, r.t, r.x, r.y+1) );
  }
  return ret;
}
vector<Facet> next_facets(const Region &r) {
  vector<Facet> ret;
  if (r.t < shape_t -1) ret.push_back(Facet(TP, r.t, r.x, r.y));
  if (r.t%2 == r.x%2) {
    ret.push_back( Facet(XP, r.t, r.x, r.y) );
    ret.push_back( Facet(XM, r.t, r.x, r.y) );
  }
  if (r.t%2 == r.y%2) {
    ret.push_back( Facet(YP, r.t, r.x, r.y) );
    ret.push_back( Facet(YM, r.t, r.x, r.y) );
  }
  return ret;
}

int rank_assingment(const Region &r) {
  int rx = r.x / element_shape_x;
  int ry = r.y / element_shape_y;
  return ry * mpi_shape_x + rx;
}

int test(){
  cout << "ping" << endl;
  cout << "pong" << endl;

  cout << sizeof(Region) << endl;
  cout << sizeof(Facet) << endl;

  for(int i=0;i<1000000; ++i) {
    Region r = random_region();
    vector<Facet> fs = next_facets(r);
    for (int j=0; j< fs.size(); ++j) {
      Facet &f=fs[j];
      if(prev_region(f) != r) {
        cout << "wrong facet " << endl;
        cout << r << endl;
      }
    }
  }

  for(int i=0;i<1000000; ++i) {
    Region r = random_region();
    vector<Facet> fs = prev_facets(r);
    for (int j=0; j< fs.size(); ++j) {
      Facet &f=fs[j];
      if(next_region(f) != r) {
        cout << "wrong facet " << endl;
        cout << r << endl;
        cout << next_region(f) << endl;
        return -1;
      }
    }
  }

  {
    map<int, int> ctr;
    for(int j=0;j<shape_y; ++j) {
      for(int i=0;i<shape_x; ++i) {
        Region r(0,i,j);
        ctr[rank_assingment(r)]++;
      }
    }
    for(map<int,int>::iterator it=ctr.begin(); it!=ctr.end();++it) {
      cout << it->first << " " << it->second << endl;
    }

  }
  return 0;
}

int main(){
  test();
}
<|endoftext|>


<commit_before>/*  This file is part of the KDE project
    Copyright (C) 2006-2007 Matthias Kretz <kretz@kde.org>

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

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

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

*/

#include "mediacontrols.h"

#include <QtCore/QTimer>
#include <QtGui/QAction>
#include <QtGui/QLabel>
#include <QtGui/QDockWidget>
#include <QtGui/QMainWindow>
#include <QtGui/QBoxLayout>
#include <QtGui/QCheckBox>
#include <QtGui/QComboBox>
#include <QtGui/QPushButton>
#include <QtGui/QSlider>

#include <phonon/audiooutput.h>
#include <phonon/backendcapabilities.h>
#include <phonon/effect.h>
#include <phonon/effectwidget.h>
#include <phonon/mediaobject.h>
#include <phonon/path.h>
#include <phonon/videowidget.h>

#include <kaboutdata.h>
#include <kdebug.h>
#include <kfiledialog.h>
#include <kapplication.h>
#include <kcmdlineargs.h>
#include <kicon.h>
#include <kurl.h>

#include <cstdlib>

using Phonon::MediaObject;
using Phonon::MediaSource;
using Phonon::AudioOutput;
using Phonon::VideoWidget;
using Phonon::MediaControls;
using Phonon::Effect;
using Phonon::EffectWidget;

class MediaPlayer : public QMainWindow
{
    Q_OBJECT
    public:
        MediaPlayer();
        void setUrl(const KUrl &url);

    private Q_SLOTS:
        void stateChanged(Phonon::State newstate);
        void workaroundQtBug();
        void getNextUrl();
        void startupReady();
        void openEffectWidget();
        void toggleScaleMode(bool);
        void switchAspectRatio(int x);
        void setBrightness(int b);

    private:
        bool setNextSource();

        QWidget *m_settingsWidget;
        Phonon::MediaObject *m_media;
        Phonon::Path m_apath;
        Phonon::AudioOutput *m_aoutput;
        Phonon::Path m_vpath;
        Phonon::Effect *m_effect;
        Phonon::VideoWidget *m_vwidget;
        Phonon::MediaControls *m_controls;
        Phonon::EffectWidget *m_effectWidget;
        QAction *m_fullScreenAction;
};

MediaPlayer::MediaPlayer()
    : QMainWindow(0), m_effectWidget(0)
{
    QDockWidget *dock = new QDockWidget(this);
    dock->setAllowedAreas(Qt::BottomDockWidgetArea);

    m_settingsWidget = new QWidget(dock);
    dock->setWidget(m_settingsWidget);
    addDockWidget(Qt::BottomDockWidgetArea, dock);

    QVBoxLayout *layout = new QVBoxLayout(m_settingsWidget);

    m_vwidget = new VideoWidget(this);
    setCentralWidget(m_vwidget);

    m_fullScreenAction = new QAction(m_vwidget);
    m_fullScreenAction->setShortcut(Qt::Key_F);
    m_fullScreenAction->setCheckable(true);
    m_fullScreenAction->setChecked(false);
    this->addAction(m_fullScreenAction);
    connect(m_fullScreenAction, SIGNAL(toggled(bool)), m_vwidget, SLOT(setFullScreen(bool)));
    connect(m_fullScreenAction, SIGNAL(toggled(bool)), SLOT(workaroundQtBug()));

    m_aoutput = new AudioOutput(Phonon::VideoCategory, this);

    m_media = new MediaObject(this);
    connect(m_media, SIGNAL(finished()), SLOT(getNextUrl()));
    connect(m_media, SIGNAL(stateChanged(Phonon::State, Phonon::State)), SLOT(stateChanged(Phonon::State)));

    createPath(m_media, m_vwidget);
    m_apath = createPath(m_media, m_aoutput);

    m_controls = new MediaControls(m_settingsWidget);
    layout->addWidget(m_controls);
    m_controls->setMediaObject(m_media);
    m_controls->setAudioOutput(m_aoutput);
    m_controls->setMaximumHeight(28);

    /*
    QList<AudioEffectDescription> effectList = BackendCapabilities::availableAudioEffects();
    if (!effectList.isEmpty())
    {
        m_effect = new AudioEffect(BackendCapabilities::availableAudioEffects().first(), m_apath);
        m_apath->insertEffect(m_effect);
        QPushButton *button = new QPushButton(m_settingsWidget);
        layout->addWidget(button);
        button->setText("configure effect");
        connect(button, SIGNAL(clicked()), SLOT(openEffectWidget()));
    }
    */

    QSlider *slider = new QSlider(m_settingsWidget);
    layout->addWidget(slider);
    slider->setOrientation(Qt::Horizontal);
    slider->setRange(-100, 100);
    slider->setValue(static_cast<int>(m_vwidget->brightness() * 100));
    connect(slider, SIGNAL(valueChanged(int)), this, SLOT(setBrightness(int)));

    QCheckBox *scaleModeCheck = new QCheckBox(m_settingsWidget);
    layout->addWidget(scaleModeCheck);
    connect(scaleModeCheck, SIGNAL(toggled(bool)), SLOT(toggleScaleMode(bool)));

    QWidget *box = new QWidget(m_settingsWidget);
    layout->addWidget(box);

    QLabel *label = new QLabel("Aspect Ratio:", box);
    label->setAlignment(Qt::AlignRight);
    QComboBox *aspectRatioCombo = new QComboBox(box);
    QHBoxLayout *hbox = new QHBoxLayout(box);
    hbox->addWidget(label);
    hbox->addWidget(aspectRatioCombo);
    label->setBuddy(aspectRatioCombo);

    connect(aspectRatioCombo, SIGNAL(currentIndexChanged(int)), SLOT(switchAspectRatio(int)));
    aspectRatioCombo->addItem("auto");
    aspectRatioCombo->addItem("fit");
    aspectRatioCombo->addItem("4:3");
    aspectRatioCombo->addItem("16:9");

    this->resize(width(), height() + 240 - m_vwidget->height());

    QTimer::singleShot(0, this, SLOT(startupReady()));
}

void MediaPlayer::stateChanged(Phonon::State newstate)
{
    switch (newstate) {
    case Phonon::ErrorState:
    case Phonon::StoppedState:
        getNextUrl();
        break;
    default:
        break;
    }
}

void MediaPlayer::workaroundQtBug()
{
    kDebug();
    if (m_vwidget->actions().contains(m_fullScreenAction)) {
        m_vwidget->removeAction(m_fullScreenAction);
        this->addAction(m_fullScreenAction);
    } else {
        this->removeAction(m_fullScreenAction);
        m_vwidget->addAction(m_fullScreenAction);
    }
}

bool MediaPlayer::setNextSource()
{
    QWidget *extraWidget = new QWidget;
    QHBoxLayout *layout = new QHBoxLayout(extraWidget);
    layout->setMargin(0);
    layout->addStretch();
    QPushButton *dvdButton = new QPushButton(i18n("DVD"), extraWidget);
    dvdButton->setCheckable(true);
    dvdButton->setChecked(false);
    layout->addWidget(dvdButton);
    QPushButton *cdButton = new QPushButton(i18n("Audio CD"), extraWidget);
    cdButton->setCheckable(true);
    cdButton->setChecked(false);
    layout->addWidget(cdButton);
    KFileDialog dlg(KUrl(), QString(), 0, extraWidget);
    connect(dvdButton, SIGNAL(toggled(bool)), &dlg, SLOT(accept()));
    connect(cdButton, SIGNAL(toggled(bool)), &dlg, SLOT(accept()));
    dlg.setOperationMode(KFileDialog::Opening);
    dlg.setWindowTitle(i18n("Open"));
    dlg.setMode(KFile::File);
    dlg.exec();
    KUrl url = dlg.selectedUrl();

    if (dvdButton->isChecked()) {
        if (url.isLocalFile()) {
            m_media->setCurrentSource(MediaSource(Phonon::Dvd, url.path()));
        } else {
            m_media->setCurrentSource(Phonon::Dvd);
        }
    } else if (cdButton->isChecked()) {
        m_media->setCurrentSource(Phonon::Cd);
    } else if (url.isValid()) {
        m_media->setCurrentSource(url);
    } else {
        QApplication::instance()->quit();
        return false;
    }
    return true;
}

void MediaPlayer::getNextUrl()
{
    static bool fileDialogAlreadyOpen = false;
    if (fileDialogAlreadyOpen) {
        return;
    }
    fileDialogAlreadyOpen = true;
    if (!setNextSource()) {
        return;
    }
    m_media->play();
    fileDialogAlreadyOpen = false;
}

void MediaPlayer::startupReady()
{
    if (m_media->currentSource().type() == MediaSource::Invalid) {
        if (!setNextSource()) {
            return;
        }
    }
    m_media->play();
}

void MediaPlayer::setBrightness(int b)
{
    m_vwidget->setBrightness(b * 0.01);
}

void MediaPlayer::switchAspectRatio(int x)
{
    m_vwidget->setAspectRatio(static_cast<VideoWidget::AspectRatio>(x));
}

void MediaPlayer::toggleScaleMode(bool mode)
{
    if (mode) {
        m_vwidget->setScaleMode(VideoWidget::ScaleAndCrop);
    } else {
        m_vwidget->setScaleMode(VideoWidget::FitInView);
    }
}

void MediaPlayer::openEffectWidget()
{
    if (!m_effectWidget)
        m_effectWidget = new EffectWidget(m_effect);
    m_effectWidget->show();
    m_effectWidget->raise();
}

void MediaPlayer::setUrl(const KUrl &url)
{
    m_media->setCurrentSource(url);
    //m_vwidget->setVisible(m_media->hasVideo());
}

int main(int argc, char ** argv)
{
    KAboutData about("phononmediaplayer", 0, ki18n("Phonon Media Player"),
            "0.1", ki18n("Media Player"),
            KAboutData::License_GPL);
    about.addAuthor(ki18n("Matthias Kretz"), KLocalizedString(), "kretz@kde.org");

    KCmdLineArgs::init(argc, argv, &about);
    KCmdLineOptions options;
    options.add("+[url]", ki18n("File to play"));
    KCmdLineArgs::addCmdLineOptions( options );

    KApplication app;
    MediaPlayer foo;
    foo.setWindowIcon(KIcon("phonon"));
    foo.show();

    KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
    if (args->count() == 1) {
        KUrl url = args->url(0);
        if (url.isValid()) {
            foo.setUrl(url);
        }
    }
    args->clear();
    return app.exec();
}

#include "mediaplayer.moc"
#include "mediacontrols.cpp"
#include "moc_mediacontrols.cpp"
<commit_msg>Fixed test - had to create dummy QString and KUrl objects to pass to the KFileDialog constructor as file wouldn't compile otherwise.<commit_after>/*  This file is part of the KDE project
    Copyright (C) 2006-2007 Matthias Kretz <kretz@kde.org>

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

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

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

*/

#include "mediacontrols.h"

#include <QtCore/QTimer>
#include <QtGui/QAction>
#include <QtGui/QLabel>
#include <QtGui/QDockWidget>
#include <QtGui/QMainWindow>
#include <QtGui/QBoxLayout>
#include <QtGui/QCheckBox>
#include <QtGui/QComboBox>
#include <QtGui/QPushButton>
#include <QtGui/QSlider>

#include <phonon/audiooutput.h>
#include <phonon/backendcapabilities.h>
#include <phonon/effect.h>
#include <phonon/effectwidget.h>
#include <phonon/mediaobject.h>
#include <phonon/path.h>
#include <phonon/videowidget.h>

#include <kaboutdata.h>
#include <kdebug.h>
#include <kfiledialog.h>
#include <kapplication.h>
#include <kcmdlineargs.h>
#include <kicon.h>
#include <kurl.h>

#include <cstdlib>

using Phonon::MediaObject;
using Phonon::MediaSource;
using Phonon::AudioOutput;
using Phonon::VideoWidget;
using Phonon::MediaControls;
using Phonon::Effect;
using Phonon::EffectWidget;

class MediaPlayer : public QMainWindow
{
    Q_OBJECT
    public:
        MediaPlayer();
        void setUrl(const KUrl &url);

    private Q_SLOTS:
        void stateChanged(Phonon::State newstate);
        void workaroundQtBug();
        void getNextUrl();
        void startupReady();
        void openEffectWidget();
        void toggleScaleMode(bool);
        void switchAspectRatio(int x);
        void setBrightness(int b);

    private:
        bool setNextSource();

        QWidget *m_settingsWidget;
        Phonon::MediaObject *m_media;
        Phonon::Path m_apath;
        Phonon::AudioOutput *m_aoutput;
        Phonon::Path m_vpath;
        Phonon::Effect *m_effect;
        Phonon::VideoWidget *m_vwidget;
        Phonon::MediaControls *m_controls;
        Phonon::EffectWidget *m_effectWidget;
        QAction *m_fullScreenAction;
};

MediaPlayer::MediaPlayer()
    : QMainWindow(0), m_effectWidget(0)
{
    QDockWidget *dock = new QDockWidget(this);
    dock->setAllowedAreas(Qt::BottomDockWidgetArea);

    m_settingsWidget = new QWidget(dock);
    dock->setWidget(m_settingsWidget);
    addDockWidget(Qt::BottomDockWidgetArea, dock);

    QVBoxLayout *layout = new QVBoxLayout(m_settingsWidget);

    m_vwidget = new VideoWidget(this);
    setCentralWidget(m_vwidget);

    m_fullScreenAction = new QAction(m_vwidget);
    m_fullScreenAction->setShortcut(Qt::Key_F);
    m_fullScreenAction->setCheckable(true);
    m_fullScreenAction->setChecked(false);
    this->addAction(m_fullScreenAction);
    connect(m_fullScreenAction, SIGNAL(toggled(bool)), m_vwidget, SLOT(setFullScreen(bool)));
    connect(m_fullScreenAction, SIGNAL(toggled(bool)), SLOT(workaroundQtBug()));

    m_aoutput = new AudioOutput(Phonon::VideoCategory, this);

    m_media = new MediaObject(this);
    connect(m_media, SIGNAL(finished()), SLOT(getNextUrl()));
    connect(m_media, SIGNAL(stateChanged(Phonon::State, Phonon::State)), SLOT(stateChanged(Phonon::State)));

    createPath(m_media, m_vwidget);
    m_apath = createPath(m_media, m_aoutput);

    m_controls = new MediaControls(m_settingsWidget);
    layout->addWidget(m_controls);
    m_controls->setMediaObject(m_media);
    m_controls->setAudioOutput(m_aoutput);
    m_controls->setMaximumHeight(28);

    /*
    QList<AudioEffectDescription> effectList = BackendCapabilities::availableAudioEffects();
    if (!effectList.isEmpty())
    {
        m_effect = new AudioEffect(BackendCapabilities::availableAudioEffects().first(), m_apath);
        m_apath->insertEffect(m_effect);
        QPushButton *button = new QPushButton(m_settingsWidget);
        layout->addWidget(button);
        button->setText("configure effect");
        connect(button, SIGNAL(clicked()), SLOT(openEffectWidget()));
    }
    */

    QSlider *slider = new QSlider(m_settingsWidget);
    layout->addWidget(slider);
    slider->setOrientation(Qt::Horizontal);
    slider->setRange(-100, 100);
    slider->setValue(static_cast<int>(m_vwidget->brightness() * 100));
    connect(slider, SIGNAL(valueChanged(int)), this, SLOT(setBrightness(int)));

    QCheckBox *scaleModeCheck = new QCheckBox(m_settingsWidget);
    layout->addWidget(scaleModeCheck);
    connect(scaleModeCheck, SIGNAL(toggled(bool)), SLOT(toggleScaleMode(bool)));

    QWidget *box = new QWidget(m_settingsWidget);
    layout->addWidget(box);

    QLabel *label = new QLabel("Aspect Ratio:", box);
    label->setAlignment(Qt::AlignRight);
    QComboBox *aspectRatioCombo = new QComboBox(box);
    QHBoxLayout *hbox = new QHBoxLayout(box);
    hbox->addWidget(label);
    hbox->addWidget(aspectRatioCombo);
    label->setBuddy(aspectRatioCombo);

    connect(aspectRatioCombo, SIGNAL(currentIndexChanged(int)), SLOT(switchAspectRatio(int)));
    aspectRatioCombo->addItem("auto");
    aspectRatioCombo->addItem("fit");
    aspectRatioCombo->addItem("4:3");
    aspectRatioCombo->addItem("16:9");

    this->resize(width(), height() + 240 - m_vwidget->height());

    QTimer::singleShot(0, this, SLOT(startupReady()));
}

void MediaPlayer::stateChanged(Phonon::State newstate)
{
    switch (newstate) {
    case Phonon::ErrorState:
    case Phonon::StoppedState:
        getNextUrl();
        break;
    default:
        break;
    }
}

void MediaPlayer::workaroundQtBug()
{
    kDebug();
    if (m_vwidget->actions().contains(m_fullScreenAction)) {
        m_vwidget->removeAction(m_fullScreenAction);
        this->addAction(m_fullScreenAction);
    } else {
        this->removeAction(m_fullScreenAction);
        m_vwidget->addAction(m_fullScreenAction);
    }
}

bool MediaPlayer::setNextSource()
{
    QWidget *extraWidget = new QWidget;
    QHBoxLayout *layout = new QHBoxLayout(extraWidget);
    layout->setMargin(0);
    layout->addStretch();
    QPushButton *dvdButton = new QPushButton(i18n("DVD"), extraWidget);
    dvdButton->setCheckable(true);
    dvdButton->setChecked(false);
    layout->addWidget(dvdButton);
    QPushButton *cdButton = new QPushButton(i18n("Audio CD"), extraWidget);
    cdButton->setCheckable(true);
    cdButton->setChecked(false);
    layout->addWidget(cdButton);
    const QString dummyString;
    const KUrl dummyUrl;
    KFileDialog dlg(dummyUrl, dummyString, 0, extraWidget);
    connect(dvdButton, SIGNAL(toggled(bool)), &dlg, SLOT(accept()));
    connect(cdButton, SIGNAL(toggled(bool)), &dlg, SLOT(accept()));
    dlg.setOperationMode(KFileDialog::Opening);
    dlg.setWindowTitle(i18n("Open"));
    dlg.setMode(KFile::File);
    dlg.exec();
    KUrl url = dlg.selectedUrl();

    if (dvdButton->isChecked()) {
        if (url.isLocalFile()) {
            m_media->setCurrentSource(MediaSource(Phonon::Dvd, url.path()));
        } else {
            m_media->setCurrentSource(Phonon::Dvd);
        }
    } else if (cdButton->isChecked()) {
        m_media->setCurrentSource(Phonon::Cd);
    } else if (url.isValid()) {
        m_media->setCurrentSource(url);
    } else {
        QApplication::instance()->quit();
        return false;
    }
    return true;
}

void MediaPlayer::getNextUrl()
{
    static bool fileDialogAlreadyOpen = false;
    if (fileDialogAlreadyOpen) {
        return;
    }
    fileDialogAlreadyOpen = true;
    if (!setNextSource()) {
        return;
    }
    m_media->play();
    fileDialogAlreadyOpen = false;
}

void MediaPlayer::startupReady()
{
    if (m_media->currentSource().type() == MediaSource::Invalid) {
        if (!setNextSource()) {
            return;
        }
    }
    m_media->play();
}

void MediaPlayer::setBrightness(int b)
{
    m_vwidget->setBrightness(b * 0.01);
}

void MediaPlayer::switchAspectRatio(int x)
{
    m_vwidget->setAspectRatio(static_cast<VideoWidget::AspectRatio>(x));
}

void MediaPlayer::toggleScaleMode(bool mode)
{
    if (mode) {
        m_vwidget->setScaleMode(VideoWidget::ScaleAndCrop);
    } else {
        m_vwidget->setScaleMode(VideoWidget::FitInView);
    }
}

void MediaPlayer::openEffectWidget()
{
    if (!m_effectWidget)
        m_effectWidget = new EffectWidget(m_effect);
    m_effectWidget->show();
    m_effectWidget->raise();
}

void MediaPlayer::setUrl(const KUrl &url)
{
    m_media->setCurrentSource(url);
    //m_vwidget->setVisible(m_media->hasVideo());
}

int main(int argc, char ** argv)
{
    KAboutData about("phononmediaplayer", 0, ki18n("Phonon Media Player"),
            "0.1", ki18n("Media Player"),
            KAboutData::License_GPL);
    about.addAuthor(ki18n("Matthias Kretz"), KLocalizedString(), "kretz@kde.org");

    KCmdLineArgs::init(argc, argv, &about);
    KCmdLineOptions options;
    options.add("+[url]", ki18n("File to play"));
    KCmdLineArgs::addCmdLineOptions( options );

    KApplication app;
    MediaPlayer foo;
    foo.setWindowIcon(KIcon("phonon"));
    foo.show();

    KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
    if (args->count() == 1) {
        KUrl url = args->url(0);
        if (url.isValid()) {
            foo.setUrl(url);
        }
    }
    args->clear();
    return app.exec();
}

#include "mediaplayer.moc"
#include "mediacontrols.cpp"
#include "moc_mediacontrols.cpp"
<|endoftext|>