diff options
Diffstat (limited to 'indra')
32 files changed, 950 insertions, 89 deletions
diff --git a/indra/llui/llflatlistview.cpp b/indra/llui/llflatlistview.cpp index 5be20bd314..dfe0a71b74 100644 --- a/indra/llui/llflatlistview.cpp +++ b/indra/llui/llflatlistview.cpp @@ -69,7 +69,7 @@ const LLRect& LLFlatListView::getItemsRect() const bool LLFlatListView::addItem(LLPanel * item, const LLSD& value /*= LLUUID::null*/, EAddPosition pos /*= ADD_BOTTOM*/,bool rearrange /*= true*/) { if (!item) return false; - if (value.isUndefined()) return false; + if (value.isUndefined()) return false; // item stays an orphan?!!! //force uniqueness of items, easiest check but unreliable if (item->getParent() == mItemsPanel) return false; diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index d5755ae4b6..ffaa09fd8c 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -1069,6 +1069,14 @@ S32 LLTextBase::insertStringNoUndo(S32 pos, const LLWString &wstr, LLTextBase::s S32 LLTextBase::removeStringNoUndo(S32 pos, S32 length) { + S32 text_length = (S32)getLength(); + if (pos >= text_length || pos < 0) + { + return 0; // nothing to remove + } + // Clamp length to not go past the end of the text + length = std::min(length, text_length - pos); + beforeValueChange(); segment_set_t::iterator seg_iter = getSegIterContaining(pos); while(seg_iter != mSegments.end()) diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 94fd104bcc..b127c9b48f 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -1000,7 +1000,7 @@ void LLWindowWin32::close() // Restore gamma to the system values. restoreGamma(); - LL_INFOS("Window") << "Destroying Window Thread" << LL_ENDL; + LL_INFOS("Window") << "Cleanup and destruction of Window Thread" << LL_ENDL; if (sWindowHandleForMessageBox == mWindowHandle) { @@ -4895,17 +4895,7 @@ bool LLWindowWin32::LLWindowWin32Thread::wakeAndDestroy() return false; } - // Hide the window immediately to prevent user interaction during shutdown - if (mWindowHandleThrd) - { - ShowWindow(mWindowHandleThrd, SW_HIDE); - } - else - { - LL_WARNS("Window") << "Tried to hide window, but Win32 window handle is NULL." << LL_ENDL; - return false; - } - + // Stop checking budget mGLReady = false; // Capture current handle before we lose it @@ -4920,24 +4910,10 @@ bool LLWindowWin32::LLWindowWin32Thread::wakeAndDestroy() // Signal thread to clean up when done mDeleteOnExit = true; - // Close the queue first - LL_DEBUGS("Window") << "Closing window's pool queue" << LL_ENDL; - mQueue->close(); - - // Wake up the thread if it's stuck in GetMessage() - if (old_handle) - { - WPARAM wparam{ 0xB0B0 }; - LL_DEBUGS("Window") << "PostMessage(" << std::hex << old_handle - << ", " << WM_DUMMY_ - << ", " << wparam << ")" << std::dec << LL_ENDL; - - // Use PostMessage to signal thread to wake up - PostMessage(old_handle, WM_DUMMY_, wparam, 0x1337); - } - + LL_INFOS("Window") << "Detaching window's thread" << LL_ENDL; // Cleanly detach threads instead of joining them to avoid blocking the main thread // This is acceptable since the thread will self-delete with mDeleteOnExit + // Doing it before close() to make sure thread doesn't die before or mid detach. for (auto& pair : mThreads) { try { @@ -4952,7 +4928,23 @@ bool LLWindowWin32::LLWindowWin32Thread::wakeAndDestroy() } } - LL_DEBUGS("Window") << "thread pool shutdown complete" << LL_ENDL; + // Close the queue. + LL_INFOS("Window") << "Closing window's pool queue" << LL_ENDL; + mQueue->close(); + + // Wake up the thread if it's stuck in GetMessage() + if (old_handle) + { + WPARAM wparam{ 0xB0B0 }; + LL_DEBUGS("Window") << "PostMessage(" << std::hex << old_handle + << ", " << WM_DUMMY_ + << ", " << wparam << ")" << std::dec << LL_ENDL; + + // Use PostMessage to signal thread to wake up + PostMessage(old_handle, WM_DUMMY_, wparam, 0x1337); + } + + LL_INFOS("Window") << "Thread pool shutdown complete" << LL_ENDL; return true; } diff --git a/indra/newview/gltf/buffer_util.h b/indra/newview/gltf/buffer_util.h index be36c5e90b..c231443a9e 100644 --- a/indra/newview/gltf/buffer_util.h +++ b/indra/newview/gltf/buffer_util.h @@ -147,6 +147,12 @@ namespace LL } template<> + inline void copyVec3<F32, LLVector2>(F32* src, LLVector2& dst) + { + dst.set(src[0], src[1]); + } + + template<> inline void copyVec3<F32, vec3>(F32* src, vec3& dst) { dst = vec3(src[0], src[1], src[2]); @@ -375,12 +381,18 @@ namespace LL template<class T> inline void copy(Asset& asset, Accessor& accessor, LLStrider<T>& dst) { - if (accessor.mBufferView == INVALID_INDEX) + if (accessor.mBufferView == INVALID_INDEX + || accessor.mBufferView >= asset.mBufferViews.size()) { LL_WARNS("GLTF") << "Invalid buffer" << LL_ENDL; return; } const BufferView& bufferView = asset.mBufferViews[accessor.mBufferView]; + if (bufferView.mBuffer >= asset.mBuffers.size()) + { + LL_WARNS("GLTF") << "Invalid buffer view" << LL_ENDL; + return; + } const Buffer& buffer = asset.mBuffers[bufferView.mBuffer]; const U8* src = buffer.mData.data() + bufferView.mByteOffset + accessor.mByteOffset; diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp index 44e71e33f3..550c3adc27 100644 --- a/indra/newview/llfloaterimagepreview.cpp +++ b/indra/newview/llfloaterimagepreview.cpp @@ -433,7 +433,7 @@ bool LLFloaterImagePreview::loadImage(const std::string& src_filename) LLStringUtil::format_map_t args; args["PIXELS"] = llformat("%dM", (S32)(MAX_IMAGE_AREA / 1000000)); - mImageLoadError = LLTrans::getString("texture_load_dimensions_error", args); + mImageLoadError = LLTrans::getString("texture_load_area_error", args); return false; } diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 6a6766fb3f..f76f39222b 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -503,7 +503,10 @@ void LLFloaterModelPreview::onClickCalculateBtn() mUploadModelUrl.clear(); mModelPhysicsFee.clear(); - gMeshRepo.uploadModel(mModelPreview->mUploadData, mModelPreview->mPreviewScale, + lod_sources_map_t lod_sources; + fillLODSourceStatistics(lod_sources); + + gMeshRepo.uploadModel(mModelPreview->mUploadData, lod_sources, mModelPreview->mPreviewScale, childGetValue("upload_textures").asBoolean(), upload_skinweights, upload_joint_positions, lock_scale_if_joint_position, mUploadModelUrl, mDestinationFolderId, false, @@ -1087,9 +1090,7 @@ void LLFloaterModelPreview::onPhysicsUseLOD(LLUICtrl* ctrl, void* userdata) } else if (which_mode == cube_mode) { - std::string path = gDirUtilp->getAppRODataDir(); - gDirUtilp->append(path, "cube.dae"); - sInstance->loadModel(LLModel::LOD_PHYSICS, path); + sInstance->loadModel(LLModel::LOD_PHYSICS, getBoundingBoxCubePath()); } LLModelPreview *model_preview = sInstance->mModelPreview; @@ -1317,8 +1318,91 @@ void LLFloaterModelPreview::createSmoothComboBox(LLComboBox* combo_box, float mi std::string label = (++ilabel == SMOOTH_VALUES_NUMBER) ? "10 (max)" : llformat("%.1d", ilabel); combo_box->add(label, value, ADD_BOTTOM, true); } +} +std::string get_source_file_format(const std::string& filename) +{ + const std::string extension = gDirUtilp->getExtension(filename); + if (extension == "gltf" + || extension == "glb") + { + return "gltf"; + } + else if (extension == "dae") + { + return "dae"; + } + else if (extension == "slm") + { + return "slm"; + } + else + { + return "unknown file"; + } +} + +std::string LLFloaterModelPreview::getBoundingBoxCubePath() +{ + std::string path = gDirUtilp->getAppRODataDir(); + gDirUtilp->append(path, "cube.dae"); + return path; +} + +void LLFloaterModelPreview::fillLODSourceStatistics(LLFloaterModelPreview::lod_sources_map_t& lod_sources) const +{ + lod_sources.clear(); + // This doesn't nessesarily reflect the actual source of meshes, just user choices, + // some meshes could have been matched from different lods, but should be good + // enough for statistics. + for (S32 lod = 0; lod <= LLModel::LOD_HIGH; ++lod) + { + const std::string &lod_string = lod_name[lod]; + if (mLODMode[lod] == LLModelPreview::USE_LOD_ABOVE) + { + lod_sources[lod_string] = "lod above"; + } + else if (mLODMode[lod] == LLModelPreview::MESH_OPTIMIZER_AUTO + || mLODMode[lod] == LLModelPreview::MESH_OPTIMIZER_PRECISE + || mLODMode[lod] == LLModelPreview::MESH_OPTIMIZER_SLOPPY) + { + lod_sources[lod_string] = "generated"; + } + else if (mLODMode[lod] == LLModelPreview::LOD_FROM_FILE) + { + const std::string& file = mModelPreview->mLODFile[lod]; + lod_sources[lod_string] = get_source_file_format(file); + } + else + { + lod_sources[lod_string] = "unknown source"; + } + } + if (mModelPreview->mLODFile[LLModel::LOD_PHYSICS].empty()) + { + if (mModelPreview->mPhysicsSearchLOD >= 0 && mModelPreview->mPhysicsSearchLOD <= 3) + { + lod_sources["physics"] = lod_name[mModelPreview->mPhysicsSearchLOD]; + } + else + { + lod_sources["physics"] = "none"; + } + } + else + { + const std::string& file = mModelPreview->mLODFile[LLModel::LOD_PHYSICS]; + const std::string cube = getBoundingBoxCubePath(); + if (cube != file) // check for "cube.dae" + { + lod_sources["physics"] = get_source_file_format(file); + } + else + { + lod_sources["physics"] = "bounding box"; + } + } } //----------------------------------------------------------------------------- @@ -1656,7 +1740,10 @@ void LLFloaterModelPreview::onUpload(void* user_data) mp->mModelPreview->saveUploadData(upload_skinweights, upload_joint_positions, lock_scale_if_joint_position); } - gMeshRepo.uploadModel(mp->mModelPreview->mUploadData, mp->mModelPreview->mPreviewScale, + lod_sources_map_t lod_sources; + mp->fillLODSourceStatistics(lod_sources); + + gMeshRepo.uploadModel(mp->mModelPreview->mUploadData, lod_sources, mp->mModelPreview->mPreviewScale, mp->childGetValue("upload_textures").asBoolean(), upload_skinweights, upload_joint_positions, lock_scale_if_joint_position, mp->mUploadModelUrl, mp->mDestinationFolderId, diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h index 7b652a3613..20e5b2666a 100644 --- a/indra/newview/llfloatermodelpreview.h +++ b/indra/newview/llfloatermodelpreview.h @@ -223,6 +223,10 @@ private: void createSmoothComboBox(LLComboBox* combo_box, float min, float max); + static std::string getBoundingBoxCubePath(); + typedef std::map<std::string, std::string> lod_sources_map_t; + void fillLODSourceStatistics(lod_sources_map_t& lod_sources) const; + LLUUID mDestinationFolderId; LLButton* mUploadBtn; LLButton* mCalculateBtn; diff --git a/indra/newview/llfloaterwebcontent.cpp b/indra/newview/llfloaterwebcontent.cpp index e1b6df6072..3ff84ac9b7 100644 --- a/indra/newview/llfloaterwebcontent.cpp +++ b/indra/newview/llfloaterwebcontent.cpp @@ -130,7 +130,7 @@ void LLFloaterWebContent::initializeURLHistory() for(; iter_history != end_history; ++iter_history) { std::string url = (*iter_history).asString(); - if(! url.empty()) + if(! url.empty() && url_list) url_list->addSimpleElement(url); } } diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 331754d009..1e6c5cf04a 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -7805,6 +7805,15 @@ void LLLinkItemBridge::buildContextMenu(LLMenuGL& menu, U32 flags) { items.push_back(std::string("Properties")); addDeleteContextMenuOptions(items, disabled_items); + + if (isFavorite()) + { + items.push_back(std::string("Remove from Favorites")); + } + else if (isAgentInventory()) + { + items.push_back(std::string("Add to Favorites")); + } } addLinkReplaceMenuOption(items, disabled_items); hide_context_entries(menu, items, disabled_items); @@ -8031,6 +8040,15 @@ void LLLinkFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags) { items.push_back(std::string("Find Original")); addDeleteContextMenuOptions(items, disabled_items); + + if (isFavorite()) + { + items.push_back(std::string("Remove from Favorites")); + } + else if (isAgentInventory()) + { + items.push_back(std::string("Add to Favorites")); + } } hide_context_entries(menu, items, disabled_items); } diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index b540e9c5bb..590cbbec4e 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -770,6 +770,7 @@ void LLInventoryPanel::itemChanged(const LLUUID& item_id, U32 mask, const LLInve // Remove the item's UI. LLFolderViewFolder* parent = view_item->getParentFolder(); removeItemID(viewmodel_item->getUUID()); + bool was_favorite = view_item->isFavorite(); view_item->destroyView(); if(parent) { @@ -783,7 +784,7 @@ void LLInventoryPanel::itemChanged(const LLUUID& item_id, U32 mask, const LLInve updateFolderLabel(viewmodel_folder->getUUID()); } } - if (view_item->isFavorite()) + if (was_favorite) { parent->updateHasFavorites(false); // favorite was removed } @@ -2298,6 +2299,7 @@ public: void removeItemID(const LLUUID& id) override; bool isInRootContent(const LLUUID& id, LLFolderViewItem* view_item) override; + bool hasPredecessorsInRootContent(const LLInventoryObject* model_item) const; protected: LLInventoryFavoritesItemsPanel(const Params&); @@ -2344,6 +2346,24 @@ bool LLInventoryFavoritesItemsPanel::isInRootContent(const LLUUID& id, LLFolderV return found != mRootContentIDs.end(); } +bool LLInventoryFavoritesItemsPanel::hasPredecessorsInRootContent(const LLInventoryObject* obj) const +{ + LLUUID parent_id = obj->getParentUUID(); + while (parent_id.notNull()) + { + if (mRootContentIDs.contains(parent_id)) + { + return true; + } + LLViewerInventoryCategory* cat = mInventory->getCategory(parent_id); + if (cat) + { + parent_id = cat->getParentUUID(); + } + } + return false; +} + void LLInventoryFavoritesItemsPanel::findAndInitRootContent(const LLUUID& id) { F64 curent_time = LLTimer::getTotalSeconds(); @@ -2433,6 +2453,7 @@ bool LLInventoryFavoritesItemsPanel::removeFavorite(const LLUUID& id, const LLIn { removeItemID(viewmodel_item->getUUID()); } + bool was_favorite = view_item->isFavorite(); view_item->destroyView(); if (parent) { @@ -2442,7 +2463,7 @@ bool LLInventoryFavoritesItemsPanel::removeFavorite(const LLUUID& id, const LLIn { updateFolderLabel(viewmodel_folder->getUUID()); } - if (view_item->isFavorite()) + if (was_favorite) { parent->updateHasFavorites(false); // favorite was removed } @@ -2495,7 +2516,8 @@ void LLInventoryFavoritesItemsPanel::itemChanged(const LLUUID& id, U32 mask, con } LLFolderViewItem* folder_view_item = getItemByID(cat->getUUID()); - if (!folder_view_item) + if (!folder_view_item + && !hasPredecessorsInRootContent(model_item)) { const LLUUID& parent_id = cat->getParentUUID(); mRootContentIDs.emplace(cat->getUUID()); @@ -2507,7 +2529,9 @@ void LLInventoryFavoritesItemsPanel::itemChanged(const LLUUID& id, U32 mask, con else { // New favorite item - if (model_item->getIsFavorite() && typedViewsFilter(id, model_item)) + if (model_item->getIsFavorite() + && typedViewsFilter(id, model_item) + && !hasPredecessorsInRootContent(model_item)) { const LLUUID& parent_id = model_item->getParentUUID(); mRootContentIDs.emplace(id); diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 07d68fc3ec..9e8ed3bb43 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -2569,7 +2569,8 @@ EMeshProcessingResult LLMeshRepoThread::physicsShapeReceived(const LLUUID& mesh_ return MESH_OK; } -LLMeshUploadThread::LLMeshUploadThread(LLMeshUploadThread::instance_list& data, LLVector3& scale, bool upload_textures, +LLMeshUploadThread::LLMeshUploadThread(LLMeshUploadThread::instance_list& data, const LLMeshUploadThread::lod_sources_map_t& sources_list, + LLVector3& scale, bool upload_textures, bool upload_skin, bool upload_joints, bool lock_scale_if_joint_position, const std::string & upload_url, LLUUID destination_folder_id, bool do_upload, LLHandle<LLWholeModelFeeObserver> fee_observer, @@ -2584,6 +2585,7 @@ LLMeshUploadThread::LLMeshUploadThread(LLMeshUploadThread::instance_list& data, mUploadObserverHandle(upload_observer) { mInstanceList = data; + mLodSources = sources_list; mUploadTextures = upload_textures; mUploadSkin = upload_skin; mUploadJoints = upload_joints; @@ -2683,6 +2685,8 @@ void dump_llsd_to_file(const LLSD& content, std::string filename) { if (gSavedSettings.getBOOL("MeshUploadLogXML")) { + filename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, + filename); llofstream of(filename.c_str()); LLSDSerialize::toPrettyXML(content,of); } @@ -2721,6 +2725,12 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, std::vector<std::string>& res["mesh_list"] = LLSD::emptyArray(); res["texture_list"] = LLSD::emptyArray(); res["instance_list"] = LLSD::emptyArray(); + LLSD& lod_sources = res["source_format"]; + lod_sources["high"] = 0; + for (auto &source : mLodSources) + { + lod_sources[source.first] = source.second; + } S32 mesh_num = 0; S32 texture_num = 0; @@ -5026,12 +5036,13 @@ bool LLMeshRepoThread::hasHeader(const LLUUID& mesh_id) const return iter != mMeshHeader.end(); } -void LLMeshRepository::uploadModel(std::vector<LLModelInstance>& data, LLVector3& scale, bool upload_textures, +void LLMeshRepository::uploadModel(std::vector<LLModelInstance>& data, const std::map<std::string, std::string> &lod_sources, + LLVector3& scale, bool upload_textures, bool upload_skin, bool upload_joints, bool lock_scale_if_joint_position, std::string upload_url, const LLUUID& destination_folder_id, bool do_upload, LLHandle<LLWholeModelFeeObserver> fee_observer, LLHandle<LLWholeModelUploadObserver> upload_observer) { - LLMeshUploadThread* thread = new LLMeshUploadThread(data, scale, upload_textures, + LLMeshUploadThread* thread = new LLMeshUploadThread(data, lod_sources, scale, upload_textures, upload_skin, upload_joints, lock_scale_if_joint_position, upload_url, destination_folder_id, do_upload, fee_observer, upload_observer); mUploadWaitList.push_back(thread); diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index 2b772f7803..ab17b921d6 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -691,6 +691,8 @@ public: }; typedef std::map<LLPointer<LLModel>, instance_list, LLUploadModelInstanceLess> instance_map; instance_map mInstance; + typedef std::map<std::string, std::string> lod_sources_map_t; + lod_sources_map_t mLodSources; LLMutex* mMutex; S32 mPendingUploads; @@ -707,7 +709,8 @@ public: std::string mWholeModelUploadURL; LLUUID mDestinationFolderId; - LLMeshUploadThread(instance_list& data, LLVector3& scale, bool upload_textures, + LLMeshUploadThread(instance_list& data, const lod_sources_map_t& sources_list, + LLVector3& scale, bool upload_textures, bool upload_skin, bool upload_joints, bool lock_scale_if_joint_position, const std::string & upload_url, const LLUUID destination_folder_id = LLUUID::null, @@ -869,7 +872,8 @@ public: bool meshUploadEnabled(); bool meshRezEnabled(); - void uploadModel(std::vector<LLModelInstance>& data, LLVector3& scale, bool upload_textures, + void uploadModel(std::vector<LLModelInstance>& data, const std::map<std::string, std::string> &lod_sources, + LLVector3& scale, bool upload_textures, bool upload_skin, bool upload_joints, bool lock_scale_if_joint_position, std::string upload_url, const LLUUID& destination_folder_id = LLUUID::null, diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp index cb2a6191fa..4e594af432 100644 --- a/indra/newview/lloutfitslist.cpp +++ b/indra/newview/lloutfitslist.cpp @@ -254,7 +254,11 @@ void LLOutfitsList::updateAddedCategory(LLUUID cat_id) // for reliability just fetch it whole, linked items included LLInventoryModelBackgroundFetch::instance().fetchFolderAndLinks(cat_id, [cat_id, list] { - if (list) list->updateList(cat_id); + if (list) + { + list->updateList(cat_id); + list->setForceRefresh(true); + } }); } else @@ -264,6 +268,7 @@ void LLOutfitsList::updateAddedCategory(LLUUID cat_id) // Refresh the list of outfit items after fetch(). // Further list updates will be triggered by the category observer. list->updateList(cat_id); + list->setForceRefresh(true); } // If filter is currently applied we store the initial tab state. @@ -590,7 +595,7 @@ void LLOutfitsList::onFilterSubStringChanged(const std::string& new_string, cons LLWearableItemsList* list = dynamic_cast<LLWearableItemsList*>(tab->getAccordionView()); if (list) { - list->setFilterSubString(new_string, true); + list->setFilterSubString(new_string, tab->getDisplayChildren()); } if (old_string.empty()) diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp index 59aa375457..ed80c8b732 100644 --- a/indra/newview/llpanellogin.cpp +++ b/indra/newview/llpanellogin.cpp @@ -184,6 +184,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect, mCallback(callback), mCallbackData(cb_data), mListener(new LLPanelLoginListener(this)), + mFirstLoginThisInstall(gSavedSettings.getBOOL("FirstLoginThisInstall")), mUsernameLength(0), mPasswordLength(0), mLocationLength(0), @@ -202,7 +203,14 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect, login_holder->addChild(this); } - buildFromFile("panel_login.xml"); + if (mFirstLoginThisInstall) + { + buildFromFile( "panel_login_first.xml"); + } + else + { + buildFromFile( "panel_login.xml"); + } reshape(rect.getWidth(), rect.getHeight()); @@ -216,36 +224,38 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect, sendChildToBack(getChildView("sign_up_text")); std::string current_grid = LLGridManager::getInstance()->getGrid(); + if (!mFirstLoginThisInstall) + { + LLComboBox* favorites_combo = getChild<LLComboBox>("start_location_combo"); + updateLocationSelectorsVisibility(); // separate so that it can be called from preferences + favorites_combo->setReturnCallback(boost::bind(&LLPanelLogin::onClickConnect, false)); + favorites_combo->setFocusLostCallback(boost::bind(&LLPanelLogin::onLocationSLURL, this)); - LLComboBox* favorites_combo = getChild<LLComboBox>("start_location_combo"); - updateLocationSelectorsVisibility(); // separate so that it can be called from preferences - favorites_combo->setReturnCallback(boost::bind(&LLPanelLogin::onClickConnect, false)); - favorites_combo->setFocusLostCallback(boost::bind(&LLPanelLogin::onLocationSLURL, this)); - - LLComboBox* server_choice_combo = getChild<LLComboBox>("server_combo"); - server_choice_combo->setCommitCallback(boost::bind(&LLPanelLogin::onSelectServer, this)); + LLComboBox* server_choice_combo = getChild<LLComboBox>("server_combo"); + server_choice_combo->setCommitCallback(boost::bind(&LLPanelLogin::onSelectServer, this)); - // Load all of the grids, sorted, and then add a bar and the current grid at the top - server_choice_combo->removeall(); + // Load all of the grids, sorted, and then add a bar and the current grid at the top + server_choice_combo->removeall(); - std::map<std::string, std::string> known_grids = LLGridManager::getInstance()->getKnownGrids(); - for (std::map<std::string, std::string>::iterator grid_choice = known_grids.begin(); - grid_choice != known_grids.end(); - grid_choice++) - { - if (!grid_choice->first.empty() && current_grid != grid_choice->first) + std::map<std::string, std::string> known_grids = LLGridManager::getInstance()->getKnownGrids(); + for (std::map<std::string, std::string>::iterator grid_choice = known_grids.begin(); + grid_choice != known_grids.end(); + grid_choice++) { - LL_DEBUGS("AppInit") << "adding " << grid_choice->first << LL_ENDL; - server_choice_combo->add(grid_choice->second, grid_choice->first); + if (!grid_choice->first.empty() && current_grid != grid_choice->first) + { + LL_DEBUGS("AppInit") << "adding " << grid_choice->first << LL_ENDL; + server_choice_combo->add(grid_choice->second, grid_choice->first); + } } - } - server_choice_combo->sortByName(); + server_choice_combo->sortByName(); - LL_DEBUGS("AppInit") << "adding current " << current_grid << LL_ENDL; - server_choice_combo->add(LLGridManager::getInstance()->getGridLabel(), - current_grid, - ADD_TOP); - server_choice_combo->selectFirstItem(); + LL_DEBUGS("AppInit") << "adding current " << current_grid << LL_ENDL; + server_choice_combo->add(LLGridManager::getInstance()->getGridLabel(), + current_grid, + ADD_TOP); + server_choice_combo->selectFirstItem(); + } LLSLURL start_slurl(LLStartUp::getStartSLURL()); // The StartSLURL might have been set either by an explicit command-line @@ -321,6 +331,15 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect, void LLPanelLogin::addFavoritesToStartLocation() { + if (mFirstLoginThisInstall) + { + // first login panel has no favorites, just update name length and buttons + std::string user_defined_name = getChild<LLComboBox>("username_combo")->getSimple(); + mUsernameLength = static_cast<unsigned int>(user_defined_name.length()); + updateLoginButtons(); + return; + } + // Clear the combo. LLComboBox* combo = getChild<LLComboBox>("start_location_combo"); if (!combo) return; @@ -540,9 +559,16 @@ void LLPanelLogin::resetFields() // function is used to reset list in case of changes by external sources return; } - - LLPointer<LLCredential> cred = gSecAPIHandler->loadCredential(LLGridManager::getInstance()->getGrid()); - sInstance->populateUserList(cred); + if (sInstance->mFirstLoginThisInstall) + { + // no list to populate + LL_WARNS() << "Shouldn't happen, user should have no ability to modify list on first install" << LL_ENDL; + } + else + { + LLPointer<LLCredential> cred = gSecAPIHandler->loadCredential(LLGridManager::getInstance()->getGrid()); + sInstance->populateUserList(cred); + } } // static @@ -560,6 +586,7 @@ void LLPanelLogin::setFields(LLPointer<LLCredential> credential) if(identifier.has("type") && (std::string)identifier["type"] == "agent") { + // not nessesary for panel_login.xml, needed for panel_login_first.xml std::string firstname = identifier["first_name"].asString(); std::string lastname = identifier["last_name"].asString(); std::string login_id = firstname; @@ -1054,7 +1081,8 @@ void LLPanelLogin::onRememberUserCheck(void*) LLComboBox* user_combo(sInstance->getChild<LLComboBox>("username_combo")); bool remember = remember_name->getValue().asBoolean(); - if (user_combo->getCurrentIndex() != -1 + if (!sInstance->mFirstLoginThisInstall + && user_combo->getCurrentIndex() != -1 && !remember) { remember = true; @@ -1169,14 +1197,17 @@ void LLPanelLogin::updateLoginButtons() login_btn->setEnabled(mUsernameLength != 0 && mPasswordLength != 0); - LLComboBox* user_combo = getChild<LLComboBox>("username_combo"); - LLCheckBoxCtrl* remember_name = getChild<LLCheckBoxCtrl>("remember_name"); - if (user_combo->getCurrentIndex() != -1) + if (!mFirstLoginThisInstall) { - remember_name->setValue(true); - LLCheckBoxCtrl* remember_pass = getChild<LLCheckBoxCtrl>("remember_password"); - remember_pass->setEnabled(true); - } // Note: might be good idea to do "else remember_name->setValue(mRememberedState)" but it might behave 'weird' to user + LLComboBox* user_combo = getChild<LLComboBox>("username_combo"); + LLCheckBoxCtrl* remember_name = getChild<LLCheckBoxCtrl>("remember_name"); + if (user_combo->getCurrentIndex() != -1) + { + remember_name->setValue(true); + LLCheckBoxCtrl* remember_pass = getChild<LLCheckBoxCtrl>("remember_password"); + remember_pass->setEnabled(true); + } // Note: might be good idea to do "else remember_name->setValue(mRememberedState)" but it might behave 'weird' to user + } } void LLPanelLogin::populateUserList(LLPointer<LLCredential> credential) diff --git a/indra/newview/llpanellogin.h b/indra/newview/llpanellogin.h index 1259bf26d6..a1bf25fb05 100644 --- a/indra/newview/llpanellogin.h +++ b/indra/newview/llpanellogin.h @@ -119,6 +119,7 @@ private: static LLPanelLogin* sInstance; static bool sCapslockDidNotification; + bool mFirstLoginThisInstall; static bool sCredentialSet; diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 44831aea03..7d39cc6059 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -3669,7 +3669,7 @@ void process_kill_object(LLMessageSystem *mesgsys, void **user_data) gObjectList.killObject(objectp); } - if(delete_object) + if(delete_object && regionp) { regionp->killCacheEntry(local_id); } diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp index 5fb22184c3..cc593fe7b4 100644 --- a/indra/newview/llwearableitemslist.cpp +++ b/indra/newview/llwearableitemslist.cpp @@ -994,8 +994,11 @@ void LLWearableItemsList::ContextMenu::updateItemsVisibility(LLContextMenu* menu LLUUID linked_id = item->getLinkedUUID(); LLViewerInventoryItem* linked_item = gInventory.getItem(linked_id); - can_favorite |= !linked_item->getIsFavorite(); - can_unfavorite |= linked_item->getIsFavorite(); + if (linked_item) + { + can_favorite |= !linked_item->getIsFavorite(); + can_unfavorite |= linked_item->getIsFavorite(); + } if (is_worn) { diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index b18d151ab7..d650e7e791 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -657,6 +657,7 @@ with the same filename but different name <texture name="login_sl_logo" file_name="windows/login_sl_logo.png" preload="true" /> <texture name="login_sl_logo_small" file_name="windows/login_sl_logo_small.png" preload="true" /> + <texture name="first_login_image" file_name="windows/first_login_image.jpg" preload="true" /> <texture name="Stepper_Down_Off" file_name="widgets/Stepper_Down_Off.png" preload="false" /> <texture name="Stepper_Down_Press" file_name="widgets/Stepper_Down_Press.png" preload="false" /> diff --git a/indra/newview/skins/default/textures/windows/first_login_image.jpg b/indra/newview/skins/default/textures/windows/first_login_image.jpg Binary files differnew file mode 100644 index 0000000000..30f31341ed --- /dev/null +++ b/indra/newview/skins/default/textures/windows/first_login_image.jpg diff --git a/indra/newview/skins/default/xui/de/panel_login_first.xml b/indra/newview/skins/default/xui/de/panel_login_first.xml new file mode 100644 index 0000000000..038001157e --- /dev/null +++ b/indra/newview/skins/default/xui/de/panel_login_first.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="utf-8"?> +<panel name="panel_login"> + <panel.string name="forgot_password_url"> + http://secondlife.com/account/request.php?lang=de + </panel.string> + <panel.string name="sign_up_url"> + https://join.secondlife.com/ + </panel.string> + <layout_stack name="logo_stack"> + <layout_panel name="parent_panel2"> + <layout_stack name="widget_stack"> + <layout_panel name="widget_container"> + <combo_box label="Benutzername" name="username_combo" tool_tip="Bei der Registrierung gewählter Benutzername wie „berndschmidt12“ oder „Liebe Sonne“"/> + <line_editor label="Kennwort" name="password_edit"/> + <button label="Anmelden" name="connect_btn"/> + <check_box label="Details speichern" name="remember_check"/> + <text name="forgot_password_text"> + Kennwort vergessen + </text> + <text name="sign_up_text"> + Registrieren + </text> + </layout_panel> + </layout_stack> + </layout_panel> + <layout_panel name="parent_panel3"> + <layout_stack name="images_stack"> + <layout_panel name="images_container"> + <text name="image_caption_left"> + Ihr erster Schritt ist Learning Island. Suchen Sie die Pforte! + </text> + <text name="image_caption_right"> + Erkunden Sie dann Social Island und lernen Sie andere Einwohner kennen! + </text> + </layout_panel> + </layout_stack> + </layout_panel> + </layout_stack> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_login_first.xml b/indra/newview/skins/default/xui/en/panel_login_first.xml new file mode 100644 index 0000000000..d6ac71db94 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_login_first.xml @@ -0,0 +1,262 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel + follows="all" + height="768" + layout="topleft" + name="panel_login" + focus_root="true" + background_visible="true" + bg_opaque_color="0.16 0.16 0.16 1" + background_opaque="true" + width="1024"> + <panel.string + name="forgot_password_url"> + http://secondlife.com/account/request.php + </panel.string> + <panel.string + name="sign_up_url"> + https://join.secondlife.com/ + </panel.string> + <layout_stack + follows="left|right|top|bottom" + width="1024" + height="768" + left="0" + name="logo_stack" + orientation="vertical" + top="0"> + <layout_panel + height="18" + auto_resize="false" + name="page_top" + width="1024" /> + <!-- start of logo stack --> + <layout_panel + height="130" + min_height="10" + auto_resize="false" + name="parent_panel" + width="1024"> + <layout_stack + follows="left|right|top|bottom" + height="100" + left="0" + name="logo_stack" + orientation="horizontal" + top="0" + width="1024"> + <layout_panel + height="110" + min_height="10" + auto_resize="true" + name="logo_left" + width="300" /> + <layout_panel + auto_resize="false" + follows="left|right|top" + name="logo_container" + width="225" + left="0" + top="0" + height="105"> + <icon + height="94" + image_name="login_sl_logo" + left="0" + name="sl_logo" + top="0" /> + </layout_panel> + <layout_panel + height="100" + name="logo_right" + auto_resize="true" + width="300" /> + </layout_stack> + </layout_panel> + <!-- end of logo stack --> + <!-- start of widget stack --> + <layout_panel + height="100" + min_height="10" + auto_resize="false" + name="parent_panel2" + width="1024"> + <layout_stack + follows="left|right|top|bottom" + height="80" + left="0" + name="widget_stack" + orientation="horizontal" + top="0" + width="1024"> + <layout_panel + height="80" + min_height="10" + auto_resize="true" + name="widget_left" + width="200" /> + <layout_panel + auto_resize="false" + follows="left|right|top" + name="widget_container" + width="730" + left="0" + top="0" + height="80"> + <combo_box + allow_text_entry="true" + follows="left|bottom" + height="32" + left="42" + label="Username" + combo_editor.font="SansSerifLarge" + max_chars="128" + top="0" + combo_editor.prevalidator="ascii" + tool_tip="The username you chose when you registered, like bobsmith12 or Steller Sunshine" + name="username_combo" + width="232"> + <combo_box.combo_editor + text_pad_left="8" /> + <combo_box.combo_button + visible ="false"/> + <combo_box.drop_down_button + visible ="false"/> + </combo_box> + <line_editor + follows="left|top" + width="200" + height="32" + left="262" + max_length_chars="16" + name="password_edit" + label="Password" + text_pad_left="8" + font="SansSerifLarge" + is_password="true" + select_on_focus="true" + commit_on_focus_lost="false" + top="0" /> + <button + follows="left|top" + image_unselected="PushButton_Login" + image_pressed="PushButton_Login_Pressed" + image_hover_unselected="PushButton_Login_Over" + label="Log In" + label_color="White" + font="SansSerifLarge" + name="connect_btn" + left_pad="15" + width="120" + height="32" + top="0" /> + <text + follows="left|top" + font="SansSerifLarge" + font.style="BOLD" + text_color="EmphasisColor" + height="34" + name="sign_up_text" + left_pad="10" + top="0" + width="200" + valign="center"> + Sign up + </text> + <check_box + follows="left|top" + font="SansSerifLarge" + left="42" + top="32" + height="24" + label="Remember me" + word_wrap="down" + check_button.bottom="3" + name="remember_name" + tool_tip="Already remembered user can be forgotten from Me > Preferences > Advanced > Remembered Usernames." + width="198" /> + <check_box + control_name="RememberPassword" + follows="left|top" + font="SansSerifLarge" + height="24" + left="262" + bottom_delta="0" + label="Remember password" + word_wrap="down" + check_button.bottom="3" + name="remember_password" + width="198" /> + <text + follows="left|top" + font="SansSerifLarge" + text_color="EmphasisColor" + height="16" + name="forgot_password_text" + left="492" + top="34" + width="200"> + Forgotten password + </text> + </layout_panel> + <layout_panel + height="100" + name="widget_right" + auto_resize="true" + width="200" /> + </layout_stack> + </layout_panel> + <!-- end of widget stack --> + <!-- start of images stack --> + <layout_panel + height="500" + min_height="10" + auto_resize="false" + name="parent_panel3" + width="1024"> + <layout_stack + follows="left|right|top|bottom" + height="500" + left="0" + name="images_stack" + orientation="horizontal" + top="0" + width="1024"> + <layout_panel + height="500" + min_height="10" + auto_resize="true" + name="images_left" + width="96" /> + <layout_panel + auto_resize="false" + follows="left|right|top" + name="images_container" + width="675" + left="0" + top="0" + height="500"> + <icon + height="450" + width="675" + image_name="first_login_image" + left="0" + name="image_left" + top="0" /> + </layout_panel> + <layout_panel + height="100" + name="images_right" + auto_resize="true" + width="96" /> + </layout_stack> + </layout_panel> + <!-- end of images stack --> + <layout_panel + height="400" + min_height="10" + auto_resize="true" + name="page_bottom" + width="1024" /> + </layout_stack> +</panel> diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index c48ba10cac..99c7d7b7d4 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -3970,7 +3970,8 @@ Abuse Report</string> <string name="AvatarBirthDateFormatShort">[mthnum,datetime,slt]/[day,datetime,slt]</string> <string name="DefaultMimeType">none/none</string> - <string name="texture_load_dimensions_error">Can't load images larger than [PIXELS] pixels</string> + <string name="texture_load_area_error">Can't load images larger than [PIXELS] pixels</string> + <string name="texture_load_dimensions_error">Can't load images larger than [WIDTH]*[HEIGHT]</string> <string name="texture_load_format_error">Incorrect image format.</string> <string name="texture_load_empty_file">File is empty.</string> <string name="outfit_photo_load_dimensions_error">Max outfit photo size is [WIDTH]*[HEIGHT]. Please resize or use another image</string> diff --git a/indra/newview/skins/default/xui/es/panel_login_first.xml b/indra/newview/skins/default/xui/es/panel_login_first.xml new file mode 100644 index 0000000000..ccb6858351 --- /dev/null +++ b/indra/newview/skins/default/xui/es/panel_login_first.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="utf-8"?> +<panel name="panel_login"> + <panel.string name="forgot_password_url"> + http://secondlife.com/account/request.php?lang=es + </panel.string> + <panel.string name="sign_up_url"> + https://join.secondlife.com/ + </panel.string> + <layout_stack name="logo_stack"> + <layout_panel name="parent_panel2"> + <layout_stack name="widget_stack"> + <layout_panel name="widget_container"> + <combo_box label="Nombre de usuario" name="username_combo" tool_tip="El nombre de usuario que elegiste al registrarte, como bobsmith12 o Steller Sunshine"/> + <line_editor label="Contraseña" name="password_edit"/> + <button label="Iniciar sesión" name="connect_btn"/> + <check_box label="Recordarme" name="remember_check"/> + <text name="forgot_password_text"> + Contraseña olvidada + </text> + <text name="sign_up_text"> + Regístrate + </text> + </layout_panel> + </layout_stack> + </layout_panel> + <layout_panel name="parent_panel3"> + <layout_stack name="images_stack"> + <layout_panel name="images_container"> + <text name="image_caption_left"> + Tu primer destino es la Isla de aprendizaje. ¡Encuentra el portal de salida! + </text> + <text name="image_caption_right"> + A continuación, puedes explorar la Isla social y hablar con otros residentes nuevos. + </text> + </layout_panel> + </layout_stack> + </layout_panel> + </layout_stack> +</panel> diff --git a/indra/newview/skins/default/xui/fr/panel_login_first.xml b/indra/newview/skins/default/xui/fr/panel_login_first.xml new file mode 100644 index 0000000000..8f40d0230c --- /dev/null +++ b/indra/newview/skins/default/xui/fr/panel_login_first.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="utf-8"?> +<panel name="panel_login"> + <panel.string name="forgot_password_url"> + http://secondlife.com/account/request.php?lang=fr + </panel.string> + <panel.string name="sign_up_url"> + https://join.secondlife.com/ + </panel.string> + <layout_stack name="logo_stack"> + <layout_panel name="parent_panel2"> + <layout_stack name="widget_stack"> + <layout_panel name="widget_container"> + <combo_box label="Nom d'utilisateur" name="username_combo" tool_tip="Nom d'utilisateur que vous avez choisi lors de votre inscription (par exemple, bobsmith12 ou Steller Sunshine)."/> + <line_editor label="Mot de passe" name="password_edit"/> + <button label="Connexion" name="connect_btn"/> + <check_box font="SansSerifSmall" label="Mémoriser mes informations" name="remember_check"/> + <text name="forgot_password_text"> + Mot de passe oublié + </text> + <text name="sign_up_text"> + S'inscrire + </text> + </layout_panel> + </layout_stack> + </layout_panel> + <layout_panel name="parent_panel3"> + <layout_stack name="images_stack"> + <layout_panel name="images_container"> + <text name="image_caption_left"> + Votre première étape est Learning Island. Trouvez le portail de sortie. + </text> + <text name="image_caption_right"> + Puis explorez Social Island et faites la connaissance d'autres résidents. + </text> + </layout_panel> + </layout_stack> + </layout_panel> + </layout_stack> +</panel> diff --git a/indra/newview/skins/default/xui/it/panel_login_first.xml b/indra/newview/skins/default/xui/it/panel_login_first.xml new file mode 100644 index 0000000000..5b04fd411a --- /dev/null +++ b/indra/newview/skins/default/xui/it/panel_login_first.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="utf-8"?> +<panel name="panel_login"> + <panel.string name="forgot_password_url"> + http://secondlife.com/account/request.php?lang=it + </panel.string> + <panel.string name="sign_up_url"> + http://join.secondlife.com/ + </panel.string> + <layout_stack name="logo_stack"> + <layout_panel name="parent_panel2"> + <layout_stack name="widget_stack"> + <layout_panel name="widget_container"> + <combo_box label="Nome utente" name="username_combo" tool_tip="Il nome utente che hai scelto durante la registrazione, come roby12 o Stella Solare"/> + <line_editor label="Password" name="password_edit"/> + <button label="Accedi" name="connect_btn"/> + <check_box label="Ricordami" name="remember_check"/> + <text name="forgot_password_text"> + Password dimenticata + </text> + <text name="sign_up_text"> + Registrati + </text> + </layout_panel> + </layout_stack> + </layout_panel> + <layout_panel name="parent_panel3"> + <layout_stack name="images_stack"> + <layout_panel name="images_container"> + <text name="image_caption_left"> + Il primo passo è a Learning Island. Trova il portale di uscita! + </text> + <text name="image_caption_right"> + Quindi esplora Social Island e incontra altri nuovi residenti. + </text> + </layout_panel> + </layout_stack> + </layout_panel> + </layout_stack> +</panel> diff --git a/indra/newview/skins/default/xui/ja/panel_login_first.xml b/indra/newview/skins/default/xui/ja/panel_login_first.xml new file mode 100644 index 0000000000..0f987fc816 --- /dev/null +++ b/indra/newview/skins/default/xui/ja/panel_login_first.xml @@ -0,0 +1,54 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="panel_login"> + <panel.string name="forgot_password_url"> + https://secondlife.com/my/account/request.php?lang=ja-JP + </panel.string> + <panel.string name="sign_up_url"> + https://join.secondlife.com/?lang=ja + </panel.string> + <layout_stack name="logo_stack"> + <layout_panel name="page_top"/> + <layout_panel name="parent_panel"> + <layout_stack name="logo_stack"> + <layout_panel name="logo_left"/> + <layout_panel name="logo_container"> + <icon name="sl_logo"/> + </layout_panel> + <layout_panel auto_resize="true"/> + </layout_stack> + </layout_panel> + <layout_panel name="parent_panel2"> + <layout_stack name="widget_stack"> + <layout_panel name="widget_left"/> + <layout_panel name="widget_container"> + <combo_box label="ユーザ名" tool_tip="登録時に自分で選んだユーザー名(例:bobsmith12、Steller Sunshineなど)" name="username_combo"> + <combo_box.combo_editor/> + <combo_box.combo_button/> + <combo_box.drop_down_button/> + </combo_box> + <line_editor name="password_edit" label="パスワード"/> + <button label="ログイン" name="connect_btn"/> + <text name="sign_up_text" valign="center"> + サインアップ + </text> + <check_box label="ユーザ名を記憶" name="remember_name" tool_tip="すでに記憶されているユーザーは、「私」>「初期設定」>「詳細設定」>「記憶されたユーザー名」から削除できます。"/> + <check_box label="パスワード記憶" name="remember_password"/> + <text name="forgot_password_text"> + パスワードを忘れましたか? + </text> + </layout_panel> + <layout_panel name="widget_right"/> + </layout_stack> + </layout_panel> + <layout_panel name="parent_panel3"> + <layout_stack name="images_stack"> + <layout_panel name="images_left"/> + <layout_panel name="images_container"> + <icon name="image_left"/> + </layout_panel> + <layout_panel name="images_right"/> + </layout_stack> + </layout_panel> + <layout_panel name="page_bottom"/> + </layout_stack> +</panel> diff --git a/indra/newview/skins/default/xui/pl/panel_login_first.xml b/indra/newview/skins/default/xui/pl/panel_login_first.xml new file mode 100644 index 0000000000..0604ecbcff --- /dev/null +++ b/indra/newview/skins/default/xui/pl/panel_login_first.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel name="panel_login"> + <layout_stack name="logo_stack"> + <layout_panel name="parent_panel2"> + <layout_stack name="widget_stack"> + <layout_panel name="widget_container"> + <combo_box label="Użytkownik" tool_tip="Nazwa użytkownika wybrana przy rejestracji, np. bobsmith12 lub Steller Sunshine" name="username_combo" /> + <line_editor name="password_edit" label="Hasło" /> + <button label="Zaloguj" name="connect_btn" /> + <check_box label="Zapamiętaj mnie" name="remember_check" /> + <text name="forgot_password_text"> + Zapomniałem/am hasła + </text> + </layout_panel> + </layout_stack> + </layout_panel> + <layout_panel name="parent_panel3"> + <layout_stack name="images_stack"> + <layout_panel name="images_container"> + <text name="image_caption_left"> + Wyspa Nauki to Twój pierwszy krok. Znajdź portal z wyjściem! + </text> + <text name="image_caption_right"> + Potem zwiedź Wyspę Towarzyską i poznaj innych nowych rezydentów! + </text> + </layout_panel> + </layout_stack> + </layout_panel> + </layout_stack> +</panel> diff --git a/indra/newview/skins/default/xui/pt/panel_login_first.xml b/indra/newview/skins/default/xui/pt/panel_login_first.xml new file mode 100644 index 0000000000..86c61163bc --- /dev/null +++ b/indra/newview/skins/default/xui/pt/panel_login_first.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="utf-8"?> +<panel name="panel_login"> + <panel.string name="forgot_password_url"> + http://secondlife.com/account/request.php?lang=pt + </panel.string> + <panel.string name="sign_up_url"> + https://join.secondlife.com/ + </panel.string> + <layout_stack name="logo_stack"> + <layout_panel name="parent_panel2"> + <layout_stack name="widget_stack"> + <layout_panel name="widget_container"> + <combo_box label="Nome de usuário" name="username_combo" tool_tip="O nome de usuário que você escolheu ao fazer seu cadastro, como zecazc12 ou Magia Solar"/> + <line_editor label="Senha" name="password_edit"/> + <button label="Login" name="connect_btn"/> + <check_box label="Lembrar-me" name="remember_check"/> + <text name="forgot_password_text"> + Senha esquecida + </text> + <text name="sign_up_text"> + Cadastre-se + </text> + </layout_panel> + </layout_stack> + </layout_panel> + <layout_panel name="parent_panel3"> + <layout_stack name="images_stack"> + <layout_panel name="images_container"> + <text name="image_caption_left"> + Sua primeira parada é a Ilha da Educação. Encontre o portal de saída! + </text> + <text name="image_caption_right"> + Em seguida, explore a Ilha Social e encontre novos residentes! + </text> + </layout_panel> + </layout_stack> + </layout_panel> + </layout_stack> +</panel> diff --git a/indra/newview/skins/default/xui/ru/panel_login_first.xml b/indra/newview/skins/default/xui/ru/panel_login_first.xml new file mode 100644 index 0000000000..5db81ea7ca --- /dev/null +++ b/indra/newview/skins/default/xui/ru/panel_login_first.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="utf-8"?> +<panel name="panel_login"> + <panel.string name="forgot_password_url"> + http://secondlife.com/account/request.php + </panel.string> + <panel.string name="sign_up_url"> + https://join.secondlife.com/ + </panel.string> + <layout_stack name="logo_stack"> + <layout_panel name="parent_panel2"> + <layout_stack name="widget_stack"> + <layout_panel name="widget_container"> + <combo_box label="Имя пользователя" name="username_combo" tool_tip="Имя пользователя, которое вы выбрали при регистрации, например, «bobsmith12» или «Steller Sunshine»"/> + <line_editor label="Пароль" name="password_edit"/> + <button label="Войти" name="connect_btn"/> + <check_box label="Запомнить меня" name="remember_check"/> + <text name="forgot_password_text"> + Забытый пароль + </text> + <text name="sign_up_text"> + Регистрация + </text> + </layout_panel> + </layout_stack> + </layout_panel> + <layout_panel name="parent_panel3"> + <layout_stack name="images_stack"> + <layout_panel name="images_container"> + <text name="image_caption_left"> + Ваш первый шаг – Учебный остров. Найдите портал выхода! + </text> + <text name="image_caption_right"> + Затем исследуйте Социальный остров и познакомьтесь с другими новичками! + </text> + </layout_panel> + </layout_stack> + </layout_panel> + </layout_stack> +</panel> diff --git a/indra/newview/skins/default/xui/tr/panel_login_first.xml b/indra/newview/skins/default/xui/tr/panel_login_first.xml new file mode 100644 index 0000000000..1fc80c2b97 --- /dev/null +++ b/indra/newview/skins/default/xui/tr/panel_login_first.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="utf-8"?> +<panel name="panel_login"> + <panel.string name="forgot_password_url"> + http://secondlife.com/account/request.php + </panel.string> + <panel.string name="sign_up_url"> + https://join.secondlife.com/ + </panel.string> + <layout_stack name="logo_stack"> + <layout_panel name="parent_panel2"> + <layout_stack name="widget_stack"> + <layout_panel name="widget_container"> + <combo_box label="Kullanıcı Adı" name="username_combo" tool_tip="Kaydolduğunuzda seçtiğiniz kullanıcı adı, örn. mustafayalcin12 veya Faruk Gungoren"/> + <line_editor label="Parola" name="password_edit"/> + <button label="Oturum Aç" name="connect_btn"/> + <check_box label="Beni hatırla" name="remember_check"/> + <text name="forgot_password_text"> + Parolamı unuttum + </text> + <text name="sign_up_text"> + Kaydol + </text> + </layout_panel> + </layout_stack> + </layout_panel> + <layout_panel name="parent_panel3"> + <layout_stack name="images_stack"> + <layout_panel name="images_container"> + <text name="image_caption_left"> + Başlangıç yeriniz Eğitim Adası. Haydi çıkış portalını bulun! + </text> + <text name="image_caption_right"> + Sonra da Sosyal Ada'yı keşfe çıkın ve diğer LS sakinleriyle tanışın! + </text> + </layout_panel> + </layout_stack> + </layout_panel> + </layout_stack> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_login_first.xml b/indra/newview/skins/default/xui/zh/panel_login_first.xml new file mode 100644 index 0000000000..4d72fcdd03 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_login_first.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="utf-8"?> +<panel name="panel_login"> + <panel.string name="forgot_password_url"> + http://secondlife.com/account/request.php + </panel.string> + <panel.string name="sign_up_url"> + http://join.secondlife.com/ + </panel.string> + <layout_stack name="logo_stack"> + <layout_panel name="parent_panel2"> + <layout_stack name="widget_stack"> + <layout_panel name="widget_container"> + <combo_box label="使用者名稱" name="username_combo" tool_tip="使用者名稱是你註冊時所挑選的,例如 bobsmith12 或 Steller Sunshine"/> + <line_editor label="密碼" name="password_edit"/> + <button label="登入" name="connect_btn"/> + <check_box label="記得我" name="remember_check"/> + <text name="forgot_password_text"> + 忘記密碼 + </text> + <text name="sign_up_text"> + 註冊 + </text> + </layout_panel> + </layout_stack> + </layout_panel> + <layout_panel name="parent_panel3"> + <layout_stack name="images_stack"> + <layout_panel name="images_container"> + <text name="image_caption_left"> + 你在「學習島」的第一步。 找到離開的傳送門! + </text> + <text name="image_caption_right"> + 接著,到「社交島」探索,認識新的居民朋友! + </text> + </layout_panel> + </layout_stack> + </layout_panel> + </layout_stack> +</panel> diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 6991e0c8f2..4804d04e45 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -148,6 +148,7 @@ class ViewerManifest(LLManifest): with self.prefix(src_dst="skins"): # include the entire textures directory recursively with self.prefix(src_dst="*/textures"): + self.path("*/*.jpg") self.path("*/*.png") self.path("*.tga") self.path("*.j2c") |