mirror of
https://github.com/qgis/QGIS.git
synced 2025-10-06 00:07:29 -04:00
[wip] Add container, onItemDoubleClick (create 2 subclasses for tree view's base subclass to get ride of type()). Invert selection. Remove selected items. Other cleanups. Drag and drop initial (partial) implementation.
This commit is contained in:
parent
89246fbbb6
commit
c96c989add
@ -44,7 +44,7 @@ class GUI_EXPORT QgsAttributeFormContainerEdit : public QWidget, private Ui_QgsA
|
||||
|
||||
/**
|
||||
* Sets up the container type comboBox
|
||||
* @param isTopLevelContainer Whether the container is allowed to be a tab or not
|
||||
* \param isTopLevelContainer Whether the container is allowed to be a tab or not
|
||||
*
|
||||
* \since QGIS 3.44
|
||||
*/
|
||||
|
@ -22,13 +22,12 @@
|
||||
#include "qgssettings.h"
|
||||
#include "qgshelp.h"
|
||||
|
||||
#include <QTreeWidgetItem>
|
||||
#include <QComboBox>
|
||||
#include <QRadioButton>
|
||||
|
||||
QgsAddAttributeFormContainerDialog::QgsAddAttributeFormContainerDialog( QgsVectorLayer *lyr, const QList<ContainerPair> &existingContainerList, QTreeWidgetItem *currentTab, QWidget *parent )
|
||||
QgsAddAttributeFormContainerDialog::QgsAddAttributeFormContainerDialog( QgsVectorLayer *layer, const QList<ContainerPair> &existingContainerList, QModelIndex ¤tNodeIndex, QWidget *parent )
|
||||
: QDialog( parent )
|
||||
, mLayer( lyr )
|
||||
, mLayer( layer )
|
||||
, mExistingContainers( existingContainerList )
|
||||
{
|
||||
setupUi( this );
|
||||
@ -46,9 +45,9 @@ QgsAddAttributeFormContainerDialog::QgsAddAttributeFormContainerDialog( QgsVecto
|
||||
for ( const ContainerPair &container : std::as_const( mExistingContainers ) )
|
||||
{
|
||||
mParentCombo->addItem( container.first, i );
|
||||
if ( container.second == currentTab )
|
||||
if ( currentNodeIndex.isValid() && container.second == currentNodeIndex )
|
||||
{
|
||||
mParentCombo->setCurrentIndex( i );
|
||||
mParentCombo->setCurrentIndex( i + 1 ); // Take empty item into account
|
||||
mTypeCombo->setCurrentIndex( mTypeCombo->findData( QVariant::fromValue( Qgis::AttributeEditorContainerType::GroupBox ) ) );
|
||||
}
|
||||
++i;
|
||||
@ -70,13 +69,13 @@ QString QgsAddAttributeFormContainerDialog::name()
|
||||
return mName->text();
|
||||
}
|
||||
|
||||
QTreeWidgetItem *QgsAddAttributeFormContainerDialog::parentContainerItem()
|
||||
QModelIndex QgsAddAttributeFormContainerDialog::parentContainerNode() const
|
||||
{
|
||||
if ( containerType() == Qgis::AttributeEditorContainerType::Tab )
|
||||
return nullptr;
|
||||
return QModelIndex();
|
||||
|
||||
if ( !mParentCombo->currentData().isValid() )
|
||||
return nullptr;
|
||||
return QModelIndex();
|
||||
|
||||
const ContainerPair tab = mExistingContainers.at( mParentCombo->currentData().toInt() );
|
||||
return tab.second;
|
||||
|
@ -26,12 +26,11 @@
|
||||
#include "qgsguiutils.h"
|
||||
#include "qgis_gui.h"
|
||||
|
||||
class QTreeWidgetItem;
|
||||
class QgsVectorLayer;
|
||||
|
||||
/**
|
||||
* \ingroup gui
|
||||
* \brief Dialog to add a tab or group of attributes
|
||||
* \brief Dialog to add a container for attribute widgets
|
||||
*
|
||||
* \note This class is not a part of public API
|
||||
* \since QGIS 3.14
|
||||
@ -41,13 +40,13 @@ class GUI_EXPORT QgsAddAttributeFormContainerDialog : public QDialog, private Ui
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
typedef QPair<QString, QTreeWidgetItem *> ContainerPair;
|
||||
typedef QPair<QString, QModelIndex> ContainerPair;
|
||||
|
||||
public:
|
||||
//! constructor
|
||||
QgsAddAttributeFormContainerDialog( QgsVectorLayer *lyr, const QList<ContainerPair> &existingContainerList, QTreeWidgetItem *currentTab = nullptr, QWidget *parent = nullptr );
|
||||
QgsAddAttributeFormContainerDialog( QgsVectorLayer *layer, const QList<ContainerPair> &existingContainerList, QModelIndex ¤tNodeIndex, QWidget *parent = nullptr );
|
||||
|
||||
//! Returns the name of the tab or group
|
||||
//! Returns the name of the container
|
||||
QString name();
|
||||
|
||||
/**
|
||||
@ -55,7 +54,7 @@ class GUI_EXPORT QgsAddAttributeFormContainerDialog : public QDialog, private Ui
|
||||
*
|
||||
* Will be NULLPTR when a new tab is created.
|
||||
*/
|
||||
QTreeWidgetItem *parentContainerItem();
|
||||
QModelIndex parentContainerNode() const;
|
||||
|
||||
//! Returns the column count
|
||||
int columnCount() const;
|
||||
|
@ -1,3 +1,17 @@
|
||||
/***************************************************************************
|
||||
qgsattributesformmodel.cpp
|
||||
---------------------
|
||||
begin : March 2025
|
||||
copyright : (C) 2025 by Germán Carrillo
|
||||
email : german at opengis dot ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgsactionmanager.h"
|
||||
#include "qgsattributesformmodel.h"
|
||||
@ -11,6 +25,8 @@
|
||||
#include "qgsattributeeditortextelement.h"
|
||||
#include "qgsattributeeditorspacerelement.h"
|
||||
|
||||
#include "QMimeData"
|
||||
|
||||
/*
|
||||
* FieldConfig implementation
|
||||
*/
|
||||
@ -201,14 +217,27 @@ AttributesFormTreeNode *AttributesFormTreeNode::firstChildRecursive( const QgsAt
|
||||
if ( !mChildren.empty() && nodeId.trimmed().isEmpty() )
|
||||
return nullptr;
|
||||
|
||||
// for ( const auto &child : std::as_const( mChildren ) )
|
||||
// {
|
||||
// if ( child->childCount() == 0 )
|
||||
// {
|
||||
// if ( child->type() == nodeType && child->id() == nodeId )
|
||||
// return child.get();
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// AttributesFormTreeNode *node = child->firstChildRecursive( nodeType, nodeId );
|
||||
// if ( node )
|
||||
// return node;
|
||||
// }
|
||||
// }
|
||||
|
||||
for ( const auto &child : std::as_const( mChildren ) )
|
||||
{
|
||||
if ( child->childCount() == 0 )
|
||||
{
|
||||
if ( child->type() == nodeType && child->id() == nodeId )
|
||||
return child.get();
|
||||
}
|
||||
else
|
||||
|
||||
if ( child->childCount() > 0 )
|
||||
{
|
||||
AttributesFormTreeNode *node = child->firstChildRecursive( nodeType, nodeId );
|
||||
if ( node )
|
||||
@ -243,12 +272,29 @@ void AttributesFormTreeNode::addChildItem( std::unique_ptr< AttributesFormTreeNo
|
||||
if ( !item )
|
||||
return;
|
||||
|
||||
Q_ASSERT( !item->mParent );
|
||||
if ( !item->mParent )
|
||||
item->mParent = this;
|
||||
|
||||
mChildren.push_back( std::move( item ) );
|
||||
}
|
||||
|
||||
void AttributesFormTreeNode::insertChildNode( int position, std::unique_ptr< AttributesFormTreeNode > &&node )
|
||||
{
|
||||
if ( position < 0 || position > ( int ) mChildren.size() || !node )
|
||||
return;
|
||||
|
||||
if ( !node->mParent )
|
||||
node->mParent = this;
|
||||
|
||||
mChildren.insert( mChildren.begin() + position, std::move( node ) );
|
||||
}
|
||||
|
||||
void AttributesFormTreeNode::deleteChildAtIndex( int index )
|
||||
{
|
||||
if ( index >= 0 && index < ( int ) mChildren.size() )
|
||||
mChildren.erase( mChildren.begin() + index );
|
||||
}
|
||||
|
||||
void AttributesFormTreeNode::deleteChildren()
|
||||
{
|
||||
mChildren.clear();
|
||||
@ -349,6 +395,46 @@ int QgsAttributesFormModel::columnCount( const QModelIndex &parent ) const
|
||||
return 1;
|
||||
}
|
||||
|
||||
QStringList QgsAttributesFormModel::mimeTypes() const
|
||||
{
|
||||
return QStringList() << QStringLiteral( "application/x-qgsattributetabledesignerelement" );
|
||||
}
|
||||
|
||||
QMimeData *QgsAttributesFormModel::mimeData( const QModelIndexList &indexes ) const
|
||||
{
|
||||
if ( indexes.count() == 0 )
|
||||
return nullptr;
|
||||
|
||||
const QStringList types = mimeTypes();
|
||||
if ( types.isEmpty() )
|
||||
return nullptr;
|
||||
|
||||
QMimeData *data = new QMimeData();
|
||||
const QString format = types.at( 0 );
|
||||
QByteArray encoded;
|
||||
QDataStream stream( &encoded, QIODevice::WriteOnly );
|
||||
|
||||
// Sort indexes since their order reflects selection order
|
||||
QModelIndexList sortedIndexes = indexes;
|
||||
std::sort( sortedIndexes.begin(), sortedIndexes.end() );
|
||||
|
||||
for ( const QModelIndex &index : std::as_const( sortedIndexes ) )
|
||||
{
|
||||
if ( index.isValid() )
|
||||
{
|
||||
const QString nodeId = index.data( QgsAttributesFormModel::NodeIdRole ).toString();
|
||||
const QString nodeName = index.data( QgsAttributesFormModel::NodeNameRole ).toString();
|
||||
int nodeType = index.data( QgsAttributesFormModel::NodeTypeRole ).toInt();
|
||||
const auto nodeData = index.data( QgsAttributesFormModel::NodeDataRole );
|
||||
|
||||
stream << nodeId << nodeType << nodeName << nodeData;
|
||||
}
|
||||
}
|
||||
|
||||
data->setData( format, encoded );
|
||||
return data;
|
||||
}
|
||||
|
||||
QModelIndex QgsAttributesFormModel::index( int row, int column, const QModelIndex &parent ) const
|
||||
{
|
||||
if ( !hasIndex( row, column, parent ) )
|
||||
@ -402,6 +488,20 @@ QgsAttributesAvailableWidgetsModel::QgsAttributesAvailableWidgetsModel( QgsVecto
|
||||
|
||||
//QgsAttributesAvailableWidgetsModel::~QgsAttributesAvailableWidgetsModel() = default;
|
||||
|
||||
Qt::ItemFlags QgsAttributesAvailableWidgetsModel::flags( const QModelIndex &index ) const
|
||||
{
|
||||
if ( !index.isValid() )
|
||||
return Qt::NoItemFlags;
|
||||
|
||||
Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled;
|
||||
|
||||
AttributesFormTreeNode *node = getItem( index );
|
||||
if ( node->type() == QgsAttributeFormTreeData::WidgetType )
|
||||
flags |= Qt::ItemIsDropEnabled;
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
QVariant QgsAttributesAvailableWidgetsModel::headerData( int section, Qt::Orientation orientation, int role ) const
|
||||
{
|
||||
Q_UNUSED( section )
|
||||
@ -644,6 +744,20 @@ QVariant QgsAttributesFormLayoutModel::headerData( int section, Qt::Orientation
|
||||
return orientation == Qt::Horizontal && role == Qt::DisplayRole ? tr( "Form Layout" ) : QVariant {};
|
||||
}
|
||||
|
||||
Qt::ItemFlags QgsAttributesFormLayoutModel::flags( const QModelIndex &index ) const
|
||||
{
|
||||
if ( !index.isValid() )
|
||||
return Qt::NoItemFlags;
|
||||
|
||||
Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled;
|
||||
|
||||
AttributesFormTreeNode *node = getItem( index );
|
||||
if ( node->type() == QgsAttributeFormTreeData::WidgetType || node->type() == QgsAttributeFormTreeData::Container )
|
||||
flags |= Qt::ItemIsDropEnabled;
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
void QgsAttributesFormLayoutModel::populate()
|
||||
{
|
||||
beginResetModel();
|
||||
@ -899,3 +1013,170 @@ bool QgsAttributesFormLayoutModel::setData( const QModelIndex &index, const QVar
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool QgsAttributesFormLayoutModel::removeRows( int row, int count, const QModelIndex &parent )
|
||||
{
|
||||
if ( row < 0 )
|
||||
return false;
|
||||
|
||||
AttributesFormTreeNode *node = getItem( parent );
|
||||
|
||||
if ( row >= node->childCount() )
|
||||
return false;
|
||||
|
||||
beginRemoveRows( parent, row, row + count - 1 );
|
||||
|
||||
// for (int i=row+count-1; i==row; i-- )
|
||||
// {
|
||||
// node->deleteChildAtIndex( i );
|
||||
// }
|
||||
while ( count-- )
|
||||
node->deleteChildAtIndex( row );
|
||||
endRemoveRows();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QgsAttributesFormLayoutModel::removeRow( int row, const QModelIndex &parent )
|
||||
{
|
||||
beginRemoveRows( parent, row, row );
|
||||
AttributesFormTreeNode *node = getItem( parent );
|
||||
node->deleteChildAtIndex( row );
|
||||
endRemoveRows();
|
||||
return true;
|
||||
}
|
||||
|
||||
Qt::DropActions QgsAttributesFormLayoutModel::supportedDropActions() const
|
||||
{
|
||||
return Qt::DropAction::CopyAction | Qt::DropAction::MoveAction;
|
||||
}
|
||||
|
||||
bool QgsAttributesFormLayoutModel::dropMimeData( const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent )
|
||||
{
|
||||
Q_UNUSED( column )
|
||||
bool bDropSuccessful = false;
|
||||
int rows = 0;
|
||||
|
||||
if ( row == -1 ) // Dropped at invalid index
|
||||
row = rowCount( parent ); // Let's append the item
|
||||
|
||||
if ( action == Qt::IgnoreAction )
|
||||
{
|
||||
bDropSuccessful = true;
|
||||
}
|
||||
else if ( data->hasFormat( QStringLiteral( "application/x-qgsattributetabledesignerelement" ) ) )
|
||||
{
|
||||
QByteArray itemData = data->data( QStringLiteral( "application/x-qgsattributetabledesignerelement" ) );
|
||||
QDataStream stream( &itemData, QIODevice::ReadOnly );
|
||||
QgsAttributeFormTreeData::DnDTreeItemData itemElement;
|
||||
|
||||
while ( !stream.atEnd() )
|
||||
{
|
||||
QString nodeId;
|
||||
int nodeTypeInt;
|
||||
QString nodeName;
|
||||
QgsAttributeFormTreeData::DnDTreeItemData nodeData;
|
||||
stream >> nodeId >> nodeTypeInt >> nodeName >> nodeData;
|
||||
|
||||
const auto nodeType = static_cast< QgsAttributeFormTreeData::AttributeFormTreeItemType >( nodeTypeInt );
|
||||
insertNode( parent, row + rows, nodeId, nodeType, nodeName, nodeData );
|
||||
|
||||
bDropSuccessful = true;
|
||||
|
||||
if ( nodeType == QgsAttributeFormTreeData::QmlWidget
|
||||
|| nodeType == QgsAttributeFormTreeData::HtmlWidget
|
||||
|| nodeType == QgsAttributeFormTreeData::TextWidget
|
||||
|| nodeType == QgsAttributeFormTreeData::SpacerWidget )
|
||||
{
|
||||
// Emit signal to open their dialogs
|
||||
}
|
||||
|
||||
//QModelIndex addedIndex = index( row + rows, 0, parent );
|
||||
rows++;
|
||||
//emit nodeDropped( addedIndex );
|
||||
}
|
||||
}
|
||||
|
||||
return bDropSuccessful;
|
||||
}
|
||||
|
||||
|
||||
QList< QgsAddAttributeFormContainerDialog::ContainerPair > QgsAttributesFormLayoutModel::getRecursiveListOfContainers( AttributesFormTreeNode *parent ) const
|
||||
{
|
||||
QList< QgsAddAttributeFormContainerDialog::ContainerPair > containerList;
|
||||
for ( int i = 0; i < parent->childCount(); i++ )
|
||||
{
|
||||
AttributesFormTreeNode *child = parent->child( i );
|
||||
if ( child->type() == QgsAttributeFormTreeData::Container )
|
||||
{
|
||||
containerList << QgsAddAttributeFormContainerDialog::ContainerPair( child->name(), createIndex( child->row(), 0, child ) );
|
||||
}
|
||||
|
||||
if ( child->childCount() > 0 )
|
||||
{
|
||||
containerList.append( getRecursiveListOfContainers( child ) );
|
||||
}
|
||||
}
|
||||
|
||||
return containerList;
|
||||
}
|
||||
|
||||
QList< QgsAddAttributeFormContainerDialog::ContainerPair > QgsAttributesFormLayoutModel::getListOfContainers() const
|
||||
{
|
||||
return getRecursiveListOfContainers( mRootItem.get() );
|
||||
}
|
||||
|
||||
void QgsAttributesFormLayoutModel::addContainer( QModelIndex &parent, const QString &title, int columnCount, Qgis::AttributeEditorContainerType type )
|
||||
{
|
||||
beginInsertRows( parent, rowCount( parent ), rowCount( parent ) );
|
||||
|
||||
AttributesFormTreeNode *parentNode = getItem( parent );
|
||||
|
||||
std::unique_ptr< AttributesFormTreeNode > containerNode = std::make_unique< AttributesFormTreeNode >( QgsAttributeFormTreeData::Container, title, QString(), parentNode );
|
||||
|
||||
QgsAttributeFormTreeData::DnDTreeItemData nodeData;
|
||||
nodeData.setColumnCount( columnCount );
|
||||
nodeData.setContainerType( parent.isValid() ? type : Qgis::AttributeEditorContainerType::Tab );
|
||||
|
||||
containerNode->setData( QgsAttributesFormModel::NodeDataRole, nodeData );
|
||||
parentNode->addChildItem( std::move( containerNode ) );
|
||||
|
||||
endInsertRows();
|
||||
}
|
||||
|
||||
void QgsAttributesFormLayoutModel::insertNode( const QModelIndex &parent, int row, QString &nodeId, QgsAttributeFormTreeData::AttributeFormTreeItemType nodeType, QString &nodeName, QgsAttributeFormTreeData::DnDTreeItemData nodeData )
|
||||
{
|
||||
if ( row < 0 )
|
||||
return;
|
||||
|
||||
beginInsertRows( parent, row, row );
|
||||
std::unique_ptr< AttributesFormTreeNode > node = std::make_unique< AttributesFormTreeNode >();
|
||||
|
||||
node->setData( QgsAttributesFormModel::NodeIdRole, nodeId );
|
||||
node->setData( QgsAttributesFormModel::NodeTypeRole, nodeType );
|
||||
node->setData( QgsAttributesFormModel::NodeNameRole, nodeName );
|
||||
node->setData( QgsAttributesFormModel::NodeDataRole, nodeData );
|
||||
|
||||
getItem( parent )->insertChildNode( row, std::move( node ) );
|
||||
endInsertRows();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Serialization helpers for DesigerTreeItemData so we can stuff this easily into QMimeData
|
||||
*/
|
||||
|
||||
QDataStream &operator<<( QDataStream &stream, const QgsAttributeFormTreeData::DnDTreeItemData &data )
|
||||
{
|
||||
QVariant streamData = QVariant::fromValue<QgsAttributeFormTreeData::DnDTreeItemData>( data );
|
||||
stream << streamData;
|
||||
return stream;
|
||||
}
|
||||
|
||||
QDataStream &operator>>( QDataStream &stream, QgsAttributeFormTreeData::DnDTreeItemData &data )
|
||||
{
|
||||
QVariant streamData;
|
||||
stream >> streamData;
|
||||
data = streamData.value< QgsAttributeFormTreeData::DnDTreeItemData >();
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
@ -1,6 +1,22 @@
|
||||
/***************************************************************************
|
||||
qgsattributesformmodel.h
|
||||
---------------------
|
||||
begin : March 2025
|
||||
copyright : (C) 2025 by Germán Carrillo
|
||||
email : german at opengis dot ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSATTRIBUTESFORMMODEL_H
|
||||
#define QGSATTRIBUTESFORMMODEL_H
|
||||
|
||||
#include "qgsaddtaborgroup.h"
|
||||
#include "qgsattributeeditorelement.h"
|
||||
#include "qgsoptionalexpression.h"
|
||||
#include "qgsvectorlayer.h"
|
||||
@ -322,10 +338,8 @@ class AttributesFormTreeNode
|
||||
|
||||
int childCount() const;
|
||||
//bool insertChildren(int position, int count, int columns);
|
||||
//bool insertColumns(int position, int columns);
|
||||
AttributesFormTreeNode *parent() { return mParent; }
|
||||
//bool removeChildren(int position, int count);
|
||||
//bool removeColumns(int position, int columns);
|
||||
int row() const;
|
||||
QVariant data( int role ) const;
|
||||
bool setData( int role, const QVariant &value );
|
||||
@ -335,13 +349,16 @@ class AttributesFormTreeNode
|
||||
*/
|
||||
void addChildItem( std::unique_ptr< AttributesFormTreeNode > &&child );
|
||||
|
||||
void insertChildNode( int position, std::unique_ptr< AttributesFormTreeNode > &&node );
|
||||
|
||||
void deleteChildAtIndex( int index );
|
||||
|
||||
/**
|
||||
* Deletes all child items from this item.
|
||||
*/
|
||||
void deleteChildren();
|
||||
|
||||
QgsAttributeFormTreeData::AttributeFormTreeItemType type() const { return mNodeType; }
|
||||
|
||||
QString id() const { return mNodeId; }
|
||||
QString name() const { return mName; }
|
||||
|
||||
@ -398,6 +415,12 @@ class QgsAttributesFormModel : public QAbstractItemModel
|
||||
int rowCount( const QModelIndex &parent = QModelIndex() ) const override;
|
||||
int columnCount( const QModelIndex &parent = QModelIndex() ) const override;
|
||||
|
||||
// Drag and drop support
|
||||
//Qt::DropActions supportedDropActions() const override;
|
||||
QStringList mimeTypes() const override;
|
||||
QMimeData *mimeData( const QModelIndexList &indexes ) const override;
|
||||
//bool dropMimeData( const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent ) override;
|
||||
|
||||
//QVariant data( const QModelIndex &index, int role = Qt::DisplayRole ) const override;
|
||||
//bool setData( const QModelIndex &index, const QVariant &value, int role = Qt::EditRole ) override;
|
||||
|
||||
@ -435,7 +458,7 @@ class QgsAttributesAvailableWidgetsModel : public QgsAttributesFormModel
|
||||
|
||||
//~QgsAttributesAvailableWidgetsModel() override;
|
||||
|
||||
// Header:
|
||||
Qt::ItemFlags flags( const QModelIndex &index ) const override;
|
||||
QVariant headerData( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const override;
|
||||
|
||||
// Basic functionality:
|
||||
@ -448,6 +471,12 @@ class QgsAttributesAvailableWidgetsModel : public QgsAttributesFormModel
|
||||
QVariant data( const QModelIndex &index, int role = Qt::DisplayRole ) const override;
|
||||
bool setData( const QModelIndex &index, const QVariant &value, int role = Qt::EditRole ) override;
|
||||
|
||||
// Drag and drop support
|
||||
//Qt::DropActions supportedDropActions() const override;
|
||||
//QStringList mimeTypes() const override;
|
||||
//QMimeData *mimeData( const QModelIndexList &indexes ) const override;
|
||||
//bool dropMimeData( const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent ) override;
|
||||
|
||||
// Add data:
|
||||
//bool insertRows( int row, int count, const QModelIndex &parent = QModelIndex() ) override;
|
||||
//bool insertColumns( int column, int count, const QModelIndex &parent = QModelIndex() ) override;
|
||||
@ -477,7 +506,7 @@ class QgsAttributesFormLayoutModel : public QgsAttributesFormModel
|
||||
|
||||
//~QgsAttributesFormLayoutModel() override;
|
||||
|
||||
// Header:
|
||||
Qt::ItemFlags flags( const QModelIndex &index ) const override;
|
||||
QVariant headerData( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const override;
|
||||
|
||||
// Basic functionality:
|
||||
@ -490,21 +519,38 @@ class QgsAttributesFormLayoutModel : public QgsAttributesFormModel
|
||||
QVariant data( const QModelIndex &index, int role = Qt::DisplayRole ) const override;
|
||||
bool setData( const QModelIndex &index, const QVariant &value, int role = Qt::EditRole ) override;
|
||||
|
||||
// Add data:
|
||||
// Add/remove data:
|
||||
//bool insertRows( int row, int count, const QModelIndex &parent = QModelIndex() ) override;
|
||||
//bool insertColumns( int column, int count, const QModelIndex &parent = QModelIndex() ) override;
|
||||
bool removeRows( int row, int count, const QModelIndex &parent = QModelIndex() ) override;
|
||||
bool removeRow( int row, const QModelIndex &parent = QModelIndex() );
|
||||
|
||||
// Remove data:
|
||||
//bool removeRows( int row, int count, const QModelIndex &parent = QModelIndex() ) override;
|
||||
//bool removeColumns( int column, int count, const QModelIndex &parent = QModelIndex() ) override;
|
||||
// Drag and drop support
|
||||
Qt::DropActions supportedDropActions() const override;
|
||||
//QStringList mimeTypes() const override;
|
||||
//QMimeData *mimeData( const QModelIndexList &indexes ) const override;
|
||||
bool dropMimeData( const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent ) override;
|
||||
|
||||
// Other methods
|
||||
//QModelIndex getFieldModelIndex( const QString &fieldName ) const;
|
||||
QList< QgsAddAttributeFormContainerDialog::ContainerPair > getListOfContainers() const;
|
||||
|
||||
/**
|
||||
* Adds a new container to \a parent.
|
||||
*
|
||||
* If no \a parent is set then the container will be forced to be a tab widget.
|
||||
*/
|
||||
void addContainer( QModelIndex &parent, const QString &title, int columnCount, Qgis::AttributeEditorContainerType type );
|
||||
|
||||
void insertNode( const QModelIndex &parent, int row, QString &nodeId, QgsAttributeFormTreeData::AttributeFormTreeItemType nodeType, QString &nodeName, QgsAttributeFormTreeData::DnDTreeItemData nodeData );
|
||||
|
||||
public slots:
|
||||
void populate() override;
|
||||
|
||||
signals:
|
||||
//! Informs that nodes were inserted (via drop) in the model.
|
||||
void nodeDropped( QModelIndex &index );
|
||||
|
||||
private:
|
||||
QList< QgsAddAttributeFormContainerDialog::ContainerPair > getRecursiveListOfContainers( AttributesFormTreeNode *parent ) const;
|
||||
void loadAttributeEditorElementItem( QgsAttributeEditorElement *const editorElement, AttributesFormTreeNode *parent );
|
||||
//AttributeFormLayoutTreeItem *getItem( const QModelIndex &index ) const;
|
||||
|
||||
@ -514,6 +560,10 @@ class QgsAttributesFormLayoutModel : public QgsAttributesFormModel
|
||||
};
|
||||
|
||||
|
||||
QDataStream &operator<<( QDataStream &stream, const QgsAttributeFormTreeData::DnDTreeItemData &data );
|
||||
QDataStream &operator>>( QDataStream &stream, QgsAttributeFormTreeData::DnDTreeItemData &data );
|
||||
|
||||
|
||||
Q_DECLARE_METATYPE( QgsAttributeFormTreeData::RelationEditorConfiguration )
|
||||
Q_DECLARE_METATYPE( QgsAttributeFormTreeData::FieldConfig )
|
||||
Q_DECLARE_METATYPE( QgsAttributeFormTreeData::DnDTreeItemData )
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -45,11 +45,10 @@
|
||||
#include "qgspropertycollection.h"
|
||||
#include "qgsmessagebar.h"
|
||||
|
||||
class QgsAttributesDnDTree;
|
||||
class QgsAttributeFormContainerEdit;
|
||||
class QgsAttributeTypeDialog;
|
||||
class QgsAttributeWidgetEdit;
|
||||
class QgsAttributesFormTreeView;
|
||||
class QgsAttributesFormBaseTreeView;
|
||||
|
||||
/**
|
||||
* \ingroup gui
|
||||
@ -68,320 +67,6 @@ class GUI_EXPORT QgsAttributesFormProperties : public QWidget, public QgsExpress
|
||||
FieldNameRole,
|
||||
};
|
||||
|
||||
struct RelationEditorConfiguration
|
||||
{
|
||||
operator QVariant();
|
||||
|
||||
QString mRelationWidgetType;
|
||||
QVariantMap mRelationWidgetConfig;
|
||||
QVariant nmRelationId;
|
||||
bool forceSuppressFormPopup = false;
|
||||
QString label;
|
||||
};
|
||||
|
||||
struct QmlElementEditorConfiguration
|
||||
{
|
||||
QString qmlCode;
|
||||
};
|
||||
|
||||
struct HtmlElementEditorConfiguration
|
||||
{
|
||||
QString htmlCode;
|
||||
};
|
||||
|
||||
struct TextElementEditorConfiguration
|
||||
{
|
||||
QString text;
|
||||
};
|
||||
|
||||
struct SpacerElementEditorConfiguration
|
||||
{
|
||||
bool drawLine = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* \ingroup gui
|
||||
* \class DnDTreeItemData
|
||||
* \brief A tree widget item containing drag-and-drop form designer elements.
|
||||
*/
|
||||
class DnDTreeItemData : public QTreeWidgetItem
|
||||
{
|
||||
public:
|
||||
enum Type
|
||||
{
|
||||
Field,
|
||||
Relation,
|
||||
Container, //!< Container for the form
|
||||
QmlWidget,
|
||||
HtmlWidget,
|
||||
WidgetType, //!< In the widget tree, the type of widget
|
||||
Action, //!< Layer action
|
||||
TextWidget, //!< Text widget type, \since QGIS 3.30
|
||||
SpacerWidget, //!< Spacer widget type, \since QGIS 3.30
|
||||
};
|
||||
|
||||
//do we need that
|
||||
DnDTreeItemData() = default;
|
||||
|
||||
DnDTreeItemData( Type type, const QString &name, const QString &displayName, const QColor &backgroundColor = QColor() )
|
||||
: mType( type )
|
||||
, mName( name )
|
||||
, mDisplayName( displayName )
|
||||
, mBackgroundColor( backgroundColor )
|
||||
{}
|
||||
|
||||
QString name() const { return mName; }
|
||||
void setName( const QString &name ) { mName = name; }
|
||||
|
||||
QString displayName() const { return mDisplayName; }
|
||||
void setDisplayName( const QString &displayName ) { mDisplayName = displayName; }
|
||||
|
||||
Type type() const { return mType; }
|
||||
void setType( Type type ) { mType = type; }
|
||||
|
||||
operator QVariant() { return QVariant::fromValue<DnDTreeItemData>( *this ); }
|
||||
|
||||
int columnCount() const { return mColumnCount; }
|
||||
void setColumnCount( int count ) { mColumnCount = count; }
|
||||
|
||||
/**
|
||||
* Returns the container type.
|
||||
*
|
||||
* \see setContainerType()
|
||||
* \since QGIS 3.32
|
||||
*/
|
||||
Qgis::AttributeEditorContainerType containerType() const;
|
||||
|
||||
/**
|
||||
* Sets the container type.
|
||||
*
|
||||
* \see containerType()
|
||||
* \since QGIS 3.32
|
||||
*/
|
||||
void setContainerType( Qgis::AttributeEditorContainerType type );
|
||||
|
||||
/**
|
||||
* For group box containers returns if this group box is collapsed.
|
||||
*
|
||||
* \returns TRUE if the group box is collapsed, FALSE otherwise.
|
||||
* \see collapsed()
|
||||
* \see setCollapsed()
|
||||
* \since QGIS 3.26
|
||||
*/
|
||||
bool collapsed() const { return mCollapsed; };
|
||||
|
||||
/**
|
||||
* For group box containers sets if this group box is \a collapsed.
|
||||
*
|
||||
* \see collapsed()
|
||||
* \see setCollapsed()
|
||||
* \since QGIS 3.26
|
||||
*/
|
||||
void setCollapsed( bool collapsed ) { mCollapsed = collapsed; };
|
||||
|
||||
/**
|
||||
* Returns the label style.
|
||||
* \see setLabelStyle()
|
||||
* \since QGIS 3.26
|
||||
*/
|
||||
const QgsAttributeEditorElement::LabelStyle labelStyle() const;
|
||||
|
||||
/**
|
||||
* Sets the label style to \a labelStyle.
|
||||
* \see labelStyle()
|
||||
* \since QGIS 3.26
|
||||
*/
|
||||
void setLabelStyle( const QgsAttributeEditorElement::LabelStyle &labelStyle );
|
||||
|
||||
bool showLabel() const;
|
||||
void setShowLabel( bool showLabel );
|
||||
|
||||
/**
|
||||
* Returns the horizontal stretch factor for the element.
|
||||
*
|
||||
* \see setHorizontalStretch()
|
||||
* \see verticalStretch()
|
||||
*
|
||||
* \since QGIS 3.32
|
||||
*/
|
||||
int horizontalStretch() const { return mHorizontalStretch; }
|
||||
|
||||
/**
|
||||
* Sets the horizontal \a stretch factor for the element.
|
||||
*
|
||||
* \see horizontalStretch()
|
||||
* \see setVerticalStretch()
|
||||
*
|
||||
* \since QGIS 3.32
|
||||
*/
|
||||
void setHorizontalStretch( int stretch ) { mHorizontalStretch = stretch; }
|
||||
|
||||
/**
|
||||
* Returns the vertical stretch factor for the element.
|
||||
*
|
||||
* \see setVerticalStretch()
|
||||
* \see horizontalStretch()
|
||||
*
|
||||
* \since QGIS 3.32
|
||||
*/
|
||||
int verticalStretch() const { return mVerticalStretch; }
|
||||
|
||||
/**
|
||||
* Sets the vertical \a stretch factor for the element.
|
||||
*
|
||||
* \see verticalStretch()
|
||||
* \see setHorizontalStretch()
|
||||
*
|
||||
* \since QGIS 3.32
|
||||
*/
|
||||
void setVerticalStretch( int stretch ) { mVerticalStretch = stretch; }
|
||||
|
||||
QgsOptionalExpression visibilityExpression() const;
|
||||
|
||||
/**
|
||||
* Sets the optional \a visibilityExpression that dynamically controls the visibility status of a container.
|
||||
*
|
||||
* \see visibilityExpression()
|
||||
* \since QGIS 3.26
|
||||
*/
|
||||
void setVisibilityExpression( const QgsOptionalExpression &visibilityExpression );
|
||||
|
||||
/**
|
||||
* Returns the optional expression that dynamically controls the collapsed status of a group box container.
|
||||
*
|
||||
* \see collapsed()
|
||||
* \see setCollapsed()
|
||||
* \see setCollapsedExpression()
|
||||
* \since QGIS 3.26
|
||||
*/
|
||||
QgsOptionalExpression collapsedExpression() const;
|
||||
|
||||
/**
|
||||
* Sets the optional \a collapsedExpression that dynamically controls the collapsed status of a group box container.
|
||||
*
|
||||
* \see collapsed()
|
||||
* \see setCollapsed()
|
||||
* \see collapsedExpression()
|
||||
* \since QGIS 3.26
|
||||
*/
|
||||
void setCollapsedExpression( const QgsOptionalExpression &collapsedExpression );
|
||||
|
||||
/**
|
||||
* Returns the relation editor configuration.
|
||||
*
|
||||
* \see setRelationEditorConfiguration()
|
||||
*/
|
||||
RelationEditorConfiguration relationEditorConfiguration() const;
|
||||
|
||||
/**
|
||||
* Sets the relation editor configuration.
|
||||
*
|
||||
* \see relationEditorConfiguration()
|
||||
*/
|
||||
void setRelationEditorConfiguration( const RelationEditorConfiguration &relationEditorConfiguration );
|
||||
|
||||
/**
|
||||
* Returns the QML editor configuration.
|
||||
*
|
||||
* \see setQmlElementEditorConfiguration()
|
||||
*/
|
||||
QmlElementEditorConfiguration qmlElementEditorConfiguration() const;
|
||||
|
||||
/**
|
||||
* Sets the QML editor configuration.
|
||||
*
|
||||
* \see qmlElementEditorConfiguration()
|
||||
*/
|
||||
void setQmlElementEditorConfiguration( const QmlElementEditorConfiguration &qmlElementEditorConfiguration );
|
||||
|
||||
/**
|
||||
* Returns the HTML editor configuration.
|
||||
*
|
||||
* \see setHtmlElementEditorConfiguration()
|
||||
*/
|
||||
HtmlElementEditorConfiguration htmlElementEditorConfiguration() const;
|
||||
|
||||
/**
|
||||
* Sets the HTML editor configuration.
|
||||
*
|
||||
* \see htmlElementEditorConfiguration()
|
||||
*/
|
||||
void setHtmlElementEditorConfiguration( const HtmlElementEditorConfiguration &htmlElementEditorConfiguration );
|
||||
|
||||
/**
|
||||
* Returns the spacer element configuration
|
||||
* \since QGIS 3.30
|
||||
*/
|
||||
SpacerElementEditorConfiguration spacerElementEditorConfiguration() const;
|
||||
|
||||
/**
|
||||
* Sets the the spacer element configuration to \a spacerElementEditorConfiguration
|
||||
* \since QGIS 3.30
|
||||
*/
|
||||
void setSpacerElementEditorConfiguration( SpacerElementEditorConfiguration spacerElementEditorConfiguration );
|
||||
|
||||
QColor backgroundColor() const;
|
||||
void setBackgroundColor( const QColor &backgroundColor );
|
||||
|
||||
/**
|
||||
* Returns the editor configuration for text element.
|
||||
* \since QGIS 3.30
|
||||
*/
|
||||
TextElementEditorConfiguration textElementEditorConfiguration() const;
|
||||
|
||||
/**
|
||||
* Sets the editor configuration for text element to \a textElementEditorConfiguration.
|
||||
* \since QGIS 3.30
|
||||
*/
|
||||
void setTextElementEditorConfiguration( const TextElementEditorConfiguration &textElementEditorConfiguration );
|
||||
|
||||
private:
|
||||
Type mType = Field;
|
||||
QString mName;
|
||||
QString mDisplayName;
|
||||
int mColumnCount = 1;
|
||||
Qgis::AttributeEditorContainerType mContainerType = Qgis::AttributeEditorContainerType::Tab;
|
||||
bool mShowLabel = true;
|
||||
int mHorizontalStretch = 0;
|
||||
int mVerticalStretch = 0;
|
||||
QgsOptionalExpression mVisibilityExpression;
|
||||
RelationEditorConfiguration mRelationEditorConfiguration;
|
||||
QmlElementEditorConfiguration mQmlElementEditorConfiguration;
|
||||
HtmlElementEditorConfiguration mHtmlElementEditorConfiguration;
|
||||
TextElementEditorConfiguration mTextElementEditorConfiguration;
|
||||
SpacerElementEditorConfiguration mSpacerElementEditorConfiguration;
|
||||
QColor mBackgroundColor;
|
||||
bool mCollapsed = false;
|
||||
QgsOptionalExpression mCollapsedExpression;
|
||||
QgsAttributeEditorElement::LabelStyle mLabelStyle;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Holds the configuration for a field
|
||||
*/
|
||||
struct FieldConfig
|
||||
{
|
||||
FieldConfig() = default;
|
||||
FieldConfig( QgsVectorLayer *layer, int idx );
|
||||
|
||||
bool mEditable = true;
|
||||
bool mLabelOnTop = false;
|
||||
bool mReuseLastValues = false;
|
||||
QgsFieldConstraints mFieldConstraints;
|
||||
QPushButton *mButton = nullptr;
|
||||
QString mEditorWidgetType;
|
||||
QMap<QString, QVariant> mEditorWidgetConfig;
|
||||
QString mAlias;
|
||||
QgsPropertyCollection mDataDefinedProperties;
|
||||
QString mComment;
|
||||
Qgis::FieldDomainSplitPolicy mSplitPolicy = Qgis::FieldDomainSplitPolicy::Duplicate;
|
||||
Qgis::FieldDuplicatePolicy mDuplicatePolicy = Qgis::FieldDuplicatePolicy::Duplicate;
|
||||
Qgis::FieldDomainMergePolicy mMergePolicy = Qgis::FieldDomainMergePolicy::DefaultValue;
|
||||
|
||||
operator QVariant();
|
||||
};
|
||||
|
||||
public:
|
||||
explicit QgsAttributesFormProperties( QgsVectorLayer *layer, QWidget *parent = nullptr );
|
||||
|
||||
@ -419,11 +104,8 @@ class GUI_EXPORT QgsAttributesFormProperties : public QWidget, public QgsExpress
|
||||
//QList<QgsRelation> mRelations;
|
||||
QgsVectorLayer *mLayer = nullptr;
|
||||
|
||||
QgsAttributesDnDTree *mAvailableWidgetsTree = nullptr;
|
||||
QgsAttributesDnDTree *mFormLayoutTree = nullptr;
|
||||
|
||||
QgsAttributesFormTreeView *mAvailableWidgetsTreeView = nullptr;
|
||||
QgsAttributesFormTreeView *mFormLayoutTreeView = nullptr;
|
||||
QgsAttributesFormBaseTreeView *mAvailableWidgetsTreeView = nullptr;
|
||||
QgsAttributesFormBaseTreeView *mFormLayoutTreeView = nullptr;
|
||||
|
||||
QgsAttributeWidgetEdit *mAttributeWidgetEdit = nullptr;
|
||||
QgsAttributeTypeDialog *mAttributeTypeDialog = nullptr;
|
||||
@ -438,7 +120,7 @@ class GUI_EXPORT QgsAttributesFormProperties : public QWidget, public QgsExpress
|
||||
void mTbInitCode_clicked();
|
||||
|
||||
void onInvertSelectionButtonClicked( bool checked );
|
||||
void loadAttributeSpecificEditor( QgsAttributesFormTreeView *emitter, QgsAttributesFormTreeView *receiver, QModelIndex &deselectedFormLayoutIndex );
|
||||
void loadAttributeSpecificEditor( QgsAttributesFormBaseTreeView *emitter, QgsAttributesFormBaseTreeView *receiver, QModelIndex &deselectedFormLayoutIndex );
|
||||
void onAttributeSelectionChanged( const QItemSelection &selected, const QItemSelection &deselected );
|
||||
void onFormLayoutSelectionChanged( const QItemSelection &selected, const QItemSelection &deselected );
|
||||
|
||||
@ -448,7 +130,7 @@ class GUI_EXPORT QgsAttributesFormProperties : public QWidget, public QgsExpress
|
||||
void updatedFields();
|
||||
|
||||
private:
|
||||
QModelIndex getPreviousIndex( const QgsAttributesFormTreeView *treeView, const QItemSelection &deselected ) const;
|
||||
QModelIndex getPreviousIndex( const QgsAttributesFormBaseTreeView *treeView, const QItemSelection &deselected ) const;
|
||||
|
||||
//! this will clean the right panel
|
||||
void clearAttributeTypeFrame();
|
||||
@ -472,8 +154,6 @@ class GUI_EXPORT QgsAttributesFormProperties : public QWidget, public QgsExpress
|
||||
void copyWidgetConfiguration();
|
||||
void pasteWidgetConfiguration();
|
||||
|
||||
QTreeWidgetItem *loadAttributeEditorTreeItem( QgsAttributeEditorElement *widgetDef, QTreeWidgetItem *parent, QgsAttributesDnDTree *tree );
|
||||
|
||||
QgsAttributesAvailableWidgetsModel *mAvailableWidgetsModel;
|
||||
QgsAttributesFormLayoutModel *mFormLayoutModel;
|
||||
|
||||
@ -494,133 +174,71 @@ class GUI_EXPORT QgsAttributesFormProperties : public QWidget, public QgsExpress
|
||||
};
|
||||
|
||||
|
||||
//QDataStream &operator<<( QDataStream &stream, const QgsAttributesFormProperties::DnDTreeItemData &data );
|
||||
//QDataStream &operator>>( QDataStream &stream, QgsAttributesFormProperties::DnDTreeItemData &data );
|
||||
|
||||
|
||||
/**
|
||||
* \ingroup gui
|
||||
* \class QgsAttributesDnDTree
|
||||
* \class QgsAttributesFormBaseTreeView
|
||||
*
|
||||
* \brief Overrides mime type handling to be able to work with
|
||||
* the drag and drop attribute editor.
|
||||
*
|
||||
* The mime type is application/x-qgsattributetablefield
|
||||
*
|
||||
* Graphical representation for the attribute editor drag and drop editor
|
||||
* Graphical representation for the attribute drag and drop editor
|
||||
*/
|
||||
class GUI_EXPORT QgsAttributesDnDTree : public QTreeWidget, private QgsExpressionContextGenerator
|
||||
class GUI_EXPORT QgsAttributesFormBaseTreeView : public QTreeView, protected QgsExpressionContextGenerator
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit QgsAttributesDnDTree( QgsVectorLayer *layer, QWidget *parent = nullptr );
|
||||
|
||||
/**
|
||||
* Adds a new item to a \a parent. If \a index is -1, the item is added to the end of the parent's existing children.
|
||||
* Otherwise it is inserted at the specified \a index.
|
||||
*/
|
||||
//QTreeWidgetItem *addItem( QTreeWidgetItem *parent, const QgsAttributesFormProperties::DnDTreeItemData &data, int index = -1, const QIcon &icon = QIcon() );
|
||||
|
||||
/**
|
||||
* Adds a new container to \a parent.
|
||||
*
|
||||
* If no \a parent is set then the container will be forced to a tab widget.
|
||||
*/
|
||||
QTreeWidgetItem *addContainer( QTreeWidgetItem *parent, const QString &title, int columnCount, Qgis::AttributeEditorContainerType type );
|
||||
|
||||
enum Type
|
||||
{
|
||||
Drag,
|
||||
Drop
|
||||
};
|
||||
|
||||
|
||||
Type type() const;
|
||||
void setType( QgsAttributesDnDTree::Type value );
|
||||
|
||||
public slots:
|
||||
void selectFirstMatchingItem( const QgsAttributeFormTreeData::DnDTreeItemData &data );
|
||||
|
||||
protected:
|
||||
void dragMoveEvent( QDragMoveEvent *event ) override;
|
||||
void dropEvent( QDropEvent *event ) override;
|
||||
bool dropMimeData( QTreeWidgetItem *parent, int index, const QMimeData *data, Qt::DropAction action ) override;
|
||||
|
||||
// QTreeWidget interface
|
||||
protected:
|
||||
QStringList mimeTypes() const override;
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
|
||||
QMimeData *mimeData( const QList<QTreeWidgetItem *> items ) const override;
|
||||
#else
|
||||
QMimeData *mimeData( const QList<QTreeWidgetItem *> &items ) const override;
|
||||
#endif
|
||||
|
||||
private slots:
|
||||
void onItemDoubleClicked( QTreeWidgetItem *item, int column );
|
||||
|
||||
private:
|
||||
QgsVectorLayer *mLayer = nullptr;
|
||||
Type mType = QgsAttributesDnDTree::Type::Drag;
|
||||
explicit QgsAttributesFormBaseTreeView( QgsVectorLayer *layer, QWidget *parent = nullptr );
|
||||
|
||||
// QgsExpressionContextGenerator interface
|
||||
public:
|
||||
QgsExpressionContext createExpressionContext() const override;
|
||||
};
|
||||
|
||||
|
||||
class GUI_EXPORT QgsAttributesFormTreeView : public QTreeView, private QgsExpressionContextGenerator
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit QgsAttributesFormTreeView( QgsVectorLayer *layer, QWidget *parent = nullptr );
|
||||
|
||||
/**
|
||||
* Adds a new item to a \a parent. If \a index is -1, the item is added to the end of the parent's existing children.
|
||||
* Otherwise it is inserted at the specified \a index.
|
||||
*/
|
||||
//QTreeWidgetItem *addItem( QTreeWidgetItem *parent, const QgsAttributesFormProperties::DnDTreeItemData &data, int index = -1, const QIcon &icon = QIcon() );
|
||||
|
||||
enum Type
|
||||
{
|
||||
Drag,
|
||||
Drop
|
||||
};
|
||||
|
||||
|
||||
Type type() const;
|
||||
void setType( QgsAttributesDnDTree::Type value );
|
||||
|
||||
public slots:
|
||||
void selectFirstMatchingItem( const QgsAttributeFormTreeData::AttributeFormTreeItemType &nodeType, const QString &nodeId );
|
||||
|
||||
// protected:
|
||||
// void dragMoveEvent( QDragMoveEvent *event ) override;
|
||||
// void dropEvent( QDropEvent *event ) override;
|
||||
// bool dropMimeData( QTreeWidgetItem *parent, int index, const QMimeData *data, Qt::DropAction action ) override;
|
||||
protected:
|
||||
QgsVectorLayer *mLayer = nullptr;
|
||||
};
|
||||
|
||||
// QTreeWidget interface
|
||||
// protected:
|
||||
// QStringList mimeTypes() const override;
|
||||
class GUI_EXPORT QgsAttributesAvailableWidgetsTreeView : public QgsAttributesFormBaseTreeView
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
// #if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
|
||||
// QMimeData *mimeData( const QList<QTreeWidgetItem *> items ) const override;
|
||||
// #else
|
||||
// QMimeData *mimeData( const QList<QTreeWidgetItem *> &items ) const override;
|
||||
// #endif
|
||||
public:
|
||||
explicit QgsAttributesAvailableWidgetsTreeView( QgsVectorLayer *layer, QWidget *parent = nullptr );
|
||||
|
||||
//! Overridden setModel() from base class. Only QgsAttributesAvailableWidgetsModel is an acceptable model.
|
||||
void setModel( QAbstractItemModel *model ) override;
|
||||
|
||||
//! Gets access to the QgsAttributesAvailableWidgetsModel model
|
||||
QgsAttributesAvailableWidgetsModel *availableWidgetsModel() const;
|
||||
|
||||
private:
|
||||
QgsAttributesAvailableWidgetsModel *mModel;
|
||||
};
|
||||
|
||||
class GUI_EXPORT QgsAttributesFormLayoutTreeView : public QgsAttributesFormBaseTreeView
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit QgsAttributesFormLayoutTreeView( QgsVectorLayer *layer, QWidget *parent = nullptr );
|
||||
|
||||
//! Overridden setModel() from base class. Only QgsAttributesFormLayoutModel is an acceptable model.
|
||||
void setModel( QAbstractItemModel *model ) override;
|
||||
|
||||
//! Gets access to the QgsAttributesFormLayoutModel model
|
||||
QgsAttributesFormLayoutModel *formLayoutModel() const;
|
||||
|
||||
protected:
|
||||
void dragEnterEvent( QDragEnterEvent *event ) override;
|
||||
|
||||
void dragMoveEvent( QDragMoveEvent *event ) override;
|
||||
void dropEvent( QDropEvent *event ) override;
|
||||
|
||||
private slots:
|
||||
void onItemDoubleClicked( const QModelIndex &index );
|
||||
void selectDroppedNode( QModelIndex &index );
|
||||
|
||||
private:
|
||||
QgsVectorLayer *mLayer = nullptr;
|
||||
// Type mType = QgsAttributesDnDTree::Type::Drag;
|
||||
|
||||
// QgsExpressionContextGenerator interface
|
||||
public:
|
||||
QgsExpressionContext createExpressionContext() const override;
|
||||
QgsAttributesFormLayoutModel *mModel;
|
||||
};
|
||||
|
||||
#endif // QGSATTRIBUTESFORMPROPERTIES_H
|
||||
|
@ -63,26 +63,26 @@ void TestQgsAttributesFormProperties::testConfigStored()
|
||||
attributeFormProperties.init();
|
||||
|
||||
// Get the fields
|
||||
QVERIFY( attributeFormProperties.mAvailableWidgetsTree );
|
||||
QTreeWidgetItem *fieldsItem = attributeFormProperties.mAvailableWidgetsTree->topLevelItem( 0 );
|
||||
QVERIFY( fieldsItem );
|
||||
QCOMPARE( fieldsItem->text( 0 ), QStringLiteral( "Fields" ) );
|
||||
QCOMPARE( fieldsItem->childCount(), 2 );
|
||||
// QVERIFY( attributeFormProperties.mAvailableWidgetsTree );
|
||||
// QTreeWidgetItem *fieldsItem = attributeFormProperties.mAvailableWidgetsTree->topLevelItem( 0 );
|
||||
// QVERIFY( fieldsItem );
|
||||
// QCOMPARE( fieldsItem->text( 0 ), QStringLiteral( "Fields" ) );
|
||||
// QCOMPARE( fieldsItem->childCount(), 2 );
|
||||
|
||||
// Insure that the configuration was stored when switching from one available widgets tree item to another
|
||||
attributeFormProperties.mAvailableWidgetsTree->setCurrentItem( fieldsItem->child( 0 ) );
|
||||
QVERIFY( attributeFormProperties.mAttributeTypeDialog );
|
||||
attributeFormProperties.mAttributeTypeDialog->setAlias( QStringLiteral( "alias0" ) );
|
||||
attributeFormProperties.mAvailableWidgetsTree->setCurrentItem( fieldsItem->child( 1 ) );
|
||||
QVERIFY( attributeFormProperties.mAttributeTypeDialog );
|
||||
attributeFormProperties.mAttributeTypeDialog->setAlias( QStringLiteral( "alias1" ) );
|
||||
// // Insure that the configuration was stored when switching from one available widgets tree item to another
|
||||
// attributeFormProperties.mAvailableWidgetsTree->setCurrentItem( fieldsItem->child( 0 ) );
|
||||
// QVERIFY( attributeFormProperties.mAttributeTypeDialog );
|
||||
// attributeFormProperties.mAttributeTypeDialog->setAlias( QStringLiteral( "alias0" ) );
|
||||
// attributeFormProperties.mAvailableWidgetsTree->setCurrentItem( fieldsItem->child( 1 ) );
|
||||
// QVERIFY( attributeFormProperties.mAttributeTypeDialog );
|
||||
// attributeFormProperties.mAttributeTypeDialog->setAlias( QStringLiteral( "alias1" ) );
|
||||
|
||||
attributeFormProperties.mAvailableWidgetsTree->setCurrentItem( fieldsItem->child( 0 ) );
|
||||
QVERIFY( attributeFormProperties.mAttributeTypeDialog );
|
||||
QCOMPARE( attributeFormProperties.mAttributeTypeDialog->alias(), QStringLiteral( "alias0" ) );
|
||||
attributeFormProperties.mAvailableWidgetsTree->setCurrentItem( fieldsItem->child( 1 ) );
|
||||
QVERIFY( attributeFormProperties.mAttributeTypeDialog );
|
||||
QCOMPARE( attributeFormProperties.mAttributeTypeDialog->alias(), QStringLiteral( "alias1" ) );
|
||||
// attributeFormProperties.mAvailableWidgetsTree->setCurrentItem( fieldsItem->child( 0 ) );
|
||||
// QVERIFY( attributeFormProperties.mAttributeTypeDialog );
|
||||
// QCOMPARE( attributeFormProperties.mAttributeTypeDialog->alias(), QStringLiteral( "alias0" ) );
|
||||
// attributeFormProperties.mAvailableWidgetsTree->setCurrentItem( fieldsItem->child( 1 ) );
|
||||
// QVERIFY( attributeFormProperties.mAttributeTypeDialog );
|
||||
// QCOMPARE( attributeFormProperties.mAttributeTypeDialog->alias(), QStringLiteral( "alias1" ) );
|
||||
}
|
||||
|
||||
QGSTEST_MAIN( TestQgsAttributesFormProperties )
|
||||
|
Loading…
x
Reference in New Issue
Block a user