Skip to content

Commit

Permalink
Merge pull request #3777 from Autodesk/donnels/EMSUSD-1121/fix_select…
Browse files Browse the repository at this point in the history
…ion_from_paste_cmd

EMSUSD-1121 - Pasted prims should be selected
  • Loading branch information
seando-adsk authored May 22, 2024
2 parents 60fd003 + 72162f6 commit de9fdf1
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 17 deletions.
25 changes: 13 additions & 12 deletions lib/usdUfe/ufe/UsdClipboardCommands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -440,8 +440,6 @@ void UsdPasteClipboardCommand::execute()
}
};

Ufe::SceneItemList itemsToSelect;

for (const auto& dstParentItem : _dstParentItems) {
Ufe::PasteClipboardCommand::PasteInfo pasteInfo;
pasteInfo.pasteTarget = dstParentItem->path();
Expand Down Expand Up @@ -488,22 +486,14 @@ void UsdPasteClipboardCommand::execute()
appendToVector(duplicateCmd->targetItems(), pasteInfo.successfulPastes);
auto tmpTargetItems = duplicateCmd->targetItems();
_targetItems.insert(_targetItems.end(), tmpTargetItems.begin(), tmpTargetItems.end());
itemsToSelect.insert(itemsToSelect.end(), tmpTargetItems.begin(), tmpTargetItems.end());
_itemsToSelect.insert(
_itemsToSelect.end(), tmpTargetItems.begin(), tmpTargetItems.end());
}

// Add the paste info.
_pasteInfos.push_back(std::move(pasteInfo));
}

if (!itemsToSelect.empty()) {
// Select the newly pasted items. This matches native DCC (ex: Maya) behavior.
Ufe::Selection pasteSelect;
for (const auto& item : itemsToSelect) {
pasteSelect.append(item);
}
Ufe::GlobalSelection::get()->replaceWith(pasteSelect);
}

// Remove ClipboardMetadata.
clearClipboardMetadata(_targetItems);
}
Expand All @@ -519,4 +509,15 @@ std::vector<Ufe::PasteClipboardCommand::PasteInfo> UsdPasteClipboardCommand::get
return _pasteInfos;
}

Ufe::Selection getNewSelectionFromCommand(const UsdPasteClipboardCommand& cmd)
{
Ufe::Selection newSelection;
if (!cmd.itemsToSelect().empty()) {
// Select the newly pasted items. This matches native DCC (ex: Maya) behavior.
for (const auto& item : cmd.itemsToSelect()) {
newSelection.append(item);
}
}
return newSelection;
}
} // namespace USDUFE_NS_DEF
10 changes: 10 additions & 0 deletions lib/usdUfe/ufe/UsdClipboardCommands.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,9 @@ class USDUFE_PUBLIC UsdPasteClipboardCommand : public Ufe::PasteClipboardCommand
Ufe::SceneItemList targetItems() const override;
std::vector<PasteInfo> getPasteInfos() const override;

// For selection of pasted items.
Ufe::SceneItemList itemsToSelect() const { return _itemsToSelect; }

private:
UsdUndoableItem _undoableItem;

Expand All @@ -131,6 +134,9 @@ class USDUFE_PUBLIC UsdPasteClipboardCommand : public Ufe::PasteClipboardCommand
// The target items.
Ufe::SceneItemList _targetItems;

// The target items to select (after paste).
Ufe::SceneItemList _itemsToSelect;

// The cmd gets the clipboard data when executed.
UsdClipboard::Ptr _clipboard;

Expand All @@ -139,6 +145,10 @@ class USDUFE_PUBLIC UsdPasteClipboardCommand : public Ufe::PasteClipboardCommand

}; // UsdPasteClipboardCommand

//! \brief Retrieve the desired selection after the command has executed.
// \see UsdUndoSelectAfterCommand.
Ufe::Selection USDUFE_PUBLIC getNewSelectionFromCommand(const UsdPasteClipboardCommand& cmd);

} // namespace USDUFE_NS_DEF

#endif // USDCLIPBOARDCOMMANDS_H
7 changes: 5 additions & 2 deletions lib/usdUfe/ufe/UsdClipboardHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "UsdClipboardHandler.h"

#include <usdUfe/ufe/UsdClipboardCommands.h>
#include <usdUfe/ufe/UsdUndoSelectAfterCommand.h>
#include <usdUfe/ufe/Utils.h>
#include <usdUfe/utils/layers.h>

Expand Down Expand Up @@ -76,12 +77,14 @@ Ufe::UndoableCommand::Ptr UsdClipboardHandler::copyCmd_(const Ufe::Selection& se
Ufe::PasteClipboardCommand::Ptr
UsdClipboardHandler::pasteCmd_(const Ufe::SceneItem::Ptr& parentItem)
{
return UsdPasteClipboardCommand::create(parentItem, _clipboard);
return UsdUfe::UsdUndoSelectAfterCommand<UsdUfe::UsdPasteClipboardCommand>::create(
parentItem, _clipboard);
}

Ufe::UndoableCommand::Ptr UsdClipboardHandler::pasteCmd_(const Ufe::Selection& parentItems)
{
return UsdPasteClipboardCommand::create(parentItems, _clipboard);
return UsdUfe::UsdUndoSelectAfterCommand<UsdUfe::UsdPasteClipboardCommand>::create(
parentItems, _clipboard);
}

bool UsdClipboardHandler::hasItemsToPaste_()
Expand Down
8 changes: 5 additions & 3 deletions lib/usdUfe/ufe/UsdUndoSelectAfterCommand.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,11 @@ template <class OTHER_COMMAND> class UsdUndoSelectAfterCommand : public OTHER_CO
private:
static void setSelection(const Ufe::Selection& newSelection)
{
if (newSelection.empty())
return;
Ufe::GlobalSelection::get()->replaceWith(newSelection);
if (newSelection.empty()) {
Ufe::GlobalSelection::get()->clear();
} else {
Ufe::GlobalSelection::get()->replaceWith(newSelection);
}
}

Ufe::Selection _previousSelection;
Expand Down
18 changes: 18 additions & 0 deletions test/lib/ufe/testClipboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ def testClipboardCopyPaste(self):
copiedSphereItem = ufeUtils.createItem(psPathStr + ',/Xform1/Sphere1')
self.assertIsNotNone(copiedSphereItem)

# Clear the selection before pasting.
ufe.GlobalSelection.get().clear()

# Paste (sphere from copy) into the xform1, it will get renamed
# to Sphere1. The Xform1 parent should have one more child.
pasteCmd = ch.pasteCmd_(xformItem)
Expand Down Expand Up @@ -118,20 +121,35 @@ def testClipboardCopyPaste(self):
# No paste failures.
self.assertEqual(0, len(pasteInfo[0].failedPastes))

# Verify that the pasted item is selected.
sn = ufe.GlobalSelection.get()
self.assertEqual(len(sn), 1)
self.assertTrue(sn.contains(pastedSphereItem.path()))

# Undo the paste, copied sphere item should be gone and child count
# should be back to original.
pasteCmd.undo()
self.assertEqual(nbChildren, len(xformHier.children()))
pastedSphereItem = ufeUtils.createItem(psPathStr + ',/Xform1/Sphere2')
self.assertIsNone(pastedSphereItem)

# The pasted sphere should no longer be selected, and the selection should
# be empty (since there was nothing selected before pasting).
sn = ufe.GlobalSelection.get()
self.assertEqual(len(sn), 0)

# Redo the paste, pasted sphere will be back and child count should increase
# by 1 again.
pasteCmd.redo()
self.assertEqual(nbChildren+1, len(xformHier.children()))
pastedSphereItem = ufeUtils.createItem(psPathStr + ',/Xform1/Sphere2')
self.assertIsNotNone(pastedSphereItem)

# Pasted sphere should again be selected.
sn = ufe.GlobalSelection.get()
self.assertEqual(len(sn), 1)
self.assertTrue(sn.contains(pastedSphereItem.path()))

def testClipboardCutPaste(self):
'''Basic test for the Clipboard cut/paste support.'''

Expand Down

0 comments on commit de9fdf1

Please sign in to comment.