예제 #1
0
void FeatureListModel::setFeatures( const QList<QgsMapToolIdentify::IdentifyResult>& results )
{
  beginResetModel();

  qDeleteAll( mFeatures );
  mFeatures.clear();

  disconnect( this, SLOT( layerDeleted() ) );

  Q_FOREACH( const QgsMapToolIdentify::IdentifyResult& res, results )
  {
    Feature* f = new Feature( res.mFeature, qobject_cast<QgsVectorLayer*>( res.mLayer ) );
    mFeatures.append( f );
    connect( f->layer(), SIGNAL( layerDeleted() ), this, SLOT( layerDeleted() ), Qt::UniqueConnection );
  }
예제 #2
0
QgsAttributeTableModel::QgsAttributeTableModel( QgsVectorLayerCache *layerCache, QObject *parent )
    : QAbstractTableModel( parent )
    , mLayerCache( layerCache )
    , mCachedField( -1 )
{
  QgsDebugMsg( "entered." );

  if ( layerCache->layer()->geometryType() == QGis::NoGeometry )
  {
    mFeatureRequest.setFlags( QgsFeatureRequest::NoGeometry );
  }

  mFeat.setFeatureId( std::numeric_limits<int>::min() );

  if ( !layer()->hasGeometryType() )
    mFeatureRequest.setFlags( QgsFeatureRequest::NoGeometry );

  loadAttributes();

  connect( mLayerCache, SIGNAL( attributeValueChanged( QgsFeatureId, int, const QVariant& ) ), this, SLOT( attributeValueChanged( QgsFeatureId, int, const QVariant& ) ) );
  connect( layer(), SIGNAL( featureDeleted( QgsFeatureId ) ), this, SLOT( featureDeleted( QgsFeatureId ) ) );
  connect( layer(), SIGNAL( attributeDeleted( int ) ), this, SLOT( attributeDeleted( int ) ) );
  connect( layer(), SIGNAL( updatedFields() ), this, SLOT( updatedFields() ) );
  connect( layer(), SIGNAL( editCommandEnded() ), this, SLOT( editCommandEnded() ) );
  connect( mLayerCache, SIGNAL( featureAdded( QgsFeatureId ) ), this, SLOT( featureAdded( QgsFeatureId ) ) );
  connect( mLayerCache, SIGNAL( cachedLayerDeleted() ), this, SLOT( layerDeleted() ) );
}
예제 #3
0
QgsAttributeTableModel::QgsAttributeTableModel( QgsVectorLayerCache *layerCache, QObject *parent )
    : QAbstractTableModel( parent )
    , mLayerCache( layerCache )
    , mFieldCount( 0 )
    , mSortCacheExpression( QLatin1String( "" ) )
    , mSortFieldIndex( -1 )
    , mExtraColumns( 0 )
{
  mExpressionContext << QgsExpressionContextUtils::globalScope()
  << QgsExpressionContextUtils::projectScope()
  << QgsExpressionContextUtils::layerScope( layerCache->layer() );

  if ( layerCache->layer()->geometryType() == QgsWkbTypes::NullGeometry )
  {
    mFeatureRequest.setFlags( QgsFeatureRequest::NoGeometry );
  }

  mFeat.setFeatureId( std::numeric_limits<int>::min() );

  if ( !layer()->hasGeometryType() )
    mFeatureRequest.setFlags( QgsFeatureRequest::NoGeometry );

  loadAttributes();

  connect( mLayerCache, SIGNAL( attributeValueChanged( QgsFeatureId, int, const QVariant& ) ), this, SLOT( attributeValueChanged( QgsFeatureId, int, const QVariant& ) ) );
  connect( layer(), SIGNAL( featuresDeleted( QgsFeatureIds ) ), this, SLOT( featuresDeleted( QgsFeatureIds ) ) );
  connect( layer(), SIGNAL( attributeDeleted( int ) ), this, SLOT( attributeDeleted( int ) ) );
  connect( layer(), SIGNAL( updatedFields() ), this, SLOT( updatedFields() ) );
  connect( layer(), SIGNAL( editCommandEnded() ), this, SLOT( editCommandEnded() ) );
  connect( mLayerCache, SIGNAL( featureAdded( QgsFeatureId ) ), this, SLOT( featureAdded( QgsFeatureId ) ) );
  connect( mLayerCache, SIGNAL( cachedLayerDeleted() ), this, SLOT( layerDeleted() ) );
}
예제 #4
0
void QgsAttributeDialog::init( QgsVectorLayer* layer, QgsFeature* feature, const QgsAttributeEditorContext &context )
{
  setWindowTitle( tr( "%1 - Feature Attributes" ).arg( layer->name() ) );
  setLayout( new QGridLayout() );
  layout()->setMargin( 0 );
  mAttributeForm = new QgsAttributeForm( layer, *feature, context, this );
  mAttributeForm->disconnectButtonBox();
  layout()->addWidget( mAttributeForm );
  QDialogButtonBox* buttonBox = mAttributeForm->findChild<QDialogButtonBox*>();
  connect( buttonBox, SIGNAL( rejected() ), this, SLOT( reject() ) );
  connect( buttonBox, SIGNAL( accepted() ), this, SLOT( accept() ) );
  connect( layer, SIGNAL( layerDeleted() ), this, SLOT( close() ) );

  QgsActionMenu* menu = new QgsActionMenu( layer, &mAttributeForm->feature(), this );
  if ( !menu->actions().isEmpty() )
  {
    QMenuBar* menuBar = new QMenuBar( this );
    menuBar->addMenu( menu );
    layout()->setMenuBar( menuBar );
  }
  else
  {
    delete menu;
  }

  restoreGeometry();
  focusNextChild();
}
예제 #5
0
void QgsFieldModel::setLayer( QgsVectorLayer *layer )
{
  if ( mLayer )
  {
    disconnect( mLayer, SIGNAL( updatedFields() ), this, SLOT( updateModel() ) );
    disconnect( mLayer, SIGNAL( layerDeleted() ), this, SLOT( layerDeleted() ) );
  }

  mLayer = layer;

  if ( mLayer )
  {
    connect( mLayer, SIGNAL( updatedFields() ), this, SLOT( updateModel() ) );
    connect( mLayer, SIGNAL( layerDeleted() ), this, SLOT( layerDeleted() ) );
  }

  updateModel();
}
예제 #6
0
void LayerListModel::deleteLayer(int id)
{
	int row = indexOf(id);
	Q_ASSERT(row>=0);
	beginRemoveRows(QModelIndex(), row, row);
	_items.remove(row);
	endRemoveRows();
	emit layerDeleted(id, row+1);
}
예제 #7
0
/****************************************************************************
**
** Copyright (C) 2016 - 2017
**
** This file is generated by the Magus toolkit
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
****************************************************************************/

// Include
#include <QApplication>
#include <QDesktopWidget>
#include <QRect>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QMessageBox>
#include <QHeaderView>
#include <QEvent>
#include <QPixmap>
#include <QImage>
#include <QMimeData>
#include <QTableWidgetItem>
#include <QTreeWidgetItem>
#include <QVector2D>
#include "constants.h"
#include "paintlayer_widget.h"
#include "paintlayer_dockwidget.h"
#include "paintlayer_dialog.h"

//****************************************************************************/
PaintLayerWidget::PaintLayerWidget(const QString& iconDir, PaintLayerDockWidget* paintLayerDockWidget, QWidget* parent) :
    QWidget(parent),
    mPaintLayerDockWidget(paintLayerDockWidget)
{
    setWindowTitle(QString("Layers"));
    QHBoxLayout* mainLayout = new QHBoxLayout;
    QVBoxLayout* tableLayout = new QVBoxLayout;
    mIconDir = iconDir;
    mLayerIdCounter = 1;
    mListenToSceneId = 0;
    mListenToDeleteEvents = true;
    helperIntVector.clear();

    // Create table
    mTable = new QTableWidget(0, 4, this);
    mTable->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    mTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
    mTable->setAcceptDrops(false);
    mTable->setShowGrid(false);
    mTable->viewport()->installEventFilter(this);
    QRect rect = QApplication::desktop()->screenGeometry();
    mTable->setColumnWidth(TOOL_LAYER_COLUMN_ICON, 2 * TOOL_LAYER_ICON_WIDTH);
    mTable->setColumnWidth(TOOL_LAYER_COLUMN_NAME, TOOL_LAYER_NAME_WIDTH);
    mTable->setColumnWidth(TOOL_LAYER_COLUMN_VISIBILITY, 2 * TOOL_LAYER_ICON_WIDTH);
    mTable->setColumnWidth(TOOL_LAYER_COLUMN_FILLER, rect.width());
    mTable->setSelectionBehavior(QAbstractItemView::SelectRows);
    setStyleSheet("QLineEdit{padding: 0 0px; margin-left: 0px; margin-right: 0px; max-height: 28px; height: 28px;}");
    connect(mTable, SIGNAL(clicked(QModelIndex)), this, SLOT(tableClicked(QModelIndex)));
    connect(mTable, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(handleTableDoubleClicked(QModelIndex)));

    // Set headers
    QStringList headers;
    headers << tr("Edit") << tr("Layer name") << tr("Visibility") << tr("");
    mTable->setHorizontalHeaderLabels(headers);
    QFont font;
    font.setBold(true);
    mTable->horizontalHeader()->setFont(font);
    mTable->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);

    // Contextmenu
    setContextMenuPolicy(Qt::CustomContextMenu);
    mContextMenu = new QMenu(mTable);
    mContextMenu->addAction(new QAction(TOOL_LAYER_ACTION_CREATE_LAYER, mTable));
    mContextMenu->addAction(new QAction(TOOL_LAYER_ACTION_EDIT_LAYER, mTable));
    mContextMenu->addAction(new QAction(TOOL_LAYER_ACTION_DELETE_LAYER, mTable));
    mContextMenu->addAction(new QAction(TOOL_LAYER_ACTION_RENAME_LAYER, mTable));
    mContextMenu->addAction(new QAction(TOOL_LAYER_ACTION_ALL_VISIBLE, mTable));
    //mContextMenu->addAction(new QAction(QString("TEST"), mTable));
    connect(mContextMenu, SIGNAL(triggered(QAction*)), this, SLOT(contextMenuItemSelected(QAction*)));

    // Layout
    tableLayout->addWidget(mTable);
    mainLayout->addLayout(tableLayout);
    setLayout(mainLayout);
}

//****************************************************************************/
PaintLayerWidget::~PaintLayerWidget(void)
{
    QVector<QtLayer*>::iterator it;
    for (it = mLayerVec.begin(); it != mLayerVec.end(); ++it)
        delete *it;

    mLayerVec.clear(); // The table is automatically deleted when this widget is deleted
}

//****************************************************************************/
bool PaintLayerWidget::eventFilter(QObject* object, QEvent* event)
{
    QMouseEvent* mouseEvent = (QMouseEvent*) event;
    switch ((int) event->type())
    {
        case QEvent::MouseButtonPress:
            mouseClickHandler(mouseEvent);
        break;

        case QEvent::MouseButtonDblClick:
            mouseDblClickHandler(mouseEvent);
        break;

        break;
    }
    return QObject::eventFilter(object, event);
}

//****************************************************************************/
void PaintLayerWidget::tableClicked(QModelIndex index)
{
    // Toggle visibility
    int row = index.row();
    int col = index.column();
    QtLayer* layer = mLayerVec.at(row);
    if (col == TOOL_LAYER_COLUMN_VISIBILITY)
    {
        if (layer->visible)
            updateVisibilityIcon(row, false);
        else
            updateVisibilityIcon(row, true);
    }

    // Signal that layer is selected
    emit layerSelected(layer->layerId, layer->name);
}

//****************************************************************************/
QVector<int> PaintLayerWidget::getSelectedLayerIds(void)
{
    helperIntVector.clear();
    QList<QTableWidgetItem*> itemList = mTable->selectedItems();
    foreach(QTableWidgetItem* item, itemList)
    {
        // Do not append all items, but only the rows; so only mark in case of a distinct column
        if (item->column() == TOOL_LAYER_COLUMN_ICON)
            helperIntVector.append(item->data(Qt::UserRole).toInt());
    }

    return helperIntVector;
}

//****************************************************************************/
void PaintLayerWidget::mouseClickHandler(QMouseEvent* event)
{
    switch ((int) event->button())
    {
        case Qt::LeftButton:
        {
            // TODO
        }
        break;

        case Qt::RightButton:
        {
            QPoint pos;
            pos.setX(event->screenPos().x());
            pos.setY(event->screenPos().y());
            mContextMenu->popup(pos);
        }
        break;
    }
}

//****************************************************************************/
void PaintLayerWidget::mouseDblClickHandler(QMouseEvent* event)
{
    switch ((int) event->button())
    {
        case Qt::LeftButton:
        {
            if (mTable->currentColumn() == TOOL_LAYER_COLUMN_NAME)
            {
                QTableWidgetItem* item = mTable->currentItem();
                if (item->column() == TOOL_LAYER_COLUMN_NAME)
                {
                    // Its the name; edit it
                    mTable->editItem(item);
                }
            }
        }
        break;
    }
}

//****************************************************************************/
void PaintLayerWidget::contextMenuItemSelected(QAction* action)
{
    // ---------------- Create layer action ----------------
    if (action->text() == TOOL_LAYER_ACTION_CREATE_LAYER)
    {
        createDefaultPaintLayer();
        return;
    }
    else if (action->text() == TOOL_LAYER_ACTION_EDIT_LAYER)
    {
        editSelectedPaintLayer();
        return;
    }
    else if (action->text() == TOOL_LAYER_ACTION_DELETE_LAYER)
    {
        deleteSelectedPaintLayer();
    }
    else if (action->text() == TOOL_LAYER_ACTION_RENAME_LAYER)
    {
        QTableWidgetItem* item = mTable->currentItem();
        if (item && item->column() == TOOL_LAYER_COLUMN_NAME)
        {
            // Its the name; edit it
            mTable->editItem(item);
        }
    }
    else if (action->text() == TOOL_LAYER_ACTION_ALL_VISIBLE)
    {
        int rows = mTable->rowCount();
        for(int row = 0; row < rows; ++row)
            if (mLayerVec.at(row)->visible == false)
                updateVisibilityIcon(row, true);
    }
    else if (action->text() == QString ("TEST"))
    {
        //setLayerName(3, QString("Test"));
        //deleteLayer(QString("New layer 4"));
    }
}

//****************************************************************************/
void PaintLayerWidget::updateVisibilityIcon(int row, bool visible, bool doEmit)
{
    QTableWidgetItem* item = mTable->item(row, TOOL_LAYER_COLUMN_VISIBILITY);
    if (!item)
        return;

    QtLayer* layer = mLayerVec.at(row);
    updateVisibilityIconForLayerId(layer->layerId, visible, doEmit);
}

//****************************************************************************/
void PaintLayerWidget::updateVisibilityIconForLayerId(int layerId, bool visible, bool doEmit)
{
    QtLayer* layer = getLayer(layerId);
    if (!layer)
        return;

    QTableWidgetItem* item = getItem(layerId, TOOL_LAYER_COLUMN_VISIBILITY);
    if (!item)
        return;

    QPixmap pixMap;
    layer->visible = visible;
    if (visible)
    {
        QImage image(mIconDir + TOOL_ICON_VIEW_VISIBLE);
        pixMap = QPixmap::fromImage(image).scaled(TOOL_LAYER_ICON_WIDTH, TOOL_LAYER_ICON_WIDTH);
        item->setData(Qt::DecorationRole, QVariant(pixMap));
    }
    else
    {
        QImage image(mIconDir + TOOL_ICON_VIEW_INVISIBLE);
        pixMap = QPixmap::fromImage(image).scaled(TOOL_LAYER_ICON_WIDTH, TOOL_LAYER_ICON_WIDTH);
        item->setData(Qt::DecorationRole, QVariant(pixMap));
    }

    if (doEmit)
        emit layerVisibiltyChanged(layer->layerId, item->text(), layer->visible);
}

//****************************************************************************/
int PaintLayerWidget::newLayerId(void)
{
    int maxId = 0;
    QtLayer* layer;
    QVector<QtLayer*>::iterator it;
    for (it = mLayerVec.begin(); it != mLayerVec.end(); ++it)
    {
        layer = *it;
        if (layer->layerId > maxId)
            maxId = layer->layerId;
    }

    ++maxId;
    return maxId;
}

//****************************************************************************/
void PaintLayerWidget::addLayer(QtLayer* layer)
{
    // Add the layer to the vector create a new row in the table
    int row = mTable->rowCount();
    mLayerVec.append(layer);
    mTable->insertRow(row);

    // Set the default brush icon
    QTableWidgetItem* item = new QTableWidgetItem();
    QImage image(DEFAULT_BRUSH_AND_PATH_QSTRING);
    QPixmap pixMapLayer = QPixmap::fromImage(image).scaled(TOOL_LAYER_ICON_WIDTH, TOOL_LAYER_ICON_WIDTH);
    item->setData(Qt::DecorationRole, QVariant(pixMapLayer));
    item->setData(Qt::UserRole, QVariant(layer->layerId));
    mTable->setItem(row, TOOL_LAYER_COLUMN_ICON, item);

    // Set the name
    item = new QTableWidgetItem();
    QString newName = layer->name;
    if (newName.size() == 0)
        newName = QString("Paint layer ") + QVariant(layer->layerId).toString();
    layer->name = newName;
    item->setText(newName);
    item->setFlags(Qt::ItemIsEditable | Qt::ItemIsSelectable | Qt::ItemIsEnabled);
    item->setData(Qt::UserRole, QVariant(layer->layerId));
    mTable->setItem(row, TOOL_LAYER_COLUMN_NAME, item);

    // Set the visibility icon
    item = new QTableWidgetItem();
    QImage imageVis(mIconDir + TOOL_ICON_VIEW_VISIBLE);
    QPixmap pixMapVis = QPixmap::fromImage(imageVis).scaled(TOOL_LAYER_ICON_WIDTH, TOOL_LAYER_ICON_WIDTH);
    item->setData(Qt::DecorationRole, QVariant(pixMapVis));
    item->setData(Qt::UserRole, QVariant(layer->layerId));
    mTable->setItem(row, TOOL_LAYER_COLUMN_VISIBILITY, item);

    // Set the layerId in the visibility icon
    //item->setData(Qt::UserRole, QVariant(layer->layerId));

    //mTable->resizeColumnToContents(0);

    // Set the item to selected
    mTable->resizeRowsToContents();
    mTable->selectRow(row);

    // Emit signal
    emit layerCreatedOrAdded(layer->layerId, layer->name);
}

//****************************************************************************/
void PaintLayerWidget::createDefaultPaintLayer (void)
{
    if (mPaintLayerDockWidget->currentDatablockExists())
    {
        if (mPaintLayerDockWidget->currentDatablockIsPbs())
        {
            createLayer(QString(""));
        }
        else
        {
            QMessageBox::information(0, QString("Warning"), QString("Painting on HLMS Unlit materials is not supported"));
        }
    }
    else
    {
        QMessageBox::information(0, QString("Warning"), QString("Create / load a hlms material before creating a paint layer.\n"
                                                                "Did you forget to generate (cog icon) or edit the hlms material?"));
    }
}

//****************************************************************************/
const QtLayer* PaintLayerWidget::createLayer(const QString& name)
{
    // Fill the layer object
    QtLayer* layer = new QtLayer();
    layer->layerId = newLayerId();
    layer->name = name;
    layer->visible = true;

    // Add the layer to the layer vector and the table
    addLayer(layer);
    return layer;
}


//****************************************************************************/
const QtLayer* PaintLayerWidget::createLayer(int layerId, const QString& name)
{
    // Fill the layer object
    QtLayer* layer = new QtLayer();
    layer->layerId = layerId;
    layer->name = name;
    layer->visible = true;

    // Add the layer to the layer vector and the table
    addLayer(layer);
    return layer;
}

//****************************************************************************/
int PaintLayerWidget::getRow(const QString& name)
{
    int rows = mTable->rowCount();
    QTableWidgetItem* item;
    for (int row = 0; row < rows; ++row)
    {
        item = mTable->item(row, TOOL_LAYER_COLUMN_NAME);
        if (item->text() == name)
            return row;
    }

    return -1; // Not found
}

//****************************************************************************/
int PaintLayerWidget::getRow(int layerId)
{
    int row = 0;
    QtLayer* layer;
    QVector<QtLayer*>::iterator it;
    for (it = mLayerVec.begin(); it != mLayerVec.end(); ++it)
    {
        layer = *it;
        if (layer->layerId == layerId)
            return row;

        ++row;
    }

    return -1; // Not found
}

//****************************************************************************/
void PaintLayerWidget::deleteLayer (const QString& name)
{
    int row = getRow(name);
    if (row != -1)
    {
        // Delete the layer from the table and the vector
        QString name = getName(row);
        mTable->removeRow(row);
        int layerId = removeFromLayerVec(row);

        emit layerDeleted(layerId, name);
    }
}

//****************************************************************************/
void PaintLayerWidget::deleteLayer (const QtLayer* layer)
{
    // Delete the layer
    int row = 0;
    QVector<QtLayer*>::iterator it;
    int layerId;
    QString name;
    for (it = mLayerVec.begin(); it != mLayerVec.end(); ++it)
    {
        if (layer == *it)
        {
            // Delete the layer from the table and the vector
            layerId = layer->layerId;
            mLayerVec.erase(it);
            name = getName(row);
            mTable->removeRow(row);
            delete layer;

            emit layerDeleted(layerId, name);
        }
        ++row;
    }
}

//****************************************************************************/
void PaintLayerWidget::deleteLayer (int layerId)
{
    int row = getRow(layerId);
    if (row != -1)
    {
        // Delete the layer from the table and the vector
        QString name = getName(row);
        mTable->removeRow(row);
        int layerId = removeFromLayerVec(row);

        emit layerDeleted(layerId, name);
    }
}
예제 #8
0
void QgsIdentifyResultsDialog::addFeature( QgsVectorLayer *vlayer, const QgsFeature &f, const QMap<QString, QString> &derivedAttributes )
{
  QTreeWidgetItem *layItem = layerItem( vlayer );

  if ( layItem == 0 )
  {
    layItem = new QTreeWidgetItem( QStringList() << QString::number( lstResults->topLevelItemCount() ) << vlayer->name() );
    layItem->setData( 0, Qt::UserRole, QVariant::fromValue( qobject_cast<QObject *>( vlayer ) ) );
    lstResults->addTopLevelItem( layItem );

    connect( vlayer, SIGNAL( layerDeleted() ), this, SLOT( layerDestroyed() ) );
    connect( vlayer, SIGNAL( layerCrsChanged() ), this, SLOT( layerDestroyed() ) );
    connect( vlayer, SIGNAL( featureDeleted( QgsFeatureId ) ), this, SLOT( featureDeleted( QgsFeatureId ) ) );
    connect( vlayer, SIGNAL( attributeValueChanged( QgsFeatureId, int, const QVariant & ) ),
             this,   SLOT( attributeValueChanged( QgsFeatureId, int, const QVariant & ) ) );
    connect( vlayer, SIGNAL( editingStarted() ), this, SLOT( editingToggled() ) );
    connect( vlayer, SIGNAL( editingStopped() ), this, SLOT( editingToggled() ) );
  }
예제 #9
0
/****************************************************************************
**
** Copyright (C) 2016 - 2017
**
** This file is generated by the Magus toolkit
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
****************************************************************************/

// Include
#include <QApplication>
#include <QDesktopWidget>
#include <QRect>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QMessageBox>
#include <QHeaderView>
#include <QEvent>
#include <QPixmap>
#include <QImage>
#include <QMimeData>
#include <QTableWidgetItem>
#include <QTreeWidgetItem>
#include <QVector2D>
#include "constants.h"
#include "paintlayer_widget.h"
#include "paintlayer_dockwidget.h"
#include "paintlayer_dialog.h"

//****************************************************************************/
PaintLayerWidget::PaintLayerWidget(const QString& iconDir, PaintLayerDockWidget* paintLayerDockWidget, QWidget* parent) :
    QWidget(parent),
    mPaintLayerDockWidget(paintLayerDockWidget)
{
    setWindowTitle(QString("Layers"));
    QHBoxLayout* mainLayout = new QHBoxLayout;
    QVBoxLayout* tableLayout = new QVBoxLayout;
    mIconDir = iconDir;
    mLayerIdCounter = 1;
    mListenToSceneId = 0;
    mListenToDeleteEvents = true;
    helperIntVector.clear();

    // Create table
    mTable = new QTableWidget(0, 4, this);
    mTable->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    mTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
    mTable->setAcceptDrops(false);
    mTable->setShowGrid(false);
    mTable->viewport()->installEventFilter(this);
    QRect rect = QApplication::desktop()->screenGeometry();
    mTable->setColumnWidth(TOOL_LAYER_COLUMN_ICON, 2 * TOOL_LAYER_ICON_WIDTH);
    mTable->setColumnWidth(TOOL_LAYER_COLUMN_NAME, TOOL_LAYER_NAME_WIDTH);
    mTable->setColumnWidth(TOOL_LAYER_COLUMN_VISIBILITY, 2 * TOOL_LAYER_ICON_WIDTH);
    mTable->setColumnWidth(TOOL_LAYER_COLUMN_FILLER, rect.width());
    mTable->setSelectionBehavior(QAbstractItemView::SelectRows);
    setStyleSheet("QLineEdit{padding: 0 0px; margin-left: 0px; margin-right: 0px; max-height: 28px; height: 28px;}");
    connect(mTable, SIGNAL(clicked(QModelIndex)), this, SLOT(tableClicked(QModelIndex)));
    connect(mTable, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(handleTableDoubleClicked(QModelIndex)));

    // Set headers
    QStringList headers;
    headers << tr("Edit") << tr("Layer name") << tr("Visibility") << tr("");
    mTable->setHorizontalHeaderLabels(headers);
    QFont font;
    font.setBold(true);
    mTable->horizontalHeader()->setFont(font);
    mTable->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);

    // Contextmenu
    setContextMenuPolicy(Qt::CustomContextMenu);
    mContextMenu = new QMenu(mTable);
    mContextMenu->addAction(new QAction(TOOL_LAYER_ACTION_CREATE_LAYER, mTable));
    mContextMenu->addAction(new QAction(TOOL_LAYER_ACTION_EDIT_LAYER, mTable));
    mContextMenu->addAction(new QAction(TOOL_LAYER_ACTION_DELETE_LAYER, mTable));
    mContextMenu->addAction(new QAction(TOOL_LAYER_ACTION_RENAME_LAYER, mTable));
    mContextMenu->addAction(new QAction(TOOL_LAYER_ACTION_ALL_VISIBLE, mTable));
    //mContextMenu->addAction(new QAction(QString("TEST"), mTable));
    connect(mContextMenu, SIGNAL(triggered(QAction*)), this, SLOT(contextMenuItemSelected(QAction*)));

    // Layout
    tableLayout->addWidget(mTable);
    mainLayout->addLayout(tableLayout);
    setLayout(mainLayout);
}

//****************************************************************************/
PaintLayerWidget::~PaintLayerWidget(void)
{
    QVector<QtLayer*>::iterator it;
    for (it = mLayerVec.begin(); it != mLayerVec.end(); ++it)
        delete *it;

    mLayerVec.clear(); // The table is automatically deleted when this widget is deleted
}

//****************************************************************************/
bool PaintLayerWidget::eventFilter(QObject* object, QEvent* event)
{
    QMouseEvent* mouseEvent = (QMouseEvent*) event;
    switch ((int) event->type())
    {
        case QEvent::MouseButtonPress:
            mouseClickHandler(mouseEvent);
        break;

        case QEvent::MouseButtonDblClick:
            mouseDblClickHandler(mouseEvent);
        break;

        break;
    }
    return QObject::eventFilter(object, event);
}

//****************************************************************************/
void PaintLayerWidget::tableClicked(QModelIndex index)
{
    // Toggle visibility
    int row = index.row();
    int col = index.column();
    QtLayer* layer = mLayerVec.at(row);
    if (col == TOOL_LAYER_COLUMN_VISIBILITY)
    {
        if (layer->visible)
            updateVisibilityIcon(row, false);
        else
            updateVisibilityIcon(row, true);
    }

    // Signal that layer is selected
    emit layerSelected(layer->layerId, layer->name);
}

//****************************************************************************/
QVector<int> PaintLayerWidget::getSelectedLayerIds(void)
{
    helperIntVector.clear();
    QList<QTableWidgetItem*> itemList = mTable->selectedItems();
    foreach(QTableWidgetItem* item, itemList)
    {
        // Do not append all items, but only the rows; so only mark in case of a distinct column
        if (item->column() == TOOL_LAYER_COLUMN_ICON)
            helperIntVector.append(item->data(Qt::UserRole).toInt());
    }

    return helperIntVector;
}

//****************************************************************************/
void PaintLayerWidget::mouseClickHandler(QMouseEvent* event)
{
    switch ((int) event->button())
    {
        case Qt::LeftButton:
        {
            // TODO
        }
        break;

        case Qt::RightButton:
        {
            QPoint pos;
            pos.setX(event->screenPos().x());
            pos.setY(event->screenPos().y());
            mContextMenu->popup(pos);
        }
        break;
    }
}

//****************************************************************************/
void PaintLayerWidget::mouseDblClickHandler(QMouseEvent* event)
{
    switch ((int) event->button())
    {
        case Qt::LeftButton:
        {
            if (mTable->currentColumn() == TOOL_LAYER_COLUMN_NAME)
            {
                QTableWidgetItem* item = mTable->currentItem();
                if (item->column() == TOOL_LAYER_COLUMN_NAME)
                {
                    // Its the name; edit it
                    mTable->editItem(item);
                }
            }
        }
        break;
    }
}

//****************************************************************************/
void PaintLayerWidget::contextMenuItemSelected(QAction* action)
{
    // ---------------- Create layer action ----------------
    if (action->text() == TOOL_LAYER_ACTION_CREATE_LAYER)
    {
        createDefaultPaintLayer();
        return;
    }
    else if (action->text() == TOOL_LAYER_ACTION_EDIT_LAYER)
    {
        editSelectedPaintLayer();
        return;
    }
    else if (action->text() == TOOL_LAYER_ACTION_DELETE_LAYER)
    {
        deleteSelectedPaintLayer();
    }
    else if (action->text() == TOOL_LAYER_ACTION_RENAME_LAYER)
    {
        QTableWidgetItem* item = mTable->currentItem();
        if (item && item->column() == TOOL_LAYER_COLUMN_NAME)
        {
            // Its the name; edit it
            mTable->editItem(item);
        }
    }
    else if (action->text() == TOOL_LAYER_ACTION_ALL_VISIBLE)
    {
        int rows = mTable->rowCount();
        for(int row = 0; row < rows; ++row)
            if (mLayerVec.at(row)->visible == false)
                updateVisibilityIcon(row, true);
    }
    else if (action->text() == QString ("TEST"))
    {
        //setLayerName(3, QString("Test"));
        //deleteLayer(QString("New layer 4"));
    }
}

//****************************************************************************/
void PaintLayerWidget::updateVisibilityIcon(int row, bool visible, bool doEmit)
{
    QTableWidgetItem* item = mTable->item(row, TOOL_LAYER_COLUMN_VISIBILITY);
    if (!item)
        return;

    QtLayer* layer = mLayerVec.at(row);
    updateVisibilityIconForLayerId(layer->layerId, visible, doEmit);
}

//****************************************************************************/
void PaintLayerWidget::updateVisibilityIconForLayerId(int layerId, bool visible, bool doEmit)
{
    QtLayer* layer = getLayer(layerId);
    if (!layer)
        return;

    QTableWidgetItem* item = getItem(layerId, TOOL_LAYER_COLUMN_VISIBILITY);
    if (!item)
        return;

    QPixmap pixMap;
    layer->visible = visible;
    if (visible)
    {
        QImage image(mIconDir + TOOL_ICON_VIEW_VISIBLE);
        pixMap = QPixmap::fromImage(image).scaled(TOOL_LAYER_ICON_WIDTH, TOOL_LAYER_ICON_WIDTH);
        item->setData(Qt::DecorationRole, QVariant(pixMap));
    }
    else
    {
        QImage image(mIconDir + TOOL_ICON_VIEW_INVISIBLE);
        pixMap = QPixmap::fromImage(image).scaled(TOOL_LAYER_ICON_WIDTH, TOOL_LAYER_ICON_WIDTH);
        item->setData(Qt::DecorationRole, QVariant(pixMap));
    }

    if (doEmit)
        emit layerVisibiltyChanged(layer->layerId, item->text(), layer->visible);
}

//****************************************************************************/
int PaintLayerWidget::newLayerId(void)
{
    int maxId = 0;
    QtLayer* layer;
    QVector<QtLayer*>::iterator it;
    for (it = mLayerVec.begin(); it != mLayerVec.end(); ++it)
    {
        layer = *it;
        if (layer->layerId > maxId)
            maxId = layer->layerId;
    }

    ++maxId;
    return maxId;
}

//****************************************************************************/
void PaintLayerWidget::addLayer(QtLayer* layer)
{
    // Add the layer to the vector create a new row in the table
    int row = mTable->rowCount();
    mLayerVec.append(layer);
    mTable->insertRow(row);

    // Set the default brush icon
    QTableWidgetItem* item = new QTableWidgetItem();
    QImage image(DEFAULT_BRUSH_AND_PATH_QSTRING);
    QPixmap pixMapLayer = QPixmap::fromImage(image).scaled(TOOL_LAYER_ICON_WIDTH, TOOL_LAYER_ICON_WIDTH);
    item->setData(Qt::DecorationRole, QVariant(pixMapLayer));
    item->setData(Qt::UserRole, QVariant(layer->layerId));
    mTable->setItem(row, TOOL_LAYER_COLUMN_ICON, item);

    // Set the name
    item = new QTableWidgetItem();
    QString newName = layer->name;
    if (newName.size() == 0)
        newName = QString("Paint layer ") + QVariant(layer->layerId).toString();
    layer->name = newName;
    item->setText(newName);
    item->setFlags(Qt::ItemIsEditable | Qt::ItemIsSelectable | Qt::ItemIsEnabled);
    item->setData(Qt::UserRole, QVariant(layer->layerId));
    mTable->setItem(row, TOOL_LAYER_COLUMN_NAME, item);

    // Set the visibility icon
    item = new QTableWidgetItem();
    QImage imageVis(mIconDir + TOOL_ICON_VIEW_VISIBLE);
    QPixmap pixMapVis = QPixmap::fromImage(imageVis).scaled(TOOL_LAYER_ICON_WIDTH, TOOL_LAYER_ICON_WIDTH);
    item->setData(Qt::DecorationRole, QVariant(pixMapVis));
    item->setData(Qt::UserRole, QVariant(layer->layerId));
    mTable->setItem(row, TOOL_LAYER_COLUMN_VISIBILITY, item);

    // Set the layerId in the visibility icon
    //item->setData(Qt::UserRole, QVariant(layer->layerId));

    //mTable->resizeColumnToContents(0);

    // Set the item to selected
    mTable->resizeRowsToContents();
    mTable->selectRow(row);

    // Emit signal
    emit layerCreatedOrAdded(layer->layerId, layer->name);
}

//****************************************************************************/
void PaintLayerWidget::createDefaultPaintLayer (void)
{
    if (mPaintLayerDockWidget->currentDatablockExists())
    {
        if (mPaintLayerDockWidget->currentDatablockIsPbs())
        {
            createLayer(QString(""));
        }
        else
        {
            QMessageBox::information(0, QString("Warning"), QString("Painting on HLMS Unlit materials is not supported"));
        }
    }
    else
    {
        QMessageBox::information(0, QString("Warning"), QString("Create / load a hlms material before creating a paint layer.\n"
                                                                "Did you forget to generate (cog icon) or edit the hlms material?"));
    }
}

//****************************************************************************/
const QtLayer* PaintLayerWidget::createLayer(const QString& name)
{
    // Fill the layer object
    QtLayer* layer = new QtLayer();
    layer->layerId = newLayerId();
    layer->name = name;
    layer->visible = true;

    // Add the layer to the layer vector and the table
    addLayer(layer);
    return layer;
}


//****************************************************************************/
const QtLayer* PaintLayerWidget::createLayer(int layerId, const QString& name)
{
    // Fill the layer object
    QtLayer* layer = new QtLayer();
    layer->layerId = layerId;
    layer->name = name;
    layer->visible = true;

    // Add the layer to the layer vector and the table
    addLayer(layer);
    return layer;
}

//****************************************************************************/
int PaintLayerWidget::getRow(const QString& name)
{
    int rows = mTable->rowCount();
    QTableWidgetItem* item;
    for (int row = 0; row < rows; ++row)
    {
        item = mTable->item(row, TOOL_LAYER_COLUMN_NAME);
        if (item->text() == name)
            return row;
    }

    return -1; // Not found
}

//****************************************************************************/
int PaintLayerWidget::getRow(int layerId)
{
    int row = 0;
    QtLayer* layer;
    QVector<QtLayer*>::iterator it;
    for (it = mLayerVec.begin(); it != mLayerVec.end(); ++it)
    {
        layer = *it;
        if (layer->layerId == layerId)
            return row;

        ++row;
    }

    return -1; // Not found
}

//****************************************************************************/
void PaintLayerWidget::deleteLayer (const QString& name)
{
    int row = getRow(name);
    if (row != -1)
    {
        // Delete the layer from the table and the vector
        QString name = getName(row);
        mTable->removeRow(row);
        int layerId = removeFromLayerVec(row);

        emit layerDeleted(layerId, name);
    }
}

//****************************************************************************/
void PaintLayerWidget::deleteLayer (const QtLayer* layer)
{
    // Delete the layer
    int row = 0;
    QVector<QtLayer*>::iterator it;
    int layerId;
    QString name;
    for (it = mLayerVec.begin(); it != mLayerVec.end(); ++it)
    {
        if (layer == *it)
        {
            // Delete the layer from the table and the vector
            layerId = layer->layerId;
            mLayerVec.erase(it);
            name = getName(row);
            mTable->removeRow(row);
            delete layer;

            emit layerDeleted(layerId, name);
        }
        ++row;
    }
}
예제 #10
0
bool QgsTransactionGroup::addLayer( QgsVectorLayer* layer )
{
  if ( !QgsTransaction::supportsTransaction( layer ) )
    return false;

  QString connString = QgsDataSourceURI( layer->source() ).connectionInfo();

  if ( mConnString.isEmpty() )
  {
    mConnString = connString;
    mProviderKey = layer->providerType();
  }
  else if ( mConnString != connString || mProviderKey != layer->providerType() )
  {
    return false;
  }

  mLayers.insert( layer );

  connect( layer, SIGNAL( beforeEditingStarted() ), this, SLOT( onEditingStarted() ) );
  connect( layer, SIGNAL( layerDeleted() ), this, SLOT( onLayerDeleted() ) );

  return true;
}
예제 #11
0
QgsAttributeTableDialog::QgsAttributeTableDialog( QgsVectorLayer *theLayer, QWidget *parent, Qt::WindowFlags flags )
    : QDialog( parent, flags ), mDock( NULL )
{
  mLayer = theLayer;

  setupUi( this );

  setAttribute( Qt::WA_DeleteOnClose );

  QSettings settings;
  restoreGeometry( settings.value( "/Windows/BetterAttributeTable/geometry" ).toByteArray() );

  mView->setLayer( mLayer );
  mFilterModel = ( QgsAttributeTableFilterModel * ) mView->model();
  mModel = ( QgsAttributeTableModel * )(( QgsAttributeTableFilterModel * )mView->model() )->sourceModel();

  mQuery = query;
  mColumnBox = columnBox;
  columnBoxInit();

  bool myDockFlag = settings.value( "/qgis/dockAttributeTable", false ).toBool();
  if ( myDockFlag )
  {
    mDock = new QgsAttributeTableDock( tr( "Attribute table - %1 (%n Feature(s))", "feature count", mModel->rowCount() ).arg( mLayer->name() ), QgisApp::instance() );
    mDock->setAllowedAreas( Qt::BottomDockWidgetArea | Qt::TopDockWidgetArea );
    mDock->setWidget( this );
    connect( this, SIGNAL( destroyed() ), mDock, SLOT( close() ) );
    QgisApp::instance()->addDockWidget( Qt::BottomDockWidgetArea, mDock );
  }

  updateTitle();

  mRemoveSelectionButton->setIcon( QgisApp::getThemeIcon( "/mActionUnselectAttributes.png" ) );
  mSelectedToTopButton->setIcon( QgisApp::getThemeIcon( "/mActionSelectedToTop.png" ) );
  mCopySelectedRowsButton->setIcon( QgisApp::getThemeIcon( "/mActionCopySelected.png" ) );
  mZoomMapToSelectedRowsButton->setIcon( QgisApp::getThemeIcon( "/mActionZoomToSelected.png" ) );
  mInvertSelectionButton->setIcon( QgisApp::getThemeIcon( "/mActionInvertSelection.png" ) );
  mToggleEditingButton->setIcon( QgisApp::getThemeIcon( "/mActionToggleEditing.png" ) );
  mSaveEditsButton->setIcon( QgisApp::getThemeIcon( "/mActionSaveEdits.png" ) );
  mDeleteSelectedButton->setIcon( QgisApp::getThemeIcon( "/mActionDeleteSelected.png" ) );
  mOpenFieldCalculator->setIcon( QgisApp::getThemeIcon( "/mActionCalculateField.png" ) );
  mAddAttribute->setIcon( QgisApp::getThemeIcon( "/mActionNewAttribute.png" ) );
  mRemoveAttribute->setIcon( QgisApp::getThemeIcon( "/mActionDeleteAttribute.png" ) );

  // toggle editing
  bool canChangeAttributes = mLayer->dataProvider()->capabilities() & QgsVectorDataProvider::ChangeAttributeValues;
  bool canDeleteFeatures = mLayer->dataProvider()->capabilities() & QgsVectorDataProvider::DeleteFeatures;
  bool canAddAttributes = mLayer->dataProvider()->capabilities() & QgsVectorDataProvider::AddAttributes;
  bool canDeleteAttributes = mLayer->dataProvider()->capabilities() & QgsVectorDataProvider::DeleteAttributes;
  bool canAddFeatures = mLayer->dataProvider()->capabilities() & QgsVectorDataProvider::AddFeatures;

  mToggleEditingButton->setCheckable( true );
  mToggleEditingButton->setChecked( mLayer->isEditable() );
  mToggleEditingButton->setEnabled( canChangeAttributes && !mLayer->isReadOnly() );

  mSaveEditsButton->setEnabled( canChangeAttributes && mLayer->isEditable() );
  mOpenFieldCalculator->setEnabled( canChangeAttributes && mLayer->isEditable() );
  mDeleteSelectedButton->setEnabled( canDeleteFeatures && mLayer->isEditable() );
  mAddAttribute->setEnabled( canAddAttributes && mLayer->isEditable() );
  mRemoveAttribute->setEnabled( canDeleteAttributes && mLayer->isEditable() );
  mAddFeature->setEnabled( canAddFeatures && mLayer->isEditable() && mLayer->geometryType() == QGis::NoGeometry );
  mAddFeature->setHidden( !canAddFeatures || mLayer->geometryType() != QGis::NoGeometry );

  // info from table to application
  connect( this, SIGNAL( editingToggled( QgsMapLayer * ) ), QgisApp::instance(), SLOT( toggleEditing( QgsMapLayer * ) ) );
  connect( this, SIGNAL( saveEdits( QgsMapLayer * ) ), QgisApp::instance(), SLOT( saveEdits( QgsMapLayer * ) ) );

  // info from layer to table
  connect( mLayer, SIGNAL( editingStarted() ), this, SLOT( editingToggled() ) );
  connect( mLayer, SIGNAL( editingStopped() ), this, SLOT( editingToggled() ) );

  connect( searchButton, SIGNAL( clicked() ), this, SLOT( search() ) );
  connect( mAddFeature, SIGNAL( clicked() ), this, SLOT( addFeature() ) );

  connect( mLayer, SIGNAL( selectionChanged() ), this, SLOT( updateSelectionFromLayer() ) );
  connect( mLayer, SIGNAL( layerDeleted() ), this, SLOT( close() ) );
  connect( mView->verticalHeader(), SIGNAL( sectionClicked( int ) ), this, SLOT( updateRowSelection( int ) ) );
  connect( mView->verticalHeader(), SIGNAL( sectionPressed( int ) ), this, SLOT( updateRowPressed( int ) ) );
  connect( mModel, SIGNAL( modelChanged() ), this, SLOT( updateSelection() ) );

  if ( settings.value( "/qgis/attributeTableBehaviour", 0 ).toInt() == 2 )
  {
    connect( QgisApp::instance()->mapCanvas(), SIGNAL( extentsChanged() ), mModel, SLOT( layerModified() ) );
  }

  mLastClickedHeaderIndex = 0;
  mSelectionModel = new QItemSelectionModel( mFilterModel );
  updateSelectionFromLayer();

  //make sure to show all recs on first load
  on_cbxShowSelectedOnly_toggled( false );
}
예제 #12
0
QgsAttributeTableDialog::QgsAttributeTableDialog( QgsVectorLayer *theLayer, QWidget *parent, Qt::WindowFlags flags )
    : QDialog( parent, flags )
    , mDock( nullptr )
    , mLayer( theLayer )
    , mRubberBand( nullptr )
    , mCurrentSearchWidgetWrapper( nullptr )
{
  setupUi( this );

  // Fix selection color on loosing focus (Windows)
  setStyleSheet( QgisApp::instance()->styleSheet() );

  setAttribute( Qt::WA_DeleteOnClose );

  QSettings settings;

  // Initialize the window geometry
  restoreGeometry( settings.value( "/Windows/BetterAttributeTable/geometry" ).toByteArray() );

  QgsAttributeEditorContext context;

  myDa = new QgsDistanceArea();

  myDa->setSourceCrs( mLayer->crs() );
  myDa->setEllipsoidalMode( QgisApp::instance()->mapCanvas()->mapSettings().hasCrsTransformEnabled() );
  myDa->setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", GEO_NONE ) );

  context.setDistanceArea( *myDa );
  context.setVectorLayerTools( QgisApp::instance()->vectorLayerTools() );

  QgsFeatureRequest r;
  if ( mLayer->geometryType() != QGis::NoGeometry &&
       settings.value( "/qgis/attributeTableBehaviour", QgsAttributeTableFilterModel::ShowAll ).toInt() == QgsAttributeTableFilterModel::ShowVisible )
  {
    QgsMapCanvas *mc = QgisApp::instance()->mapCanvas();
    QgsRectangle extent( mc->mapSettings().mapToLayerCoordinates( theLayer, mc->extent() ) );
    r.setFilterRect( extent );

    QgsGeometry *g = QgsGeometry::fromRect( extent );
    mRubberBand = new QgsRubberBand( mc, QGis::Polygon );
    mRubberBand->setToGeometry( g, theLayer );
    delete g;

    mActionShowAllFilter->setText( tr( "Show All Features In Initial Canvas Extent" ) );
  }

  // Initialize dual view
  mMainView->init( mLayer, QgisApp::instance()->mapCanvas(), r, context );

  // Initialize filter gui elements
  mFilterActionMapper = new QSignalMapper( this );
  mFilterColumnsMenu = new QMenu( this );
  mActionFilterColumnsMenu->setMenu( mFilterColumnsMenu );
  mApplyFilterButton->setDefaultAction( mActionApplyFilter );

  // Set filter icon in a couple of places
  QIcon filterIcon = QgsApplication::getThemeIcon( "/mActionFilter.svg" );
  mActionShowAllFilter->setIcon( filterIcon );
  mActionAdvancedFilter->setIcon( filterIcon );
  mActionSelectedFilter->setIcon( filterIcon );
  mActionVisibleFilter->setIcon( filterIcon );
  mActionEditedFilter->setIcon( filterIcon );

  // Connect filter signals
  connect( mActionAdvancedFilter, SIGNAL( triggered() ), SLOT( filterExpressionBuilder() ) );
  connect( mActionShowAllFilter, SIGNAL( triggered() ), SLOT( filterShowAll() ) );
  connect( mActionSelectedFilter, SIGNAL( triggered() ), SLOT( filterSelected() ) );
  connect( mActionVisibleFilter, SIGNAL( triggered() ), SLOT( filterVisible() ) );
  connect( mActionEditedFilter, SIGNAL( triggered() ), SLOT( filterEdited() ) );
  connect( mFilterActionMapper, SIGNAL( mapped( QObject* ) ), SLOT( filterColumnChanged( QObject* ) ) );
  connect( mFilterQuery, SIGNAL( returnPressed() ), SLOT( filterQueryAccepted() ) );
  connect( mActionApplyFilter, SIGNAL( triggered() ), SLOT( filterQueryAccepted() ) );
  connect( mSetStyles, SIGNAL( pressed() ), SLOT( openConditionalStyles() ) );

  // info from layer to table
  connect( mLayer, SIGNAL( editingStarted() ), this, SLOT( editingToggled() ) );
  connect( mLayer, SIGNAL( editingStopped() ), this, SLOT( editingToggled() ) );
  connect( mLayer, SIGNAL( layerDeleted() ), this, SLOT( close() ) );
  connect( mLayer, SIGNAL( selectionChanged() ), this, SLOT( updateTitle() ) );
  connect( mLayer, SIGNAL( featureAdded( QgsFeatureId ) ), this, SLOT( updateTitle() ) );
  connect( mLayer, SIGNAL( featuresDeleted( QgsFeatureIds ) ), this, SLOT( updateTitle() ) );
  connect( mLayer, SIGNAL( attributeAdded( int ) ), this, SLOT( columnBoxInit() ) );
  connect( mLayer, SIGNAL( attributeDeleted( int ) ), this, SLOT( columnBoxInit() ) );

  // connect table info to window
  connect( mMainView, SIGNAL( filterChanged() ), this, SLOT( updateTitle() ) );

  // info from table to application
  connect( this, SIGNAL( saveEdits( QgsMapLayer * ) ), QgisApp::instance(), SLOT( saveEdits( QgsMapLayer * ) ) );

  bool myDockFlag = settings.value( "/qgis/dockAttributeTable", false ).toBool();
  if ( myDockFlag )
  {
    mDock = new QgsAttributeTableDock( tr( "Attribute table - %1 (%n Feature(s))", "feature count", mMainView->featureCount() ).arg( mLayer->name() ), QgisApp::instance() );
    mDock->setAllowedAreas( Qt::BottomDockWidgetArea | Qt::TopDockWidgetArea );
    mDock->setWidget( this );
    connect( this, SIGNAL( destroyed() ), mDock, SLOT( close() ) );
    QgisApp::instance()->addDockWidget( Qt::BottomDockWidgetArea, mDock );
  }

  columnBoxInit();
  updateTitle();

  mRemoveSelectionButton->setIcon( QgsApplication::getThemeIcon( "/mActionUnselectAttributes.png" ) );
  mSelectedToTopButton->setIcon( QgsApplication::getThemeIcon( "/mActionSelectedToTop.png" ) );
  mCopySelectedRowsButton->setIcon( QgsApplication::getThemeIcon( "/mActionCopySelected.png" ) );
  mZoomMapToSelectedRowsButton->setIcon( QgsApplication::getThemeIcon( "/mActionZoomToSelected.svg" ) );
  mPanMapToSelectedRowsButton->setIcon( QgsApplication::getThemeIcon( "/mActionPanToSelected.svg" ) );
  mInvertSelectionButton->setIcon( QgsApplication::getThemeIcon( "/mActionInvertSelection.png" ) );
  mToggleEditingButton->setIcon( QgsApplication::getThemeIcon( "/mActionToggleEditing.svg" ) );
  mSaveEditsButton->setIcon( QgsApplication::getThemeIcon( "/mActionSaveEdits.svg" ) );
  mDeleteSelectedButton->setIcon( QgsApplication::getThemeIcon( "/mActionDeleteSelected.svg" ) );
  mOpenFieldCalculator->setIcon( QgsApplication::getThemeIcon( "/mActionCalculateField.png" ) );
  mAddAttribute->setIcon( QgsApplication::getThemeIcon( "/mActionNewAttribute.png" ) );
  mRemoveAttribute->setIcon( QgsApplication::getThemeIcon( "/mActionDeleteAttribute.png" ) );
  mTableViewButton->setIcon( QgsApplication::getThemeIcon( "/mActionOpenTable.png" ) );
  mAttributeViewButton->setIcon( QgsApplication::getThemeIcon( "/mActionPropertyItem.png" ) );
  mExpressionSelectButton->setIcon( QgsApplication::getThemeIcon( "/mIconExpressionSelect.svg" ) );
  mAddFeature->setIcon( QgsApplication::getThemeIcon( "/mActionNewTableRow.png" ) );

  // toggle editing
  bool canChangeAttributes = mLayer->dataProvider()->capabilities() & QgsVectorDataProvider::ChangeAttributeValues;
  bool canDeleteFeatures = mLayer->dataProvider()->capabilities() & QgsVectorDataProvider::DeleteFeatures;
  bool canAddAttributes = mLayer->dataProvider()->capabilities() & QgsVectorDataProvider::AddAttributes;
  bool canDeleteAttributes = mLayer->dataProvider()->capabilities() & QgsVectorDataProvider::DeleteAttributes;
  bool canAddFeatures = mLayer->dataProvider()->capabilities() & QgsVectorDataProvider::AddFeatures;

  mToggleEditingButton->blockSignals( true );
  mToggleEditingButton->setCheckable( true );
  mToggleEditingButton->setChecked( mLayer->isEditable() );
  mToggleEditingButton->setEnabled(( canChangeAttributes || canDeleteFeatures || canAddAttributes || canDeleteAttributes || canAddFeatures ) && !mLayer->isReadOnly() );
  mToggleEditingButton->blockSignals( false );

  mSaveEditsButton->setEnabled( mToggleEditingButton->isEnabled() && mLayer->isEditable() );
  mReloadButton->setEnabled( ! mLayer->isEditable() );
  mAddAttribute->setEnabled(( canChangeAttributes || canAddAttributes ) && mLayer->isEditable() );
  mDeleteSelectedButton->setEnabled( canDeleteFeatures && mLayer->isEditable() );
  mAddFeature->setEnabled( canAddFeatures && mLayer->isEditable() );
  mAddFeature->setHidden( !canAddFeatures );

  mMainViewButtonGroup->setId( mTableViewButton, QgsDualView::AttributeTable );
  mMainViewButtonGroup->setId( mAttributeViewButton, QgsDualView::AttributeEditor );

  // Load default attribute table filter
  QgsAttributeTableFilterModel::FilterMode defaultFilterMode = ( QgsAttributeTableFilterModel::FilterMode ) settings.value( "/qgis/attributeTableBehaviour", QgsAttributeTableFilterModel::ShowAll ).toInt();

  switch ( defaultFilterMode )
  {
    case QgsAttributeTableFilterModel::ShowVisible:
      filterVisible();
      break;

    case QgsAttributeTableFilterModel::ShowSelected:
      filterSelected();
      break;

    case QgsAttributeTableFilterModel::ShowAll:
    default:
      filterShowAll();
      break;
  }

  mUpdateExpressionText->registerGetExpressionContextCallback( &_getExpressionContext, mLayer );

  mFieldModel = new QgsFieldModel( this );
  mFieldModel->setLayer( mLayer );
  mFieldCombo->setModel( mFieldModel );
  connect( mRunFieldCalc, SIGNAL( clicked() ), this, SLOT( updateFieldFromExpression() ) );
  connect( mRunFieldCalcSelected, SIGNAL( clicked() ), this, SLOT( updateFieldFromExpressionSelected() ) );
  // NW TODO Fix in 2.6 - Doesn't work with field model for some reason.
//  connect( mUpdateExpressionText, SIGNAL( returnPressed() ), this, SLOT( updateFieldFromExpression() ) );
  connect( mUpdateExpressionText, SIGNAL( fieldChanged( QString, bool ) ), this, SLOT( updateButtonStatus( QString, bool ) ) );
  mUpdateExpressionText->setLayer( mLayer );
  mUpdateExpressionText->setLeftHandButtonStyle( true );

  mMainView->setView( QgsDualView::AttributeTable );

  editingToggled();
}
예제 #13
0
QgsAttributeTableDialog::QgsAttributeTableDialog( QgsVectorLayer *theLayer, QWidget *parent, Qt::WindowFlags flags )
    : QDialog( parent, flags )
    , mDock( nullptr )
    , mLayer( theLayer )
    , mRubberBand( nullptr )
    , mCurrentSearchWidgetWrapper( nullptr )
{
  setupUi( this );

  Q_FOREACH ( const QgsField& field, mLayer->fields() )
  {
    mVisibleFields.append( field.name() );
  }

  // Fix selection color on loosing focus (Windows)
  setStyleSheet( QgisApp::instance()->styleSheet() );

  setAttribute( Qt::WA_DeleteOnClose );

  layout()->setMargin( 0 );
  layout()->setContentsMargins( 0, 0, 0, 0 );
  static_cast< QGridLayout* >( layout() )->setVerticalSpacing( 0 );

  QSettings settings;

  int size = settings.value( "/IconSize", 16 ).toInt();
  if ( size > 32 )
  {
    size -= 16;
  }
  else if ( size == 32 )
  {
    size = 24;
  }
  else
  {
    size = 16;
  }
  mToolbar->setIconSize( QSize( size, size ) );

  // Initialize the window geometry
  restoreGeometry( settings.value( "/Windows/BetterAttributeTable/geometry" ).toByteArray() );

  myDa = new QgsDistanceArea();

  myDa->setSourceCrs( mLayer->crs() );
  myDa->setEllipsoidalMode( QgisApp::instance()->mapCanvas()->mapSettings().hasCrsTransformEnabled() );
  myDa->setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", GEO_NONE ) );

  mEditorContext.setDistanceArea( *myDa );
  mEditorContext.setVectorLayerTools( QgisApp::instance()->vectorLayerTools() );

  QgsFeatureRequest r;
  if ( mLayer->geometryType() != QGis::NoGeometry &&
       settings.value( "/qgis/attributeTableBehaviour", QgsAttributeTableFilterModel::ShowAll ).toInt() == QgsAttributeTableFilterModel::ShowVisible )
  {
    QgsMapCanvas *mc = QgisApp::instance()->mapCanvas();
    QgsRectangle extent( mc->mapSettings().mapToLayerCoordinates( theLayer, mc->extent() ) );
    r.setFilterRect( extent );

    QgsGeometry *g = QgsGeometry::fromRect( extent );
    mRubberBand = new QgsRubberBand( mc, QGis::Polygon );
    mRubberBand->setToGeometry( g, theLayer );
    delete g;

    mActionShowAllFilter->setText( tr( "Show All Features In Initial Canvas Extent" ) );
  }

  // Initialize dual view
  mMainView->init( mLayer, QgisApp::instance()->mapCanvas(), r, mEditorContext );

  QgsAttributeTableConfig config = mLayer->attributeTableConfig();
  mMainView->setAttributeTableConfig( config );

  // Initialize filter gui elements
  mFilterActionMapper = new QSignalMapper( this );
  mFilterColumnsMenu = new QMenu( this );
  mActionFilterColumnsMenu->setMenu( mFilterColumnsMenu );
  mApplyFilterButton->setDefaultAction( mActionApplyFilter );

  // Set filter icon in a couple of places
  QIcon filterIcon = QgsApplication::getThemeIcon( "/mActionFilter2.svg" );
  mActionShowAllFilter->setIcon( filterIcon );
  mActionAdvancedFilter->setIcon( filterIcon );
  mActionSelectedFilter->setIcon( filterIcon );
  mActionVisibleFilter->setIcon( filterIcon );
  mActionEditedFilter->setIcon( filterIcon );

  // Connect filter signals
  connect( mActionAdvancedFilter, SIGNAL( triggered() ), SLOT( filterExpressionBuilder() ) );
  connect( mActionShowAllFilter, SIGNAL( triggered() ), SLOT( filterShowAll() ) );
  connect( mActionSelectedFilter, SIGNAL( triggered() ), SLOT( filterSelected() ) );
  connect( mActionVisibleFilter, SIGNAL( triggered() ), SLOT( filterVisible() ) );
  connect( mActionEditedFilter, SIGNAL( triggered() ), SLOT( filterEdited() ) );
  connect( mFilterActionMapper, SIGNAL( mapped( QObject* ) ), SLOT( filterColumnChanged( QObject* ) ) );
  connect( mFilterQuery, SIGNAL( returnPressed() ), SLOT( filterQueryAccepted() ) );
  connect( mActionApplyFilter, SIGNAL( triggered() ), SLOT( filterQueryAccepted() ) );
  connect( mActionSetStyles, SIGNAL( triggered() ), SLOT( openConditionalStyles() ) );

  // info from layer to table
  connect( mLayer, SIGNAL( editingStarted() ), this, SLOT( editingToggled() ) );
  connect( mLayer, SIGNAL( editingStopped() ), this, SLOT( editingToggled() ) );
  connect( mLayer, SIGNAL( layerDeleted() ), this, SLOT( close() ) );
  connect( mLayer, SIGNAL( selectionChanged() ), this, SLOT( updateTitle() ) );
  connect( mLayer, SIGNAL( featureAdded( QgsFeatureId ) ), this, SLOT( updateTitle() ) );
  connect( mLayer, SIGNAL( featuresDeleted( QgsFeatureIds ) ), this, SLOT( updateTitle() ) );
  connect( mLayer, SIGNAL( attributeAdded( int ) ), this, SLOT( columnBoxInit() ) );
  connect( mLayer, SIGNAL( attributeDeleted( int ) ), this, SLOT( columnBoxInit() ) );

  // connect table info to window
  connect( mMainView, SIGNAL( filterChanged() ), this, SLOT( updateTitle() ) );
  connect( mMainView, SIGNAL( filterExpressionSet( QString, QgsAttributeForm::FilterType ) ), this, SLOT( formFilterSet( QString, QgsAttributeForm::FilterType ) ) );
  connect( mMainView, SIGNAL( formModeChanged( QgsAttributeForm::Mode ) ), this, SLOT( viewModeChanged( QgsAttributeForm::Mode ) ) );

  // info from table to application
  connect( this, SIGNAL( saveEdits( QgsMapLayer * ) ), QgisApp::instance(), SLOT( saveEdits( QgsMapLayer * ) ) );

  bool myDockFlag = settings.value( "/qgis/dockAttributeTable", false ).toBool();
  if ( myDockFlag )
  {
    mDock = new QgsAttributeTableDock( tr( "%1 (%n Feature(s))", "feature count", mMainView->featureCount() ).arg( mLayer->name() ), QgisApp::instance() );
    mDock->setWidget( this );
    connect( this, SIGNAL( destroyed() ), mDock, SLOT( close() ) );
    QgisApp::instance()->addDockWidget( Qt::BottomDockWidgetArea, mDock );
  }

  columnBoxInit();
  updateTitle();

  mActionRemoveSelection->setIcon( QgsApplication::getThemeIcon( "/mActionDeselectAll.svg" ) );
  mActionSelectAll->setIcon( QgsApplication::getThemeIcon( "/mActionSelectAll.svg" ) );
  mActionSelectedToTop->setIcon( QgsApplication::getThemeIcon( "/mActionSelectedToTop.svg" ) );
  mActionCopySelectedRows->setIcon( QgsApplication::getThemeIcon( "/mActionEditCopy.svg" ) );
  mActionPasteFeatures->setIcon( QgsApplication::getThemeIcon( "/mActionEditPaste.svg" ) );
  mActionZoomMapToSelectedRows->setIcon( QgsApplication::getThemeIcon( "/mActionZoomToSelected.svg" ) );
  mActionPanMapToSelectedRows->setIcon( QgsApplication::getThemeIcon( "/mActionPanToSelected.svg" ) );
  mActionInvertSelection->setIcon( QgsApplication::getThemeIcon( "/mActionInvertSelection.svg" ) );
  mActionToggleEditing->setIcon( QgsApplication::getThemeIcon( "/mActionToggleEditing.svg" ) );
  mActionSaveEdits->setIcon( QgsApplication::getThemeIcon( "/mActionSaveEdits.svg" ) );
  mActionDeleteSelected->setIcon( QgsApplication::getThemeIcon( "/mActionDeleteSelected.svg" ) );
  mActionOpenFieldCalculator->setIcon( QgsApplication::getThemeIcon( "/mActionCalculateField.svg" ) );
  mActionAddAttribute->setIcon( QgsApplication::getThemeIcon( "/mActionNewAttribute.svg" ) );
  mActionRemoveAttribute->setIcon( QgsApplication::getThemeIcon( "/mActionDeleteAttribute.svg" ) );
  mTableViewButton->setIcon( QgsApplication::getThemeIcon( "/mActionOpenTable.svg" ) );
  mAttributeViewButton->setIcon( QgsApplication::getThemeIcon( "/mActionFormView.svg" ) );
  mActionExpressionSelect->setIcon( QgsApplication::getThemeIcon( "/mIconExpressionSelect.svg" ) );
  mActionAddFeature->setIcon( QgsApplication::getThemeIcon( "/mActionNewTableRow.svg" ) );

  // toggle editing
  bool canChangeAttributes = mLayer->dataProvider()->capabilities() & QgsVectorDataProvider::ChangeAttributeValues;
  bool canDeleteFeatures = mLayer->dataProvider()->capabilities() & QgsVectorDataProvider::DeleteFeatures;
  bool canAddAttributes = mLayer->dataProvider()->capabilities() & QgsVectorDataProvider::AddAttributes;
  bool canDeleteAttributes = mLayer->dataProvider()->capabilities() & QgsVectorDataProvider::DeleteAttributes;
  bool canAddFeatures = mLayer->dataProvider()->capabilities() & QgsVectorDataProvider::AddFeatures;

  mActionToggleEditing->blockSignals( true );
  mActionToggleEditing->setCheckable( true );
  mActionToggleEditing->setChecked( mLayer->isEditable() );
  mActionToggleEditing->setEnabled(( canChangeAttributes || canDeleteFeatures || canAddAttributes || canDeleteAttributes || canAddFeatures ) && !mLayer->readOnly() );
  mActionToggleEditing->blockSignals( false );

  mActionSaveEdits->setEnabled( mActionToggleEditing->isEnabled() && mLayer->isEditable() );
  mActionReload->setEnabled( ! mLayer->isEditable() );
  mActionAddAttribute->setEnabled(( canChangeAttributes || canAddAttributes ) && mLayer->isEditable() );
  mActionRemoveAttribute->setEnabled( canDeleteAttributes && mLayer->isEditable() );
  mActionDeleteSelected->setEnabled( canDeleteFeatures && mLayer->isEditable() );
  if ( !canDeleteFeatures )
    mToolbar->removeAction( mActionDeleteSelected );
  mActionAddFeature->setEnabled( canAddFeatures && mLayer->isEditable() );
  if ( !canAddFeatures )
    mToolbar->removeAction( mActionAddFeature );

  if ( canDeleteFeatures || canAddFeatures )
    mToolbar->insertSeparator( mActionExpressionSelect );

  mMainViewButtonGroup->setId( mTableViewButton, QgsDualView::AttributeTable );
  mMainViewButtonGroup->setId( mAttributeViewButton, QgsDualView::AttributeEditor );

  // Load default attribute table filter
  QgsAttributeTableFilterModel::FilterMode defaultFilterMode = ( QgsAttributeTableFilterModel::FilterMode ) settings.value( "/qgis/attributeTableBehaviour", QgsAttributeTableFilterModel::ShowAll ).toInt();

  switch ( defaultFilterMode )
  {
    case QgsAttributeTableFilterModel::ShowVisible:
      filterVisible();
      break;

    case QgsAttributeTableFilterModel::ShowSelected:
      filterSelected();
      break;

    case QgsAttributeTableFilterModel::ShowAll:
    default:
      filterShowAll();
      break;
  }

  mUpdateExpressionText->registerGetExpressionContextCallback( &_getExpressionContext, mLayer );
  mFieldCombo->setFilters( QgsFieldProxyModel::All | QgsFieldProxyModel::HideReadOnly );
  mFieldCombo->setLayer( mLayer );

  connect( mRunFieldCalc, SIGNAL( clicked() ), this, SLOT( updateFieldFromExpression() ) );
  connect( mRunFieldCalcSelected, SIGNAL( clicked() ), this, SLOT( updateFieldFromExpressionSelected() ) );
  // NW TODO Fix in 2.6 - Doesn't work with field model for some reason.
//  connect( mUpdateExpressionText, SIGNAL( returnPressed() ), this, SLOT( updateFieldFromExpression() ) );
  connect( mUpdateExpressionText, SIGNAL( fieldChanged( QString, bool ) ), this, SLOT( updateButtonStatus( QString, bool ) ) );
  mUpdateExpressionText->setLayer( mLayer );
  mUpdateExpressionText->setLeftHandButtonStyle( true );

  int initialView = settings.value( "/qgis/attributeTableView", -1 ).toInt();
  if ( initialView < 0 )
  {
    initialView = settings.value( "/qgis/attributeTableLastView", QgsDualView::AttributeTable ).toInt();
  }
  mMainView->setView( static_cast< QgsDualView::ViewMode >( initialView ) );
  mMainViewButtonGroup->button( initialView )->setChecked( true );

  connect( mActionToggleMultiEdit, SIGNAL( toggled( bool ) ), mMainView, SLOT( setMultiEditEnabled( bool ) ) );
  connect( mActionSearchForm, SIGNAL( toggled( bool ) ), mMainView, SLOT( toggleSearchMode( bool ) ) );
  updateMultiEditButtonState();

  if ( mLayer->editFormConfig()->layout() == QgsEditFormConfig::UiFileLayout )
  {
    //not supported with custom UI
    mActionToggleMultiEdit->setEnabled( false );
    mActionToggleMultiEdit->setToolTip( tr( "Multiedit is not supported when using custom UI forms" ) );
    mActionSearchForm->setEnabled( false );
    mActionSearchForm->setToolTip( tr( "Search is not supported when using custom UI forms" ) );
  }

  editingToggled();
}
QgsAttributeTableDialog::QgsAttributeTableDialog( QgsVectorLayer *theLayer, QWidget *parent, Qt::WindowFlags flags )
    : QDialog( parent, flags )
    , mDock( 0 )
    , mLayer( theLayer )
{
  setupUi( this );

  setAttribute( Qt::WA_DeleteOnClose );

  QSettings settings;

  // Initialize the window geometry
  restoreGeometry( settings.value( "/Windows/BetterAttributeTable/geometry" ).toByteArray() );


  QgsDistanceArea myDa;

  myDa.setSourceCrs( mLayer->crs().srsid() );
  myDa.setEllipsoidalMode( QgisApp::instance()->mapCanvas()->mapRenderer()->hasCrsTransformEnabled() );
  myDa.setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", GEO_NONE ) );

  // Initialize dual view
  mMainView->init( mLayer, QgisApp::instance()->mapCanvas(), myDa );

  // Initialize filter gui elements
  mFilterActionMapper = new QSignalMapper( this );
  mFilterColumnsMenu = new QMenu( this );
  mActionFilterColumnsMenu->setMenu( mFilterColumnsMenu );
  mApplyFilterButton->setDefaultAction( mActionApplyFilter );

  // Set filter icon in a couple of places
  QIcon filterIcon = QgsApplication::getThemeIcon( "/mActionFilter.svg" );
  mActionShowAllFilter->setIcon( filterIcon );
  mActionAdvancedFilter->setIcon( filterIcon );
  mActionSelectedFilter->setIcon( filterIcon );
  mActionVisibleFilter->setIcon( filterIcon );
  mActionEditedFilter->setIcon( filterIcon );

  // Connect filter signals
  connect( mActionAdvancedFilter, SIGNAL( triggered() ), SLOT( filterExpressionBuilder() ) );
  connect( mActionShowAllFilter, SIGNAL( triggered() ), SLOT( filterShowAll() ) );
  connect( mActionSelectedFilter, SIGNAL( triggered() ), SLOT( filterSelected() ) );
  connect( mActionVisibleFilter, SIGNAL( triggered() ), SLOT( filterVisible() ) );
  connect( mActionEditedFilter, SIGNAL( triggered() ), SLOT( filterEdited() ) );
  connect( mFilterActionMapper, SIGNAL( mapped( QObject* ) ), SLOT( filterColumnChanged( QObject* ) ) );
  connect( mFilterQuery, SIGNAL( returnPressed() ), SLOT( filterQueryAccepted() ) );
  connect( mActionApplyFilter, SIGNAL( triggered() ), SLOT( filterQueryAccepted() ) );

  // info from layer to table
  connect( mLayer, SIGNAL( editingStarted() ), this, SLOT( editingToggled() ) );
  connect( mLayer, SIGNAL( editingStopped() ), this, SLOT( editingToggled() ) );
  connect( mLayer, SIGNAL( layerDeleted() ), this, SLOT( close() ) );
  connect( mLayer, SIGNAL( selectionChanged() ), this, SLOT( updateTitle() ) );
  connect( mLayer, SIGNAL( attributeAdded( int ) ), this, SLOT( columnBoxInit() ) );
  connect( mLayer, SIGNAL( attributeDeleted( int ) ), this, SLOT( columnBoxInit() ) );

  // connect table info to window
  connect( mMainView, SIGNAL( filterChanged() ), this, SLOT( updateTitle() ) );

  // info from table to application
  connect( this, SIGNAL( saveEdits( QgsMapLayer * ) ), QgisApp::instance(), SLOT( saveEdits( QgsMapLayer * ) ) );

  bool myDockFlag = settings.value( "/qgis/dockAttributeTable", false ).toBool();
  if ( myDockFlag )
  {
    mDock = new QgsAttributeTableDock( tr( "Attribute table - %1 (%n Feature(s))", "feature count", mMainView->featureCount() ).arg( mLayer->name() ), QgisApp::instance() );
    mDock->setAllowedAreas( Qt::BottomDockWidgetArea | Qt::TopDockWidgetArea );
    mDock->setWidget( this );
    connect( this, SIGNAL( destroyed() ), mDock, SLOT( close() ) );
    QgisApp::instance()->addDockWidget( Qt::BottomDockWidgetArea, mDock );
  }

  columnBoxInit();
  updateTitle();

  mRemoveSelectionButton->setIcon( QgsApplication::getThemeIcon( "/mActionUnselectAttributes.png" ) );
  mSelectedToTopButton->setIcon( QgsApplication::getThemeIcon( "/mActionSelectedToTop.png" ) );
  mCopySelectedRowsButton->setIcon( QgsApplication::getThemeIcon( "/mActionCopySelected.png" ) );
  mZoomMapToSelectedRowsButton->setIcon( QgsApplication::getThemeIcon( "/mActionZoomToSelected.svg" ) );
  mPanMapToSelectedRowsButton->setIcon( QgsApplication::getThemeIcon( "/mActionPanToSelected.png" ) );
  mInvertSelectionButton->setIcon( QgsApplication::getThemeIcon( "/mActionInvertSelection.png" ) );
  mToggleEditingButton->setIcon( QgsApplication::getThemeIcon( "/mActionToggleEditing.svg" ) );
  mSaveEditsButton->setIcon( QgsApplication::getThemeIcon( "/mActionSaveEdits.svg" ) );
  mDeleteSelectedButton->setIcon( QgsApplication::getThemeIcon( "/mActionDeleteSelected.svg" ) );
  mOpenFieldCalculator->setIcon( QgsApplication::getThemeIcon( "/mActionCalculateField.png" ) );
  mAddAttribute->setIcon( QgsApplication::getThemeIcon( "/mActionNewAttribute.png" ) );
  mRemoveAttribute->setIcon( QgsApplication::getThemeIcon( "/mActionDeleteAttribute.png" ) );
  mTableViewButton->setIcon( QgsApplication::getThemeIcon( "/mActionOpenTable.png" ) );
  mAttributeViewButton->setIcon( QgsApplication::getThemeIcon( "/mActionPropertyItem.png" ) );
  mExpressionSelectButton->setIcon( QgsApplication::getThemeIcon( "/mIconExpressionSelect.svg" ) );

  // toggle editing
  bool canChangeAttributes = mLayer->dataProvider()->capabilities() & QgsVectorDataProvider::ChangeAttributeValues;
  bool canDeleteFeatures = mLayer->dataProvider()->capabilities() & QgsVectorDataProvider::DeleteFeatures;
  bool canAddAttributes = mLayer->dataProvider()->capabilities() & QgsVectorDataProvider::AddAttributes;
  bool canDeleteAttributes = mLayer->dataProvider()->capabilities() & QgsVectorDataProvider::DeleteAttributes;
  bool canAddFeatures = mLayer->dataProvider()->capabilities() & QgsVectorDataProvider::AddFeatures;

  mToggleEditingButton->blockSignals( true );
  mToggleEditingButton->setCheckable( true );
  mToggleEditingButton->setChecked( mLayer->isEditable() );
  mToggleEditingButton->setEnabled( canChangeAttributes && !mLayer->isReadOnly() );
  mToggleEditingButton->blockSignals( false );

  mSaveEditsButton->setEnabled( canChangeAttributes && mLayer->isEditable() );
  mOpenFieldCalculator->setEnabled(( canChangeAttributes || canAddAttributes ) && mLayer->isEditable() );
  mDeleteSelectedButton->setEnabled( canDeleteFeatures && mLayer->isEditable() );
  mAddAttribute->setEnabled( canAddAttributes && mLayer->isEditable() );
  mRemoveAttribute->setEnabled( canDeleteAttributes && mLayer->isEditable() );
  mAddFeature->setEnabled( canAddFeatures && mLayer->isEditable() && mLayer->geometryType() == QGis::NoGeometry );
  mAddFeature->setHidden( !canAddFeatures || mLayer->geometryType() != QGis::NoGeometry );

  mMainViewButtonGroup->setId( mTableViewButton, QgsDualView::AttributeTable );
  mMainViewButtonGroup->setId( mAttributeViewButton, QgsDualView::AttributeEditor );

  // Load default attribute table filter
  QgsAttributeTableFilterModel::FilterMode defaultFilterMode = ( QgsAttributeTableFilterModel::FilterMode ) settings.value( "/qgis/attributeTableBehaviour", QgsAttributeTableFilterModel::ShowAll ).toInt();

  switch ( defaultFilterMode )
  {
    case QgsAttributeTableFilterModel::ShowVisible:
      filterVisible();
      break;

    case QgsAttributeTableFilterModel::ShowSelected:
      filterSelected();
      break;

    case QgsAttributeTableFilterModel::ShowAll:
    default:
      filterShowAll();
      break;
  }
}