diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 5a092893ae4ef4fdcad3b2d167fe4d3a0a6e9de1..8dbdd489c4045a10b3627588280f40f2f6d5a975 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -47,7 +47,7 @@ test:fedora33:
- .cmake_test_linux
- .cmake_test_artifacts
- .linux_test_tags
- - .run_automatically
+ - .run_dependent
dependencies:
- build:fedora33
needs:
@@ -67,7 +67,7 @@ test:fedora33-vtk-python3:
- .cmake_test_linux
- .cmake_test_artifacts
- .linux_test_tags
- - .run_automatically
+ - .run_dependent
dependencies:
- build:fedora33-vtk-python3
needs:
@@ -87,7 +87,7 @@ test:fedora33-paraview:
- .cmake_test_linux
- .cmake_test_artifacts
- .linux_test_tags
- - .run_automatically
+ - .run_dependent
dependencies:
- build:fedora33-paraview
needs:
@@ -107,7 +107,7 @@ test:fedora33-nodata:
- .cmake_test_linux
- .cmake_test_artifacts
- .linux_test_tags
- - .run_automatically
+ - .run_dependent
dependencies:
- build:fedora33-nodata
needs:
@@ -129,7 +129,7 @@ test:fedora33-asan:
- .cmake_memcheck_linux
- .cmake_test_artifacts
- .linux_test_priv_tags
- - .run_automatically
+ - .run_dependent
dependencies:
- build:fedora33-asan
needs:
@@ -149,7 +149,7 @@ test:fedora33-ubsan:
- .cmake_memcheck_linux
- .cmake_test_artifacts
- .linux_test_priv_tags
- - .run_automatically
+ - .run_dependent
dependencies:
- build:fedora33-ubsan
needs:
@@ -169,7 +169,7 @@ build:fedora33-coverage:
- .cmake_build_linux
- .cmake_build_artifacts
- .linux_builder_tags
- - .run_automatically
+ - .run_dependent
test:fedora33-coverage:
extends:
@@ -177,7 +177,7 @@ test:fedora33-coverage:
- .cmake_test_linux
- .linux_test_tags
- .cmake_coverage_artifacts
- - .run_automatically
+ - .run_dependent
dependencies:
- build:fedora33-coverage
needs:
@@ -188,7 +188,7 @@ analyze:fedora33-coverage:
- .fedora33_coverage
- .cmake_coverage_linux
- .linux_builder_tags
- - .run_automatically
+ - .run_dependent
dependencies:
- test:fedora33-coverage
needs:
@@ -212,7 +212,7 @@ test:macos-arm64:
- .cmake_test_macos
- .cmake_test_artifacts
- .macos_arm64_builder_tags
- - .run_automatically
+ - .run_dependent
dependencies:
- build:macos-arm64
needs:
@@ -232,7 +232,7 @@ test:macos-x86_64:
- .cmake_test_macos
- .cmake_test_artifacts
- .macos_builder_tags
- - .run_automatically
+ - .run_dependent
dependencies:
- build:macos-x86_64
needs:
@@ -256,7 +256,7 @@ test:windows-vs2019-ninja:
- .cmake_test_windows
- .cmake_test_artifacts
- .windows_builder_tags
- - .run_automatically
+ - .run_dependent
dependencies:
- build:windows-vs2019-ninja
needs:
diff --git a/.gitlab/ci/cmake.ps1 b/.gitlab/ci/cmake.ps1
index 5d01e3f9e336c06f702a93c63e16a8d3cb44d67e..11e37069b6f359fe8b2016d7fae067f33ca51c67 100755
--- a/.gitlab/ci/cmake.ps1
+++ b/.gitlab/ci/cmake.ps1
@@ -1,7 +1,7 @@
$erroractionpreference = "stop"
-$version = "3.21.0"
-$sha256sum = "C7B88C907A753F4EC86E43DDC89F91F70BF1B011859142F7F29E6D51EA4ABB3C"
+$version = "3.21.1"
+$sha256sum = "9FBA6DF0B89BE0DC0377F2E77CA272B3F8C38691FE237699DE275EA0C2254242"
$filename = "cmake-$version-windows-x86_64"
$tarball = "$filename.zip"
diff --git a/.gitlab/ci/cmake.sh b/.gitlab/ci/cmake.sh
index 1547e30aa246c3d387c39a1992f3e9fc4ebc47fd..0a1d13682b6cfffedabc887af08e796a107e3b50 100755
--- a/.gitlab/ci/cmake.sh
+++ b/.gitlab/ci/cmake.sh
@@ -2,17 +2,17 @@
set -e
-readonly version="3.21.0"
+readonly version="3.21.1"
case "$( uname -s )" in
Linux)
shatool="sha256sum"
- sha256sum="d54ef6909f519740bc85cec07ff54574cd1e061f9f17357d9ace69f61c6291ce"
+ sha256sum="bf496ce869d0aa8c1f57e4d1a2e50c8f2fb12a6cd7ccb37ad743bb88f6b76a1e"
platform="linux-x86_64"
;;
Darwin)
shatool="shasum -a 256"
- sha256sum="c1c6f19dfc9c658a48b5aed22806595b2337bb3aedb71ab826552f74f568719f"
+ sha256sum="9dc2978c4d94a44f71336fa88c15bb0eee47cf44b6ece51b10d1dfae95f82279"
platform="macos-universal"
;;
*)
diff --git a/.gitlab/ci/configure_fedora33_paraview.cmake b/.gitlab/ci/configure_fedora33_paraview.cmake
index 7f86900d2a66d42a53719110b780d91b3c598f81..2203fce351a48f185db83619f5b97f2480302047 100644
--- a/.gitlab/ci/configure_fedora33_paraview.cmake
+++ b/.gitlab/ci/configure_fedora33_paraview.cmake
@@ -4,6 +4,7 @@ set(SMTK_PLUGIN_CONTRACT_FILE_URLS
"https://gitlab.kitware.com/cmb/plugins/truchas-extensions/-/raw/master/CMake/truchas-extensions.cmake"
"https://gitlab.kitware.com/cmb/cmb/-/raw/master/cmake/cmb.cmake"
"https://gitlab.kitware.com/cmb/plugins/ace3p-extensions/-/raw/master/CMake/ace3p-extensions.cmake"
+ "https://gitlab.kitware.com/cmb/plugins/xmsmeshoperation/-/raw/master/CMake/xms-mesh-operation.cmake"
CACHE STRING "")
include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora33.cmake")
diff --git a/.gitlab/ci/docker/fedora33-paraview/install_superbuild.sh b/.gitlab/ci/docker/fedora33-paraview/install_superbuild.sh
index bd3df49bcd5ae986dcc5c2e9f27a2c575f7984d4..96f9a77836cbe96bbe4099d0dc147b6ff6e8a181 100755
--- a/.gitlab/ci/docker/fedora33-paraview/install_superbuild.sh
+++ b/.gitlab/ci/docker/fedora33-paraview/install_superbuild.sh
@@ -27,12 +27,12 @@ cmake -GNinja \
-DDEVELOPER_MODE_smtk:BOOL=ON \
-DENABLE_cmb:BOOL=OFF \
-DENABLE_cmbusersguide:BOOL=OFF \
- -DENABLE_smtkprojectmanager:BOOL=OFF \
-DENABLE_smtkresourcemanagerstate:BOOL=OFF \
-DENABLE_paraview:BOOL=ON \
-DENABLE_python3:BOOL=ON \
-DSUPPRESS_szip_OUTPUT:BOOL=OFF \
-DUSE_SYSTEM_qt5:BOOL=ON \
+ -DENABLE_xmsmesher:BOOL=ON \
$sccache_settings \
"-D__BUILDBOT_INSTALL_LOCATION:PATH=$SUPERBUILD_PREFIX" \
"$workdir"
diff --git a/.gitlab/issue_templates/new-release.md b/.gitlab/issue_templates/new-release.md
index dec45344e4e562dc29120f77040269b3a24c8531..9d7e38e0d5372d6baf25d9d7732d8c3e43e35307 100644
--- a/.gitlab/issue_templates/new-release.md
+++ b/.gitlab/issue_templates/new-release.md
@@ -6,7 +6,7 @@ following strings with the associated values:
- `MAJOR`: e.g. yy is the year
- `MINOR`: e.g. mm is the month
- `PATCH`: e.g. the release sequence number (start at 0)
- - `BRANCHPOINT`: The commit where the release should be started
+ - `BRANCHPOINT`: The commit where the release should be started - it is a point on master where the release process branch is started from. The release process branch will have multiple commits including the assembling of release notes and changing of the version.
Please remove this comment.
-->
@@ -31,7 +31,8 @@ Please remove this comment.
- Integrate changes.
- Make a commit for each of these `release`-only changes on a single topic
(suggested branch name: `update-to-vVERSION`):
- - Assemble release notes into `doc/release/notes/smtk-MAJOR.MINOR.md`.
+ - [ ] Assemble release notes into `doc/release/notes/smtk-MAJOR.MINOR.rst`.
+ - [ ] Update the ReadMe file to refer to the new release notes
- [ ] If `PATCH` is greater than 0, add items to the end of this file.
- [ ] Update `version.txt` and tag the commit (tag this commit below)
- [ ] `git checkout -b update-to-vVERSION BRANCHPOINT`
diff --git a/.gitlab/os-linux.yml b/.gitlab/os-linux.yml
index ad137a44e71c457acb8bab33b6a4d06f8b193d28..65378dad707b98e74622fbdbb65a8075366bf532 100644
--- a/.gitlab/os-linux.yml
+++ b/.gitlab/os-linux.yml
@@ -72,7 +72,7 @@
.fedora33_paraview:
extends: .fedora33_vtk_python3
- image: "kitware/cmb:ci-smtk-fedora33-paraview-20210714"
+ image: "kitware/cmb:ci-smtk-fedora33-paraview-20210829"
variables:
CMAKE_CONFIGURATION: fedora33_paraview
diff --git a/.gitlab/os-macos.yml b/.gitlab/os-macos.yml
index 7cb8f5030c6d3fef5e2cf94e216f51adad2a42bc..5f4dcbae355bfe0be4e79e98288c20454c4c2980 100644
--- a/.gitlab/os-macos.yml
+++ b/.gitlab/os-macos.yml
@@ -10,7 +10,7 @@
# use so that different versions can be tested in a single pipeline.
DEVELOPER_DIR: "/Applications/Xcode-12.4.app/Contents/Developer"
# Avoid conflicting with other projects running on the same machine.
- SCCACHE_SERVER_PORT: 4231
+ SCCACHE_SERVER_PORT: 4228
### Build and test
diff --git a/.gitlab/os-windows.yml b/.gitlab/os-windows.yml
index b65671aa0045211797bd0f36c1a0a8ffbb3b00bb..3c111a4858b720cfb7ef00a8a6c16e1329bfcdcf 100644
--- a/.gitlab/os-windows.yml
+++ b/.gitlab/os-windows.yml
@@ -7,7 +7,9 @@
GIT_SUBMODULE_STRATEGY: recursive
GIT_CLONE_PATH: "$CI_BUILDS_DIR\\cmb-ci-ext\\$CI_CONCURRENT_ID"
# Avoid conflicting with other projects running on the same machine.
- SCCACHE_SERVER_PORT: 4231
+ SCCACHE_SERVER_PORT: 4228
+ # Do not let the sccache server shut down due to a slow machine.
+ SCCACHE_IDLE_TIMEOUT: 0
### Build and test
@@ -75,7 +77,7 @@
- *before_script_windows
- Set-Item -Force -Path "env:PATH" -Value "$env:PATH;$env:SCCACHE_PATH"
- Invoke-Expression -Command .gitlab/ci/vcvarsall.ps1
- - sccache --start-server
+ - Invoke-Expression -Command "sccache --start-server"
- sccache --show-stats
- ctest -VV -S .gitlab/ci/ctest_configure.cmake
- ctest -VV -S .gitlab/ci/ctest_build.cmake
@@ -90,9 +92,4 @@
- *before_script_windows
- Invoke-Expression -Command .gitlab/ci/vcvarsall.ps1
- ctest --output-on-failure -V -S .gitlab/ci/ctest_test.cmake
- after_script:
- # Ensure that `git clean` can always remove the directory. But don't
- # remove so much that the build cannot be debugged.
- # https://github.com/git-for-windows/git/issues/2715
- - cmd /C "rmdir /S /Q build\superbuild\smtk\build\PluginTests"
interruptible: true
diff --git a/.gitlab/rules.yml b/.gitlab/rules.yml
index 6c7db2fbd4dbb6407adab6166d8157d899919f78..76f23103b99705f98cec4481ed03aa65ee73769c 100644
--- a/.gitlab/rules.yml
+++ b/.gitlab/rules.yml
@@ -8,3 +8,11 @@
when: delayed
start_in: 30 minutes
- when: never
+
+.run_dependent:
+ rules:
+ - if: '$CI_MERGE_REQUEST_ID'
+ when: on_success
+ - if: '$CI_PROJECT_PATH == "cmb/smtk"'
+ when: on_success
+ - when: never
diff --git a/CMake/CTestCustom.cmake.in b/CMake/CTestCustom.cmake.in
index a2ad18fc406e47269b39bdb7720ea8d213835199..6bb43e294307b5d5531c8fcf0c5ae5dd177f949b 100644
--- a/CMake/CTestCustom.cmake.in
+++ b/CMake/CTestCustom.cmake.in
@@ -34,11 +34,11 @@ list(APPEND CTEST_CUSTOM_WARNING_EXCEPTION
"_server_manager_data\\.h.*modernize-deprecated-headers"
"note: make as 'inline'"
- # CMake-generated sources. (cmake/cmake!6352)
- "UnitTests_smtk_"
-
# Warnings from the delaunay submodule.
"thirdparty/delaunay"
+
+ # Warnings from sccache that we don't care about.
+ "sccache: warning: The server looks like it shut down unexpectedly, compiling locally instead"
)
##------------------------------------------------------------------------------
diff --git a/CMake/Version.h.in b/CMake/Version.h.in
index 3dceeb1b7e917a1530bc776a220ea6ae295a1b14..2a0081bed9989536dade69beb7795efd3052aaae 100644
--- a/CMake/Version.h.in
+++ b/CMake/Version.h.in
@@ -16,10 +16,13 @@
/// Integer-valued major version number
#define SMTK_VERSION_MAJOR @SMTK_VERSION_MAJOR@
/// Integer-valued minor version number
-#define SMTK_VERSION_MINOR @SMTK_VERSION_MINOR@
+#define SMTK_VERSION_MINOR_INT @SMTK_VERSION_MINOR_INT@
/// Integer-valued patch version number
#define SMTK_VERSION_PATCH @SMTK_VERSION_PATCH@
+/// String-valued minor version number
+#define SMTK_VERSION_MINOR @SMTK_VERSION_MINOR@
+
// On some systems, major and minor are defined as macros. If this is one of
// those systems, undefine these macros before defining the static methods
// of smtk::common::Version.
@@ -42,7 +45,7 @@ public:
static int major() { return SMTK_VERSION_MAJOR; }
/// Return the version number components as integers.
- static int minor() { return SMTK_VERSION_MINOR; }
+ static int minor() { return SMTK_VERSION_MINOR_INT; }
/// Return the version number components as integers.
static int patch() { return SMTK_VERSION_PATCH; }
diff --git a/CMake/smtkVersion.cmake b/CMake/smtkVersion.cmake
index b90c69b419e394aca5649b130e9d1f1a6249ed26..df0edf89603223909b0dcc49d1f8eb9eaca48337 100644
--- a/CMake/smtkVersion.cmake
+++ b/CMake/smtkVersion.cmake
@@ -31,4 +31,6 @@ if (NOT DEFINED SMTK_VERISON)
set(SMTK_VERSION_LABEL "${CMAKE_MATCH_4}")
endif()
+ set(SMTK_VERSION_MINOR_STRING ${SMTK_VERSION_MINOR})
+ string(REGEX REPLACE "^0" "" SMTK_VERSION_MINOR_INT ${SMTK_VERSION_MINOR})
endif()
diff --git a/CTestConfig.cmake b/CTestConfig.cmake
index 1dcdb9b5fdb82ce8f5fdbe44f0cb17f138139d6a..f44a82eda3a0366e756bff228a799a7011e5abd9 100644
--- a/CTestConfig.cmake
+++ b/CTestConfig.cmake
@@ -7,8 +7,7 @@
set(CTEST_PROJECT_NAME "SuperBuild-ConceptualModelBuilder")
set(CTEST_NIGHTLY_START_TIME "21:00:00 EDT")
-#set(drop_sites kitware)
-set(drop_sites)
+set(drop_sites kitware)
set(CTEST_DROP_METHOD_kitware "https")
set(CTEST_DROP_SITE_kitware "www.kitware.com/CDash")
diff --git a/ReadMe.md b/ReadMe.md
index 5383954b5ce076e0558d8b46bd089748f2abb8e1..e7a978d46ab79b8ba70eecf2138185bc1125e9bd 100644
--- a/ReadMe.md
+++ b/ReadMe.md
@@ -62,7 +62,7 @@ See [CONTRIBUTING.md][] for instructions to contribute.
Latest Release Notes
====================
-Can be found [here](doc/release/smtk-21.05.rst).
+Can be found [here](doc/release/smtk-21.09.rst).
License
=======
diff --git a/data/attribute/attribute_collection/SimpleAttribute.sbt b/data/attribute/attribute_collection/SimpleAttribute.sbt
new file mode 100644
index 0000000000000000000000000000000000000000..768f04c62681dfc3c87a271938b21e23dc6d23f4
--- /dev/null
+++ b/data/attribute/attribute_collection/SimpleAttribute.sbt
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:43f373091dfadef4387c09c947bf0df4dc074149eccc34d71258d3cd9ce9b352
+size 578
diff --git a/data/attribute/attribute_collection/externalExpressionsPt1.sbt b/data/attribute/attribute_collection/externalExpressionsPt1.sbt
new file mode 100644
index 0000000000000000000000000000000000000000..700ab9aa24d8007cdf06e66296af400e925e1574
--- /dev/null
+++ b/data/attribute/attribute_collection/externalExpressionsPt1.sbt
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:7e248ed259011f0c9561d4ecda7739999b4fe8c23fd2cb1ca24f7ebe3679eff9
+size 655
diff --git a/data/attribute/attribute_collection/externalExpressionsPt2.sbt b/data/attribute/attribute_collection/externalExpressionsPt2.sbt
new file mode 100644
index 0000000000000000000000000000000000000000..aa77be233905e8728e5c9f88dbdcc6b7e1c14207
--- /dev/null
+++ b/data/attribute/attribute_collection/externalExpressionsPt2.sbt
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:762389e4f4b89efac5939a53ae6adbf9c07eaffd2115e5bdf6e58261353055d6
+size 707
diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt
index 3cab56ba9a49717244c4a736cf184d7f9ca6effe..4ce8765629f884ee319a7be5bef153d99d69204f 100644
--- a/doc/CMakeLists.txt
+++ b/doc/CMakeLists.txt
@@ -119,8 +119,11 @@ if (SPHINX_FOUND)
userguide/obtain-build-install.rst
userguide/simulation/index.rst
userguide/overview.rst
- userguide/workflow/index.rst
- userguide/workflow/concepts.rst
+ userguide/task/adaptors.rst
+ userguide/task/concepts.rst
+ userguide/task/classes.rst
+ userguide/task/index.rst
+ userguide/task/io.rst
userguide/model/index.rst
userguide/model/property-names.rst
userguide/model/sessions.rst
diff --git a/doc/conf.py b/doc/conf.py
index 4042d9b2711e764fee69366a11deaed4cd79dd88..3edbc0d0327bf59bba267753f667a62b8b591d4c 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -34,7 +34,7 @@ builddir = sys.argv[-1]
def setup(app):
# prevent stupid-wide table columns.
- app.add_stylesheet("theme-overrides.css")
+ app.add_css_file("theme-overrides.css")
def runDoxygen(rtdsrcdir, rtdblddir, doxyfileIn, doxyfileOut):
diff --git a/doc/index.rst b/doc/index.rst
index b80e6b90e4bf09e75b638d5a868751cdee3efd51..c4e3ce7d2578396d9d1686be03af4e02ac009c06 100644
--- a/doc/index.rst
+++ b/doc/index.rst
@@ -17,6 +17,7 @@ Contents:
userguide/index.rst
tutorials/index.rst
+ release/index.rst
##################
diff --git a/doc/release/index.rst b/doc/release/index.rst
new file mode 100644
index 0000000000000000000000000000000000000000..5e771a138542a0cad2ba60d72f2d6f8d09e3ec6c
--- /dev/null
+++ b/doc/release/index.rst
@@ -0,0 +1,9 @@
+=============
+Release notes
+=============
+
+.. toctree::
+ :maxdepth: 2
+
+ smtk-21.07.rst
+ smtk-21.05.rst
diff --git a/doc/release/notes/modelEntityViewChanges.rst b/doc/release/notes/modelEntityViewChanges.rst
new file mode 100644
index 0000000000000000000000000000000000000000..64a62cecd691d00746b5bdc5650cb21d8f4f878e
--- /dev/null
+++ b/doc/release/notes/modelEntityViewChanges.rst
@@ -0,0 +1,6 @@
+Changes to qtModelEntityView
+----------------------------
+
+* Selection of the Type of Attribute via the ComboBox no longer requires any button press after the selection has been made
+
+* Also addressed a bug related to the View being updated when selecting a different attribute to be assigned to the model entity. The symptom was that instead of accepting the requested type, the View would instead display "Please Select" indicating that the model entity had no attribute associated with it. The reason was due to the fact that the View was being updated via the call to removeAttribute prior to the new attribute being created. The fix was to postpone calling that method until after the new attribute was in place.
diff --git a/doc/release/smtk-21.05.rst b/doc/release/smtk-21.05.rst
index e93039cf4a7f888e7abfa32b8858f29bf2e75e0c..fbee5ab111079c58110a82342a8b5e1cdbc34497 100644
--- a/doc/release/smtk-21.05.rst
+++ b/doc/release/smtk-21.05.rst
@@ -1,3 +1,4 @@
+.. _release-notes-21.05:
========================
SMTK 21.05 Release Notes
diff --git a/doc/release/smtk-21.07.rst b/doc/release/smtk-21.07.rst
index a1bde93c3628e6b3325a0b897c2dc2c5d180ea42..93d1b4ee12ebf3e2cbdd89ee87534929db645a44 100644
--- a/doc/release/smtk-21.07.rst
+++ b/doc/release/smtk-21.07.rst
@@ -1,10 +1,10 @@
+.. _release-notes-21.07:
+
=========================
SMTK 21.07 Release Notes
=========================
-See also `SMTK 21.05 Release Notes`_ for previous changes.
-
-.. _`SMTK 21.05 Release Notes`: smtk-21.05.md
+See also :ref:`release-notes-21.05` for previous changes.
Registration Changes
====================
diff --git a/doc/release/smtk-21.09.rst b/doc/release/smtk-21.09.rst
new file mode 100644
index 0000000000000000000000000000000000000000..2ab4de624ad678c90a465eea14cdfa9c1c98e829
--- /dev/null
+++ b/doc/release/smtk-21.09.rst
@@ -0,0 +1,175 @@
+.. _release-notes-21.09:
+
+=========================
+SMTK 21.09 Release Notes
+=========================
+
+See also :ref:`release-notes-21.07` for previous changes.
+
+
+SMTK Resource and Component Changes
+===================================
+
+Supporting MarkedForRemoval
+--------------------------
+Resources can now be markedForRemoval indicating that the resource will be removed from memory (as apposed to deletion which also means it is being deleted from storage as well). This can be used in the UI to determine if a View needs to worry about keeping its contents up to date if the reason it is using is going to be removed. This also gets around a current issue with the Resource Links system which will cause a resource to be pulled back into memory even though the resources that its associated with is going to be removed.
+
+Another benefit is to potentially optimize the removal of components when its resource is targeted for removal.
+
+Developer changes
+~~~~~~~~~~~~~~~~~~
+* Added the following API to smtk::resource::Resource
+ * setMarkedForRemoval - sets the resource's marked for removal state
+ * isMarkedForRemoval - returns the resource's marked for removal state
+* UI class changes
+ * All Attribute Related Qt classes that handle operations will now check to see if the resource is marked for removal.
+
+
+Attribute Resource Changes
+==========================
+
+Changing Expression Format
+--------------------------
+JSON will now store a ValueItem's Expression in ComponentItem format using the key "ExpressionReference" instead of 2 keys called "Expression" and "ExpressionName". This no only simplifies things format wise but will also support expressions stored in different resources.
+
+**Note** The older format is still supported so this change is backward compatible.
+**Note** The XML format is still using the older style.
+
+Supporting "External" Expressions
+---------------------------------
+There are use cases where the workflow may want to store expressions in a separate Attribute Resource.
+The core of SMTK already supported this but the UI system assumed that the Attribute Resource which owned the ValueItem was also the source for expressions. This is no longer the case.
+
+qtInstancedView can now optionally take in an Attribute Resource instead of solely relying on the one associated with the UI Manager. This allows classes like the qtAttributeEditor to supply the Attribute Resource.
+
+Added a new query function called: findResourceContainingDefinition that will return an Attribute Resource that contains an Attribute Definition referred to by its typename. If the optional Attribute Resource provided to the function also contains the Definition, it is returned immediately without doing any additional searching. This maintains the original use case where the expressions are stored in the same resource.
+
+qtInputItem no longer assumes the Item's Attribute Resource is the one being used as a source for expressions.
+
+Added two template files that can be used to demo the functionality.
+
+* `data/attribute/attribute_collection/externalExpressionsPt1.sbt` - Contains an Attribute Definition with an Item that can use an expression that is not defined in that template
+
+* `data/attribute/attribute_collection/externalExpressionsPt2.sbt` - Contains an Attribute Definition that represents the expressions used in Pt1.
+
+
+Qt UI Changes
+=============
+
+Changes to qtBaseAttributeView
+------------------------------
+In the past classes derived from qtBaseAttributeView relied on the qtUIManager to get access to the Attribute Resource they depended on. This is no longer the case. The Attribute Resource is now part of the information used to defined the instance.
+
+Deprecation of qtUIManager::attResource() method
+------------------------------------------------
+This method is no longer needed for qtBaseAttributeView derived classes.
+
+Added qtItem::attributeResource() method
+----------------------------------------
+This is a convenience method for accessing the qtItem's underlying Attribute Resource
+
+Fixing qtAttributeView handling of Operations
+---------------------------------------------
+In qtAttributeView::handleOperationEvent, the code had the following issues:
+
+1. It assumed that an Attribute that is in the operation's result must be based on the View's current definition. This is only true if the View only contained one Definition. In reality, the attribute's Definition needs to be tested against the Definitions that defined the View and if it matches any of them it needs to be processed.
+2. It always assumed that there was a Current Attribute selected. This would result in a crash if there wasn't any.
+3. There was a bug in qtAttributeView::getItemFromAttribute, it was getting items from column 0 instead of the name column. This resulted in names not being properly updated
+
+Added qtAttributeView::matchesDefinitions
+-----------------------------------------
+This method tests a Definition against the Definitions that define the View and returns true if it matches or is derived from any in the list.
+
+Replacing qtBaseView::getObject()
+---------------------------------
+This method returns the instance's view::Configuration but the name didn't reflect that. Also the getObject method returned a smtk::view::ConfigurationPtr which means that a new shared pointer was always being created and as a result, incrementing its reference count. The new configuration() method returns a const smtk::view::ConfigurationPtr& instead which does not effect the shared point reference count.
+
+Developer changes
+~~~~~~~~~~~~~~~~~
+* `qtBaseView::getObject()` method is now deprecated.
+
+Added Ability to Set Attribute Editor Panel's Title
+----------------------------------------------------
+The Attribute Editor Panel name can now be configure by a smtk::view::Configuration.
+
+If the Configuration is Top Level then the following Configuration Attributes can be used:
+
+* AttributePanelTitle - defines the base name of the Panel. If not specified it defaults to Attribute Editor.
+* IncludeResourceNameInPanel - if specified and set to true, the Panel's title will include the name of the resource in ()
+
+SimpleAttribute.sbt contains an example:
+
+.. code-block:: xml
+
+
+
+
+
+
+
+
+
+Developer changes
+~~~~~~~~~~~~~~~~~~
+* `pqSMTKAttributePanel::updateTitle()` now takes in a `const smtk::view::ConfigurationPtr&` argument.
+
+
+SMTK Task Subsystem (Preview)
+=============================
+
+New Task Classes
+----------------
+The task subsystem now provides more task types, task-adaptor classes
+for configuring tasks as they change state, and additional tests.
+See the `task class documentation`_ for details.
+
+Tasks now include "style" strings that will be used to configure
+application state when the task becomes active.
+
+Tasks now include references to dependencies and dependents,
+children and a parent. These are used to provide workflow
+observers that user interfaces can use to monitor when tasks
+are added-to and removed-from a pipeline.
+
+.. _task class documentation: https://smtk.readthedocs.io/en/latest/userguide/task/classes.html
+
+Task serialization/deserialization
+----------------------------------
+The task classes and task manager now support serialization
+and deserialization (to/from JSON). See the TestTaskJSON
+test and user guide for more details.
+
+
+Other SMTK Core Changes
+=======================
+
+Using TypeContainers instead of ViewInfo
+----------------------------------------
+
+In order to make the View System more flexible and to work with the new Task System, the following changes were made:
+
+* smtk::view::Information is now derived from TypeContainer and is no longer an abstract class. As a result it can now do the job that ViewInfo and OperationViewInfo does
+* ViewInfo and OperationViewInfo are no longer needed.
+* qtBaseView's m_viewInfo is now an instance of smtk::view::Information and not ViewInfo
+
+Developer changes
+~~~~~~~~~~~~~~~~~~
+
+Unless the qtView is directly accessing m_viewInfo, there should be no required changes.
+
+When dealing with smtk::view::information, it is important that the type you insert into the container exactly matches the type you use to get information from the container. For example if you insert a QPushButton* into the container and attempt to get a QWidget* back, it will fail and throw an exception.
+
+So it is recommended you explicitly state the template type instead of having the compiler determine it. In the above example you would need to do an insert(myQtPushButton) in order to get a QWidget* back.
+
+Removed Data Structures
++++++++++++++++++++++++
+smtk::external::ViewInfo and smtk::external::OperatorViewInfo are no longer needed and have been removed. smtk::view::Information object should be used instead.
+
+
+Visibility badge improvements
+-----------------------------
+The ParaView visibility-badge extension had an issue when large numbers
+of phrase-model instances existed and a resource was closed: the visibility
+was updated by completely rebuilding the map of visible entities which
+is slow. This is now fixed.
diff --git a/doc/requirements/dev.txt b/doc/requirements/dev.txt
index fd3c0b0f03c05bdf540966db2de66cceb538ad6b..8f1ed1d4c03dc51d48515bfbacc9fa53f0585449 100644
--- a/doc/requirements/dev.txt
+++ b/doc/requirements/dev.txt
@@ -1,9 +1,9 @@
-Sphinx==2.2.1
-pyparsing==2.2.0
-Pygments==2.4.2
-actdiag==0.5.4
-blockdiag==1.5.4
+Sphinx==4.1.2
+pyparsing==2.4.7
+Pygments==2.10.0
+actdiag==2.0.0
+blockdiag==2.0.1
sphinxcontrib-actdiag==2.0.0
-sphinxcontrib-doxylink==1.6.1
-sphinx-rtd-theme==0.4.3
-breathe==4.13.1
+sphinxcontrib-doxylink==1.8
+sphinx-rtd-theme==0.5.2
+breathe==4.30.0
diff --git a/doc/smtk.doxyfile.in b/doc/smtk.doxyfile.in
index 8f8467ace6e90e0a5069b342b1b0da92d72d9827..b84db938032331168d07d946189d0ef137bc5893 100644
--- a/doc/smtk.doxyfile.in
+++ b/doc/smtk.doxyfile.in
@@ -735,6 +735,8 @@ INPUT = \
"@smtk_SOURCE_DIR@/smtk/project" \
"@smtk_SOURCE_DIR@/smtk/common" \
"@smtk_SOURCE_DIR@/smtk/task" \
+ "@smtk_SOURCE_DIR@/smtk/task/adaptor" \
+ "@smtk_SOURCE_DIR@/smtk/task/json" \
"@smtk_SOURCE_DIR@/smtk/workflow" \
"@smtk_SOURCE_DIR@/smtk/model" \
"@smtk_SOURCE_DIR@/smtk/model/operators" \
@@ -831,6 +833,8 @@ INPUT = \
"@smtk_BINARY_DIR@/smtk/project" \
"@smtk_BINARY_DIR@/smtk/common" \
"@smtk_BINARY_DIR@/smtk/task" \
+ "@smtk_BINARY_DIR@/smtk/task/adaptor" \
+ "@smtk_BINARY_DIR@/smtk/task/json" \
"@smtk_BINARY_DIR@/smtk/workflow" \
"@smtk_BINARY_DIR@/smtk/model" \
"@smtk_BINARY_DIR@/smtk/model/operators" \
diff --git a/doc/userguide/figures/task-terminology.png b/doc/userguide/figures/task-terminology.png
new file mode 100644
index 0000000000000000000000000000000000000000..8e6215ee3c7aec76d3518825a095dad9bbc11f7a
--- /dev/null
+++ b/doc/userguide/figures/task-terminology.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:b58b1f8705ff125a2f97bec04250687633da5e8f0a8f40039554a85c9eb5a4bc
+size 107702
diff --git a/doc/userguide/figures/task-terminology.svg b/doc/userguide/figures/task-terminology.svg
new file mode 100644
index 0000000000000000000000000000000000000000..857f6a053054e5cac2c54a1136793cac2106325b
--- /dev/null
+++ b/doc/userguide/figures/task-terminology.svg
@@ -0,0 +1,570 @@
+
+
diff --git a/doc/userguide/index.rst b/doc/userguide/index.rst
index bcd785c26157a0243bc9e76b047c2771dd1ebcce..f8e411fc983179dc31ba3fbe335d76543e10caa7 100644
--- a/doc/userguide/index.rst
+++ b/doc/userguide/index.rst
@@ -44,11 +44,10 @@ simulation domain.
graph/index.rst
mesh/index.rst
project/index.rst
+ task/index.rst
simulation/index.rst
view/index.rst
extension/index.rst
- task/index.rst
- workflow/index.rst
bindings/index.rst
plugin/index.rst
administration.rst
diff --git a/doc/userguide/task/adaptors.rst b/doc/userguide/task/adaptors.rst
new file mode 100644
index 0000000000000000000000000000000000000000..313c936ebb48da8feddaf2272ab9fa726e51960d
--- /dev/null
+++ b/doc/userguide/task/adaptors.rst
@@ -0,0 +1,82 @@
+.. _smtk-adaptor-classes:
+
+Guide to adaptor classes
+========================
+
+The following sections describe the different adaptor subclasses that
+exist for use in your workflows, the use cases that motivate them,
+and how to configure them.
+
+Adaptor
+-------
+
+The :smtk:`base Adaptor class` is abstract and
+cannot be instantiated on its own but does have configuration parameters
+that are common to all adaptors and must be provided:
+
+* ``id``: this is an integer identifying the adaptor.
+ Although currently unused, all adaptor JSON should provide a unique,
+ non-zero value as it may be used in the future to reference adaptors
+ during configuration.
+* ``type``: this is the fully-qualified class name of the adaptor
+ class that should be created.
+* ``from``: an integer used to identify the task which should be
+ observed and used to configure another.
+* ``to``: an integer used to identify the task which should be
+ configured when the "from" task has changed into a completable
+ or completed state.
+
+Example
+"""""""
+
+.. code:: json
+
+ {
+ "id": 1,
+ "type": "smtk::task::Adaptor",
+ "from": 1,
+ "to": 2
+ }
+
+ResourceAndRole
+---------------
+
+The :smtk:`ResourceAndRole ` adaptor
+exists to pass information from GatherResources to FillOutAttributes,
+possibly passing this information "through" Groups that have these tasks
+as children.
+When configured, only attribute resources chosen by the user will be examined
+for validity.
+
+The ResourceAndRole adaptor accepts two additional JSON configuration entries
+beyond the base Adaptor class:
+
+* ``from-tag``: this is a string used *only* when the "from" task is a Group.
+ It specifies a key in the Group's interal configuration object from which
+ to fetch data to apply to the destination task.
+ The default value is an empty string.
+* ``to-tag``: this is a string used *only* when the "to" task is a Group.
+ It specifies a key in the Group's interal configuration object to which
+ to write data that will be applied to the destination task.
+ The default value is an empty string.
+
+The Group from- and to-tag strings exist because a Group task may need
+to aggregate state from multiple child tasks or configure multiple
+child tasks separately.
+By providing the key, authors can control which child tasks share or
+do not share configuration information.
+If the default empty string is used, then all tasks will share
+the same configuration information.
+
+Example
+"""""""
+
+.. code:: json
+
+ {
+ "id": 1,
+ "type": "smtk::task::adaptor::ResourceAndRole",
+ "from": 1, /* must be a GatherResources or Group task */
+ "to": 2, /* must be a FillOutAttributes or Group task */
+ "to-tag": "foo" /* if "to" is a Group, "foo" is a key for resource+role data. */
+ }
diff --git a/doc/userguide/task/classes.rst b/doc/userguide/task/classes.rst
index b574b380dc83cbb31976cee1fb37125d430e6676..82c235abe957a9a1255e9f1b43c03930d0443b73 100644
--- a/doc/userguide/task/classes.rst
+++ b/doc/userguide/task/classes.rst
@@ -16,48 +16,215 @@ It is Completable by default.
The following JSON can be used to configure it:
* ``title``: an optional string value holding instructions to users.
+* ``style``: an optional array of strings holding presentation
+ style-class names for the task.
* ``completed``: an optional boolean value indicating whether the
user has marked the task complete or not.
-Example:
+Example
+"""""""
.. code:: json
{
"type": "smtk::task::Task",
"title": "Instructions to users.",
+ "style": [ "unique-component-colors", "fancy-menu" ],
"completed": false
}
-TaskNeedsResources
-------------------
+FillOutAttributes
+-----------------
-The :smtk:`TaskNeedsResources ` class monitors
+The :smtk:`FillOutAttributes task `
+monitors operations for attribute resources with particular roles.
+When an operation creates or modifies a matching resource, the
+task checks whether all the attributes with matching definitions
+are valid. If so, the task is Completable. If not, it is Incomplete.
+It is Completable by default (i.e., if no matching resources
+or attributes exist).
+
+This task accepts all the JSON configuration that the base Task class does, plus:
+
+* ``attribute-sets``: a JSON array of required attributes, organized by role.
+ Each array entry must be a JSON object holding:
+
+ * ``role``: an optional string holding an attribute-resource role name.
+ If omitted, any role is allowed.
+ * ``definitions``: a set of :smtk:`smtk::attribute::Definition` type-names
+ specifying which types of attributes to validate before allowing completion.
+ * ``auto-configure``: either true or false (the default), depending on
+ whether resources with matching roles should automatically be added.
+ The default is false since a task-adaptor, such as
+ :smtk:`ResourceAndRole `, will
+ normally configure only those resources identified by a user as
+ relevant in a dependent task.
+
+Example
+"""""""
+
+.. code:: json
+
+ {
+ "type": "smtk::task::FillOutAttributes",
+ "title": "Assign materials and mesh sizing.",
+ "attribute-sets": [
+ {
+ "role": "simulation attribute",
+ "definitions": ["SolidMaterial", "FluidMaterial"]
+ },
+ {
+ "role": "meshing attribute",
+ "definitions": [
+ "GlobalSizingParameters",
+ "FaceSize",
+ "EdgeSize"
+ ]
+ }
+ ]
+ }
+
+In the example above, you can see that two different attribute resources
+(one for the simulation and one for a mesh generator) are specified with
+different roles and the definitions that should be checked for resources
+in those roles are different.
+
+Group
+-----
+
+A task :smtk:`Group ` exists to collect similar or related
+child tasks together in order to organize the workflow and reduce clutter.
+The Group's state and output are dependent on its children.
+
+The Group instance is responsible for configuring its children, including
+creating dependencies among them; this is accomplished by accepting
+adaptors that link the Group to its child task and vice-versa.
+The Group provides adaptors with an "adaptor data" object where they
+can store configuration information and isolate the children from
+external tasks.
+
+The Group has a "mode," which describes how children are related to
+one another: when the mode is parallel, children have no dependency on
+one another; the parent group configures them independently.
+When the mode is serial, children must be completed in the
+order specified (i.e., each successive task is dependent on its
+predecessor) and each child task may configure its successor as
+it becomes completable.
+
+Task groups are completable by default (i.e., when no children are configured).
+If children exist, the group takes its internal state as a combination of its children's
+states:
+
+* irrelevant if all of its children are irrelevant;
+* unavailable if all of its children are unavailable;
+* incomplete if any of its children are incomplete;
+* completable if all of its relevant children are completable; and
+* completed when the user marks either it or all of its children completed.
+
+As with other task classes, the group's overall state also includes the state of
+its external dependencies.
+
+The task Group class accepts all the JSON configuration that the base Task class does, plus:
+
+* ``mode``: either ``serial`` or ``parallel``.
+* ``children``: an ordered JSON array of child task specifications.
+ Each child task may have an integer ``id`` whose value may be referenced
+ by ``adaptors`` below.
+* ``adaptors``: an array of task-adaptor specifications that inform
+ the group task how to configure children. The reserved ``id`` of 1
+ refers to the Group itself. Child tasks are numbered 2 and above.
+* ``adaptor-data``: a dictionary of key-value pairs. The keys are arbitrary strings
+ provided by adaptors and the values are serializations of configuration information
+ to be passed to child tasks from the parent or vice-versa.
+ This is not typically specified when authoring a workflow but is saved and loaded
+ when saving task state.
+
+Example
+"""""""
+
+.. code:: json
+
+ {
+ "type": "smtk::task::Group",
+ "title": "Perform the child tasks in order.",
+ "mode": "serial",
+ "children": [
+ {
+ "id": 2,
+ "type": "smtk::task::Task",
+ "title": "Step 1."
+ },
+ {
+ "id": 3,
+ "type": "smtk::task::Task",
+ "title": "Step 2."
+ }
+ ],
+ "adaptors": [
+ {
+ "//": "How the parent configures its child."
+ "type": "smtk::task::adaptor::ResourceAndRole",
+ "from-tag": "simulation",
+ "from": 1,
+ "to": 2
+ },
+ {
+ "//": "How the parent configures its child."
+ "type": "smtk::task::adaptor::ResourceAndRole",
+ "from-tag": "model",
+ "from": 1,
+ "to": 3
+ },
+ {
+ "//": "How the serial task configures its successor."
+ "type": "smtk::task::adaptor::PassComponents",
+ "from": 2,
+ "to": 3
+ },
+ {
+ "//": "How a child task configures its parent's"
+ "//": "output. Be careful to avoid loops."
+ "type": "smtk::task::adaptor::PassComponents",
+ "from": 3,
+ "to": 1
+ }
+ ]
+ }
+
+
+GatherResources
+---------------
+
+The :smtk:`GatherResources ` class monitors
a resource manager and is incomplete until its configured list of required
resources is acceptable, at which time it transitions to completable.
It is Incomplete by default unless unconfigured (in which case it is Completable).
It accepts all the JSON configuration that the base Task class does, plus:
+* ``auto-configure``: either true or false (the default), depending on whether
+ resources should be automatically pulled from the resource manager based on
+ their roles (true) or whether a user must explicitly assign resources (false).
* ``resources``: a JSON array of required resources, organized by role.
Each array entry must be a JSON object holding:
- * ``role``: an optional string holding a resource role name. If omitted, any role is allowed.
- * ``type``: an optional string holding a resource typename. If omitted, any resource type is allowed.
- * ``min``: an optional integer specifying the number of resources with the given role and type that must be present.
- Only non-negative values are accepted.
- It defaults to 1, which makes the requirement mandatory.
- If set to 0, the requirement is optional.
- * ``max``: an optional integer specifying the maximum number of resources with the given role and type allowed.
- Negative values indicate that there is no maximum.
- It defaults to -1.
- It is possible to set this to 0 to indicate that resources of a given role/type are disallowed.
+ * ``role``: an optional string holding a resource role name. If omitted, any role is allowed.
+ * ``type``: an optional string holding a resource typename. If omitted, any resource type is allowed.
+ * ``min``: an optional integer specifying the number of resources with the given role and type that must be present.
+ Only non-negative values are accepted.
+ It defaults to 1, which makes the requirement mandatory.
+ If set to 0, the requirement is optional.
+ * ``max``: an optional integer specifying the maximum number of resources with the given role and type allowed.
+ Negative values indicate that there is no maximum.
+ It defaults to -1.
+ It is possible to set this to 0 to indicate that resources of a given role/type are disallowed.
-Example:
+Example
+"""""""
.. code:: json
{
- "type": "smtk::task::TaskNeedsResources",
+ "type": "smtk::task::GatherResources",
"title": "Load a geometric model (or models) and a simulation template.",
"resources": [
{
diff --git a/doc/userguide/task/concepts.rst b/doc/userguide/task/concepts.rst
index bb933e14b29a00a26524c66a96bfa3e087f1b6b3..c23393fdbf408adf5cbfc93590a9af31ddf270cb 100644
--- a/doc/userguide/task/concepts.rst
+++ b/doc/userguide/task/concepts.rst
@@ -1,15 +1,49 @@
Key Concepts
============
+A *task* is some activity that a user must complete to accomplish
+a simulation pre- or post-processing objective (e.g., generating
+a geometric model of a simulation domain, associating attributes
+to model geometry, meshing a model, exporting a simulation input
+deck, submitting a simulation job, post-processing simulation results).
+Each task has *state* that indicates how complete it is.
+Tasks may reference other tasks as *dependencies*,
+which means the referenced tasks must be completed before
+their *dependent* tasks may be undertaken by the user.
+
The graph of tasks (with dependencies as arcs) indicates what tasks a user may
work on, what tasks are incomplete, and what tasks cannot be performed because of
unmet dependencies.
+.. findfigure:: task-terminology.*
+ :align: center
+ :width: 90%
+
+It is possible to have multiple, disjoint graphs of tasks.
+Each connected component is called a *workflow* or *pipeline*.
+
A task becomes active when its dependencies are met and the user
chooses to focus on the task.
An application can compute the set of tasks which users
are allowed to focus on (make active) by cutting the graph along arcs
that connect completed tasks to incomplete tasks.
+When a task becomes active, the application will generally change
+its appearance and functionality to aid the user in performing
+the task. The visual *style* adopted by the application should be
+guided by the style class-names (arbitrary, author-defined strings)
+assigned (by the task author) to the task.
+
+Tasks are allowed to have children.
+When a task has children, the children form a workflow with one or more
+head tasks and may not have dependencies on external tasks (i.e., on
+tasks that are not children of the same parent).
+The parent task should configure its children and its internal state
+should be some function of the state of its children.
+To work on a child task, the user must first make the parent task
+active and may then make one of the children head-tasks active.
+
+Note that a workflow may have multiple "head" tasks (i.e., tasks without
+dependencies whose dependents reference all of the head tasks).
:smtk:`State `
is an enumeration of the states a task may take on.
@@ -27,9 +61,9 @@ that connect completed tasks to incomplete tasks.
is unavailable until its dependencies are met, at which time it
will transition straight to completable.
-:smtk:`Instances `
+:smtk:`Task instance-tracker and factory `
is used to create instances of registered task classes.
- Any plugins that provide new task subclasses should
+ Any plugins that provide new Task subclasses should
register those classes with the factory in their registrar
(see :ref:`smtk-plugin-sys`).
@@ -42,7 +76,34 @@ that connect completed tasks to incomplete tasks.
thus should not be active.
This object can be observed for changes to the active task.
+:smtk:`Adaptor `
+ instances configure a dependent task when the dependency
+ changes state. This way, information provided by the user
+ can have an effect on the state and user-interface of
+ subsequent tasks.
+ You should subclass this to implement logic that determines what
+ information should be transmitted from one task to another.
+
+:smtk:`Adaptor instance-tracker and factory `
+ is used to create instances of registered adaptor classes.
+ Any plugins that provide new Adaptor subclasses should
+ register those classes with the factory in their registrar
+ (see :ref:`smtk-plugin-sys`).
+
:smtk:`Manager `
is an object applications can create to hold a task factory and
the set of task instances the factory has created.
It also holds the active task tracker.
+
+Pipelines
+ are tasks that form a directed acyclic graph of dependencies.
+ There is no explicit class representing pipelines since they
+ can be produced by visiting related (dependent) Task instances given
+ the task(s) at the "head" of the pipeline (i.e., tasks with no
+ dependencies).
+
+ Instead of providing an explicit representation of pipelines,
+ SMTK provides observers for changes to the set of pipeline head tasks.
+ The task :smtk:`Instances ` class has
+ a ``workflowObservers()`` method that you may use to be informed
+ of :smtk:`workflow events `.
diff --git a/doc/userguide/task/index.rst b/doc/userguide/task/index.rst
index c4b9aaa2ae3dee629a9c73ca19ab19616e69b9b8..638b3081a926d65dff3635b6044b7967bcc87c56 100644
--- a/doc/userguide/task/index.rst
+++ b/doc/userguide/task/index.rst
@@ -1,15 +1,23 @@
.. _smtk-task-sys:
---------------
-Workflow tasks
---------------
+------------------
+SMTK's Task System
+------------------
-SMTK provides tools to guide users through the process of preparing a simulation description.
-A workflow consists of a series of tasks that may have dependencies.
-These tasks form a graph with dependencies as arcs.
+Simulations can require input from many people with different skill sets.
+People with backgrounds in engineering; physical modeling; geometric discretization;
+numerical analysis; visualization and data analysis; statistics; and project management
+may all be involved, each with different tasks to complete.
+SMTK accommodates this range of interests and tasks by providing applications
+with ways to prompt users – especially infrequent or inexpert users – with
+suggested tasks required to complete the portion of the design process.
+
+These tasks, together with their inter-dependencies, form a
+a graph with tasks as nodes and dependencies as arcs.
.. toctree::
:maxdepth: 3
concepts.rst
classes.rst
+ adaptors.rst
diff --git a/doc/userguide/task/io.rst b/doc/userguide/task/io.rst
new file mode 100644
index 0000000000000000000000000000000000000000..b0bba9cc42f87296bb9908e2d49f983051880ba4
--- /dev/null
+++ b/doc/userguide/task/io.rst
@@ -0,0 +1,28 @@
+.. _smtk-task-io:
+
+Serialization and deserialization
+=================================
+
+Tasks are created by passing JSON configuration data;
+this constitutes the majority of deserialization.
+However, beyond configuration, deserialization involves
+connecting tasks via dependencies and potentially other
+information – such as functors and references to SMTK's
+various managers – that cannot be simply encoded into JSON.
+
+For this reason, the task manager may be serialized and
+deserialized. It uses a :smtk:`helper `
+to swizzle_ pointers to tasks
+into integer indices during serialization and adds a phase
+during deserialization that un-swizzles the integers back
+into pointers to the objects it created.
+
+Serialization also requires a functor for each class that
+examines a task and returns a JSON object with its
+full serialization.
+See :smtk:`smtk::task::json::jsonTask` for an example
+and note that subclasses of task should invoke the
+functor for their superclass rather than trying to
+reproduce its logic.
+
+.. _swizzle: https://en.wikipedia.org/wiki/Pointer_swizzling
diff --git a/doc/userguide/workflow/concepts.rst b/doc/userguide/workflow/concepts.rst
deleted file mode 100644
index 3aa7917805c33334d82a1eec53bdc928a708b4c7..0000000000000000000000000000000000000000
--- a/doc/userguide/workflow/concepts.rst
+++ /dev/null
@@ -1,15 +0,0 @@
-Key Concepts
-============
-
-Internally, SMTK represents a workflow as a directed acyclic graph.
-Nodes in the graph may be
-
-+ actions to take;
-+ conditions which must be met; or
-+ choices between acceptable actions or conditions.
-
-Edges in the graph indicate dependencies between nodes.
-
-Presenting a complete task DAG would be confusing to many users.
-Instead, we use SMTK's view presentation model to allow applications
-to tailor what is shown based on the current state.
diff --git a/doc/userguide/workflow/index.rst b/doc/userguide/workflow/index.rst
deleted file mode 100644
index 1143ad6f952aa0c1c999792e13e395ffeb96f9c2..0000000000000000000000000000000000000000
--- a/doc/userguide/workflow/index.rst
+++ /dev/null
@@ -1,22 +0,0 @@
-.. _smtk-workflow-sys:
-
-----------------------
-SMTK's Workflow System
-----------------------
-
-SMTK's workflow system is aimed at providing guidance to
-users on tasks required to complete the simulation preparation
-process.
-
-Simulations can require input from many people with different skill sets.
-People with backgrounds in engineering; physical modeling; geometric discretization;
-numerical analysis; visualization and data analysis; statistics; and project management
-may all be involved, each with different tasks to complete.
-SMTK accommodates this range of interests and tasks by providing applications
-with ways to prompt users, especially infrequent or inexpert users, with
-suggested actions.
-
-.. toctree::
- :maxdepth: 3
-
- concepts.rst
diff --git a/smtk/attribute/Item.cxx b/smtk/attribute/Item.cxx
index f690a35cd176a767042c29230a90e22e7e6fed39..c97e42749799a520cac3eb201963ce77e4bd399b 100644
--- a/smtk/attribute/Item.cxx
+++ b/smtk/attribute/Item.cxx
@@ -23,8 +23,8 @@ Item::Item(Attribute* owningAttribute, int itemPosition)
, m_owningItem(nullptr)
, m_position(itemPosition)
, m_isEnabled(true)
- , m_forceRequired(false)
, m_isIgnored(false)
+ , m_forceRequired(false)
{
m_hasLocalAdvanceLevelInfo[0] = false;
m_hasLocalAdvanceLevelInfo[1] = false;
@@ -37,8 +37,8 @@ Item::Item(Item* inOwningItem, int itemPosition, int inSubGroupPosition)
, m_position(itemPosition)
, m_subGroupPosition(inSubGroupPosition)
, m_isEnabled(true)
- , m_forceRequired(false)
, m_isIgnored(false)
+ , m_forceRequired(false)
{
m_hasLocalAdvanceLevelInfo[0] = false;
m_hasLocalAdvanceLevelInfo[1] = false;
diff --git a/smtk/attribute/json/jsonValueItem.h b/smtk/attribute/json/jsonValueItem.h
index 474c5b1d193b57f38bd901d3901aec623b070de4..ff2715a2ce7b48393d3b56ed1ebc90a732b9c827 100644
--- a/smtk/attribute/json/jsonValueItem.h
+++ b/smtk/attribute/json/jsonValueItem.h
@@ -12,8 +12,10 @@
#include "smtk/PublicPointerDefs.h"
#include "smtk/attribute/Attribute.h"
+#include "smtk/attribute/ComponentItem.h"
#include "smtk/attribute/Resource.h"
#include "smtk/attribute/ValueItem.h"
+#include "smtk/attribute/json/jsonComponentItem.h"
#include "smtk/attribute/json/jsonHelperFunction.h"
#include "smtk/attribute/json/jsonItem.h"
@@ -58,8 +60,7 @@ static void processDerivedValueToJson(json& j, ItemType itemPtr)
}
if (itemPtr->isExpression())
{
- j["Expression"] = true;
- j["ExpressionName"] = itemPtr->expression()->name();
+ j["ExpressionReference"] = itemPtr->expressionReference();
return;
}
if ((itemPtr->numberOfRequiredValues() == 1) && !itemPtr->isExtensible())
@@ -100,7 +101,7 @@ static void processDerivedValueFromJson(
const json& j,
ItemType itemPtr,
std::vector& itemExpressionInfo,
- std::vector& /*attRefInfo*/)
+ std::vector& attRefInfo)
{
auto resPtr = itemPtr->attribute()->attributeResource();
if (itemPtr->isDiscrete())
@@ -119,7 +120,18 @@ static void processDerivedValueFromJson(
{
json expression;
{
- auto query = j.find("Expression");
+ // This is the latest version for expressions
+ auto query = j.find("ExpressionReference");
+ if (query != j.end())
+ {
+ std::set convertedAttDefs;
+ ItemPtr expressionItem = itemPtr->expressionReference();
+ smtk::attribute::JsonHelperFunction::processItemTypeFromJson(
+ *query, expressionItem, itemExpressionInfo, attRefInfo, convertedAttDefs);
+ return;
+ }
+ // This is the older implementation
+ query = j.find("Expression");
if (query != j.end())
{
expression = *query;
diff --git a/smtk/attribute/utility/Queries.cxx b/smtk/attribute/utility/Queries.cxx
index d23353563993577cfdc2d74bf1488cf31ed443f1..8e6f5b33fc36c0f09c32fee060128b8d98ffeee6 100644
--- a/smtk/attribute/utility/Queries.cxx
+++ b/smtk/attribute/utility/Queries.cxx
@@ -244,6 +244,68 @@ std::set associatableObjects(
}
return checkUniquenessCondition(compItem, candidates);
}
+
+smtk::attribute::ResourcePtr findResourceContainingDefinition(
+ const std::string& defType,
+ smtk::attribute::ResourcePtr& sourceAttResource,
+ smtk::resource::ManagerPtr& resManager,
+ const smtk::common::UUID& ignoreResource)
+{
+ if (defType.empty())
+ {
+ return nullptr; // No definition was given
+ }
+
+ // Are we dealing with a source attribute resource?
+ if (sourceAttResource)
+ {
+ // Does it contain the definition?
+ if (sourceAttResource->findDefinition(defType))
+ {
+ return sourceAttResource;
+ }
+ // Are there Resources associated with the sourceAttResource?
+ if (sourceAttResource->hasAssociations())
+ {
+ auto resources = sourceAttResource->associations();
+ // Lets see if any of the resources are attribute resources
+ for (const auto& resource : resources)
+ {
+ if (resource->id() == ignoreResource)
+ {
+ continue;
+ }
+ smtk::attribute::ResourcePtr attRes =
+ std::dynamic_pointer_cast(resource);
+ if (attRes && attRes->findDefinition(defType))
+ {
+ return attRes;
+ }
+ }
+ }
+ }
+ if (resManager == nullptr) // There is no other place to search
+ {
+ return nullptr;
+ }
+ // Get all of the Attribute Resources stored in the Manager
+ auto managedResources = resManager->find(smtk::common::typeName());
+ for (const auto& resource : managedResources)
+ {
+ if (resource->id() == ignoreResource)
+ {
+ continue;
+ }
+ smtk::attribute::ResourcePtr attRes =
+ std::dynamic_pointer_cast(resource);
+ if (attRes && attRes->findDefinition(defType))
+ {
+ return attRes;
+ }
+ }
+ // Couldn't find it
+ return nullptr;
+}
} // namespace utility
} // namespace attribute
} // namespace smtk
diff --git a/smtk/attribute/utility/Queries.h b/smtk/attribute/utility/Queries.h
index d1cd54b4bd6116ec53db50bc0530f2325bb2ffc3..9ec518f834161084672aaf6cfd0b73657dce7a00 100644
--- a/smtk/attribute/utility/Queries.h
+++ b/smtk/attribute/utility/Queries.h
@@ -63,6 +63,23 @@ std::set associatableObjects(
smtk::attribute::ResourcePtr& attResource,
smtk::resource::ManagerPtr& resManager,
const smtk::common::UUID& ignoreResource = smtk::common::UUID::null());
+///\brief Find an Attribute Resource that contains an Attribute Definition type.
+///
+/// If ignoreResource is specified the corresponding resource will not participate in determining
+/// which objects can be associated. The main use case would be updating the widget because a
+/// resource is about to be removed from the system. Since it is still in memory we needed a way to ignore it.
+/// There are 3 possible sources of Attribute Resources:
+///
+/// * The sourceAttResource (if specified) contains the Definition - in that case, it is returned
+/// * One of the Attribute Resources associated with the sourceAttResource (if specified), contains the Definition
+/// * The resManager (if specified) has an Attribute Resource that contains the Definition
+/// The above is also the order of precedence in terms of the search order
+SMTKCORE_EXPORT
+smtk::attribute::ResourcePtr findResourceContainingDefinition(
+ const std::string& defType,
+ smtk::attribute::ResourcePtr& sourceAttResource,
+ smtk::resource::ManagerPtr& resManager,
+ const smtk::common::UUID& ignoreResource = smtk::common::UUID::null());
} // namespace utility
} // namespace attribute
} // namespace smtk
diff --git a/smtk/common/Deprecation.h b/smtk/common/Deprecation.h
index 9911f882847b5fd3f795d2e5e024640069f34e79..34efd77917cfdbd8f637fdc5baec3b928149d809 100644
--- a/smtk/common/Deprecation.h
+++ b/smtk/common/Deprecation.h
@@ -19,8 +19,8 @@
#define SMTK_DEPRECATION_LEVEL SMTK_VERSION_NUMBER
#endif
-// API deprecated before 21.4 have already been removed.
-#define SMTK_MINIMUM_DEPRECATION_LEVEL SMTK_VERSION_CHECK(21, 4)
+// API deprecated before 21.04 have already been removed.
+#define SMTK_MINIMUM_DEPRECATION_LEVEL SMTK_VERSION_CHECK(21, 04)
// Force the deprecation level to be at least that of SMTK's build
// configuration.
@@ -54,7 +54,19 @@
#endif
#define SMTK_DEPRECATION_REASON(version_major, version_minor, reason) \
- "SMTK Deprecated in " #version_major "." #version_minor ": " #reason
+ "SMTK Deprecated in " #version_major "." #version_minor ": " reason
+
+#if SMTK_DEPRECATION_LEVEL >= SMTK_VERSION_CHECK(21, 9)
+#define SMTK_DEPRECATED_IN_21_09(reason) SMTK_DEPRECATION(SMTK_DEPRECATION_REASON(21, 9, reason))
+#else
+#define SMTK_DEPRECATED_IN_21_09(reason)
+#endif
+
+#if SMTK_DEPRECATION_LEVEL >= SMTK_VERSION_CHECK(21, 8)
+#define SMTK_DEPRECATED_IN_21_08(reason) SMTK_DEPRECATION(SMTK_DEPRECATION_REASON(21, 8, reason))
+#else
+#define SMTK_DEPRECATED_IN_21_08(reason)
+#endif
#if SMTK_DEPRECATION_LEVEL >= SMTK_VERSION_CHECK(21, 07)
#define SMTK_DEPRECATED_IN_21_07(reason) SMTK_DEPRECATION(SMTK_DEPRECATION_REASON(21, 07, reason))
diff --git a/smtk/common/Instances.h b/smtk/common/Instances.h
index 3932bf5696c9906918350f9767e22deff3d03e04..0ab0562970094a57e709c497a091a107e2b75900 100644
--- a/smtk/common/Instances.h
+++ b/smtk/common/Instances.h
@@ -188,6 +188,9 @@ public:
return smtk::common::Visit::Continue;
}
+ /// Return the number of instances being managed.
+ std::size_t size() const { return m_instances.size(); }
+
private:
/// The container that owns managed instances.
using Container = std::set>;
diff --git a/smtk/common/TypeContainer.h b/smtk/common/TypeContainer.h
index 36f8a1ae9f26aec7babd4f989af90da23dd7e202..751e003ccc377d5fc389771d1f383e92febceefd 100644
--- a/smtk/common/TypeContainer.h
+++ b/smtk/common/TypeContainer.h
@@ -109,6 +109,7 @@ public:
}
/// Insert a Type instance into the TypeContainer.
+ /// Note that if the type already exists in the container, the insertion will fail.
template
bool insert(const Type& value)
{
@@ -123,6 +124,17 @@ public:
.second;
}
+ /// Insert a Type instance into the TypeContainer if it does not exist already or replace it if it does.
+ template
+ bool insert_or_assign(const Type& value)
+ {
+ if (this->contains())
+ {
+ this->erase();
+ }
+ return this->insert(value);
+ }
+
/// Emplace a Type instance into the TypeContainer.
template
bool emplace(Args&&... args)
diff --git a/smtk/common/VersionMacros.h b/smtk/common/VersionMacros.h
index d125be56c39b881409adc8bbc8d6c1fee01dbb2f..03cf99656a1cfef65dd1d2a63551ce37de146e58 100644
--- a/smtk/common/VersionMacros.h
+++ b/smtk/common/VersionMacros.h
@@ -15,6 +15,6 @@
#define SMTK_VERSION_CHECK(major, minor) (100ULL * (major) + (minor))
-#define SMTK_VERSION_NUMBER SMTK_VERSION_CHECK(SMTK_VERSION_MAJOR, SMTK_VERSION_MINOR)
+#define SMTK_VERSION_NUMBER SMTK_VERSION_CHECK(SMTK_VERSION_MAJOR, SMTK_VERSION_MINOR_INT)
#endif // smtk_common_VersionMacros_h
diff --git a/smtk/doc.h b/smtk/doc.h
index 53eeb9428bfdeaeffe543c2700eaa3e2909420a9..56dd6eed080f4090c29f51990636769a604b4825 100644
--- a/smtk/doc.h
+++ b/smtk/doc.h
@@ -149,6 +149,26 @@ namespace io
{
}
+/**\brief User-interface tasks.
+ *
+ */
+namespace task
+{
+/**\brief Adaptors that configure downstream tasks.
+ *
+ */
+namespace adaptor
+{
+}
+
+/**\brief JSON serialization and deserialization of tasks.
+ *
+ */
+namespace json
+{
+}
+} // namespace task
+
/**\brief workflow managment.
*
*/
diff --git a/smtk/extension/paraview/appcomponents/VisibilityBadge.cxx b/smtk/extension/paraview/appcomponents/VisibilityBadge.cxx
index c98ee0c5d7c0f39c85274af981f0dc70c1c23cae..cc15326818f699eb5cc7cc79db45f444addac00b 100644
--- a/smtk/extension/paraview/appcomponents/VisibilityBadge.cxx
+++ b/smtk/extension/paraview/appcomponents/VisibilityBadge.cxx
@@ -462,11 +462,11 @@ void VisibilityBadge::activeViewChanged(pqView* view)
void VisibilityBadge::representationAddedToActiveView(pqRepresentation* rep)
{
- auto* modelRep = dynamic_cast(rep);
- if (modelRep)
+ auto* smtkRep = dynamic_cast(rep);
+ if (smtkRep)
{
QObject::connect(
- modelRep,
+ smtkRep,
SIGNAL(componentVisibilityChanged(smtk::resource::ComponentPtr, bool)),
this,
SLOT(componentVisibilityChanged(smtk::resource::ComponentPtr, bool)));
@@ -475,21 +475,49 @@ void VisibilityBadge::representationAddedToActiveView(pqRepresentation* rep)
void VisibilityBadge::representationRemovedFromActiveView(pqRepresentation* rep)
{
- auto* modelRep = dynamic_cast(rep);
- if (modelRep)
+ auto* smtkRep = dynamic_cast(rep);
+ if (smtkRep)
{
+ auto* pipeline = dynamic_cast(smtkRep->getInput());
+ if (pipeline)
+ {
+ auto resource = pipeline->getResource();
+ // Ensure that when a representation is removed due to
+ // the resource being closed that we "forget" the visibility
+ // state of its components — otherwise, reloading the resource
+ // will result in inconsistent state.
+ if (!this->phraseModel()->root())
+ {
+ return;
+ }
+ auto rsrcPhrases = this->phraseModel()->root()->subphrases();
+ std::function updater =
+ [this, &resource, &updater](const smtk::view::DescriptivePhrase::Ptr& phrase) {
+ if (phrase && phrase->relatedResource() == resource)
+ {
+ m_visibleThings.erase(phrase->relatedObject()->id());
+ }
+ if (phrase->areSubphrasesBuilt())
+ {
+ for (const auto& child : phrase->subphrases())
+ {
+ updater(child);
+ }
+ }
+ };
+ for (const auto& rsrcPhrase : rsrcPhrases)
+ {
+ updater(rsrcPhrase);
+ }
+ // Indicate to the Qt model that it needs to refresh every row,
+ // since in theory visibility may be altered on each one:
+ this->phraseModel()->triggerDataChanged();
+ }
QObject::disconnect(
- modelRep,
+ smtkRep,
SIGNAL(componentVisibilityChanged(smtk::resource::ComponentPtr, bool)),
this,
SLOT(componentVisibilityChanged(smtk::resource::ComponentPtr, bool)));
- // Now, call activeViewChanged() to reset m_visibleThings;
- // this ensures that when a representation is removed due to
- // the resource being closed that we "forget" the visibility
- // state of its components — otherwise, reloading the resource
- // will result in inconsistent state.
- auto* view = pqActiveObjects::instance().activeView();
- this->activeViewChanged(view);
}
}
diff --git a/smtk/extension/paraview/appcomponents/pqSMTKAttributePanel.cxx b/smtk/extension/paraview/appcomponents/pqSMTKAttributePanel.cxx
index cdc7cd4bddc20f8c7aace35774936269fa282e53..6d99f0dc2cab2a1da9d5d296df46a989725f73ff 100644
--- a/smtk/extension/paraview/appcomponents/pqSMTKAttributePanel.cxx
+++ b/smtk/extension/paraview/appcomponents/pqSMTKAttributePanel.cxx
@@ -46,7 +46,7 @@ pqSMTKAttributePanel::pqSMTKAttributePanel(QWidget* parent)
: Superclass(parent)
{
this->setObjectName("attributeEditor");
- updateTitle();
+ this->updateTitle();
QWidget* w = new QWidget(this);
w->setObjectName("attributePanel");
this->setWidget(w);
@@ -159,8 +159,10 @@ bool pqSMTKAttributePanel::displayResource(const smtk::attribute::ResourcePtr& r
resetPanel(rsrc->manager());
}
}
-
- this->updateTitle();
+ else
+ {
+ this->updateTitle();
+ }
return didDisplay;
}
@@ -228,6 +230,7 @@ bool pqSMTKAttributePanel::displayResourceInternal(const smtk::attribute::Resour
{
didDisplay = this->displayView(view);
}
+ this->updateTitle(view);
auto rsrcMgr = rsrc->manager();
if (rsrcMgr)
{
@@ -312,10 +315,20 @@ void pqSMTKAttributePanel::updateSettings()
m_attrUIMgr->setHighlightOnHover(smtkSettings->GetHighlightOnHover());
}
-void pqSMTKAttributePanel::updateTitle()
+void pqSMTKAttributePanel::updateTitle(const smtk::view::ConfigurationPtr& view)
{
- auto rsrc = m_rsrc.lock();
- QString panelName = "Attribute Editor";
- QString title = rsrc ? (panelName + '(' + rsrc->name().c_str() + ')') : panelName;
- this->setWindowTitle(title);
+ // By default the Panel's name is Attribute Editor
+ std::string panelName = "Attribute Editor";
+ if (view)
+ {
+ // Lets see if the view wants a different base name
+ view->details().attribute("AttributePanelTitle", panelName);
+ // Lets see if we are suppose to add the resource name to it
+ if (view->details().attributeAsBool("IncludeResourceNameInPanel"))
+ {
+ auto rsrc = m_rsrc.lock();
+ panelName = rsrc ? (panelName + '(' + rsrc->name() + ')') : panelName;
+ }
+ }
+ this->setWindowTitle(panelName.c_str());
}
diff --git a/smtk/extension/paraview/appcomponents/pqSMTKAttributePanel.h b/smtk/extension/paraview/appcomponents/pqSMTKAttributePanel.h
index d654e9e36b61f74365c5637bb4b7b96a904e44dc..97d9e934f8928ee898d306cf9aea8957b2962eee 100644
--- a/smtk/extension/paraview/appcomponents/pqSMTKAttributePanel.h
+++ b/smtk/extension/paraview/appcomponents/pqSMTKAttributePanel.h
@@ -101,7 +101,7 @@ protected slots:
protected:
virtual bool displayResourceInternal(const smtk::attribute::ResourcePtr& rsrc);
- virtual void updateTitle();
+ virtual void updateTitle(const smtk::view::ConfigurationPtr& view = nullptr);
smtk::extension::qtUIManager* m_attrUIMgr{ nullptr };
std::weak_ptr m_rsrc;
smtk::view::SelectionPtr m_seln;
diff --git a/smtk/extension/paraview/appcomponents/pqSMTKResourceBrowser.cxx b/smtk/extension/paraview/appcomponents/pqSMTKResourceBrowser.cxx
index 9cc4c91151c7438c88462dd3b08d99d7907a0785..d24fdeb4a6534b8830142b70839923e825f83161 100644
--- a/smtk/extension/paraview/appcomponents/pqSMTKResourceBrowser.cxx
+++ b/smtk/extension/paraview/appcomponents/pqSMTKResourceBrowser.cxx
@@ -133,7 +133,7 @@ void pqSMTKResourceBrowser::resourceManagerRemoved(pqSMTKWrapper* mgr, pqServer*
void pqSMTKResourceBrowser::initSubphraseGenerator()
{
- std::string subphraseViewType = smtk::view::SubphraseGenerator::getType(m_viewInfo.m_view);
+ std::string subphraseViewType = smtk::view::SubphraseGenerator::getType(this->configuration());
auto* smtkSettings = vtkSMTKSettings::GetInstance();
int resourceTreeStyle = smtkSettings->GetResourceTreeStyle();
@@ -159,7 +159,7 @@ void pqSMTKResourceBrowser::initSubphraseGenerator()
m_p->m_resourceTreeType.empty() || m_p->m_resourceTreeType != subphraseViewType ||
(subphraseViewType == "default" && resourceTreeStyle != m_p->m_resourceTreeStyle))
{
- smtk::view::ManagerPtr manager = m_viewInfo.m_UIManager->viewManager();
+ smtk::view::ManagerPtr manager = this->uiManager()->viewManager();
smtk::view::SubphraseGenerator::Ptr spg = smtk::view::SubphraseGenerator::create(
subphraseViewType == "default" ? defaultSubphraseType : subphraseViewType, manager);
if (spg)
diff --git a/smtk/extension/paraview/appcomponents/pqSMTKResourcePanel.cxx b/smtk/extension/paraview/appcomponents/pqSMTKResourcePanel.cxx
index 777a87269f930569d64e3d746449abdb36ab7ad6..cd1fa4d1e84921064cfed7db9d4a3f5c70b53246 100644
--- a/smtk/extension/paraview/appcomponents/pqSMTKResourcePanel.cxx
+++ b/smtk/extension/paraview/appcomponents/pqSMTKResourcePanel.cxx
@@ -88,7 +88,10 @@ void pqSMTKResourcePanel::resourceManagerAdded(pqSMTKWrapper* wrapper, pqServer*
m_viewUIMgr->setSelection(wrapper->smtkSelection());
// m_viewUIMgr->setSelectionBit(1); // ToDo: should be set ?
- smtk::extension::ViewInfo resinfo(m_view, this, m_viewUIMgr);
+ smtk::view::Information resinfo;
+ resinfo.insert(m_view);
+ resinfo.insert(this);
+ resinfo.insert(m_viewUIMgr);
// the top-level "Type" in m_view should be pqSMTKResourceBrowser or compatible.
auto* baseview = m_viewUIMgr->setSMTKView(resinfo);
diff --git a/smtk/extension/paraview/operators/smtkAssignColorsView.cxx b/smtk/extension/paraview/operators/smtkAssignColorsView.cxx
index ffd17fd8b80ba4d3900f43672ff244c786f086ad..edbffe89f542c66c96595b87757904213adf1cc8 100644
--- a/smtk/extension/paraview/operators/smtkAssignColorsView.cxx
+++ b/smtk/extension/paraview/operators/smtkAssignColorsView.cxx
@@ -129,11 +129,11 @@ public:
smtk::shared_ptr CurrentOp;
};
-smtkAssignColorsView::smtkAssignColorsView(const OperationViewInfo& info)
+smtkAssignColorsView::smtkAssignColorsView(const smtk::view::Information& info)
: qtBaseAttributeView(info)
{
this->Internals = new smtkAssignColorsViewInternals;
- this->Internals->CurrentOp = info.m_operator;
+ this->Internals->CurrentOp = info.get>();
}
smtkAssignColorsView::~smtkAssignColorsView()
@@ -152,15 +152,13 @@ bool smtkAssignColorsView::displayItem(smtk::attribute::ItemPtr item) const
qtBaseView* smtkAssignColorsView::createViewWidget(const smtk::view::Information& info)
{
- const OperationViewInfo* opinfo = dynamic_cast(&info);
- smtkAssignColorsView* view;
- if (!opinfo)
+ if (qtOperationView::validateInformation(info))
{
- return nullptr;
+ auto* view = new smtkAssignColorsView(info);
+ view->buildUI();
+ return view;
}
- view = new smtkAssignColorsView(*opinfo);
- view->buildUI();
- return view;
+ return nullptr; // Information is not suitable for this View
}
QIcon smtkAssignColorsView::renderColorSwatch(const QColor& color, int radius)
@@ -260,7 +258,7 @@ void smtkAssignColorsView::prepPaletteChooser()
void smtkAssignColorsView::createWidget()
{
- smtk::view::ConfigurationPtr view = this->getObject();
+ smtk::view::ConfigurationPtr view = this->configuration();
if (!view)
{
return;
@@ -360,7 +358,7 @@ void smtkAssignColorsView::onShowCategory()
void smtkAssignColorsView::updateUI()
{
- smtk::view::ConfigurationPtr view = this->getObject();
+ smtk::view::ConfigurationPtr view = this->configuration();
if (!view || !this->Widget)
{
return;
@@ -571,5 +569,5 @@ void smtkAssignColorsView::requestModelEntityAssociation()
void smtkAssignColorsView::setInfoToBeDisplayed()
{
- m_infoDialog->displayInfo(this->getObject());
+ m_infoDialog->displayInfo(this->configuration());
}
diff --git a/smtk/extension/paraview/operators/smtkAssignColorsView.h b/smtk/extension/paraview/operators/smtkAssignColorsView.h
index 13afec5bf559dbdb4c466b10c3adb6ed7ecd96f6..48a06835a4c1d738d1d684abfdd318e735260291 100644
--- a/smtk/extension/paraview/operators/smtkAssignColorsView.h
+++ b/smtk/extension/paraview/operators/smtkAssignColorsView.h
@@ -28,11 +28,7 @@ class SMTKPQOPERATIONVIEWSPLUGIN_EXPORT smtkAssignColorsView
public:
smtkTypenameMacro(smtkAssignColorsView);
- smtkAssignColorsView(const smtk::view::Information& info)
- : smtkAssignColorsView(static_cast(info))
- {
- }
- smtkAssignColorsView(const smtk::extension::OperationViewInfo& info);
+ smtkAssignColorsView(const smtk::view::Information& info);
~smtkAssignColorsView() override;
static smtk::extension::qtBaseView* createViewWidget(const smtk::view::Information& info);
diff --git a/smtk/extension/paraview/widgets/qtSimpleExpressionEvaluationView.cxx b/smtk/extension/paraview/widgets/qtSimpleExpressionEvaluationView.cxx
index 72e5f16589203ed82068455eb859917719ed314d..e6f1fcde53541856622e5114feaaf58bb633e514 100644
--- a/smtk/extension/paraview/widgets/qtSimpleExpressionEvaluationView.cxx
+++ b/smtk/extension/paraview/widgets/qtSimpleExpressionEvaluationView.cxx
@@ -79,7 +79,7 @@ qtSimpleExpressionEvaluationView::~qtSimpleExpressionEvaluationView() = default;
void qtSimpleExpressionEvaluationView::createWidget()
{
- if (!this->getObject())
+ if (!this->configuration())
{
return;
}
@@ -90,7 +90,7 @@ void qtSimpleExpressionEvaluationView::createWidget()
// A common add/delete/(copy/paste ??) widget
QSplitter* frame = new QSplitter(this->parentWidget());
- frame->setObjectName(this->getObject()->name().c_str());
+ frame->setObjectName(this->configuration()->name().c_str());
QFrame* leftFrame = new QFrame(frame);
leftFrame->setObjectName("left");
QFrame* rightFrame = new QFrame(frame);
diff --git a/smtk/extension/qt/CMakeLists.txt b/smtk/extension/qt/CMakeLists.txt
index f933973b7575b20935f9dad5a9fcd68d8547eadb..77ab37de33ff3ca1f13f202cce2e7da656945bfa 100644
--- a/smtk/extension/qt/CMakeLists.txt
+++ b/smtk/extension/qt/CMakeLists.txt
@@ -54,7 +54,6 @@ set(QAttrLibSrcs
qtOverlay.cxx
qtTimeZoneRegionModel.cxx
qtTimeZoneSelectWidget.cxx
- qtViewInterface.cxx
qtSMTKUtilities.cxx
qtDateTimeItem.cxx
@@ -149,7 +148,6 @@ set(QAttrLibHeaders
qtSMTKUtilities.h
qtStringItem.h
qtTypeDeclarations.h
- qtViewInterface.h
qtViewRegistrar.h
)
diff --git a/smtk/extension/qt/examples/cxx/testItemFactory.cxx b/smtk/extension/qt/examples/cxx/testItemFactory.cxx
index 7f75f422bbea109cd027bef691d66303a749839f..214392f81178616eb8015e254bc1adf39f6684a4 100644
--- a/smtk/extension/qt/examples/cxx/testItemFactory.cxx
+++ b/smtk/extension/qt/examples/cxx/testItemFactory.cxx
@@ -87,7 +87,10 @@ int testLifecycle()
AttributePtr att = createAttribForTest(resource);
qtUIManager* mgr = new qtUIManager(resource);
QWidget* w = new QWidget;
- smtk::extension::ViewInfo vinfo(smtk::view::Configuration::New("base", "test view"), w, mgr);
+ smtk::view::Information vinfo;
+ vinfo.insert(smtk::view::Configuration::New("base", "test view"));
+ vinfo.insert(w);
+ vinfo.insert(mgr);
qtBaseView* v = new qtBaseView(vinfo);
qtAttribute* qatt = new qtAttribute(att, w, v);
diff --git a/smtk/extension/qt/qtAnalysisView.cxx b/smtk/extension/qt/qtAnalysisView.cxx
index 55218e3259bb2b25d3e4ee6a0b798109745df1e9..38311eb803dacc64634f9bd0b145faa44f527d76 100644
--- a/smtk/extension/qt/qtAnalysisView.cxx
+++ b/smtk/extension/qt/qtAnalysisView.cxx
@@ -12,11 +12,13 @@
#include "smtk/attribute/Attribute.h"
#include "smtk/attribute/GroupItem.h"
+#include "smtk/attribute/Item.h"
#include "smtk/attribute/StringItem.h"
#include "smtk/extension/qt/qtAttribute.h"
#include "smtk/extension/qt/qtUIManager.h"
#include "smtk/io/AttributeWriter.h"
#include "smtk/io/Logger.h"
+#include "smtk/simulation/UserData.h"
#include "smtk/view/Configuration.h"
@@ -33,15 +35,20 @@
#include
#include
+#include
using namespace smtk::attribute;
using namespace smtk::extension;
qtBaseView* qtAnalysisView::createViewWidget(const smtk::view::Information& info)
{
- qtAnalysisView* view = new qtAnalysisView(info);
- view->buildUI();
- return view;
+ if (qtBaseAttributeView::validateInformation(info))
+ {
+ auto* view = new qtAnalysisView(info);
+ view->buildUI();
+ return view;
+ }
+ return nullptr; // Information is not suitable for this View
}
qtAnalysisView::qtAnalysisView(const smtk::view::Information& info)
@@ -62,7 +69,7 @@ void qtAnalysisView::createWidget()
// If there is a previous qt analysis attribute delete it
delete m_qtAnalysisAttribute;
- smtk::view::ConfigurationPtr view = this->getObject();
+ smtk::view::ConfigurationPtr view = this->configuration();
if (!view)
{
return;
@@ -74,7 +81,7 @@ void qtAnalysisView::createWidget()
layout->setMargin(0);
this->Widget->setLayout(layout);
- auto attRes = this->uiManager()->attResource();
+ auto attRes = this->attributeResource();
std::string attName, defName;
view->details().attribute("AnalysisAttributeName", attName);
view->details().attribute("AnalysisAttributeType", defName);
@@ -94,6 +101,24 @@ void qtAnalysisView::createWidget()
attChanged = true;
}
+#if !defined(__APPLE__)
+ // This is a workaround for an unwanted scrolling behavoir that has been observed
+ // on Windows and linux builds. More details can be found at
+ // https://gitlab.kitware.com/cmb/smtk/-/issues/442
+ // The following code marks all void items in the analyis attribute with a UserData
+ // instance that is read by qtVoidItem. This is only done for analysis views.
+ std::vector items;
+ auto filter = [](smtk::attribute::Item::Ptr item) {
+ return item->type() == smtk::attribute::Item::VoidType;
+ };
+ m_analysisAttribute->filterItems(items, filter, false);
+ auto uData = smtk::simulation::UserDataInt::New();
+ for (auto& item : items)
+ {
+ item->setUserData("smtk.extensions.void_item.no_focus", uData);
+ }
+#endif
+
// OK Now lets create a qtAttribute for the Analysis Attribute
int labelWidth =
this->uiManager()->getWidthOfAttributeMaxLabel(attDef, this->uiManager()->advancedFont());
@@ -119,7 +144,7 @@ void qtAnalysisView::analysisChanged(bool attChanged)
// Lets iterate over the items in the analysis attribute and set
// the categories accordingly
std::set cats;
- auto attRes = this->uiManager()->attResource();
+ auto attRes = this->attributeResource();
if (attRes == nullptr)
{
return; // There is nothing we can do
diff --git a/smtk/extension/qt/qtAssociation2ColumnWidget.cxx b/smtk/extension/qt/qtAssociation2ColumnWidget.cxx
index 2590ca39ba4e119c2b47eb471a7ed4793f1f012c..1fb01e193e1d64007b22ccd15c05e4ab645691fe 100644
--- a/smtk/extension/qt/qtAssociation2ColumnWidget.cxx
+++ b/smtk/extension/qt/qtAssociation2ColumnWidget.cxx
@@ -88,7 +88,7 @@ qtAssociation2ColumnWidget::qtAssociation2ColumnWidget(QWidget* _p, qtBaseView*
this->initWidget();
// Are there any customizations?
- const smtk::view::Configuration::Component& config = m_view->getObject()->details();
+ const smtk::view::Configuration::Component& config = m_view->configuration()->details();
m_allAssociatedMode = config.attributeAsBool("RequireAllAssociated");
std::string val;
if (config.attribute("AvailableLabel", val))
@@ -355,6 +355,13 @@ void qtAssociation2ColumnWidget::refreshAssociations(const smtk::common::UUID& i
}
ResourcePtr attResource = attDef->resource();
+ // If this resource is marked for removal there is nothing to be done
+ if (attResource->isMarkedForRemoval())
+ {
+ m_internals->CurrentList->blockSignals(false);
+ m_internals->AvailableList->blockSignals(false);
+ return;
+ }
auto resManager = m_view->uiManager()->resourceManager();
// Lets get the objects that can possibly be associated with the attribute/definition
if (theAttribute)
diff --git a/smtk/extension/qt/qtAssociationView.cxx b/smtk/extension/qt/qtAssociationView.cxx
index f41009629e7b2e1ced30895b8305dfd38e57e161..941809a739f075768499871971deab47dd55e0b4 100644
--- a/smtk/extension/qt/qtAssociationView.cxx
+++ b/smtk/extension/qt/qtAssociationView.cxx
@@ -39,10 +39,8 @@ using namespace smtk::extension;
class qtAssociationViewInternals : public Ui::qtAssociationView
{
public:
- QList getCurrentDefs(
- smtk::extension::qtUIManager* uiManager) const
+ QList getCurrentDefs(const ResourcePtr& attResource) const
{
- auto attResource = uiManager->attResource();
if (!(attResource && attResource->activeCategoriesEnabled()))
{
// There is no filtering - return everything
@@ -69,9 +67,8 @@ public:
return defs;
}
- bool currentDefsIsEmpty(smtk::extension::qtUIManager* uiManager) const
+ bool currentDefsIsEmpty(const ResourcePtr& attResource) const
{
- auto attResource = uiManager->attResource();
if (attResource && attResource->activeCategoriesEnabled())
{
if (attResource->activeCategories().empty())
@@ -114,9 +111,13 @@ public:
qtBaseView* qtAssociationView::createViewWidget(const smtk::view::Information& info)
{
- qtAssociationView* view = new qtAssociationView(info);
- view->buildUI();
- return view;
+ if (qtBaseAttributeView::validateInformation(info))
+ {
+ auto* view = new qtAssociationView(info);
+ view->buildUI();
+ return view;
+ }
+ return nullptr; // Information is not suitable for this View
}
qtAssociationView::qtAssociationView(const smtk::view::Information& info)
@@ -149,7 +150,7 @@ void qtAssociationView::createWidget()
// since the getAllDefinitions() call needs the categories list in AttDefMap
// Create a map for all catagories so we can cluster the definitions
this->Internals->AttDefMap.clear();
- const ResourcePtr attResource = this->uiManager()->attResource();
+ const ResourcePtr attResource = this->attributeResource();
std::set::const_iterator it;
const std::set& cats = attResource->categories();
@@ -217,7 +218,7 @@ void qtAssociationView::updateUI()
}
QList currentDefs =
- this->Internals->getCurrentDefs(this->uiManager());
+ this->Internals->getCurrentDefs(this->attributeResource());
std::set atts;
// Get all of the attributes that match the list of definitions
foreach (attribute::DefinitionPtr attDef, currentDefs)
@@ -251,13 +252,13 @@ void qtAssociationView::onShowCategory()
void qtAssociationView::getAllDefinitions()
{
- smtk::view::ConfigurationPtr view = this->getObject();
+ smtk::view::ConfigurationPtr view = this->configuration();
if (!view)
{
return;
}
- smtk::attribute::ResourcePtr resource = this->uiManager()->attResource();
+ smtk::attribute::ResourcePtr resource = this->attributeResource();
std::string attName, defName, val;
smtk::attribute::AttributePtr att;
@@ -339,7 +340,7 @@ void qtAssociationView::getAllDefinitions()
// hidden at the same time.
bool qtAssociationView::isEmpty() const
{
- return this->Internals->currentDefsIsEmpty(this->uiManager());
+ return this->Internals->currentDefsIsEmpty(this->attributeResource());
}
void qtAssociationView::associationsChanged()
diff --git a/smtk/extension/qt/qtAttributeEditorDialog.cxx b/smtk/extension/qt/qtAttributeEditorDialog.cxx
index 690af18ab91068fcdc711daa2429469b41869f5f..8c6189f4532eb0c74ace9b862bfc94859a5b5992 100644
--- a/smtk/extension/qt/qtAttributeEditorDialog.cxx
+++ b/smtk/extension/qt/qtAttributeEditorDialog.cxx
@@ -48,7 +48,11 @@ qtAttributeEditorDialog::qtAttributeEditorDialog(
m_instancedViewDef->details().addChild("InstancedAttributes").addChild("Att");
child.setAttribute("Name", m_attribute->name()).setAttribute("Type", m_attribute->type());
- ViewInfo v(m_instancedViewDef, this->m_widget->attributeFrame, m_uiManager);
+ smtk::view::Information v;
+ v.insert(m_instancedViewDef);
+ v.insert(this->m_widget->attributeFrame);
+ v.insert(m_uiManager);
+ v.insert>(m_attribute->attributeResource());
qtInstancedView* iview = dynamic_cast(qtInstancedView::createViewWidget(v));
m_instancedView.reset(iview);
diff --git a/smtk/extension/qt/qtAttributeView.cxx b/smtk/extension/qt/qtAttributeView.cxx
index d6701a4467debaed5928af09b9572e5a1e7d1455..aa819370788122b4ab9c7bbc6c771d4b429a5e81 100644
--- a/smtk/extension/qt/qtAttributeView.cxx
+++ b/smtk/extension/qt/qtAttributeView.cxx
@@ -104,6 +104,7 @@ public:
// of the UI Manager and whether the View is to ignore
// categories
const QList getCurrentDefs(
+ const ResourcePtr& attResource,
smtk::extension::qtUIManager* uiManager,
bool ignoreCategories) const
{
@@ -112,7 +113,6 @@ public:
return removeAdvancedDefs(uiManager, this->AllDefs);
}
- auto attResource = uiManager->attResource();
if (!(attResource && attResource->activeCategoriesEnabled()))
{
// There are no active categories - return everything
@@ -197,9 +197,13 @@ public:
qtBaseView* qtAttributeView::createViewWidget(const smtk::view::Information& info)
{
- qtAttributeView* view = new qtAttributeView(info);
- view->buildUI();
- return view;
+ if (qtBaseAttributeView::validateInformation(info))
+ {
+ auto* view = new qtAttributeView(info);
+ view->buildUI();
+ return view;
+ }
+ return nullptr; // Information is not suitable for this View
}
qtAttributeView::qtAttributeView(const smtk::view::Information& info)
@@ -208,7 +212,7 @@ qtAttributeView::qtAttributeView(const smtk::view::Information& info)
m_internals = new qtAttributeViewInternals;
m_internals->m_alertIcon = QIcon(this->uiManager()->alertPixmap());
m_internals->m_alertSize = this->uiManager()->alertPixmap().size();
- smtk::view::ConfigurationPtr view = this->getObject();
+ smtk::view::ConfigurationPtr view = this->configuration();
m_hideAssociations = false;
m_allAssociatedMode = false;
m_disableNameField = false;
@@ -254,7 +258,7 @@ smtk::extension::qtAssociationWidget* qtAttributeView::createAssociationWidget(
void qtAttributeView::createWidget()
{
- smtk::view::ConfigurationPtr view = this->getObject();
+ smtk::view::ConfigurationPtr view = this->configuration();
if (view == nullptr)
{
return;
@@ -269,7 +273,7 @@ void qtAttributeView::createWidget()
// since the getAllDefinitions() call needs the categories list in AttDefMap
// Create a map for all categories so we can cluster the definitions
m_internals->AttDefMap.clear();
- const ResourcePtr attResource = this->uiManager()->attResource();
+ const ResourcePtr attResource = this->attributeResource();
std::set::const_iterator it;
const std::set& cats = attResource->categories();
@@ -584,7 +588,7 @@ QStandardItem* qtAttributeView::getItemFromAttribute(smtk::attribute::Attribute*
int n = m_internals->ListTableModel->rowCount();
for (int i = 0; i < n; i++)
{
- QStandardItem* item = m_internals->ListTableModel->item(i);
+ QStandardItem* item = m_internals->ListTableModel->item(i, name_column);
if (this->getRawAttributeFromItem(item) == attribute)
{
return item;
@@ -671,7 +675,7 @@ void qtAttributeView::onListBoxSelectionChanged()
if (dataItem)
{
- this->getObject()->details().setAttribute(
+ this->configuration()->details().setAttribute(
m_internals->m_activeAttributeViewAttName, dataItem->id().toString());
this->updateAssociationEnableState(dataItem);
this->updateTableWithAttribute(dataItem);
@@ -835,7 +839,7 @@ smtk::attribute::DefinitionPtr qtAttributeView::getCurrentDef() const
foreach (
attribute::DefinitionPtr attDef,
- m_internals->getCurrentDefs(this->uiManager(), m_ignoreCategories))
+ m_internals->getCurrentDefs(this->attributeResource(), this->uiManager(), m_ignoreCategories))
{
std::string txtDef = attDef->displayedTypeName();
if (strDef == QString::fromUtf8(txtDef.c_str()))
@@ -1001,7 +1005,7 @@ void qtAttributeView::onViewBy()
}
QList currentDefs =
- m_internals->getCurrentDefs(this->uiManager(), m_ignoreCategories);
+ m_internals->getCurrentDefs(this->attributeResource(), this->uiManager(), m_ignoreCategories);
m_internals->AddAction->setEnabled(currentDefs.count() > 0);
@@ -1070,10 +1074,10 @@ void qtAttributeView::onViewBy()
// so switch tabs would not reset selection
// get the active tab from the view config if it exists
std::string activeAttUuid;
- this->getObject()->details().attribute(
+ this->configuration()->details().attribute(
m_internals->m_activeAttributeViewAttName, activeAttUuid);
smtk::attribute::ConstAttributePtr activeAtt =
- this->uiManager()->attResource()->findAttribute(smtk::common::UUID(activeAttUuid));
+ this->attributeResource()->findAttribute(smtk::common::UUID(activeAttUuid));
if (activeAtt)
{
@@ -1242,13 +1246,13 @@ int qtAttributeView::currentViewBy()
void qtAttributeView::getAllDefinitions()
{
- smtk::view::ConfigurationPtr view = this->getObject();
+ smtk::view::ConfigurationPtr view = this->configuration();
if (!view)
{
return;
}
- smtk::attribute::ResourcePtr resource = this->uiManager()->attResource();
+ smtk::attribute::ResourcePtr resource = this->attributeResource();
std::string attName, defName, val, styleName;
smtk::attribute::AttributePtr att;
@@ -1396,7 +1400,7 @@ void qtAttributeView::showAdvanceLevelOverlay(bool show)
bool qtAttributeView::isEmpty() const
{
QList currentDefs =
- m_internals->getCurrentDefs(this->uiManager(), m_ignoreCategories);
+ m_internals->getCurrentDefs(this->attributeResource(), this->uiManager(), m_ignoreCategories);
return currentDefs.isEmpty();
}
@@ -1471,6 +1475,14 @@ void qtAttributeView::updateAttributeStatus(Attribute* att)
}
}
+bool qtAttributeView::matchesDefinitions(const smtk::attribute::DefinitionPtr& def) const
+{
+ return std::any_of(
+ m_internals->m_attDefinitions.begin(),
+ m_internals->m_attDefinitions.end(),
+ [=](const smtk::attribute::DefinitionPtr& viewDef) { return def->isA(viewDef); });
+}
+
int qtAttributeView::handleOperationEvent(
const smtk::operation::Operation& op,
smtk::operation::EventType event,
@@ -1497,9 +1509,10 @@ int qtAttributeView::handleOperationEvent(
std::size_t i, n;
smtk::attribute::DefinitionPtr currentDef = this->getCurrentDef();
- if (currentDef == nullptr)
+ // If there is no definition or it's attribute resource is mark for removal
+ // then we don't need to update anything
+ if ((currentDef == nullptr) || currentDef->resource()->isMarkedForRemoval())
{
- // There is nothing being displayed so nothing needs to be updated
return 0;
}
@@ -1514,43 +1527,40 @@ int qtAttributeView::handleOperationEvent(
}
auto att = dynamic_pointer_cast(compItem->value(i));
- if (att == nullptr)
+ // If there is no attribute or it's definition is not being displayed in the View - skip it
+ if (!(att && this->matchesDefinitions(att->definition())))
{
continue;
}
- smtk::attribute::DefinitionPtr attDef = att->definition();
- if (attDef->isA(currentDef))
+ // Is this the current attribute being displayed?
+ if (m_internals->CurrentAtt && (att == m_internals->CurrentAtt->attribute()))
{
- // Is this the current attribute being displayed?
- if (att == m_internals->CurrentAtt->attribute())
+ // Update the attribute's items
+ auto items = m_internals->CurrentAtt->items();
+ for (auto* item : items)
{
- // Update the attribute's items
- auto items = m_internals->CurrentAtt->items();
- for (auto* item : items)
- {
- item->updateItemData();
- }
+ item->updateItemData();
}
- // Need to update the item's name and edit ability
- auto* item = this->getItemFromAttribute(att.get());
- if (item)
+ }
+ // Need to update the item's name and edit ability
+ auto* item = this->getItemFromAttribute(att.get());
+ if (item)
+ {
+ item->setText(QString::fromUtf8(att->name().c_str()));
+ if (!this->attributeNamesConstant())
{
- item->setText(QString::fromUtf8(att->name().c_str()));
- if (!this->attributeNamesConstant())
+ // Need to see if the name is editable
+ if (
+ att->properties().contains("smtk.extensions.attribute_view.name_read_only") &&
+ att->properties().at("smtk.extensions.attribute_view.name_read_only"))
{
- // Need to see if the name is editable
- if (
- att->properties().contains("smtk.extensions.attribute_view.name_read_only") &&
- att->properties().at("smtk.extensions.attribute_view.name_read_only"))
- {
- Qt::ItemFlags itemFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
- item->setFlags(itemFlags);
- }
- else
- {
- Qt::ItemFlags itemFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable);
- item->setFlags(itemFlags);
- }
+ Qt::ItemFlags itemFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
+ item->setFlags(itemFlags);
+ }
+ else
+ {
+ Qt::ItemFlags itemFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable);
+ item->setFlags(itemFlags);
}
}
}
@@ -1570,24 +1580,20 @@ int qtAttributeView::handleOperationEvent(
}
auto att = dynamic_pointer_cast(compItem->value(i));
- if (att == nullptr)
+ // If there is no attribute or it's definition is not being displayed in the View - skip it
+ if (!(att && this->matchesDefinitions(att->definition())))
{
continue;
}
- smtk::attribute::DefinitionPtr attDef = att->definition();
- // Is this type of attribute being displayed?
- if (attDef->isA(currentDef))
+ int row, numRows = m_internals->ListTableModel->rowCount();
+ for (row = 0; row < numRows; ++row)
{
- int row, numRows = m_internals->ListTableModel->rowCount();
- for (row = 0; row < numRows; ++row)
+ QStandardItem* item = m_internals->ListTableModel->item(row, name_column);
+ smtk::attribute::Attribute* itemAtt = this->getRawAttributeFromItem(item);
+ if (att.get() == itemAtt)
{
- QStandardItem* item = m_internals->ListTableModel->item(row, name_column);
- smtk::attribute::Attribute* itemAtt = this->getRawAttributeFromItem(item);
- if (att.get() == itemAtt)
- {
- m_internals->ListTableModel->removeRow(row);
- break;
- }
+ m_internals->ListTableModel->removeRow(row);
+ break;
}
}
}
@@ -1600,15 +1606,12 @@ int qtAttributeView::handleOperationEvent(
if (compItem->isSet(i))
{
auto att = dynamic_pointer_cast(compItem->value(i));
- if (att == nullptr)
+ // If there is no attribute or it's definition is not being displayed in the View - skip it
+ if (!(att && this->matchesDefinitions(att->definition())))
{
continue;
}
- smtk::attribute::DefinitionPtr attDef = att->definition();
- if (attDef->isA(currentDef))
- {
- this->addAttributeListItem(att);
- }
+ this->addAttributeListItem(att);
}
}
return 0;
diff --git a/smtk/extension/qt/qtAttributeView.h b/smtk/extension/qt/qtAttributeView.h
index c957c2cb4696656478c69a44a8fd36a7c7b1e38f..9733542bee8c075d9ae4c75adb4e7be6e8b64b51 100644
--- a/smtk/extension/qt/qtAttributeView.h
+++ b/smtk/extension/qt/qtAttributeView.h
@@ -82,6 +82,8 @@ public:
smtk::attribute::DefinitionPtr getCurrentDef() const;
+ // Returns true if the Definition matches any of the View's Definitions
+ bool matchesDefinitions(const smtk::attribute::DefinitionPtr& def) const;
enum enumViewBy
{
VIEWBY_Attribute = 0,
diff --git a/smtk/extension/qt/qtBaseAttributeView.cxx b/smtk/extension/qt/qtBaseAttributeView.cxx
index f4d32e19e662750bf2d610f116f8d95d31771e3e..0e23274f1c6dd59a10e6282e2c3dde0913988a43 100644
--- a/smtk/extension/qt/qtBaseAttributeView.cxx
+++ b/smtk/extension/qt/qtBaseAttributeView.cxx
@@ -75,15 +75,21 @@ public:
QPointer m_configurationLabel;
};
+bool qtBaseAttributeView::validateInformation(const smtk::view::Information& info)
+{
+ return qtBaseView::validateInformation(info) &&
+ info.contains>();
+}
+
qtBaseAttributeView::qtBaseAttributeView(const smtk::view::Information& info)
: qtBaseView(info)
, m_topLevelCanCreateConfigurations(false)
{
this->Internals = new qtBaseAttributeViewInternals;
m_ScrollArea = nullptr;
- m_fixedLabelWidth = m_viewInfo.m_UIManager->maxValueLabelLength();
+ m_fixedLabelWidth = this->uiManager()->maxValueLabelLength();
m_topLevelInitialized = false;
- m_ignoreCategories = m_viewInfo.m_view->details().attributeAsBool("IgnoreCategories");
+ m_ignoreCategories = this->configuration()->details().attributeAsBool("IgnoreCategories");
// We need to be able to determine within the a Signal Operation, which View caused
// the change in order to avoid infinite loops. To do this, each View will have an addressString
// set to its address. This string is then passed to the signalAttribute function when needed.
@@ -97,6 +103,11 @@ qtBaseAttributeView::~qtBaseAttributeView()
delete this->Internals;
}
+smtk::attribute::ResourcePtr qtBaseAttributeView::attributeResource() const
+{
+ return m_viewInfo.get>().lock();
+}
+
void qtBaseAttributeView::getDefinitions(
smtk::attribute::DefinitionPtr attDef,
QList& defs)
@@ -139,7 +150,7 @@ bool qtBaseAttributeView::displayItemDefinition(
{
return false;
}
- auto attResoure = this->uiManager()->attResource();
+ auto attResoure = this->attributeResource();
return attResoure->passActiveCategoryCheck(idef->categories());
}
@@ -549,10 +560,10 @@ void qtBaseAttributeView::makeTopLevel()
this->qtBaseView::makeTopLevel();
m_topLevelInitialized = true;
- smtk::view::ConfigurationPtr view = this->getObject();
+ smtk::view::ConfigurationPtr view = this->configuration();
this->Internals->clearWidgets();
- const attribute::ResourcePtr attResource = this->uiManager()->attResource();
+ const attribute::ResourcePtr attResource = this->attributeResource();
this->topLevelPrepAdvanceLevels(view);
this->topLevelPrepConfigurations(view, attResource);
@@ -634,7 +645,7 @@ void qtBaseAttributeView::showAdvanceLevel(int level)
return;
}
- smtk::view::ConfigurationPtr view = this->getObject();
+ smtk::view::ConfigurationPtr view = this->configuration();
if (!view)
{
return;
@@ -723,7 +734,7 @@ bool qtBaseAttributeView::isEmpty() const
void qtBaseAttributeView::onConfigurationChanged(int index)
{
std::set cats;
- smtk::attribute::ResourcePtr attRes = this->uiManager()->attResource();
+ smtk::attribute::ResourcePtr attRes = this->attributeResource();
smtk::attribute::AttributePtr att;
std::string attName;
@@ -783,7 +794,7 @@ void qtBaseAttributeView::onConfigurationChanged(int index)
void qtBaseAttributeView::prepConfigurationComboBox(const std::string& newConfigurationName)
{
std::set cats;
- smtk::attribute::ResourcePtr attRes = this->uiManager()->attResource();
+ smtk::attribute::ResourcePtr attRes = this->attributeResource();
smtk::attribute::DefinitionPtr def = m_topLevelConfigurationDef.lock();
if (def == nullptr)
{
diff --git a/smtk/extension/qt/qtBaseAttributeView.h b/smtk/extension/qt/qtBaseAttributeView.h
index e45ff38513d9210dae4ab89d6961d76fb0088fda..4a745062f17b315b10f449461061e33c2b4f728b 100644
--- a/smtk/extension/qt/qtBaseAttributeView.h
+++ b/smtk/extension/qt/qtBaseAttributeView.h
@@ -64,6 +64,12 @@ public:
void setIgnoreCategories(bool mode);
bool ignoreCategories() const { return m_ignoreCategories; }
+ /// Return the attribute resource used by this View
+ smtk::attribute::ResourcePtr attributeResource() const;
+
+ // Validates the view information to see if it is suitable for creating a qtAttributeBaseView instance
+ static bool validateInformation(const smtk::view::Information& info);
+
signals:
void modified(smtk::attribute::ItemPtr);
diff --git a/smtk/extension/qt/qtBaseView.cxx b/smtk/extension/qt/qtBaseView.cxx
index 46acff7c06da33a262afbaff233ee31630ef01a0..6b418003e0890ff8bb1aa6c6383b39f157f47b59 100644
--- a/smtk/extension/qt/qtBaseView.cxx
+++ b/smtk/extension/qt/qtBaseView.cxx
@@ -28,17 +28,24 @@
using namespace smtk::extension;
-qtBaseView::qtBaseView(const ViewInfo& info)
+bool qtBaseView::validateInformation(const smtk::view::Information& info)
+{
+ return info.contains() && info.contains() &&
+ info.contains();
+}
+
+qtBaseView::qtBaseView(const smtk::view::Information& info)
{
m_viewInfo = info;
this->Widget = nullptr;
m_advOverlayVisible = false;
m_isTopLevel = false;
m_useSelectionManager = false;
- if (m_viewInfo.m_view)
+ const auto& view = this->configuration();
+ if (view)
{
- m_isTopLevel = m_viewInfo.m_view->details().attributeAsBool("TopLevel");
- m_useSelectionManager = m_viewInfo.m_view->details().attributeAsBool("UseSelectionManager");
+ m_isTopLevel = view->details().attributeAsBool("TopLevel");
+ m_useSelectionManager = view->details().attributeAsBool("UseSelectionManager");
}
}
@@ -49,7 +56,7 @@ qtBaseView::~qtBaseView()
void qtBaseView::makeTopLevel()
{
- smtk::view::ConfigurationPtr view = this->getObject();
+ smtk::view::ConfigurationPtr view = this->configuration();
if (!view)
{
return;
@@ -111,5 +118,5 @@ void qtBaseView::onInfo()
void qtBaseView::setInfoToBeDisplayed()
{
- m_infoDialog->displayInfo(this->getObject());
+ m_infoDialog->displayInfo(this->configuration());
}
diff --git a/smtk/extension/qt/qtBaseView.h b/smtk/extension/qt/qtBaseView.h
index f0eb154e1103abac8694f1496abc458c3f3263d8..1c21e1b304577fda6ab8e0a4a38d7ad90952a438 100644
--- a/smtk/extension/qt/qtBaseView.h
+++ b/smtk/extension/qt/qtBaseView.h
@@ -18,6 +18,7 @@
#include "smtk/PublicPointerDefs.h"
#include "smtk/SharedFromThis.h"
+#include "smtk/common/Deprecation.h"
#include "smtk/extension/qt/Exports.h"
#include "smtk/extension/qt/qtViewInfoDialog.h"
#include "smtk/view/BaseView.h"
@@ -33,37 +34,6 @@ class qtUIManager;
class qtItem;
class qtViewInfoDialog;
-// This struct is used to initialize qtView-based classes
-class SMTKQTEXT_EXPORT ViewInfo : public smtk::view::Information
-{
-public:
- ViewInfo(smtk::view::ConfigurationPtr view, QWidget* parent, qtUIManager* uiman)
- : m_view(view)
- , m_parent(parent)
- , m_UIManager(uiman)
- {
- }
-
- // ViewInfo(smtk::view::ConfigurationPtr view, QWidget* parent, qtUIManager* uiman,
- // const std::map& layoutDict)
- // : m_view(view)
- // , m_parent(parent)
- // , m_UIManager(uiman)
- // , m_layoutDict(layoutDict)
- // {
- // }
-
- ViewInfo() = default;
- ~ViewInfo() override = default;
-
- const smtk::view::Configuration* configuration() const override { return m_view.get(); }
-
- smtk::view::ConfigurationPtr m_view; // View Definition
- QWidget* m_parent; // Parent Widget of the View
- qtUIManager* m_UIManager; // UI Manager
- // std::map m_layoutDict; // Widget Layout Dictionary
-};
-
///\brief A base class for all view types implemented using Qt
class SMTKQTEXT_EXPORT qtBaseView
: public QObject
@@ -81,18 +51,22 @@ public:
smtkTypenameMacro(qtBaseView);
- qtBaseView(const ViewInfo& info);
- qtBaseView(const smtk::view::Information& info)
- : qtBaseView(dynamic_cast(info))
- {
- }
+ qtBaseView(const smtk::view::Information& info);
~qtBaseView() override;
- smtk::view::ConfigurationPtr getObject() const { return m_viewInfo.m_view; }
+ SMTK_DEPRECATED_IN_21_09("Method has been replaced by qtBaseView::configuration")
+ smtk::view::ConfigurationPtr getObject() const { return this->configuration(); }
+ const smtk::view::ConfigurationPtr& configuration() const
+ {
+ return m_viewInfo.get();
+ }
+
QWidget* widget() const { return this->Widget; }
- QWidget* parentWidget() const { return m_viewInfo.m_parent; }
- qtUIManager* uiManager() const { return m_viewInfo.m_UIManager; }
+
+ QWidget* parentWidget() const { return m_viewInfo.get(); }
+
+ qtUIManager* uiManager() const { return m_viewInfo.get(); }
virtual int advanceLevel() const { return 0; }
virtual bool categoryEnabled() const { return false; }
@@ -113,6 +87,9 @@ public:
///\brief Return true if the view's contents are valid.
virtual bool isValid() const { return true; }
+ // Validates the view information to see if it is suitable for creating a qtBaseView instance
+ static bool validateInformation(const smtk::view::Information& info);
+
signals:
void aboutToDestroy();
void modified();
@@ -150,7 +127,7 @@ protected:
QWidget* Widget;
bool m_isTopLevel;
bool m_useSelectionManager;
- ViewInfo m_viewInfo;
+ smtk::view::Information m_viewInfo;
QPointer m_infoDialog;
bool m_advOverlayVisible;
}; // class
diff --git a/smtk/extension/qt/qtCategorySelectorView.cxx b/smtk/extension/qt/qtCategorySelectorView.cxx
index 72faca772dd7c932b3e31d082189330cdbf2ce2a..5831ae501c957dd2cd3653f437fe8309639dc269 100644
--- a/smtk/extension/qt/qtCategorySelectorView.cxx
+++ b/smtk/extension/qt/qtCategorySelectorView.cxx
@@ -48,9 +48,13 @@ public:
qtBaseView* qtCategorySelectorView::createViewWidget(const smtk::view::Information& info)
{
- qtCategorySelectorView* view = new qtCategorySelectorView(info);
- view->buildUI();
- return view;
+ if (qtBaseAttributeView::validateInformation(info))
+ {
+ auto* view = new qtCategorySelectorView(info);
+ view->buildUI();
+ return view;
+ }
+ return nullptr; // Information is not suitable for this View
}
qtCategorySelectorView::qtCategorySelectorView(const smtk::view::Information& info)
@@ -67,7 +71,7 @@ qtCategorySelectorView::~qtCategorySelectorView()
void qtCategorySelectorView::createWidget()
{
- smtk::view::ConfigurationPtr view = this->getObject();
+ smtk::view::ConfigurationPtr view = this->configuration();
if (!view)
{
return;
@@ -83,8 +87,8 @@ void qtCategorySelectorView::createWidget()
bool qtCategorySelectorView::createChildren()
{
- smtk::view::ConfigurationPtr view = this->getObject();
- smtk::attribute::ResourcePtr resource = this->uiManager()->attResource();
+ smtk::view::ConfigurationPtr view = this->configuration();
+ smtk::attribute::ResourcePtr resource = this->attributeResource();
int viewsIndex;
viewsIndex = view->details().findChild("Views");
@@ -125,10 +129,10 @@ bool qtCategorySelectorView::createChildren()
continue;
}
// Setup the information for the new child view based off of
- // this one
- smtk::extension::ViewInfo vinfo = m_viewInfo;
- vinfo.m_view = v;
- vinfo.m_parent = this->Widget;
+ // this one but with a different view configuration and (parent) widget
+ auto vinfo = m_viewInfo;
+ vinfo.insert_or_assign(v);
+ vinfo.insert_or_assign(this->Widget);
qtView = this->uiManager()->createView(vinfo);
if (qtView)
{
@@ -144,11 +148,11 @@ void qtCategorySelectorView::getChildView(const std::string& viewType, QListInternals->ChildViews)
{
- if (childView->getObject()->type() == viewType)
+ if (childView->configuration()->type() == viewType)
{
views.append(childView);
}
- else if (childView->getObject()->type() == "Group")
+ else if (childView->configuration()->type() == "Group")
{
qobject_cast(childView)->getChildView(viewType, views);
}
@@ -171,7 +175,7 @@ void qtCategorySelectorView::addChildView(qtBaseView* child, const std::string&
this->Internals->ChildViews.append(child);
this->Internals->m_viewCategories.append(cval);
QFrame* frame = dynamic_cast(this->Widget);
- if (!frame || !child || !child->getObject())
+ if (!frame || !child || !child->configuration())
{
return;
}
diff --git a/smtk/extension/qt/qtDiscreteValueEditor.cxx b/smtk/extension/qt/qtDiscreteValueEditor.cxx
index b4df9d3b66f3df971d87a3ddc0f4fe8b78fe1f8c..ceb7f3412e149001141a866d2f41049a6d01a0ce 100644
--- a/smtk/extension/qt/qtDiscreteValueEditor.cxx
+++ b/smtk/extension/qt/qtDiscreteValueEditor.cxx
@@ -86,12 +86,8 @@ qtDiscreteValueEditor::~qtDiscreteValueEditor()
void qtDiscreteValueEditor::createWidget()
{
+ smtk::attribute::ResourcePtr attResource = this->Internals->m_inputItem->attributeResource();
auto* uiManager = this->Internals->m_inputItem->uiManager();
- smtk::attribute::ResourcePtr attResource;
- if (uiManager)
- {
- attResource = uiManager->attResource();
- }
smtk::attribute::ValueItemPtr item = this->Internals->m_inputItem->itemAs();
if (!item)
@@ -321,9 +317,11 @@ void qtDiscreteValueEditor::updateContents()
{
auto* uiManager = this->Internals->m_inputItem->uiManager();
if (uiManager == nullptr)
+ {
return;
+ }
- smtk::attribute::ResourcePtr attResource = uiManager->attResource();
+ smtk::attribute::ResourcePtr attResource = this->Internals->m_inputItem->attributeResource();
this->Internals->clearChildItems();
@@ -373,14 +371,10 @@ void qtDiscreteValueEditor::updateContents()
auto* iiview = this->Internals->m_inputItem->m_itemInfo.baseView();
int currentLen = iiview ? iiview->fixedLabelWidth() : 0;
- if (this->Internals->m_inputItem->uiManager())
+ int tmpLen = uiManager->getWidthOfItemsMaxLabel(activeChildDefs, uiManager->advancedFont());
+ if (iiview)
{
- int tmpLen = this->Internals->m_inputItem->uiManager()->getWidthOfItemsMaxLabel(
- activeChildDefs, this->Internals->m_inputItem->uiManager()->advancedFont());
- if (iiview)
- {
- iiview->setFixedLabelWidth(tmpLen);
- }
+ iiview->setFixedLabelWidth(tmpLen);
}
bool hasVisibleChildren = false;
for (i = 0; i < m; i++)
@@ -407,7 +401,7 @@ void qtDiscreteValueEditor::updateContents()
comp,
this->Internals->m_childrenFrame.data(),
this->Internals->m_inputItem->m_itemInfo.baseView());
- childItem = this->Internals->m_inputItem->uiManager()->createItem(info);
+ childItem = uiManager->createItem(info);
}
if (childItem)
{
diff --git a/smtk/extension/qt/qtGroupView.cxx b/smtk/extension/qt/qtGroupView.cxx
index 3be1e46834ce1ab07d56136f536cf8fd55c97cc1..078122f0605eab203ec4ce9c9bf7957cbaf55d17 100644
--- a/smtk/extension/qt/qtGroupView.cxx
+++ b/smtk/extension/qt/qtGroupView.cxx
@@ -97,7 +97,7 @@ void qtGroupViewInternals::updateChildren(qtGroupView* gview, qtBaseViewMemFn mf
tabWidget->blockSignals(true);
tabWidget->clear();
std::string lastSavedViewName;
- gview->getObject()->details().attribute(m_activeTabViewAttNamee, lastSavedViewName);
+ gview->configuration()->details().attribute(m_activeTabViewAttNamee, lastSavedViewName);
m_TabbedViews.clear();
m_currentTabSelected = -1;
int i, size = m_ChildViews.size();
@@ -111,13 +111,13 @@ void qtGroupViewInternals::updateChildren(qtGroupView* gview, qtBaseViewMemFn mf
}
m_PageWidgets.at(i)->show();
m_TabbedViews.append(child);
- if (child->getObject()->name() == lastSavedViewName)
+ if (child->configuration()->name() == lastSavedViewName)
{
m_currentTabSelected = m_TabbedViews.size() - 1;
}
if (m_PageIcons.at(i).isNull())
{
- QString secTitle = child->getObject()->label().c_str();
+ QString secTitle = child->configuration()->label().c_str();
if (child->isValid())
{
tabWidget->addTab(m_PageWidgets.at(i), secTitle);
@@ -152,9 +152,13 @@ void qtGroupViewInternals::updateChildren(qtGroupView* gview, qtBaseViewMemFn mf
qtBaseView* qtGroupView::createViewWidget(const smtk::view::Information& info)
{
- qtGroupView* view = new qtGroupView(info);
- view->buildUI();
- return view;
+ if (qtBaseAttributeView::validateInformation(info))
+ {
+ auto* view = new qtGroupView(info);
+ view->buildUI();
+ return view;
+ }
+ return nullptr; // Information is not suitable for this View
}
qtGroupView::qtGroupView(const smtk::view::Information& info)
@@ -164,7 +168,7 @@ qtGroupView::qtGroupView(const smtk::view::Information& info)
QPixmap image = this->uiManager()->alertPixmap();
QTransform transform;
std::string val;
- auto view = this->getObject();
+ auto view = this->configuration();
transform.scale(0.5, 0.5);
if (view)
{
@@ -206,21 +210,21 @@ void qtGroupView::updateCurrentTab(int ithTab)
if (ithTab == -1)
{
//Clear the active tab info since nothing is selected
- this->getObject()->details().setAttribute(m_internals->m_activeTabViewAttNamee, "");
+ this->configuration()->details().setAttribute(m_internals->m_activeTabViewAttNamee, "");
return;
}
qtBaseView* currView = this->getChildView(ithTab);
if (currView)
{
- this->getObject()->details().setAttribute(
- m_internals->m_activeTabViewAttNamee, currView->getObject()->name());
+ this->configuration()->details().setAttribute(
+ m_internals->m_activeTabViewAttNamee, currView->configuration()->name());
currView->updateUI();
}
}
void qtGroupView::createWidget()
{
- smtk::view::ConfigurationPtr view = this->getObject();
+ smtk::view::ConfigurationPtr view = this->configuration();
if (!view)
{
return;
@@ -257,7 +261,7 @@ void qtGroupView::createWidget()
QTabWidget* tab = new QTabWidget(this->parentWidget());
// If we have previously created a widget for this view
// lets get the name of the last selected tab View name
- this->getObject()->details().attribute(
+ this->configuration()->details().attribute(
m_internals->m_activeTabViewAttNamee, m_internals->m_savedViewName);
tab->setUsesScrollButtons(true);
this->Widget = tab;
@@ -280,7 +284,7 @@ void qtGroupView::createWidget()
smtk::view::Configuration::Component& viewsComp = view->details().child(viewsIndex);
std::size_t i, n = viewsComp.numberOfChildren();
smtk::view::ConfigurationPtr v;
- smtk::attribute::ResourcePtr resource = this->uiManager()->attResource();
+ smtk::attribute::ResourcePtr resource = this->attributeResource();
qtBaseView* qtView;
for (i = 0; i < n; i++)
@@ -304,9 +308,10 @@ void qtGroupView::createWidget()
}
// Setup the information for the new child view based off of
// this one
- smtk::extension::ViewInfo vinfo = m_viewInfo;
- vinfo.m_view = v;
- vinfo.m_parent = this->Widget;
+ auto vinfo = m_viewInfo;
+ vinfo.insert_or_assign(v);
+ vinfo.insert_or_assign(this->Widget);
+ vinfo.insert_or_assign>(resource);
qtView = this->uiManager()->createView(vinfo);
if (qtView)
{
@@ -325,8 +330,8 @@ void qtGroupView::createWidget()
qtBaseView* currView = this->getChildView(m_internals->m_currentTabSelected);
if (currView)
{
- m_internals->m_savedViewName = currView->getObject()->name();
- this->getObject()->details().setAttribute(
+ m_internals->m_savedViewName = currView->configuration()->name();
+ this->configuration()->details().setAttribute(
m_internals->m_activeTabViewAttNamee, m_internals->m_savedViewName);
}
}
@@ -430,7 +435,7 @@ void qtGroupView::showAdvanceLevelOverlay(bool show)
void qtGroupView::addTabEntry(qtBaseView* child)
{
QTabWidget* tabWidget = dynamic_cast(this->Widget);
- if (!tabWidget || !child || !child->getObject())
+ if (!tabWidget || !child || !child->configuration())
{
return;
}
@@ -441,7 +446,7 @@ void qtGroupView::addTabEntry(qtBaseView* child)
QScrollArea* tabPage = new QScrollArea(tabWidget);
tabPage->setWidgetResizable(true);
tabPage->setFrameShape(QFrame::NoFrame);
- QString secTitle = child->getObject()->label().c_str();
+ QString secTitle = child->configuration()->label().c_str();
QString name = "tab" + QString(secTitle);
tabPage->setObjectName(name);
tabPage->setWidget(content);
@@ -454,7 +459,7 @@ void qtGroupView::addTabEntry(qtBaseView* child)
//using the ui label name find if we have an icon resource
QString resourceName = QApplication::applicationDirPath().append("/../Resources/Icons/");
//QString resourceName = ":/SimBuilder/Icons/";
- resourceName.append(child->getObject()->iconName().c_str());
+ resourceName.append(child->configuration()->iconName().c_str());
resourceName.append(".png");
// If user specified icons are not found, use default ones
@@ -504,7 +509,7 @@ void qtGroupView::addTabEntry(qtBaseView* child)
m_internals->m_TabbedViews.append(child);
tabWidget->setTabToolTip(index, secTitle);
- if (child->getObject()->name() == m_internals->m_savedViewName)
+ if (child->configuration()->name() == m_internals->m_savedViewName)
{
m_internals->m_currentTabSelected = index;
}
@@ -549,14 +554,14 @@ void qtGroupView::childModified()
void qtGroupView::addGroupBoxEntry(qtBaseView* child)
{
QFrame* frame = dynamic_cast(this->Widget);
- if (!frame || !child || !child->getObject())
+ if (!frame || !child || !child->configuration())
{
return;
}
QObject::connect(child, &qtBaseView::modified, this, &qtGroupView::childModified);
smtk::extension::qtCollapsibleGroupWidget* gw = new qtCollapsibleGroupWidget(frame);
this->Widget->layout()->addWidget(gw);
- gw->setName(child->getObject()->label().c_str());
+ gw->setName(child->configuration()->label().c_str());
gw->contentsLayout()->addWidget(child->widget());
gw->collapse();
}
@@ -564,12 +569,12 @@ void qtGroupView::addGroupBoxEntry(qtBaseView* child)
void qtGroupView::addTileEntry(qtBaseView* child)
{
QFrame* frame = dynamic_cast(this->Widget);
- if (!frame || !child || !child->getObject())
+ if (!frame || !child || !child->configuration())
{
return;
}
QObject::connect(child, &qtBaseView::modified, this, &qtGroupView::childModified);
- QLabel* label = new QLabel(child->getObject()->label().c_str(), this->Widget);
+ QLabel* label = new QLabel(child->configuration()->label().c_str(), this->Widget);
m_internals->m_Labels.append(label);
QFont titleFont;
titleFont.setBold(true);
diff --git a/smtk/extension/qt/qtInputsItem.cxx b/smtk/extension/qt/qtInputsItem.cxx
index e66f153508ab88135e3f778141b3acb3d438a9c0..7a3b7b72cc7cbff6a284b3b6f7593b87d0941caa 100644
--- a/smtk/extension/qt/qtInputsItem.cxx
+++ b/smtk/extension/qt/qtInputsItem.cxx
@@ -11,12 +11,14 @@
#include "smtk/extension/qt/qtInputsItem.h"
#include "smtk/attribute/Definition.h"
+#include "smtk/attribute/utility/Queries.h"
#include "smtk/extension/qt/qtAttributeEditorDialog.h"
#include "smtk/extension/qt/qtBaseAttributeView.h"
#include "smtk/extension/qt/qtDiscreteValueEditor.h"
#include "smtk/extension/qt/qtDoubleLineEdit.h"
#include "smtk/extension/qt/qtOverlay.h"
#include "smtk/extension/qt/qtUIManager.h"
+#include "smtk/io/Logger.h"
#include
#include
@@ -1188,19 +1190,31 @@ void qtInputsItem::displayExpressionWidget(bool checkstate)
}
auto inputitem = m_itemInfo.itemAs();
- ResourcePtr lAttResource = inputitem->attribute()->attributeResource();
-
if (!inputitem)
{
return;
}
+ ResourcePtr sourceAttResource = inputitem->attribute()->attributeResource();
+
if (checkstate)
{
m_internals->m_expressionCombo->blockSignals(true);
m_internals->m_expressionCombo->clear();
auto valItemDef = inputitem->definitionAs();
- smtk::attribute::DefinitionPtr attDef = valItemDef->expressionDefinition(lAttResource);
+ // Lets find the attribute resource that contains the expression information
+ ResourcePtr lAttResource = smtk::attribute::utility::findResourceContainingDefinition(
+ valItemDef->expressionType(), sourceAttResource, this->uiManager()->resourceManager());
+ if (lAttResource == nullptr)
+ {
+ smtkErrorMacro(
+ smtk::io::Logger::instance(),
+ " Could not find any AttributeResource containing Expressions of Type: "
+ << valItemDef->expressionType());
+ return;
+ }
+ smtk::attribute::DefinitionPtr attDef =
+ lAttResource->findDefinition(valItemDef->expressionType());
QStringList attNames;
int setIndex = 0;
@@ -1312,6 +1326,12 @@ void qtInputsItem::onExpressionReferenceChanged()
{
return;
}
+ smtk::attribute::ResourcePtr sourceAttResource = inputitem->attribute()->attributeResource();
+ auto valItemDef = inputitem->definitionAs();
+ // Lets find the attribute resource that contains the expression information
+ ResourcePtr lAttResource = smtk::attribute::utility::findResourceContainingDefinition(
+ valItemDef->expressionType(), sourceAttResource, this->uiManager()->resourceManager());
+
smtk::attribute::ComponentItemPtr item = inputitem->expressionReference();
if (!item)
{
@@ -1326,8 +1346,6 @@ void qtInputsItem::onExpressionReferenceChanged()
}
else if (curIdx == 1)
{
- smtk::attribute::ResourcePtr lAttResource = item->attribute()->attributeResource();
- auto valItemDef = inputitem->definitionAs();
smtk::attribute::DefinitionPtr attDef = valItemDef->expressionDefinition(lAttResource);
smtk::attribute::AttributePtr newAtt = lAttResource->createAttribute(attDef->type());
auto* editor =
@@ -1372,7 +1390,6 @@ void qtInputsItem::onExpressionReferenceChanged()
}
else
{
- smtk::attribute::ResourcePtr lAttResource = item->attribute()->attributeResource();
AttributePtr attPtr =
lAttResource->findAttribute(m_internals->m_expressionCombo->currentText().toStdString());
if (inputitem->isSet() && attPtr == inputitem->expression())
diff --git a/smtk/extension/qt/qtInstancedView.cxx b/smtk/extension/qt/qtInstancedView.cxx
index 908e8b1ec8bfe9902f33ed4d02cc101db0ca2bba..06a4e40a0b93c1ed422372fbbe777cf4c8e5e1c3 100644
--- a/smtk/extension/qt/qtInstancedView.cxx
+++ b/smtk/extension/qt/qtInstancedView.cxx
@@ -55,9 +55,13 @@ public:
qtBaseView* qtInstancedView::createViewWidget(const smtk::view::Information& info)
{
- qtInstancedView* view = new qtInstancedView(info);
- view->buildUI();
- return view;
+ if (qtBaseAttributeView::validateInformation(info))
+ {
+ auto* view = new qtInstancedView(info);
+ view->buildUI();
+ return view;
+ }
+ return nullptr; // Information is not suitable for this View
}
qtInstancedView::qtInstancedView(const smtk::view::Information& info)
@@ -81,7 +85,7 @@ qtInstancedView::~qtInstancedView()
void qtInstancedView::createWidget()
{
- if (!this->getObject())
+ if (!this->configuration())
{
return;
}
@@ -96,7 +100,7 @@ void qtInstancedView::createWidget()
}
this->Widget = new QFrame(this->parentWidget());
- this->Widget->setObjectName(this->getObject()->name().c_str());
+ this->Widget->setObjectName(this->configuration()->name().c_str());
//create the layout for the tabs area
QVBoxLayout* layout = new QVBoxLayout(this->Widget);
layout->setMargin(0);
@@ -130,13 +134,13 @@ void qtInstancedView::onShowCategory()
void qtInstancedView::updateUI()
{
- smtk::view::ConfigurationPtr view = this->getObject();
+ smtk::view::ConfigurationPtr view = this->configuration();
if (!view)
{
return;
}
- smtk::attribute::ResourcePtr resource = this->uiManager()->attResource();
+ smtk::attribute::ResourcePtr resource = this->attributeResource();
std::string attName, defName;
smtk::attribute::AttributePtr att;
smtk::attribute::DefinitionPtr attDef;
@@ -287,7 +291,11 @@ int qtInstancedView::handleOperationEvent(
smtk::operation::EventType event,
smtk::operation::Operation::Result result)
{
- if (event != smtk::operation::EventType::DID_OPERATE)
+ // If the operation did not execute or if the view's
+ // attribute resource is marked for removal, just return
+ if (
+ (event != smtk::operation::EventType::DID_OPERATE) ||
+ this->attributeResource()->isMarkedForRemoval())
{
return 0;
}
diff --git a/smtk/extension/qt/qtInstancedView.h b/smtk/extension/qt/qtInstancedView.h
index 56a109af1507ed1d92e192511ca937a76f279884..d14034b72a411c28157221efb0dfe18b1717af24 100644
--- a/smtk/extension/qt/qtInstancedView.h
+++ b/smtk/extension/qt/qtInstancedView.h
@@ -35,6 +35,9 @@ class SMTKQTEXT_EXPORT qtInstancedView : public qtBaseAttributeView
public:
smtkTypenameMacro(qtInstancedView);
+ ///\brief Create an instance view using an optionally specified attribute resource instead of the one
+ /// associated with the UI Manager
+
static qtBaseView* createViewWidget(const smtk::view::Information& info);
qtInstancedView(const smtk::view::Information& info);
diff --git a/smtk/extension/qt/qtItem.cxx b/smtk/extension/qt/qtItem.cxx
index fff67ed07951ba4ba2df93e7490aa7d8b476cc05..1866ab9bab92d14354e6c4244155af114ec1cc8e 100644
--- a/smtk/extension/qt/qtItem.cxx
+++ b/smtk/extension/qt/qtItem.cxx
@@ -52,6 +52,11 @@ qtItem::~qtItem()
delete this->Internals;
}
+smtk::attribute::ResourcePtr qtItem::attributeResource() const
+{
+ return m_itemInfo.baseView()->attributeResource();
+}
+
void qtItem::markForDeletion()
{
// Disconnect this object's signals
@@ -135,7 +140,7 @@ void qtItem::showAdvanceLevelOverlay(bool show)
int idx = std::distance(levels.begin(), it) - 1;
this->Internals->AdvLevelCombo->setCurrentIndex(idx);
}
- const double* rgba = m_itemInfo.uiManager()->attResource()->advanceLevelColor(mylevel);
+ const double* rgba = this->attributeResource()->advanceLevelColor(mylevel);
if (rgba)
{
this->Internals->advOverlay->overlay()->setColor(
@@ -172,7 +177,7 @@ void qtItem::setLocalAdvanceLevel(unsigned int l)
item->setLocalAdvanceLevel(1, l);
if (this->Internals->advOverlay)
{
- const double* rgba = m_itemInfo.uiManager()->attResource()->advanceLevelColor(l);
+ const double* rgba = this->attributeResource()->advanceLevelColor(l);
if (rgba)
{
this->Internals->advOverlay->overlay()->setColor(
diff --git a/smtk/extension/qt/qtItem.h b/smtk/extension/qt/qtItem.h
index a604612799e6be3a5a90de20d6fed4f071f676ad..ec6b6bcb9cf4d69439fdc7f4c755b6332d08af07 100644
--- a/smtk/extension/qt/qtItem.h
+++ b/smtk/extension/qt/qtItem.h
@@ -68,6 +68,9 @@ public:
qtUIManager* uiManager() const { return m_itemInfo.uiManager(); }
+ /// Return the underlying Attribute Resource
+ smtk::attribute::ResourcePtr attributeResource() const;
+
QPointer widget() { return m_widget; }
QPointer parentWidget() { return m_itemInfo.parentWidget(); }
diff --git a/smtk/extension/qt/qtModelEntityAttributeView.cxx b/smtk/extension/qt/qtModelEntityAttributeView.cxx
index ae411115ee31b392d09f72e282d1452ea35ebc7e..711665cc17f8c989b70238314f44da7c42dc0072 100644
--- a/smtk/extension/qt/qtModelEntityAttributeView.cxx
+++ b/smtk/extension/qt/qtModelEntityAttributeView.cxx
@@ -66,7 +66,12 @@ QWidget* qModelEntityAttributeViewComboBoxItemDelegate::createEditor(
{
auto* cbox = new QComboBox(parent);
cbox->addItems(m_values);
- connect(cbox, SIGNAL(currentIndexChanged(int)), this, SIGNAL(choiceMade()));
+ // We want the combo box to immediately display when chosen and
+ // to immediately closed when a value has been selected
+ connect(cbox, static_cast(&QComboBox::activated), [=]() {
+ // This event will be captured by the delegate eventFilter()
+ QApplication::sendEvent(cbox, new QKeyEvent(QEvent::KeyPress, Qt::Key_Enter, Qt::NoModifier));
+ });
return cbox;
}
@@ -78,7 +83,7 @@ void qModelEntityAttributeViewComboBoxItemDelegate::setEditorData(
if (cb != nullptr)
{
// Lets find the proper index of the current value w/r the combobox
- auto currentText = index.data(Qt::EditRole).toString();
+ auto currentText = index.data(Qt::DisplayRole).toString();
int pos = cb->findText(currentText);
if (pos >= 0)
{
@@ -101,13 +106,9 @@ void qModelEntityAttributeViewComboBoxItemDelegate::setModelData(
{
if (cb->currentIndex() > -1)
{
- model->setData(index, cb->currentText(), Qt::EditRole);
+ model->setData(index, cb->currentText(), Qt::DisplayRole);
model->setData(index, qtUIManager::contrastWithText(Qt::white), Qt::BackgroundRole);
}
- //QApplication::postEvent(model, new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_Enter, Qt::NoModifier));
- emit const_cast(this)->choiceMade();
- emit const_cast(this)->destroyEditor(
- editor, index);
}
else
{
@@ -115,15 +116,32 @@ void qModelEntityAttributeViewComboBoxItemDelegate::setModelData(
}
}
+bool qModelEntityAttributeViewComboBoxItemDelegate::eventFilter(QObject* object, QEvent* event)
+{
+ // Show combo box popup when the box gains focus
+ if (event->type() == QEvent::FocusIn)
+ {
+ auto* combo_box = qobject_cast(object);
+ auto* focus_event = dynamic_cast(event);
+ if (
+ combo_box && focus_event &&
+ // Do not consider focus gained when the popup closes
+ focus_event->reason() != Qt::PopupFocusReason)
+ {
+ combo_box->showPopup();
+ }
+ }
+
+ return QStyledItemDelegate::eventFilter(object, event);
+}
+
class qtModelEntityAttributeViewInternals
{
public:
~qtModelEntityAttributeViewInternals() { delete this->CurrentAtt; }
- const QList getCurrentDefs(
- smtk::extension::qtUIManager* uiManager) const
+ const QList getCurrentDefs(const ResourcePtr& attResource) const
{
- auto attResource = uiManager->attResource();
if (!(attResource && attResource->activeCategoriesEnabled()))
{
// There are no active categories - return everything
@@ -196,9 +214,13 @@ public:
qtBaseView* qtModelEntityAttributeView::createViewWidget(const smtk::view::Information& info)
{
// TO DO Need to deal with Selections
- qtModelEntityAttributeView* view = new qtModelEntityAttributeView(info);
- view->buildUI();
- return view;
+ if (qtBaseAttributeView::validateInformation(info))
+ {
+ auto* view = new qtModelEntityAttributeView(info);
+ view->buildUI();
+ return view;
+ }
+ return nullptr; // Information is not suitable for this View
}
qtModelEntityAttributeView::qtModelEntityAttributeView(const smtk::view::Information& info)
@@ -257,14 +279,14 @@ qtModelEntityAttributeView::attDefinitionMap() const
void qtModelEntityAttributeView::createWidget()
{
- auto view = this->getObject();
+ auto view = this->configuration();
if (view == nullptr)
{
return;
}
this->Internals->AttDefMap.clear();
- const ResourcePtr attResource = this->uiManager()->attResource();
+ const ResourcePtr attResource = this->attributeResource();
std::set::const_iterator it;
const std::set& cats = attResource->categories();
@@ -367,7 +389,7 @@ std::set qtModelEntityAttributeView::associ
std::set result;
// First we need to determine if the attribute resource has resources associated with it
// if not we need to go to resource manager to get the information
- auto attResource = this->uiManager()->attResource();
+ auto attResource = this->attributeResource();
auto resources = attResource->associations();
if (!resources.empty())
{
@@ -444,7 +466,7 @@ void qtModelEntityAttributeView::updateModelEntities()
}
QList currentDefs =
- this->Internals->getCurrentDefs(this->uiManager());
+ this->Internals->getCurrentDefs(this->attributeResource());
// Create an initial string list for the combo boxes
QStringList slist;
@@ -461,7 +483,6 @@ void qtModelEntityAttributeView::updateModelEntities()
auto* col2Delegate =
new qModelEntityAttributeViewComboBoxItemDelegate(slist, this->Internals->ListTable);
- connect(col2Delegate, SIGNAL(choiceMade()), this, SLOT(selectionMade()));
this->Internals->ListTable->blockSignals(true);
this->Internals->ListTable->setRowCount(0);
this->Internals->ListTable->setItemDelegateForColumn(1, col2Delegate);
@@ -530,7 +551,7 @@ void qtModelEntityAttributeView::cellChanged(int row, int column)
// Get selected type
std::string tname = this->Internals->ListTable->item(row, 1)->text().toStdString();
- auto attRes = this->uiManager()->attResource();
+ auto attRes = this->attributeResource();
auto resManager = this->uiManager()->resourceManager();
if (resManager == nullptr)
{
@@ -538,7 +559,7 @@ void qtModelEntityAttributeView::cellChanged(int row, int column)
}
QList currentDefs =
- this->Internals->getCurrentDefs(this->uiManager());
+ this->Internals->getCurrentDefs(this->attributeResource());
// Get the component of the item
auto entity = this->object(this->Internals->ListTable->item(row, 0));
if (entity == nullptr)
@@ -548,16 +569,19 @@ void qtModelEntityAttributeView::cellChanged(int row, int column)
}
// Get the current attribute associated with the model entity (if any)
- auto att = this->Internals->getAttribute(entity);
- if (att && att->definition()->displayedTypeName() == tname)
+ smtk::attribute::AttributePtr exisitingAtt = this->Internals->getAttribute(entity);
+ smtk::attribute::AttributePtr newAtt;
+ if (exisitingAtt && exisitingAtt->definition()->displayedTypeName() == tname)
{
// The attribute itself didn't change, so we can stop here
return;
}
- else if (att)
+ else if (exisitingAtt)
{
- attRes->removeAttribute(att);
- this->attributeRemoved(att);
+ // Note though we are removing the attribute from the resource here, we can't call
+ // attributeRemoved until after we have created it's replacement since it will
+ // cause the view to update.
+ attRes->removeAttribute(exisitingAtt);
}
// Now create a new attribute for the model entity of the correct type
@@ -566,13 +590,17 @@ void qtModelEntityAttributeView::cellChanged(int row, int column)
{
if (currentDefs.at(j)->displayedTypeName() == tname)
{
- att = attRes->createAttribute(currentDefs.at(j));
- att->associate(entity);
+ newAtt = attRes->createAttribute(currentDefs.at(j));
+ newAtt->associate(entity);
// Notify the application of the new attribute via an "operation"
- this->attributeCreated(att);
+ this->attributeCreated(newAtt);
break;
}
}
+ if (exisitingAtt)
+ {
+ this->attributeRemoved(exisitingAtt);
+ }
this->Internals->ListTable->selectRow(row);
this->selectedRowChanged();
}
@@ -699,13 +727,13 @@ void qtModelEntityAttributeView::displayAttribute(smtk::attribute::AttributePtr
void qtModelEntityAttributeView::getAllDefinitions()
{
- smtk::view::ConfigurationPtr view = this->getObject();
+ smtk::view::ConfigurationPtr view = this->configuration();
if (!view)
{
return;
}
- smtk::attribute::ResourcePtr resource = this->uiManager()->attResource();
+ smtk::attribute::ResourcePtr resource = this->attributeResource();
std::string attName, defName, val;
smtk::attribute::AttributePtr att;
@@ -789,19 +817,9 @@ void qtModelEntityAttributeView::showAdvanceLevelOverlay(bool show)
}
}
-void qtModelEntityAttributeView::selectionMade()
-{
- if (this->Internals->ListTable)
- {
- QApplication::postEvent(
- this->Internals->ListTable,
- new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_Enter, Qt::NoModifier));
- }
-}
-
bool qtModelEntityAttributeView::isEmpty() const
{
QList currentDefs =
- this->Internals->getCurrentDefs(this->uiManager());
+ this->Internals->getCurrentDefs(this->attributeResource());
return currentDefs.isEmpty();
}
diff --git a/smtk/extension/qt/qtModelEntityAttributeView.h b/smtk/extension/qt/qtModelEntityAttributeView.h
index 16f3b620510049c6a8357801bee46531c85b39a0..d76c4722a6a610ec19b7471e2eb6eec06c90a212 100644
--- a/smtk/extension/qt/qtModelEntityAttributeView.h
+++ b/smtk/extension/qt/qtModelEntityAttributeView.h
@@ -100,9 +100,6 @@ protected:
/**\brief Return a presistent object that cooresponds to a table widget item.*/
smtk::resource::PersistentObjectPtr object(QTableWidgetItem* item);
-protected slots:
- void selectionMade();
-
private:
qtModelEntityAttributeViewInternals* Internals;
@@ -123,10 +120,8 @@ public:
void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index)
const override;
-signals:
- void choiceMade();
-
protected:
+ bool eventFilter(QObject* object, QEvent* event) override;
QStringList m_values;
};
diff --git a/smtk/extension/qt/qtOperationView.cxx b/smtk/extension/qt/qtOperationView.cxx
index 323843dd4f31fb55a9b5eb43f9b12b8fa091cc6c..ed0bd84a110af50e1637d76ca55c0a3ec4b2416b 100644
--- a/smtk/extension/qt/qtOperationView.cxx
+++ b/smtk/extension/qt/qtOperationView.cxx
@@ -42,7 +42,6 @@ public:
, m_activeOperations(0)
{
}
- smtk::operation::OperationPtr m_operator;
std::unique_ptr m_instancedView;
smtk::view::ConfigurationPtr m_instancedViewDef;
QPointer m_applyButton;
@@ -52,28 +51,31 @@ public:
std::atomic m_activeOperations;
};
+bool qtOperationView::validateInformation(const smtk::view::Information& info)
+{
+ return qtBaseAttributeView::validateInformation(info) &&
+ info.contains();
+}
+
qtBaseView* qtOperationView::createViewWidget(const smtk::view::Information& info)
{
- const OperationViewInfo* opinfo = dynamic_cast(&info);
- qtOperationView* view;
- if (!opinfo)
+ if (qtOperationView::validateInformation(info))
{
- return nullptr;
+ auto* view = new qtOperationView(info);
+ view->buildUI();
+ return view;
}
- view = new qtOperationView(*opinfo);
- view->buildUI();
- return view;
+ return nullptr; // Information is not suitable for this View
}
-qtOperationView::qtOperationView(const OperationViewInfo& info)
+qtOperationView::qtOperationView(const smtk::view::Information& info)
: qtBaseAttributeView(info)
, m_applied(false)
{
this->Internals = new qtOperationViewInternals;
- this->Internals->m_operator = info.m_operator;
// We need to create a new View for the internal instanced View
this->Internals->m_instancedViewDef = smtk::view::Configuration::New("Instanced", "Parameters");
- smtk::view::ConfigurationPtr view = this->getObject();
+ smtk::view::ConfigurationPtr view = this->configuration();
if (view)
{
this->Internals->m_instancedViewDef->copyContents(*view);
@@ -90,7 +92,7 @@ qtOperationView::qtOperationView(const OperationViewInfo& info)
view->details().setAttribute("FilterByCategory", "false");
}
}
- if (auto manager = this->Internals->m_operator->manager())
+ if (auto manager = this->operation()->manager())
{
auto* launcher = manager->launchers()[qtOperationLauncher::type_name].target();
if (launcher == nullptr)
@@ -115,9 +117,9 @@ QPointer qtOperationView::applyButton() const
return this->Internals->m_applyButton;
}
-smtk::operation::OperationPtr qtOperationView::operation() const
+const smtk::operation::OperationPtr& qtOperationView::operation() const
{
- return this->Internals->m_operator;
+ return m_viewInfo.get();
}
void qtOperationView::showInfoButton(bool visible)
@@ -183,7 +185,12 @@ void qtOperationView::createWidget()
QVBoxLayout* layout = new QVBoxLayout(this->Widget);
layout->setMargin(0);
this->Widget->setLayout(layout);
- ViewInfo v(this->Internals->m_instancedViewDef, this->Widget, this->uiManager());
+
+ // Create the information to create an Instance View
+ smtk::view::Information v = m_viewInfo;
+ v.insert_or_assign(this->Internals->m_instancedViewDef);
+ v.insert_or_assign(this->Widget);
+
qtInstancedView* iview = dynamic_cast(qtInstancedView::createViewWidget(v));
this->Internals->m_instancedView.reset(iview);
@@ -270,15 +277,16 @@ void qtOperationView::requestModelEntityAssociation()
void qtOperationView::setInfoToBeDisplayed()
{
- m_infoDialog->displayInfo(this->Internals->m_operator->parameters());
+ m_infoDialog->displayInfo(this->operation()->parameters());
}
void qtOperationView::onOperate()
{
if ((!m_applied) && this->Internals->m_instancedView->isValid())
{
+ const auto& myOperation = this->operation();
shared_ptr handler =
- (*this->Internals->m_launcher)(this->Internals->m_operator);
+ (*this->Internals->m_launcher)(myOperation);
connect(
handler.get(),
@@ -286,7 +294,7 @@ void qtOperationView::onOperate()
this,
&qtOperationView::operationExecuted);
- emit this->operationRequested(this->Internals->m_operator);
+ emit this->operationRequested(myOperation);
if (this->Internals->m_applyButton)
{ // The button may disappear when a session is closed by an operator.
this->Internals->m_applyButton->setEnabled(false);
diff --git a/smtk/extension/qt/qtOperationView.h b/smtk/extension/qt/qtOperationView.h
index 4c72f5c9590d6776c0bd91df915c0abd5ddc6d04..2903eb84468b64664e3d9bcd66a3177ac2e8f86f 100644
--- a/smtk/extension/qt/qtOperationView.h
+++ b/smtk/extension/qt/qtOperationView.h
@@ -30,30 +30,6 @@ namespace smtk
{
namespace extension
{
-class SMTKQTEXT_EXPORT OperationViewInfo : public ViewInfo
-{
-public:
- OperationViewInfo(
- smtk::view::ConfigurationPtr view,
- smtk::operation::OperationPtr targetOperation,
- QWidget* parent,
- qtUIManager* uiman)
- : ViewInfo(view, parent, uiman)
- , m_operator(targetOperation)
- {
- }
-
- // OperationViewInfo(smtk::view::ConfigurationPtr view,
- // smtk::operation::OperationPtr targetOperation, QWidget* parent, qtUIManager* uiman,
- // const std::map& layoutDict)
- // : ViewInfo(view, parent, uiman, layoutDict)
- // , m_operator(targetOperation)
- // {
- // }
-
- OperationViewInfo() = default;
- smtk::operation::OperationPtr m_operator;
-};
class SMTKQTEXT_EXPORT qtOperationView : public qtBaseAttributeView
{
@@ -64,16 +40,12 @@ public:
static qtBaseView* createViewWidget(const smtk::view::Information& info);
- qtOperationView(const smtk::view::Information& info)
- : qtOperationView(static_cast(info))
- {
- }
+ qtOperationView(const smtk::view::Information& info);
- qtOperationView(const OperationViewInfo& info);
~qtOperationView() override;
QPointer applyButton() const;
- smtk::operation::OperationPtr operation() const;
+ const smtk::operation::OperationPtr& operation() const;
void showInfoButton(bool visible = true);
// Replaces default buttons, for embedding operation view in other widgets.
@@ -83,6 +55,9 @@ public:
QPointer infoButton,
QPointer doneButton);
+ // Validates the view information to see if it is suitable for creating a qtOperationView instance
+ static bool validateInformation(const smtk::view::Information& info);
+
public slots:
void updateUI() override;
void showAdvanceLevelOverlay(bool show) override;
diff --git a/smtk/extension/qt/qtReferenceItem.h b/smtk/extension/qt/qtReferenceItem.h
index eef104c0387d347bab5e045b00ead085ef55ffbe..bcdf73447595c64ed79c015d11df1d70b432b9ae 100644
--- a/smtk/extension/qt/qtReferenceItem.h
+++ b/smtk/extension/qt/qtReferenceItem.h
@@ -124,7 +124,7 @@ protected slots:
protected:
/**\brief Subclasses override this to create a model of the appropriate type.
*
- * The model should be configured using information the item (this->getObject())
+ * The model should be configured using information the item (this->configuration())
* and be ready for use.
*/
virtual smtk::view::PhraseModelPtr createPhraseModel() const;
diff --git a/smtk/extension/qt/qtReferenceItemEditor.cxx b/smtk/extension/qt/qtReferenceItemEditor.cxx
index 1ba8b8e6fd40f0d1674a877c11c7812faba03051..b33cd1e1e0f9d0735c4f17d501a1a800029e3bf5 100644
--- a/smtk/extension/qt/qtReferenceItemEditor.cxx
+++ b/smtk/extension/qt/qtReferenceItemEditor.cxx
@@ -665,6 +665,14 @@ void qtReferenceItemEditor::handleResourceEvent(
auto theAttribute = item->attribute();
auto attResource = theAttribute->attributeResource();
+ // If this resource is marked for removal, then we don't need to update this widget since
+ // it should be deleted shortly - this will also prevent the resource's links system from
+ // pulling in associated resources unnecessarily
+ if (attResource->isMarkedForRemoval())
+ {
+ return;
+ }
+
if ((event == smtk::resource::EventType::REMOVED) && (attResource->id() != resource.id()))
{
// The simplest solution is just to refresh the widget
@@ -743,9 +751,11 @@ void qtReferenceItemEditor::updateContents()
{
auto* uiManager = this->uiManager();
if (uiManager == nullptr)
+ {
return;
+ }
- smtk::attribute::ResourcePtr attResource = uiManager->attResource();
+ smtk::attribute::ResourcePtr attResource = this->attributeResource();
// First clear all of the current children items being displayed
m_internals->clearChildItems();
diff --git a/smtk/extension/qt/qtResourceBrowser.cxx b/smtk/extension/qt/qtResourceBrowser.cxx
index 3e47af0f4c319d87e7035fb97fdb12c76633f779..7409af4d00c4c1e3d978797ebcda9f38e618b786 100644
--- a/smtk/extension/qt/qtResourceBrowser.cxx
+++ b/smtk/extension/qt/qtResourceBrowser.cxx
@@ -57,9 +57,13 @@ std::string qtResourceBrowser::s_configurationJSON = ResourcePanelConfiguration_
qtBaseView* qtResourceBrowser::createViewWidget(const smtk::view::Information& info)
{
- qtResourceBrowser* view = new qtResourceBrowser(info);
- view->buildUI();
- return view;
+ if (qtBaseView::validateInformation(info))
+ {
+ auto* view = new qtResourceBrowser(info);
+ view->buildUI();
+ return view;
+ }
+ return nullptr; // Information is not suitable for this View
}
qtResourceBrowser::qtResourceBrowser(const smtk::view::Information& info)
@@ -69,15 +73,16 @@ qtResourceBrowser::qtResourceBrowser(const smtk::view::Information& info)
smtk::view::PhraseModelPtr phraseModel;
std::string modelViewType;
QAbstractItemModel* qtPhraseModel = nullptr;
- if (m_viewInfo.m_view)
+ const auto& view = this->configuration();
+ if (view)
{
// empty Widget attribute is OK, will use default.
- m_viewInfo.m_view->details().attribute("Widget", modelViewType);
- smtk::view::ManagerPtr manager = m_viewInfo.m_UIManager->viewManager();
- phraseModel = manager->phraseModelFactory().createFromConfiguration(m_viewInfo.configuration());
+ view->details().attribute("Widget", modelViewType);
+ smtk::view::ManagerPtr manager = this->uiManager()->viewManager();
+ phraseModel = manager->phraseModelFactory().createFromConfiguration(view.get());
qtPhraseModel = new smtk::extension::qtDescriptivePhraseModel;
}
- m_p->setup(this, phraseModel, modelViewType, qtPhraseModel, m_viewInfo.m_parent);
+ m_p->setup(this, phraseModel, modelViewType, qtPhraseModel, this->parentWidget());
this->Widget = m_p->m_container;
}
diff --git a/smtk/extension/qt/qtResourceBrowser.h b/smtk/extension/qt/qtResourceBrowser.h
index 4aeeb493a9e35dd904a99dae887a95c5967db7a5..64b201d4126a7175356ced5538be3931f7c51149 100644
--- a/smtk/extension/qt/qtResourceBrowser.h
+++ b/smtk/extension/qt/qtResourceBrowser.h
@@ -35,7 +35,7 @@ class qtDescriptivePhraseModel;
* This contains Qt widget that displays a tree or list view holding an SMTK
* descriptive phrase model.
*
- * Its ViewInfo should be initialized with json/xml that contains:
+ * Its Information should be initialized with json/xml that contains:
* (1) an smtk::view::PhraseModel that you have configured,
* (2) the string name registered to a QAbstractItemView subclass constructor,
* (3) a QAbstactItemModel implementing qtDescriptivePhraseModel model index queries, and
diff --git a/smtk/extension/qt/qtResourceItem.cxx b/smtk/extension/qt/qtResourceItem.cxx
index fe2d6bb24f3b10e7a041b0367343801e9aeb4cf9..ff083982420e3fad13df51536dacf2c4f92178fe 100644
--- a/smtk/extension/qt/qtResourceItem.cxx
+++ b/smtk/extension/qt/qtResourceItem.cxx
@@ -97,7 +97,7 @@ smtk::view::PhraseModelPtr qtResourceItem::createPhraseModel() const
// auto phraseModel = smtk::view::ResourcePhraseModel::create(config);
auto phraseModel =
m_itemInfo.uiManager()->viewManager()->phraseModelFactory().createFromConfiguration(
- m_itemInfo.baseView()->getObject().get());
+ m_itemInfo.baseView()->configuration().get());
if (
!phraseModel ||
!m_p->m_phraseModel->badges().findBadgeOfType())
diff --git a/smtk/extension/qt/qtSMTKUtilities.h b/smtk/extension/qt/qtSMTKUtilities.h
index 01ea4c6ba0a60678e8f39d1e178053c1cb2577f5..a57298a8852b91069437f70005d6ebde7f5db9ff 100644
--- a/smtk/extension/qt/qtSMTKUtilities.h
+++ b/smtk/extension/qt/qtSMTKUtilities.h
@@ -11,8 +11,7 @@
#define __smtk_attribute_qtSMTKUtilities_h
#include "smtk/extension/qt/Exports.h"
-#include "smtk/extension/qt/qtUIManager.h" // for qtItemConstructor definition
-#include "smtk/extension/qt/qtViewInterface.h" // for qtSMTKViewConstructor definition
+#include "smtk/extension/qt/qtUIManager.h" // for qtItemConstructor definition
#include
diff --git a/smtk/extension/qt/qtSelectorView.cxx b/smtk/extension/qt/qtSelectorView.cxx
index f28070c4634f4d821e042b3e86a73954143a5257..58f8bce7c64580aecb2bf8bed49a74aee0e24c7d 100644
--- a/smtk/extension/qt/qtSelectorView.cxx
+++ b/smtk/extension/qt/qtSelectorView.cxx
@@ -52,9 +52,13 @@ public:
qtBaseView* qtSelectorView::createViewWidget(const smtk::view::Information& info)
{
- qtSelectorView* view = new qtSelectorView(info);
- view->buildUI();
- return view;
+ if (qtBaseAttributeView::validateInformation(info))
+ {
+ auto* view = new qtSelectorView(info);
+ view->buildUI();
+ return view;
+ }
+ return nullptr; // Information is not suitable for this View
}
qtSelectorView::qtSelectorView(const smtk::view::Information& info)
@@ -71,7 +75,7 @@ qtSelectorView::~qtSelectorView()
void qtSelectorView::createWidget()
{
- smtk::view::ConfigurationPtr view = this->getObject();
+ smtk::view::ConfigurationPtr view = this->configuration();
if (!view)
{
return;
@@ -94,13 +98,13 @@ void qtSelectorView::createWidget()
bool qtSelectorView::createSelector()
{
//create the layout for the frame area
- smtk::view::ConfigurationPtr view = this->getObject();
+ smtk::view::ConfigurationPtr view = this->configuration();
QVBoxLayout* layout = new QVBoxLayout(this->Widget);
layout->setMargin(0);
this->Widget->setLayout(layout);
// Get the Selector Attribute
- smtk::attribute::ResourcePtr resource = this->uiManager()->attResource();
+ smtk::attribute::ResourcePtr resource = this->attributeResource();
std::string attName, defName;
view->details().attribute("SelectorName", attName);
view->details().attribute("SelectorType", defName);
@@ -172,8 +176,8 @@ bool qtSelectorView::isEmpty() const
bool qtSelectorView::createChildren()
{
- smtk::view::ConfigurationPtr view = this->getObject();
- smtk::attribute::ResourcePtr resource = this->uiManager()->attResource();
+ smtk::view::ConfigurationPtr view = this->configuration();
+ smtk::attribute::ResourcePtr resource = this->attributeResource();
// We need the selector item's definition in order to get the enumeration info
auto selItemDef =
@@ -225,9 +229,10 @@ bool qtSelectorView::createChildren()
}
// Setup the information for the new child view based off of
// this one
- smtk::extension::ViewInfo vinfo = m_viewInfo;
- vinfo.m_view = v;
- vinfo.m_parent = this->Widget;
+ auto vinfo = m_viewInfo;
+ vinfo.insert_or_assign(v);
+ vinfo.insert_or_assign(this->Widget);
+
qtView = this->uiManager()->createView(vinfo);
if (qtView)
{
@@ -245,11 +250,11 @@ void qtSelectorView::getChildView(const std::string& viewType, QListChildViews)
{
- if (childView->getObject()->type() == viewType)
+ if (childView->configuration()->type() == viewType)
{
views.append(childView);
}
- else if (childView->getObject()->type() == "Group")
+ else if (childView->configuration()->type() == "Group")
{
qobject_cast(childView)->getChildView(viewType, views);
}
@@ -272,7 +277,7 @@ void qtSelectorView::addChildView(qtBaseView* child, int viewEnumIndex)
m_internals->ChildViews.append(child);
m_internals->m_viewEnumIdices.append(viewEnumIndex);
QFrame* frame = dynamic_cast(this->Widget);
- if (!frame || !child || !child->getObject())
+ if (!frame || !child || !child->configuration())
{
return;
}
diff --git a/smtk/extension/qt/qtSimpleExpressionView.cxx b/smtk/extension/qt/qtSimpleExpressionView.cxx
index 92d62445942847ec55c5bfef9c6f5ef8a4c94193..2f7dc902bc97d4e0c445675863922599462ff07f 100644
--- a/smtk/extension/qt/qtSimpleExpressionView.cxx
+++ b/smtk/extension/qt/qtSimpleExpressionView.cxx
@@ -81,9 +81,13 @@ const char* qtSimpleExpressionView::qtSimpleExpressionViewInternals::getFunction
qtBaseView* qtSimpleExpressionView::createViewWidget(const smtk::view::Information& info)
{
- qtSimpleExpressionView* view = new qtSimpleExpressionView(info);
- view->buildUI();
- return view;
+ if (qtBaseAttributeView::validateInformation(info))
+ {
+ auto* view = new qtSimpleExpressionView(info);
+ view->buildUI();
+ return view;
+ }
+ return nullptr; // Information is not suitable for this View
}
qtSimpleExpressionView::qtSimpleExpressionView(const smtk::view::Information& info)
@@ -99,7 +103,7 @@ qtSimpleExpressionView::~qtSimpleExpressionView()
void qtSimpleExpressionView::createWidget()
{
- if (!this->getObject())
+ if (!this->configuration())
{
return;
}
@@ -110,7 +114,7 @@ void qtSimpleExpressionView::createWidget()
// A common add/delete/(copy/paste ??) widget
QSplitter* frame = new QSplitter(this->parentWidget());
- frame->setObjectName(this->getObject()->name().c_str());
+ frame->setObjectName(this->configuration()->name().c_str());
QFrame* leftFrame = new QFrame(frame);
leftFrame->setObjectName("left");
QFrame* rightFrame = new QFrame(frame);
@@ -605,7 +609,7 @@ void qtSimpleExpressionView::onDeleteSelected()
return;
}
- smtk::attribute::ResourcePtr resource = this->uiManager()->attResource();
+ smtk::attribute::ResourcePtr resource = this->attributeResource();
resource->removeAttribute(this->getFunctionFromItem(selItem));
this->Internals->FuncList->takeItem(this->Internals->FuncList->row(selItem));
@@ -774,12 +778,12 @@ void qtSimpleExpressionView::onShowCategory()
void qtSimpleExpressionView::updateUI()
{
- smtk::view::ConfigurationPtr view = this->getObject();
+ smtk::view::ConfigurationPtr view = this->configuration();
if (!view)
{
return;
}
- smtk::attribute::ResourcePtr resource = this->uiManager()->attResource();
+ smtk::attribute::ResourcePtr resource = this->attributeResource();
// There should be only 1 child component called Type
if ((view->details().numberOfChildren() != 1) || (view->details().child(0).name() != "Att"))
{
diff --git a/smtk/extension/qt/qtUIManager.cxx b/smtk/extension/qt/qtUIManager.cxx
index f2ae607ac4476ddb888a2841890bed0fcfcaeddc..117a8bec0d7c1da2cf80222aed09ecf93873c1b7 100644
--- a/smtk/extension/qt/qtUIManager.cxx
+++ b/smtk/extension/qt/qtUIManager.cxx
@@ -13,6 +13,7 @@
#include "smtk/extension/qt/qtAnalysisView.h"
#include "smtk/extension/qt/qtAssociationView.h"
#include "smtk/extension/qt/qtAttributeView.h"
+#include "smtk/extension/qt/qtBaseView.h"
#include "smtk/extension/qt/qtCategorySelectorView.h"
#include "smtk/extension/qt/qtComponentItem.h"
#include "smtk/extension/qt/qtDateTimeItem.h"
@@ -220,21 +221,27 @@ void qtUIManager::initializeUI(QWidget* pWidget, bool useInternalFileBrowser)
}
this->internalInitialize();
+ smtk::view::Information vinfo;
+ vinfo.insert(m_smtkView);
+ vinfo.insert(pWidget);
+ vinfo.insert(this);
if (!m_operation)
{
- smtk::extension::ViewInfo vinfo(m_smtkView, pWidget, this);
- m_topView = this->createView(vinfo);
+ vinfo.insert>(m_attResource);
}
else
{
- smtk::extension::OperationViewInfo vinfo(m_smtkView, m_operation, pWidget, this);
- m_topView = this->createView(vinfo);
+ vinfo.insert(m_operation);
+ vinfo.insert>(m_operation->specification());
}
+
+ m_topView = this->createView(vinfo);
+
if (m_topView)
{
- if (m_topView->getObject()->details().attribute(m_activeAdvLevelXmlAttName))
+ if (m_topView->configuration()->details().attribute(m_activeAdvLevelXmlAttName))
{
- m_topView->getObject()->details().attributeAsInt(
+ m_topView->configuration()->details().attributeAsInt(
m_activeAdvLevelXmlAttName, m_currentAdvLevel);
}
if (m_currentAdvLevel) // only build advanced level when needed)
@@ -252,12 +259,11 @@ void qtUIManager::initializeUI(QWidget* pWidget, bool useInternalFileBrowser)
}
}
-void qtUIManager::initializeUI(
- const smtk::extension::ViewInfo& viewInfo,
- bool useInternalFileBrowser)
+void qtUIManager::initializeUI(const smtk::view::Information& viewInfo, bool useInternalFileBrowser)
{
m_useInternalFileBrowser = useInternalFileBrowser;
- m_parentWidget = viewInfo.m_parent;
+ m_parentWidget = viewInfo.get();
+ m_smtkView = viewInfo.get();
if (m_topView)
{
delete m_topView;
@@ -373,21 +379,21 @@ smtk::view::ConfigurationPtr qtUIManager::findOrCreateOperationView() const
}
qtBaseView* qtUIManager::setSMTKView(
- const smtk::extension::ViewInfo& viewInfo,
+ const smtk::view::Information& viewInfo,
bool useInternalFileBrowser)
{
if (
- (m_smtkView == viewInfo.m_view) && (m_parentWidget == viewInfo.m_parent) &&
+ (m_smtkView == viewInfo.get()) &&
+ (m_parentWidget == viewInfo.get()) &&
(m_useInternalFileBrowser == useInternalFileBrowser))
{
return m_topView;
}
- m_smtkView = viewInfo.m_view;
this->initializeUI(viewInfo, m_useInternalFileBrowser);
return m_topView;
}
-qtBaseView* qtUIManager::setSMTKView(smtk::view::ConfigurationPtr v)
+qtBaseView* qtUIManager::setSMTKView(const smtk::view::ConfigurationPtr& v)
{
if (m_smtkView != v)
{
@@ -398,7 +404,7 @@ qtBaseView* qtUIManager::setSMTKView(smtk::view::ConfigurationPtr v)
}
qtBaseView* qtUIManager::setSMTKView(
- smtk::view::ConfigurationPtr v,
+ const smtk::view::ConfigurationPtr& v,
QWidget* pWidget,
bool useInternalFileBrowser)
{
@@ -447,7 +453,8 @@ void qtUIManager::setAdvanceLevel(int b)
if (m_topView)
{
m_topView->showAdvanceLevel(b);
- m_topView->getObject()->details().setAttribute(m_activeAdvLevelXmlAttName, std::to_string(b));
+ m_topView->configuration()->details().setAttribute(
+ m_activeAdvLevelXmlAttName, std::to_string(b));
}
}
@@ -888,39 +895,40 @@ void qtUIManager::registerItemConstructor(const std::string& itype, qtItemConstr
m_itemConstructors[itype] = f;
}
-qtBaseView* qtUIManager::createView(const ViewInfo& info)
+qtBaseView* qtUIManager::createView(const smtk::view::Information& info)
{
- if (info.m_UIManager != this)
+ if (info.get() != this)
{
- // The view being constructed is not refering to this manager!
+ // The view being constructed is not referring to this manager!
return nullptr;
}
auto& viewManager = m_managers.get();
+ std::string viewType = info.get()->type();
if (!viewManager)
{
- std::cerr << "No viewManager for View Type: " << info.m_view->type() << " skipping view!\n";
+ std::cerr << "No viewManager for View Type: " << viewType << " skipping view!\n";
return nullptr;
}
qtBaseView* qtView = nullptr;
- if (viewManager->viewWidgetFactory().contains(info.m_view->type()))
+ if (viewManager->viewWidgetFactory().contains(viewType))
{
qtView = dynamic_cast(
viewManager->viewWidgetFactory()
- .createFromName(info.m_view->type(), static_cast(info))
+ .createFromName(viewType, static_cast(info))
.release());
}
- else if (viewManager->viewWidgetFactory().containsAlias(info.m_view->type()))
+ else if (viewManager->viewWidgetFactory().containsAlias(viewType))
{
qtView = dynamic_cast(
viewManager->viewWidgetFactory()
- .createFromAlias(info.m_view->type(), static_cast(info))
+ .createFromAlias(viewType, static_cast(info))
.release());
}
if (!qtView)
{
// Constructor for that type could not be found)
- std::cerr << "Could not find View Type: " << info.m_view->type() << " skipping view!\n";
+ std::cerr << "Could not find View Type: " << viewType << " skipping view!\n";
}
else
{
diff --git a/smtk/extension/qt/qtUIManager.h b/smtk/extension/qt/qtUIManager.h
index 137d7098b0c55d516c167547779a1f3ad2f84951..861003e8e68fb4ac2d86f2888b4961f45c9fc38a 100644
--- a/smtk/extension/qt/qtUIManager.h
+++ b/smtk/extension/qt/qtUIManager.h
@@ -13,6 +13,7 @@
#include "smtk/attribute/Categories.h"
#include "smtk/attribute/Resource.h"
+#include "smtk/common/Deprecation.h"
#include "smtk/common/TypeContainer.h"
#include "smtk/operation/Manager.h"
@@ -22,7 +23,6 @@
#include "smtk/view/Selection.h"
#include "smtk/extension/qt/Exports.h"
-#include "smtk/extension/qt/qtBaseView.h" // Needed for ViewInfo definition
#include "smtk/extension/qt/qtItem.h"
#include
@@ -47,7 +47,6 @@ class qtFileItem;
class qtModelEntityItem;
class qtBaseView;
-typedef qtBaseView* (*widgetConstructor)(const ViewInfo& info);
typedef qtItem* (*qtItemConstructor)(const qtAttributeItemInfo& info);
/**\brief Container for managers whose content is presented via Qt widgets.
@@ -79,7 +78,7 @@ public:
~qtUIManager() override;
void initializeUI(QWidget* pWidget, bool useInternalFileBrowser = false);
- void initializeUI(const smtk::extension::ViewInfo& v, bool useInternalFileBrowser = false);
+ void initializeUI(const smtk::view::Information& v, bool useInternalFileBrowser = false);
/// If this instance was constructed with an operation, return an appropriate view for it.
smtk::view::ConfigurationPtr findOrCreateOperationView() const;
@@ -89,10 +88,12 @@ public:
///@{
/// Use the given smtk::view::Configuration to construct widgets matching the specification.
- qtBaseView* setSMTKView(smtk::view::ConfigurationPtr v);
- qtBaseView*
- setSMTKView(smtk::view::ConfigurationPtr v, QWidget* pWidget, bool useInternalFileBrowser = true);
- qtBaseView* setSMTKView(const smtk::extension::ViewInfo& v, bool useInternalFileBrowser = true);
+ qtBaseView* setSMTKView(const smtk::view::ConfigurationPtr& v);
+ qtBaseView* setSMTKView(
+ const smtk::view::ConfigurationPtr& v,
+ QWidget* pWidget,
+ bool useInternalFileBrowser = true);
+ qtBaseView* setSMTKView(const smtk::view::Information& v, bool useInternalFileBrowser = true);
smtk::view::ConfigurationPtr smtkView() const { return m_smtkView; }
const smtk::view::Configuration::Component& findStyle(
const smtk::attribute::DefinitionPtr& def,
@@ -129,8 +130,9 @@ public:
const smtk::common::TypeContainer& managers() const { return m_managers; }
smtk::common::TypeContainer& managers() { return m_managers; }
+ SMTK_DEPRECATED_IN_21_08("Since the attribute resource is now passed into qtBaseAttributeViews, "
+ "there is no longer a need to access the resource from the qtUIManager")
smtk::attribute::ResourcePtr attResource() const { return m_attResource.lock(); }
-
///@{
/// Set/Get the color used for indicating items with default values
void setDefaultValueColor(const QColor& color);
@@ -237,7 +239,7 @@ public:
virtual int getWidthOfText(const std::string& text, const QFont& font);
///Mechanism for creating new GUI view based on registered factory functions
- qtBaseView* createView(const ViewInfo& info);
+ qtBaseView* createView(const smtk::view::Information& info);
///Mechanism for creating new GUI item based on registered factory functions
qtItem* createItem(const qtAttributeItemInfo& info);
diff --git a/smtk/extension/qt/qtViewInterface.h b/smtk/extension/qt/qtViewInterface.h
deleted file mode 100644
index b4892d4e17dcbcca4dca0e2216f07bbe0127508d..0000000000000000000000000000000000000000
--- a/smtk/extension/qt/qtViewInterface.h
+++ /dev/null
@@ -1,49 +0,0 @@
-//=========================================================================
-// Copyright (c) Kitware, Inc.
-// All rights reserved.
-// See LICENSE.txt for details.
-//
-// This software is distributed WITHOUT ANY WARRANTY; without even
-// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-// PURPOSE. See the above copyright notice for more information.
-//=========================================================================
-
-#ifndef __smtk_attribute_qtViewInterface_h
-#define __smtk_attribute_qtViewInterface_h
-
-#include "smtk/extension/qt/Exports.h"
-#include "smtk/extension/qt/qtBaseView.h"
-
-#include
-#include
-
-typedef smtk::extension::qtBaseView* (*qtSMTKViewConstructor)(
- const smtk::extension::ViewInfo& info);
-
-namespace smtk
-{
-namespace extension
-{
-
-/// interface class for plugins that add a QDockWindow
-class SMTKQTEXT_EXPORT qtViewInterface
-{
-public:
- qtViewInterface();
- virtual ~qtViewInterface();
-
- virtual QString viewName() const = 0;
-
- /// return a static constructor for derived class of qtBaseView
- virtual qtSMTKViewConstructor viewConstructor() = 0;
-
-private:
- Q_DISABLE_COPY(qtViewInterface)
-};
-
-}; // namespace extension
-}; // namespace smtk
-
-Q_DECLARE_INTERFACE(smtk::extension::qtViewInterface, "com.kitware/paraview/smtkview")
-
-#endif
diff --git a/smtk/extension/qt/qtVoidItem.cxx b/smtk/extension/qt/qtVoidItem.cxx
index 5c09cdd1b3d41e7fa29dc8bfe00bffd77dcdb19f..4cb1183cea179744a6636e20398c185cc9cf1f33 100644
--- a/smtk/extension/qt/qtVoidItem.cxx
+++ b/smtk/extension/qt/qtVoidItem.cxx
@@ -20,6 +20,7 @@
#include "smtk/attribute/VoidItem.h"
#include "smtk/attribute/VoidItemDefinition.h"
+#include "smtk/simulation/UserData.h"
using namespace smtk::extension;
@@ -86,6 +87,14 @@ void qtVoidItem::createWidget()
if (dataObj->isOptional())
{
QCheckBox* optionalCheck = new QCheckBox(m_widget);
+
+ // Check for "no_focus" user data
+ auto udata = dataObj->userData("smtk.extensions.void_item.no_focus");
+ if (udata != nullptr)
+ {
+ optionalCheck->setFocusPolicy(Qt::NoFocus);
+ }
+
optionalCheck->setChecked(dataObj->definition()->isEnabledByDefault());
optionalCheck->setSizePolicy(sizeFixedPolicy);
diff --git a/smtk/project/ResourceContainer.h b/smtk/project/ResourceContainer.h
index 5b4eef13c51fa1caddd30ceee183549b23050973..8cecd151a1e962d09711234d5d20a9f4f4159e8a 100644
--- a/smtk/project/ResourceContainer.h
+++ b/smtk/project/ResourceContainer.h
@@ -283,7 +283,12 @@ std::set> ResourceContainer::findByRole(
template
std::set> ResourceContainer::find() const
{
- return this->find(typeid(ResourceType).hash_code());
+ std::set> cast_set;
+ for (const auto& resourceptr : this->find(typeid(ResourceType).hash_code()))
+ {
+ cast_set.insert(std::dynamic_pointer_cast(resourceptr));
+ }
+ return cast_set;
}
template
diff --git a/smtk/project/operators/Read.cxx b/smtk/project/operators/Read.cxx
index a1b63030c23e0e74a20f19eab16bf4839b1403c0..5ae800bc7496a3a999e69c69bfa91c82f8008703 100644
--- a/smtk/project/operators/Read.cxx
+++ b/smtk/project/operators/Read.cxx
@@ -105,32 +105,6 @@ Read::Result Read::operateInternal()
smtk::project::from_json(j, project);
Result result = this->createResult(smtk::operation::Operation::Outcome::SUCCEEDED);
-
- // For now, load all project resources
- j = j["resources"];
- for (json::const_iterator it = j["resources"].begin(); it != j["resources"].end(); ++it)
- {
- boost::filesystem::path path(it->at("location").get());
- if (path.is_relative())
- {
- path = projectPath / path;
- }
- smtk::resource::ResourcePtr resource =
- project->resources().manager()->read(it->at("type").get(), path.string());
- if (!resource)
- {
- smtkErrorMacro(
- log(),
- "Cannot read resource type \"" << it->at("type").get() << "\" at location \""
- << it->at("location").get() << "\".");
-
- result = this->createResult(smtk::operation::Operation::Outcome::FAILED);
- continue;
- }
- resource->setClean(true);
- project->resources().add(resource, detail::role(resource));
- }
-
{
smtk::attribute::ResourceItem::Ptr created = result->findResource("resource");
created->setValue(project);
diff --git a/smtk/project/plugin/pqSMTKProjectPanel.cxx b/smtk/project/plugin/pqSMTKProjectPanel.cxx
index c9203d80a1dc06704cacc2f0475a6771874eb73b..08b13b41b14e7279487dbf0e9547b37de3f5aac3 100644
--- a/smtk/project/plugin/pqSMTKProjectPanel.cxx
+++ b/smtk/project/plugin/pqSMTKProjectPanel.cxx
@@ -88,7 +88,10 @@ void pqSMTKProjectPanel::sourceAdded(pqSMTKWrapper* wrapper, pqServer* server)
m_viewUIMgr->setSelection(wrapper->smtkSelection());
// m_viewUIMgr->setSelectionBit(1); // ToDo: should be set ?
- smtk::extension::ViewInfo resinfo(m_view, this, m_viewUIMgr);
+ smtk::view::Information resinfo;
+ resinfo.insert(m_view);
+ resinfo.insert(this);
+ resinfo.insert(m_viewUIMgr);
// the top-level "Type" in m_view should be pqSMTKProjectBrowser or compatible.
auto* baseview = m_viewUIMgr->setSMTKView(resinfo);
diff --git a/smtk/project/testing/cxx/TestProject.cxx b/smtk/project/testing/cxx/TestProject.cxx
index 405be05848b1980f4cefbe55a70860c251c92d17..d416d56c13a99cd9357f72eb1f2e21d2a93cd85f 100644
--- a/smtk/project/testing/cxx/TestProject.cxx
+++ b/smtk/project/testing/cxx/TestProject.cxx
@@ -116,6 +116,10 @@ int TestProject(int /*unused*/, char** const /*unused*/)
resource = project->resources().get(myResource->id());
smtkTest(!!resource, "could not access resource from project interface");
+ // Verify the find by type method
+ auto resourceSet = project->resources().find();
+ smtkTest(resourceSet.size() == 1, "could not get resources by type");
+
// Remove the instance of smtk::project::Project
projectManager->remove(project);
diff --git a/smtk/resource/PersistentObject.h b/smtk/resource/PersistentObject.h
index bd368eee73d23e2ecd6f740292f521bbaa62e1d9..2fd5be8c66fbfc7bcc8760e3524eafddefa1f677 100644
--- a/smtk/resource/PersistentObject.h
+++ b/smtk/resource/PersistentObject.h
@@ -49,7 +49,7 @@ public:
/// connect to this object (see Resource::setId and its treatment of
/// manager registration for reference).
virtual bool setId(const common::UUID& myID) = 0;
- /// Return the name of the object - by default it will return the UUID but that can be overriden
+ /// Return the name of the object - by default it will return the UUID but that can be overridden
virtual std::string name() const;
/// Attempt to cast this object to a subclass.
diff --git a/smtk/resource/Resource.h b/smtk/resource/Resource.h
index f8e2359e298d08f86027e798d416cef7f68f95c3..7b39a65001ee760a1ec0e01de78af7fe3889a147 100644
--- a/smtk/resource/Resource.h
+++ b/smtk/resource/Resource.h
@@ -126,6 +126,12 @@ public:
virtual bool clean() const { return m_clean; }
void setClean(bool state = true);
+ /// Mark the resource to indicate it is about to removed (meaning it is being removed from memory
+ /// not necessarily for deletion)
+ void setMarkedForRemoval(bool val) { m_markedForRemoval = val; }
+
+ /// Return whether the object is marked for removal
+ virtual bool isMarkedForRemoval() const { return m_markedForRemoval; }
/// Resources that are managed have a non-null pointer to their manager.
ManagerPtr manager() const { return m_manager.lock(); }
@@ -223,6 +229,7 @@ private:
Links m_links;
Properties m_properties;
Queries m_queries;
+ bool m_markedForRemoval = false;
mutable Lock m_lock;
};
diff --git a/smtk/session/polygon/CMakeLists.txt b/smtk/session/polygon/CMakeLists.txt
index c64eb60b5269bbabf705575e35a28852271702cc..17d28a86cbe6aa295d87f876d1bef338a0235ac9 100644
--- a/smtk/session/polygon/CMakeLists.txt
+++ b/smtk/session/polygon/CMakeLists.txt
@@ -134,12 +134,7 @@ smtk_install_library(smtkPolygonSession)
# Install the headers
smtk_public_headers(smtkPolygonSession ${polygonHeaders})
-
install(FILES PointerDefs.h DESTINATION include/smtk/${SMTK_VERSION}/smtk/session/polygon)
-target_include_directories(smtkPolygonSession
- PUBLIC
- $
-)
if (SMTK_ENABLE_VTK_SUPPORT)
set(module_files
diff --git a/smtk/session/polygon/operators/ImportPPG.cxx b/smtk/session/polygon/operators/ImportPPG.cxx
index 6e1108dc212b61c10b1bf169dbbcfb9305eb46f6..424706837435072d4174c646448bc725e3dc2273 100644
--- a/smtk/session/polygon/operators/ImportPPG.cxx
+++ b/smtk/session/polygon/operators/ImportPPG.cxx
@@ -42,6 +42,7 @@
#include
#include
+#include
#include
#include