/** * @file llpreviewnotecard.cpp * @brief Implementation of the notecard editor * * $LicenseInfo:firstyear=2002&license=viewergpl$ * * Copyright (c) 2002-2009, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab * to you under the terms of the GNU General Public License, version 2.0 * ("GPL"), unless you have obtained a separate licensing agreement * ("Other License"), formally executed by you and Linden Lab. Terms of * the GPL can be found in doc/GPL-license.txt in this distribution, or * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 * * There are special exceptions to the terms and conditions of the GPL as * it is applied to this Source Code. View the full text of the exception * in the file doc/FLOSS-exception.txt in this software distribution, or * online at * http://secondlifegrid.net/programs/open_source/licensing/flossexception * * By copying, modifying or distributing this software, you acknowledge * that you have read and understood your obligations described above, * and agree to abide by those obligations. * * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ */ #include "llviewerprecompiledheaders.h" #include "llpreviewnotecard.h" #include "llinventory.h" #include "llagent.h" #include "llassetuploadresponders.h" #include "llviewerwindow.h" #include "llbutton.h" #include "llfilepicker.h" #include "llfloatersearchreplace.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 "llviewercontrol.h" // gSavedSettings #include "llappviewer.h" // app_abort_quit() #include "lllineeditor.h" #include "llmenugl.h" #include "lluictrlfactory.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, LLPointer inv_item) : LLPreview(name, rect, title, item_id, object_id, TRUE, PREVIEW_MIN_WIDTH, PREVIEW_MIN_HEIGHT, inv_item), mAssetID( asset_id ), mNotecardItemID(item_id), mObjectID(object_id) { LLRect curRect = rect; if (show_keep_discard) { LLUICtrlFactory::getInstance()->buildFloater(this,"floater_preview_notecard_keep_discard.xml"); childSetAction("Keep",onKeepBtn,this); childSetAction("Discard",onDiscardBtn,this); } else { LLUICtrlFactory::getInstance()->buildFloater(this,"floater_preview_notecard.xml"); childSetAction("Save",onClickSave,this); if( mAssetID.isNull() ) { const LLInventoryItem* item = getItem(); if( item ) { mAssetID = item->getAssetUUID(); } } } // only assert shape if not hosted in a multifloater if (!getHost()) { reshape(curRect.getWidth(), curRect.getHeight(), TRUE); setRect(curRect); } childSetVisible("lock", FALSE); const LLInventoryItem* item = getItem(); childSetCommitCallback("desc", LLPreview::onText, this); if (item) childSetText("desc", item->getDescription()); childSetPrevalidate("desc", &LLLineEditor::prevalidatePrintableNotPipe); setTitle(title); LLViewerTextEditor* editor = getChild("Notecard Editor"); if (editor) { editor->setWordWrap(TRUE); editor->setSourceID(item_id); editor->setHandleEditKeysDirectly(TRUE); } initMenu(); } LLPreviewNotecard::~LLPreviewNotecard() { } BOOL LLPreviewNotecard::postBuild() { LLViewerTextEditor *ed = getChild("Notecard Editor"); if (ed) { ed->setNotecardInfo(mNotecardItemID, mObjectID); ed->makePristine(); } return TRUE; } bool LLPreviewNotecard::saveItem(LLPointer* 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 = getChild("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 = getChild("Notecard Editor"); BOOL script_changed = !editor->isPristine(); childSetEnabled("Save", script_changed && getEnabled()); LLPreview::draw(); } // virtual BOOL LLPreviewNotecard::handleKeyHere(KEY key, MASK mask) { if(('S' == key) && (MASK_CONTROL == (mask & MASK_CONTROL))) { saveIfNeeded(); return TRUE; } if(('F' == key) && (MASK_CONTROL == (mask & MASK_CONTROL))) { LLFloaterSearchReplace::show(getChild("Notecard Editor")); return TRUE; } return LLPreview::handleKeyHere(key, mask); } // virtual BOOL LLPreviewNotecard::canClose() { LLViewerTextEditor* editor = getChild("Notecard Editor"); if(mForceClose || editor->isPristine()) { return TRUE; } else { // Bring up view-modal dialog: Save changes? Yes, No, Cancel LLNotifications::instance().add("SaveChanges", LLSD(), LLSD(), boost::bind(&LLPreviewNotecard::handleSaveChangesDialog,this, _1, _2)); return FALSE; } } const LLInventoryItem* LLPreviewNotecard::getDragItem() { LLViewerTextEditor* editor = getChild("Notecard Editor"); if(editor) { return editor->getDragItem(); } return NULL; } bool LLPreviewNotecard::hasEmbeddedInventory() { LLViewerTextEditor* editor = NULL; editor = getChild("Notecard Editor"); if (!editor) return false; return editor->hasEmbeddedInventory(); } void LLPreviewNotecard::refreshFromInventory() { lldebugs << "LLPreviewNotecard::refreshFromInventory()" << llendl; loadAsset(); } void LLPreviewNotecard::loadAsset() { // request the asset. const LLInventoryItem* item = getItem(); LLViewerTextEditor* editor = getChild("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(LLStringUtil::null); 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(getString("no_object")); editor->makePristine(); editor->setEnabled(FALSE); mAssetStatus = PREVIEW_ASSET_LOADED; delete new_uuid; 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(getString("not_allowed")); 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(LLStringUtil::null); 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, LLExtStat ext_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); /*Flawfinder: ignore*/ // put a EOS at the end buffer[file_length] = 0; LLViewerTextEditor* previewEditor = preview->getChild("Notecard Editor"); if( (file_length > 19) && !strncmp( buffer, "Linden text version", 19 ) ) { if( !previewEditor->importBuffer( buffer, file_length+1 ) ) { llwarns << "Problem importing notecard" << llendl; } } else { // Version 0 (just text, doesn't include version number) previewEditor->setText(LLStringExplicit(buffer)); } previewEditor->makePristine(); const LLInventoryItem* item = preview->getItem(); BOOL modifiable = item && gAgent.allowOperation(PERM_MODIFY, item->getPermissions(), GP_OBJECT_MANIPULATE); preview->setEnabled(modifiable); delete[] buffer; preview->mAssetStatus = PREVIEW_ASSET_LOADED; } else { LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED ); if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status || LL_ERR_FILE_EMPTY == status) { LLNotifications::instance().add("NotecardMissing"); } else if (LL_ERR_INSUFFICIENT_PERMISSIONS == status) { LLNotifications::instance().add("NotecardNoPermissions"); } else { LLNotifications::instance().add("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 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 = getChild("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); std::string buffer; if (!editor->exportBuffer(buffer)) { return false; } editor->makePristine(); S32 size = buffer.length() + 1; file.setMaxSize(size); file.write((U8*)buffer.c_str(), size); const LLInventoryItem* item = getItem(); // save it out to database if (item) { std::string agent_url = gAgent.getRegion()->getCapability("UpdateNotecardAgentInventory"); std::string task_url = gAgent.getRegion()->getCapability("UpdateNotecardTaskInventory"); if (mObjectUUID.isNull() && !agent_url.empty()) { // Saving into agent inventory mAssetStatus = PREVIEW_ASSET_LOADING; setEnabled(FALSE); LLSD body; body["item_id"] = mItemUUID; llinfos << "Saving notecard " << mItemUUID << " into agent inventory via " << agent_url << llendl; LLHTTPClient::post(agent_url, body, new LLUpdateAgentInventoryResponder(body, asset_id, LLAssetType::AT_NOTECARD)); } else if (!mObjectUUID.isNull() && !task_url.empty()) { // Saving into task inventory mAssetStatus = PREVIEW_ASSET_LOADING; setEnabled(FALSE); LLSD body; body["task_id"] = mObjectUUID; body["item_id"] = mItemUUID; llinfos << "Saving notecard " << mItemUUID << " into task " << mObjectUUID << " via " << task_url << llendl; LLHTTPClient::post(task_url, body, new LLUpdateTaskInventoryResponder(body, asset_id, LLAssetType::AT_NOTECARD)); } else if (gAssetStorage) { 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, LLExtStat ext_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 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 { LLNotifications::instance().add("SaveNotecardFailObjectNotFound"); } } // Perform item copy to inventory if (info->mCopyItem.notNull()) { LLViewerTextEditor* editor = info->mSelf->getChild("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; LLSD args; args["REASON"] = std::string(LLAssetStorage::getErrorString(status)); LLNotifications::instance().add("SaveNotecardFailReason", args); } std::string uuid_string; asset_uuid.toString(uuid_string); std::string filename; filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_string) + ".tmp"; LLFile::remove(filename); delete info; } bool LLPreviewNotecard::handleSaveChangesDialog(const LLSD& notification, const LLSD& response) { S32 option = LLNotification::getSelectedOption(notification, response); switch(option) { case 0: // "Yes" mCloseAfterSave = TRUE; LLPreviewNotecard::onClickSave((void*)this); break; case 1: // "No" mForceClose = TRUE; close(); break; case 2: // "Cancel" default: // If we were quitting, we didn't really mean it. LLAppViewer::instance()->abortQuit(); break; } return false; } 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", getRect()); } } LLTextEditor* LLPreviewNotecard::getEditor() { return getChild("Notecard Editor"); } void LLPreviewNotecard::initMenu() { // File menu LLMenuItemCallGL* menuItem = getChild("Save Menu"); menuItem->setMenuCallback(onSaveMenu, this); menuItem->setEnabledCallback(enableSaveMenu); menuItem = getChild("Export Text..."); menuItem->setMenuCallback(onExportTextMenu, this); menuItem->setEnabledCallback(enableExportTextMenu); menuItem = getChild("Import Text..."); menuItem->setMenuCallback(onImportTextMenu, this); menuItem->setEnabledCallback(enableImportTextMenu); // Edit menu menuItem = getChild("Undo"); menuItem->setMenuCallback(onUndoMenu, this); menuItem->setEnabledCallback(enableUndoMenu); menuItem = getChild("Redo"); menuItem->setMenuCallback(onRedoMenu, this); menuItem->setEnabledCallback(enableRedoMenu); menuItem = getChild("Cut"); menuItem->setMenuCallback(onCutMenu, this); menuItem->setEnabledCallback(enableCutMenu); menuItem = getChild("Copy"); menuItem->setMenuCallback(onCopyMenu, this); menuItem->setEnabledCallback(enableCopyMenu); menuItem = getChild("Paste"); menuItem->setMenuCallback(onPasteMenu, this); menuItem->setEnabledCallback(enablePasteMenu); menuItem = getChild("Select All"); menuItem->setMenuCallback(onSelectAllMenu, this); menuItem->setEnabledCallback(enableSelectAllMenu); menuItem = getChild("Deselect"); menuItem->setMenuCallback(onDeselectMenu, this); menuItem->setEnabledCallback(enableDeselectMenu); menuItem = getChild("Search / Replace..."); menuItem->setMenuCallback(onSearchMenu, this); menuItem->setEnabledCallback(NULL); } //static void LLPreviewNotecard::onSaveMenu(void* userdata) { LLPreviewNotecard* preview = (LLPreviewNotecard*)userdata; if (preview) { preview->saveIfNeeded(); } } //static void LLPreviewNotecard::onExportTextMenu(void* userdata) { LLPreviewNotecard* preview = (LLPreviewNotecard*)userdata; if (preview) { LLViewerTextEditor* editor = preview->getChild("Notecard Editor"); if (editor) { LLFilePicker& file_picker = LLFilePicker::instance(); const LLViewerInventoryItem *item = preview->getItem(); if (!file_picker.getSaveFile(LLFilePicker::FFSAVE_TEXT, item ? LLDir::getScrubbedFileName(item->getName()) : LLStringUtil::null)) { return; } std::string filename = file_picker.getFirstFile(); std::string scriptText = editor->getText(); std::ofstream fout(filename.c_str()); fout << scriptText; fout.close(); } } } //static void LLPreviewNotecard::onImportTextMenu(void* userdata) { LLPreviewNotecard* preview = (LLPreviewNotecard*)userdata; if (preview) { LLViewerTextEditor* editor = preview->getChild("Notecard Editor"); if (editor) { LLFilePicker& file_picker = LLFilePicker::instance(); if (!file_picker.getOpenFile(LLFilePicker::FFLOAD_TEXT)) { return; } std::string filename = file_picker.getFirstFile(); std::ifstream fin(filename.c_str()); editor->clear(); std::string line; while (!fin.eof()) { getline(fin, line); line = line + "\n"; editor->insertText(line); } fin.close(); preview->saveIfNeeded(); } } } // static void LLPreviewNotecard::onSearchMenu(void* userdata) { LLPreviewNotecard* self = (LLPreviewNotecard*)userdata; if (self) { LLViewerTextEditor* editor = self->getChild("Notecard Editor"); if (editor) { LLFloaterSearchReplace::show(editor); } } } // static void LLPreviewNotecard::onUndoMenu(void* userdata) { LLPreviewNotecard* self = (LLPreviewNotecard*)userdata; if (self) { LLViewerTextEditor* editor = self->getChild("Notecard Editor"); if (editor) { editor->undo(); } } } // static void LLPreviewNotecard::onRedoMenu(void* userdata) { LLPreviewNotecard* self = (LLPreviewNotecard*)userdata; if (self) { LLViewerTextEditor* editor = self->getChild("Notecard Editor"); if (editor) { editor->redo(); } } } // static void LLPreviewNotecard::onCutMenu(void* userdata) { LLPreviewNotecard* self = (LLPreviewNotecard*)userdata; if (self) { LLViewerTextEditor* editor = self->getChild("Notecard Editor"); if (editor) { editor->cut(); } } } // static void LLPreviewNotecard::onCopyMenu(void* userdata) { LLPreviewNotecard* self = (LLPreviewNotecard*)userdata; if (self) { LLViewerTextEditor* editor = self->getChild("Notecard Editor"); if (editor) { editor->copy(); } } } // static void LLPreviewNotecard::onPasteMenu(void* userdata) { LLPreviewNotecard* self = (LLPreviewNotecard*)userdata; if (self) { LLViewerTextEditor* editor = self->getChild("Notecard Editor"); if (editor) { editor->paste(); } } } // static void LLPreviewNotecard::onSelectAllMenu(void* userdata) { LLPreviewNotecard* self = (LLPreviewNotecard*)userdata; if (self) { LLViewerTextEditor* editor = self->getChild("Notecard Editor"); if (editor) { editor->selectAll(); } } } // static void LLPreviewNotecard::onDeselectMenu(void* userdata) { LLPreviewNotecard* self = (LLPreviewNotecard*)userdata; if (self) { LLViewerTextEditor* editor = self->getChild("Notecard Editor"); if (editor) { editor->deselect(); } } } //static BOOL LLPreviewNotecard::enableSaveMenu(void* userdata) { LLPreviewNotecard* self = (LLPreviewNotecard*)userdata; if (!self) return FALSE; LLViewerTextEditor* editor = self->getChild("Notecard Editor"); if (!editor) return FALSE; return !editor->isPristine(); } //static BOOL LLPreviewNotecard::enableExportTextMenu(void* userdata) { LLPreviewNotecard* self = (LLPreviewNotecard*)userdata; if (!self) return FALSE; LLViewerTextEditor* editor = self->getChild("Notecard Editor"); if (!editor) return FALSE; // request the asset const LLInventoryItem* item = self->getItem(); return (item && (gAgent.allowOperation(PERM_MODIFY, item->getPermissions(), GP_OBJECT_MANIPULATE) || gAgent.isGodlike())); } //static BOOL LLPreviewNotecard::enableImportTextMenu(void* userdata) { LLPreviewNotecard* self = (LLPreviewNotecard*)userdata; if (!self) return FALSE; LLViewerTextEditor* editor = self->getChild("Notecard Editor"); if (!editor) return FALSE; // request the asset const LLInventoryItem* item = self->getItem(); return (item && (gAgent.allowOperation(PERM_MODIFY, item->getPermissions(), GP_OBJECT_MANIPULATE) || gAgent.isGodlike())); } // static BOOL LLPreviewNotecard::enableUndoMenu(void* userdata) { LLPreviewNotecard* self = (LLPreviewNotecard*)userdata; if (!self) return FALSE; LLViewerTextEditor* editor = self->getChild("Notecard Editor"); if (!editor) return FALSE; return editor->canUndo(); } // static BOOL LLPreviewNotecard::enableRedoMenu(void* userdata) { LLPreviewNotecard* self = (LLPreviewNotecard*)userdata; if (!self) return FALSE; LLViewerTextEditor* editor = self->getChild("Notecard Editor"); if (!editor) return FALSE; return editor->canRedo(); } // static BOOL LLPreviewNotecard::enableCutMenu(void* userdata) { LLPreviewNotecard* self = (LLPreviewNotecard*)userdata; if (!self) return FALSE; LLViewerTextEditor* editor = self->getChild("Notecard Editor"); if (!editor) return FALSE; return editor->canCut(); } // static BOOL LLPreviewNotecard::enableCopyMenu(void* userdata) { LLPreviewNotecard* self = (LLPreviewNotecard*)userdata; if (!self) return FALSE; LLViewerTextEditor* editor = self->getChild("Notecard Editor"); if (!editor) return FALSE; return editor->canCopy(); } // static BOOL LLPreviewNotecard::enablePasteMenu(void* userdata) { LLPreviewNotecard* self = (LLPreviewNotecard*)userdata; if (!self) return FALSE; LLViewerTextEditor* editor = self->getChild("Notecard Editor"); if (!editor) return FALSE; return editor->canPaste(); } // static BOOL LLPreviewNotecard::enableSelectAllMenu(void* userdata) { LLPreviewNotecard* self = (LLPreviewNotecard*)userdata; if (!self) return FALSE; LLViewerTextEditor* editor = self->getChild("Notecard Editor"); if (!editor) return FALSE; return editor->canSelectAll(); } // static BOOL LLPreviewNotecard::enableDeselectMenu(void* userdata) { LLPreviewNotecard* self = (LLPreviewNotecard*)userdata; if (!self) return FALSE; LLViewerTextEditor* editor = self->getChild("Notecard Editor"); if (!editor) return FALSE; return editor->canDeselect(); } // EOF