summaryrefslogtreecommitdiff
path: root/indra/newview/llpreviewnotecard.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llpreviewnotecard.cpp')
-rw-r--r--indra/newview/llpreviewnotecard.cpp579
1 files changed, 579 insertions, 0 deletions
diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp
new file mode 100644
index 0000000000..e88c702453
--- /dev/null
+++ b/indra/newview/llpreviewnotecard.cpp
@@ -0,0 +1,579 @@
+/**
+ * @file llpreviewnotecard.cpp
+ * @brief Implementation of the notecard editor
+ *
+ * Copyright (c) 2002-$CurrentYear$, Linden Research, Inc.
+ * $License$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llpreviewnotecard.h"
+
+#include "llinventory.h"
+
+#include "llagent.h"
+#include "llviewerwindow.h"
+#include "llbutton.h"
+#include "llinventorymodel.h"
+#include "lllineeditor.h"
+#include "llnotify.h"
+#include "llresmgr.h"
+#include "roles_constants.h"
+#include "llscrollbar.h"
+#include "llselectmgr.h"
+#include "llviewertexteditor.h"
+#include "llvfile.h"
+#include "llviewerinventory.h"
+#include "llviewerobject.h"
+#include "llviewerobjectlist.h"
+#include "llviewerregion.h"
+#include "lldir.h"
+//#include "llfloaterchat.h"
+#include "llviewerstats.h"
+#include "viewer.h" // app_abort_quit()
+#include "lllineeditor.h"
+#include "llvieweruictrlfactory.h"
+
+///----------------------------------------------------------------------------
+/// Local function declarations, constants, enums, and typedefs
+///----------------------------------------------------------------------------
+
+const S32 PREVIEW_MIN_WIDTH =
+ 2 * PREVIEW_BORDER +
+ 2 * PREVIEW_BUTTON_WIDTH +
+ PREVIEW_PAD + RESIZE_HANDLE_WIDTH +
+ PREVIEW_PAD;
+const S32 PREVIEW_MIN_HEIGHT =
+ 2 * PREVIEW_BORDER +
+ 3*(20 + PREVIEW_PAD) +
+ 2 * SCROLLBAR_SIZE + 128;
+
+///----------------------------------------------------------------------------
+/// Class LLPreviewNotecard
+///----------------------------------------------------------------------------
+
+// Default constructor
+LLPreviewNotecard::LLPreviewNotecard(const std::string& name,
+ const LLRect& rect,
+ const std::string& title,
+ const LLUUID& item_id,
+ const LLUUID& object_id,
+ const LLUUID& asset_id,
+ BOOL show_keep_discard) :
+ LLPreview(name, rect, title, item_id, object_id, TRUE,
+ PREVIEW_MIN_WIDTH,
+ PREVIEW_MIN_HEIGHT),
+ mAssetID( asset_id ),
+ mNotecardItemID(item_id),
+ mObjectID(object_id)
+{
+ LLRect curRect = rect;
+
+ if (show_keep_discard)
+ {
+ gUICtrlFactory->buildFloater(this,"floater_preview_notecard_keep_discard.xml");
+ childSetAction("Keep",onKeepBtn,this);
+ childSetAction("Discard",onDiscardBtn,this);
+ }
+ else
+ {
+ gUICtrlFactory->buildFloater(this,"floater_preview_notecard.xml");
+ childSetAction("Save",onClickSave,this);
+
+ if( mAssetID.isNull() )
+ {
+ LLInventoryItem* item = getItem();
+ if( item )
+ {
+ mAssetID = item->getAssetUUID();
+ }
+ }
+ }
+
+ reshape(curRect.getWidth(), curRect.getHeight(), TRUE);
+ setRect(curRect);
+
+ childSetVisible("lock", FALSE);
+
+ LLInventoryItem* item = getItem();
+
+ childSetCommitCallback("desc", LLPreview::onText, this);
+ if (item)
+ childSetText("desc", item->getDescription());
+ childSetPrevalidate("desc", &LLLineEditor::prevalidatePrintableNotPipe);
+
+ setTitle(title);
+
+ LLViewerTextEditor* editor = LLViewerUICtrlFactory::getViewerTextEditorByName(this, "Notecard Editor");
+
+ if (editor)
+ {
+ editor->setWordWrap(TRUE);
+ editor->setSourceID(item_id);
+ editor->setHandleEditKeysDirectly(TRUE);
+ }
+
+ gAgent.changeCameraToDefault();
+}
+
+BOOL LLPreviewNotecard::postBuild()
+{
+ LLViewerTextEditor *ed = (LLViewerTextEditor *)gUICtrlFactory->getTextEditorByName(this, "Notecard Editor");
+ if (ed)
+ {
+ ed->setNotecardInfo(mNotecardItemID, mObjectID);
+ }
+ return TRUE;
+}
+
+bool LLPreviewNotecard::saveItem(LLPointer<LLInventoryItem>* itemptr)
+{
+ LLInventoryItem* item = NULL;
+ if (itemptr && itemptr->notNull())
+ {
+ item = (LLInventoryItem*)(*itemptr);
+ }
+ bool res = saveIfNeeded(item);
+ if (res)
+ {
+ delete itemptr;
+ }
+ return res;
+}
+
+void LLPreviewNotecard::setEnabled( BOOL enabled )
+{
+
+ LLViewerTextEditor* editor = LLViewerUICtrlFactory::getViewerTextEditorByName(this, "Notecard Editor");
+
+ childSetEnabled("Notecard Editor", enabled);
+ childSetVisible("lock", !enabled);
+ childSetEnabled("desc", enabled);
+ childSetEnabled("Save", enabled && editor && (!editor->isPristine()));
+
+}
+
+
+void LLPreviewNotecard::draw()
+{
+
+
+ //childSetFocus("Save", FALSE);
+
+ LLViewerTextEditor* editor = LLViewerUICtrlFactory::getViewerTextEditorByName(this, "Notecard Editor");
+ BOOL script_changed = !editor->isPristine();
+
+ childSetEnabled("Save", script_changed && getEnabled());
+
+ LLPreview::draw();
+}
+
+// virtual
+BOOL LLPreviewNotecard::handleKeyHere(KEY key, MASK mask,
+ BOOL called_from_parent)
+{
+ if(getVisible() && getEnabled())
+ {
+ if(('S' == key) && (MASK_CONTROL == (mask & MASK_CONTROL)))
+ {
+ saveIfNeeded();
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+// virtual
+BOOL LLPreviewNotecard::canClose()
+{
+ LLViewerTextEditor* editor = LLViewerUICtrlFactory::getViewerTextEditorByName(this, "Notecard Editor");
+
+ if(mForceClose || editor->isPristine())
+ {
+ return TRUE;
+ }
+ else
+ {
+ // Bring up view-modal dialog: Save changes? Yes, No, Cancel
+ gViewerWindow->alertXml("SaveChanges",
+ &LLPreviewNotecard::handleSaveChangesDialog,
+ this);
+
+ return FALSE;
+ }
+}
+
+const LLInventoryItem* LLPreviewNotecard::getDragItem()
+{
+ LLViewerTextEditor* editor = LLViewerUICtrlFactory::getViewerTextEditorByName(this, "Notecard Editor");
+
+ if(editor)
+ {
+ return editor->getDragItem();
+ }
+ return NULL;
+}
+
+void LLPreviewNotecard::loadAsset()
+{
+ // request the asset.
+ LLInventoryItem* item = getItem();
+ LLViewerTextEditor* editor = LLViewerUICtrlFactory::getViewerTextEditorByName(this, "Notecard Editor");
+
+ if (!editor)
+ return;
+
+
+ if(item)
+ {
+ if (gAgent.allowOperation(PERM_COPY, item->getPermissions(),
+ GP_OBJECT_MANIPULATE)
+ || gAgent.isGodlike())
+ {
+ mAssetID = item->getAssetUUID();
+ if(mAssetID.isNull())
+ {
+ editor->setText("");
+ editor->makePristine();
+ editor->setEnabled(TRUE);
+ mAssetStatus = PREVIEW_ASSET_LOADED;
+ }
+ else
+ {
+ LLUUID* new_uuid = new LLUUID(mItemUUID);
+ LLHost source_sim = LLHost::invalid;
+ if (mObjectUUID.notNull())
+ {
+ LLViewerObject *objectp = gObjectList.findObject(mObjectUUID);
+ if (objectp && objectp->getRegion())
+ {
+ source_sim = objectp->getRegion()->getHost();
+ }
+ else
+ {
+ // The object that we're trying to look at disappeared, bail.
+ llwarns << "Can't find object " << mObjectUUID << " associated with notecard." << llendl;
+ mAssetID.setNull();
+ editor->setText("Unable to find object containing this note.");
+ editor->makePristine();
+ editor->setEnabled(FALSE);
+ mAssetStatus = PREVIEW_ASSET_LOADED;
+ return;
+ }
+ }
+ gAssetStorage->getInvItemAsset(source_sim,
+ gAgent.getID(),
+ gAgent.getSessionID(),
+ item->getPermissions().getOwner(),
+ mObjectUUID,
+ item->getUUID(),
+ item->getAssetUUID(),
+ item->getType(),
+ &onLoadComplete,
+ (void*)new_uuid,
+ TRUE);
+ mAssetStatus = PREVIEW_ASSET_LOADING;
+ }
+ }
+ else
+ {
+ mAssetID.setNull();
+ editor->setText("You are not allowed to view this note.");
+ editor->makePristine();
+ editor->setEnabled(FALSE);
+ mAssetStatus = PREVIEW_ASSET_LOADED;
+ }
+ if(!gAgent.allowOperation(PERM_MODIFY, item->getPermissions(),
+ GP_OBJECT_MANIPULATE))
+ {
+ editor->setEnabled(FALSE);
+ childSetVisible("lock", TRUE);
+ }
+ }
+ else
+ {
+ editor->setText("");
+ editor->makePristine();
+ editor->setEnabled(TRUE);
+ mAssetStatus = PREVIEW_ASSET_LOADED;
+ }
+}
+
+// static
+void LLPreviewNotecard::onLoadComplete(LLVFS *vfs,
+ const LLUUID& asset_uuid,
+ LLAssetType::EType type,
+ void* user_data, S32 status)
+{
+ llinfos << "LLPreviewNotecard::onLoadComplete()" << llendl;
+ LLUUID* item_id = (LLUUID*)user_data;
+ LLPreviewNotecard* preview = LLPreviewNotecard::getInstance(*item_id);
+ if( preview )
+ {
+ if(0 == status)
+ {
+ LLVFile file(vfs, asset_uuid, type, LLVFile::READ);
+
+ S32 file_length = file.getSize();
+
+ char* buffer = new char[file_length+1];
+ file.read((U8*)buffer, file_length);
+
+ // put a EOS at the end
+ buffer[file_length] = 0;
+
+
+ LLViewerTextEditor* previewEditor = LLViewerUICtrlFactory::getViewerTextEditorByName(preview, "Notecard Editor");
+
+ if( (file_length > 19) && !strncmp( buffer, "Linden text version", 19 ) )
+ {
+ if( !previewEditor->importBuffer( buffer ) )
+ {
+ llwarns << "Problem importing notecard" << llendl;
+ }
+ }
+ else
+ {
+ // Version 0 (just text, doesn't include version number)
+ previewEditor->setText(buffer);
+ }
+
+ previewEditor->makePristine();
+
+ LLInventoryItem* item = preview->getItem();
+ BOOL modifiable = item && gAgent.allowOperation(PERM_MODIFY,
+ item->getPermissions(), GP_OBJECT_MANIPULATE);
+ previewEditor->setEnabled(modifiable);
+ delete[] buffer;
+ preview->mAssetStatus = PREVIEW_ASSET_LOADED;
+ }
+ else
+ {
+ if( gViewerStats )
+ {
+ gViewerStats->incStat( LLViewerStats::ST_DOWNLOAD_FAILED );
+ }
+
+ if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status ||
+ LL_ERR_FILE_EMPTY == status)
+ {
+ LLNotifyBox::showXml("NotecardMissing");
+ }
+ else if (LL_ERR_INSUFFICIENT_PERMISSIONS == status)
+ {
+ LLNotifyBox::showXml("NotecardNoPermissions");
+ }
+ else
+ {
+ LLNotifyBox::showXml("UnableToLoadNotecard");
+ }
+
+ llwarns << "Problem loading notecard: " << status << llendl;
+ preview->mAssetStatus = PREVIEW_ASSET_ERROR;
+ }
+ }
+ delete item_id;
+}
+
+// static
+LLPreviewNotecard* LLPreviewNotecard::getInstance(const LLUUID& item_id)
+{
+ LLPreview* instance = NULL;
+ preview_map_t::iterator found_it = LLPreview::sInstances.find(item_id);
+ if(found_it != LLPreview::sInstances.end())
+ {
+ instance = found_it->second;
+ }
+ return (LLPreviewNotecard*)instance;
+}
+
+// static
+void LLPreviewNotecard::onClickSave(void* user_data)
+{
+ //llinfos << "LLPreviewNotecard::onBtnSave()" << llendl;
+ LLPreviewNotecard* preview = (LLPreviewNotecard*)user_data;
+ if(preview)
+ {
+ preview->saveIfNeeded();
+ }
+}
+
+struct LLSaveNotecardInfo
+{
+ LLPreviewNotecard* mSelf;
+ LLUUID mItemUUID;
+ LLUUID mObjectUUID;
+ LLTransactionID mTransactionID;
+ LLPointer<LLInventoryItem> mCopyItem;
+ LLSaveNotecardInfo(LLPreviewNotecard* self, const LLUUID& item_id, const LLUUID& object_id,
+ const LLTransactionID& transaction_id, LLInventoryItem* copyitem) :
+ mSelf(self), mItemUUID(item_id), mObjectUUID(object_id), mTransactionID(transaction_id), mCopyItem(copyitem)
+ {
+ }
+};
+
+bool LLPreviewNotecard::saveIfNeeded(LLInventoryItem* copyitem)
+{
+ if(!gAssetStorage)
+ {
+ llwarns << "Not connected to an asset storage system." << llendl;
+ return false;
+ }
+
+
+ LLViewerTextEditor* editor = LLViewerUICtrlFactory::getViewerTextEditorByName(this, "Notecard Editor");
+
+ if(!editor->isPristine())
+ {
+ // We need to update the asset information
+ LLTransactionID tid;
+ LLAssetID asset_id;
+ tid.generate();
+ asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
+
+ LLVFile file(gVFS, asset_id, LLAssetType::AT_NOTECARD, LLVFile::APPEND);
+
+ LLString buffer;
+ if (!editor->exportBuffer(buffer))
+ {
+ return false;
+ }
+
+ editor->makePristine();
+
+ S32 size = buffer.length() + 1;
+ file.setMaxSize(size);
+ file.write((U8*)buffer.c_str(), size);
+
+ LLInventoryItem* item = getItem();
+ // save it out to database
+ if (item)
+ {
+
+ LLSaveNotecardInfo* info = new LLSaveNotecardInfo(this, mItemUUID, mObjectUUID,
+ tid, copyitem);
+ gAssetStorage->storeAssetData(tid, LLAssetType::AT_NOTECARD,
+ &onSaveComplete,
+ (void*)info,
+ FALSE);
+ }
+ }
+ return true;
+}
+
+// static
+void LLPreviewNotecard::onSaveComplete(const LLUUID& asset_uuid, void* user_data, S32 status) // StoreAssetData callback (fixed)
+{
+ LLSaveNotecardInfo* info = (LLSaveNotecardInfo*)user_data;
+ if(info && (0 == status))
+ {
+ if(info->mObjectUUID.isNull())
+ {
+ LLViewerInventoryItem* item;
+ item = (LLViewerInventoryItem*)gInventory.getItem(info->mItemUUID);
+ if(item)
+ {
+ LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
+ new_item->setAssetUUID(asset_uuid);
+ new_item->setTransactionID(info->mTransactionID);
+ new_item->updateServer(FALSE);
+ gInventory.updateItem(new_item);
+ gInventory.notifyObservers();
+ }
+ else
+ {
+ llwarns << "Inventory item for script " << info->mItemUUID
+ << " is no longer in agent inventory." << llendl;
+ }
+ }
+ else
+ {
+ LLViewerObject* object = gObjectList.findObject(info->mObjectUUID);
+ LLViewerInventoryItem* item = NULL;
+ if(object)
+ {
+ item = (LLViewerInventoryItem*)object->getInventoryObject(info->mItemUUID);
+ }
+ if(object && item)
+ {
+ item->setAssetUUID(asset_uuid);
+ item->setTransactionID(info->mTransactionID);
+ object->updateInventory(item, TASK_INVENTORY_ITEM_KEY, false);
+ dialog_refresh_all();
+ }
+ else
+ {
+ gViewerWindow->alertXml("SaveNotecardFailObjectNotFound");
+ }
+ }
+ // Perform item copy to inventory
+ if (info->mCopyItem.notNull())
+ {
+ LLViewerTextEditor* editor = LLViewerUICtrlFactory::getViewerTextEditorByName(info->mSelf, "Notecard Editor");
+ if (editor)
+ {
+ editor->copyInventory(info->mCopyItem);
+ }
+ }
+
+ // Find our window and close it if requested.
+ LLPreviewNotecard* previewp = (LLPreviewNotecard*)LLPreview::find(info->mItemUUID);
+ if (previewp && previewp->mCloseAfterSave)
+ {
+ previewp->close();
+ }
+ }
+ else
+ {
+ llwarns << "Problem saving notecard: " << status << llendl;
+ LLStringBase<char>::format_map_t args;
+ args["[REASON]"] = std::string(LLAssetStorage::getErrorString(status));
+ gViewerWindow->alertXml("SaveNotecardFailReason",args);
+ }
+
+ char uuid_string[UUID_STR_LENGTH];
+ asset_uuid.toString(uuid_string);
+ char filename[LL_MAX_PATH];
+ sprintf(filename, "%s.tmp", gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_string).c_str());
+ LLFile::remove(filename);
+ delete info;
+}
+
+// static
+void LLPreviewNotecard::handleSaveChangesDialog(S32 option, void* userdata)
+{
+ LLPreviewNotecard* self = (LLPreviewNotecard*)userdata;
+ switch(option)
+ {
+ case 0: // "Yes"
+ self->mCloseAfterSave = TRUE;
+ LLPreviewNotecard::onClickSave((void*)self);
+ break;
+
+ case 1: // "No"
+ self->mForceClose = TRUE;
+ self->close();
+ break;
+
+ case 2: // "Cancel"
+ default:
+ // If we were quitting, we didn't really mean it.
+ app_abort_quit();
+ break;
+ }
+}
+
+void LLPreviewNotecard::reshape(S32 width, S32 height, BOOL called_from_parent)
+{
+ LLPreview::reshape( width, height, called_from_parent );
+
+ if( !isMinimized() )
+ {
+ // So that next time you open a script it will have the same height and width
+ // (although not the same position).
+ gSavedSettings.setRect("NotecardEditorRect", mRect);
+ }
+}
+
+// EOF