Merge pull request #8524 from OPM/tree_filter

Add Project Tree filter support
This commit is contained in:
jonjenssen 2022-02-04 15:49:22 +01:00 committed by GitHub
parent 358c11264a
commit a3ad9d2c1e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 715 additions and 381 deletions

View File

@ -303,7 +303,7 @@ void RiaGuiApplication::storeTreeViewState()
for ( auto& tv : mainWindow()->projectTreeViews() )
{
QString treeViewState;
caf::QTreeViewStateSerializer::storeTreeViewStateToString( tv->treeView(), treeViewState );
tv->storeTreeViewStateToString( treeViewState );
treeStates.append( treeViewState );
QModelIndex mi = tv->treeView()->currentIndex();
@ -324,7 +324,7 @@ void RiaGuiApplication::storeTreeViewState()
for ( auto& tv : mainPlotWindow()->projectTreeViews() )
{
QString treeViewState;
caf::QTreeViewStateSerializer::storeTreeViewStateToString( tv->treeView(), treeViewState );
tv->storeTreeViewStateToString( treeViewState );
treeStates.append( treeViewState );
QModelIndex mi = tv->treeView()->currentIndex();

View File

@ -25,6 +25,7 @@
#include "RimWellPath.h"
#include "RimWellPathCollection.h"
#include "cafPdmUiTreeAttributes.h"
#include "cafPdmUiTreeViewEditor.h"
#include <QFileInfo>

View File

@ -32,6 +32,7 @@
#include "cafPdmObjectGroup.h"
#include "cafPdmUiListView.h"
#include "cafPdmUiPropertyView.h"
#include "cafPdmUiTreeAttributes.h"
#include "cafPdmUiTreeView.h"
#include "cafPdmUiTreeViewEditor.h"
#include "cafUtils.h"

View File

@ -192,7 +192,7 @@ caf::PdmUiTreeOrdering* RicToggleItemsFeatureImpl::findTreeItemFromSelectedUiIte
if ( pdmUiTreeView )
{
QModelIndex modIndex = pdmUiTreeView->findModelIndex( uiItem );
return static_cast<caf::PdmUiTreeOrdering*>( modIndex.internalPointer() );
return pdmUiTreeView->uiTreeOrderingFromModelIndex( modIndex );
}
return nullptr;

View File

@ -29,6 +29,7 @@
#include "RimMdiWindowController.h"
#include "RimProject.h"
#include "cafPdmUiTreeAttributes.h"
#include "cafPdmUiTreeViewEditor.h"
#include <QDebug>

View File

@ -34,6 +34,7 @@
#include "cafPdmFieldReorderCapability.h"
#include "cafPdmUiPushButtonEditor.h"
#include "cafPdmUiTreeAttributes.h"
#include "cafPdmUiTreeViewEditor.h"
#include "qwt_plot.h"

View File

@ -57,6 +57,7 @@
#include "RiuMainWindow.h"
#include "cafPdmFieldScriptingCapability.h"
#include "cafPdmUiTreeAttributes.h"
#include "cafPdmUiTreeOrdering.h"
#include "cafPdmUiTreeViewEditor.h"
#include "cafUtils.h"

View File

@ -1303,6 +1303,8 @@ void RiuMainWindow::selectViewInProjectTreePreservingSubItemSelection( const Rim
if ( is3dViewCurrentlySelected && ( previousActiveReservoirView != activatedView ) )
{
QModelIndex newViewModelIndex = projectTreeView( 0 )->findModelIndex( activatedView );
if ( !newViewModelIndex.isValid() ) return;
QModelIndex newSelectionIndex = newViewModelIndex;
if ( previousActiveReservoirView && is3dViewCurrentlySelected )

View File

@ -67,10 +67,10 @@ void RiuMainWindowTools::collapseSiblings( const caf::PdmUiItem* sourceUiItem )
caf::PdmUiTreeOrdering* sourceTreeOrderingItem = nullptr;
QModelIndex modIndex = sourceTreeView->findModelIndex( sourceUiItem );
if ( !modIndex.isValid() ) return;
sourceTreeOrderingItem = static_cast<caf::PdmUiTreeOrdering*>( modIndex.internalPointer() );
sourceTreeOrderingItem = sourceTreeView->uiTreeOrderingFromModelIndex( modIndex );
if ( sourceTreeOrderingItem == nullptr ) return;
if ( sourceTreeOrderingItem && sourceTreeOrderingItem->parent() )
{

View File

@ -194,10 +194,10 @@ caf::PdmUiTreeOrdering* ToggleItemsFeatureImpl::findTreeItemFromSelectedUiItem(
if ( pdmUiTreeView )
{
QModelIndex modIndex = pdmUiTreeView->findModelIndex( uiItem );
return static_cast<caf::PdmUiTreeOrdering*>( modIndex.internalPointer() );
return pdmUiTreeView->uiTreeOrderingFromModelIndex( modIndex );
}
return nullptr;
}
} // namespace caf
} // namespace caf

View File

@ -165,6 +165,9 @@ set(PROJECT_FILES
cafStyleSheetTools.cpp
cafPdmUiTabbedPropertyViewDialog.h
cafPdmUiTabbedPropertyViewDialog.cpp
cafPdmUiTreeViewItemDelegate.h
cafPdmUiTreeViewItemDelegate.cpp
cafPdmUiTreeAttributes.h
)
add_library(

View File

@ -0,0 +1,104 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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 3 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include "cafPdmUiFieldEditorHandle.h"
#include "cafSignal.h"
namespace caf
{
class PdmUiTreeViewItemAttribute : public PdmUiEditorAttribute
{
public:
struct Tag : public SignalEmitter
{
enum Position
{
IN_FRONT,
AT_END
};
Tag()
: text()
, position( AT_END )
, bgColor( Qt::red )
, fgColor( Qt::white )
, selectedOnly( false )
, clicked( this )
{
}
QString text;
IconProvider icon;
Position position;
QColor bgColor;
QColor fgColor;
bool selectedOnly;
caf::Signal<size_t> clicked;
static std::unique_ptr<Tag> create() { return std::unique_ptr<Tag>( new Tag ); }
private:
Tag& operator=( const Tag& rhs ) { return *this; }
};
std::vector<std::unique_ptr<Tag>> tags;
};
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
class PdmUiTreeViewEditorAttribute : public PdmUiEditorAttribute
{
public:
PdmUiTreeViewEditorAttribute()
: currentObject( nullptr )
, objectForUpdateOfUiTree( nullptr )
{
}
public:
QStringList columnHeaders;
/// This object is set as current item in the tree view in configureAndUpdateUi()
caf::PdmObjectHandle* currentObject;
caf::PdmObjectHandle* objectForUpdateOfUiTree;
};
} // namespace caf

View File

@ -39,10 +39,16 @@
#include "cafPdmObject.h"
#include "cafPdmUiDefaultObjectEditor.h"
#include "cafPdmUiDragDropInterface.h"
#include "cafPdmUiTreeOrdering.h"
#include "cafPdmUiTreeViewEditor.h"
#include "cafQTreeViewStateSerializer.h"
#include <QHBoxLayout>
#include <QLineEdit>
#include <QPushButton>
#include <QSortFilterProxyModel>
#include <QTreeView>
#include <QVBoxLayout>
namespace caf
{
@ -52,16 +58,30 @@ namespace caf
PdmUiTreeView::PdmUiTreeView( QWidget* parent, Qt::WindowFlags f )
: QWidget( parent, f )
{
m_layout = new QVBoxLayout( this );
m_layout = new QVBoxLayout();
m_layout->setContentsMargins( 0, 0, 0, 0 );
setLayout( m_layout );
m_treeViewEditor = new PdmUiTreeViewEditor();
QHBoxLayout* searchLayout = new QHBoxLayout();
QWidget* widget = m_treeViewEditor->getOrCreateWidget( this );
m_searchBox = new QLineEdit( this );
m_searchBox->setPlaceholderText( "Type here to search in tree." );
searchLayout->addWidget( m_searchBox );
m_clearSearchButton = new QPushButton( "X" );
m_clearSearchButton->setMaximumSize( 30, 30 );
searchLayout->addWidget( m_clearSearchButton );
this->m_layout->insertWidget( 0, widget );
#if QT_VERSION >= QT_VERSION_CHECK( 5, 10, 0 )
m_layout->addLayout( searchLayout );
connect( m_searchBox, SIGNAL( textChanged( QString ) ), SLOT( slotOnSearchTextChanged() ) );
connect( m_clearSearchButton, SIGNAL( clicked() ), SLOT( slotOnClearSearchBox() ) );
#endif
m_treeViewEditor = new PdmUiTreeViewEditor();
QWidget* treewidget = m_treeViewEditor->getOrCreateWidget( this );
m_layout->addWidget( treewidget );
connect( m_treeViewEditor, SIGNAL( selectionChanged() ), SLOT( slotOnSelectionChanged() ) );
}
@ -144,6 +164,53 @@ void PdmUiTreeView::slotOnSelectionChanged()
emit selectedObjectChanged( objHandle );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmUiTreeView::slotOnClearSearchBox()
{
m_searchBox->setText( "" );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmUiTreeView::slotOnSearchTextChanged()
{
QString searchText = m_searchBox->text().trimmed();
if ( searchText.isEmpty() )
{
m_treeViewEditor->setFilterString( searchText );
if ( !m_treeStateString.isEmpty() )
{
m_treeViewEditor->treeView()->collapseAll();
QTreeViewStateSerializer::applyTreeViewStateFromString( m_treeViewEditor->treeView(), m_treeStateString );
m_treeStateString = "";
}
return;
}
else if ( m_treeStateString.isEmpty() )
{
QTreeViewStateSerializer::storeTreeViewStateToString( m_treeViewEditor->treeView(), m_treeStateString );
}
m_treeViewEditor->setFilterString( searchText );
m_treeViewEditor->treeView()->expandAll();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmUiTreeView::storeTreeViewStateToString( QString& treeViewState ) const
{
QString searchText = m_searchBox->text().trimmed();
if ( !searchText.isEmpty() )
{
treeViewState = m_treeStateString;
return;
}
QTreeViewStateSerializer::storeTreeViewStateToString( m_treeViewEditor->treeView(), treeViewState );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -193,6 +260,14 @@ PdmUiItem* PdmUiTreeView::uiItemFromModelIndex( const QModelIndex& index ) const
return m_treeViewEditor->uiItemFromModelIndex( index );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
PdmUiTreeOrdering* PdmUiTreeView::uiTreeOrderingFromModelIndex( const QModelIndex& index ) const
{
return m_treeViewEditor->uiTreeOrderingFromModelIndex( index );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -45,12 +45,16 @@ class QTreeView;
class QItemSelection;
class QMenu;
class QModelIndex;
class QLineEdit;
class QPushButton;
class QSortFilterProxyModel;
namespace caf
{
class PdmUiItem;
class PdmUiTreeViewEditor;
class PdmObjectHandle;
class PdmUiTreeOrdering;
//==================================================================================================
///
@ -84,7 +88,12 @@ public:
PdmUiItem* uiItemFromModelIndex( const QModelIndex& index ) const;
QModelIndex findModelIndex( const PdmUiItem* object ) const;
void updateSubTree( const QModelIndex& index );
void setDragDropInterface( PdmUiDragDropInterface* dragDropInterface );
PdmUiTreeOrdering* uiTreeOrderingFromModelIndex( const QModelIndex& index ) const;
void setDragDropInterface( PdmUiDragDropInterface* dragDropInterface );
void storeTreeViewStateToString( QString& treeViewState ) const;
signals:
void selectionChanged();
@ -96,11 +105,16 @@ public slots:
private slots:
void slotOnSelectionChanged();
void slotOnClearSearchBox();
void slotOnSearchTextChanged();
private:
PdmUiTreeViewEditor* m_treeViewEditor;
QString m_uiConfigName;
QVBoxLayout* m_layout;
QLineEdit* m_searchBox;
QPushButton* m_clearSearchButton;
QString m_treeStateString;
};
} // End of namespace caf

View File

@ -45,6 +45,7 @@
#include "cafPdmUiDragDropInterface.h"
#include "cafPdmUiEditorHandle.h"
#include "cafPdmUiTreeOrdering.h"
#include "cafPdmUiTreeViewItemDelegate.h"
#include "cafPdmUiTreeViewQModel.h"
#include "cafSelectionManager.h"
@ -149,6 +150,7 @@ PdmUiTreeViewEditor::PdmUiTreeViewEditor()
m_treeView = nullptr;
m_treeViewModel = nullptr;
m_delegate = nullptr;
m_filterModel = nullptr;
}
//--------------------------------------------------------------------------------------------------
@ -156,6 +158,7 @@ PdmUiTreeViewEditor::PdmUiTreeViewEditor()
//--------------------------------------------------------------------------------------------------
PdmUiTreeViewEditor::~PdmUiTreeViewEditor()
{
m_treeView->removeEventFilter( this );
m_treeViewModel->setPdmItemRoot( nullptr );
}
@ -170,11 +173,20 @@ QWidget* PdmUiTreeViewEditor::createWidget( QWidget* parent )
m_mainWidget->setLayout( m_layout );
m_treeViewModel = new caf::PdmUiTreeViewQModel( this );
m_treeView = new PdmUiTreeViewWidget( m_mainWidget );
m_treeView->setModel( m_treeViewModel );
m_filterModel = new QSortFilterProxyModel( this );
m_filterModel->setFilterKeyColumn( 0 );
m_filterModel->setFilterCaseSensitivity( Qt::CaseInsensitive );
#if QT_VERSION >= QT_VERSION_CHECK( 5, 10, 0 )
m_filterModel->setRecursiveFilteringEnabled( true );
#endif
m_filterModel->setSourceModel( m_treeViewModel );
m_treeView = new PdmUiTreeViewWidget( m_mainWidget );
m_treeView->setModel( m_filterModel );
m_treeView->installEventFilter( this );
m_delegate = new PdmUiTreeViewItemDelegate( this, m_treeViewModel );
m_delegate = new PdmUiTreeViewItemDelegate( this, m_filterModel );
m_treeView->setItemDelegate( m_delegate );
@ -256,10 +268,16 @@ void PdmUiTreeViewEditor::selectedUiItems( std::vector<PdmUiItem*>& objects )
if ( !this->treeView() ) return;
QModelIndexList idxList = this->treeView()->selectionModel()->selectedIndexes();
QModelIndexList proxyList;
for ( int i = 0; i < idxList.size(); i++ )
{
caf::PdmUiItem* item = this->m_treeViewModel->uiItemFromModelIndex( idxList[i] );
proxyList.append( m_filterModel->mapToSource( idxList[i] ) );
}
for ( int i = 0; i < proxyList.size(); i++ )
{
caf::PdmUiItem* item = this->m_treeViewModel->uiItemFromModelIndex( proxyList[i] );
if ( item )
{
objects.push_back( item );
@ -289,8 +307,8 @@ void PdmUiTreeViewEditor::updateMySubTree( PdmUiItem* uiItem )
}
m_treeViewModel->updateSubTree( itemToUpdate );
QModelIndex index = m_treeViewModel->findModelIndex( itemToUpdate );
updateItemDelegateForSubTree( index );
QModelIndex itemIndex = m_treeViewModel->findModelIndex( itemToUpdate );
updateItemDelegateForSubTree( itemIndex );
}
}
@ -393,11 +411,11 @@ PdmChildArrayFieldHandle* PdmUiTreeViewEditor::currentChildArrayFieldHandle()
void PdmUiTreeViewEditor::selectAsCurrentItem( const PdmUiItem* uiItem )
{
QModelIndex index = m_treeViewModel->findModelIndex( uiItem );
QModelIndex currentIndex = m_treeView->currentIndex();
QModelIndex currentIndex = m_filterModel->mapFromSource( index );
m_treeView->clearSelection();
m_treeView->setCurrentIndex( index );
m_treeView->setCurrentIndex( currentIndex );
}
//--------------------------------------------------------------------------------------------------
@ -438,21 +456,53 @@ void PdmUiTreeViewEditor::slotOnSelectionChanged( const QItemSelection& selected
//--------------------------------------------------------------------------------------------------
void PdmUiTreeViewEditor::setExpanded( const PdmUiItem* uiItem, bool doExpand ) const
{
QModelIndex index = m_treeViewModel->findModelIndex( uiItem );
m_treeView->setExpanded( index, doExpand );
QModelIndex index = m_treeViewModel->findModelIndex( uiItem );
QModelIndex filterIndex = m_filterModel->mapFromSource( index );
if ( doExpand )
if ( filterIndex.isValid() )
{
m_treeView->scrollTo( index );
m_treeView->setExpanded( filterIndex, doExpand );
if ( doExpand )
{
m_treeView->scrollTo( filterIndex );
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QModelIndex PdmUiTreeViewEditor::mapIndexIfNecessary( QModelIndex index ) const
{
const QAbstractProxyModel* proxyModel = dynamic_cast<const QAbstractProxyModel*>( index.model() );
QModelIndex returnIndex = index;
if ( proxyModel )
{
returnIndex = proxyModel->mapToSource( index );
}
return returnIndex;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
PdmUiItem* PdmUiTreeViewEditor::uiItemFromModelIndex( const QModelIndex& index ) const
{
return m_treeViewModel->uiItemFromModelIndex( index );
QModelIndex realIndex = mapIndexIfNecessary( index );
return m_treeViewModel->uiItemFromModelIndex( realIndex );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
PdmUiTreeOrdering* PdmUiTreeViewEditor::uiTreeOrderingFromModelIndex( const QModelIndex& index ) const
{
QModelIndex realIndex = mapIndexIfNecessary( index );
if ( realIndex.isValid() ) return static_cast<caf::PdmUiTreeOrdering*>( realIndex.internalPointer() );
return nullptr;
}
//--------------------------------------------------------------------------------------------------
@ -460,7 +510,8 @@ PdmUiItem* PdmUiTreeViewEditor::uiItemFromModelIndex( const QModelIndex& index )
//--------------------------------------------------------------------------------------------------
QModelIndex PdmUiTreeViewEditor::findModelIndex( const PdmUiItem* object ) const
{
return m_treeViewModel->findModelIndex( object );
QModelIndex index = m_treeViewModel->findModelIndex( object );
return m_filterModel->mapFromSource( index );
}
//--------------------------------------------------------------------------------------------------
@ -471,6 +522,14 @@ void PdmUiTreeViewEditor::setDragDropInterface( PdmUiDragDropInterface* dragDrop
m_treeViewModel->setDragDropInterface( dragDropInterface );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmUiTreeViewEditor::setFilterString( QString filterString )
{
m_filterModel->setFilterWildcard( filterString );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -502,12 +561,15 @@ void PdmUiTreeViewEditor::updateSelectionManager()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmUiTreeViewEditor::updateItemDelegateForSubTree( const QModelIndex& modelIndex /*= QModelIndex()*/ )
void PdmUiTreeViewEditor::updateItemDelegateForSubTree( const QModelIndex& subRootIndex /* = QModelIndex() */ )
{
auto allIndices = m_treeViewModel->allIndicesRecursive();
auto allIndices = m_treeViewModel->allIndicesRecursive( subRootIndex );
for ( QModelIndex& index : allIndices )
{
m_delegate->clearTags( index );
QModelIndex filterIndex = m_filterModel->mapFromSource( index );
if ( !filterIndex.isValid() ) continue;
m_delegate->clearTags( filterIndex );
PdmUiItem* uiItem = m_treeViewModel->uiItemFromModelIndex( index );
PdmUiObjectHandle* uiObjectHandle = dynamic_cast<PdmUiObjectHandle*>( uiItem );
@ -523,9 +585,9 @@ void PdmUiTreeViewEditor::updateItemDelegateForSubTree( const QModelIndex& model
std::vector<PdmUiItem*> selection;
selectedUiItems( selection );
if ( reorderability && index.row() >= 0 && selection.size() == 1u && selection.front() == uiItem )
if ( reorderability && filterIndex.row() >= 0 && selection.size() == 1u && selection.front() == uiItem )
{
size_t indexInParent = static_cast<size_t>( index.row() );
size_t indexInParent = static_cast<size_t>( filterIndex.row() );
{
auto tag = PdmUiTreeViewItemAttribute::Tag::create();
tag->icon = caf::IconProvider( ":/caf/Up16x16.png" );
@ -539,7 +601,7 @@ void PdmUiTreeViewEditor::updateItemDelegateForSubTree( const QModelIndex& model
tag->icon.setActive( false );
}
m_delegate->addTag( index, std::move( tag ) );
m_delegate->addTag( filterIndex, std::move( tag ) );
}
{
auto tag = PdmUiTreeViewItemAttribute::Tag::create();
@ -553,7 +615,7 @@ void PdmUiTreeViewEditor::updateItemDelegateForSubTree( const QModelIndex& model
{
tag->icon.setActive( false );
}
m_delegate->addTag( index, std::move( tag ) );
m_delegate->addTag( filterIndex, std::move( tag ) );
}
}
}
@ -564,7 +626,7 @@ void PdmUiTreeViewEditor::updateItemDelegateForSubTree( const QModelIndex& model
{
if ( !tag->text.isEmpty() || tag->icon.valid() )
{
m_delegate->addTag( index, std::move( tag ) );
m_delegate->addTag( filterIndex, std::move( tag ) );
}
}
}
@ -587,260 +649,4 @@ bool PdmUiTreeViewEditor::isAppendOfClassNameToUiItemTextEnabled()
return m_appendClassNameToUiItemText;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
PdmUiTreeViewItemDelegate::PdmUiTreeViewItemDelegate( PdmUiTreeViewEditor* parent, PdmUiTreeViewQModel* model )
: QStyledItemDelegate( parent->treeView() )
, m_treeView( parent )
, m_model( model )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmUiTreeViewItemDelegate::clearTags( QModelIndex index )
{
m_tags.erase( index );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmUiTreeViewItemDelegate::clearAllTags()
{
m_tags.clear();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmUiTreeViewItemDelegate::addTag( QModelIndex index, std::unique_ptr<PdmUiTreeViewItemAttribute::Tag> tag )
{
std::vector<std::unique_ptr<PdmUiTreeViewItemAttribute::Tag>>& tagList = m_tags[index];
tagList.push_back( std::move( tag ) );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QRect PdmUiTreeViewItemDelegate::tagRect( const QRect& itemRect, QModelIndex index, size_t tagIndex ) const
{
auto it = m_tags.find( index );
if ( it == m_tags.end() ) return QRect();
QSize fullSize = itemRect.size();
QPoint offset( 0, 0 );
for ( size_t i = 0; i < it->second.size(); ++i )
{
const PdmUiTreeViewItemAttribute::Tag* tag = it->second[i].get();
if ( tag->icon.valid() )
{
auto icon = tag->icon.icon();
QSize iconSize = icon->actualSize( fullSize );
QRect iconRect;
if ( tag->position == PdmUiTreeViewItemAttribute::Tag::AT_END )
{
QPoint bottomRight = itemRect.bottomRight() - offset;
QPoint topLeft = bottomRight - QPoint( iconSize.width(), iconSize.height() );
iconRect = QRect( topLeft, bottomRight );
}
else
{
QPoint topLeft = itemRect.topLeft() + offset;
QPoint bottomRight = topLeft + QPoint( iconSize.width(), iconSize.height() );
iconRect = QRect( topLeft, bottomRight );
}
offset += QPoint( iconSize.width() + 2, 0 );
if ( i == tagIndex ) return iconRect;
}
}
return QRect();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmUiTreeViewItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const
{
QStyledItemDelegate::paint( painter, option, index );
auto it = m_tags.find( index );
if ( it == m_tags.end() ) return;
// Save painter so we can restore it
painter->save();
QRect rect = option.rect;
QPoint center = rect.center();
QSize fullSize = rect.size();
QPoint offset( 0, 0 );
for ( const std::unique_ptr<PdmUiTreeViewItemAttribute::Tag>& tag : it->second )
{
if ( tag->selectedOnly && !( option.state & QStyle::State_Selected ) ) continue;
if ( tag->icon.valid() )
{
auto icon = tag->icon.icon();
QSize iconSize = icon->actualSize( fullSize );
QRect iconRect;
if ( tag->position == PdmUiTreeViewItemAttribute::Tag::AT_END )
{
QPoint bottomRight( rect.bottomRight().x() - offset.x(), center.y() + iconSize.height() / 2 );
QPoint topLeft( bottomRight.x() - iconSize.width(), bottomRight.y() - iconSize.height() );
iconRect = QRect( topLeft, bottomRight );
}
else
{
QPoint topLeft( rect.topLeft().x() + offset.x(), center.y() - iconSize.height() / 2 );
QPoint bottomRight( topLeft.x() + iconSize.width(), topLeft.y() + iconSize.height() );
iconRect = QRect( topLeft, bottomRight );
}
offset += QPoint( iconSize.width() + 2, 0 );
icon->paint( painter, iconRect );
}
else
{
const int insideTopBottomMargins = 1;
const int insideleftRightMargins = 6;
const int outsideLeftRightMargins = 4;
QFont font = QApplication::font();
if ( font.pixelSize() > 0 )
{
font.setPixelSize( std::max( 1, font.pixelSize() - 1 ) );
}
else
{
font.setPointSize( std::max( 1, font.pointSize() - 1 ) );
}
painter->setFont( font );
QString text = tag->text;
QColor bgColor = tag->bgColor;
QColor fgColor = tag->fgColor;
QSize textSize( QFontMetrics( font ).size( Qt::TextSingleLine, text ) );
int textDiff = ( fullSize.height() - textSize.height() );
QRect textRect;
if ( tag->position == PdmUiTreeViewItemAttribute::Tag::AT_END )
{
QPoint bottomRight = rect.bottomRight() - QPoint( outsideLeftRightMargins, 0 ) - offset;
QPoint textBottomRight = bottomRight - QPoint( insideleftRightMargins, textDiff / 2 );
QPoint textTopLeft = textBottomRight - QPoint( textSize.width(), textSize.height() );
textRect = QRect( textTopLeft, textBottomRight );
}
else
{
QPoint textTopLeft = QPoint( 0, rect.topLeft().y() ) + offset +
QPoint( outsideLeftRightMargins + insideleftRightMargins, +textDiff / 2 );
QPoint textBottomRight = textTopLeft + QPoint( textSize.width(), textSize.height() );
textRect = QRect( textTopLeft, textBottomRight );
}
QRect tagRect = textRect.marginsAdded(
QMargins( insideleftRightMargins, insideTopBottomMargins, insideleftRightMargins, insideTopBottomMargins ) );
offset += QPoint( tagRect.width() + 2, 0 );
QBrush brush( bgColor );
painter->setBrush( brush );
painter->setPen( bgColor );
painter->setRenderHint( QPainter::Antialiasing );
const double xRoundingRadiusPercent = 50.0;
const double yRoundingRadiusPercent = 25.0;
painter->drawRoundedRect( tagRect, xRoundingRadiusPercent, yRoundingRadiusPercent, Qt::RelativeSize );
painter->setPen( fgColor );
painter->drawText( textRect, Qt::AlignCenter, text );
}
}
// Restore painter
painter->restore();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<const caf::PdmUiTreeViewItemAttribute::Tag*> PdmUiTreeViewItemDelegate::tags( QModelIndex index ) const
{
std::vector<const caf::PdmUiTreeViewItemAttribute::Tag*> tagPtrVector;
auto it = m_tags.find( index );
if ( it != m_tags.end() )
{
for ( const auto& tag : it->second )
{
tagPtrVector.push_back( tag.get() );
}
}
return tagPtrVector;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool PdmUiTreeViewItemDelegate::editorEvent( QEvent* event,
QAbstractItemModel* model,
const QStyleOptionViewItem& option,
const QModelIndex& itemIndex )
{
if ( event->type() == QEvent::MouseButtonPress )
{
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>( event );
if ( mouseEvent->button() == Qt::LeftButton && mouseEvent->modifiers() == Qt::NoModifier )
{
const PdmUiTreeViewItemAttribute::Tag* tag;
if ( tagClicked( mouseEvent->pos(), option.rect, itemIndex, &tag ) )
{
QModelIndex parentIndex = itemIndex.parent();
auto uiItem = m_treeView->uiItemFromModelIndex( itemIndex );
auto parentUiItem = m_treeView->uiItemFromModelIndex( parentIndex );
tag->clicked.send( (size_t)itemIndex.row() );
m_treeView->updateSubTree( parentUiItem );
m_treeView->selectAsCurrentItem( uiItem );
}
}
}
return QStyledItemDelegate::editorEvent( event, model, option, itemIndex );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool PdmUiTreeViewItemDelegate::tagClicked( const QPoint& pos,
const QRect& itemRect,
const QModelIndex& itemIndex,
const PdmUiTreeViewItemAttribute::Tag** tag ) const
{
if ( itemIndex.isValid() )
{
auto itemTags = tags( itemIndex );
for ( size_t i = 0; i < itemTags.size(); ++i )
{
QRect rect = tagRect( itemRect, itemIndex, i );
if ( rect.contains( pos ) )
{
*tag = itemTags[i];
return true;
}
}
}
return false;
}
} // end namespace caf

View File

@ -47,14 +47,13 @@
#include <QItemSelectionModel>
#include <QPointer>
#include <QProxyStyle>
#include <QSortFilterProxyModel>
#include <QStyledItemDelegate>
#include <QTreeView>
#include <QWidget>
#include <memory>
class MySortFilterProxyModel;
class QGridLayout;
class QMenu;
class QTreeView;
@ -68,6 +67,7 @@ class PdmUiItem;
class PdmUiTreeViewEditor;
class PdmUiTreeViewQModel;
class PdmUiTreeViewWidget;
class PdmUiTreeViewItemDelegate;
class PdmUiTreeViewStyle : public QProxyStyle
{
@ -98,91 +98,6 @@ protected:
void dragLeaveEvent( QDragLeaveEvent* event ) override;
};
class PdmUiTreeViewItemAttribute : public PdmUiEditorAttribute
{
public:
struct Tag : public SignalEmitter
{
enum Position
{
IN_FRONT,
AT_END
};
Tag()
: text()
, position( AT_END )
, bgColor( Qt::red )
, fgColor( Qt::white )
, selectedOnly( false )
, clicked( this )
{
}
QString text;
IconProvider icon;
Position position;
QColor bgColor;
QColor fgColor;
bool selectedOnly;
caf::Signal<size_t> clicked;
static std::unique_ptr<Tag> create() { return std::unique_ptr<Tag>( new Tag ); }
private:
Tag& operator=( const Tag& rhs ) { return *this; }
};
std::vector<std::unique_ptr<Tag>> tags;
};
class PdmUiTreeViewItemDelegate : public QStyledItemDelegate
{
public:
PdmUiTreeViewItemDelegate( PdmUiTreeViewEditor* parent, PdmUiTreeViewQModel* model );
void clearTags( QModelIndex index );
void clearAllTags();
void addTag( QModelIndex index, std::unique_ptr<PdmUiTreeViewItemAttribute::Tag> tag );
void paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const override;
std::vector<const PdmUiTreeViewItemAttribute::Tag*> tags( QModelIndex index ) const;
protected:
bool editorEvent( QEvent* event,
QAbstractItemModel* model,
const QStyleOptionViewItem& option,
const QModelIndex& itemIndex ) override;
bool tagClicked( const QPoint& clickPos,
const QRect& itemRect,
const QModelIndex& itemIndex,
const PdmUiTreeViewItemAttribute::Tag** tag ) const;
QRect tagRect( const QRect& itemRect, QModelIndex itemIndex, size_t tagIndex ) const;
private:
PdmUiTreeViewEditor* m_treeView;
PdmUiTreeViewQModel* m_model;
std::map<QModelIndex, std::vector<std::unique_ptr<PdmUiTreeViewItemAttribute::Tag>>> m_tags;
};
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
class PdmUiTreeViewEditorAttribute : public PdmUiEditorAttribute
{
public:
PdmUiTreeViewEditorAttribute()
: currentObject( nullptr )
, objectForUpdateOfUiTree( nullptr )
{
}
public:
QStringList columnHeaders;
/// This object is set as current item in the tree view in configureAndUpdateUi()
caf::PdmObjectHandle* currentObject;
caf::PdmObjectHandle* objectForUpdateOfUiTree;
};
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -208,13 +123,16 @@ public:
void selectedUiItems( std::vector<PdmUiItem*>& objects );
void setExpanded( const PdmUiItem* uiItem, bool doExpand ) const;
PdmUiItem* uiItemFromModelIndex( const QModelIndex& index ) const;
QModelIndex findModelIndex( const PdmUiItem* object ) const;
PdmUiItem* uiItemFromModelIndex( const QModelIndex& index ) const;
PdmUiTreeOrdering* uiTreeOrderingFromModelIndex( const QModelIndex& index ) const;
QModelIndex findModelIndex( const PdmUiItem* object ) const;
QWidget* createWidget( QWidget* parent ) override;
void setDragDropInterface( PdmUiDragDropInterface* dragDropInterface );
void setFilterString( QString filterStr );
signals:
void selectionChanged();
@ -231,8 +149,10 @@ private slots:
private:
PdmChildArrayFieldHandle* currentChildArrayFieldHandle();
QModelIndex mapIndexIfNecessary( QModelIndex index ) const;
void updateSelectionManager();
void updateItemDelegateForSubTree( const QModelIndex& modelIndex = QModelIndex() );
void updateItemDelegateForSubTree( const QModelIndex& subRootIndex = QModelIndex() );
bool eventFilter( QObject* obj, QEvent* event ) override;
@ -243,6 +163,7 @@ private:
PdmUiTreeViewWidget* m_treeView;
PdmUiTreeViewQModel* m_treeViewModel;
PdmUiTreeViewItemDelegate* m_delegate;
QSortFilterProxyModel* m_filterModel;
bool m_useDefaultContextMenu;
bool m_updateSelectionManager;

View File

@ -0,0 +1,320 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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 3 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cafPdmUiTreeViewItemDelegate.h"
#include "cafPdmChildArrayField.h"
#include "cafPdmField.h"
#include "cafPdmFieldReorderCapability.h"
#include "cafPdmObject.h"
#include "cafPdmPtrArrayFieldHandle.h"
#include "cafPdmUiCommandSystemProxy.h"
#include "cafPdmUiDragDropInterface.h"
#include "cafPdmUiEditorHandle.h"
#include "cafPdmUiTreeOrdering.h"
#include "cafPdmUiTreeViewEditor.h"
#include "cafPdmUiTreeViewQModel.h"
#include "cafSelectionManager.h"
#include <QEvent>
#include <QIcon>
#include <QModelIndexList>
#include <QMouseEvent>
#include <QPainter>
#include <QStyleOptionViewItem>
#include <QTreeView>
namespace caf
{
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
PdmUiTreeViewItemDelegate::PdmUiTreeViewItemDelegate( PdmUiTreeViewEditor* parent, QAbstractItemModel* model )
: QStyledItemDelegate( parent->treeView() )
, m_treeView( parent )
, m_model( model )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmUiTreeViewItemDelegate::clearTags( QModelIndex index )
{
m_tags.erase( index );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmUiTreeViewItemDelegate::clearAllTags()
{
m_tags.clear();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmUiTreeViewItemDelegate::addTag( QModelIndex index, std::unique_ptr<PdmUiTreeViewItemAttribute::Tag> tag )
{
std::vector<std::unique_ptr<PdmUiTreeViewItemAttribute::Tag>>& tagList = m_tags[index];
tagList.push_back( std::move( tag ) );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QRect PdmUiTreeViewItemDelegate::tagRect( const QRect& itemRect, QModelIndex index, size_t tagIndex ) const
{
auto it = m_tags.find( index );
if ( it == m_tags.end() ) return QRect();
QSize fullSize = itemRect.size();
QPoint offset( 0, 0 );
for ( size_t i = 0; i < it->second.size(); ++i )
{
const PdmUiTreeViewItemAttribute::Tag* tag = it->second[i].get();
if ( tag->icon.valid() )
{
auto icon = tag->icon.icon();
QSize iconSize = icon->actualSize( fullSize );
QRect iconRect;
if ( tag->position == PdmUiTreeViewItemAttribute::Tag::AT_END )
{
QPoint bottomRight = itemRect.bottomRight() - offset;
QPoint topLeft = bottomRight - QPoint( iconSize.width(), iconSize.height() );
iconRect = QRect( topLeft, bottomRight );
}
else
{
QPoint topLeft = itemRect.topLeft() + offset;
QPoint bottomRight = topLeft + QPoint( iconSize.width(), iconSize.height() );
iconRect = QRect( topLeft, bottomRight );
}
offset += QPoint( iconSize.width() + 2, 0 );
if ( i == tagIndex ) return iconRect;
}
}
return QRect();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmUiTreeViewItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const
{
QStyledItemDelegate::paint( painter, option, index );
auto it = m_tags.find( index );
if ( it == m_tags.end() ) return;
// Save painter so we can restore it
painter->save();
QRect rect = option.rect;
QPoint center = rect.center();
QSize fullSize = rect.size();
QPoint offset( 0, 0 );
for ( const std::unique_ptr<PdmUiTreeViewItemAttribute::Tag>& tag : it->second )
{
if ( tag->selectedOnly && !( option.state & QStyle::State_Selected ) ) continue;
if ( tag->icon.valid() )
{
auto icon = tag->icon.icon();
QSize iconSize = icon->actualSize( fullSize );
QRect iconRect;
if ( tag->position == PdmUiTreeViewItemAttribute::Tag::AT_END )
{
QPoint bottomRight( rect.bottomRight().x() - offset.x(), center.y() + iconSize.height() / 2 );
QPoint topLeft( bottomRight.x() - iconSize.width(), bottomRight.y() - iconSize.height() );
iconRect = QRect( topLeft, bottomRight );
}
else
{
QPoint topLeft( rect.topLeft().x() + offset.x(), center.y() - iconSize.height() / 2 );
QPoint bottomRight( topLeft.x() + iconSize.width(), topLeft.y() + iconSize.height() );
iconRect = QRect( topLeft, bottomRight );
}
offset += QPoint( iconSize.width() + 2, 0 );
icon->paint( painter, iconRect );
}
else
{
const int insideTopBottomMargins = 1;
const int insideleftRightMargins = 6;
const int outsideLeftRightMargins = 4;
QFont font = QApplication::font();
if ( font.pixelSize() > 0 )
{
font.setPixelSize( std::max( 1, font.pixelSize() - 1 ) );
}
else
{
font.setPointSize( std::max( 1, font.pointSize() - 1 ) );
}
painter->setFont( font );
QString text = tag->text;
QColor bgColor = tag->bgColor;
QColor fgColor = tag->fgColor;
QSize textSize( QFontMetrics( font ).size( Qt::TextSingleLine, text ) );
int textDiff = ( fullSize.height() - textSize.height() );
QRect textRect;
if ( tag->position == PdmUiTreeViewItemAttribute::Tag::AT_END )
{
QPoint bottomRight = rect.bottomRight() - QPoint( outsideLeftRightMargins, 0 ) - offset;
QPoint textBottomRight = bottomRight - QPoint( insideleftRightMargins, textDiff / 2 );
QPoint textTopLeft = textBottomRight - QPoint( textSize.width(), textSize.height() );
textRect = QRect( textTopLeft, textBottomRight );
}
else
{
QPoint textTopLeft = QPoint( 0, rect.topLeft().y() ) + offset +
QPoint( outsideLeftRightMargins + insideleftRightMargins, +textDiff / 2 );
QPoint textBottomRight = textTopLeft + QPoint( textSize.width(), textSize.height() );
textRect = QRect( textTopLeft, textBottomRight );
}
QRect tagRect = textRect.marginsAdded(
QMargins( insideleftRightMargins, insideTopBottomMargins, insideleftRightMargins, insideTopBottomMargins ) );
offset += QPoint( tagRect.width() + 2, 0 );
QBrush brush( bgColor );
painter->setBrush( brush );
painter->setPen( bgColor );
painter->setRenderHint( QPainter::Antialiasing );
const double xRoundingRadiusPercent = 50.0;
const double yRoundingRadiusPercent = 25.0;
painter->drawRoundedRect( tagRect, xRoundingRadiusPercent, yRoundingRadiusPercent, Qt::RelativeSize );
painter->setPen( fgColor );
painter->drawText( textRect, Qt::AlignCenter, text );
}
}
// Restore painter
painter->restore();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<const caf::PdmUiTreeViewItemAttribute::Tag*> PdmUiTreeViewItemDelegate::tags( QModelIndex index ) const
{
std::vector<const caf::PdmUiTreeViewItemAttribute::Tag*> tagPtrVector;
auto it = m_tags.find( index );
if ( it != m_tags.end() )
{
for ( const auto& tag : it->second )
{
tagPtrVector.push_back( tag.get() );
}
}
return tagPtrVector;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool PdmUiTreeViewItemDelegate::editorEvent( QEvent* event,
QAbstractItemModel* model,
const QStyleOptionViewItem& option,
const QModelIndex& itemIndex )
{
if ( event->type() == QEvent::MouseButtonPress )
{
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>( event );
if ( mouseEvent->button() == Qt::LeftButton && mouseEvent->modifiers() == Qt::NoModifier )
{
const PdmUiTreeViewItemAttribute::Tag* tag;
if ( tagClicked( mouseEvent->pos(), option.rect, itemIndex, &tag ) )
{
QModelIndex parentIndex = itemIndex.parent();
auto uiItem = m_treeView->uiItemFromModelIndex( itemIndex );
auto parentUiItem = m_treeView->uiItemFromModelIndex( parentIndex );
tag->clicked.send( (size_t)itemIndex.row() );
m_treeView->updateSubTree( parentUiItem );
m_treeView->selectAsCurrentItem( uiItem );
return true;
}
}
}
return QStyledItemDelegate::editorEvent( event, model, option, itemIndex );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool PdmUiTreeViewItemDelegate::tagClicked( const QPoint& pos,
const QRect& itemRect,
const QModelIndex& itemIndex,
const PdmUiTreeViewItemAttribute::Tag** tag ) const
{
if ( itemIndex.isValid() )
{
auto itemTags = tags( itemIndex );
for ( size_t i = 0; i < itemTags.size(); ++i )
{
QRect rect = tagRect( itemRect, itemIndex, i );
if ( rect.contains( pos ) )
{
*tag = itemTags[i];
return true;
}
}
}
return false;
}
} // namespace caf

View File

@ -0,0 +1,84 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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 3 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include "cafPdmUiFieldEditorHandle.h"
#include "cafPdmUiTreeAttributes.h"
#include "cafPdmUiTreeEditorHandle.h"
#include <QAbstractItemModel>
#include <QEvent>
#include <QModelIndex>
#include <QPoint>
#include <QRect>
#include <QStyledItemDelegate>
#include <memory>
namespace caf
{
class PdmUiTreeViewEditor;
class PdmUiTreeViewItemDelegate : public QStyledItemDelegate
{
public:
PdmUiTreeViewItemDelegate( PdmUiTreeViewEditor* parent, QAbstractItemModel* model );
void clearTags( QModelIndex index );
void clearAllTags();
void addTag( QModelIndex index, std::unique_ptr<PdmUiTreeViewItemAttribute::Tag> tag );
void paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const override;
std::vector<const PdmUiTreeViewItemAttribute::Tag*> tags( QModelIndex index ) const;
protected:
bool editorEvent( QEvent* event,
QAbstractItemModel* model,
const QStyleOptionViewItem& option,
const QModelIndex& itemIndex ) override;
bool tagClicked( const QPoint& clickPos,
const QRect& itemRect,
const QModelIndex& itemIndex,
const PdmUiTreeViewItemAttribute::Tag** tag ) const;
QRect tagRect( const QRect& itemRect, QModelIndex itemIndex, size_t tagIndex ) const;
private:
PdmUiTreeViewEditor* m_treeView;
QAbstractItemModel* m_model;
std::map<QModelIndex, std::vector<std::unique_ptr<PdmUiTreeViewItemAttribute::Tag>>> m_tags;
};
} // namespace caf