<commit_before>/**
 * This file is part of node-kdtree, a node.js Addon for working with kd-trees.
 * Copyright (C) 2011 Justin Ethier <justinethier@github>
 *
 * Please use github to submit patches and bug reports:
 * https://github.com/justinethier/node-kdtree
 */

// TODO: publish via npm. see: https://github.com/isaacs/npm/blob/master/doc/developers.md#readme
//
#include <v8.h>
#include <node.h>
#include <node_events.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <kdtree.h>

using namespace v8;
using namespace node;

/**
 * Free memory allocated to the 'data' portion of a node...
 */
void freeNodeData(void *data){
  if (data != NULL) {
    // Release this persistent handle's storage cell
    Persistent<Value> hData = Persistent<Value>::Persistent((Value *)data);
    hData.Dispose();
  }
}

class KDTree : public ObjectWrap {
  public:
    static void
    Initialize (v8::Handle<v8::Object> target){
        HandleScope scope;

        Local<FunctionTemplate> t = FunctionTemplate::New(New);

        t->InstanceTemplate()->SetInternalFieldCount(1);
        t->SetClassName(String::NewSymbol("KDTree"));

        NODE_SET_PROTOTYPE_METHOD(t, "insert", Insert);
        NODE_SET_PROTOTYPE_METHOD(t, "nearest", Nearest);
//        NODE_SET_PROTOTYPE_METHOD(t, "nearestRange", NearestRange); // kd_nearest_range

        target->Set(String::NewSymbol("KDTree"), t->GetFunction());
    }

    /**
     * Insert a set of points into the tree.
     *
     * An optional data argument is present as well;
     * if len == dim_, then the data param will be ignored.
     *
     * @param pos   An array of points
     * @param len   Number of points in the array
     * @param data  Optional data argument
     *
     * @return true if the point was inserted successfully, false otherwise
     */
    bool Insert(const double *pos, int len, Handle<Value> data){
      if (len == dim_)
        return (kd_insert(kd_, pos, NULL) == 0);
      return (kd_insert(kd_, pos, *data) == 0);
    }

    /**
     * Find the point nearest to the given point.
     *
     * @return An array containing the nearest point, or an empty array if no point is found.
     *         If a data element was provided for the nearest point, it will be the last
     *         member of the returned array.
     */
    Handle<Value>
    Nearest(const double *pos){
      int rpos;
      void *pdata;
      kdres *results = kd_nearest(kd_, pos);
      Local<Array> rv = Array::New(dim_ + 1);

      if (results != NULL) {
        double *respos = (double *)(malloc(sizeof(double) * dim_));
        pdata = (void *)kd_res_item(results, respos);

        for(rpos = 0; rpos < dim_; rpos++){
          rv->Set(rpos, Number::New(respos[rpos]));
        }

        // Append data element, if present
        if (pdata != NULL) {
          Persistent<Value> hdata = Persistent<Value>::Persistent((Value *)pdata);
          // TODO: somehow need to dispose of the persistent handle, and perhaps
          // allocate a new var with a local (?) handle
          rv->Set(dim_, hdata);
        }

        free(respos);
        kd_res_free(results);
      }
      return rv;
    }

    /*int Test()
    {
       int i, vcount = 10;
       kdtree *kd;
       kdres *set;
    //   unsigned int msec, start;

       printf("inserting %d random vectors... ", vcount);
       fflush(stdout);

       kd = kd_create(3);

    //   start = get_msec();
       for(i=0; i<vcount; i++) {
               float x, y, z;
               x = ((float)rand() / RAND_MAX) * 200.0 - 100.0;
               y = ((float)rand() / RAND_MAX) * 200.0 - 100.0;
               z = ((float)rand() / RAND_MAX) * 200.0 - 100.0;

               assert(kd_insert3(kd, x, y, z, 0) == 0);
       }
    //   msec = get_msec() - start;
    //   printf("%.3f sec\n", (float)msec / 1000.0);

    //   start = get_msec();
       set = kd_nearest_range3(kd, 0, 0, 0, 100);
    //   msec = get_msec() - start;
    //
       i = kd_res_size(set);
       printf("range query returned %d items\n", kd_res_size(set));
       kd_res_free(set);

       kd_free(kd);
       return i;
    }*/

  protected:

    /**
     * Wrapper for Insert()
     */
    static Handle<Value>
    Insert(const Arguments& args){
        KDTree *kd = ObjectWrap::Unwrap<KDTree>(args.This());
        HandleScope scope;

      double *pos = (double *)(malloc(sizeof(double) * args.Length()));
      for (int i = 0; i < args.Length(); i++){
        pos[i] = args[i]->NumberValue();
      }

      Handle<Value> result = Boolean::New( kd->Insert(pos, args.Length(),
          Persistent<Value>::New(args[ args.Length() - 1])));
            // Test code, just stuff number as data for now...
            // Eventually will want API to allow an optional data arg.
            // If not specified, will default to something (null?)
      free(pos);
      return result;
    }

    /**
     * Wrapper for Nearest()
     */
    static Handle<Value>
    Nearest(const Arguments& args){
      KDTree *kd = ObjectWrap::Unwrap<KDTree>(args.This());
      HandleScope scope;

      double *pos = (double *)(malloc(sizeof(double) * args.Length()));
      for (int i = 0; i < args.Length(); i++){
        pos[i] = args[i]->NumberValue();
      }

      // TODO: may want to pass Length down, so class can assert == dim_
      Handle<Value> result = kd->Nearest(pos);

      free(pos);
      return result;
    }

// TODO:
//    static Handle<Value>
//    NearestRange(const Arguments& args){}

    /**
     *
     */
    static Handle<Value>
    New (const Arguments& args){
        HandleScope scope;

// TODO: an example of how to handle arguments to constructor
//Async *async = new Async(args[0]->Int32Value(), args[1]->Int32Value());

        int dimension = 3; // Default
        if (args.Length() > 0){
          dimension = args[3]->Int32Value();
        }

        KDTree *kd = new KDTree(dimension);
        kd->Wrap(args.This());

        return args.This();
    }

    KDTree (int dim) : ObjectWrap (){
        kd_ = kd_create(dim);
        dim_ = dim;
        kd_data_destructor(kd_, freeNodeData);
    }

    ~KDTree(){
      // TODO: need to call this to clean up allocated 'data' elements
      //       see the kdtree docs:
        if (kd_ != NULL){
            kd_free(kd_);
        }
    }

    /*static Handle<Value>
    Test (const Arguments& args){
        KDTree *kd = ObjectWrap::Unwrap<KDTree>(args.This());

        HandleScope scope;

        int num = kd->Test();

        return Integer::New(num); // Undefined();
    }*/

  private:
    kdtree* kd_;
    int dim_;
};

extern "C" void
init (Handle<Object> target)
{
    HandleScope scope;
    KDTree::Initialize(target);
}

<commit_msg>Removed stale comments, and fixed a bug with the arg that is passed to the KDTree constructor.<commit_after>/**
 * This file is part of node-kdtree, a node.js Addon for working with kd-trees.
 * Copyright (C) 2011 Justin Ethier <justinethier@github>
 *
 * Please use github to submit patches and bug reports:
 * https://github.com/justinethier/node-kdtree
 */

// TODO: publish via npm. see: https://github.com/isaacs/npm/blob/master/doc/developers.md#readme
//
#include <v8.h>
#include <node.h>
#include <node_events.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <kdtree.h>

using namespace v8;
using namespace node;

/**
 * Free memory allocated to the 'data' portion of a node...
 */
void freeNodeData(void *data){
  if (data != NULL) {
    // Release this persistent handle's storage cell
    Persistent<Value> hData = Persistent<Value>::Persistent((Value *)data);
    hData.Dispose();
  }
}

class KDTree : public ObjectWrap {
  public:
    static void
    Initialize (v8::Handle<v8::Object> target){
        HandleScope scope;

        Local<FunctionTemplate> t = FunctionTemplate::New(New);

        t->InstanceTemplate()->SetInternalFieldCount(1);
        t->SetClassName(String::NewSymbol("KDTree"));

        NODE_SET_PROTOTYPE_METHOD(t, "insert", Insert);
        NODE_SET_PROTOTYPE_METHOD(t, "nearest", Nearest);
//        NODE_SET_PROTOTYPE_METHOD(t, "nearestRange", NearestRange); // kd_nearest_range

        target->Set(String::NewSymbol("KDTree"), t->GetFunction());
    }

    /**
     * Insert a set of points into the tree.
     *
     * An optional data argument is present as well;
     * if len == dim_, then the data param will be ignored.
     *
     * @param pos   An array of points
     * @param len   Number of points in the array
     * @param data  Optional data argument
     *
     * @return true if the point was inserted successfully, false otherwise
     */
    bool Insert(const double *pos, int len, Handle<Value> data){
      if (len == dim_)
        return (kd_insert(kd_, pos, NULL) == 0);
      return (kd_insert(kd_, pos, *data) == 0);
    }

    /**
     * Find the point nearest to the given point.
     *
     * @return An array containing the nearest point, or an empty array if no point is found.
     *         If a data element was provided for the nearest point, it will be the last
     *         member of the returned array.
     */
    Handle<Value>
    Nearest(const double *pos){
      int rpos;
      void *pdata;
      kdres *results = kd_nearest(kd_, pos);
      Local<Array> rv = Array::New(dim_ + 1);

      if (results != NULL) {
        double *respos = (double *)(malloc(sizeof(double) * dim_));
        pdata = (void *)kd_res_item(results, respos);

        for(rpos = 0; rpos < dim_; rpos++){
          rv->Set(rpos, Number::New(respos[rpos]));
        }

        // Append data element, if present
        if (pdata != NULL) {
          Persistent<Value> hdata = Persistent<Value>::Persistent((Value *)pdata);
          rv->Set(dim_, hdata);
        }

        free(respos);
        kd_res_free(results);
      }
      return rv;
    }

    /*int Test()
    {
       int i, vcount = 10;
       kdtree *kd;
       kdres *set;
    //   unsigned int msec, start;

       printf("inserting %d random vectors... ", vcount);
       fflush(stdout);

       kd = kd_create(3);

    //   start = get_msec();
       for(i=0; i<vcount; i++) {
               float x, y, z;
               x = ((float)rand() / RAND_MAX) * 200.0 - 100.0;
               y = ((float)rand() / RAND_MAX) * 200.0 - 100.0;
               z = ((float)rand() / RAND_MAX) * 200.0 - 100.0;

               assert(kd_insert3(kd, x, y, z, 0) == 0);
       }
    //   msec = get_msec() - start;
    //   printf("%.3f sec\n", (float)msec / 1000.0);

    //   start = get_msec();
       set = kd_nearest_range3(kd, 0, 0, 0, 100);
    //   msec = get_msec() - start;
    //
       i = kd_res_size(set);
       printf("range query returned %d items\n", kd_res_size(set));
       kd_res_free(set);

       kd_free(kd);
       return i;
    }*/

  protected:

    /**
     * Wrapper for Insert()
     */
    static Handle<Value>
    Insert(const Arguments& args){
        KDTree *kd = ObjectWrap::Unwrap<KDTree>(args.This());
        HandleScope scope;

      double *pos = (double *)(malloc(sizeof(double) * args.Length()));
      for (int i = 0; i < args.Length(); i++){
        pos[i] = args[i]->NumberValue();
      }

      Handle<Value> result = Boolean::New( kd->Insert(pos, args.Length(),
          Persistent<Value>::New(args[ args.Length() - 1])));
            // Test code, just stuff number as data for now...
            // Eventually will want API to allow an optional data arg.
            // If not specified, will default to something (null?)
      free(pos);
      return result;
    }

    /**
     * Wrapper for Nearest()
     */
    static Handle<Value>
    Nearest(const Arguments& args){
      KDTree *kd = ObjectWrap::Unwrap<KDTree>(args.This());
      HandleScope scope;

      double *pos = (double *)(malloc(sizeof(double) * args.Length()));
      for (int i = 0; i < args.Length(); i++){
        pos[i] = args[i]->NumberValue();
      }

      // TODO: may want to pass Length down, so class can assert == dim_
      Handle<Value> result = kd->Nearest(pos);

      free(pos);
      return result;
    }

// TODO:
//    static Handle<Value>
//    NearestRange(const Arguments& args){}

    /**
     *
     */
    static Handle<Value>
    New (const Arguments& args){
        HandleScope scope;

        int dimension = 3; // Default
        if (args.Length() > 0){
          dimension = args[0]->Int32Value();
        }

        KDTree *kd = new KDTree(dimension);
        kd->Wrap(args.This());

        return args.This();
    }

    KDTree (int dim) : ObjectWrap (){
        kd_ = kd_create(dim);
        dim_ = dim;
        kd_data_destructor(kd_, freeNodeData);
    }

    ~KDTree(){
        if (kd_ != NULL){
            kd_free(kd_);
        }
    }

    /*static Handle<Value>
    Test (const Arguments& args){
        KDTree *kd = ObjectWrap::Unwrap<KDTree>(args.This());

        HandleScope scope;

        int num = kd->Test();

        return Integer::New(num); // Undefined();
    }*/

  private:
    kdtree* kd_;
    int dim_;
};

extern "C" void
init (Handle<Object> target)
{
    HandleScope scope;
    KDTree::Initialize(target);
}

<|endoftext|>


<commit_before>/**
   @file gyroscopeadaptor.cpp
   @brief GyroscopeAdaptor based on SysfsAdaptor

   Copyright (C) 2009-2010 Nokia Corporation

   @author Timo Rongas <ext-timo.2.rongas@nokia.com>
   @author Samuli Piippo <ext-samuli.1.piippo@nokia.com>
   @author Antti Virtanen <antti.i.virtanen@nokia.com>
   @author Pia Niemelä <pia.s.niemela@nokia.com>

   This file is part of Sensord.

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

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

   You should have received a copy of the GNU Lesser General Public
   License along with Sensord.  If not, see <http://www.gnu.org/licenses/>.

*/
#include <errno.h>

#include "logging.h"
#include "config.h"
#include "datatypes/utils.h"

#include "gyroscopeadaptor.h"

GyroscopeAdaptor::GyroscopeAdaptor(const QString& id) :
    SysfsAdaptor(id, SysfsAdaptor::SelectMode)
{

    QString path = Config::configuration()->value("gyroscope_sysfs_path").toString();
    if ( !addPath(path, 0) ) {
        setValid(false);
    }

    gyroscopeBuffer_ = new DeviceAdaptorRingBuffer<TimedXyzData>(32);
    setAdaptedSensor("gyroscope", "l3g4200dh", gyroscopeBuffer_);

    introduceAvailableDataRange(DataRange(-250000, 250000, 1));
    setDescription("Sysfs Gyroscope adaptor (l3g4200dh)");

    introduceAvailableInterval(DataRange(1.25, 1000, 1));  // [1,800] Hz
    setDefaultInterval(10); // 100 Hz

}

GyroscopeAdaptor::~GyroscopeAdaptor()
{
    delete gyroscopeBuffer_;
}

void GyroscopeAdaptor::processSample(int pathId, int fd)
{
    Q_UNUSED(pathId);
    short x, y, z;
    char buf[32];

    if (read(fd, buf, sizeof(buf)) <= 0) {
        sensordLogW() << "read():" << strerror(errno);
        return;
    }
    sensordLogT() << "gyroscope output value: " << buf;

    sscanf(buf, "%hd %hd %hd\n", &x, &y, &z);

    TimedXyzData* pos = gyroscopeBuffer_->nextSlot();
    pos->x_ = x;
    pos->y_ = y;
    pos->z_ = z;
    pos->timestamp_ = Utils::getTimeStamp();

    gyroscopeBuffer_->commit();
    gyroscopeBuffer_->wakeUpReaders();
}

bool GyroscopeAdaptor::setInterval(const unsigned int value, const int sessionId)
{
    return SysfsAdaptor::setInterval(value, sessionId);
}

unsigned int GyroscopeAdaptor::interval() const{
    return SysfsAdaptor::interval();
}

<commit_msg>discrete interval values<commit_after>/**
   @file gyroscopeadaptor.cpp
   @brief GyroscopeAdaptor based on SysfsAdaptor

   Copyright (C) 2009-2010 Nokia Corporation

   @author Timo Rongas <ext-timo.2.rongas@nokia.com>
   @author Samuli Piippo <ext-samuli.1.piippo@nokia.com>
   @author Antti Virtanen <antti.i.virtanen@nokia.com>
   @author Pia Niemelä <pia.s.niemela@nokia.com>

   This file is part of Sensord.

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

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

   You should have received a copy of the GNU Lesser General Public
   License along with Sensord.  If not, see <http://www.gnu.org/licenses/>.

*/
#include <errno.h>

#include "logging.h"
#include "config.h"
#include "datatypes/utils.h"

#include "gyroscopeadaptor.h"

GyroscopeAdaptor::GyroscopeAdaptor(const QString& id) :
    SysfsAdaptor(id, SysfsAdaptor::SelectMode)
{

    QString path = Config::configuration()->value("gyroscope_sysfs_path").toString();
    if ( !addPath(path, 0) ) {
        setValid(false);
    }

    gyroscopeBuffer_ = new DeviceAdaptorRingBuffer<TimedXyzData>(32);
    setAdaptedSensor("gyroscope", "l3g4200dh", gyroscopeBuffer_);

    introduceAvailableDataRange(DataRange(-250000, 250000, 1));
    setDescription("Sysfs Gyroscope adaptor (l3g4200dh)");

    introduceAvailableInterval(DataRange(100, 100, 1));     // 10 Hz
    introduceAvailableInterval(DataRange(25, 25, 1));       // 40 Hz
    introduceAvailableInterval(DataRange(10, 10, 1));       // 100 Hz
    introduceAvailableInterval(DataRange(5, 5, 1));         // 200 Hz
    introduceAvailableInterval(DataRange(2.5, 2.5, 1));     // 400 Hz
    introduceAvailableInterval(DataRange(1.25, 1.25, 1));   // 800 Hz
    setDefaultInterval(10); // 100 Hz

}

GyroscopeAdaptor::~GyroscopeAdaptor()
{
    delete gyroscopeBuffer_;
}

void GyroscopeAdaptor::processSample(int pathId, int fd)
{
    Q_UNUSED(pathId);
    short x, y, z;
    char buf[32];

    if (read(fd, buf, sizeof(buf)) <= 0) {
        sensordLogW() << "read():" << strerror(errno);
        return;
    }
    sensordLogT() << "gyroscope output value: " << buf;

    sscanf(buf, "%hd %hd %hd\n", &x, &y, &z);

    TimedXyzData* pos = gyroscopeBuffer_->nextSlot();
    pos->x_ = x;
    pos->y_ = y;
    pos->z_ = z;
    pos->timestamp_ = Utils::getTimeStamp();

    gyroscopeBuffer_->commit();
    gyroscopeBuffer_->wakeUpReaders();
}

bool GyroscopeAdaptor::setInterval(const unsigned int value, const int sessionId)
{
    return SysfsAdaptor::setInterval(value>10?10:value, sessionId);
}

unsigned int GyroscopeAdaptor::interval() const{
    return SysfsAdaptor::interval();
}

<|endoftext|>


<commit_before>// //////////////////////////////////////////////////////////////////////
// Import section
// //////////////////////////////////////////////////////////////////////
// C
#include <assert.h>
// STL
#include <string>
// STDAIR
#include <stdair/bom/BomStructureRoot.hpp>
#include <stdair/bom/BomStructureDummy.hpp>
#include <stdair/bom/BomContentDummy.hpp>
#include <stdair/bom/InventoryStructure.hpp>
#include <stdair/bom/FlightDateStructure.hpp>
#include <stdair/bom/LegDateStructure.hpp>
#include <stdair/bom/SegmentDateStructure.hpp>
#include <stdair/bom/LegCabinStructure.hpp>
#include <stdair/bom/SegmentCabinStructure.hpp>
#include <stdair/bom/BookingClassStructure.hpp>
#include <stdair/bom/BomContentRoot.hpp>
#include <stdair/bom/BomChildrenHolderImp.hpp>
#include <stdair/bom/BomIterator.hpp>
#include <stdair/bom/Inventory.hpp>
#include <stdair/bom/FlightDate.hpp>
#include <stdair/bom/FlightDateList.hpp>
#include <stdair/bom/FlightDateMap.hpp>
#include <stdair/bom/LegDate.hpp>
#include <stdair/bom/LegDateList.hpp>
#include <stdair/bom/LegDateMap.hpp>
#include <stdair/bom/SegmentDate.hpp>
#include <stdair/bom/SegmentDateList.hpp>
#include <stdair/bom/SegmentDateMap.hpp>
#include <stdair/bom/SegmentCabin.hpp>
#include <stdair/bom/LegCabin.hpp>
#include <stdair/bom/BookingClass.hpp>
#include <stdair/factory/FacBomContent.hpp>
// AIRSCHED
#include <airsched/command/Simulator.hpp>
#include <airsched/service/Logger.hpp>

namespace AIRSCHED {

  // //////////////////////////////////////////////////////////////////////
  void Simulator::simulate () {
    // DEBUG
    AIRSCHED_LOG_DEBUG ("Welcome to Air-Schedule");

    // Step 0.0: initialisation
    // Create the root of the Bom tree (i.e., a BomContentRoot object)
    stdair::BomContentRoot_T& lBomContentRoot =
      stdair::FacBomContent::instance().createBomRoot<stdair::Inventory>();

    // Step 0.1: Inventory level
    // Create an Inventory (BA)
    const stdair::AirlineCode_T lAirlineCode ("BA");
    const stdair::InventoryKey_T lInventoryKey (lAirlineCode);

    stdair::Inventory& lInventory =
      stdair::FacBomContent::
      instance().create<stdair::Inventory> (lBomContentRoot, lInventoryKey);

    // Display the inventory
    AIRSCHED_LOG_DEBUG ("Inventory: " << lInventory.toString());

    // Step 0.2: Flight-date level
    // Create a FlightDate (BA15/10-JUN-2010)
    const stdair::FlightNumber_T lFlightNumber = 15;
    const stdair::Date_T lDate (2010, 6, 10);
    const stdair::FlightDateKey_T lFlightDateKey (lFlightNumber, lDate);

    stdair::FlightDate& lFlightDate =
      stdair::FacBomContent::instance().create<stdair::FlightDate> (lInventory,
                                                            lFlightDateKey);

    // Display the flight-date
    AIRSCHED_LOG_DEBUG ("FlightDate: " << lFlightDate.toString());

    // Step 0.3: Segment-date level
    // Create a first SegmentDate (LHR-SYD)
    const stdair::AirportCode_T lLHR ("LHR");
    const stdair::AirportCode_T lSYD ("SYD");
    stdair::SegmentDateKey_T lSegmentDateKey (lLHR, lSYD);

    stdair::SegmentDate& lLHRSYDSegment =
      stdair::FacBomContent::instance().create<stdair::SegmentDate> (lFlightDate,
                                                             lSegmentDateKey);

    // Display the segment-date
    AIRSCHED_LOG_DEBUG ("SegmentDate: " << lLHRSYDSegment.toString());

    // Create a second SegmentDate (LHR-BKK)
    const stdair::AirportCode_T lBKK ("BKK");
    lSegmentDateKey = stdair::SegmentDateKey_T (lLHR, lBKK);

    stdair::SegmentDate& lLHRBKKSegment =
      stdair::FacBomContent::instance().create<stdair::SegmentDate> (lFlightDate,
                                                             lSegmentDateKey);

    // Display the segment-date
    AIRSCHED_LOG_DEBUG ("SegmentDate: " << lLHRBKKSegment.toString());

    // Create a third SegmentDate (BKK-SYD)
    lSegmentDateKey = stdair::SegmentDateKey_T (lBKK, lSYD);

    stdair::SegmentDate& lBKKSYDSegment =
      stdair::FacBomContent::instance().create<stdair::SegmentDate> (lFlightDate,
                                                             lSegmentDateKey);

    // Display the segment-date
    AIRSCHED_LOG_DEBUG ("SegmentDate: " << lBKKSYDSegment.toString());

    // Step 0.4: Leg-date level
    // Create a first LegDate (LHR)
    stdair::LegDateKey_T lLegDateKey (lLHR);

    stdair::LegDate& lLHRLeg =
      stdair::FacBomContent::instance().create<stdair::LegDate> (lFlightDate,
                                                         lLegDateKey);

    // Display the leg-date
    AIRSCHED_LOG_DEBUG ("LegDate: " << lLHRLeg.toString());

    // Create a second LegDate (BKK)
    lLegDateKey = stdair::LegDateKey_T (lBKK);

    stdair::LegDate& lBKKLeg =
      stdair::FacBomContent::instance().create<stdair::LegDate> (lFlightDate,
                                                         lLegDateKey);

    // Display the leg-date
    AIRSCHED_LOG_DEBUG ("LegDate: " << lBKKLeg.toString());

    // Step 0.5: Initialisation results
    // Display the full structure and content
    AIRSCHED_LOG_DEBUG ("Full Inventory: " << lInventory.toString());

    testIteratorInventory (lInventory);
    testIteratorFlightDate (lFlightDate);
  }

  // ////////////////////////////////////////////////////////////////
  void Simulator::testIteratorInventory (const stdair::Inventory& iInventory) {
    AIRSCHED_LOG_DEBUG ("Test iterator.");

    // Browse the list with a for-loop
    AIRSCHED_LOG_DEBUG ("Browse the list");
    stdair::FlightDateList_T lFDList = iInventory.getFlightDateList();
    for (stdair::FlightDateList_T::iterator itFD = lFDList.begin();
         itFD != lFDList.end(); ++itFD) {
      AIRSCHED_LOG_DEBUG ("Current flight-date: " << *itFD);
    }

    // Browse the map with a for-loops
    AIRSCHED_LOG_DEBUG ("Browse the map with iterator");
    stdair::FlightDateMap_T lFDMap = iInventory.getFlightDateMap();
    for (stdair::FlightDateMap_T::iterator itFD = lFDMap.begin();
         itFD != lFDMap.end(); ++itFD) {
      const stdair::FlightDate* lCurrentFlightDate_ptr = itFD->second;
      AIRSCHED_LOG_DEBUG ("Current flight-date: "
                          << lCurrentFlightDate_ptr->toString());
    }

    AIRSCHED_LOG_DEBUG ("Browse the map with reverse_iterator");
    for (stdair::FlightDateMap_T::reverse_iterator itFD = lFDMap.rbegin();
         itFD != lFDMap.rend(); ++itFD) {
      const stdair::FlightDate* lCurrentFlightDate_ptr = itFD->second;
      AIRSCHED_LOG_DEBUG ("Current flight-date: "
                          << lCurrentFlightDate_ptr->toString());
    }

    AIRSCHED_LOG_DEBUG ("Test operators: ");
    stdair::FlightDateList_T::iterator itBegin = lFDList.begin();
    stdair::FlightDateList_T::iterator itEnd = lFDList.end();
    AIRSCHED_LOG_DEBUG ("itEnd - itBegin, should be 1: " << itEnd - itBegin);
    AIRSCHED_LOG_DEBUG ("itBegin - itEnd, should be -1: " << itBegin - itEnd);
    AIRSCHED_LOG_DEBUG ("itBegin < itEnd, should be 1: " << (itBegin < itEnd));
    AIRSCHED_LOG_DEBUG ("itEnd - (1 + itBegin), should be 0: "
                        << (itEnd - (1 + itBegin)));
    AIRSCHED_LOG_DEBUG ( *(itEnd - 1));
    AIRSCHED_LOG_DEBUG ( *(itEnd -= 1));
  }

  // ////////////////////////////////////////////////////////////////
  void Simulator::
  testIteratorFlightDate (const stdair::FlightDate& iFlightDate) {
    AIRSCHED_LOG_DEBUG ("Test iterator.");

    // Browse the list with a for-loop
    AIRSCHED_LOG_DEBUG ("Browse the segment-date list");
    stdair::SegmentDateList_T lSDList = iFlightDate.getSegmentDateList();
    for (stdair::SegmentDateList_T::iterator itSD = lSDList.begin();
         itSD != lSDList.end(); ++itSD) {
      AIRSCHED_LOG_DEBUG ("Current segment-date: " << *itSD);
    }

    // Browse the map with a for-loop
    AIRSCHED_LOG_DEBUG ("Browse the segment_date map with iterator");
    stdair::SegmentDateMap_T lSDMap = iFlightDate.getSegmentDateMap();
    for (stdair::SegmentDateMap_T::iterator itSD = lSDMap.begin();
         itSD != lSDMap.end(); ++itSD) {
      const stdair::SegmentDate* lCurrentSegmentDate_ptr = itSD->second;
      AIRSCHED_LOG_DEBUG ("Current segment-date: "
                          << lCurrentSegmentDate_ptr->toString());
    }

    // Browse the list with a for-loop
    AIRSCHED_LOG_DEBUG ("Browse the leg-date list");
    stdair::LegDateList_T lLDList = iFlightDate.getLegDateList();
    for (stdair::LegDateList_T::iterator itLD = lLDList.begin();
         itLD != lLDList.end(); ++itLD) {
      AIRSCHED_LOG_DEBUG ("Current leg-date: " << *itLD);
    }

    // Browse the map with a for-loop
    AIRSCHED_LOG_DEBUG ("Browse the leg-date map with iterator");
    stdair::LegDateMap_T lLDMap = iFlightDate.getLegDateMap();
    for (stdair::LegDateMap_T::iterator itLD = lLDMap.begin();
         itLD != lLDMap.end(); ++itLD) {
      const stdair::LegDate* lCurrentLegDate_ptr = itLD->second;
      AIRSCHED_LOG_DEBUG ("Current leg-date: "
                          << lCurrentLegDate_ptr->toString());
    }
  }

}
<commit_msg>[Dev] Updated the test (Simulator) using segment-cabin, leg-cabin, booking class.<commit_after>// //////////////////////////////////////////////////////////////////////
// Import section
// //////////////////////////////////////////////////////////////////////
// C
#include <assert.h>
// STL
#include <string>
// STDAIR
#include <stdair/bom/BomStructureRoot.hpp>
#include <stdair/bom/BomStructureDummy.hpp>
#include <stdair/bom/BomContentDummy.hpp>
#include <stdair/bom/InventoryStructure.hpp>
#include <stdair/bom/FlightDateStructure.hpp>
#include <stdair/bom/LegDateStructure.hpp>
#include <stdair/bom/SegmentDateStructure.hpp>
#include <stdair/bom/LegCabinStructure.hpp>
#include <stdair/bom/SegmentCabinStructure.hpp>
#include <stdair/bom/BookingClassStructure.hpp>
#include <stdair/bom/BomContentRoot.hpp>
#include <stdair/bom/BomChildrenHolderImp.hpp>
#include <stdair/bom/BomIterator.hpp>
#include <stdair/bom/Inventory.hpp>
#include <stdair/bom/FlightDate.hpp>
#include <stdair/bom/FlightDateList.hpp>
#include <stdair/bom/FlightDateMap.hpp>
#include <stdair/bom/LegDate.hpp>
#include <stdair/bom/LegDateList.hpp>
#include <stdair/bom/LegDateMap.hpp>
#include <stdair/bom/SegmentDate.hpp>
#include <stdair/bom/SegmentDateList.hpp>
#include <stdair/bom/SegmentDateMap.hpp>
#include <stdair/bom/SegmentCabin.hpp>
#include <stdair/bom/LegCabin.hpp>
#include <stdair/bom/BookingClass.hpp>
#include <stdair/factory/FacBomContent.hpp>
// AIRSCHED
#include <airsched/command/Simulator.hpp>
#include <airsched/service/Logger.hpp>

namespace AIRSCHED {

  // //////////////////////////////////////////////////////////////////////
  void Simulator::simulate () {
    // DEBUG
    AIRSCHED_LOG_DEBUG ("Welcome to Air-Schedule");

    // Step 0.0: initialisation
    // Create the root of the Bom tree (i.e., a BomContentRoot object)
    stdair::BomContentRoot_T& lBomContentRoot =
      stdair::FacBomContent::instance().createBomRoot<stdair::Inventory>();

    // Step 0.1: Inventory level
    // Create an Inventory (BA)
    const stdair::AirlineCode_T lAirlineCode ("BA");
    const stdair::InventoryKey_T lInventoryKey (lAirlineCode);

    stdair::Inventory& lInventory =
      stdair::FacBomContent::
      instance().create<stdair::Inventory> (lBomContentRoot, lInventoryKey);

    // Display the inventory
    AIRSCHED_LOG_DEBUG ("Inventory: " << lInventory.toString());

    // Step 0.2: Flight-date level
    // Create a FlightDate (BA15/10-JUN-2010)
    const stdair::FlightNumber_T lFlightNumber = 15;
    const stdair::Date_T lDate (2010, 6, 10);
    const stdair::FlightDateKey_T lFlightDateKey (lFlightNumber, lDate);

    stdair::FlightDate& lFlightDate =
      stdair::FacBomContent::instance().create<stdair::FlightDate> (lInventory,
                                                            lFlightDateKey);

    // Display the flight-date
    AIRSCHED_LOG_DEBUG ("FlightDate: " << lFlightDate.toString());

    // Step 0.3: Segment-date level
    // Create a first SegmentDate (LHR-SYD)
    const stdair::AirportCode_T lLHR ("LHR");
    const stdair::AirportCode_T lSYD ("SYD");
    stdair::SegmentDateKey_T lSegmentDateKey (lLHR, lSYD);

    stdair::SegmentDate& lLHRSYDSegment =
      stdair::FacBomContent::instance().create<stdair::SegmentDate> (lFlightDate,
                                                             lSegmentDateKey);

    // Display the segment-date
    AIRSCHED_LOG_DEBUG ("SegmentDate: " << lLHRSYDSegment.toString());

    // Create a second SegmentDate (LHR-BKK)
    const stdair::AirportCode_T lBKK ("BKK");
    lSegmentDateKey = stdair::SegmentDateKey_T (lLHR, lBKK);

    stdair::SegmentDate& lLHRBKKSegment =
      stdair::FacBomContent::instance().create<stdair::SegmentDate> (lFlightDate,
                                                             lSegmentDateKey);

    // Display the segment-date
    AIRSCHED_LOG_DEBUG ("SegmentDate: " << lLHRBKKSegment.toString());

    // Create a third SegmentDate (BKK-SYD)
    lSegmentDateKey = stdair::SegmentDateKey_T (lBKK, lSYD);

    stdair::SegmentDate& lBKKSYDSegment =
      stdair::FacBomContent::instance().create<stdair::SegmentDate> (lFlightDate,
                                                             lSegmentDateKey);

    // Display the segment-date
    AIRSCHED_LOG_DEBUG ("SegmentDate: " << lBKKSYDSegment.toString());

    // Step 0.4: Leg-date level
    // Create a first LegDate (LHR)
    stdair::LegDateKey_T lLegDateKey (lLHR);

    stdair::LegDate& lLHRLeg =
      stdair::FacBomContent::instance().create<stdair::LegDate> (lFlightDate,
                                                         lLegDateKey);

    // Display the leg-date
    AIRSCHED_LOG_DEBUG ("LegDate: " << lLHRLeg.toString());

    // Create a second LegDate (BKK)
    lLegDateKey = stdair::LegDateKey_T (lBKK);

    stdair::LegDate& lBKKLeg =
      stdair::FacBomContent::instance().create<stdair::LegDate> (lFlightDate,
                                                         lLegDateKey);

    // Display the leg-date
    AIRSCHED_LOG_DEBUG ("LegDate: " << lBKKLeg.toString());

    // Step 0.5: segment-cabin level
    // Create a SegmentCabin (Y) of the Segment LHR-BKK;
    const stdair::CabinCode_T lY ("Y");
    stdair::SegmentCabinKey_T lYSegmentCabinKey (lY);

    stdair::SegmentCabin& lLHRBKKSegmentYCabin =
      stdair::FacBomContent::
      instance().create<stdair::SegmentCabin> (lLHRBKKSegment,
                                               lYSegmentCabinKey);

    // Display the segment-cabin
    AIRSCHED_LOG_DEBUG ("SegmentCabin: " << lLHRBKKSegmentYCabin.toString());

    // Create a SegmentCabin (Y) of the Segment BKK-SYD;
    stdair::SegmentCabin& lBKKSYDSegmentYCabin =
      stdair::FacBomContent::
      instance().create<stdair::SegmentCabin> (lBKKSYDSegment,
                                               lYSegmentCabinKey);

    // Display the segment-cabin
    AIRSCHED_LOG_DEBUG ("SegmentCabin: " << lBKKSYDSegmentYCabin.toString());

    // Create a SegmentCabin (Y) of the Segment LHR-SYD;
    stdair::SegmentCabin& lLHRSYDSegmentYCabin =
      stdair::FacBomContent::
      instance().create<stdair::SegmentCabin> (lLHRSYDSegment,
                                               lYSegmentCabinKey);

    // Display the segment-cabin
    AIRSCHED_LOG_DEBUG ("SegmentCabin: " << lLHRSYDSegmentYCabin.toString());

    // Step 0.6: leg-cabin level
    // Create a LegCabin (Y) of the Leg LHR-BKK;
    stdair::LegCabinKey_T lYLegCabinKey (lY);

    stdair::LegCabin& lLHRLegYCabin =
      stdair::FacBomContent::
      instance().create<stdair::LegCabin> (lLHRLeg, lYLegCabinKey);

    // Display the leg-cabin
    AIRSCHED_LOG_DEBUG ("LegCabin: " << lLHRLegYCabin.toString());

    // Create a LegCabin (Y) of the Leg BKK-SYD;
    stdair::LegCabin& lBKKLegYCabin =
      stdair::FacBomContent::
      instance().create<stdair::LegCabin> (lBKKLeg, lYLegCabinKey);

    // Display the leg-cabin
    AIRSCHED_LOG_DEBUG ("LegCabin: " << lBKKLegYCabin.toString());

    // Step 0.7: booking class level
    // Create a BookingClass (Q) of the Segment LHR-BKK, cabin Y;
    const stdair::ClassCode_T lQ ("Q");
    stdair::BookingClassKey_T lQBookingClassKey (lQ);

    stdair::BookingClass& lLHRBKKSegmentYCabinQClass =
      stdair::FacBomContent::
      instance().create<stdair::BookingClass> (lLHRBKKSegmentYCabin,
                                               lQBookingClassKey);

    // Display the booking class
    AIRSCHED_LOG_DEBUG ("BookingClass: "
                        << lLHRBKKSegmentYCabinQClass.toString());

    // Step 0.8: Initialisation results
    // Display the full structure and content
    AIRSCHED_LOG_DEBUG ("Full Inventory: " << lInventory.toString());

    testIteratorInventory (lInventory);
    testIteratorFlightDate (lFlightDate);
  }

  // ////////////////////////////////////////////////////////////////
  void Simulator::testIteratorInventory (const stdair::Inventory& iInventory) {
    AIRSCHED_LOG_DEBUG ("Test iterator.");

    // Browse the list with a for-loop
    AIRSCHED_LOG_DEBUG ("Browse the list");
    stdair::FlightDateList_T lFDList = iInventory.getFlightDateList();
    for (stdair::FlightDateList_T::iterator itFD = lFDList.begin();
         itFD != lFDList.end(); ++itFD) {
      AIRSCHED_LOG_DEBUG ("Current flight-date: " << *itFD);
    }

    // Browse the map with a for-loops
    AIRSCHED_LOG_DEBUG ("Browse the map with iterator");
    stdair::FlightDateMap_T lFDMap = iInventory.getFlightDateMap();
    for (stdair::FlightDateMap_T::iterator itFD = lFDMap.begin();
         itFD != lFDMap.end(); ++itFD) {
      const stdair::FlightDate* lCurrentFlightDate_ptr = itFD->second;
      AIRSCHED_LOG_DEBUG ("Current flight-date: "
                          << lCurrentFlightDate_ptr->toString());
    }

    AIRSCHED_LOG_DEBUG ("Browse the map with reverse_iterator");
    for (stdair::FlightDateMap_T::reverse_iterator itFD = lFDMap.rbegin();
         itFD != lFDMap.rend(); ++itFD) {
      const stdair::FlightDate* lCurrentFlightDate_ptr = itFD->second;
      AIRSCHED_LOG_DEBUG ("Current flight-date: "
                          << lCurrentFlightDate_ptr->toString());
    }

    AIRSCHED_LOG_DEBUG ("Test operators: ");
    stdair::FlightDateList_T::iterator itBegin = lFDList.begin();
    stdair::FlightDateList_T::iterator itEnd = lFDList.end();
    AIRSCHED_LOG_DEBUG ("itEnd - itBegin, should be 1: " << itEnd - itBegin);
    AIRSCHED_LOG_DEBUG ("itBegin - itEnd, should be -1: " << itBegin - itEnd);
    AIRSCHED_LOG_DEBUG ("itBegin < itEnd, should be 1: " << (itBegin < itEnd));
    AIRSCHED_LOG_DEBUG ("itEnd - (1 + itBegin), should be 0: "
                        << (itEnd - (1 + itBegin)));
    AIRSCHED_LOG_DEBUG ( *(itEnd - 1));
    AIRSCHED_LOG_DEBUG ( *(itEnd -= 1));
  }

  // ////////////////////////////////////////////////////////////////
  void Simulator::
  testIteratorFlightDate (const stdair::FlightDate& iFlightDate) {
    AIRSCHED_LOG_DEBUG ("Test iterator.");

    // Browse the list with a for-loop
    AIRSCHED_LOG_DEBUG ("Browse the segment-date list");
    stdair::SegmentDateList_T lSDList = iFlightDate.getSegmentDateList();
    for (stdair::SegmentDateList_T::iterator itSD = lSDList.begin();
         itSD != lSDList.end(); ++itSD) {
      AIRSCHED_LOG_DEBUG ("Current segment-date: " << *itSD);
    }

    // Browse the map with a for-loop
    AIRSCHED_LOG_DEBUG ("Browse the segment_date map with iterator");
    stdair::SegmentDateMap_T lSDMap = iFlightDate.getSegmentDateMap();
    for (stdair::SegmentDateMap_T::iterator itSD = lSDMap.begin();
         itSD != lSDMap.end(); ++itSD) {
      const stdair::SegmentDate* lCurrentSegmentDate_ptr = itSD->second;
      AIRSCHED_LOG_DEBUG ("Current segment-date: "
                          << lCurrentSegmentDate_ptr->toString());
    }

    // Browse the list with a for-loop
    AIRSCHED_LOG_DEBUG ("Browse the leg-date list");
    stdair::LegDateList_T lLDList = iFlightDate.getLegDateList();
    for (stdair::LegDateList_T::iterator itLD = lLDList.begin();
         itLD != lLDList.end(); ++itLD) {
      AIRSCHED_LOG_DEBUG ("Current leg-date: " << *itLD);
    }

    // Browse the map with a for-loop
    AIRSCHED_LOG_DEBUG ("Browse the leg-date map with iterator");
    stdair::LegDateMap_T lLDMap = iFlightDate.getLegDateMap();
    for (stdair::LegDateMap_T::iterator itLD = lLDMap.begin();
         itLD != lLDMap.end(); ++itLD) {
      const stdair::LegDate* lCurrentLegDate_ptr = itLD->second;
      AIRSCHED_LOG_DEBUG ("Current leg-date: "
                          << lCurrentLegDate_ptr->toString());
    }
  }

}
<|endoftext|>


<commit_before>#ifndef STAN__MATH__ODE__COUPLED_ODE_OBSERVER_HPP
#define STAN__MATH__ODE__COUPLED_ODE_OBSERVER_HPP

#include <vector>

namespace stan {

  namespace math {

    /**
     * Observer for the coupled states.  Holds a reference to
     * an externally defined vector of vectors passed in at
     * construction time.
     */
    struct coupled_ode_observer {

      std::vector<std::vector<double> >& y_coupled_;
      int n_;

      /**
       * Construct a coupled ODE observer from the specified coupled
       * vector.
       *
       * @param y_coupled reference to a vector of vector of doubles.
       */
      coupled_ode_observer(std::vector<std::vector<double> >& y_coupled)
        : y_coupled_(y_coupled), n_(0) {
      }

      /**
       * Callback function for Boost's ODE solver to record values.
       *
       * @param coupled_state solution at the specified time.
       * @param t time of solution.
       */
      void operator()(const std::vector<double>& coupled_state,
                      const double t) {
        y_coupled_[n_] = coupled_state;
        n++;
      }

    };

  }

}

#endif
<commit_msg>fixed typo in math coupled ODE observer<commit_after>#ifndef STAN__MATH__ODE__COUPLED_ODE_OBSERVER_HPP
#define STAN__MATH__ODE__COUPLED_ODE_OBSERVER_HPP

#include <vector>

namespace stan {

  namespace math {

    /**
     * Observer for the coupled states.  Holds a reference to
     * an externally defined vector of vectors passed in at
     * construction time.
     */
    struct coupled_ode_observer {

      std::vector<std::vector<double> >& y_coupled_;
      int n_;

      /**
       * Construct a coupled ODE observer from the specified coupled
       * vector.
       *
       * @param y_coupled reference to a vector of vector of doubles.
       */
      coupled_ode_observer(std::vector<std::vector<double> >& y_coupled)
        : y_coupled_(y_coupled), n_(0) {
      }

      /**
       * Callback function for Boost's ODE solver to record values.
       *
       * @param coupled_state solution at the specified time.
       * @param t time of solution.
       */
      void operator()(const std::vector<double>& coupled_state,
                      const double t) {
        y_coupled_[n_] = coupled_state;
        n_++;
      }

    };

  }

}

#endif
<|endoftext|>


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

    Copyright (C) 2007 Frank Osterfeld <frank.osterfeld@kdemail.net>

    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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 "subscriptionlistmodel.h"
#include "feed.h"
#include "feedlist.h"
#include "folder.h"
#include "subscriptionlistjobs.h"
#include "treenode.h"

#include <KDebug>
#include <KIconLoader>
#include <KLocalizedString>

#include <QByteArray>
#include <QDataStream>
#include <QFont>
#include <QIcon>
#include <QList>
#include <QMimeData>
#include <QUrl>
#include <QVariant>

#include <cassert>

using namespace Akregator;
using namespace Syndication;

#define AKREGATOR_TREENODE_MIMETYPE "akregator/treenode-id"

namespace {

    QString errorCodeToString( Syndication::ErrorCode err )
    {
        switch ( err )
        {
            case Timeout:
                return i18n( "Timeout on remote server" );
            case UnknownHost:
                return i18n( "Unknown host" );
            case FileNotFound:
                return i18n( "Feed file not found on remote server" );
            case InvalidXml:
                return i18n( "Could not read feed (invalid XML)" );
            case XmlNotAccepted:
                return i18n( "Could not read feed (unknown format)" );
            case InvalidFormat:
                return i18n( "Could not read feed (invalid feed)" );
            case Success:
            case Aborted:
            default:
                return QString();
        }
    }

    static const Akregator::TreeNode* nodeForIndex( const QModelIndex& index, const Akregator::FeedList* feedList )
    {
        return ( !index.isValid() || !feedList ) ? 0 : feedList->findByID( index.internalId() );
    }
}

Akregator::SubscriptionListModel::SubscriptionListModel( const Akregator::FeedList* feedList, QObject* parent ) : QAbstractItemModel( parent ), m_feedList( feedList ), m_beganRemoval( false )
{
    if ( feedList )
    {
        connect( feedList, SIGNAL( signalDestroyed( Akregator::FeedList* ) ),
                 this, SLOT( feedListDestroyed( Akregator::FeedList* ) ) );
        connect( feedList, SIGNAL( signalNodeAdded( Akregator::TreeNode* ) ),
                 this, SLOT( subscriptionAdded( Akregator::TreeNode* ) ) );
        connect( feedList, SIGNAL( signalAboutToRemoveNode( Akregator::TreeNode* ) ),
                 this, SLOT( aboutToRemoveSubscription( Akregator::TreeNode* ) ) );
        connect( feedList, SIGNAL( signalNodeRemoved( Akregator::TreeNode* ) ),
                   this, SLOT( subscriptionRemoved( Akregator::TreeNode* ) ) );
        connect( feedList, SIGNAL( signalNodeChanged( Akregator::TreeNode* ) ),
                 this, SLOT( subscriptionChanged( Akregator::TreeNode* ) ) );
        connect( feedList, SIGNAL( fetchStarted( Akregator::Feed* ) ),
                 this, SLOT( fetchStarted( Akregator::Feed* ) ) );
        connect( feedList, SIGNAL( fetched( Akregator::Feed* ) ),
                 this, SLOT( fetched( Akregator::Feed* ) ) );
        connect( feedList, SIGNAL( fetchAborted( Akregator::Feed* ) ),
                 this, SLOT( fetchAborted( Akregator::Feed* ) ) );
    }
}

int Akregator::SubscriptionListModel::columnCount( const QModelIndex& ) const
{
    return 3;
}

int Akregator::SubscriptionListModel::rowCount( const QModelIndex& parent ) const
{
    if ( !parent.isValid() )
        return 1;

    const Akregator::TreeNode* const node = nodeForIndex( parent, m_feedList );
    return node ? node->children().count() : 0;
}

uint Akregator::SubscriptionListModel::nodeIdForIndex( const QModelIndex& idx ) const
{
    return idx.isValid() ? idx.internalId() : 0;
}

QVariant Akregator::SubscriptionListModel::data( const QModelIndex& index, int role ) const
{
    if ( !index.isValid() )
        return QVariant();

    const Akregator::TreeNode* const node = nodeForIndex( index, m_feedList );

    if ( !node )
        return QVariant();

    switch ( role )
    {
        case Qt::DisplayRole:
        {
            switch ( index.column() )
            {
                case TitleColumn:
                    return node->title();
                case UnreadCountColumn:
                    return node->unread();
                case TotalCountColumn:
                    return node->totalCount();
            }
        }
        case Qt::FontRole:
        {
            if(node->unread() > 0) {
                QFont font;
                font.setBold(true);
                return font;
            }
        }
        case Qt::ToolTipRole:
        {
            if ( node->isGroup() || node->isAggregation() )
                return QString();
            const Feed* const feed = qobject_cast<const Feed* const>( node );
            if ( feed && feed->fetchErrorOccurred() )
                return i18n( "Could not fetch feed: %1", errorCodeToString( feed->fetchErrorCode() ) );
            else
                return QString();
        }
        case Qt::DecorationRole:
        {
            if ( index.column() != TitleColumn )
                return QVariant();
            const Feed* const feed = qobject_cast<const Feed* const>( node );
            return feed && feed->isFetching() ? node->icon().pixmap( KIconLoader::SizeSmall, QIcon::Active ) : node->icon();
        }
        case SubscriptionIdRole:
        {
            return node->id();
        }
        case IsGroupRole:
        {
            return node->isGroup();
        }
        case IsFetchableRole:
        {
            return !node->isGroup() && !node->isAggregation();
        }
        case IsAggregationRole:
        {
            return node->isAggregation();
        }
        case LinkRole:
        {
        	const Feed* const feed = qobject_cast<const Feed* const>( node );
        	return feed ? feed->xmlUrl() : QVariant();
        }
        case IsOpenRole:
        {
            if ( !node->isGroup() )
                return false;
            const Akregator::Folder* const folder = qobject_cast<const Akregator::Folder* const>( node );
            Q_ASSERT( folder );
            return folder->isOpen();
        }
    }

    return QVariant();
}

QVariant Akregator::SubscriptionListModel::headerData( int section, Qt::Orientation, int role ) const
{
    if ( role != Qt::DisplayRole )
        return QVariant();

    switch (section)
    {
        case TitleColumn:
            return i18n("Feeds");
        case UnreadCountColumn:
            return i18n("Unread");
        case TotalCountColumn:
            return i18n("Total");
    }

    return QVariant();
}

QModelIndex Akregator::SubscriptionListModel::parent( const QModelIndex& index ) const
{
    const Akregator::TreeNode* const node = nodeForIndex( index, m_feedList );

    if ( !node || !node->parent() )
        return QModelIndex();

    const Akregator::Folder* parent = node->parent();

    if ( !parent->parent() )
        return createIndex( 0, 0, parent->id() );

    const Akregator::Folder* const grandparent = parent->parent();

    const int row = grandparent->indexOf( parent );

    Q_ASSERT( row != -1 );

    return createIndex( row, 0, parent->id() );
}

QModelIndex Akregator::SubscriptionListModel::index( int row, int column, const QModelIndex& parent ) const
{
    if ( !parent.isValid() )
        return ( row == 0 && m_feedList ) ? createIndex( row, column , m_feedList->rootNode()->id() ) : QModelIndex();

    const Akregator::TreeNode* const parentNode = nodeForIndex( parent, m_feedList );
    const Akregator::TreeNode* const childNode = parentNode->childAt( row );
    return  childNode ? createIndex( row, column, childNode->id() ) : QModelIndex();
}

QModelIndex SubscriptionListModel::indexForNode( const TreeNode* node ) const
{
    if ( !node || !m_feedList )
        return QModelIndex();
    const Folder* const parent = node->parent();
    if ( !parent )
        return index( 0, 0 );
    const int row = parent->indexOf( node );
    Q_ASSERT( row >= 0 );
    const QModelIndex idx = index( row, 0, indexForNode( parent ) );
    Q_ASSERT( idx.internalId() == node->id() );
    return idx;
}

void Akregator::SubscriptionListModel::feedListDestroyed( Akregator::FeedList* )
{
    m_feedList = 0;
}

void Akregator::SubscriptionListModel::subscriptionAdded( Akregator::TreeNode* subscription )
{
    const Folder* const parent = subscription->parent();
    const int row = parent ? parent->indexOf( subscription ) : 0;
    Q_ASSERT( row >= 0 );
    beginInsertRows( indexForNode( parent ), row, row );
    endInsertRows();
}

void Akregator::SubscriptionListModel::aboutToRemoveSubscription( Akregator::TreeNode* subscription )
{
    kDebug() << subscription->id() << endl;
    const Folder* const parent = subscription->parent();
    const int row = parent ? parent->indexOf( subscription ) : -1;
    if ( row < 0 )
        return;
    beginRemoveRows( indexForNode( parent ), row, row );
    m_beganRemoval = true;
}

void Akregator::SubscriptionListModel::subscriptionRemoved( TreeNode* subscription )
{
    kDebug() << subscription->id() << endl;
    if ( m_beganRemoval )
    {
        m_beganRemoval = false;
        endRemoveRows();
    }
}

void Akregator::SubscriptionListModel::subscriptionChanged( TreeNode* node )
{
    const QModelIndex idx = indexForNode( node );
    if ( !idx.isValid() )
        return;
    emit dataChanged( index( idx.row(), 0, idx.parent() ),
                      index( idx.row(), ColumnCount - 1, idx.parent() ) );
}

void SubscriptionListModel::fetchStarted( Akregator::Feed* node )
{
    subscriptionChanged( node );
}

void SubscriptionListModel::fetched( Akregator::Feed* node )
{
    subscriptionChanged( node );
}

void SubscriptionListModel::fetchError( Akregator::Feed* node )
{
    subscriptionChanged( node );
}

void Akregator::FolderExpansionHandler::itemExpanded( const QModelIndex& idx )
{
    setExpanded( idx, true );
}

void Akregator::FolderExpansionHandler::itemCollapsed( const QModelIndex& idx )
{
    setExpanded( idx, false );
}

void Akregator::FolderExpansionHandler::setExpanded( const QModelIndex& idx, bool expanded )
{
    if ( !m_feedList || !m_model )
        return;
    Akregator::TreeNode* const node = m_feedList->findByID( m_model->nodeIdForIndex( idx ) );
    if ( !node || !node->isGroup() )
        return;

    Akregator::Folder* const folder = qobject_cast<Akregator::Folder*>( node );
    Q_ASSERT( folder );
    folder->setOpen( expanded );
}

Akregator::FolderExpansionHandler::FolderExpansionHandler( QObject* parent ) : QObject( parent ), m_feedList( 0 ), m_model( 0 )
{
}

void Akregator::FolderExpansionHandler::setModel( Akregator::SubscriptionListModel* model )
{
    m_model = model;
}

void Akregator::FolderExpansionHandler::setFeedList( Akregator::FeedList* feedList )
{
    m_feedList = feedList;
}

Qt::ItemFlags SubscriptionListModel::flags( const QModelIndex& idx ) const
{
    const Qt::ItemFlags flags = QAbstractItemModel::flags( idx );
    if ( (!idx.isValid() | idx.column()) != TitleColumn )
        return flags;
    if ( !idx.parent().isValid() ) // the root folder is neither draggable nor editable
        return flags | Qt::ItemIsDropEnabled;
    return flags | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | Qt::ItemIsEditable;
}

QStringList SubscriptionListModel::mimeTypes() const
{
    QStringList types;
    types << "text/uri-list" << AKREGATOR_TREENODE_MIMETYPE;
    return types;
}

QMimeData* SubscriptionListModel::mimeData( const QModelIndexList& indexes ) const
{
    QMimeData* mimeData = new QMimeData;

    QList<QUrl> urls;
    Q_FOREACH ( const QModelIndex& i, indexes )
    {
        const QUrl url = i.data( LinkRole ).toString();
        if ( !url.isEmpty() )
            urls << url;
    }

    mimeData->setUrls( urls );

    QByteArray idList;
    QDataStream idStream( &idList, QIODevice::WriteOnly );
    Q_FOREACH ( const QModelIndex& i, indexes )
        if ( i.isValid() )
            idStream << i.data( SubscriptionIdRole ).toInt();

    mimeData->setData( AKREGATOR_TREENODE_MIMETYPE, idList );

    return mimeData;
}

bool SubscriptionListModel::setData( const QModelIndex& idx, const QVariant& value, int role )
{
    if ( !idx.isValid() || idx.column() != TitleColumn || role != Qt::EditRole )
        return false;
    const TreeNode* const node = nodeForIndex( idx, m_feedList );
    if ( !node )
        return false;
    RenameSubscriptionJob* job = new RenameSubscriptionJob( this );
    job->setSubscriptionId( node->id() );
    job->setName( value.toString() );
    job->start();
    return true;
}

bool SubscriptionListModel::dropMimeData( const QMimeData* data,
                                          Qt::DropAction action,
                                          int row,
                                          int column,
                                          const QModelIndex& parent )
{
    if ( action == Qt::IgnoreAction )
        return true;

    //if ( column != TitleColumn )
    //    return false;

    if ( data->hasFormat( AKREGATOR_TREENODE_MIMETYPE ) )
    {
        const TreeNode* const droppedOnNode = qobject_cast<const TreeNode*>( nodeForIndex( parent, m_feedList ) );

        const Folder* const destFolder = droppedOnNode->isGroup() ? qobject_cast<const Folder*>( droppedOnNode ) : droppedOnNode->parent();
        if ( !destFolder )
            return false;

        QByteArray idData = data->data( AKREGATOR_TREENODE_MIMETYPE );
        QList<int> ids;
        QDataStream stream( &idData, QIODevice::ReadOnly );
        while ( !stream.atEnd() )
        {
            int id;
            stream >> id;
            ids << id;
        }

        //don't drop nodes into their own subtree
        Q_FOREACH ( const int id, ids )
        {
            const Folder* const asFolder = qobject_cast<const Folder*>( m_feedList->findByID( id ) );
            if ( asFolder && asFolder->subtreeContains( destFolder ) )
                return false;
        }

        const TreeNode* const after = droppedOnNode->isGroup() ? destFolder->childAt( row ) : droppedOnNode;

        Q_FOREACH ( const int id, ids )
        {
            const TreeNode* const node = m_feedList->findByID( id );
            if ( !node )
                continue;
            MoveSubscriptionJob* job = new MoveSubscriptionJob( this );
            job->setSubscriptionId( node->id() );
            job->setDestination( destFolder->id(), after ? after->id() : -1 );
            job->start();
        }
        return true;
    }

    return false;
}

#include "subscriptionlistmodel.moc"
<commit_msg>SVN_SILENT wow, that was broken by so many degrees<commit_after>/*
    This file is part of Akregator.

    Copyright (C) 2007 Frank Osterfeld <frank.osterfeld@kdemail.net>

    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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 "subscriptionlistmodel.h"
#include "feed.h"
#include "feedlist.h"
#include "folder.h"
#include "subscriptionlistjobs.h"
#include "treenode.h"

#include <KDebug>
#include <KIconLoader>
#include <KLocalizedString>

#include <QByteArray>
#include <QDataStream>
#include <QFont>
#include <QIcon>
#include <QList>
#include <QMimeData>
#include <QUrl>
#include <QVariant>

#include <cassert>

using namespace Akregator;
using namespace Syndication;

#define AKREGATOR_TREENODE_MIMETYPE "akregator/treenode-id"

namespace {

    QString errorCodeToString( Syndication::ErrorCode err )
    {
        switch ( err )
        {
            case Timeout:
                return i18n( "Timeout on remote server" );
            case UnknownHost:
                return i18n( "Unknown host" );
            case FileNotFound:
                return i18n( "Feed file not found on remote server" );
            case InvalidXml:
                return i18n( "Could not read feed (invalid XML)" );
            case XmlNotAccepted:
                return i18n( "Could not read feed (unknown format)" );
            case InvalidFormat:
                return i18n( "Could not read feed (invalid feed)" );
            case Success:
            case Aborted:
            default:
                return QString();
        }
    }

    static const Akregator::TreeNode* nodeForIndex( const QModelIndex& index, const Akregator::FeedList* feedList )
    {
        return ( !index.isValid() || !feedList ) ? 0 : feedList->findByID( index.internalId() );
    }
}

Akregator::SubscriptionListModel::SubscriptionListModel( const Akregator::FeedList* feedList, QObject* parent ) : QAbstractItemModel( parent ), m_feedList( feedList ), m_beganRemoval( false )
{
    if ( feedList )
    {
        connect( feedList, SIGNAL( signalDestroyed( Akregator::FeedList* ) ),
                 this, SLOT( feedListDestroyed( Akregator::FeedList* ) ) );
        connect( feedList, SIGNAL( signalNodeAdded( Akregator::TreeNode* ) ),
                 this, SLOT( subscriptionAdded( Akregator::TreeNode* ) ) );
        connect( feedList, SIGNAL( signalAboutToRemoveNode( Akregator::TreeNode* ) ),
                 this, SLOT( aboutToRemoveSubscription( Akregator::TreeNode* ) ) );
        connect( feedList, SIGNAL( signalNodeRemoved( Akregator::TreeNode* ) ),
                   this, SLOT( subscriptionRemoved( Akregator::TreeNode* ) ) );
        connect( feedList, SIGNAL( signalNodeChanged( Akregator::TreeNode* ) ),
                 this, SLOT( subscriptionChanged( Akregator::TreeNode* ) ) );
        connect( feedList, SIGNAL( fetchStarted( Akregator::Feed* ) ),
                 this, SLOT( fetchStarted( Akregator::Feed* ) ) );
        connect( feedList, SIGNAL( fetched( Akregator::Feed* ) ),
                 this, SLOT( fetched( Akregator::Feed* ) ) );
        connect( feedList, SIGNAL( fetchAborted( Akregator::Feed* ) ),
                 this, SLOT( fetchAborted( Akregator::Feed* ) ) );
    }
}

int Akregator::SubscriptionListModel::columnCount( const QModelIndex& ) const
{
    return 3;
}

int Akregator::SubscriptionListModel::rowCount( const QModelIndex& parent ) const
{
    if ( !parent.isValid() )
        return 1;

    const Akregator::TreeNode* const node = nodeForIndex( parent, m_feedList );
    return node ? node->children().count() : 0;
}

uint Akregator::SubscriptionListModel::nodeIdForIndex( const QModelIndex& idx ) const
{
    return idx.isValid() ? idx.internalId() : 0;
}

QVariant Akregator::SubscriptionListModel::data( const QModelIndex& index, int role ) const
{
    if ( !index.isValid() )
        return QVariant();

    const Akregator::TreeNode* const node = nodeForIndex( index, m_feedList );

    if ( !node )
        return QVariant();

    switch ( role )
    {
        case Qt::DisplayRole:
        {
            switch ( index.column() )
            {
                case TitleColumn:
                    return node->title();
                case UnreadCountColumn:
                    return node->unread();
                case TotalCountColumn:
                    return node->totalCount();
            }
        }
        case Qt::FontRole:
        {
            if(node->unread() > 0) {
                QFont font;
                font.setBold(true);
                return font;
            }
        }
        case Qt::ToolTipRole:
        {
            if ( node->isGroup() || node->isAggregation() )
                return QString();
            const Feed* const feed = qobject_cast<const Feed* const>( node );
            if ( feed && feed->fetchErrorOccurred() )
                return i18n( "Could not fetch feed: %1", errorCodeToString( feed->fetchErrorCode() ) );
            else
                return QString();
        }
        case Qt::DecorationRole:
        {
            if ( index.column() != TitleColumn )
                return QVariant();
            const Feed* const feed = qobject_cast<const Feed* const>( node );
            return feed && feed->isFetching() ? node->icon().pixmap( KIconLoader::SizeSmall, QIcon::Active ) : node->icon();
        }
        case SubscriptionIdRole:
        {
            return node->id();
        }
        case IsGroupRole:
        {
            return node->isGroup();
        }
        case IsFetchableRole:
        {
            return !node->isGroup() && !node->isAggregation();
        }
        case IsAggregationRole:
        {
            return node->isAggregation();
        }
        case LinkRole:
        {
        	const Feed* const feed = qobject_cast<const Feed* const>( node );
        	return feed ? feed->xmlUrl() : QVariant();
        }
        case IsOpenRole:
        {
            if ( !node->isGroup() )
                return false;
            const Akregator::Folder* const folder = qobject_cast<const Akregator::Folder* const>( node );
            Q_ASSERT( folder );
            return folder->isOpen();
        }
    }

    return QVariant();
}

QVariant Akregator::SubscriptionListModel::headerData( int section, Qt::Orientation, int role ) const
{
    if ( role != Qt::DisplayRole )
        return QVariant();

    switch (section)
    {
        case TitleColumn:
            return i18n("Feeds");
        case UnreadCountColumn:
            return i18n("Unread");
        case TotalCountColumn:
            return i18n("Total");
    }

    return QVariant();
}

QModelIndex Akregator::SubscriptionListModel::parent( const QModelIndex& index ) const
{
    const Akregator::TreeNode* const node = nodeForIndex( index, m_feedList );

    if ( !node || !node->parent() )
        return QModelIndex();

    const Akregator::Folder* parent = node->parent();

    if ( !parent->parent() )
        return createIndex( 0, 0, parent->id() );

    const Akregator::Folder* const grandparent = parent->parent();

    const int row = grandparent->indexOf( parent );

    Q_ASSERT( row != -1 );

    return createIndex( row, 0, parent->id() );
}

QModelIndex Akregator::SubscriptionListModel::index( int row, int column, const QModelIndex& parent ) const
{
    if ( !parent.isValid() )
        return ( row == 0 && m_feedList ) ? createIndex( row, column , m_feedList->rootNode()->id() ) : QModelIndex();

    const Akregator::TreeNode* const parentNode = nodeForIndex( parent, m_feedList );
    const Akregator::TreeNode* const childNode = parentNode->childAt( row );
    return  childNode ? createIndex( row, column, childNode->id() ) : QModelIndex();
}

QModelIndex SubscriptionListModel::indexForNode( const TreeNode* node ) const
{
    if ( !node || !m_feedList )
        return QModelIndex();
    const Folder* const parent = node->parent();
    if ( !parent )
        return index( 0, 0 );
    const int row = parent->indexOf( node );
    Q_ASSERT( row >= 0 );
    const QModelIndex idx = index( row, 0, indexForNode( parent ) );
    Q_ASSERT( idx.internalId() == node->id() );
    return idx;
}

void Akregator::SubscriptionListModel::feedListDestroyed( Akregator::FeedList* )
{
    m_feedList = 0;
}

void Akregator::SubscriptionListModel::subscriptionAdded( Akregator::TreeNode* subscription )
{
    const Folder* const parent = subscription->parent();
    const int row = parent ? parent->indexOf( subscription ) : 0;
    Q_ASSERT( row >= 0 );
    beginInsertRows( indexForNode( parent ), row, row );
    endInsertRows();
}

void Akregator::SubscriptionListModel::aboutToRemoveSubscription( Akregator::TreeNode* subscription )
{
    kDebug() << subscription->id() << endl;
    const Folder* const parent = subscription->parent();
    const int row = parent ? parent->indexOf( subscription ) : -1;
    if ( row < 0 )
        return;
    beginRemoveRows( indexForNode( parent ), row, row );
    m_beganRemoval = true;
}

void Akregator::SubscriptionListModel::subscriptionRemoved( TreeNode* subscription )
{
    kDebug() << subscription->id() << endl;
    if ( m_beganRemoval )
    {
        m_beganRemoval = false;
        endRemoveRows();
    }
}

void Akregator::SubscriptionListModel::subscriptionChanged( TreeNode* node )
{
    const QModelIndex idx = indexForNode( node );
    if ( !idx.isValid() )
        return;
    emit dataChanged( index( idx.row(), 0, idx.parent() ),
                      index( idx.row(), ColumnCount - 1, idx.parent() ) );
}

void SubscriptionListModel::fetchStarted( Akregator::Feed* node )
{
    subscriptionChanged( node );
}

void SubscriptionListModel::fetched( Akregator::Feed* node )
{
    subscriptionChanged( node );
}

void SubscriptionListModel::fetchError( Akregator::Feed* node )
{
    subscriptionChanged( node );
}

void Akregator::FolderExpansionHandler::itemExpanded( const QModelIndex& idx )
{
    setExpanded( idx, true );
}

void Akregator::FolderExpansionHandler::itemCollapsed( const QModelIndex& idx )
{
    setExpanded( idx, false );
}

void Akregator::FolderExpansionHandler::setExpanded( const QModelIndex& idx, bool expanded )
{
    if ( !m_feedList || !m_model )
        return;
    Akregator::TreeNode* const node = m_feedList->findByID( m_model->nodeIdForIndex( idx ) );
    if ( !node || !node->isGroup() )
        return;

    Akregator::Folder* const folder = qobject_cast<Akregator::Folder*>( node );
    Q_ASSERT( folder );
    folder->setOpen( expanded );
}

Akregator::FolderExpansionHandler::FolderExpansionHandler( QObject* parent ) : QObject( parent ), m_feedList( 0 ), m_model( 0 )
{
}

void Akregator::FolderExpansionHandler::setModel( Akregator::SubscriptionListModel* model )
{
    m_model = model;
}

void Akregator::FolderExpansionHandler::setFeedList( Akregator::FeedList* feedList )
{
    m_feedList = feedList;
}

Qt::ItemFlags SubscriptionListModel::flags( const QModelIndex& idx ) const
{
    const Qt::ItemFlags flags = QAbstractItemModel::flags( idx );
    if ( !idx.isValid() || ( idx.column() != TitleColumn ) )
        return flags;
    if ( !idx.parent().isValid() ) // the root folder is neither draggable nor editable
        return flags | Qt::ItemIsDropEnabled;
    return flags | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | Qt::ItemIsEditable;
}

QStringList SubscriptionListModel::mimeTypes() const
{
    QStringList types;
    types << "text/uri-list" << AKREGATOR_TREENODE_MIMETYPE;
    return types;
}

QMimeData* SubscriptionListModel::mimeData( const QModelIndexList& indexes ) const
{
    QMimeData* mimeData = new QMimeData;

    QList<QUrl> urls;
    Q_FOREACH ( const QModelIndex& i, indexes )
    {
        const QUrl url = i.data( LinkRole ).toString();
        if ( !url.isEmpty() )
            urls << url;
    }

    mimeData->setUrls( urls );

    QByteArray idList;
    QDataStream idStream( &idList, QIODevice::WriteOnly );
    Q_FOREACH ( const QModelIndex& i, indexes )
        if ( i.isValid() )
            idStream << i.data( SubscriptionIdRole ).toInt();

    mimeData->setData( AKREGATOR_TREENODE_MIMETYPE, idList );

    return mimeData;
}

bool SubscriptionListModel::setData( const QModelIndex& idx, const QVariant& value, int role )
{
    if ( !idx.isValid() || idx.column() != TitleColumn || role != Qt::EditRole )
        return false;
    const TreeNode* const node = nodeForIndex( idx, m_feedList );
    if ( !node )
        return false;
    RenameSubscriptionJob* job = new RenameSubscriptionJob( this );
    job->setSubscriptionId( node->id() );
    job->setName( value.toString() );
    job->start();
    return true;
}

bool SubscriptionListModel::dropMimeData( const QMimeData* data,
                                          Qt::DropAction action,
                                          int row,
                                          int column,
                                          const QModelIndex& parent )
{
    if ( action == Qt::IgnoreAction )
        return true;

    //if ( column != TitleColumn )
    //    return false;

    if ( data->hasFormat( AKREGATOR_TREENODE_MIMETYPE ) )
    {
        const TreeNode* const droppedOnNode = qobject_cast<const TreeNode*>( nodeForIndex( parent, m_feedList ) );

        const Folder* const destFolder = droppedOnNode->isGroup() ? qobject_cast<const Folder*>( droppedOnNode ) : droppedOnNode->parent();
        if ( !destFolder )
            return false;

        QByteArray idData = data->data( AKREGATOR_TREENODE_MIMETYPE );
        QList<int> ids;
        QDataStream stream( &idData, QIODevice::ReadOnly );
        while ( !stream.atEnd() )
        {
            int id;
            stream >> id;
            ids << id;
        }

        //don't drop nodes into their own subtree
        Q_FOREACH ( const int id, ids )
        {
            const Folder* const asFolder = qobject_cast<const Folder*>( m_feedList->findByID( id ) );
            if ( asFolder && asFolder->subtreeContains( destFolder ) )
                return false;
        }

        const TreeNode* const after = droppedOnNode->isGroup() ? destFolder->childAt( row ) : droppedOnNode;

        Q_FOREACH ( const int id, ids )
        {
            const TreeNode* const node = m_feedList->findByID( id );
            if ( !node )
                continue;
            MoveSubscriptionJob* job = new MoveSubscriptionJob( this );
            job->setSubscriptionId( node->id() );
            job->setDestination( destFolder->id(), after ? after->id() : -1 );
            job->start();
        }
        return true;
    }

    return false;
}

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


<commit_before>#pragma once
#ifndef DELEGATE_HPP
# define DELEGATE_HPP

#include <cassert>

#include <memory>

#include <new>

#include <type_traits>

#include <utility>

template <typename T> class delegate;

template<class R, class ...A>
class delegate<R (A...)>
{
  typedef R (*stub_ptr_type)(void*, A&&...);

  delegate(void* const o, stub_ptr_type const m) noexcept
    : object_ptr_(o),
      stub_ptr_(m)
  {
  }

public:
  delegate() = default;

  delegate(delegate const&) = default;

  delegate(delegate&&) = default;

  template <class C>
  explicit delegate(C const* const o) noexcept
    : object_ptr_(const_cast<C*>(o))
  {
  }

  template <class C>
  explicit delegate(C const& o) noexcept
    : object_ptr_(const_cast<C*>(&o))
  {
  }

  delegate(R (* const function_ptr)(A...))
  {
    *this = from(function_ptr);
  }

  template <class C>
  delegate(C* const object_ptr, R (C::* const method_ptr)(A...))
  {
    *this = from(object_ptr, method_ptr);
  }

  template <class C>
  delegate(C* const object_ptr, R (C::* const method_ptr)(A...) const)
  {
    *this = from(object_ptr, method_ptr);
  }

  template <class C>
  delegate(C& object, R (C::* const method_ptr)(A...))
  {
    *this = from(object, method_ptr);
  }

  template <class C>
  delegate(C const& object, R (C::* const method_ptr)(A...) const)
  {
    *this = from(object, method_ptr);
  }

  template <
    typename T,
    typename = typename std::enable_if<
      !std::is_same<delegate, typename std::decay<T>::type>::value
    >::type
  >
  delegate(T&& f)
    : store_(operator new(sizeof(T)),
        functor_deleter<typename std::decay<T>::type>),
      store_size_(sizeof(T))
  {
    typedef typename std::decay<T>::type functor_type;

    new (store_.get()) functor_type(std::forward<T>(f));

    object_ptr_ = store_.get();

    stub_ptr_ = functor_stub<functor_type>;

    deleter_ = destructor_stub<functor_type>;
  }

  delegate& operator=(delegate const&) = default;

  delegate& operator=(delegate&& rhs) = default;

  delegate& operator=(R (* const function_ptr)(A...))
  {
    return *this = from(function_ptr);
  }

  template <class C>
  delegate& operator=(R (C::* const rhs)(A...))
  {
    return *this = from(static_cast<C*>(object_ptr_), rhs);
  }

  template <class C>
  delegate& operator=(R (C::* const rhs)(A...) const)
  {
    return *this = from(static_cast<C const*>(object_ptr_), rhs);
  }

  template <
    typename T,
    typename = typename std::enable_if<
      !std::is_same<delegate, typename std::decay<T>::type>::value
    >::type
  >
  delegate& operator=(T&& f)
  {
    typedef typename std::decay<T>::type functor_type;

    if ((sizeof(T) > store_size_)
      || (decltype(store_.use_count())(1) != store_.use_count()))
    {
      store_.reset(operator new(sizeof(T)), functor_deleter<functor_type>);

      store_size_ = sizeof(T);
    }
    else
    {
      deleter_(store_.get());
    }

    new (store_.get()) functor_type(std::forward<T>(f));

    object_ptr_ = store_.get();

    stub_ptr_ = functor_stub<functor_type>;

    deleter_ = destructor_stub<functor_type>;

    return *this;
  }

  template <R (* const function_ptr)(A...)>
  static delegate from() noexcept
  {
    return { nullptr, function_stub<function_ptr> };
  }

  template <class C, R (C::* const method_ptr)(A...)>
  static delegate from(C* object_ptr) noexcept
  {
    return { object_ptr, method_stub<C, method_ptr> };
  }

  template <class C, R (C::* const method_ptr)(A...) const>
  static delegate from(C const* object_ptr) noexcept
  {
    return { const_cast<C*>(object_ptr), const_method_stub<C, method_ptr> };
  }

  template <class C, R (C::* const method_ptr)(A...)>
  static delegate from(C& object) noexcept
  {
    return { &object, method_stub<C, method_ptr> };
  }

  template <class C, R (C::* const method_ptr)(A...) const>
  static delegate from(C const& object) noexcept
  {
    return { const_cast<C*>(&object), const_method_stub<C, method_ptr> };
  }

  template <typename T>
  static delegate from(T&& f)
  {
    return std::forward<T>(f);
  }

  static delegate from(R (* const function_ptr)(A...))
  {
    return [function_ptr](A&&... args) {
      return (*function_ptr)(std::forward<A>(args)...); };
  }

  template <class C>
  static delegate from(C* const object_ptr,
    R (C::* const method_ptr)(A...))
  {
    return [object_ptr, method_ptr](A&&... args) {
      return (object_ptr->*method_ptr)(std::forward<A>(args)...); };
  }

  template <class C>
  static delegate from(C const* const object_ptr,
    R (C::* const method_ptr)(A...) const)
  {
    return [object_ptr, method_ptr](A&&... args) {
      return (object_ptr->*method_ptr)(std::forward<A>(args)...); };
  }

  template <class C>
  static delegate from(C& object, R (C::* const method_ptr)(A...))
  {
    return [&object, method_ptr](A&&... args) {
      return (object.*method_ptr)(std::forward<A>(args)...); };
  }

  template <class C>
  static delegate from(C const& object,
    R (C::* const method_ptr)(A...) const)
  {
    return [&object, method_ptr](A&&... args) {
      return (object.*method_ptr)(std::forward<A>(args)...); };
  }

  void reset() { stub_ptr_ = nullptr; store_.reset(); }

  void swap(delegate& other) noexcept { ::std::swap(*this, other); }

  bool operator==(delegate const& rhs) const noexcept
  {
    return (object_ptr_ == rhs.object_ptr_) && (stub_ptr_ == rhs.stub_ptr_);
  }

  bool operator!=(delegate const& rhs) const noexcept
  {
    return !operator==(rhs);
  }

  bool operator<(delegate const& rhs) const noexcept
  {
    return (object_ptr_ < rhs.object_ptr_) || (stub_ptr_ < rhs.stub_ptr_);
  }

  explicit operator bool() const noexcept { return stub_ptr_; }

  R operator()(A... args) const
  {
//  assert(stub_ptr);
    return stub_ptr_(object_ptr_, std::forward<A>(args)...);
  }

private:
  friend class ::std::hash<delegate>;

  typedef void (*deleter_type)(void*);

  void* object_ptr_;
  stub_ptr_type stub_ptr_{};

  deleter_type deleter_;

  std::shared_ptr<void> store_;
  std::size_t store_size_;

  template <class T>
  static void destructor_stub(void* const p)
  {
    static_cast<T*>(p)->~T();
  }

  template <class T>
  static void functor_deleter(void* const p)
  {
    static_cast<T*>(p)->~T();

    operator delete(p);
  }

  template <R (*function_ptr)(A...)>
  static R function_stub(void* const, A&&... args)
  {
    return function_ptr(std::forward<A>(args)...);
  }

  template <class C, R (C::*method_ptr)(A...)>
  static R method_stub(void* const object_ptr, A&&... args)
  {
    return (static_cast<C*>(object_ptr)->*method_ptr)(
      std::forward<A>(args)...);
  }

  template <class C, R (C::*method_ptr)(A...) const>
  static R const_method_stub(void* const object_ptr, A&&... args)
  {
    return (static_cast<C const*>(object_ptr)->*method_ptr)(
      std::forward<A>(args)...);
  }

  template <typename T>
  static R functor_stub(void* const object_ptr, A&&... args)
  {
    return (*static_cast<T*>(object_ptr))(std::forward<A>(args)...);
  }
};

namespace std
{
  template <typename R, typename ...A>
  struct hash<delegate<R (A...)> >
  {
    size_t operator()(delegate<R (A...)> const& d) const noexcept
    {
      auto const seed(hash<void*>()(d.object_ptr_) + 0x9e3779b9);

      return hash<typename delegate<R (A...)>::stub_ptr_type>()(d.stub_ptr_)
        + 0x9e3779b9 + (seed << 6) + (seed >> 2);
    }
  };
}

#endif // DELEGATE_HPP
<commit_msg>strips<commit_after>#pragma once
#ifndef DELEGATE_HPP
# define DELEGATE_HPP

#include <cassert>

#include <memory>

#include <new>

#include <type_traits>

#include <utility>

template <typename T> class delegate;

template<class R, class ...A>
class delegate<R (A...)>
{
  typedef R (*stub_ptr_type)(void*, A&&...);

  delegate(void* const o, stub_ptr_type const m) noexcept
    : object_ptr_(o),
      stub_ptr_(m)
  {
  }

public:
  delegate() = default;

  delegate(delegate const&) = default;

  delegate(delegate&&) = default;

  template <class C>
  explicit delegate(C const* const o) noexcept
    : object_ptr_(const_cast<C*>(o))
  {
  }

  template <class C>
  explicit delegate(C const& o) noexcept
    : object_ptr_(const_cast<C*>(&o))
  {
  }

  delegate(R (* const function_ptr)(A...))
  {
    *this = from(function_ptr);
  }

  template <class C>
  delegate(C* const object_ptr, R (C::* const method_ptr)(A...))
  {
    *this = from(object_ptr, method_ptr);
  }

  template <class C>
  delegate(C* const object_ptr, R (C::* const method_ptr)(A...) const)
  {
    *this = from(object_ptr, method_ptr);
  }

  template <class C>
  delegate(C& object, R (C::* const method_ptr)(A...))
  {
    *this = from(object, method_ptr);
  }

  template <class C>
  delegate(C const& object, R (C::* const method_ptr)(A...) const)
  {
    *this = from(object, method_ptr);
  }

  template <
    typename T,
    typename = typename std::enable_if<
      !std::is_same<delegate, typename std::decay<T>::type>::value
    >::type
  >
  delegate(T&& f)
    : store_(operator new(sizeof(T)),
        functor_deleter<typename std::decay<T>::type>),
      store_size_(sizeof(T))
  {
    typedef typename std::decay<T>::type functor_type;

    new (store_.get()) functor_type(std::forward<T>(f));

    object_ptr_ = store_.get();

    stub_ptr_ = functor_stub<functor_type>;

    deleter_ = destructor_stub<functor_type>;
  }

  delegate& operator=(delegate const&) = default;

  delegate& operator=(delegate&& rhs) = default;

  delegate& operator=(R (* const rhs)(A...))
  {
    return *this = from(rhs);
  }

  template <class C>
  delegate& operator=(R (C::* const rhs)(A...))
  {
    return *this = from(static_cast<C*>(object_ptr_), rhs);
  }

  template <class C>
  delegate& operator=(R (C::* const rhs)(A...) const)
  {
    return *this = from(static_cast<C const*>(object_ptr_), rhs);
  }

  template <
    typename T,
    typename = typename std::enable_if<
      !std::is_same<delegate, typename std::decay<T>::type>::value
    >::type
  >
  delegate& operator=(T&& f)
  {
    typedef typename std::decay<T>::type functor_type;

    if ((sizeof(T) > store_size_)
      || (decltype(store_.use_count())(1) != store_.use_count()))
    {
      store_.reset(operator new(sizeof(T)), functor_deleter<functor_type>);

      store_size_ = sizeof(T);
    }
    else
    {
      deleter_(store_.get());
    }

    new (store_.get()) functor_type(std::forward<T>(f));

    object_ptr_ = store_.get();

    stub_ptr_ = functor_stub<functor_type>;

    deleter_ = destructor_stub<functor_type>;

    return *this;
  }

  template <R (* const function_ptr)(A...)>
  static delegate from() noexcept
  {
    return { nullptr, function_stub<function_ptr> };
  }

  template <class C, R (C::* const method_ptr)(A...)>
  static delegate from(C* object_ptr) noexcept
  {
    return { object_ptr, method_stub<C, method_ptr> };
  }

  template <class C, R (C::* const method_ptr)(A...) const>
  static delegate from(C const* object_ptr) noexcept
  {
    return { const_cast<C*>(object_ptr), const_method_stub<C, method_ptr> };
  }

  template <class C, R (C::* const method_ptr)(A...)>
  static delegate from(C& object) noexcept
  {
    return { &object, method_stub<C, method_ptr> };
  }

  template <class C, R (C::* const method_ptr)(A...) const>
  static delegate from(C const& object) noexcept
  {
    return { const_cast<C*>(&object), const_method_stub<C, method_ptr> };
  }

  template <typename T>
  static delegate from(T&& f)
  {
    return std::forward<T>(f);
  }

  static delegate from(R (* const function_ptr)(A...))
  {
    return [function_ptr](A&&... args) {
      return (*function_ptr)(std::forward<A>(args)...); };
  }

  template <class C>
  static delegate from(C* const object_ptr,
    R (C::* const method_ptr)(A...))
  {
    return [object_ptr, method_ptr](A&&... args) {
      return (object_ptr->*method_ptr)(std::forward<A>(args)...); };
  }

  template <class C>
  static delegate from(C const* const object_ptr,
    R (C::* const method_ptr)(A...) const)
  {
    return [object_ptr, method_ptr](A&&... args) {
      return (object_ptr->*method_ptr)(std::forward<A>(args)...); };
  }

  template <class C>
  static delegate from(C& object, R (C::* const method_ptr)(A...))
  {
    return [&object, method_ptr](A&&... args) {
      return (object.*method_ptr)(std::forward<A>(args)...); };
  }

  template <class C>
  static delegate from(C const& object,
    R (C::* const method_ptr)(A...) const)
  {
    return [&object, method_ptr](A&&... args) {
      return (object.*method_ptr)(std::forward<A>(args)...); };
  }

  void reset() { stub_ptr_ = nullptr; store_.reset(); }

  void swap(delegate& other) noexcept { ::std::swap(*this, other); }

  bool operator==(delegate const& rhs) const noexcept
  {
    return (object_ptr_ == rhs.object_ptr_) && (stub_ptr_ == rhs.stub_ptr_);
  }

  bool operator!=(delegate const& rhs) const noexcept
  {
    return !operator==(rhs);
  }

  bool operator<(delegate const& rhs) const noexcept
  {
    return (object_ptr_ < rhs.object_ptr_) || (stub_ptr_ < rhs.stub_ptr_);
  }

  explicit operator bool() const noexcept { return stub_ptr_; }

  R operator()(A... args) const
  {
//  assert(stub_ptr);
    return stub_ptr_(object_ptr_, std::forward<A>(args)...);
  }

private:
  friend class ::std::hash<delegate>;

  typedef void (*deleter_type)(void*);

  void* object_ptr_;
  stub_ptr_type stub_ptr_{};

  deleter_type deleter_;

  std::shared_ptr<void> store_;
  std::size_t store_size_;

  template <class T>
  static void destructor_stub(void* const p)
  {
    static_cast<T*>(p)->~T();
  }

  template <class T>
  static void functor_deleter(void* const p)
  {
    static_cast<T*>(p)->~T();

    operator delete(p);
  }

  template <R (*function_ptr)(A...)>
  static R function_stub(void* const, A&&... args)
  {
    return function_ptr(std::forward<A>(args)...);
  }

  template <class C, R (C::*method_ptr)(A...)>
  static R method_stub(void* const object_ptr, A&&... args)
  {
    return (static_cast<C*>(object_ptr)->*method_ptr)(
      std::forward<A>(args)...);
  }

  template <class C, R (C::*method_ptr)(A...) const>
  static R const_method_stub(void* const object_ptr, A&&... args)
  {
    return (static_cast<C const*>(object_ptr)->*method_ptr)(
      std::forward<A>(args)...);
  }

  template <typename T>
  static R functor_stub(void* const object_ptr, A&&... args)
  {
    return (*static_cast<T*>(object_ptr))(std::forward<A>(args)...);
  }
};

namespace std
{
  template <typename R, typename ...A>
  struct hash<delegate<R (A...)> >
  {
    size_t operator()(delegate<R (A...)> const& d) const noexcept
    {
      auto const seed(hash<void*>()(d.object_ptr_) + 0x9e3779b9);

      return hash<typename delegate<R (A...)>::stub_ptr_type>()(d.stub_ptr_)
        + 0x9e3779b9 + (seed << 6) + (seed >> 2);
    }
  };
}

#endif // DELEGATE_HPP
<|endoftext|>