From 548727ab00558976dc2574710d20bd35a9eedf0b Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 15 Aug 2025 17:35:45 +0300 Subject: #4537 Some links were missing favorite options --- indra/newview/llinventorybridge.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) 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); } -- cgit v1.2.3 From d5cc91e1f1b7ea71d0866d91d4a39ab826957635 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 15 Aug 2025 19:55:22 +0300 Subject: #4559 Crash at killCacheEntry --- indra/newview/llviewermessage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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); } -- cgit v1.2.3 From 99001eaa4ffdac78953a64797d9d8163b9d32791 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 15 Aug 2025 20:03:30 +0300 Subject: #4561 Crash at initializeURLHistory --- indra/llui/llflatlistview.cpp | 2 +- indra/newview/llfloaterwebcontent.cpp | 2 +- 2 files changed, 2 insertions(+), 2 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/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); } } -- cgit v1.2.3 From 89b8490dedb3f8c41c6027da6af0be4552d81a23 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Sat, 16 Aug 2025 09:27:10 +0300 Subject: #4544 Fix extension check being case sensitive --- indra/newview/llfloatermodelpreview.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 08d3488ef2..96a03ce2a6 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -1322,18 +1322,19 @@ void LLFloaterModelPreview::createSmoothComboBox(LLComboBox* combo_box, float mi } } -std::string get_source_file_extr(const std::string& filename) +std::string get_source_file_format(const std::string& filename) { - if (std::string::npos != filename.rfind(".gltf") - || std::string::npos != filename.rfind(".glb")) + const std::string extension = gDirUtilp->getExtension(filename); + if (extension == "gltf" + || extension == "glb") { return "gltf"; } - else if (std::string::npos != filename.rfind(".dae")) + else if (extension == "dae") { return "dae"; } - else if (std::string::npos != filename.rfind(".slm")) + else if (extension == "slm") { return "slm"; } @@ -1366,7 +1367,7 @@ void LLFloaterModelPreview::fillLODSourceStatistics(LLFloaterModelPreview::lod_s else if (mLODMode[lod] == LLModelPreview::LOD_FROM_FILE) { const std::string& file = mModelPreview->mLODFile[lod]; - lod_sources[lod_string] = get_source_file_extr(file); + lod_sources[lod_string] = get_source_file_format(file); } else { @@ -1391,7 +1392,7 @@ void LLFloaterModelPreview::fillLODSourceStatistics(LLFloaterModelPreview::lod_s { // There is a chance it will misfire if someone tries to upload a cube.dae mesh, // but should be negligible enough. - lod_sources["physics"] = get_source_file_extr(file); + lod_sources["physics"] = get_source_file_format(file); } else { -- cgit v1.2.3 From a9a2e7c633bbe289b553762741adfe9e4ad94928 Mon Sep 17 00:00:00 2001 From: Maxim Nikolenko Date: Mon, 18 Aug 2025 16:21:01 +0300 Subject: #4557 fix lags in outfit search with many outfits --- indra/newview/lloutfitslist.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) 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(tab->getAccordionView()); if (list) { - list->setFilterSubString(new_string, true); + list->setFilterSubString(new_string, tab->getDisplayChildren()); } if (old_string.empty()) -- cgit v1.2.3 From b96c7ec6e6e2e4f2bfd11469155bec4827ac9517 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 18 Aug 2025 22:15:51 +0300 Subject: #4518 Dupplicates can appear in favorites if parent and child gets added back to back --- indra/newview/llinventorypanel.cpp | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index b540e9c5bb..b2dd47548c 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -2298,6 +2298,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 +2345,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(); @@ -2495,7 +2514,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 +2527,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); -- cgit v1.2.3 From 434f9e927135d961b51b2175960a27be3908f7c3 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 18 Aug 2025 21:36:45 +0300 Subject: #4544 Make model dump go into logs not into work folder, viewer isn't supposed to write there. --- indra/newview/llfloatermodelpreview.cpp | 16 ++++++++++------ indra/newview/llfloatermodelpreview.h | 1 + indra/newview/llmeshrepository.cpp | 2 ++ 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 96a03ce2a6..f76f39222b 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -1090,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; @@ -1344,6 +1342,13 @@ std::string get_source_file_format(const std::string& filename) } } +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(); @@ -1388,10 +1393,9 @@ void LLFloaterModelPreview::fillLODSourceStatistics(LLFloaterModelPreview::lod_s else { const std::string& file = mModelPreview->mLODFile[LLModel::LOD_PHYSICS]; - if (std::string::npos == file.rfind("cube.dae")) + const std::string cube = getBoundingBoxCubePath(); + if (cube != file) // check for "cube.dae" { - // There is a chance it will misfire if someone tries to upload a cube.dae mesh, - // but should be negligible enough. lod_sources["physics"] = get_source_file_format(file); } else diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h index 982f36c46e..20e5b2666a 100644 --- a/indra/newview/llfloatermodelpreview.h +++ b/indra/newview/llfloatermodelpreview.h @@ -223,6 +223,7 @@ private: void createSmoothComboBox(LLComboBox* combo_box, float min, float max); + static std::string getBoundingBoxCubePath(); typedef std::map lod_sources_map_t; void fillLODSourceStatistics(lod_sources_map_t& lod_sources) const; diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index fd3360b234..9e8ed3bb43 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -2685,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); } -- cgit v1.2.3 From 07daeb4632d34a469b459347bd46800ebb05bc54 Mon Sep 17 00:00:00 2001 From: Signal Linden Date: Tue, 19 Aug 2025 12:22:36 -0700 Subject: Revert "Remove the first login screen (#4451)" (#4578) * Revert "Remove the first login screen (#4451)" This reverts commit b82f52acbb00a9dd3e5426e8a6510a0ef6f41289. * Revert "#4451 Remove missed first login image" This reverts commit 8eb2429a16b7dee570a28578f3d75f2a423f20af. --- indra/newview/llpanellogin.cpp | 103 +++++--- indra/newview/llpanellogin.h | 1 + indra/newview/skins/default/textures/textures.xml | 1 + .../default/textures/windows/first_login_image.jpg | Bin 0 -> 104529 bytes .../skins/default/xui/de/panel_login_first.xml | 39 +++ .../skins/default/xui/en/panel_login_first.xml | 262 +++++++++++++++++++++ .../skins/default/xui/es/panel_login_first.xml | 39 +++ .../skins/default/xui/fr/panel_login_first.xml | 39 +++ .../skins/default/xui/it/panel_login_first.xml | 39 +++ .../skins/default/xui/ja/panel_login_first.xml | 54 +++++ .../skins/default/xui/pl/panel_login_first.xml | 30 +++ .../skins/default/xui/pt/panel_login_first.xml | 39 +++ .../skins/default/xui/ru/panel_login_first.xml | 39 +++ .../skins/default/xui/tr/panel_login_first.xml | 39 +++ .../skins/default/xui/zh/panel_login_first.xml | 39 +++ indra/newview/viewer_manifest.py | 1 + 16 files changed, 728 insertions(+), 36 deletions(-) create mode 100644 indra/newview/skins/default/textures/windows/first_login_image.jpg create mode 100644 indra/newview/skins/default/xui/de/panel_login_first.xml create mode 100644 indra/newview/skins/default/xui/en/panel_login_first.xml create mode 100644 indra/newview/skins/default/xui/es/panel_login_first.xml create mode 100644 indra/newview/skins/default/xui/fr/panel_login_first.xml create mode 100644 indra/newview/skins/default/xui/it/panel_login_first.xml create mode 100644 indra/newview/skins/default/xui/ja/panel_login_first.xml create mode 100644 indra/newview/skins/default/xui/pl/panel_login_first.xml create mode 100644 indra/newview/skins/default/xui/pt/panel_login_first.xml create mode 100644 indra/newview/skins/default/xui/ru/panel_login_first.xml create mode 100644 indra/newview/skins/default/xui/tr/panel_login_first.xml create mode 100644 indra/newview/skins/default/xui/zh/panel_login_first.xml 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("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("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("server_combo"); - server_choice_combo->setCommitCallback(boost::bind(&LLPanelLogin::onSelectServer, this)); + LLComboBox* server_choice_combo = getChild("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 known_grids = LLGridManager::getInstance()->getKnownGrids(); - for (std::map::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 known_grids = LLGridManager::getInstance()->getKnownGrids(); + for (std::map::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("username_combo")->getSimple(); + mUsernameLength = static_cast(user_defined_name.length()); + updateLoginButtons(); + return; + } + // Clear the combo. LLComboBox* combo = getChild("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 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 cred = gSecAPIHandler->loadCredential(LLGridManager::getInstance()->getGrid()); + sInstance->populateUserList(cred); + } } // static @@ -560,6 +586,7 @@ void LLPanelLogin::setFields(LLPointer 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("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("username_combo"); - LLCheckBoxCtrl* remember_name = getChild("remember_name"); - if (user_combo->getCurrentIndex() != -1) + if (!mFirstLoginThisInstall) { - remember_name->setValue(true); - LLCheckBoxCtrl* remember_pass = getChild("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("username_combo"); + LLCheckBoxCtrl* remember_name = getChild("remember_name"); + if (user_combo->getCurrentIndex() != -1) + { + remember_name->setValue(true); + LLCheckBoxCtrl* remember_pass = getChild("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 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/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 + diff --git a/indra/newview/skins/default/textures/windows/first_login_image.jpg b/indra/newview/skins/default/textures/windows/first_login_image.jpg new file mode 100644 index 0000000000..30f31341ed Binary files /dev/null and b/indra/newview/skins/default/textures/windows/first_login_image.jpg differ 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 @@ + + + + http://secondlife.com/account/request.php?lang=de + + + https://join.secondlife.com/ + + + + + + + +