master
Ansariel 2021-03-27 11:33:19 +01:00
commit e0152ecc39
16 changed files with 582 additions and 81 deletions

View File

@ -342,6 +342,7 @@ set(viewer_SOURCE_FILES
llfloatercolorpicker.cpp
llfloaterconversationlog.cpp
llfloaterconversationpreview.cpp
llfloatercreatelandmark.cpp
llfloaterdeleteprefpreset.cpp
llfloaterdestinations.cpp
llfloaterdisplayname.cpp
@ -1111,6 +1112,7 @@ set(viewer_HEADER_FILES
llfloatercolorpicker.h
llfloaterconversationlog.h
llfloaterconversationpreview.h
llfloatercreatelandmark.h
llfloaterdeleteprefpreset.h
llfloaterdestinations.h
llfloaterdisplayname.h

View File

@ -6925,6 +6925,17 @@
<string>https://search.[GRID]/viewer/[CATEGORY]/?q=[QUERY]&amp;p=[AUTH_TOKEN]&amp;r=[MATURITY]&amp;lang=[LANGUAGE]&amp;g=[GODLIKE]&amp;sid=[SESSION_ID]&amp;rid=[REGION_ID]&amp;pid=[PARCEL_ID]&amp;channel=[CHANNEL]&amp;version=[VERSION]&amp;major=[VERSION_MAJOR]&amp;minor=[VERSION_MINOR]&amp;patch=[VERSION_PATCH]&amp;build=[VERSION_BUILD]</string>
-->
</map>
<key>GuidebookURL</key>
<map>
<key>Comment</key>
<string>URL for Guidebook content</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
<string>https://guidebooks.secondlife.io/welcome</string>
</map>
<key>HighResSnapshot</key>
<map>
<key>Comment</key>

View File

@ -0,0 +1,314 @@
/**
* @file llfloatercreatelandmark.cpp
* @brief LLFloaterCreateLandmark class implementation
*
* $LicenseInfo:firstyear=2021&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2021, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "llfloatercreatelandmark.h"
#include "llagent.h"
#include "llagentui.h"
#include "llcombobox.h"
#include "llinventoryfunctions.h"
#include "llinventoryobserver.h"
#include "lllandmarkactions.h"
#include "llnotificationsutil.h"
#include "llpanellandmarkinfo.h"
#include "llparcel.h"
#include "lltextbox.h"
#include "lltexteditor.h"
#include "lluictrlfactory.h"
#include "llviewermessage.h"
#include "llviewerparcelmgr.h"
#include "llviewerregion.h"
typedef std::pair<LLUUID, std::string> folder_pair_t;
class LLLandmarksInventoryObserver : public LLInventoryAddedObserver
{
public:
LLLandmarksInventoryObserver(LLFloaterCreateLandmark* create_landmark_floater) :
mFloater(create_landmark_floater)
{}
protected:
/*virtual*/ void done()
{
mFloater->setItem(gInventory.getAddedIDs());
}
private:
LLFloaterCreateLandmark* mFloater;
};
LLFloaterCreateLandmark::LLFloaterCreateLandmark(const LLSD& key)
: LLFloater("add_landmark"),
mItem(NULL)
{
mInventoryObserver = new LLLandmarksInventoryObserver(this);
}
LLFloaterCreateLandmark::~LLFloaterCreateLandmark()
{
removeObserver();
}
BOOL LLFloaterCreateLandmark::postBuild()
{
mFolderCombo = getChild<LLComboBox>("folder_combo");
mLandmarkTitleEditor = getChild<LLLineEditor>("title_editor");
mNotesEditor = getChild<LLTextEditor>("notes_editor");
getChild<LLTextBox>("new_folder_textbox")->setURLClickedCallback(boost::bind(&LLFloaterCreateLandmark::onCreateFolderClicked, this));
getChild<LLButton>("ok_btn")->setClickedCallback(boost::bind(&LLFloaterCreateLandmark::onSaveClicked, this));
getChild<LLButton>("cancel_btn")->setClickedCallback(boost::bind(&LLFloaterCreateLandmark::onCancelClicked, this));
mLandmarksID = gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK);
return TRUE;
}
void LLFloaterCreateLandmark::removeObserver()
{
if (gInventory.containsObserver(mInventoryObserver))
gInventory.removeObserver(mInventoryObserver);
}
void LLFloaterCreateLandmark::onOpen(const LLSD& key)
{
LLUUID dest_folder = LLUUID();
if (key.has("dest_folder"))
{
dest_folder = key["dest_folder"].asUUID();
}
mItem = NULL;
gInventory.addObserver(mInventoryObserver);
setLandmarkInfo(dest_folder);
populateFoldersList(dest_folder);
}
void LLFloaterCreateLandmark::setLandmarkInfo(const LLUUID &folder_id)
{
LLViewerParcelMgr* parcel_mgr = LLViewerParcelMgr::getInstance();
LLParcel* parcel = parcel_mgr->getAgentParcel();
std::string name = parcel->getName();
LLVector3 agent_pos = gAgent.getPositionAgent();
if (name.empty())
{
S32 region_x = ll_round(agent_pos.mV[VX]);
S32 region_y = ll_round(agent_pos.mV[VY]);
S32 region_z = ll_round(agent_pos.mV[VZ]);
std::string region_name;
LLViewerRegion* region = parcel_mgr->getSelectionRegion();
if (region)
{
region_name = region->getName();
}
else
{
std::string desc;
LLAgentUI::buildLocationString(desc, LLAgentUI::LOCATION_FORMAT_NORMAL, agent_pos);
region_name = desc;
}
mLandmarkTitleEditor->setText(llformat("%s (%d, %d, %d)",
region_name.c_str(), region_x, region_y, region_z));
}
else
{
mLandmarkTitleEditor->setText(name);
}
LLLandmarkActions::createLandmarkHere(name, "", folder_id.notNull() ? folder_id : gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE));
}
bool cmp_folders(const folder_pair_t& left, const folder_pair_t& right)
{
return left.second < right.second;
}
void LLFloaterCreateLandmark::populateFoldersList(const LLUUID &folder_id)
{
// Collect all folders that can contain landmarks.
LLInventoryModel::cat_array_t cats;
LLPanelLandmarkInfo::collectLandmarkFolders(cats);
mFolderCombo->removeall();
// Put the "My Favorites" folder first in list.
LLUUID favorites_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
LLViewerInventoryCategory* favorites_cat = gInventory.getCategory(favorites_id);
if (!favorites_cat)
{
LL_WARNS() << "Cannot find the favorites folder" << LL_ENDL;
}
else
{
mFolderCombo->add(getString("favorites_bar"), favorites_cat->getUUID());
}
// Add the "Landmarks" category.
const LLViewerInventoryCategory* lmcat = gInventory.getCategory(mLandmarksID);
if (!lmcat)
{
LL_WARNS() << "Cannot find the landmarks folder" << LL_ENDL;
}
else
{
std::string cat_full_name = LLPanelLandmarkInfo::getFullFolderName(lmcat);
mFolderCombo->add(cat_full_name, lmcat->getUUID());
}
typedef std::vector<folder_pair_t> folder_vec_t;
folder_vec_t folders;
// Sort the folders by their full name.
for (S32 i = 0; i < cats.size(); i++)
{
const LLViewerInventoryCategory* cat = cats.at(i);
std::string cat_full_name = LLPanelLandmarkInfo::getFullFolderName(cat);
folders.push_back(folder_pair_t(cat->getUUID(), cat_full_name));
}
sort(folders.begin(), folders.end(), cmp_folders);
// Finally, populate the combobox.
for (folder_vec_t::const_iterator it = folders.begin(); it != folders.end(); it++)
mFolderCombo->add(it->second, LLSD(it->first));
if (folder_id.notNull())
{
mFolderCombo->setCurrentByID(folder_id);
}
}
void LLFloaterCreateLandmark::onCreateFolderClicked()
{
LLNotificationsUtil::add("CreateLandmarkFolder", LLSD(), LLSD(),
[this](const LLSD&notif, const LLSD&resp)
{
S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp);
if (opt == 0)
{
std::string folder_name = resp["message"].asString();
if (!folder_name.empty())
{
inventory_func_type func = boost::bind(&LLFloaterCreateLandmark::folderCreatedCallback, this, _1);
LLUUID test = gInventory.createNewCategory(mLandmarksID, LLFolderType::FT_NONE, folder_name, func);
gInventory.notifyObservers();
}
}
});
}
void LLFloaterCreateLandmark::folderCreatedCallback(LLUUID folder_id)
{
populateFoldersList(folder_id);
}
void LLFloaterCreateLandmark::onSaveClicked()
{
if (mItem.isNull())
return;
std::string current_title_value = mLandmarkTitleEditor->getText();
std::string item_title_value = mItem->getName();
std::string current_notes_value = mNotesEditor->getText();
std::string item_notes_value = mItem->getDescription();
LLStringUtil::trim(current_title_value);
LLStringUtil::trim(current_notes_value);
LLUUID item_id = mItem->getUUID();
LLUUID folder_id = mFolderCombo->getValue().asUUID();
bool change_parent = folder_id != mItem->getParentUUID();
LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(mItem);
if (!current_title_value.empty() &&
(item_title_value != current_title_value || item_notes_value != current_notes_value))
{
new_item->rename(current_title_value);
new_item->setDescription(current_notes_value);
LLPointer<LLInventoryCallback> cb;
if (change_parent)
{
cb = new LLUpdateLandmarkParent(new_item, folder_id);
}
LLInventoryModel::LLCategoryUpdate up(mItem->getParentUUID(), 0);
gInventory.accountForUpdate(up);
update_inventory_item(new_item, cb);
}
else if (change_parent)
{
LLInventoryModel::update_list_t update;
LLInventoryModel::LLCategoryUpdate old_folder(mItem->getParentUUID(),-1);
update.push_back(old_folder);
LLInventoryModel::LLCategoryUpdate new_folder(folder_id, 1);
update.push_back(new_folder);
gInventory.accountForUpdate(update);
new_item->setParent(folder_id);
new_item->updateParentOnServer(FALSE);
}
gInventory.updateItem(new_item);
gInventory.notifyObservers();
closeFloater();
}
void LLFloaterCreateLandmark::onCancelClicked()
{
closeFloater();
}
void LLFloaterCreateLandmark::setItem(const uuid_set_t& items)
{
for (uuid_set_t::const_iterator item_iter = items.begin();
item_iter != items.end();
++item_iter)
{
const LLUUID& item_id = (*item_iter);
if(!highlight_offered_object(item_id))
{
continue;
}
LLInventoryItem* item = gInventory.getItem(item_id);
llassert(item);
if (item && (LLAssetType::AT_LANDMARK == item->getType()) )
{
if(!getItem())
{
removeObserver();
mItem = item;
break;
}
}
}
}

View File

@ -0,0 +1,75 @@
/**
* @file llfloatercreatelandmark.h
* @brief LLFloaterCreateLandmark class definition
*
* $LicenseInfo:firstyear=2021&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2021, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_LLFLOATERCREATELANDMARK_H
#define LL_LLFLOATERCREATELANDMARK_H
#include "llfloater.h"
class LLComboBox;
class LLInventoryItem;
class LLLineEditor;
class LLTextEditor;
class LLLandmarksInventoryObserver;
class LLFloaterCreateLandmark:
public LLFloater
{
friend class LLFloaterReg;
public:
LLFloaterCreateLandmark(const LLSD& key);
~LLFloaterCreateLandmark();
BOOL postBuild();
void onOpen(const LLSD& key);
void setItem(const uuid_set_t& items);
LLInventoryItem* getItem() { return mItem; }
private:
void setLandmarkInfo(const LLUUID &folder_id);
void removeObserver();
void populateFoldersList(const LLUUID &folder_id = LLUUID::null);
void onCreateFolderClicked();
void onSaveClicked();
void onCancelClicked();
void folderCreatedCallback(LLUUID folder_id);
LLComboBox* mFolderCombo;
LLLineEditor* mLandmarkTitleEditor;
LLTextEditor* mNotesEditor;
LLUUID mLandmarksID;
LLUUID mItemID;
LLLandmarksInventoryObserver* mInventoryObserver;
LLPointer<LLInventoryItem> mItem;
};
#endif

View File

@ -44,6 +44,7 @@
// newview includes
#include "llagent.h"
#include "llfloaterreg.h"
#include "llfloatersidepanelcontainer.h"
#include "llinventoryobserver.h"
#include "lllandmarkactions.h"
@ -694,10 +695,7 @@ void LLLocationInputCtrl::onAddLandmarkButtonClicked()
}
else
{
// <FS:Ansariel> FIRE-817: Separate place details floater
//LLFloaterSidePanelContainer::showPanel("places", LLSD().with("type", "create_landmark"));
FSFloaterPlaceDetails::showPlaceDetails(LLSD().with("type", "create_landmark"));
// </FS:Ansariel>
LLFloaterReg::showInstance("add_landmark");
}
}
@ -1213,10 +1211,7 @@ void LLLocationInputCtrl::onLocationContextMenuItemClicked(const LLSD& userdata)
if(!landmark)
{
// <FS:Ansariel> FIRE-817: Separate place details floater
//LLFloaterSidePanelContainer::showPanel("places", LLSD().with("type", "create_landmark"));
FSFloaterPlaceDetails::showPlaceDetails(LLSD().with("type", "create_landmark"));
// </FS:Ansariel>
LLFloaterReg::showInstance("add_landmark");
}
else
{

View File

@ -52,7 +52,6 @@
typedef std::pair<LLUUID, std::string> folder_pair_t;
static bool cmp_folders(const folder_pair_t& left, const folder_pair_t& right);
static void collectLandmarkFolders(LLInventoryModel::cat_array_t& cats);
static LLPanelInjector<LLPanelLandmarkInfo> t_landmark_info("panel_landmark_info");
@ -516,7 +515,7 @@ static bool cmp_folders(const folder_pair_t& left, const folder_pair_t& right)
return left.second < right.second;
}
static void collectLandmarkFolders(LLInventoryModel::cat_array_t& cats)
void LLPanelLandmarkInfo::collectLandmarkFolders(LLInventoryModel::cat_array_t& cats)
{
LLUUID landmarks_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK);
@ -529,16 +528,20 @@ static void collectLandmarkFolders(LLInventoryModel::cat_array_t& cats)
items,
LLInventoryModel::EXCLUDE_TRASH,
is_category);
// Add the "My Favorites" category.
LLUUID favorites_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
LLViewerInventoryCategory* favorites_cat = gInventory.getCategory(favorites_id);
if (!favorites_cat)
{
LL_WARNS() << "Cannot find the favorites folder" << LL_ENDL;
}
else
{
cats.push_back(favorites_cat);
}
}
/* virtual */ void LLUpdateLandmarkParent::fire(const LLUUID& inv_item_id)
{
LLInventoryModel::update_list_t update;
LLInventoryModel::LLCategoryUpdate old_folder(mItem->getParentUUID(), -1);
update.push_back(old_folder);
LLInventoryModel::LLCategoryUpdate new_folder(mNewParentId, 1);
update.push_back(new_folder);
gInventory.accountForUpdate(update);
mItem->setParent(mNewParentId);
mItem->updateParentOnServer(FALSE);
gInventory.updateItem(mItem);
gInventory.notifyObservers();
}

View File

@ -28,6 +28,7 @@
#define LL_LLPANELLANDMARKINFO_H
#include "llpanelplaceinfo.h"
#include "llinventorymodel.h"
class LLComboBox;
class LLLineEditor;
@ -63,7 +64,9 @@ public:
// Select current landmark folder in combobox.
BOOL setLandmarkFolder(const LLUUID& id);
typedef std::vector<LLPointer<LLViewerInventoryCategory> > cat_array_t;
static std::string getFullFolderName(const LLViewerInventoryCategory* cat);
static void collectLandmarkFolders(LLInventoryModel::cat_array_t& cats);
private:
// Create a landmark for the current location
@ -85,4 +88,17 @@ private:
LLComboBox* mFolderCombo;
};
class LLUpdateLandmarkParent : public LLInventoryCallback
{
public:
LLUpdateLandmarkParent(LLPointer<LLViewerInventoryItem> item, LLUUID new_parent) :
mItem(item),
mNewParentId(new_parent)
{};
/* virtual */ void fire(const LLUUID& inv_item_id);
private:
LLPointer<LLViewerInventoryItem> mItem;
LLUUID mNewParentId;
};
#endif // LL_LLPANELLANDMARKINFO_H

View File

@ -65,7 +65,6 @@
// helper functions
static void filter_list(LLPlacesInventoryPanel* inventory_list, const std::string& string);
static bool category_has_descendents(LLPlacesInventoryPanel* inventory_list);
static void collapse_all_folders(LLFolderView* root_folder);
static void expand_all_folders(LLFolderView* root_folder);
static bool has_expanded_folders(LLFolderView* root_folder);
@ -508,10 +507,7 @@ void LLLandmarksPanel::onAddAction(const LLSD& userdata) const
{
args["dest_folder"] = view_model->getUUID();
}
// <FS:Ansariel> FIRE-817: Separate place details floater
//LLFloaterSidePanelContainer::showPanel("places", args);
FSFloaterPlaceDetails::showPlaceDetails(args);
// </FS:Ansariel>
LLFloaterReg::showInstance("add_landmark", args);
}
// [RLVa:KB] - Checked: 2012-02-08 (RLVa-1.4.5) | Added: RLVa-1.4.5
}
@ -1122,17 +1118,6 @@ static void filter_list(LLPlacesInventoryPanel* inventory_list, const std::strin
inventory_list->setFilterSubString(string);
}
static bool category_has_descendents(LLPlacesInventoryPanel* inventory_list)
{
LLViewerInventoryCategory* category = gInventory.getCategory(inventory_list->getRootFolderID());
if (category)
{
return category->getDescendentCount() > 0;
}
return false;
}
static void collapse_all_folders(LLFolderView* root_folder)
{
if (!root_folder)

View File

@ -807,34 +807,6 @@ void LLPanelPlaces::onEditButtonClicked()
updateVerbs();
}
class LLUpdateLandmarkParent : public LLInventoryCallback
{
public:
LLUpdateLandmarkParent(LLPointer<LLViewerInventoryItem> item, LLUUID new_parent) :
mItem(item),
mNewParentId(new_parent)
{};
/* virtual */ void fire(const LLUUID& inv_item_id)
{
LLInventoryModel::update_list_t update;
LLInventoryModel::LLCategoryUpdate old_folder(mItem->getParentUUID(), -1);
update.push_back(old_folder);
LLInventoryModel::LLCategoryUpdate new_folder(mNewParentId, 1);
update.push_back(new_folder);
gInventory.accountForUpdate(update);
mItem->setParent(mNewParentId);
mItem->updateParentOnServer(FALSE);
gInventory.updateItem(mItem);
gInventory.notifyObservers();
}
private:
LLPointer<LLViewerInventoryItem> mItem;
LLUUID mNewParentId;
};
void LLPanelPlaces::onSaveButtonClicked()
{
if (!mLandmarkInfo || mItem.isNull())

View File

@ -31,6 +31,7 @@
#include "llagent.h"
#include "llagentui.h"
#include "llclipboard.h"
#include "llfloaterreg.h"
#include "llfloatersidepanelcontainer.h"
#include "lllandmarkactions.h"
#include "lllocationinputctrl.h"
@ -476,10 +477,7 @@ void LLPanelTopInfoBar::onContextMenuItemClicked(const LLSD::String& item)
if(landmark == NULL)
{
// <FS:Ansariel> FIRE-817: Separate place details floater
//LLFloaterSidePanelContainer::showPanel("places", LLSD().with("type", "create_landmark"));
FSFloaterPlaceDetails::showPlaceDetails(LLSD().with("type", "create_landmark"));
// </FS:Ansariel>
LLFloaterReg::showInstance("add_landmark");
}
else
{

View File

@ -297,7 +297,7 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal
mLineEditor->setText(edit_text_contents);
std::string notif_name = mNotification->getName();
if (("SaveOutfitAs" == notif_name) || ("SaveSettingAs" == notif_name))
if (("SaveOutfitAs" == notif_name) || ("SaveSettingAs" == notif_name) || ("CreateLandmarkFolder" == notif_name))
{
mLineEditor->setPrevalidate(&LLTextValidate::validateASCII);
}

View File

@ -58,6 +58,7 @@
#include "llfloaterchatvoicevolume.h"
#include "llfloaterconversationlog.h"
#include "llfloaterconversationpreview.h"
#include "llfloatercreatelandmark.h"
#include "llfloaterdeleteprefpreset.h"
#include "llfloaterdestinations.h"
#include "llfloatereditextdaycycle.h"
@ -277,6 +278,7 @@ void LLViewerFloaterReg::registerFloaters()
// </FS:Ansariel> [FS communication UI]
LLFloaterReg::add("compile_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCompileQueue>);
LLFloaterReg::add("conversation", "floater_conversation_log.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterConversationLog>);
LLFloaterReg::add("add_landmark", "floater_create_landmark.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCreateLandmark>);
LLFloaterReg::add("delete_pref_preset", "floater_delete_pref_preset.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterDeletePrefPreset>);
LLFloaterReg::add("destinations", "floater_destinations.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterDestinations>);

View File

@ -7468,10 +7468,7 @@ class LLWorldCreateLandmark : public view_listener_t
return true;
// [/RLVa:KB]
// <FS:Ansariel> FIRE-817: Separate place details floater
//LLFloaterSidePanelContainer::showPanel("places", LLSD().with("type", "create_landmark"));
FSFloaterPlaceDetails::showPlaceDetails(LLSD().with("type", "create_landmark"));
// </FS:Ansariel>
LLFloaterReg::showInstance("add_landmark");
return true;
}

View File

@ -0,0 +1,110 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater
can_resize="false"
show_title="false"
can_minimize="false"
can_close="false"
height="305"
layout="topleft"
name="create_landmark"
width="330">
<string name="favorites_bar">
Favorites bar
</string>
<text
follows="left|top"
height="15"
layout="topleft"
left="20"
name="title_label"
top="5"
font="SansSerifLargeBold"
value="Landmark added"
width="290" />
<text
follows="left|top"
height="15"
layout="topleft"
left="20"
name="name_label"
top_pad="10"
value="Name"
width="290" />
<line_editor
follows="left|top"
height="22"
layout="topleft"
max_length_bytes="63"
name="title_editor"
prevalidate_callback="ascii"
text_readonly_color="white"
top_pad="5"
width="290" />
<text
follows="left|top"
height="15"
layout="topleft"
name="folder_label"
top_pad="10"
value="Landmark location:"
width="290" />
<combo_box
follows="bottom|left"
height="23"
layout="topleft"
name="folder_combo"
top_pad="2"
width="290" />
<text
follows="left|top"
layout="topleft"
top_pad="6"
left="20"
name="new_folder_textbox"
height="20"
parse_urls="true"
skip_link_underline="true"
wrap="true">
[secondlife:/// Create new folder]
</text>
<text
follows="left|top"
height="15"
layout="topleft"
name="notes_label"
top_pad="10"
value="My notes"
width="290" />
<text_editor
bg_readonly_color="DkGray0"
follows="all"
height="75"
layout="topleft"
max_length="127"
name="notes_editor"
spellcheck="true"
text_readonly_color="white"
text_type="ascii_with_newline"
top_pad="5"
width="290"
wrap="true" />
<button
follows="bottom|left|right"
height="23"
label="OK"
layout="topleft"
mouse_opaque="false"
name="ok_btn"
top_pad="10"
left="19"
width="140" />
<button
follows="bottom|left|right"
height="23"
label="Cancel"
layout="topleft"
left_pad="12"
mouse_opaque="false"
name="cancel_btn"
width="140" />
</floater>

View File

@ -1,16 +1,14 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater
legacy_header_height="18"
can_resize="true"
can_minimize="true"
can_resize="false"
can_minimize="false"
can_close="false"
height="775"
layout="topleft"
min_height="360"
left="10000"
top="10"
top="0"
min_width="335"
name="floater_how_to"
help_topic="how_to"
single_instance="true"
save_rect="true"
title="How to"

View File

@ -2412,6 +2412,29 @@ You cannot create a landmark here because the owner of the land does not allow i
<tag>fail</tag>
</notification>
<notification
icon="alertmodal.tga"
label="Create folder"
name="CreateLandmarkFolder"
type="alertmodal">
<unique/>
Choose a name for the folder:
<tag>confirm</tag>
<form name="form">
<input name="message" type="text">
</input>
<button
default="true"
index="0"
name="OK"
text="OK"/>
<button
index="1"
name="Cancel"
text="Cancel"/>
</form>
</notification>
<notification
icon="alertmodal.tga"
name="CannotRecompileSelectObjectsNoScripts"