mirror of
https://github.com/FirestormViewer/phoenix-firestorm.git
synced 2026-08-14 00:48:30 +00:00
FIRE-36685 - Toolbox Window - Add new notecard button to Content tab
Added new "New Notecard" button to the Build Window's Content tab. Creates a new notecard directly in the objects content inventory. New scripts and notecards automatically appear at the top of the content inventory with the new object having renamed automatically enabled. Added flag to settings to store a backup of inventory flags, which is used to disable popup of new objects appearing in the main inventory as new notecards need to appear in the user inventory before being moved over to the object's content inventory.
This commit is contained in:
@@ -162,6 +162,7 @@ set(viewer_SOURCE_FILES
|
||||
fsnearbychatcontrol.cpp
|
||||
fsnearbychathub.cpp
|
||||
fsnearbychatvoicemonitor.cpp
|
||||
fsnewitemctrl.cpp
|
||||
fspanelblocklist.cpp
|
||||
fspanelcontactsets.cpp
|
||||
fspanelface.cpp
|
||||
@@ -1022,6 +1023,7 @@ set(viewer_HEADER_FILES
|
||||
fsnearbychatcontrol.h
|
||||
fsnearbychathub.h
|
||||
fsnearbychatvoicemonitor.h
|
||||
fsnewitemctrl.h
|
||||
fspanelblocklist.h
|
||||
fspanelcontactsets.h
|
||||
fspanelface.h
|
||||
|
||||
@@ -15156,6 +15156,19 @@ Change of this parameter will affect the layout of buttons in notification toast
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<!-- <FS:mjr> -->
|
||||
<key>BackupInventoryFlags</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Store the flags for Show In/New/Gesture inventory</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<!-- </FS:mjr> -->
|
||||
<key>ShowObjectUpdates</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
||||
@@ -0,0 +1,274 @@
|
||||
/**
|
||||
* @file fsnewitemctrl.cpp
|
||||
* @brief A singleton controller for handling adding new items to Objects using Build Window's Content tab.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2026&license=viewerlgpl$
|
||||
* Phoenix Firestorm Viewer Source Code
|
||||
* Copyright (c) 2026 minerjr @ The Phoenix Firestorm Project, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
// <FS:mjr> [FIRE-36685] - Toolbox Window - Add new notecard button to Content tab
|
||||
|
||||
#include "fsnewitemctrl.h"
|
||||
#include "llinventory.h"
|
||||
#include "llviewerinventory.h"
|
||||
#include "llselectmgr.h"
|
||||
#include "llcontrol.h" // gSavedSettings
|
||||
#include "llinventorymodel.h" // gInventory
|
||||
#include "llagentdata.h" // gAgentID
|
||||
|
||||
extern LLControlGroup gSavedSettings;
|
||||
extern LLInventoryModel gInventory;
|
||||
extern LLUUID gAgentID;
|
||||
|
||||
FSNewItemCtrl::FSNewItemCtrl() : LLSingleton<FSNewItemCtrl>(),
|
||||
mState(EAddNewItemState::IDLE),
|
||||
mItemAssetType(LLAssetType::AT_NONE),
|
||||
mOriginalItemUUID(),
|
||||
mNewItemUUID()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
FSNewItemCtrl::~FSNewItemCtrl()
|
||||
{
|
||||
// delete Xxx;
|
||||
}
|
||||
|
||||
void FSNewItemCtrl::init()
|
||||
{
|
||||
mState = EAddNewItemState::IDLE;
|
||||
mItemAssetType = LLAssetType::AT_NONE;
|
||||
mOriginalItemUUID.setNull();
|
||||
mNewItemUUID.setNull();
|
||||
}
|
||||
|
||||
void FSNewItemCtrl::processStates(LLPanelObjectInventory* panel_object_inv)
|
||||
{
|
||||
// Check if the passed in panel object inventory is valid, and if not, return
|
||||
if (panel_object_inv == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LLFolderView* folders = panel_object_inv->getRootFolder();
|
||||
|
||||
// Idle state, just return as there is nothing to process
|
||||
if (mState == EAddNewItemState::IDLE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// Handle the start of the drag and drop the item from avatar inventory to the object's inventory
|
||||
// wait until the inventory movement has finished before handling the item appearing in the inventory
|
||||
else if (mState == EAddNewItemState::DND_INV_TO_OBJECT)
|
||||
{
|
||||
if (LLViewerObject* objectp = gObjectList.findObject(panel_object_inv->getTaskUUID()))
|
||||
{
|
||||
// If the inveotory is not pending and not dirty, then we want to move to the next step.
|
||||
if (objectp && !objectp->isInventoryPending() && !objectp->isInventoryDirty())
|
||||
{
|
||||
mState = EAddNewItemState::DND_INV_TO_OBJECT_DONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Handles when the item appears, will select the new item and set it to rename.
|
||||
// If the item is able to be opened, it will be opened.
|
||||
else if (mState == EAddNewItemState::DND_INV_TO_OBJECT_DONE)
|
||||
{
|
||||
bool inventory_has_focus = panel_object_inv->hasInventory() && folders && gFocusMgr.childHasKeyboardFocus(folders);
|
||||
|
||||
// Restore the show new inventory current settings
|
||||
restoreInventoryFlags();
|
||||
|
||||
panel_object_inv->setFocusRoot(true);
|
||||
|
||||
if (!mNewItemUUID.isNull())
|
||||
{
|
||||
// Flag that item needs to be renamed, needs to be done once added to the actual folder.
|
||||
LLFolderViewItem* current_item = panel_object_inv->getItemByID(mNewItemUUID);
|
||||
if (current_item && folders)
|
||||
{
|
||||
// Set the found
|
||||
folders->setSelection(current_item, true, inventory_has_focus);
|
||||
// mFolders->requestArrange();
|
||||
folders->startRenamingSelectedItem();
|
||||
// If the item is a gesture, notecard, text or script, we need to re-open the item floater to allow floater to
|
||||
// modify the object content's item and not the one generated in the avatar's inventory.
|
||||
if (mItemAssetType == LLAssetType::AT_LSL_TEXT || mItemAssetType == LLAssetType::AT_NOTECARD ||
|
||||
mItemAssetType == LLAssetType::AT_GESTURE || mItemAssetType == LLAssetType::AT_MATERIAL)
|
||||
{
|
||||
current_item->openItem();
|
||||
}
|
||||
}
|
||||
}
|
||||
// Turn off the do action
|
||||
mState = EAddNewItemState::MOVE_INT_TO_TRASH_START;
|
||||
}
|
||||
else if (mState == EAddNewItemState::MOVE_INT_TO_TRASH_START)
|
||||
{
|
||||
// Once the object's inventory is done being processed, can switch back to the idle state
|
||||
if (LLViewerObject* objectp = gObjectList.findObject(panel_object_inv->getTaskUUID()))
|
||||
{
|
||||
// If there is no original item (LSL scripts), can go back to normal
|
||||
if (mOriginalItemUUID.isNull())
|
||||
{
|
||||
onRemoveItemDone();
|
||||
}
|
||||
// Else if the inveotory is not pending and not dirty, then we want to move to the next step.
|
||||
else if (objectp && !objectp->isInventoryPending() && !objectp->isInventoryDirty())
|
||||
{
|
||||
// Remove the original inventory item and do a callback to set the
|
||||
// state to the next one once it finishes.
|
||||
LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(FSNewItemCtrl::onRemoveItemDone));
|
||||
remove_inventory_item(mOriginalItemUUID, cb);
|
||||
// Set the state to the move iventory to trash, which will spin until the callback is triggered
|
||||
mState = EAddNewItemState::MOVE_INT_TO_TRASH;
|
||||
}
|
||||
}
|
||||
}
|
||||
// No need to MOVE_INT_TO_TRASH as it's handled by the onRemoveItemDone callback method.
|
||||
}
|
||||
|
||||
// <FS:mjr> [FIRE-36685] - Toolbox Window - Add new notecard button to Content tab
|
||||
// static
|
||||
// Callback method for when an item is removed from the avatar's inventory to reset the internal state
|
||||
void FSNewItemCtrl::onRemoveItemDone()
|
||||
{
|
||||
// Store the pointer to the FSNewItemCtrl as a static value as it is a singleton and
|
||||
// saves from having to be called all the time.
|
||||
static FSNewItemCtrl* self = FSNewItemCtrl::getInstance();
|
||||
if (self)
|
||||
{
|
||||
// Set the new item state back to idle
|
||||
self->setState(FSNewItemCtrl::EAddNewItemState::IDLE);
|
||||
self->callFinishNewItem();
|
||||
}
|
||||
}
|
||||
|
||||
// Call the Finish New Item callback method if it is valid.
|
||||
void FSNewItemCtrl::callFinishNewItem()
|
||||
{
|
||||
if (mFinishNewItemCallback)
|
||||
mFinishNewItemCallback();
|
||||
}
|
||||
|
||||
void FSNewItemCtrl::onCreateInvDone(LLHandle<LLPanel> handle, const LLUUID& new_id, const void_callback_t& cb)
|
||||
{
|
||||
gInventory.notifyObservers();
|
||||
LLPanelContents* panel = (LLPanelContents*)handle.get();
|
||||
|
||||
if (panel && new_id.notNull())
|
||||
{
|
||||
// The the selected object's root object
|
||||
const bool children_ok = true;
|
||||
LLPointer<LLViewerObject> object = LLSelectMgr::getInstance()->getSelection()->getFirstRootObject(children_ok);
|
||||
|
||||
if (object && new_id.notNull())
|
||||
{
|
||||
// Get the Inventory Item from the new ID passed in
|
||||
LLViewerInventoryItem* item = gInventory.getItem(new_id);
|
||||
if (item)
|
||||
{
|
||||
// If the item can move to the target object
|
||||
if (LLToolDragAndDrop::isInventoryDropAcceptable(object, item))
|
||||
{
|
||||
// Set the panel to treat the newest item as a new item and needs to perform an action on it.
|
||||
startDNDInvToObject(item->getUUID(), cb);
|
||||
// Drag and Drop the new item into the inventory of the object.
|
||||
LLToolDragAndDrop::dropInventory(object, item, LLToolDragAndDrop::SOURCE_AGENT, gAgentID);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS() << "Could not transfer new item with ID: " << new_id << LL_ENDL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FSNewItemCtrl::startDNDInvToObject(const LLUUID& original_UUID, const void_callback_t& cb)
|
||||
{
|
||||
// Store the UUID of the original item drag and dropped by the script
|
||||
// so once it is finished with, can then next move to the avatar's trash.
|
||||
mOriginalItemUUID = original_UUID;
|
||||
// Flag that an action needs to take place on the newest item
|
||||
mState = EAddNewItemState::DND_INV_TO_OBJECT_START;
|
||||
|
||||
// Set the finish new item callback to the one passed in, defaults to null.
|
||||
mFinishNewItemCallback = cb;
|
||||
}
|
||||
|
||||
bool FSNewItemCtrl::checkAgainstLatestObject(const LLPointer<LLInventoryObject> &obj)
|
||||
{
|
||||
// If there is a need to do an action on the item, then
|
||||
if (mState == EAddNewItemState::DND_INV_TO_OBJECT_START)
|
||||
{
|
||||
// This is needed to be able to convert the LLPointer<LLInventoryObject> to an LLInventoryItem*.
|
||||
// Issue is the existing methods ends up returning a const pointer, which you then cannnot
|
||||
// act upon or return with a static method call.
|
||||
LLInventoryObject* current_object = obj;
|
||||
LLInventoryItem* current_item = dynamic_cast<LLInventoryItem*>(current_object);
|
||||
|
||||
// Need to search for the newest item as the new item recieved a new UUID so the one
|
||||
// from the LLPanelContents.cpp no longer exists.
|
||||
// Use the CreationDate of the item to determine which is the newer item.
|
||||
if (current_item && current_item->getCreationDate() > mLatestCreationTime)
|
||||
{
|
||||
// Store the latest creation date
|
||||
mLatestCreationTime = current_item->getCreationDate();
|
||||
// Store the current items new UUID and action type (for use to determine if the item needs to be opened)
|
||||
mNewItemUUID = current_item->getUUID();
|
||||
mItemAssetType = current_item->getActualType();
|
||||
mLatestCreatedItem = current_item;
|
||||
|
||||
// Return true as there was a newer item was found
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// Return false as there was no newer item found
|
||||
return false;
|
||||
}
|
||||
|
||||
// Store the show invengory flags and disables them.
|
||||
// Used to hide the item floaters attached to the new avatar items
|
||||
// so the user does not edit the wrong items.
|
||||
void FSNewItemCtrl::saveAndClearInventoryFlags()
|
||||
{
|
||||
// Save the show new, in and gesture inventory settings
|
||||
S32 backup_inventory_flags = 0;
|
||||
backup_inventory_flags |= S32(gSavedSettings.getBOOL("ShowNewInventory")) * SHOW_NEW_INVENTORY;
|
||||
backup_inventory_flags |= S32(gSavedSettings.getBOOL("ShowInInventory")) * SHOW_IN_INVENTORY;
|
||||
backup_inventory_flags |= S32(gSavedSettings.getBOOL("ShowGestureInventory")) * SHOW_GESTURE_INVENTORY;
|
||||
gSavedSettings.setS32("BackupInventoryFlags", backup_inventory_flags);
|
||||
|
||||
// do not pop up preview floaters when creating new and in inventory items.
|
||||
gSavedSettings.setBOOL("ShowNewInventory", false);
|
||||
gSavedSettings.setBOOL("ShowInInventory", false);
|
||||
gSavedSettings.setBOOL("ShowGestureInventory", false);
|
||||
}
|
||||
|
||||
// Restores the Show Inventory settings.xml flags.
|
||||
void FSNewItemCtrl::restoreInventoryFlags()
|
||||
{
|
||||
// Restore the show new inventory current settings
|
||||
S32 backup_inventory_flags = gSavedSettings.getS32("BackupInventoryFlags");
|
||||
gSavedSettings.setBOOL("ShowGestureInventory", bool(backup_inventory_flags & SHOW_GESTURE_INVENTORY));
|
||||
gSavedSettings.setBOOL("ShowNewInventory", bool(backup_inventory_flags & SHOW_NEW_INVENTORY));
|
||||
gSavedSettings.setBOOL("ShowInInventory", bool(backup_inventory_flags & SHOW_IN_INVENTORY));
|
||||
}
|
||||
// </FS:mjr> [FIRE-36685]
|
||||
@@ -0,0 +1,101 @@
|
||||
/**
|
||||
* @file fsnewitemctrl.h
|
||||
* @brief A singleton controller for handling adding new items to Objects using Build Window's Content tab.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2026&license=viewerlgpl$
|
||||
* Phoenix Firestorm Viewer Source Code
|
||||
* Copyright (c) 2026 minerjr @ The Phoenix Firestorm Project, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef FSNEWITEMCTRL_H
|
||||
#define FSNEWITEMCTRL_H
|
||||
|
||||
// <FS:mjr> [FIRE-36685] - Toolbox Window - Add new notecard button to Content tab
|
||||
|
||||
#include "llsingleton.h"
|
||||
#include "llpanelobjectinventory.h"
|
||||
|
||||
class LLPanelContents;
|
||||
|
||||
class FSNewItemCtrl : public LLSingleton<FSNewItemCtrl>
|
||||
{
|
||||
LLSINGLETON(FSNewItemCtrl);
|
||||
~FSNewItemCtrl();
|
||||
|
||||
public:
|
||||
enum EAddNewItemState
|
||||
{
|
||||
IDLE = 0,
|
||||
DND_INV_TO_OBJECT_START,
|
||||
DND_INV_TO_OBJECT,
|
||||
DND_INV_TO_OBJECT_DONE,
|
||||
MOVE_INT_TO_TRASH_START,
|
||||
MOVE_INT_TO_TRASH,
|
||||
MOVE_INT_TO_TRASH_DONE
|
||||
};
|
||||
|
||||
static const S32 SHOW_NEW_INVENTORY = 1;
|
||||
static const S32 SHOW_IN_INVENTORY = 2;
|
||||
static const S32 SHOW_GESTURE_INVENTORY = 4;
|
||||
|
||||
typedef std::function<void()> void_callback_t;
|
||||
typedef std::function<void(LLPanelContents *, const LLUUID &new_id)> panel_contents_callback_t;
|
||||
|
||||
void init();
|
||||
|
||||
void processStates(LLPanelObjectInventory* panel_object_inv);
|
||||
static void onRemoveItemDone(); // Callback
|
||||
void callFinishNewItem();
|
||||
// Used by the LLPanelContents to let this class to enable rename, sticky sort location
|
||||
// and open the supported window if need be.
|
||||
void onCreateInvDone(LLHandle<LLPanel> handle, const LLUUID& new_id, const void_callback_t& cb = nullptr);
|
||||
void startDNDInvToObject(const LLUUID& original_UUID, const void_callback_t& cb = nullptr);
|
||||
void saveAndClearInventoryFlags(); // Saves the Show Inventory settings.xml flags and clears therm
|
||||
void restoreInventoryFlags();// Restores the Show Inventory settings.xml flags.
|
||||
|
||||
const LLUUID& getNewItemUUID() const { return mNewItemUUID; }
|
||||
void setNewItemUUID(const LLUUID &new_uuid) { mNewItemUUID = new_uuid; }
|
||||
|
||||
const LLUUID& getOriginalItemUUID() const { return mOriginalItemUUID; }
|
||||
void setOriginalItemUUID(const LLUUID& new_uuid) { mOriginalItemUUID = new_uuid; }
|
||||
|
||||
const LLAssetType::EType getItemAssetType() const { return mItemAssetType; }
|
||||
void setItemAssetType(LLAssetType::EType new_type) { mItemAssetType = new_type; }
|
||||
|
||||
EAddNewItemState getState() const { return mState; }
|
||||
void setState(const EAddNewItemState new_state) { mState = new_state; }
|
||||
bool checkState(const EAddNewItemState check_state) const { return mState == check_state; }
|
||||
bool isStateIdle() const { return mState == EAddNewItemState::IDLE; }
|
||||
|
||||
void resetLatestCreationTime() { mLatestCreationTime = 0; }
|
||||
bool checkAgainstLatestObject(const LLPointer<LLInventoryObject> &obj);
|
||||
|
||||
void setFinishNewItemCallback(void_callback_t cb) { mFinishNewItemCallback = cb; }
|
||||
|
||||
protected:
|
||||
|
||||
EAddNewItemState mState; // Flags if there is a item that needs an action performed on it.
|
||||
LLAssetType::EType mItemAssetType; // Stores the action type of the new item, used for idenifying the idem.
|
||||
LLUUID mOriginalItemUUID; // Stores the UUID of the item that was first passed to be transfered. UUID is changed when added to object's inventory
|
||||
LLUUID mNewItemUUID; // The UUID will change when moved so that cannot be used for tracking which item needs to be acted upon.
|
||||
time_t mLatestCreationTime; // Stores the latest creation time, used for finding the object with the latest version.
|
||||
LLInventoryItem* mLatestCreatedItem; // Stores the pointer to the latest item found.
|
||||
void_callback_t mFinishNewItemCallback; // Function pointer used as a callback for when the new item is finished.
|
||||
};
|
||||
// </FS:mjr> [FIRE-36685]
|
||||
#endif
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "llinventorypanel.h"
|
||||
#include "lltooldraganddrop.h"
|
||||
#include "llfavoritesbar.h"
|
||||
#include "fsnewitemctrl.h" // <FS:mjr> [FIRE-36685] - Toolbox Window - Add new notecard button to Content tab
|
||||
|
||||
//
|
||||
// class LLFolderViewModelInventory
|
||||
@@ -333,6 +334,24 @@ bool LLFolderViewModelItemInventory::filter(LLFolderViewFilter& filter)
|
||||
|
||||
bool LLInventorySort::operator()(const LLFolderViewModelItemInventory* const& a, const LLFolderViewModelItemInventory* const& b) const
|
||||
{
|
||||
// <FS:mjr> [FIRE-36685] - Toolbox Window - Add new notecard button to Content tab
|
||||
// Store a static pointer to the singleton FSNewItemCtrl so that it only has to be looked up once.
|
||||
static FSNewItemCtrl* new_item_ctrl = FSNewItemCtrl::getInstance();
|
||||
// When new items are created with the Build Widow, want the new item to appear at
|
||||
// the top of the list so the user can edit the name.
|
||||
// Stores the UUID of the new item as a static value in the LLPanelObjectInventory.
|
||||
if (!new_item_ctrl->getNewItemUUID().isNull())
|
||||
{
|
||||
if (a->getUUID() == new_item_ctrl->getNewItemUUID())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (b->getUUID() == new_item_ctrl->getNewItemUUID())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// </FS:mjr> [FIRE-36685]
|
||||
// Ignore sort order for landmarks in the Favorites folder.
|
||||
// In that folder, landmarks should be always sorted as in the Favorites bar. See EXT-719
|
||||
if (a->getSortGroup() == SG_ITEM
|
||||
|
||||
@@ -67,6 +67,7 @@
|
||||
#include "rlvhandler.h"
|
||||
#include "rlvlocks.h"
|
||||
// [/RLVa:KB]
|
||||
#include "fsnewitemctrl.h" // <FS:mjr> [FIRE-36685] - Toolbox Window - Add new notecard button to Content tab
|
||||
|
||||
//
|
||||
// Imported globals
|
||||
@@ -89,6 +90,7 @@ bool LLPanelContents::postBuild()
|
||||
setMouseOpaque(false);
|
||||
|
||||
childSetAction("button new script",&LLPanelContents::onClickNewScript, this);
|
||||
childSetAction("button new notecard", &LLPanelContents::onClickNewNotecard, this); // <FS:mjr> [FIRE-36685] - Toolbox Window - Add new notecard button to Content tab
|
||||
childSetAction("button permissions",&LLPanelContents::onClickPermissions, this);
|
||||
childSetAction("btn_reset_scripts", &LLPanelContents::onClickResetScripts, this); // <FS> Script reset in edit floater
|
||||
childSetAction("button refresh",&LLPanelContents::onClickRefresh, this);
|
||||
@@ -123,6 +125,13 @@ void LLPanelContents::getState(LLViewerObject *objectp )
|
||||
{
|
||||
getChildView("button new script")->setEnabled(false);
|
||||
getChildView("btn_reset_scripts")->setEnabled(false); // <FS> Script reset in edit floater
|
||||
// <FS:mjr> [FIRE-36685] - Toolbox Window - Add new notecard button to Content tab
|
||||
getChildView("button new notecard")->setEnabled(false);
|
||||
// Store a static pointer to the singleton FSNewItemCtrl so that it only has to be looked up once.
|
||||
static FSNewItemCtrl* new_item_ctrl = FSNewItemCtrl::getInstance();
|
||||
// Want to clear the saved New Item UUID as we may click on another object
|
||||
new_item_ctrl->setNewItemUUID(LLUUID::null);
|
||||
// </FS:mjr> [FIRE-36685]
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -169,6 +178,7 @@ void LLPanelContents::getState(LLViewerObject *objectp )
|
||||
}
|
||||
|
||||
getChildView("button new script")->setEnabled(objectIsOK);
|
||||
getChildView("button new notecard")->setEnabled(objectIsOK); // <FS:mjr> [FIRE-36685] - Toolbox Window - Add new notecard button to Content tab
|
||||
getChildView("btn_reset_scripts")->setEnabled(objectIsOK);
|
||||
// </FS:PP>
|
||||
|
||||
@@ -263,6 +273,12 @@ void LLPanelContents::clearContents()
|
||||
// static
|
||||
void LLPanelContents::onClickNewScript(void *userdata)
|
||||
{
|
||||
// <FS:mjr> [FIRE-36685] - Toolbox Window - Add new notecard button to Content tab
|
||||
// Store a static pointer to the singleton FSNewItemCtrl so that it only has to be looked up once.
|
||||
static FSNewItemCtrl* new_item_ctrl = FSNewItemCtrl::getInstance();
|
||||
// Get the Panel Contents from the userdata void pointer.
|
||||
LLPanelContents* self = (LLPanelContents*)userdata;
|
||||
// </FS:mjr> [FIRE-36685]
|
||||
const bool children_ok = true;
|
||||
LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getFirstRootObject(children_ok);
|
||||
if(object)
|
||||
@@ -289,6 +305,10 @@ void LLPanelContents::onClickNewScript(void *userdata)
|
||||
{
|
||||
if (auto custom_script = gInventory.getItem(custom_script_id); custom_script && custom_script->getType() == LLAssetType::AT_LSL_TEXT)
|
||||
{
|
||||
// <FS:mjr> [FIRE-36685] - Toolbox Window - Add new notecard button to Content tab
|
||||
// Flag the new script to also needs to be scrolled to and opened if needed.
|
||||
new_item_ctrl->startDNDInvToObject(LLUUID::null, std::bind(&LLPanelContents::onFinishCreateItem, self));
|
||||
// </FS:mjr> [FIRE-36685]
|
||||
LLToolDragAndDrop::dropScript(object, custom_script, true, LLToolDragAndDrop::SOURCE_AGENT, gAgentID);
|
||||
return;
|
||||
}
|
||||
@@ -308,6 +328,10 @@ void LLPanelContents::onClickNewScript(void *userdata)
|
||||
PERM_MOVE | LLFloaterPerms::getNextOwnerPerms("Scripts"));
|
||||
std::string desc;
|
||||
LLViewerAssetType::generateDescriptionFor(LLAssetType::AT_LSL_TEXT, desc);
|
||||
// <FS:mjr> [FIRE-36685] - Toolbox Window - Add new notecard button to Content tab
|
||||
// Flag the new script to also needs to be scrolled to and opened if needed.
|
||||
new_item_ctrl->startDNDInvToObject(LLUUID::null, std::bind(&LLPanelContents::onFinishCreateItem, self));
|
||||
// </FS:mjr> [FIRE-36685]
|
||||
LLPointer<LLViewerInventoryItem> new_item =
|
||||
new LLViewerInventoryItem(
|
||||
LLUUID::null,
|
||||
@@ -355,3 +379,70 @@ void LLPanelContents::onClickRefresh(void *userdata)
|
||||
LLPanelContents* self = (LLPanelContents*)userdata;
|
||||
self->refresh();
|
||||
}
|
||||
|
||||
// <FS:mjr> [FIRE-36685] - Toolbox Window - Add new notecard button to Content tab
|
||||
// static
|
||||
void LLPanelContents::onClickNewNotecard(void* userdata)
|
||||
{
|
||||
// Store a static pointer to the singleton FSNewItemCtrl so that it only has to be looked up once.
|
||||
static FSNewItemCtrl* new_item_ctrl = FSNewItemCtrl::getInstance();
|
||||
// Get the Panel Contents from the userdata void pointer.
|
||||
LLPanelContents* self = (LLPanelContents*)userdata;
|
||||
// Maintain RLV support for notecard object type being added.
|
||||
const bool children_ok = true;
|
||||
LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getFirstRootObject(children_ok);
|
||||
|
||||
// [RLVa:KB] - Checked: 2010-03-31 (RLVa-1.2.0c) | Modified: RLVa-1.0.5a
|
||||
if (rlv_handler_t::isEnabled()) // Fallback code [see LLPanelContents::getState()]
|
||||
{
|
||||
if (gRlvAttachmentLocks.isLockedAttachment(object->getRootEdit()))
|
||||
{
|
||||
return; // Disallow creating new scripts in a locked attachment
|
||||
}
|
||||
else if ((gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT)) || (gRlvHandler.hasBehaviour(RLV_BHVR_SITTP)))
|
||||
{
|
||||
if ((isAgentAvatarValid()) && (gAgentAvatarp->isSitting()) && (gAgentAvatarp->getRoot() == object->getRootEdit()))
|
||||
return; // .. or in a linkset the avie is sitting on under @unsit=n/@sittp=n
|
||||
}
|
||||
}
|
||||
// [/RLVa:KB]
|
||||
|
||||
// Need to disable the new notecard button to prevent spaming the button and causing inventory issues
|
||||
self->getChildView("button new notecard")->setEnabled(false);
|
||||
// Need to save the filter first so it is not lost
|
||||
std::string save_filter = self->mFilterEditor->getText();
|
||||
// Clear the actual filter
|
||||
self->mFilterEditor->setText(LLStringExplicit(""));
|
||||
// Update the filter state
|
||||
self->onFilterEdit();
|
||||
// </FS:Ansariel>
|
||||
// Create the LLSD paramater for the new notecard
|
||||
LLSD component("notecard");
|
||||
|
||||
// Callback handle to allow for moving the new item to the object from the avatar inventory
|
||||
// Also moves the new item in the users avatar inventory to the trash.
|
||||
// Will also open up the dialog for Gesture and Notecards in the object's inventory.
|
||||
LLHandle<LLPanel> handle = self->getHandle();
|
||||
std::function<void(const LLUUID&)> callback_item_created = [handle](const LLUUID& new_id)
|
||||
{
|
||||
// Call the on Create Inventory Done of the new item controller which will kick off next steps
|
||||
new_item_ctrl->onCreateInvDone(handle, new_id, std::bind(&LLPanelContents::onFinishCreateItem, (LLPanelContents*)handle.get()));
|
||||
};
|
||||
|
||||
// Save and clear the Show Inventroy flags used to prevent the floaters appearing
|
||||
// when items that have floaters like the Notecard, Gesture, Material and Script
|
||||
// from opening the temp item in the avatars inventory.
|
||||
new_item_ctrl->saveAndClearInventoryFlags();
|
||||
// Create the new item using the menu system in the user's avatar inventory.
|
||||
// The callback from above will move the item to the object and remove it from the user's inventory after.
|
||||
menu_create_inventory_item(NULL, LLUUID::null, component, LLUUID::null, callback_item_created);
|
||||
// Restore the filter
|
||||
self->mFilterEditor->setText(LLStringExplicit(save_filter));
|
||||
}
|
||||
|
||||
// Callback method for when the item finishes
|
||||
void LLPanelContents::onFinishCreateItem()
|
||||
{
|
||||
getChildView("button new notecard")->setEnabled(true);
|
||||
}
|
||||
// </FS:mjr> [FIRE-36685]
|
||||
|
||||
@@ -51,8 +51,13 @@ public:
|
||||
void refresh();
|
||||
void clearContents();
|
||||
|
||||
// <FS:mjr> [FIRE-36685] - Toolbox Window - Add new notecard button to Content tab
|
||||
void onClickAddItemToObject(); // Adds the actual item to the object's Content Inventory.
|
||||
void onFinishCreateItem();
|
||||
// </FS:mjr> [FIRE-36685]
|
||||
|
||||
static void onClickNewScript(void*);
|
||||
static void onClickNewNotecard(void*); // <FS:mjr> [FIRE-36685] - Toolbox Window - Add new notecard button to Content tab
|
||||
static void onClickPermissions(void*);
|
||||
static void onClickResetScripts(void*); // <FS> Script reset in edit floater
|
||||
static void onClickRefresh(void*);
|
||||
|
||||
@@ -73,6 +73,7 @@
|
||||
#include "rlvlocks.h"
|
||||
// [/RLVa:KB]
|
||||
#include "llfloaterproperties.h" // <FS:Ansariel> Keep legacy properties floater
|
||||
#include "fsnewitemctrl.h" // <FS:mjr> [FIRE-36685] - Toolbox Window - Add new notecard button to Content tab
|
||||
|
||||
const LLColor4U DEFAULT_WHITE(255, 255, 255);
|
||||
#include "tea.h" // <FS:AW opensim currency support>
|
||||
@@ -1797,6 +1798,12 @@ void LLPanelObjectInventory::createViewsForCategory(LLInventoryObject::object_li
|
||||
{
|
||||
LLUIColor item_color = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
|
||||
|
||||
// <FS:mjr> [FIRE-36685] - Toolbox Window - Add new notecard button to Content tab
|
||||
// Store a static pointer to the singleton FSNewItemCtrl so that it only has to be looked up once.
|
||||
static FSNewItemCtrl* new_item_ctrl = FSNewItemCtrl::getInstance();
|
||||
// Reset the latest creation time, to allow for finding the newest item below.
|
||||
new_item_ctrl->resetLatestCreationTime();
|
||||
// </FS:mjr> [FIRE-36685]
|
||||
// Find all in the first pass
|
||||
std::vector<obj_folder_pair*> child_categories;
|
||||
for (const LLPointer<LLInventoryObject>& obj : *inventory)
|
||||
@@ -1850,6 +1857,10 @@ void LLPanelObjectInventory::createViewsForCategory(LLInventoryObject::object_li
|
||||
// </FS:Ansariel>
|
||||
|
||||
view = LLUICtrlFactory::create<LLFolderViewItem>(params);
|
||||
// <FS:mjr> [FIRE-36685] - Toolbox Window - Add new notecard button to Content tab
|
||||
// Check the current object against the existing newest item
|
||||
new_item_ctrl->checkAgainstLatestObject(obj);
|
||||
// </FS:mjr> [FIRE-36685]
|
||||
}
|
||||
|
||||
view->addToFolder(folder);
|
||||
@@ -1865,6 +1876,15 @@ void LLPanelObjectInventory::createViewsForCategory(LLInventoryObject::object_li
|
||||
delete pair;
|
||||
}
|
||||
folder->setChildrenInited(true);
|
||||
// <FS:mjr> [FIRE-36685] - Toolbox Window - Add new notecard button to Content tab
|
||||
// Switch to the next state if not already done so.
|
||||
// Check to see if the new item control is in the drag and drop inventory to object start state
|
||||
if (new_item_ctrl->checkState(FSNewItemCtrl::DND_INV_TO_OBJECT_START))
|
||||
{
|
||||
// If so, can move on to the next state
|
||||
new_item_ctrl->setState(FSNewItemCtrl::DND_INV_TO_OBJECT);
|
||||
}
|
||||
// </FS:mjr> [FIRE-36685]
|
||||
}
|
||||
|
||||
void LLPanelObjectInventory::refresh()
|
||||
@@ -2028,6 +2048,12 @@ void LLPanelObjectInventory::idle(void* user_data)
|
||||
{
|
||||
self->updateInventory();
|
||||
}
|
||||
// <FS:mjr> [FIRE-36685] - Toolbox Window - Add new notecard button to Content tab
|
||||
// Store a static pointer to the singleton FSNewItemCtrl so that it only has to be looked up once.
|
||||
static FSNewItemCtrl* new_item_ctrl = FSNewItemCtrl::getInstance();
|
||||
// Process the current state using the current LLPanelObjectInveotory
|
||||
new_item_ctrl->processStates(self);
|
||||
// <FS:mjr> [FIRE-36685]
|
||||
}
|
||||
|
||||
void LLPanelObjectInventory::onFocusLost()
|
||||
|
||||
@@ -47,6 +47,9 @@ class LLViewerObject;
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
class LLPanelObjectInventory : public LLPanel, public LLVOInventoryListener
|
||||
{
|
||||
// <FS:mjr> [FIRE-36685] - Toolbox Window - Add new notecard button to Content tab
|
||||
friend class FSNewItemCtrl; // Need to declare FSNewItemCtrl a friend class to access the protected methods(getItemByID())
|
||||
// </FS:mjr> [FIRE-36685]
|
||||
public:
|
||||
struct Params : public LLInitParam::Block<Params, LLPanel::Params>
|
||||
{
|
||||
|
||||
@@ -3689,7 +3689,7 @@ Low ↔ Lwst
|
||||
width="295">
|
||||
<button
|
||||
follows="left|top"
|
||||
height="35"
|
||||
height="16"
|
||||
label="New Script"
|
||||
label_selected="New Script"
|
||||
layout="topleft"
|
||||
@@ -3699,12 +3699,25 @@ Low ↔ Lwst
|
||||
width="90"
|
||||
font="DejaVu"
|
||||
font.size="LSmall" />
|
||||
<button
|
||||
follows="left|top"
|
||||
height="16"
|
||||
label="New Notecard"
|
||||
label_selected="New Notecard"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
name="button new notecard"
|
||||
top_pad="4"
|
||||
width="90"
|
||||
font="DejaVu"
|
||||
font.size="LSmall" />
|
||||
<button
|
||||
follows="left|top"
|
||||
height="35"
|
||||
label="Permissions"
|
||||
layout="topleft"
|
||||
left_pad="5"
|
||||
top="8"
|
||||
name="button permissions"
|
||||
width="80"
|
||||
font="DejaVu"
|
||||
|
||||
Reference in New Issue
Block a user