//################################################################################################## // // Custom Visualization Core library // Copyright (C) 2014 Ceetron Solutions 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 <> // 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 <> // for more details. // //################################################################################################## #include "cafPdmUiToolBarEditor.h" #include "cafPdmField.h" #include "cafPdmObjectHandle.h" #include "cafPdmUiComboBoxEditor.h" #include "cafPdmUiFieldEditorHandle.h" #include "cafPdmUiFieldEditorHelper.h" #include "cafPdmUiFieldHandle.h" #include "cafPdmUiLineEditor.h" #include "cafPdmUiObjectHandle.h" #include "cafPdmUiOrdering.h" #include "cafPdmUiPushButtonEditor.h" #include "cafPdmUiToolButtonEditor.h" #include #include #include #include namespace caf { //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- PdmUiToolBarEditor::PdmUiToolBarEditor( const QString& title, QMainWindow* mainWindow ) { m_toolbar = new QToolBar( mainWindow ); m_toolbar->setObjectName( title ); m_toolbar->setWindowTitle( title ); mainWindow->addToolBar( m_toolbar ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- PdmUiToolBarEditor::~PdmUiToolBarEditor() { clear(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- bool PdmUiToolBarEditor::isEditorDataEqualAndValid( const std::vector& fields ) const { if ( m_fields.size() != fields.size() || m_fieldViews.size() != fields.size() ) { return false; } for ( size_t i = 0; i < m_fields.size(); i++ ) { auto currentField = m_fields[i]; if ( currentField != fields[i] ) { return false; } if ( currentField && currentField->uiCapability() ) { auto contentText = currentField->uiCapability()->uiValue(); // If there is no selection in a combo box, the content text is "-1" // Rebuild the UI to make sure the available items in the combo box is updated if ( contentText == "-1" ) return false; } } return true; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void PdmUiToolBarEditor::configureAndUpdateUi( const QString& uiConfigName ) { { // Find set of owner objects. Can be several objects, make a set to avoid calling uiOrdering more than once for // an object std::set ownerUiObjects; for ( PdmFieldHandle* field : m_fields ) { caf::PdmUiObjectHandle* ownerUiObject = field->ownerObject()->uiCapability(); if ( ownerUiObject ) { ownerUiObjects.insert( ownerUiObject ); } } for ( caf::PdmUiObjectHandle* ownerUiObject : ownerUiObjects ) { PdmUiOrdering config; ownerUiObject->uiOrdering( uiConfigName, config ); } } for ( PdmFieldHandle* field : m_fields ) { PdmUiFieldEditorHandle* fieldEditor = nullptr; // Find or create FieldEditor std::map::iterator it; it = m_fieldViews.find( field->keyword() ); if ( it == m_fieldViews.end() ) { caf::PdmUiFieldHandle* uiFieldHandle = field->uiCapability(); bool addSpace = false; if ( uiFieldHandle ) { if ( uiFieldHandle->uiValue().metaType().id() == QMetaType::Bool ) { QString editorTypeName = caf::PdmUiToolButtonEditor::uiEditorTypeName(); fieldEditor = caf::Factory::instance()->create( editorTypeName ); } else { fieldEditor = caf::PdmUiFieldEditorHelper::createFieldEditorForField( field->uiCapability(), uiConfigName ); addSpace = true; } } if ( fieldEditor ) { m_fieldViews[field->keyword()] = fieldEditor; fieldEditor->setUiField( uiFieldHandle ); fieldEditor->createWidgets( nullptr ); m_actions.push_back( m_toolbar->addWidget( fieldEditor->editorWidget() ) ); if ( addSpace ) { QWidget* widget = new QWidget; widget->setMinimumWidth( 5 ); m_toolbar->addWidget( widget ); } fieldEditor->updateUi( uiConfigName ); } } else { if ( it->second ) { it->second->updateUi( uiConfigName ); } } } // CAF_ASSERT( m_fields.size() == m_fieldViews.size() ); if ( static_cast( m_fields.size() ) != m_actions.size() ) return; // CAF_ASSERT( static_cast( m_fields.size() ) == m_actions.size() ); if ( static_cast( m_fields.size() ) != m_actions.size() ) return; for ( size_t i = 0; i < m_fields.size(); i++ ) { caf::PdmFieldHandle* field = m_fields[i]; // Enabled state of a tool button is controlled by the QAction associated with a tool button // Changing the state of a widget directly has no effect // See Qt doc for QToolBar::insertWidget QAction* action = m_actions[static_cast( i )]; caf::PdmUiFieldHandle* uiFieldHandle = field->uiCapability(); if ( uiFieldHandle ) { action->setEnabled( !uiFieldHandle->isUiReadOnly( uiConfigName ) ); } // TODO: Show/hide of tool bar items can be done by // action->setVisible(!field->isUiHidden(uiConfigName)); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- QWidget* PdmUiToolBarEditor::focusWidget( PdmUiFieldEditorHandle* uiFieldEditorHandle ) { // Some editors have a placeholder widget as parent of the main editor widget // This is the case for combo box widget to allow up/down arrow buttons associated with the combo box QWidget* editorWidget = nullptr; auto comboEditor = dynamic_cast( uiFieldEditorHandle ); if ( comboEditor ) { auto topWidget = comboEditor->editorWidget(); QComboBox* comboBox = topWidget->findChild(); editorWidget = comboBox; } else { editorWidget = uiFieldEditorHandle->editorWidget(); } return editorWidget; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void PdmUiToolBarEditor::setFields( std::vector& fields ) { clear(); m_fields = fields; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void PdmUiToolBarEditor::clear() { for ( const auto& it : m_fieldViews ) { delete it.second; } m_fieldViews.clear(); if ( m_toolbar ) { m_toolbar->clear(); } m_actions.clear(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void PdmUiToolBarEditor::setFocusWidgetFromKeyword( const QString& fieldKeyword ) { if ( !m_toolbar->isVisible() ) return; auto fieldView = m_fieldViews.find( fieldKeyword ); if ( fieldView != m_fieldViews.end() && fieldView->second ) { QWidget* widget = focusWidget( fieldView->second ); if ( widget ) { widget->setFocus( Qt::ActiveWindowFocusReason ); PdmUiLineEditorAttribute attributes; for ( auto field : m_fields ) { if ( field->keyword() == fieldKeyword ) { caf::PdmUiObjectHandle* uiObject = uiObj( field->ownerObject() ); if ( uiObject ) { uiObject->editorAttribute( field, uiEditorConfigName(), &attributes ); } } } if ( attributes.selectAllOnFocusEvent ) { auto lineEdit = dynamic_cast( widget ); if ( lineEdit ) { lineEdit->selectAll(); } } } } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void PdmUiToolBarEditor::show() { if ( m_toolbar ) { m_toolbar->show(); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void PdmUiToolBarEditor::hide() { if ( m_toolbar ) { m_toolbar->hide(); } } //-------------------------------------------------------------------------------------------------- /// Special config name used to configure toolbar UI (tooltip etc.) //-------------------------------------------------------------------------------------------------- QString PdmUiToolBarEditor::uiEditorConfigName() { return "ToolbarConfigName"; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- QString PdmUiToolBarEditor::keywordForFocusWidget() { QString keyword; if ( m_toolbar->isVisible() ) { for ( auto fieldViewPair : m_fieldViews ) { auto uiFieldEditorHandle = fieldViewPair.second; if ( uiFieldEditorHandle ) { auto widget = focusWidget( uiFieldEditorHandle ); if ( widget && widget->hasFocus() ) { keyword = fieldViewPair.first; } } } } return keyword; } } // end namespace caf