diff options
| author | Andrey Kleshchev <andreykproductengine@lindenlab.com> | 2022-04-09 00:57:19 +0300 | 
|---|---|---|
| committer | Andrey Kleshchev <andreykproductengine@lindenlab.com> | 2022-04-09 00:57:19 +0300 | 
| commit | 285e36b57ea895f660f06095652b8cf03b7cbc09 (patch) | |
| tree | 2c591fd818882a3c2a6d454ebf6801c698f25866 | |
| parent | 2f776a38af873163d6b5d5e030ce4b57a3e10e93 (diff) | |
SL-15312 Legacy profiles remake #3
| -rw-r--r-- | indra/newview/llpanelprofile.cpp | 326 | ||||
| -rw-r--r-- | indra/newview/llpanelprofile.h | 15 | ||||
| -rw-r--r-- | indra/newview/llviewertexturelist.cpp | 1 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/menu_profile_other.xml | 31 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/menu_profile_self.xml | 74 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/panel_profile_secondlife.xml | 4 | 
6 files changed, 337 insertions, 114 deletions
| diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index adf5036498..53d0cbec9f 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -291,13 +291,7 @@ void put_avatar_properties_coro(std::string cap_url, LLUUID agent_id, LLSD data)      }  } -enum EProfileImageType -{ -    PROFILE_IMAGE_SL, -    PROFILE_IMAGE_FL, -}; - -void post_profile_image_coro(std::string cap_url, EProfileImageType type, std::string path_to_image) +LLUUID post_profile_image(std::string cap_url, const LLSD &first_data, std::string path_to_image, LLHandle<LLPanel> *handle)  {      LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);      LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t @@ -307,17 +301,6 @@ void post_profile_image_coro(std::string cap_url, EProfileImageType type, std::s      LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);      httpOpts->setFollowRedirects(true); - -    LLSD first_data; -    switch (type) -    { -    case PROFILE_IMAGE_SL: -        first_data["profile-image-asset"] = "sl_image_id"; -        break; -    case PROFILE_IMAGE_FL: -        first_data["profile-image-asset"] = "fl_image_id"; -        break; -    }      LLSD result = httpAdapter->postAndSuspend(httpRequest, cap_url, first_data, httpOpts, httpHeaders); @@ -326,22 +309,21 @@ void post_profile_image_coro(std::string cap_url, EProfileImageType type, std::s      if (!status)      { +        // todo: notification?          LL_WARNS("AvatarProperties") << "Failed to get uploader cap " << status.toString() << LL_ENDL; -        LLFile::remove(path_to_image); -        return; +        return LLUUID::null;      }      if (!result.has("uploader"))      { +        // todo: notification?          LL_WARNS("AvatarProperties") << "Failed to get uploader cap, response contains no data." << LL_ENDL; -        LLFile::remove(path_to_image); -        return; +        return LLUUID::null;      }      std::string uploader_cap = result["uploader"].asString();      if (uploader_cap.empty())      {          LL_WARNS("AvatarProperties") << "Failed to get uploader cap, cap invalid." << LL_ENDL; -        LLFile::remove(path_to_image); -        return; +        return LLUUID::null;      }      // Upload the image @@ -356,8 +338,7 @@ void post_profile_image_coro(std::string cap_url, EProfileImageType type, std::s          if (!instream.is_open())          {              LL_WARNS("AvatarProperties") << "Failed to open file " << path_to_image << LL_ENDL; -            LLFile::remove(path_to_image); -            return; +            return LLUUID::null;          }          length = instream.tellg();      } @@ -371,11 +352,12 @@ void post_profile_image_coro(std::string cap_url, EProfileImageType type, std::s      httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];      status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); +    LL_WARNS("AvatarProperties") << result << LL_ENDL; +      if (!status)      {          LL_WARNS("AvatarProperties") << "Failed to upload image " << status.toString() << LL_ENDL; -        LLFile::remove(path_to_image); -        return; +        return LLUUID::null;      }      if (result["state"].asString() != "complete") @@ -388,14 +370,62 @@ void post_profile_image_coro(std::string cap_url, EProfileImageType type, std::s          {              LL_WARNS("AvatarProperties") << "Failed to upload image " << result << LL_ENDL;          } -        LLFile::remove(path_to_image); -        return; +        return LLUUID::null; +    } + +    return result["new_asset"].asUUID(); +} + +enum EProfileImageType +{ +    PROFILE_IMAGE_SL, +    PROFILE_IMAGE_FL, +}; + +void post_profile_image_coro(std::string cap_url, EProfileImageType type, std::string path_to_image, LLHandle<LLPanel> *handle) +{ +    LLSD data; +    switch (type) +    { +    case PROFILE_IMAGE_SL: +        data["profile-image-asset"] = "sl_image_id"; +        break; +    case PROFILE_IMAGE_FL: +        data["profile-image-asset"] = "fl_image_id"; +        break;      } +    LLUUID result = post_profile_image(cap_url, data, path_to_image, handle); + +    // reset loading indicator +    switch (type) +    { +    case PROFILE_IMAGE_SL: +        if (!handle->isDead()) +        { +            LLPanelProfileSecondLife* panel = static_cast<LLPanelProfileSecondLife*>(handle->get()); +            if (result.notNull()) +            { +                panel->setProfileImageUploaded(result); +            } +            else +            { +                // failure, just stop progress indicator +                panel->setProfileImageUploading(false); +            } +        } +        break; +    case PROFILE_IMAGE_FL: +        // Todo: refresh the panel +        break; +    } + +    // Cleanup      LLFile::remove(path_to_image); +    delete handle;  } -void launch_profile_image_coro(EProfileImageType type, const std::string &file_path) +void launch_profile_image_coro(EProfileImageType type, const std::string &file_path, LLHandle<LLPanel> *handle)  {      std::string cap_url = gAgent.getRegionCapability(PROFILE_IMAGE_UPLOAD_CAP);      if (!cap_url.empty()) @@ -410,7 +440,7 @@ void launch_profile_image_coro(EProfileImageType type, const std::string &file_p          if (LLViewerTextureList::createUploadFile(file_path, temp_file, codec, MAX_DIM))          {              LLCoros::instance().launch("postAgentUserImageCoro", -                boost::bind(post_profile_image_coro, cap_url, type, temp_file)); +                boost::bind(post_profile_image_coro, cap_url, type, temp_file, handle));          }      }      else @@ -564,6 +594,7 @@ LLAgentHandler gAgentHandler;  LLPanelProfileSecondLife::LLPanelProfileSecondLife()   : LLPanelProfileTab()   , mAvatarNameCacheConnection() + , mWaitingForImageUpload(false)  {  } @@ -583,8 +614,6 @@ LLPanelProfileSecondLife::~LLPanelProfileSecondLife()      {          mAvatarNameCacheConnection.disconnect();      } - -    clearUploadProfileImagePath();  }  BOOL LLPanelProfileSecondLife::postBuild() @@ -594,11 +623,14 @@ BOOL LLPanelProfileSecondLife::postBuild()      mSecondLifePic          = getChild<LLIconCtrl>("2nd_life_pic");      mSecondLifePicLayout    = getChild<LLPanel>("image_stack");      mDescriptionEdit        = getChild<LLTextBase>("sl_description_edit"); -    mGiveInvPanel           = getChild<LLPanel>("give_stack");      mAgentActionMenuButton  = getChild<LLMenuButton>("agent_actions_menu"); +    mSaveDescriptionChanges = getChild<LLButton>("save_description_changes"); +    mDiscardDescriptionChanges = getChild<LLButton>("discard_description_changes"); -    mGroupList->setDoubleClickCallback(boost::bind(&LLPanelProfileSecondLife::openGroupProfile, this)); -    mGroupList->setReturnCallback(boost::bind(&LLPanelProfileSecondLife::openGroupProfile, this)); +    mGroupList->setDoubleClickCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { LLPanelProfileSecondLife::openGroupProfile(); }); +    mGroupList->setReturnCallback([this](LLUICtrl*, const LLSD&) { LLPanelProfileSecondLife::openGroupProfile(); }); +    mSaveDescriptionChanges->setCommitCallback([this](LLUICtrl*, void*) { onSaveDescriptionChanges(); }, nullptr); +    mDiscardDescriptionChanges->setCommitCallback([this](LLUICtrl*, void*) { onDiscardDescriptionChanges(); }, nullptr);      return TRUE;  } @@ -615,10 +647,10 @@ void LLPanelProfileSecondLife::onOpen(const LLSD& key)      BOOL own_profile = getSelfProfile();      mGroupList->setShowNone(!own_profile); -    //mGiveInvPanel->setVisible(!own_profile);      childSetVisible("notes_panel", !own_profile);      childSetVisible("settings_panel", own_profile); +    childSetVisible("about_buttons_panel", own_profile);      childSetVisible("permissions_panel", !own_profile);      if (own_profile && !getEmbedded()) @@ -638,12 +670,11 @@ void LLPanelProfileSecondLife::onOpen(const LLSD& key)      if (own_profile)      { -        //mAgentActionMenuButton->setMenu("menu_profile_self.xml", LLMenuButton::MP_BOTTOM_RIGHT); +        mAgentActionMenuButton->setMenu("menu_profile_self.xml", LLMenuButton::MP_BOTTOM_RIGHT);      }      else      {          // Todo: use PeopleContextMenu instead? -        // Todo: add options to copy name, display name, id, may be slurl          mAgentActionMenuButton->setMenu("menu_profile_other.xml", LLMenuButton::MP_BOTTOM_RIGHT);      } @@ -665,6 +696,7 @@ void LLPanelProfileSecondLife::onOpen(const LLSD& key)      mAvatarNameCacheConnection = LLAvatarNameCache::get(getAvatarId(), boost::bind(&LLPanelProfileSecondLife::onAvatarNameCache, this, _1, _2));  } +// todo:: remove apply  void LLPanelProfileSecondLife::apply(LLAvatarData* data)  {      if (getIsLoaded() && getSelfProfile()) @@ -675,7 +707,6 @@ void LLPanelProfileSecondLife::apply(LLAvatarData* data)          LLSD params = LLSDMap();          // we have an image, check if it is local. Server won't recognize local ids.          if (data->image_id != mImageAssetId -            && mImageFile.empty()              && !LLLocalBitmapMgr::getInstance()->isLocal(mImageAssetId))          {              params["sl_image_id"] = mImageAssetId; @@ -701,22 +732,6 @@ void LLPanelProfileSecondLife::apply(LLAvatarData* data)                  LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL;              }          } - -        // Only if image is local -        if (!mImageFile.empty()) -        { -            std::string cap_url = gAgent.getRegionCapability(PROFILE_IMAGE_UPLOAD_CAP); -            if (!cap_url.empty()) -            { -                LLCoros::instance().launch("postAgentUserImageCoro", -                    boost::bind(post_profile_image_coro, cap_url, PROFILE_IMAGE_SL, mImageFile)); -                mImageFile.clear(); // coro should do the deleting -            } -            else -            { -                LL_WARNS("AvatarProperties") << "Failed to upload profile image of type " << (S32)PROFILE_IMAGE_SL << ", no cap found" << LL_ENDL; -            } -        }      }  } @@ -769,8 +784,6 @@ void LLPanelProfileSecondLife::resetData()      mDescriptionEdit->setValue(LLStringUtil::null);      mGroups.clear();      mGroupList->setGroups(mGroups); -    clearUploadProfileImagePath(); -    //mAgentActionMenuButton set menu  }  void LLPanelProfileSecondLife::processProfileProperties(const LLAvatarData* avatar_data) @@ -834,35 +847,34 @@ void LLPanelProfileSecondLife::onAvatarNameCache(const LLUUID& agent_id, const L      getChild<LLUICtrl>("user_name")->setValue(av_name.getUserName() );  } -void LLPanelProfileSecondLife::setUploadProfileImagePath(const std::string &path, const std::string &orig_path) +void LLPanelProfileSecondLife::setProfileImageUploading(bool loading)  { -    clearUploadProfileImagePath(); -    // todo: display this in floater, -    // LLIconCtrl can't show a path, only by id or name, so may be draw directly or add as a local bitmap? -    // LLLocalBitmap* unit = new LLLocalBitmap(path); - -    // assign a local texture to view in viewer -    // Todo: remove LLLocalBitmap and just draw texture instead -    // orig_path was used instead of path, since LLLocalBitmapMgr does not support j2c -    LLUUID tracking_id = LLLocalBitmapMgr::getInstance()->addUnit(orig_path); -    if (tracking_id.isNull()) -    { -        // todo: error handling -        return; -    } - -    mImageFile = path; -    mImageAssetId = LLLocalBitmapMgr::getInstance()->getWorldID(tracking_id); -    mSecondLifePic->setValue(mImageAssetId); +    // Todo: loading indicator here +    mWaitingForImageUpload = loading;  } -void LLPanelProfileSecondLife::clearUploadProfileImagePath() +void LLPanelProfileSecondLife::setProfileImageUploaded(const LLUUID &image_asset_id)  { -    if (!mImageFile.empty()) +    mSecondLifePic->setValue(image_asset_id); + +    LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTexture(image_asset_id); +    if (imagep->getFullHeight()) +    { +        onImageLoaded(true, imagep); +    } +    else      { -        LLFile::remove(mImageFile); //todo: supress errors, may be not need to remove if it becomes a LLLocalBitmap +        imagep->setLoadedCallback(onImageLoaded, +            MAX_DISCARD_LEVEL, +            FALSE, +            FALSE, +            new LLHandle<LLPanel>(getHandle()), +            NULL, +            FALSE);      } -    mImageFile.clear(); + +    mWaitingForImageUpload = false; +    // Todo: reset loading indicator here  }  void LLPanelProfileSecondLife::fillCommonData(const LLAvatarData* avatar_data) @@ -879,7 +891,7 @@ void LLPanelProfileSecondLife::fillCommonData(const LLAvatarData* avatar_data)      mImageAssetId = avatar_data->image_id;      mSecondLifePic->setValue(mImageAssetId); -    //Don't bother about boost level, picker will set it +    // Will be loaded as a LLViewerFetchedTexture::BOOST_UI due to mSecondLifePic      LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTexture(avatar_data->image_id);      if (imagep->getFullHeight())      { @@ -1046,14 +1058,11 @@ void LLPanelProfileSecondLife::updateButtons()          mShowInSearchCheckbox->setVisible(TRUE);          mShowInSearchCheckbox->setEnabled(TRUE);          mDescriptionEdit->setEnabled(TRUE); -    } -} -void LLPanelProfileSecondLife::onClickSetName() -{ -    LLAvatarNameCache::get(getAvatarId(), boost::bind(&LLPanelProfileSecondLife::onAvatarNameCacheSetName, this, _1, _2)); - -    LLFirstUse::setDisplayName(false); +        // todo: enable/disble buttons based on text changes +        //mSaveDescriptionChanges-> +        //mDiscardDescriptionChanges-> +    }  } @@ -1061,17 +1070,19 @@ void LLPanelProfileSecondLife::onClickSetName()  class LLProfileImagePicker : public LLFilePickerThread  {  public: -    LLProfileImagePicker(LLHandle<LLPanel> *handle); +    LLProfileImagePicker(EProfileImageType type, LLHandle<LLPanel> *handle);      ~LLProfileImagePicker();      virtual void notify(const std::vector<std::string>& filenames);  private:      LLHandle<LLPanel> *mHandle; +    EProfileImageType mType;  }; -LLProfileImagePicker::LLProfileImagePicker(LLHandle<LLPanel> *handle) +LLProfileImagePicker::LLProfileImagePicker(EProfileImageType type, LLHandle<LLPanel> *handle)      : LLFilePickerThread(LLFilePicker::FFLOAD_IMAGE), -    mHandle(handle) +    mHandle(handle), +    mType(type)  {  } @@ -1082,10 +1093,6 @@ LLProfileImagePicker::~LLProfileImagePicker()  void LLProfileImagePicker::notify(const std::vector<std::string>& filenames)  { -    /*if (LLAppViewer::instance()->quitRequested()) -    { -        return; -    }*/      if (mHandle->isDead())      {          return; @@ -1102,17 +1109,25 @@ void LLProfileImagePicker::notify(const std::vector<std::string>& filenames)      const S32 MAX_DIM = 256;      if (!LLViewerTextureList::createUploadFile(file_path, temp_file, codec, MAX_DIM))      { -        // todo: error handling +        //todo: image not supported notification +        LL_WARNS("AvatarProperties") << "Failed to upload profile image of type " << (S32)PROFILE_IMAGE_SL << ", failed to open image" << LL_ENDL; +        return; +    } + +    std::string cap_url = gAgent.getRegionCapability(PROFILE_IMAGE_UPLOAD_CAP); +    if (cap_url.empty()) +    { +        LL_WARNS("AvatarProperties") << "Failed to upload profile image of type " << (S32)PROFILE_IMAGE_SL << ", no cap found" << LL_ENDL;          return;      }      LLPanelProfileSecondLife* panel = static_cast<LLPanelProfileSecondLife*>(mHandle->get()); -    panel->setUploadProfileImagePath(temp_file, file_path); -} +    panel->setProfileImageUploading(true); -void LLPanelProfileSecondLife::onPickTexture() -{ -    (new LLProfileImagePicker(new LLHandle<LLPanel>(getHandle())))->getFile(); +    LLCoros::instance().launch("postAgentUserImageCoro", +        boost::bind(post_profile_image_coro, cap_url, mType, temp_file, mHandle)); + +    mHandle = nullptr; // transferred to post_profile_image_coro  }  void LLPanelProfileSecondLife::onCommitMenu(const LLSD& userdata) @@ -1169,6 +1184,63 @@ void LLPanelProfileSecondLife::onCommitMenu(const LLSD& userdata)      {          LLAvatarActions::toggleBlock(agent_id);      } +    else if (item_name == "copy_user_id") +    { +        LLWString wstr = utf8str_to_wstring(getAvatarId().asString()); +        LLClipboard::instance().copyToClipboard(wstr, 0, wstr.size()); +    } +    else if (item_name == "copy_display_name" +        || item_name == "copy_username") +    { +        LLAvatarName av_name; +        if (!LLAvatarNameCache::get(getAvatarId(), &av_name)) +        { +            // shouldn't happen, option is supposed to be invisible while name is fetching +            LL_WARNS() << "Failed to get agent data" << LL_ENDL; +            return; +        } +        LLWString wstr; +        if (item_name == "copy_display_name") +        { +            wstr = utf8str_to_wstring(av_name.getDisplayName(true)); +        } +        else if (item_name == "copy_username") +        { +            wstr = utf8str_to_wstring(av_name.getUserName()); +        } +        LLClipboard::instance().copyToClipboard(wstr, 0, wstr.size()); +    } +    else if (item_name == "edit_display_name") +    { +        LLAvatarNameCache::get(getAvatarId(), boost::bind(&LLPanelProfileSecondLife::onAvatarNameCacheSetName, this, _1, _2)); +        LLFirstUse::setDisplayName(false); +    } +    else if (item_name == "edit_partner") +    { +        // todo: open https://secondlife.com/my/account/partners.php or whatever link is correct for the grid +    } +    else if (item_name == "change_photo") +    { +        (new LLProfileImagePicker(PROFILE_IMAGE_SL, new LLHandle<LLPanel>(getHandle())))->getFile(); +    } +    else if (item_name == "remove_photo") +    { +        LLSD params; +        params["sl_image_id"] = LLUUID::null; // todo: verify that it works and matches Generic_Person_Large + +        std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); +        if (!cap_url.empty()) +        { +            LLCoros::instance().launch("putAgentUserInfoCoro", +                boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), params)); + +            mSecondLifePic->setValue("Generic_Person_Large"); +        } +        else +        { +            LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL; +        } +    }  }  bool LLPanelProfileSecondLife::onEnableMenu(const LLSD& userdata) @@ -1181,7 +1253,7 @@ bool LLPanelProfileSecondLife::onEnableMenu(const LLSD& userdata)      }      else if (item_name == "voice_call")      { -        return LLAvatarActions::canCall(); +        return mVoiceStatus;      }      else if (item_name == "callog")      { @@ -1204,6 +1276,21 @@ bool LLPanelProfileSecondLife::onEnableMenu(const LLSD& userdata)      {          return LLAvatarActions::canBlock(agent_id);      } +    else if (item_name == "copy_display_name" +        || item_name == "copy_username") +    { +        return !mAvatarNameCacheConnection.connected(); +    } +    else if (item_name == "change_photo") +    { +        std::string cap_url = gAgent.getRegionCapability(PROFILE_IMAGE_UPLOAD_CAP); +        return !cap_url.empty() && !mWaitingForImageUpload; +    } +    else if (item_name == "remove_photo") +    { +        std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); +        return !cap_url.empty() && !mWaitingForImageUpload; +    }      return false;  } @@ -1247,6 +1334,35 @@ void LLPanelProfileSecondLife::onAvatarNameCacheSetName(const LLUUID& agent_id,      LLFloaterReg::showInstance("display_name");  } +void LLPanelProfileSecondLife::onSaveDescriptionChanges() +{ +    // todo: force commit changes in mDescriptionEdit, reset dirty flags +    // todo: check if mDescriptionEdit can be made to not commit immediately + +    LLSD params; +    params["sl_about_text"] = mDescriptionEdit->getValue().asString(); + +    std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); +    if (!cap_url.empty()) +    { +        LLCoros::instance().launch("putAgentUserInfoCoro", +            boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), params)); +    } +    else +    { +        LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL; +    } + +    updateButtons(); +} + +void LLPanelProfileSecondLife::onDiscardDescriptionChanges() +{ +    // todo: restore mDescriptionEdit + +    updateButtons(); +} +  //////////////////////////////////////////////////////////////////////////  // LLPanelProfileWeb @@ -1514,7 +1630,7 @@ void LLPanelProfileFirstLife::apply(LLAvatarData* data)      {          // todo: temporary file, connect to UI          std::string file_path = gDirUtilp->findSkinnedFilename("textures", "icons/Default_Outfit_Photo.png"); -        launch_profile_image_coro(PROFILE_IMAGE_FL, file_path); +        launch_profile_image_coro(PROFILE_IMAGE_FL, file_path, new LLHandle<LLPanel>(getHandle()));      }  } diff --git a/indra/newview/llpanelprofile.h b/indra/newview/llpanelprofile.h index f695167a89..fb38a361cb 100644 --- a/indra/newview/llpanelprofile.h +++ b/indra/newview/llpanelprofile.h @@ -45,6 +45,7 @@  // class LLPanelProfileNotes;  class LLAvatarName; +class LLButton;  class LLCheckBoxCtrl;  class LLIconCtrl;  class LLTabContainer; @@ -103,8 +104,8 @@ public:  	void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name); -    void setUploadProfileImagePath(const std::string &path, const std::string &orig_path); -    void clearUploadProfileImagePath(); +    void setProfileImageUploading(bool loading); +    void setProfileImageUploaded(const LLUUID &image_asset_id);      friend void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id); @@ -162,13 +163,14 @@ protected:  private:      /*virtual*/ void updateButtons(); -	void onClickSetName(); -	void onPickTexture();      void onCommitMenu(const LLSD& userdata);      bool onEnableMenu(const LLSD& userdata);      bool onCheckMenu(const LLSD& userdata);  	void onAvatarNameCacheSetName(const LLUUID& id, const LLAvatarName& av_name); +    void onSaveDescriptionChanges(); +    void onDiscardDescriptionChanges(); +  private:  	typedef std::map<std::string, LLUUID> group_map_t;  	group_map_t				mGroups; @@ -179,11 +181,12 @@ private:      LLIconCtrl*			mSecondLifePic;  	LLPanel*			mSecondLifePicLayout;  	LLTextBase*			mDescriptionEdit; -	LLPanel*			mGiveInvPanel;      LLMenuButton*		mAgentActionMenuButton; +    LLButton*			mSaveDescriptionChanges; +    LLButton*			mDiscardDescriptionChanges;  	bool				mVoiceStatus; -    std::string mImageFile; +    bool				mWaitingForImageUpload;      LLUUID mImageAssetId;  	boost::signals2::connection	mAvatarNameCacheConnection; diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 7afc310fdd..b97f3874b7 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -1264,7 +1264,6 @@ BOOL LLViewerTextureList::createUploadFile(const std::string& filename,  	LLPointer<LLImageFormatted> image = LLImageFormatted::createFromType(codec);  	if (image.isNull())  	{ -		image->setLastError("Couldn't open the image to be uploaded.");  		return FALSE;  	}	  	if (!image->load(filename)) diff --git a/indra/newview/skins/default/xui/en/menu_profile_other.xml b/indra/newview/skins/default/xui/en/menu_profile_other.xml index 5fc625b8e5..7731ee65d1 100644 --- a/indra/newview/skins/default/xui/en/menu_profile_other.xml +++ b/indra/newview/skins/default/xui/en/menu_profile_other.xml @@ -126,4 +126,35 @@       function="Profile.EnableItem"       parameter="toggle_block_agent"/>    </menu_item_check> +  <menu_item_separator name="separator_copy_options"/> +  <menu_item_call +   label="Copy Display Name" +   layout="topleft" +   name="copy_display_name"> +    <menu_item_call.on_click +     function="Profile.Commit" +     parameter="copy_display_name"/> +    <menu_item_call.on_enable +     function="Profile.EnableItem" +     parameter="copy_display_name"/> +  </menu_item_call> +  <menu_item_call +   label="Copy Agent Name" +   layout="topleft" +   name="copy_name"> +    <menu_item_call.on_click +     function="Profile.Commit" +     parameter="copy_username"/> +    <menu_item_call.on_enable +     function="Profile.EnableItem" +     parameter="copy_username"/> +  </menu_item_call> +  <menu_item_call +   label="Copy Agent Id" +   layout="topleft" +   name="copy_id"> +    <menu_item_call.on_click +     function="Profile.Commit" +     parameter="copy_user_id"/> +  </menu_item_call>  </toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_profile_self.xml b/indra/newview/skins/default/xui/en/menu_profile_self.xml new file mode 100644 index 0000000000..552c96c60c --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_profile_self.xml @@ -0,0 +1,74 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<toggleable_menu + layout="topleft" + name="Avatar Profile Menu Self"> +  <menu_item_call +   label="Edit Display Name" +   layout="topleft" +   name="edit_display_name"> +    <on_click +     function="Profile.Commit" +     parameter="edit_display_name"/> +  </menu_item_call> +  <menu_item_call +   label="Edit Partner" +   layout="topleft" +   name="edit_partner"> +    <on_click +     function="Profile.Commit" +     parameter="edit_partner"/> +  </menu_item_call> +  <menu_item_call +   label="Change Photo" +   layout="topleft" +   name="change_photo"> +    <menu_item_call.on_click +     function="Profile.Commit" +     parameter="change_photo"/> +    <menu_item_call.on_enable +    function="Profile.EnableItem" +     parameter="change_photo"/> +  </menu_item_call> +  <menu_item_call +   label="Remove Photo" +   layout="topleft" +   name="remove_photo"> +    <menu_item_call.on_click +     function="Profile.Commit" +     parameter="remove_photo"/> +    <menu_item_call.on_enable +     function="Profile.EnableItem" +     parameter="remove_photo"/> +  </menu_item_call> +  <menu_item_separator name="separator_copy_options"/> +  <menu_item_call +   label="Copy Display Name" +   layout="topleft" +   name="copy_display_name"> +    <menu_item_call.on_click +     function="Profile.Commit" +     parameter="copy_display_name"/> +    <menu_item_call.on_enable +     function="Profile.EnableItem" +     parameter="copy_display_name"/> +  </menu_item_call> +  <menu_item_call +   label="Copy Agent Name" +   layout="topleft" +   name="copy_name"> +    <menu_item_call.on_click +     function="Profile.Commit" +     parameter="copy_username"/> +    <menu_item_call.on_enable +     function="Profile.EnableItem" +     parameter="copy_username"/> +  </menu_item_call> +  <menu_item_call +   label="Copy Agent Id" +   layout="topleft" +   name="copy_id"> +    <menu_item_call.on_click +     function="Profile.Commit" +     parameter="copy_user_id"/> +  </menu_item_call> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml index 4b40db9b5d..3ed704b090 100644 --- a/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml +++ b/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml @@ -264,10 +264,10 @@ Account: [ACCTTYPE]        <layout_stack         name="groups_notes_settings_stack" -       top="1" +       top="0"         left="1"         right="-1" -       bottom="-1" +       height="159"         follows="all"         layout="topleft"         orientation="horizontal"> | 
