mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
Merge pull request #8524 from OPM/tree_filter
Add Project Tree filter support
This commit is contained in:
parent
358c11264a
commit
a3ad9d2c1e
@ -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();
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "RimWellPath.h"
|
||||
#include "RimWellPathCollection.h"
|
||||
|
||||
#include "cafPdmUiTreeAttributes.h"
|
||||
#include "cafPdmUiTreeViewEditor.h"
|
||||
|
||||
#include <QFileInfo>
|
||||
|
@ -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"
|
||||
|
@ -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;
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "RimMdiWindowController.h"
|
||||
#include "RimProject.h"
|
||||
|
||||
#include "cafPdmUiTreeAttributes.h"
|
||||
#include "cafPdmUiTreeViewEditor.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
@ -34,6 +34,7 @@
|
||||
|
||||
#include "cafPdmFieldReorderCapability.h"
|
||||
#include "cafPdmUiPushButtonEditor.h"
|
||||
#include "cafPdmUiTreeAttributes.h"
|
||||
#include "cafPdmUiTreeViewEditor.h"
|
||||
|
||||
#include "qwt_plot.h"
|
||||
|
@ -57,6 +57,7 @@
|
||||
#include "RiuMainWindow.h"
|
||||
|
||||
#include "cafPdmFieldScriptingCapability.h"
|
||||
#include "cafPdmUiTreeAttributes.h"
|
||||
#include "cafPdmUiTreeOrdering.h"
|
||||
#include "cafPdmUiTreeViewEditor.h"
|
||||
#include "cafUtils.h"
|
||||
|
@ -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 )
|
||||
|
@ -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() )
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -165,6 +165,9 @@ set(PROJECT_FILES
|
||||
cafStyleSheetTools.cpp
|
||||
cafPdmUiTabbedPropertyViewDialog.h
|
||||
cafPdmUiTabbedPropertyViewDialog.cpp
|
||||
cafPdmUiTreeViewItemDelegate.h
|
||||
cafPdmUiTreeViewItemDelegate.cpp
|
||||
cafPdmUiTreeAttributes.h
|
||||
)
|
||||
|
||||
add_library(
|
||||
|
104
Fwk/AppFwk/cafUserInterface/cafPdmUiTreeAttributes.h
Normal file
104
Fwk/AppFwk/cafUserInterface/cafPdmUiTreeAttributes.h
Normal 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
|
@ -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 );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
320
Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewItemDelegate.cpp
Normal file
320
Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewItemDelegate.cpp
Normal 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
|
84
Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewItemDelegate.h
Normal file
84
Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewItemDelegate.h
Normal 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
|
Loading…
Reference in New Issue
Block a user