summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/llappearancemgr.cpp47
-rw-r--r--indra/newview/llcallfloater.cpp3
-rw-r--r--indra/newview/llchathistory.cpp13
-rw-r--r--indra/newview/llfavoritesbar.cpp21
-rw-r--r--indra/newview/llfloaterpreference.cpp100
-rw-r--r--indra/newview/llfloaterpreference.h16
-rw-r--r--indra/newview/llfloatersnapshot.cpp4
-rw-r--r--indra/newview/llgroupactions.cpp7
-rw-r--r--indra/newview/llnamelistctrl.cpp3
-rw-r--r--indra/newview/llnavigationbar.cpp57
-rw-r--r--indra/newview/llnavigationbar.h37
-rw-r--r--indra/newview/llnearbychat.cpp25
-rw-r--r--indra/newview/llnearbychathandler.cpp7
-rw-r--r--indra/newview/llpanellandmarks.cpp22
-rw-r--r--indra/newview/llpanellandmarks.h2
-rw-r--r--indra/newview/llpanelme.cpp14
-rw-r--r--indra/newview/llpanelprofile.cpp16
-rw-r--r--indra/newview/llpanelprofile.h2
-rw-r--r--indra/newview/llparticipantlist.cpp4
-rw-r--r--indra/newview/llscreenchannel.cpp8
-rw-r--r--indra/newview/llspeakers.cpp17
-rw-r--r--indra/newview/llspeakers.h4
-rw-r--r--indra/newview/llvoiceclient.cpp26
-rw-r--r--indra/newview/llweb.cpp19
-rw-r--r--indra/newview/skins/default/xui/en/floater_preferences.xml2
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml15
-rw-r--r--indra/newview/skins/default/xui/en/panel_classifieds_list_item.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_people.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_pick_list_item.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_advanced.xml57
-rw-r--r--indra/newview/skins/default/xui/en/widgets/flat_list_view.xml10
31 files changed, 370 insertions, 192 deletions
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 585d42f66d..0fe236c056 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -321,7 +321,7 @@ public:
~LLWearableHoldingPattern();
bool pollCompletion();
- bool isDone();
+ bool isFetchCompleted();
bool isTimedOut();
typedef std::list<LLFoundData> found_list_t;
@@ -330,10 +330,12 @@ public:
LLInventoryModel::item_array_t mGestItems;
S32 mResolved;
LLTimer mWaitTime;
+ bool mFired;
};
LLWearableHoldingPattern::LLWearableHoldingPattern():
- mResolved(0)
+ mResolved(0),
+ mFired(false)
{
}
@@ -341,31 +343,34 @@ LLWearableHoldingPattern::~LLWearableHoldingPattern()
{
}
-bool LLWearableHoldingPattern::isDone()
+bool LLWearableHoldingPattern::isFetchCompleted()
{
- if (mResolved >= (S32)mFoundList.size())
- return true; // have everything we were waiting for
- else if (isTimedOut())
- {
- llwarns << "Exceeded max wait time, updating appearance based on what has arrived" << llendl;
- return true;
- }
- return false;
-
+ return (mResolved >= (S32)mFoundList.size()); // have everything we were waiting for?
}
bool LLWearableHoldingPattern::isTimedOut()
{
- static F32 max_wait_time = 15.0; // give up if wearable fetches haven't completed in max_wait_time seconds.
+ static F32 max_wait_time = 20.0; // give up if wearable fetches haven't completed in max_wait_time seconds.
return mWaitTime.getElapsedTimeF32() > max_wait_time;
}
bool LLWearableHoldingPattern::pollCompletion()
{
- bool done = isDone();
- llinfos << "polling, done status: " << done << " elapsed " << mWaitTime.getElapsedTimeF32() << llendl;
+ bool completed = isFetchCompleted();
+ bool timed_out = isTimedOut();
+ bool done = completed || timed_out;
+
+ llinfos << "polling, done status: " << completed << " timed out? " << timed_out << " elapsed " << mWaitTime.getElapsedTimeF32() << llendl;
+
if (done)
{
+ mFired = true;
+
+ if (timed_out)
+ {
+ llwarns << "Exceeded max wait time for wearables, updating appearance based on what has arrived" << llendl;
+ }
+
// Activate all gestures in this folder
if (mGestItems.count() > 0)
{
@@ -397,7 +402,11 @@ bool LLWearableHoldingPattern::pollCompletion()
LLAgentWearables::userUpdateAttachments(mObjItems);
}
- delete this;
+ if (completed)
+ {
+ // Only safe to delete if all wearable callbacks completed.
+ delete this;
+ }
}
return done;
}
@@ -432,7 +441,11 @@ static void removeDuplicateItems(LLInventoryModel::item_array_t& items)
static void onWearableAssetFetch(LLWearable* wearable, void* data)
{
LLWearableHoldingPattern* holder = (LLWearableHoldingPattern*)data;
-
+ if (holder->mFired)
+ {
+ llwarns << "called after holder fired" << llendl;
+ }
+
if(wearable)
{
for (LLWearableHoldingPattern::found_list_t::iterator iter = holder->mFoundList.begin();
diff --git a/indra/newview/llcallfloater.cpp b/indra/newview/llcallfloater.cpp
index 8cb240c7c2..bd4fae6ab6 100644
--- a/indra/newview/llcallfloater.cpp
+++ b/indra/newview/llcallfloater.cpp
@@ -678,7 +678,8 @@ void LLCallFloater::resetVoiceRemoveTimers()
void LLCallFloater::removeVoiceRemoveTimer(const LLUUID& voice_speaker_id)
{
- mSpeakerDelayRemover->unsetActionTimer(voice_speaker_id);
+ bool delete_it = true;
+ mSpeakerDelayRemover->unsetActionTimer(voice_speaker_id, delete_it);
}
bool LLCallFloater::validateSpeaker(const LLUUID& speaker_id)
diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index 1dc0e8c0a7..f046e08827 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -585,9 +585,16 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
bool irc_me = prefix == "/me " || prefix == "/me'";
// Delimiter after a name in header copy/past and in plain text mode
- std::string delimiter = (chat.mChatType != CHAT_TYPE_SHOUT && chat.mChatType != CHAT_TYPE_WHISPER)
- ? ": "
- : " ";
+ std::string delimiter = ": ";
+ std::string shout = LLTrans::getString("shout");
+ std::string whisper = LLTrans::getString("whisper");
+ if (chat.mChatType == CHAT_TYPE_SHOUT ||
+ chat.mChatType == CHAT_TYPE_WHISPER ||
+ chat.mText.compare(0, shout.length(), shout) == 0 ||
+ chat.mText.compare(0, whisper.length(), whisper) == 0)
+ {
+ delimiter = " ";
+ }
// Don't add any delimiter after name in irc styled messages
if (irc_me || chat.mChatStyle == CHAT_STYLE_IRC)
diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp
index a5b62439f4..90f6438980 100644
--- a/indra/newview/llfavoritesbar.cpp
+++ b/indra/newview/llfavoritesbar.cpp
@@ -34,7 +34,6 @@
#include "llfavoritesbar.h"
-#include "llbutton.h"
#include "llfloaterreg.h"
#include "llfocusmgr.h"
#include "llinventory.h"
@@ -48,7 +47,6 @@
#include "llclipboard.h"
#include "llinventoryclipboard.h"
#include "llinventorybridge.h"
-#include "llinventorymodel.h"
#include "llfloaterworldmap.h"
#include "lllandmarkactions.h"
#include "llnotificationsutil.h"
@@ -674,7 +672,14 @@ void LLFavoritesBarCtrl::updateButtons()
{
return;
}
-
+ if(mItems.empty())
+ {
+ mBarLabel->setVisible(TRUE);
+ }
+ else
+ {
+ mBarLabel->setVisible(FALSE);
+ }
const child_list_t* childs = getChildList();
child_list_const_iter_t child_it = childs->begin();
int first_changed_item_index = 0;
@@ -720,14 +725,22 @@ void LLFavoritesBarCtrl::updateButtons()
}
}
// we have to remove ChevronButton to make sure that the last item will be LandmarkButton to get the right aligning
+ // keep in mind that we are cutting all buttons in space between the last visible child of favbar and ChevronButton
if (mChevronButton->getParent() == this)
{
removeChild(mChevronButton);
}
int last_right_edge = 0;
+ //calculate new buttons offset
if (getChildList()->size() > 0)
{
- last_right_edge = getChildList()->back()->getRect().mRight;
+ //find last visible child to get the rightest button offset
+ child_list_const_reverse_iter_t last_visible_it = std::find_if(childs->rbegin(), childs->rend(),
+ std::mem_fun(&LLView::getVisible));
+ if(last_visible_it != childs->rend())
+ {
+ last_right_edge = (*last_visible_it)->getRect().mRight;
+ }
}
//last_right_edge is saving coordinates
LLButton* last_new_button = NULL;
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index ef444c8ba4..9d9fbacee3 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -571,6 +571,16 @@ void LLFloaterPreference::setHardwareDefaults()
{
LLFeatureManager::getInstance()->applyRecommendedSettings();
refreshEnabledGraphics();
+ LLTabContainer* tabcontainer = getChild<LLTabContainer>("pref core");
+ child_list_t::const_iterator iter = tabcontainer->getChildList()->begin();
+ child_list_t::const_iterator end = tabcontainer->getChildList()->end();
+ for ( ; iter != end; ++iter)
+ {
+ LLView* view = *iter;
+ LLPanelPreference* panel = dynamic_cast<LLPanelPreference*>(view);
+ if (panel)
+ panel->setHardwareDefaults();
+ }
}
//virtual
@@ -1525,3 +1535,93 @@ void LLPanelPreference::setControlFalse(const LLSD& user_data)
if (control)
control->set(LLSD(FALSE));
}
+
+static LLRegisterPanelClassWrapper<LLPanelPreferenceGraphics> t_pref_graph("panel_preference_graphics");
+
+BOOL LLPanelPreferenceGraphics::postBuild()
+{
+ return LLPanelPreference::postBuild();
+}
+void LLPanelPreferenceGraphics::draw()
+{
+ LLPanelPreference::draw();
+
+ LLButton* button_apply = findChild<LLButton>("Apply");
+
+ if(button_apply && button_apply->getVisible())
+ {
+ bool enable = hasDirtyChilds();
+
+ button_apply->setEnabled(enable);
+
+ }
+}
+bool LLPanelPreferenceGraphics::hasDirtyChilds()
+{
+ std::list<LLView*> view_stack;
+ view_stack.push_back(this);
+ while(!view_stack.empty())
+ {
+ // Process view on top of the stack
+ LLView* curview = view_stack.front();
+ view_stack.pop_front();
+
+ LLUICtrl* ctrl = dynamic_cast<LLUICtrl*>(curview);
+ if (ctrl)
+ {
+ if(ctrl->isDirty())
+ return true;
+ }
+ // Push children onto the end of the work stack
+ for (child_list_t::const_iterator iter = curview->getChildList()->begin();
+ iter != curview->getChildList()->end(); ++iter)
+ {
+ view_stack.push_back(*iter);
+ }
+ }
+ return false;
+}
+
+void LLPanelPreferenceGraphics::resetDirtyChilds()
+{
+ std::list<LLView*> view_stack;
+ view_stack.push_back(this);
+ while(!view_stack.empty())
+ {
+ // Process view on top of the stack
+ LLView* curview = view_stack.front();
+ view_stack.pop_front();
+
+ LLUICtrl* ctrl = dynamic_cast<LLUICtrl*>(curview);
+ if (ctrl)
+ {
+ ctrl->resetDirty();
+ }
+ // Push children onto the end of the work stack
+ for (child_list_t::const_iterator iter = curview->getChildList()->begin();
+ iter != curview->getChildList()->end(); ++iter)
+ {
+ view_stack.push_back(*iter);
+ }
+ }
+}
+void LLPanelPreferenceGraphics::apply()
+{
+ resetDirtyChilds();
+ LLPanelPreference::apply();
+}
+void LLPanelPreferenceGraphics::cancel()
+{
+ resetDirtyChilds();
+ LLPanelPreference::cancel();
+}
+void LLPanelPreferenceGraphics::saveSettings()
+{
+ resetDirtyChilds();
+ LLPanelPreference::saveSettings();
+}
+void LLPanelPreferenceGraphics::setHardwareDefaults()
+{
+ resetDirtyChilds();
+ LLPanelPreference::setHardwareDefaults();
+}
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index 8778d76a5a..0827c7c2b2 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -161,6 +161,7 @@ public:
virtual void apply();
virtual void cancel();
void setControlFalse(const LLSD& user_data);
+ virtual void setHardwareDefaults(){};
// This function squirrels away the current values of the controls so that
// cancel() can restore them.
@@ -177,4 +178,19 @@ private:
string_color_map_t mSavedColors;
};
+class LLPanelPreferenceGraphics : public LLPanelPreference
+{
+public:
+ BOOL postBuild();
+ void draw();
+ void apply();
+ void cancel();
+ void saveSettings();
+ void setHardwareDefaults();
+protected:
+ bool hasDirtyChilds();
+ void resetDirtyChilds();
+
+};
+
#endif // LL_LLPREFERENCEFLOATER_H
diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp
index b6e9fb3f6c..a0031f0193 100644
--- a/indra/newview/llfloatersnapshot.cpp
+++ b/indra/newview/llfloatersnapshot.cpp
@@ -2084,10 +2084,6 @@ void LLFloaterSnapshot::draw()
S32 offset_x = (getRect().getWidth() - previewp->getThumbnailWidth()) / 2 ;
S32 offset_y = thumbnail_rect.mBottom + (thumbnail_rect.getHeight() - previewp->getThumbnailHeight()) / 2 ;
- if (! gSavedSettings.getBOOL("AdvanceSnapshot"))
- {
- offset_y += getUIWinHeightShort() - getUIWinHeightLong();
- }
glMatrixMode(GL_MODELVIEW);
gl_draw_scaled_image(offset_x, offset_y,
diff --git a/indra/newview/llgroupactions.cpp b/indra/newview/llgroupactions.cpp
index 3653371d76..00e2365ffd 100644
--- a/indra/newview/llgroupactions.cpp
+++ b/indra/newview/llgroupactions.cpp
@@ -161,12 +161,17 @@ void LLGroupActions::join(const LLUUID& group_id)
S32 cost = gdatap->mMembershipFee;
LLSD args;
args["COST"] = llformat("%d", cost);
+ args["NAME"] = gdatap->mName;
LLSD payload;
payload["group_id"] = group_id;
if (can_afford_transaction(cost))
{
- LLNotificationsUtil::add("JoinGroupCanAfford", args, payload, onJoinGroup);
+ if(cost > 0)
+ LLNotificationsUtil::add("JoinGroupCanAfford", args, payload, onJoinGroup);
+ else
+ LLNotificationsUtil::add("JoinGroupNoCost", args, payload, onJoinGroup);
+
}
else
{
diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp
index 8c875c9b63..d579058c32 100644
--- a/indra/newview/llnamelistctrl.cpp
+++ b/indra/newview/llnamelistctrl.cpp
@@ -152,6 +152,7 @@ BOOL LLNameListCtrl::handleToolTip(S32 x, S32 y, MASK mask)
if (avatar_id.notNull())
{
// ...valid avatar id
+
LLScrollListCell* hit_cell = hit_item->getColumn(column_index);
if (hit_cell)
{
@@ -162,8 +163,8 @@ BOOL LLNameListCtrl::handleToolTip(S32 x, S32 y, MASK mask)
localRectToScreen(cell_rect, &sticky_rect);
// Spawn at right side of cell
- LLCoordGL pos( sticky_rect.mRight - 16, sticky_rect.mTop + (sticky_rect.getHeight()-16)/2 );
LLPointer<LLUIImage> icon = LLUI::getUIImage("Info_Small");
+ LLCoordGL pos( sticky_rect.mRight - 16, sticky_rect.mTop - (sticky_rect.getHeight() - icon->getHeight())/2 );
// Should we show a group or an avatar inspector?
bool is_group = hit_item->getValue()["is_group"].asBoolean();
diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp
index 59708fcfb5..46cab0d868 100644
--- a/indra/newview/llnavigationbar.cpp
+++ b/indra/newview/llnavigationbar.cpp
@@ -185,43 +185,46 @@ void LLTeleportHistoryMenuItem::onMouseLeave(S32 x, S32 y, MASK mask)
static LLDefaultChildRegistry::Register<LLPullButton> menu_button("pull_button");
-LLPullButton::LLPullButton(const LLPullButton::Params& params):
- LLButton(params)
- , mClickDraggingSignal(NULL)
+LLPullButton::LLPullButton(const LLPullButton::Params& params) :
+ LLButton(params)
{
setDirectionFromName(params.direction);
}
-boost::signals2::connection LLPullButton::setClickDraggingCallback( const commit_signal_t::slot_type& cb )
-{
- if (!mClickDraggingSignal) mClickDraggingSignal = new commit_signal_t();
- return mClickDraggingSignal->connect(cb);
+boost::signals2::connection LLPullButton::setClickDraggingCallback(const commit_signal_t::slot_type& cb)
+{
+ return mClickDraggingSignal.connect(cb);
}
/*virtual*/
void LLPullButton::onMouseLeave(S32 x, S32 y, MASK mask)
{
LLButton::onMouseLeave(x, y, mask);
-
- if(mMouseDownTimer.getStarted() )
+
+ if (mMouseDownTimer.getStarted()) //an user have done a mouse down, if the timer started. see LLButton::handleMouseDown for details
{
- const LLVector2 cursor_direction = LLVector2(F32(x),F32(y)) - mLastMouseDown;
- if( angle_between(mDraggingDirection, cursor_direction) < 0.5 * F_PI_BY_TWO)//call if angle < pi/4
- {
- if(mClickDraggingSignal)
- {
- (*mClickDraggingSignal)(this, LLSD());
- }
- }
+ const LLVector2 cursor_direction = LLVector2(F32(x), F32(y)) - mLastMouseDown;
+ /* For now cursor_direction points to the direction of mouse movement
+ * Need to decide whether should we fire a signal.
+ * We fire if angle between mDraggingDirection and cursor_direction is less that 45 degree
+ * Note:
+ * 0.5 * F_PI_BY_TWO equals to PI/4 radian that equals to angle of 45 degrees
+ */
+ if (angle_between(mDraggingDirection, cursor_direction) < 0.5 * F_PI_BY_TWO)//call if angle < pi/4
+ {
+ mClickDraggingSignal(this, LLSD());
+ }
}
}
/*virtual*/
BOOL LLPullButton::handleMouseDown(S32 x, S32 y, MASK mask)
+{
+ BOOL handled = LLButton::handleMouseDown(x, y, mask);
+ if (handled)
{
- BOOL handled = LLButton::handleMouseDown(x,y, mask);
- if(handled)
- {
+ //if mouse down was handled by button,
+ //capture mouse position to calculate the direction of mouse move after mouseLeave event
mLastMouseDown.set(F32(x), F32(y));
}
return handled;
@@ -230,27 +233,31 @@ BOOL LLPullButton::handleMouseDown(S32 x, S32 y, MASK mask)
/*virtual*/
BOOL LLPullButton::handleMouseUp(S32 x, S32 y, MASK mask)
{
+ // reset data to get ready for next circle
mLastMouseDown.clear();
return LLButton::handleMouseUp(x, y, mask);
}
-
+/**
+ * this function is setting up dragging direction vector.
+ * Last one is just unit vector. It points to direction of mouse drag that we need to handle
+ */
void LLPullButton::setDirectionFromName(const std::string& name)
{
if (name == "left")
{
- mDraggingDirection.set(F32(-1), F32(0));
+ mDraggingDirection.set(F32(-1), F32(0));
}
else if (name == "right")
{
- mDraggingDirection.set(F32(0), F32(1));
+ mDraggingDirection.set(F32(0), F32(1));
}
else if (name == "down")
{
- mDraggingDirection.set(F32(0), F32(-1));
+ mDraggingDirection.set(F32(0), F32(-1));
}
else if (name == "up")
{
- mDraggingDirection.set(F32(0), F32(1));
+ mDraggingDirection.set(F32(0), F32(1));
}
}
diff --git a/indra/newview/llnavigationbar.h b/indra/newview/llnavigationbar.h
index 9d0abc7a3a..b512f2a79c 100644
--- a/indra/newview/llnavigationbar.h
+++ b/indra/newview/llnavigationbar.h
@@ -44,46 +44,41 @@ class LLSearchComboBox;
/**
* This button is able to handle click-dragging mouse event.
* It has appropriated signal for this event.
- * Dragging direction can be set from xml by attribute called 'direction'
+ * Dragging direction can be set from xml attribute called 'direction'
*
* *TODO: move to llui?
*/
-class LLPullButton : public LLButton
+class LLPullButton: public LLButton
{
LOG_CLASS(LLPullButton);
-
+
public:
-
- struct Params : public LLInitParam::Block<Params, LLButton::Params>
+ struct Params: public LLInitParam::Block<Params, LLButton::Params>
{
- Optional<std::string> direction; // left, right, down, up
-
- Params()
- : direction("direction","down")
- {}
+ Optional<std::string> direction; // left, right, down, up
+
+ Params()
+ : direction("direction", "down")
+ {
+ }
};
/*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
-
+
/*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask);
-
+
/*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask);
- boost::signals2::connection setClickDraggingCallback( const commit_signal_t::slot_type& cb );
-
- /* virtual*/ ~LLPullButton()
- {
- delete mClickDraggingSignal;
- }
-
+ boost::signals2::connection setClickDraggingCallback(const commit_signal_t::slot_type& cb);
+
protected:
friend class LLUICtrlFactory;
// convert string name into direction vector
void setDirectionFromName(const std::string& name);
LLPullButton(const LLPullButton::Params& params);
-
- commit_signal_t* mClickDraggingSignal;
+
+ commit_signal_t mClickDraggingSignal;
LLVector2 mLastMouseDown;
LLVector2 mDraggingDirection;
};
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index 6de47fccd2..8fc11d3929 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -200,18 +200,16 @@ void LLNearbyChat::addMessage(const LLChat& chat,bool archive,const LLSD &args)
mMessageArchive.push_back(chat);
if(mMessageArchive.size()>200)
mMessageArchive.erase(mMessageArchive.begin());
+ }
- if (gSavedPerAccountSettings.getBOOL("LogChat"))
- {
- if (chat.mChatType != CHAT_TYPE_WHISPER && chat.mChatType != CHAT_TYPE_SHOUT)
- {
- LLLogChat::saveHistory("chat", chat.mFromName, chat.mFromID, chat.mText);
- }
- else
- {
- LLLogChat::saveHistory("chat", "", chat.mFromID, chat.mFromName + " " + chat.mText);
- }
- }
+ if (args["do_not_log"].asBoolean())
+ {
+ return;
+ }
+
+ if (gSavedPerAccountSettings.getBOOL("LogChat"))
+ {
+ LLLogChat::saveHistory("chat", chat.mFromName, chat.mFromID, chat.mText);
}
}
@@ -282,6 +280,9 @@ void LLNearbyChat::processChatHistoryStyleUpdate(const LLSD& newvalue)
void LLNearbyChat::loadHistory()
{
+ LLSD do_not_log;
+ do_not_log["do_not_log"] = true;
+
std::list<LLSD> history;
LLLogChat::loadAllHistory("chat", history);
@@ -302,7 +303,7 @@ void LLNearbyChat::loadHistory()
chat.mFromID = from_id;
chat.mText = msg[IM_TEXT].asString();
chat.mTimeStr = msg[IM_TIME].asString();
- addMessage(chat);
+ addMessage(chat, true, do_not_log);
it++;
}
diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp
index c08ca30bab..be48770567 100644
--- a/indra/newview/llnearbychathandler.cpp
+++ b/indra/newview/llnearbychathandler.cpp
@@ -274,6 +274,13 @@ void LLNearbyChatScreenChannel::showToastsBottom()
toast->setRect(toast_rect);
toast->setIsHidden(false);
toast->setVisible(TRUE);
+
+ if(!toast->hasFocus())
+ {
+ // Fixing Z-order of toasts (EXT-4862)
+ // Next toast will be positioned under this one.
+ gFloaterView->sendChildToBack(toast);
+ }
bottom = toast->getRect().mTop;
}
diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp
index 47feef496a..7c1b0f6234 100644
--- a/indra/newview/llpanellandmarks.cpp
+++ b/indra/newview/llpanellandmarks.cpp
@@ -171,8 +171,6 @@ BOOL LLLandmarksPanel::postBuild()
initLandmarksInventoryPanel();
initMyInventoryPanel();
initLibraryInventoryPanel();
- getChild<LLAccordionCtrlTab>("tab_favorites")->setDisplayChildren(true);
- getChild<LLAccordionCtrlTab>("tab_landmarks")->setDisplayChildren(true);
return TRUE;
}
@@ -462,7 +460,7 @@ void LLLandmarksPanel::initFavoritesInventoryPanel()
initLandmarksPanel(mFavoritesInventoryPanel);
mFavoritesInventoryPanel->getFilter()->setEmptyLookupMessage("FavoritesNoMatchingItems");
- initAccordion("tab_favorites", mFavoritesInventoryPanel);
+ initAccordion("tab_favorites", mFavoritesInventoryPanel, true);
}
void LLLandmarksPanel::initLandmarksInventoryPanel()
@@ -481,7 +479,7 @@ void LLLandmarksPanel::initLandmarksInventoryPanel()
// subscribe to have auto-rename functionality while creating New Folder
mLandmarksInventoryPanel->setSelectCallback(boost::bind(&LLInventoryPanel::onSelectionChange, mLandmarksInventoryPanel, _1, _2));
- initAccordion("tab_landmarks", mLandmarksInventoryPanel);
+ initAccordion("tab_landmarks", mLandmarksInventoryPanel, true);
}
void LLLandmarksPanel::initMyInventoryPanel()
@@ -490,7 +488,7 @@ void LLLandmarksPanel::initMyInventoryPanel()
initLandmarksPanel(mMyInventoryPanel);
- initAccordion("tab_inventory", mMyInventoryPanel);
+ initAccordion("tab_inventory", mMyInventoryPanel, false);
}
void LLLandmarksPanel::initLibraryInventoryPanel()
@@ -499,7 +497,15 @@ void LLLandmarksPanel::initLibraryInventoryPanel()
initLandmarksPanel(mLibraryInventoryPanel);
- initAccordion("tab_library", mLibraryInventoryPanel);
+ // We want to fetch only "Landmarks" category from the library.
+ const LLUUID &landmarks_cat = gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK, false, true);
+ if (landmarks_cat.notNull())
+ {
+ gInventory.startBackgroundFetch(landmarks_cat);
+ }
+
+ // Expanding "Library" tab for new users who have no landmarks in "My Inventory".
+ initAccordion("tab_library", mLibraryInventoryPanel, true);
}
void LLLandmarksPanel::initLandmarksPanel(LLPlacesInventoryPanel* inventory_list)
@@ -526,14 +532,14 @@ void LLLandmarksPanel::initLandmarksPanel(LLPlacesInventoryPanel* inventory_list
inventory_list->saveFolderState();
}
-void LLLandmarksPanel::initAccordion(const std::string& accordion_tab_name, LLPlacesInventoryPanel* inventory_list)
+void LLLandmarksPanel::initAccordion(const std::string& accordion_tab_name, LLPlacesInventoryPanel* inventory_list, bool expand_tab)
{
LLAccordionCtrlTab* accordion_tab = getChild<LLAccordionCtrlTab>(accordion_tab_name);
mAccordionTabs.push_back(accordion_tab);
accordion_tab->setDropDownStateChangedCallback(
boost::bind(&LLLandmarksPanel::onAccordionExpandedCollapsed, this, _2, inventory_list));
- accordion_tab->setDisplayChildren(false);
+ accordion_tab->setDisplayChildren(expand_tab);
}
void LLLandmarksPanel::onAccordionExpandedCollapsed(const LLSD& param, LLPlacesInventoryPanel* inventory_list)
diff --git a/indra/newview/llpanellandmarks.h b/indra/newview/llpanellandmarks.h
index 96b790844c..cbbd10ac26 100644
--- a/indra/newview/llpanellandmarks.h
+++ b/indra/newview/llpanellandmarks.h
@@ -110,7 +110,7 @@ private:
void initMyInventoryPanel();
void initLibraryInventoryPanel();
void initLandmarksPanel(LLPlacesInventoryPanel* inventory_list);
- void initAccordion(const std::string& accordion_tab_name, LLPlacesInventoryPanel* inventory_list);
+ void initAccordion(const std::string& accordion_tab_name, LLPlacesInventoryPanel* inventory_list, bool expand_tab);
void onAccordionExpandedCollapsed(const LLSD& param, LLPlacesInventoryPanel* inventory_list);
void deselectOtherThan(const LLPlacesInventoryPanel* inventory_list);
diff --git a/indra/newview/llpanelme.cpp b/indra/newview/llpanelme.cpp
index ea66ef7d2c..a68552a91e 100644
--- a/indra/newview/llpanelme.cpp
+++ b/indra/newview/llpanelme.cpp
@@ -69,6 +69,20 @@ BOOL LLPanelMe::postBuild()
void LLPanelMe::onOpen(const LLSD& key)
{
LLPanelProfile::onOpen(key);
+
+ if(key.isUndefined() || key.has("edit_my_profile"))
+ {
+ // Open Edit My Profile panel by default (through Side Tray -> My Profile) (EXT-4823)
+ buildEditPanel();
+ openPanel(mEditPanel, getAvatarId());
+ }
+ else if(mEditPanel)
+ {
+ // When opening Me Panel through Side Tray LLPanelMe::onOpen() is called twice.
+ // First time key can be undefined and second time - key may contain some data.
+ // Lets close Edit Panel if key does contain some data on second call.
+ closePanel(mEditPanel);
+ }
}
bool LLPanelMe::notifyChildren(const LLSD& info)
diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp
index c73ade53c8..b5d85dfd4b 100644
--- a/indra/newview/llpanelprofile.cpp
+++ b/indra/newview/llpanelprofile.cpp
@@ -197,11 +197,7 @@ void LLPanelProfile::togglePanel(LLPanel* panel, const LLSD& key)
}
else
{
- panel->setVisible(FALSE);
- if (panel->getParent() == this)
- {
- removeChild(panel);
- }
+ closePanel(panel);
getTabCtrl()->getCurrentPanel()->onOpen(getAvatarId());
}
@@ -248,6 +244,16 @@ void LLPanelProfile::openPanel(LLPanel* panel, const LLSD& params)
panel->setRect(new_rect);
}
+void LLPanelProfile::closePanel(LLPanel* panel)
+{
+ panel->setVisible(FALSE);
+
+ if (panel->getParent() == this)
+ {
+ removeChild(panel);
+ }
+}
+
S32 LLPanelProfile::notifyParent(const LLSD& info)
{
std::string action = info["action"];
diff --git a/indra/newview/llpanelprofile.h b/indra/newview/llpanelprofile.h
index bcf4bdd0ec..f1aa3f10f8 100644
--- a/indra/newview/llpanelprofile.h
+++ b/indra/newview/llpanelprofile.h
@@ -55,6 +55,8 @@ public:
virtual void openPanel(LLPanel* panel, const LLSD& params);
+ virtual void closePanel(LLPanel* panel);
+
S32 notifyParent(const LLSD& info);
protected:
diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp
index ad47e351ee..1c4004c37a 100644
--- a/indra/newview/llparticipantlist.cpp
+++ b/indra/newview/llparticipantlist.cpp
@@ -584,7 +584,7 @@ bool LLParticipantList::LLParticipantListMenu::enableContextMenuItem(const LLSD&
{
std::string item = userdata.asString();
if (item == "can_mute_text" || "can_block" == item || "can_share" == item || "can_im" == item
- || "can_pay" == item || "can_add" == item)
+ || "can_pay" == item)
{
return mUUIDs.front() != gAgentID;
}
@@ -619,7 +619,7 @@ bool LLParticipantList::LLParticipantListMenu::enableContextMenuItem(const LLSD&
for (;id != uuids_end; ++id)
{
- if ( LLAvatarActions::isFriend(*id) )
+ if ( *id == gAgentID || LLAvatarActions::isFriend(*id) )
{
result = false;
break;
diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp
index 8f36c0e88a..7c2e7e3319 100644
--- a/indra/newview/llscreenchannel.cpp
+++ b/indra/newview/llscreenchannel.cpp
@@ -533,9 +533,13 @@ void LLScreenChannel::showToastsBottom()
// HACK
// EXT-2653: it is necessary to prevent overlapping for secondary showed toasts
(*it).toast->setVisible(TRUE);
- // Show toast behind floaters. (EXT-3089)
- gFloaterView->sendChildToBack((*it).toast);
}
+ if(!(*it).toast->hasFocus())
+ {
+ // Fixing Z-order of toasts (EXT-4862)
+ // Next toast will be positioned under this one.
+ gFloaterView->sendChildToBack((*it).toast);
+ }
}
if(it != mToastList.rend())
diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp
index 6f9a1ccdbe..786fa24e65 100644
--- a/indra/newview/llspeakers.cpp
+++ b/indra/newview/llspeakers.cpp
@@ -205,7 +205,7 @@ void LLSpeakersDelayActionsStorage::setActionTimer(const LLUUID& speaker_id)
}
}
-void LLSpeakersDelayActionsStorage::unsetActionTimer(const LLUUID& speaker_id)
+void LLSpeakersDelayActionsStorage::unsetActionTimer(const LLUUID& speaker_id, bool delete_it)
{
if (mActionTimersMap.size() == 0) return;
@@ -213,7 +213,10 @@ void LLSpeakersDelayActionsStorage::unsetActionTimer(const LLUUID& speaker_id)
if (it_speaker != mActionTimersMap.end())
{
- delete it_speaker->second;
+ if (delete_it)
+ {
+ delete it_speaker->second;
+ }
mActionTimersMap.erase(it_speaker);
}
}
@@ -230,16 +233,15 @@ void LLSpeakersDelayActionsStorage::removeAllTimers()
bool LLSpeakersDelayActionsStorage::onTimerActionCallback(const LLUUID& speaker_id)
{
- unsetActionTimer(speaker_id);
+ bool delete_it = false; // we're *in* this timer, return true to delete it, don't manually delete it
+ unsetActionTimer(speaker_id, delete_it);
if (mActionCallback)
{
mActionCallback(speaker_id);
}
- // do not return true to avoid deleting of an timer twice:
- // in LLSpeakersDelayActionsStorage::unsetActionTimer() & LLEventTimer::updateClass()
- return false;
+ return true;
}
@@ -291,7 +293,8 @@ LLPointer<LLSpeaker> LLSpeakerMgr::setSpeaker(const LLUUID& id, const std::strin
}
}
- mSpeakerDelayRemover->unsetActionTimer(speakerp->mID);
+ bool delete_it = true;
+ mSpeakerDelayRemover->unsetActionTimer(speakerp->mID, delete_it);
return speakerp;
}
diff --git a/indra/newview/llspeakers.h b/indra/newview/llspeakers.h
index 63237204c8..ddc3632f07 100644
--- a/indra/newview/llspeakers.h
+++ b/indra/newview/llspeakers.h
@@ -176,11 +176,11 @@ public:
void setActionTimer(const LLUUID& speaker_id);
/**
- * Removes stored LLSpeakerActionTimer for passed speaker UUID from internal map and deletes it.
+ * Removes stored LLSpeakerActionTimer for passed speaker UUID from internal map and optionally deletes it.
*
* @see onTimerActionCallback()
*/
- void unsetActionTimer(const LLUUID& speaker_id);
+ void unsetActionTimer(const LLUUID& speaker_id, bool delete_it);
void removeAllTimers();
private:
diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp
index b6e7e73b9d..f3bfc2e86c 100644
--- a/indra/newview/llvoiceclient.cpp
+++ b/indra/newview/llvoiceclient.cpp
@@ -1107,16 +1107,17 @@ public:
* Sets internal voluem level for specified user.
*
* @param[in] speaker_id - LLUUID of user to store volume level for
- * @param[in] volume - internal volume level to be stored for user.
+ * @param[in] volume - external (vivox) volume level to be stored for user.
*/
- void storeSpeakerVolume(const LLUUID& speaker_id, S32 volume);
+ void storeSpeakerVolume(const LLUUID& speaker_id, F32 volume);
/**
- * Gets stored internal volume level for specified speaker.
+ * Gets stored external (vivox) volume level for specified speaker and
+ * transforms it into internal (viewer) level.
*
* If specified user is not found default level will be returned. It is equivalent of
* external level 0.5 from the 0.0..1.0 range.
- * Default internal level is calculated as: internal = 400 * external^2
+ * Internal level is calculated as: internal = 400 * external^2
* Maps 0.0 to 1.0 to internal values 0-400 with default 0.5 == 100
*
* @param[in] speaker_id - LLUUID of user to get his volume level
@@ -1133,7 +1134,7 @@ private:
void load();
void save();
- typedef std::map<LLUUID, S32> speaker_data_map_t;
+ typedef std::map<LLUUID, F32> speaker_data_map_t;
speaker_data_map_t mSpeakersData;
};
@@ -1149,7 +1150,7 @@ LLSpeakerVolumeStorage::~LLSpeakerVolumeStorage()
save();
}
-void LLSpeakerVolumeStorage::storeSpeakerVolume(const LLUUID& speaker_id, S32 volume)
+void LLSpeakerVolumeStorage::storeSpeakerVolume(const LLUUID& speaker_id, F32 volume)
{
mSpeakersData[speaker_id] = volume;
}
@@ -1163,7 +1164,10 @@ S32 LLSpeakerVolumeStorage::getSpeakerVolume(const LLUUID& speaker_id)
if (it != mSpeakersData.end())
{
- ret_val = it->second;
+ F32 f_val = it->second;
+ // volume can amplify by as much as 4x!
+ S32 ivol = (S32)(400.f * f_val * f_val);
+ ret_val = llclamp(ivol, 0, 400);
}
return ret_val;
}
@@ -1184,7 +1188,7 @@ void LLSpeakerVolumeStorage::load()
for (LLSD::map_const_iterator iter = settings_llsd.beginMap();
iter != settings_llsd.endMap(); ++iter)
{
- mSpeakersData.insert(std::make_pair(LLUUID(iter->first), (S32)iter->second.asInteger()));
+ mSpeakersData.insert(std::make_pair(LLUUID(iter->first), (F32)iter->second.asReal()));
}
}
@@ -6288,14 +6292,14 @@ void LLVoiceClient::setUserVolume(const LLUUID& id, F32 volume)
participantState *participant = findParticipantByID(id);
if (participant)
{
+ // store this volume setting for future sessions
+ LLSpeakerVolumeStorage::getInstance()->storeSpeakerVolume(id, volume);
+
// volume can amplify by as much as 4x!
S32 ivol = (S32)(400.f * volume * volume);
participant->mUserVolume = llclamp(ivol, 0, 400);
participant->mVolumeDirty = TRUE;
mAudioSession->mVolumeDirty = TRUE;
-
- // store this volume setting for future sessions
- LLSpeakerVolumeStorage::getInstance()->storeSpeakerVolume(id, participant->mUserVolume);
}
}
}
diff --git a/indra/newview/llweb.cpp b/indra/newview/llweb.cpp
index 7866f735c5..100ec0bb69 100644
--- a/indra/newview/llweb.cpp
+++ b/indra/newview/llweb.cpp
@@ -145,11 +145,20 @@ std::string LLWeb::expandURLSubstitutions(const std::string &url,
substitution["VERSION_PATCH"] = LLVersionInfo::getPatch();
substitution["VERSION_BUILD"] = LLVersionInfo::getBuild();
substitution["CHANNEL"] = LLVersionInfo::getChannel();
- substitution["LANGUAGE"] = LLUI::getLanguage();
substitution["GRID"] = LLViewerLogin::getInstance()->getGridLabel();
substitution["OS"] = LLAppViewer::instance()->getOSInfo().getOSStringSimple();
substitution["SESSION_ID"] = gAgent.getSessionID();
+ // work out the current language
+ std::string lang = LLUI::getLanguage();
+ if (lang == "en-us")
+ {
+ // *HACK: the correct fix is to change English.lproj/language.txt,
+ // but we're late in the release cycle and this is a less risky fix
+ lang = "en";
+ }
+ substitution["LANGUAGE"] = lang;
+
// find the region ID
LLUUID region_id;
LLViewerRegion *region = gAgent.getRegion();
@@ -159,14 +168,14 @@ std::string LLWeb::expandURLSubstitutions(const std::string &url,
}
substitution["REGION_ID"] = region_id;
- // find the parcel ID
- LLUUID parcel_id;
+ // find the parcel local ID
+ S32 parcel_id = 0;
LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
if (parcel)
{
- parcel_id = parcel->getID();
+ parcel_id = parcel->getLocalID();
}
- substitution["PARCEL_ID"] = parcel_id;
+ substitution["PARCEL_ID"] = llformat("%d", parcel_id);
// expand all of the substitution strings and escape the url
std::string expanded_url = url;
diff --git a/indra/newview/skins/default/xui/en/floater_preferences.xml b/indra/newview/skins/default/xui/en/floater_preferences.xml
index 15655a920e..05deca705a 100644
--- a/indra/newview/skins/default/xui/en/floater_preferences.xml
+++ b/indra/newview/skins/default/xui/en/floater_preferences.xml
@@ -56,7 +56,7 @@
help_topic="preferences_general_tab"
name="general" />
<panel
- class="panel_preference"
+ class="panel_preference_graphics"
filename="panel_preferences_graphics1.xml"
label="Graphics"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 5c37ef75b5..d16474873f 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -405,6 +405,19 @@ Do you wish to proceed?
<notification
icon="alertmodal.tga"
+ name="JoinGroupNoCost"
+ type="alertmodal">
+You are Joining group [NAME].
+Do you wish to proceed?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="Join"/>
+ </notification>
+
+
+ <notification
+ icon="alertmodal.tga"
name="JoinGroupCannotAfford"
type="alertmodal">
Joining this group costs L$[COST].
@@ -1519,7 +1532,7 @@ Your search terms were too short so no search was performed.
icon="alertmodal.tga"
name="CouldNotTeleportReason"
type="alertmodal">
-Could not teleport.
+Teleport failed.
[REASON]
</notification>
diff --git a/indra/newview/skins/default/xui/en/panel_classifieds_list_item.xml b/indra/newview/skins/default/xui/en/panel_classifieds_list_item.xml
index b881719e3a..0c1418fc2d 100644
--- a/indra/newview/skins/default/xui/en/panel_classifieds_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_classifieds_list_item.xml
@@ -64,6 +64,7 @@
layout="topleft"
left="103"
name="description"
+ textbox.mouse_opaque="false"
top_pad="0"
width="178"
word_wrap="true" />
diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml
index 3b5add33a8..447ac1b123 100644
--- a/indra/newview/skins/default/xui/en/panel_people.xml
+++ b/indra/newview/skins/default/xui/en/panel_people.xml
@@ -137,6 +137,7 @@ background_visible="true"
<avatar_list
allow_select="true"
follows="all"
+ height="235"
layout="topleft"
left="0"
multi_select="true"
@@ -152,6 +153,7 @@ background_visible="true"
<avatar_list
allow_select="true"
follows="all"
+ height="235"
layout="topleft"
left="0"
multi_select="true"
diff --git a/indra/newview/skins/default/xui/en/panel_pick_list_item.xml b/indra/newview/skins/default/xui/en/panel_pick_list_item.xml
index 023b1fc81d..e62c1278f9 100644
--- a/indra/newview/skins/default/xui/en/panel_pick_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_pick_list_item.xml
@@ -64,6 +64,7 @@
layout="topleft"
left="103"
name="picture_descr"
+ textbox.mouse_opaque="false"
top_pad="0"
width="178"
word_wrap="true" />
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml
index 4d14d46743..05a3771edf 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml
@@ -266,61 +266,4 @@ Automatic position for:
<button.commit_callback
function="Pref.VoiceSetMiddleMouse" />
</button>
- <text
- follows="left|top"
- type="string"
- length="1"
- height="13"
- layout="topleft"
- left="30"
- top_pad="8"
- name="AspectRatioLabel1"
- tool_tip="width / height"
- label_width="50"
- width="120">
- Aspect ratio
- </text>
- <combo_box
- allow_text_entry="true"
- height="23"
- follows="left|top"
- layout="topleft"
- left="80"
- max_chars="100"
- name="aspect_ratio"
- tool_tip="width / height"
- width="150">
- <combo_box.item
- enabled="true"
- label=" 4:3 (Standard CRT)"
- name="item1"
- value="1.333333" />
- <combo_box.item
- enabled="true"
- label=" 5:4 (1280x1024 LCD)"
- name="item2"
- value="1.25" />
- <combo_box.item
- enabled="true"
- label=" 8:5 (Widescreen)"
- name="item3"
- value="1.6" />
- <combo_box.item
- enabled="true"
- label=" 16:9 (Widescreen)"
- name="item4"
- value="1.7777777" />
- </combo_box>
- <check_box
- control_name="FullScreenAutoDetectAspectRatio"
- follows="left|top"
- height="25"
- label="Automatic"
- layout="topleft"
- left_pad="10"
- name="aspect_auto_detect"
- width="256">
- <check_box.commit_callback
- function="Pref.AutoDetectAspect" />
- </check_box>
</panel>
diff --git a/indra/newview/skins/default/xui/en/widgets/flat_list_view.xml b/indra/newview/skins/default/xui/en/widgets/flat_list_view.xml
index 888b4eaf7c..a71b293f31 100644
--- a/indra/newview/skins/default/xui/en/widgets/flat_list_view.xml
+++ b/indra/newview/skins/default/xui/en/widgets/flat_list_view.xml
@@ -5,4 +5,12 @@
item_pad="0"
keep_one_selected="true"
multi_select="false"
- opaque="true" /> \ No newline at end of file
+ opaque="true">
+ <flat_list_view.no_items_text
+ follows="all"
+ name="no_items_msg"
+ v_pad="10"
+ h_pad="10"
+ value="There are no any items in the list"
+ wrap="true" />
+</flat_list_view> \ No newline at end of file