caf: Create a new CommandFeature libary.

Move Add and Delete command features there.
Implement generic Toggle Commands.
Make library an cmake "OBJECT" library to allow "registering by static initialization".
Add the concept of CurrentContextMenuTargetWidget  into CmdFeatureManager to support the toggle commands.
Updated test application to use the new commands
This commit is contained in:
Jacob Støren 2019-08-29 11:48:43 +02:00
parent 6c8feeb60a
commit 01921a50ab
42 changed files with 1123 additions and 25 deletions

View File

@ -45,6 +45,7 @@ add_subdirectory (cafProjectDataModel/cafPdmXml)
add_subdirectory(cafProjectDataModel)
add_subdirectory(cafCommand)
add_subdirectory(cafCommandFeatures)
add_subdirectory(cafUserInterface)
#executables

View File

@ -28,20 +28,6 @@ set( PROJECT_FILES
cafCmdUiCommandSystemImpl.h
cafCmdUiCommandSystemImpl.cpp
# Default features
defaultfeatures/cafCmdAddItemExec.cpp
defaultfeatures/cafCmdAddItemExec.h
defaultfeatures/cafCmdAddItemExecData.cpp
defaultfeatures/cafCmdAddItemExecData.h
defaultfeatures/cafCmdAddItemFeature.cpp
defaultfeatures/cafCmdAddItemFeature.h
defaultfeatures/cafCmdDeleteItemExec.cpp
defaultfeatures/cafCmdDeleteItemExec.h
defaultfeatures/cafCmdDeleteItemExecData.cpp
defaultfeatures/cafCmdDeleteItemExecData.h
defaultfeatures/cafCmdDeleteItemFeature.cpp
defaultfeatures/cafCmdDeleteItemFeature.h
cafCmdFieldChangeExec.cpp
cafCmdFieldChangeExec.h

View File

@ -41,9 +41,6 @@
#include "cafCmdSelectionHelper.h"
#include "cafFactory.h"
#include "defaultfeatures/cafCmdDeleteItemFeature.h"
#include "defaultfeatures/cafCmdAddItemFeature.h"
#include <QAction>
#include <QKeySequence>
@ -56,9 +53,6 @@ namespace caf
//--------------------------------------------------------------------------------------------------
CmdFeatureManager::CmdFeatureManager()
{
CmdDeleteItemFeature::idNameStatic();
CmdAddItemFeature::idNameStatic();
// Make sure all command features are created. The command feature is registered
// in the command factory, and instantiated when required. This will enable possibility
// of searching through all command features instead of having to use the string keys to
@ -66,7 +60,7 @@ CmdFeatureManager::CmdFeatureManager()
std::vector<std::string> keys = CommandFeatureFactory::instance()->allKeys();
for (size_t i = 0; i < keys.size(); i++)
{
action(QString::fromStdString(keys[i]));
createFeature(keys[i]);
}
}
@ -337,4 +331,20 @@ std::vector<CmdFeature*> CmdFeatureManager::commandFeaturesMatchingKeyboardShort
return matches;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void CmdFeatureManager::setCurrentContextMenuTargetWidget(QWidget * targetWidget)
{
m_currentContextMenuTargetWidget = targetWidget;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QWidget* CmdFeatureManager::currentContextMenuTargetWidget()
{
return m_currentContextMenuTargetWidget;
}
} // end namespace caf

View File

@ -43,9 +43,11 @@
#include <QObject>
#include <QStringList>
#include <QPointer>
class QAction;
class QKeySequence;
class QWidget;
namespace caf
{
@ -66,14 +68,18 @@ public:
QAction* action(const QString& commandId);
QAction* action(const QString& commandId, const QString& customActionText);
QAction* actionWithUserData(const QString& commandId, const QString& customActionText, const QVariant& userData);
void refreshStates(const QStringList& commandIdList = QStringList());
void refreshEnabledState(const QStringList& commandIdList = QStringList());
void refreshCheckedState(const QStringList& commandIdList = QStringList());
CmdFeature* getCommandFeature(const std::string& commandId);
void refreshStates(const QStringList& commandIdList = QStringList());
void refreshEnabledState(const QStringList& commandIdList = QStringList());
void refreshCheckedState(const QStringList& commandIdList = QStringList());
CmdFeature* getCommandFeature(const std::string& commandId);
std::vector<CmdFeature*> commandFeaturesMatchingSubString(const std::string& subString) const;
std::vector<CmdFeature*> commandFeaturesMatchingKeyboardShortcut(const QKeySequence& keySequence) const;
void setCurrentContextMenuTargetWidget(QWidget * targetWidget);
QWidget* currentContextMenuTargetWidget();
private:
CmdFeatureManager();
@ -87,6 +93,7 @@ private:
std::map<std::string , size_t > m_commandIdToFeatureIdxMap;
std::map<QAction*, size_t > m_actionToFeatureIdxMap;
QPointer<QWidget> m_currentContextMenuTargetWidget;
};

View File

@ -168,4 +168,12 @@ bool CmdUiCommandSystemImpl::disableUndoForFieldChange()
return m_disableUndoForFieldChange;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void CmdUiCommandSystemImpl::setCurrentContextMenuTargetWidget(QWidget* targetWidget)
{
caf::CmdFeatureManager::instance()->setCurrentContextMenuTargetWidget(targetWidget);
}
} // end namespace caf

View File

@ -51,6 +51,7 @@ public:
CmdUiCommandSystemImpl();
void fieldChangedCommand(const std::vector<PdmFieldHandle*>& fieldsToUpdate, const QVariant& newUiValue) override;
void setCurrentContextMenuTargetWidget(QWidget* targetWidget) override;
void populateMenuWithDefaultCommands(const QString& uiConfigName, QMenu* menu) override;
bool isUndoEnabled();

View File

@ -0,0 +1,95 @@
cmake_minimum_required (VERSION 2.8.12)
project (cafCommandFeatures)
# These headers need to go through Qt's MOC compiler
set (MOC_HEADER_FILES
)
# Qt
if (CEE_USE_QT5)
find_package(Qt5 COMPONENTS REQUIRED Core Gui Widgets)
set(QT_LIBRARIES Qt5::Core Qt5::Gui Qt5::Widgets)
qt5_wrap_cpp(MOC_SOURCE_FILES ${MOC_HEADER_FILES} )
else()
find_package(Qt4 COMPONENTS QtCore QtGui QtMain REQUIRED)
include(${QT_USE_FILE})
qt4_wrap_cpp(MOC_SOURCE_FILES ${MOC_HEADER_FILES} )
endif(CEE_USE_QT5)
set( PROJECT_FILES
# Default features
AddAndDelete/cafCmdAddItemExec.cpp
AddAndDelete/cafCmdAddItemExec.h
AddAndDelete/cafCmdAddItemExecData.cpp
AddAndDelete/cafCmdAddItemExecData.h
AddAndDelete/cafCmdAddItemFeature.cpp
AddAndDelete/cafCmdAddItemFeature.h
AddAndDelete/cafCmdDeleteItemExec.cpp
AddAndDelete/cafCmdDeleteItemExec.h
AddAndDelete/cafCmdDeleteItemExecData.cpp
AddAndDelete/cafCmdDeleteItemExecData.h
AddAndDelete/cafCmdDeleteItemFeature.cpp
AddAndDelete/cafCmdDeleteItemFeature.h
ToggleCommands/cafToggleItemsFeature.cpp
ToggleCommands/cafToggleItemsFeature.h
ToggleCommands/cafToggleItemsFeatureImpl.cpp
ToggleCommands/cafToggleItemsFeatureImpl.h
ToggleCommands/cafToggleItemsOffFeature.cpp
ToggleCommands/cafToggleItemsOffFeature.h
ToggleCommands/cafToggleItemsOnFeature.cpp
ToggleCommands/cafToggleItemsOnFeature.h
ToggleCommands/cafToggleItemsOnOthersOffFeature.cpp
ToggleCommands/cafToggleItemsOnOthersOffFeature.h
)
# NOTE! Resources in this subfolder appends to the variable QRC_FILES in parent scope
# CMakeList.txt in the application folder (parent scope) must use the following syntax
# to make sure the QRC_FILES variable contains appended files in subfolders
# set( QRC_FILES
# ${QRC_FILES}
# <Path/To/ApplicationResourceFile.qrc>
# )
set( QRC_FILES
${QRC_FILES}
${CMAKE_CURRENT_SOURCE_DIR}/Resources/cafCommandFeatures.qrc
PARENT_SCOPE
)
# NOTE! Adding the library as a cmake "OBJECT" library
# to make sure the linker is not pruning the seemingly unused features,
# and to make sure that the static initialization based registration of the features into the factory is done properly
# see https://gitlab.kitware.com/cmake/community/wikis/doc/tutorials/Object-Library
# and https://cmake.org/cmake/help/v3.15/command/add_library.html?highlight=add_library#object-libraries
add_library( ${PROJECT_NAME} OBJECT
${PROJECT_FILES}
${MOC_SOURCE_FILES}
)
target_include_directories(${PROJECT_NAME}
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
)
target_link_libraries ( ${PROJECT_NAME}
cafCommand
cafUserInterface
${QT_LIBRARIES}
)
if (MSVC)
set_target_properties(${PROJECT_NAME} PROPERTIES COMPILE_FLAGS "/W4 /wd4100 /wd4127")
endif()
source_group("" FILES ${PROJECT_FILES})
# cotire
if (COMMAND caf_apply_cotire)
caf_apply_cotire("${PROJECT_NAME}")
endif()

Binary file not shown.

After

Width:  |  Height:  |  Size: 312 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 369 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 556 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 482 B

View File

@ -0,0 +1,8 @@
<RCC>
<qresource prefix="cafCommandFeatures">
<file>ToggleOnL16x16.png</file>
<file>ToggleOffL16x16.png</file>
<file>ToggleOnOffL16x16.png</file>
<file>ToggleOnOthersOffL16x16.png</file>
</qresource>
</RCC>

View File

@ -0,0 +1,79 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2019- 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 <<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 "cafToggleItemsFeature.h"
#include "cafToggleItemsFeatureImpl.h"
#include "cafSelectionManager.h"
#include <QAction>
namespace caf
{
CAF_CMD_SOURCE_INIT(ToggleItemsFeature, "cafToggleItemsFeature");
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool ToggleItemsFeature::isCommandEnabled()
{
return ToggleItemsFeatureImpl::isToggleCommandsAvailable();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void ToggleItemsFeature::onActionTriggered(bool isChecked)
{
ToggleItemsFeatureImpl::setObjectToggleStateForSelection(ToggleItemsFeatureImpl::TOGGLE_SUBITEMS);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void ToggleItemsFeature::setupActionLook(QAction* actionToSetup)
{
if (ToggleItemsFeatureImpl::isToggleCommandsForSubItems())
actionToSetup->setText("Toggle Sub Items");
else
actionToSetup->setText("Toggle");
actionToSetup->setIcon(QIcon(":/cafCommandFeatures/ToggleOnOffL16x16.png"));
}
}

View File

@ -0,0 +1,57 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2019- 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 <<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 "cafCmdFeature.h"
namespace caf
{
//==================================================================================================
///
//==================================================================================================
class ToggleItemsFeature : public caf::CmdFeature
{
CAF_CMD_HEADER_INIT;
protected:
// Overrides
bool isCommandEnabled() override;
void onActionTriggered( bool isChecked ) override;
void setupActionLook( QAction* actionToSetup ) override;
};
}

View File

@ -0,0 +1,204 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2019- 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 <<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 "cafToggleItemsFeatureImpl.h"
//#include "RiaFeatureCommandContext.h"
//#include "RiaGuiApplication.h"
//#include "RiuMainWindow.h"
//#include "RiuPlotMainWindow.h"
#include "cafPdmUiFieldHandle.h"
#include "cafPdmUiItem.h"
#include "cafPdmUiObjectHandle.h"
#include "cafPdmUiTreeOrdering.h"
#include "cafPdmUiTreeView.h"
#include "cafSelectionManager.h"
#include <QModelIndex>
#include <vector>
#include "cafCmdFeatureManager.h"
namespace caf
{
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool ToggleItemsFeatureImpl::isToggleCommandsAvailable()
{
std::vector<caf::PdmUiItem*> selectedItems;
caf::SelectionManager::instance()->selectedItems(selectedItems);
if (selectedItems.size() == 1)
{
caf::PdmUiTreeOrdering* treeItem = findTreeItemFromSelectedUiItem(selectedItems[0]);
if (!treeItem) return false;
for (int cIdx = 0; cIdx < treeItem->childCount(); ++ cIdx)
{
caf::PdmUiTreeOrdering* child = treeItem->child(cIdx);
if (!child) continue;
if (!child->isRepresentingObject()) continue;
caf::PdmObjectHandle* childObj = child->object();
caf::PdmUiObjectHandle* uiObjectHandleChild = uiObj(childObj);
if (uiObjectHandleChild &&
uiObjectHandleChild->objectToggleField() &&
!uiObjectHandleChild->objectToggleField()->uiCapability()->isUiReadOnly())
{
return true;
}
}
}
else
{
for (size_t i = 0; i < selectedItems.size(); ++i)
{
caf::PdmUiObjectHandle* uiObjectHandle = dynamic_cast<caf::PdmUiObjectHandle*>(selectedItems[i]);
if (uiObjectHandle && uiObjectHandle->objectToggleField())
{
return true;
}
}
}
return false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool ToggleItemsFeatureImpl::isToggleCommandsForSubItems()
{
std::vector<caf::PdmUiItem*> selectedItems;
caf::SelectionManager::instance()->selectedItems(selectedItems);
if (isToggleCommandsAvailable() && selectedItems.size() == 1)
{
return true;
}
return false;
}
//--------------------------------------------------------------------------------------------------
/// Set toggle state for list of model indices.
//--------------------------------------------------------------------------------------------------
void ToggleItemsFeatureImpl::setObjectToggleStateForSelection(SelectionToggleType state)
{
std::vector<caf::PdmUiItem*> selectedItems;
caf::SelectionManager::instance()->selectedItems(selectedItems);
if (state != TOGGLE && selectedItems.size() == 1)
{
// If only one item is selected, loop over its children, and toggle them instead of the
// selected item directly
// We need to get the children through the tree view, because that is where the actually shown children is
caf::PdmUiTreeOrdering* treeItem = findTreeItemFromSelectedUiItem(selectedItems[0]);
if (!treeItem) return;
for (int cIdx = 0; cIdx < treeItem->childCount(); ++ cIdx)
{
caf::PdmUiTreeOrdering* child = treeItem->child(cIdx);
if (!child) continue;
if (!child->isRepresentingObject()) continue;
caf::PdmObjectHandle* childObj = child->object();
caf::PdmUiObjectHandle* uiObjectHandleChild = uiObj(childObj);
if (uiObjectHandleChild && uiObjectHandleChild->objectToggleField())
{
caf::PdmField<bool>* field = dynamic_cast<caf::PdmField<bool>*>(uiObjectHandleChild->objectToggleField());
if (state == TOGGLE_ON) field->setValueWithFieldChanged(true);
if (state == TOGGLE_OFF) field->setValueWithFieldChanged(false);
if (state == TOGGLE_SUBITEMS) field->setValueWithFieldChanged(!(field->v()));
}
}
}
else
{
for (size_t i = 0; i < selectedItems.size(); ++i)
{
caf::PdmUiObjectHandle* uiObjectHandle = dynamic_cast< caf::PdmUiObjectHandle*>(selectedItems[i]);
if (uiObjectHandle && uiObjectHandle->objectToggleField())
{
caf::PdmField<bool>* field = dynamic_cast<caf::PdmField<bool>* >(uiObjectHandle->objectToggleField());
if (state == TOGGLE_ON) field->setValueWithFieldChanged(true);
if (state == TOGGLE_OFF) field->setValueWithFieldChanged(false);
if (state == TOGGLE_SUBITEMS || state == TOGGLE)
{
field->setValueWithFieldChanged(!(field->v()));
}
}
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
caf::PdmUiTreeView* ToggleItemsFeatureImpl::findTreeView(const caf::PdmUiItem* uiItem)
{
caf::PdmUiTreeView* customActiveTreeView = dynamic_cast<caf::PdmUiTreeView*>(CmdFeatureManager::instance()->currentContextMenuTargetWidget());
return customActiveTreeView;
}
//--------------------------------------------------------------------------------------------------
/// Finds the tree item in either the 3D main window or plot main window project tree view
//--------------------------------------------------------------------------------------------------
caf::PdmUiTreeOrdering* ToggleItemsFeatureImpl::findTreeItemFromSelectedUiItem(const caf::PdmUiItem* uiItem)
{
caf::PdmUiTreeView* pdmUiTreeView = findTreeView(uiItem);
if (pdmUiTreeView)
{
QModelIndex modIndex = pdmUiTreeView->findModelIndex(uiItem);
return static_cast<caf::PdmUiTreeOrdering*>(modIndex.internalPointer());
}
return nullptr;
}
}

View File

@ -0,0 +1,70 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2019- 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 <<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
namespace caf
{
class PdmUiItem;
class PdmUiTreeOrdering;
class PdmUiTreeView;
//==================================================================================================
///
//==================================================================================================
class ToggleItemsFeatureImpl
{
public:
enum SelectionToggleType
{
TOGGLE_ON,
TOGGLE_OFF,
TOGGLE_SUBITEMS,
TOGGLE,
TOGGLE_UNDEFINED
};
static bool isToggleCommandsAvailable();
static bool isToggleCommandsForSubItems();
static void setObjectToggleStateForSelection(SelectionToggleType state);
private:
static caf::PdmUiTreeView* findTreeView(const caf::PdmUiItem* uiItem);
static caf::PdmUiTreeOrdering* findTreeItemFromSelectedUiItem(const caf::PdmUiItem* uiItem);
};
};

View File

@ -0,0 +1,80 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2019- 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 <<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 "cafToggleItemsOffFeature.h"
#include "cafToggleItemsFeatureImpl.h"
#include "cafSelectionManager.h"
#include <QAction>
namespace caf
{
CAF_CMD_SOURCE_INIT(ToggleItemsOffFeature, "cafToggleItemsOffFeature");
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool ToggleItemsOffFeature::isCommandEnabled()
{
return ToggleItemsFeatureImpl::isToggleCommandsAvailable();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void ToggleItemsOffFeature::onActionTriggered(bool isChecked)
{
ToggleItemsFeatureImpl::setObjectToggleStateForSelection(ToggleItemsFeatureImpl::TOGGLE_OFF);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void ToggleItemsOffFeature::setupActionLook(QAction* actionToSetup)
{
if (ToggleItemsFeatureImpl::isToggleCommandsForSubItems())
actionToSetup->setText("Sub Items Off");
else
actionToSetup->setText("Off");
actionToSetup->setIcon(QIcon(":/cafCommandFeatures/ToggleOffL16x16.png"));
}
}

View File

@ -0,0 +1,57 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2019- 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 <<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 "cafCmdFeature.h"
namespace caf
{
//==================================================================================================
///
//==================================================================================================
class ToggleItemsOffFeature : public caf::CmdFeature
{
CAF_CMD_HEADER_INIT;
protected:
// Overrides
bool isCommandEnabled() override;
void onActionTriggered( bool isChecked ) override;
void setupActionLook( QAction* actionToSetup ) override;
};
}

View File

@ -0,0 +1,80 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2019- 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 <<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 "cafToggleItemsOnFeature.h"
#include "cafToggleItemsFeatureImpl.h"
#include "cafSelectionManager.h"
#include <QAction>
namespace caf
{
CAF_CMD_SOURCE_INIT(ToggleItemsOnFeature, "cafToggleItemsOnFeature");
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool ToggleItemsOnFeature::isCommandEnabled()
{
return ToggleItemsFeatureImpl::isToggleCommandsAvailable();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void ToggleItemsOnFeature::onActionTriggered(bool isChecked)
{
ToggleItemsFeatureImpl::setObjectToggleStateForSelection(ToggleItemsFeatureImpl::TOGGLE_ON);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void ToggleItemsOnFeature::setupActionLook(QAction* actionToSetup)
{
if (ToggleItemsFeatureImpl::isToggleCommandsForSubItems())
actionToSetup->setText("Sub Items On");
else
actionToSetup->setText("On");
actionToSetup->setIcon(QIcon(":/cafCommandFeatures/ToggleOnL16x16.png"));
}
}

View File

@ -0,0 +1,58 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2019- 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 <<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 "cafCmdFeature.h"
namespace caf
{
//==================================================================================================
///
//==================================================================================================
class ToggleItemsOnFeature : public caf::CmdFeature
{
CAF_CMD_HEADER_INIT;
protected:
// Overrides
bool isCommandEnabled() override;
void onActionTriggered( bool isChecked ) override;
void setupActionLook( QAction* actionToSetup ) override;
};
}

View File

@ -0,0 +1,165 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2019- 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 <<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 "cafToggleItemsOnOthersOffFeature.h"
#include "cafToggleItemsFeatureImpl.h"
#include "cafSelectionManager.h"
#include <QAction>
#include "cafPdmObjectHandle.h"
#include "cafPdmObject.h"
#include "cafPdmUiItem.h"
namespace caf
{
CAF_CMD_SOURCE_INIT(ToggleItemsOnOthersOffFeature, "cafToggleItemsOnOthersOffFeature");
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool ToggleItemsOnOthersOffFeature::isCommandEnabled()
{
std::vector<caf::PdmObject*> selectedObjects;
caf::SelectionManager::instance()->objectsByType(&selectedObjects);
caf::PdmFieldHandle* commonParent = verifySameParentForSelection(selectedObjects);
std::vector<caf::PdmObjectHandle*> children = childObjects(commonParent);
return commonParent != nullptr
&& children.size() > 0
&& objectToggleField(children.front())
&& children.size() > selectedObjects.size();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void ToggleItemsOnOthersOffFeature::onActionTriggered(bool isChecked)
{
std::vector<caf::PdmObject*> selectedObjects;
caf::SelectionManager::instance()->objectsByType(&selectedObjects);
// First toggle off all siblings
caf::PdmFieldHandle* commonParent = verifySameParentForSelection(selectedObjects);
for (caf::PdmObjectHandle* child : childObjects(commonParent))
{
caf::PdmField<bool>* field = objectToggleField(child);
if (field)
{
field->setValueWithFieldChanged(false);
}
}
// Then toggle on the selected item(s)
for (caf::PdmObject* selectedObject : selectedObjects)
{
caf::PdmField<bool>* field = dynamic_cast<caf::PdmField<bool>*>(selectedObject->objectToggleField());
field->setValueWithFieldChanged(true);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void ToggleItemsOnOthersOffFeature::setupActionLook(QAction* actionToSetup)
{
actionToSetup->setText("On - Others Off");
actionToSetup->setIcon(QIcon(":/cafCommandFeatures/ToggleOnOthersOffL16x16.png"));
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
caf::PdmFieldHandle* ToggleItemsOnOthersOffFeature::verifySameParentForSelection(const std::vector<caf::PdmObject*>& selection)
{
caf::PdmFieldHandle* sameParent = nullptr;
for ( caf::PdmObject* obj : selection )
{
caf::PdmFieldHandle* parent = obj->parentField();
if ( parent )
{
if ( !sameParent )
{
sameParent = parent;
}
else if ( parent != sameParent )
{
// Different parents detected
return nullptr;
}
}
}
return sameParent;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<caf::PdmObjectHandle*> ToggleItemsOnOthersOffFeature::childObjects(caf::PdmFieldHandle* parent)
{
std::vector<caf::PdmObjectHandle*> children;
if ( parent )
{
parent->childObjects(&children);
}
return children;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
caf::PdmField<bool>* ToggleItemsOnOthersOffFeature::objectToggleField(caf::PdmObjectHandle* objectHandle)
{
caf::PdmUiObjectHandle* childUiObject = uiObj(objectHandle);
if ( childUiObject && childUiObject->objectToggleField() )
{
return dynamic_cast<caf::PdmField<bool>*>(childUiObject->objectToggleField());
}
return nullptr;
}
}

View File

@ -0,0 +1,68 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2019- 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 <<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 "cafCmdFeature.h"
#include "cafPdmField.h"
namespace caf
{
class PdmFieldHandle;
class PdmObject;
class PdmObjectHandle;
//==================================================================================================
///
//==================================================================================================
class ToggleItemsOnOthersOffFeature : public caf::CmdFeature
{
CAF_CMD_HEADER_INIT;
protected:
// Overrides
bool isCommandEnabled() override;
void onActionTriggered( bool isChecked ) override;
void setupActionLook( QAction* actionToSetup ) override;
private:
caf::PdmFieldHandle* verifySameParentForSelection(const std::vector<caf::PdmObject*>& selectedObjects);
std::vector<caf::PdmObjectHandle*> childObjects(caf::PdmFieldHandle* parent);
caf::PdmField<bool>* objectToggleField(caf::PdmObjectHandle* objectHandle);
};
}

View File

@ -41,6 +41,7 @@
class QVariant;
class QMenu;
class QString;
class QWidget;
namespace caf
{
@ -53,6 +54,8 @@ class PdmUiCommandSystemInterface
{
public:
virtual void fieldChangedCommand( const std::vector<PdmFieldHandle*>& fieldsToUpdate, const QVariant& newUiValue) = 0;
virtual void setCurrentContextMenuTargetWidget(QWidget* targetWidget) = 0;
virtual void populateMenuWithDefaultCommands(const QString& uiConfigName, QMenu* menu) = 0;
};

View File

@ -145,6 +145,17 @@ void PdmUiCommandSystemProxy::setUiValueToField(PdmUiFieldHandle* uiFieldHandle,
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmUiCommandSystemProxy::setCurrentContextMenuTargetWidget(QWidget* targetWidget)
{
if (m_commandInterface)
{
m_commandInterface->setCurrentContextMenuTargetWidget(targetWidget);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -39,6 +39,7 @@
class QVariant;
class QMenu;
class QString;
class QWidget;
namespace caf
{
@ -57,6 +58,7 @@ public:
void setCommandInterface(PdmUiCommandSystemInterface* undoCommandInterface);
void setUiValueToField(PdmUiFieldHandle* uiFieldHandle, const QVariant& newUiValue);
void setCurrentContextMenuTargetWidget(QWidget* targetWidget);
void populateMenuWithDefaultCommands(const QString& uiConfigName, QMenu* menu);
private:

View File

@ -237,12 +237,15 @@ void PdmUiFieldEditorHandle::customMenuRequested(QPoint pos)
}
QMenu menu;
PdmUiCommandSystemProxy::instance()->setCurrentContextMenuTargetWidget(widget);
objectHandle->uiCapability()->defineCustomContextMenu(uiField()->fieldHandle(), &menu, widget);
if (!menu.actions().empty())
{
menu.exec(globalPos);
}
PdmUiCommandSystemProxy::instance()->setCurrentContextMenuTargetWidget(nullptr);
}
}

View File

@ -17,6 +17,7 @@ set (MOC_HEADER_FILES
# Resource file
set( QRC_FILES
${QRC_FILES}
textedit.qrc
)
@ -76,6 +77,7 @@ if (USE_COMMAND_FRAMEWORK)
set (TAP_LINK_LIBRARIES
${TAP_LINK_LIBRARIES}
cafCommand
cafCommandFeatures
)
endif(USE_COMMAND_FRAMEWORK)

View File

@ -45,6 +45,7 @@
#include <QMenuBar>
#include <QTreeView>
#include <QUndoView>
#include "cafCmdFeatureMenuBuilder.h"
class DemoPdmObjectGroup : public caf::PdmDocument
@ -821,6 +822,14 @@ void MainWindow::createDockPanels()
m_pdmUiTreeView = new caf::PdmUiTreeView(dockWidget);
dockWidget->setWidget(m_pdmUiTreeView);
m_pdmUiTreeView->treeView()->setContextMenuPolicy(Qt::CustomContextMenu);
QObject::connect(m_pdmUiTreeView->treeView(),
SIGNAL(customContextMenuRequested(const QPoint&)),
SLOT(slotCustomMenuRequestedForProjectTree(const QPoint&)));
m_pdmUiTreeView->treeView()->setSelectionMode(QAbstractItemView::ExtendedSelection);
m_pdmUiTreeView->enableSelectionManagerUpdating(true);
addDockWidget(Qt::LeftDockWidgetArea, dockWidget);
}
@ -1235,3 +1244,31 @@ void MainWindow::slotSaveProject()
m_testRoot->writeFile();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void MainWindow::slotCustomMenuRequestedForProjectTree(const QPoint&)
{
QObject* senderObj = this->sender();
QTreeView* treeView = dynamic_cast<QTreeView*>(senderObj);
if (treeView)
{
QMenu menu;
caf::CmdFeatureManager::instance()->setCurrentContextMenuTargetWidget(m_pdmUiTreeView);
caf::CmdFeatureMenuBuilder menuBuilder;
menuBuilder << "cafToggleItemsOnFeature";
menuBuilder << "cafToggleItemsOffFeature";
menuBuilder << "cafToggleItemsFeature";
menuBuilder << "Separator";
menuBuilder << "cafToggleItemsOnOthersOffFeature";
menuBuilder.appendToMenu(&menu);
menu.exec(QCursor::pos());
caf::CmdFeatureManager::instance()->setCurrentContextMenuTargetWidget(nullptr);
}
}

View File

@ -50,6 +50,8 @@ private slots:
void slotLoadProject();
void slotSaveProject();
void slotCustomMenuRequestedForProjectTree(const QPoint&);
private:
static MainWindow* sm_mainWindowInstance;

View File

@ -262,6 +262,8 @@ void PdmUiTreeViewEditor::customMenuRequested(QPoint pos)
SelectionManager::instance()->setActiveChildArrayFieldHandle(this->currentChildArrayFieldHandle());
QMenu menu;
PdmUiCommandSystemProxy::instance()->setCurrentContextMenuTargetWidget(m_mainWidget->parentWidget());
caf::PdmUiCommandSystemProxy::instance()->populateMenuWithDefaultCommands("PdmUiTreeViewEditor", &menu);
if (menu.actions().size() > 0)
@ -271,6 +273,8 @@ void PdmUiTreeViewEditor::customMenuRequested(QPoint pos)
menu.exec(globalPos);
}
PdmUiCommandSystemProxy::instance()->setCurrentContextMenuTargetWidget(nullptr);
}