Logo Search packages:      
Sourcecode: mapnik-viewer version File versions  Download package

styles_model.cpp

/* This file is part of Mapnik (c++ mapping toolkit)
 * Copyright (C) 2007 Artem Pavlenko
 *
 * Mapnik 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 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.
 */

//$Id$

#include "styles_model.hpp"
#include <mapnik/expression_string.hpp>
// boost
#include <boost/concept_check.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/utility.hpp>
// qt
#include <QList>
#include <QIcon>
#include <QPainter>
#include <QPixmap>

00033 class node : private boost::noncopyable
{
00035     struct node_base
    {
      virtual QString name() const=0;
      virtual QIcon   icon() const=0;
      virtual ~node_base() {}
    };
      
    template <typename T>
00043     struct wrap : public node_base
    {
      wrap(T const& obj)
          : obj_(obj) {}
            
      ~wrap() {}
            
      QString name () const
      {
          return obj_.name();
      }
            
      QIcon icon() const
      {
          return obj_.icon();
      }
            
      T obj_;
    };
      
public:
    template <typename T> 
    node ( T const& obj, node * parent=0)
      : impl_(new wrap<T>(obj)),
        parent_(parent)
    {}
      
    QString name() const
    {
      return impl_->name();
    }
      
    QIcon icon() const
    {
      return impl_->icon();
    }
      
    unsigned num_children() const
    {
      return children_.count();
    }
      
    node * child(unsigned row) const
    {
      return children_.value(row);
    }
      
    node * parent() const
    {
      return parent_;
    }
      
    node * add_child(node * child)
    {
      children_.push_back(child);
      return child;
    }
    int row () const
    {
      if (parent_)
            return parent_->children_.indexOf(const_cast<node*>(this));
      else
            return 0;
    }
      
    ~node() 
    {
      qDeleteAll(children_);
    }
      
private:
    boost::scoped_ptr<node_base> impl_;
    QList<node*> children_;
    node * parent_;
};


00120 struct symbolizer_info : public boost::static_visitor<QString>
{
    QString operator() (mapnik::point_symbolizer const& sym) const
    {
      boost::ignore_unused_variable_warning(sym);
      return QString("PointSymbolizer");
    }
      
    QString operator() (mapnik::line_symbolizer const& sym) const
    {
      boost::ignore_unused_variable_warning(sym);
      return QString("LineSymbolizer");
    }

    QString operator() (mapnik::line_pattern_symbolizer const& sym) const
    {
      boost::ignore_unused_variable_warning(sym);
      return QString("LinePatternSymbolizer");
    }

    QString operator() (mapnik::polygon_symbolizer const& sym) const
    {
      boost::ignore_unused_variable_warning(sym);
      return QString("PolygonSymbolizer");
    }

    QString operator() (mapnik::polygon_pattern_symbolizer const& sym) const
    {
      boost::ignore_unused_variable_warning(sym);
      return QString("PolygonSymbolizer");
    }
            
    QString operator() (mapnik::text_symbolizer const& sym) const
    {
      boost::ignore_unused_variable_warning(sym);
      return QString("TextSymbolizer");
    }
      
    QString operator() (mapnik::shield_symbolizer const& sym) const
    {
      boost::ignore_unused_variable_warning(sym);
      return QString("ShieldSymbolizer");
    }
      
    template <typename T>
    QString operator() (T const& ) const
    {
      return QString ("FIXME");
    }
};

00171 struct symbolizer_icon : public boost::static_visitor<QIcon>
{
    QIcon operator() (mapnik::polygon_symbolizer const& sym) const
    {
      QPixmap pix(16,16);
      QPainter painter(&pix);
      mapnik::color const& fill = sym.get_fill();
      QBrush brush(QColor(fill.red(),fill.green(),fill.blue(),fill.alpha()));
      painter.fillRect(0, 0, 16, 16, brush);
      return QIcon(pix);
    }

    QIcon operator() (mapnik::point_symbolizer const& sym) const
    {
      // FIXME!
      /*
        boost::shared_ptr<mapnik::image_data_32> symbol = sym.get_image();
        if (symbol)
        {
        QImage image(symbol->getBytes(),
        symbol->width(),symbol->height(),QImage::Format_ARGB32);
        QPixmap pix = QPixmap::fromImage(image.rgbSwapped());
        return QIcon(pix);
        }
      */
      return QIcon();
    }
    QIcon operator() (mapnik::line_symbolizer const& sym) const
    {
      QPixmap pix(48,16);
      pix.fill();
      QPainter painter(&pix);
      mapnik::stroke const&  strk = sym.get_stroke(); 
      mapnik::color const& col = strk.get_color();
      QPen pen(QColor(col.red(),col.green(),col.blue(),col.alpha()));
      pen.setWidth(strk.get_width());
      painter.setPen(pen);
      painter.drawLine(0,7,47,7);
      //painter.drawLine(7,15,12,0);
      //painter.drawLine(12,0,8,15);      
      return QIcon(pix);
    }

    template <typename T>
    QIcon operator() (T const& ) const
    {
      return QIcon (":/images/filter.png");
    }
};

00221 class symbolizer_node
{
public:
    symbolizer_node(mapnik::symbolizer const & sym)
      : sym_(sym) {}
    ~symbolizer_node(){}
      
    QString name() const 
    {
      //return QString("Symbolizer:fixme");
      return boost::apply_visitor(symbolizer_info(),sym_);
    }
      
    QIcon icon() const
    {
      return boost::apply_visitor(symbolizer_icon(),sym_);//QIcon(":/images/filter.png");
    }
    mapnik::symbolizer const& sym_;
};

00241 class rule_node
{
public:
    rule_node(QString name,mapnik::rule const & r)
      : name_(name),
        rule_(r) {}
    ~rule_node() {}
    QString name() const
    {
      mapnik::expression_ptr filter = rule_.get_filter();
         
      return QString(mapnik::to_expression_string(*filter).c_str());
    } 
      
    QIcon icon() const
    {
      return QIcon(":/images/filter.png");
    }
      
private:
    QString name_;
    mapnik::rule const& rule_;
};

00265 class style_node
{
public:
    style_node(QString name, mapnik::feature_type_style const& style)
      : name_(name),
        style_(style) {}
      
    ~style_node() {}
      
    QString name() const
    {
      return name_;
    }
      
    QIcon icon() const
    {
      return QIcon(":/images/style.png");
    }
      
private:
    QString name_;
    mapnik::feature_type_style const& style_;
};

00289 class map_node
{
public:
    explicit map_node(boost::shared_ptr<mapnik::Map> map)
      : map_(map)  {}
    ~map_node() {}
      
    QString name() const
    {
      return QString("Map");
    }
      
    QIcon icon() const
    {
      return QIcon(":/images/map.png");
    }
      
private:
    boost::shared_ptr<mapnik::Map> map_;
};

StyleModel::StyleModel(boost::shared_ptr<mapnik::Map> map, QObject * parent)
    : QAbstractItemModel(parent),
      root_(new node(map_node(map))) 
{
    typedef std::map<std::string,mapnik::feature_type_style> style_type; 
    style_type const & styles = map->styles();
    style_type::const_iterator itr = styles.begin();
    style_type::const_iterator end = styles.end();
    for (; itr != end; ++itr)
    {
      node * style_n = root_->add_child(new node(style_node(QString(itr->first.c_str()),itr->second),root_.get()));
      mapnik::rules const& rules = itr->second.get_rules();
      mapnik::rules::const_iterator itr2 = rules.begin();
      for ( ; itr2 != rules.end();++itr2)
      {
          node* rule_n = style_n->add_child(new node(rule_node(QString("Rule"),*itr2),style_n));
          mapnik::rule::symbolizers::const_iterator itr3 = (*itr2).begin();
          for ( ; itr3 !=itr2->end();++itr3)
          {
            rule_n->add_child(new node(symbolizer_node(*itr3),rule_n));
          }
      }
    }   
}

StyleModel::~StyleModel() {}

// interface 
QModelIndex StyleModel::index (int row, int col, QModelIndex const& parent) const
{
//   qDebug("index() row=%d col=%d parent::internalId() = %lld", row,col,parent.internalId());
    node * parent_node;
   
    if (!parent.isValid())
      parent_node = root_.get();
    else
      parent_node = static_cast<node*>(parent.internalPointer());
   
    node * child_node = parent_node->child(row);
    if (child_node)
      return createIndex(row,col,child_node);
    else
      return QModelIndex();
}

QModelIndex StyleModel::parent (QModelIndex const& index) const
{
    node * child_node = static_cast<node*>(index.internalPointer());
    node * parent_node = child_node->parent();
    if (parent_node == root_.get())
      return QModelIndex();
  
    return createIndex(parent_node->row(),0,parent_node);
}

int StyleModel::rowCount(QModelIndex const& parent) const
{
    //qDebug("rowCount");
    node * parent_node;
    if (parent.column() > 0) return 0;
    if (!parent.isValid())
      parent_node = root_.get();
    else
      parent_node = static_cast<node*>(parent.internalPointer());
    return parent_node->num_children();
}

int StyleModel::columnCount( QModelIndex const&) const
{
    return 1;
}

QVariant StyleModel::data(const QModelIndex & index, int role) const
{
    //qDebug("data index::internalId() = %lld", index.internalId());
    if (!index.isValid())
      return QVariant();
    node * cur_node = static_cast<node*>(index.internalPointer());
    if (cur_node)
    {
      if (role == Qt::DisplayRole)
      {
         
          return QVariant(cur_node->name());
      }
      else if ( role == Qt::DecorationRole)
      {
          return cur_node->icon();
      }
    }
    return QVariant();
}

Generated by  Doxygen 1.6.0   Back to index