summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rw-r--r--indra/llui/llchatentry.cpp32
-rw-r--r--indra/llui/llchatentry.h7
-rw-r--r--indra/llui/llscrollbar.cpp5
-rw-r--r--indra/llui/llscrollbar.h3
-rw-r--r--indra/llui/llscrollcontainer.cpp32
-rw-r--r--indra/llui/llscrollcontainer.h4
-rw-r--r--indra/llui/llscrolllistctrl.cpp27
-rw-r--r--indra/llui/llscrolllistctrl.h3
-rw-r--r--indra/llui/lltextbase.cpp22
-rw-r--r--indra/llui/lltextbase.h6
-rw-r--r--indra/llui/lltexteditor.cpp8
-rw-r--r--indra/llui/lltoolbar.cpp5
-rw-r--r--indra/newview/app_settings/settings_per_account.xml11
-rw-r--r--indra/newview/llchiclet.cpp1
-rwxr-xr-xindra/newview/llconversationview.cpp2
-rw-r--r--indra/newview/lldonotdisturbnotificationstorage.cpp4
-rw-r--r--indra/newview/llfloaterimcontainer.cpp20
-rw-r--r--indra/newview/llfloaterimcontainer.h1
-rw-r--r--indra/newview/llfloaterimnearbychat.cpp24
-rw-r--r--indra/newview/llfloaterimnearbychathandler.cpp21
-rw-r--r--indra/newview/llfloaterimsession.cpp2
-rw-r--r--indra/newview/llfloaterimsessiontab.cpp112
-rw-r--r--indra/newview/llfloaterimsessiontab.h20
-rw-r--r--indra/newview/llimview.cpp227
-rw-r--r--indra/newview/llnotificationstorage.cpp4
-rw-r--r--indra/newview/llpersistentnotificationstorage.cpp4
-rwxr-xr-xindra/newview/llvoavatar.cpp12
-rwxr-xr-xindra/newview/llvoavatar.h2
-rw-r--r--indra/newview/llvoicevivox.cpp69
-rw-r--r--indra/newview/llvoicevivox.h1
-rw-r--r--indra/newview/skins/default/xui/en/floater_im_session.xml439
31 files changed, 618 insertions, 512 deletions
diff --git a/indra/llui/llchatentry.cpp b/indra/llui/llchatentry.cpp
index 9e48dcde7e..6a1b48a08a 100644
--- a/indra/llui/llchatentry.cpp
+++ b/indra/llui/llchatentry.cpp
@@ -25,6 +25,7 @@
*/
#include "linden_common.h"
+#include "llscrollcontainer.h"
#include "llchatentry.h"
@@ -42,7 +43,9 @@ LLChatEntry::LLChatEntry(const Params& p)
mHasHistory(p.has_history),
mIsExpandable(p.is_expandable),
mExpandLinesCount(p.expand_lines_count),
- mPrevLinesCount(0)
+ mPrevLinesCount(0),
+ mSingleLineMode(false),
+ mPrevExpandedLineCount(S32_MAX)
{
// Initialize current history line iterator
mCurrentHistoryLine = mLineHistory.begin();
@@ -82,20 +85,23 @@ boost::signals2::connection LLChatEntry::setTextExpandedCallback(const commit_si
void LLChatEntry::expandText()
{
+ S32 line_count = mSingleLineMode ? 1 : mExpandLinesCount;
+
int visible_lines_count = llabs(getVisibleLines(true).first - getVisibleLines(true).second);
- bool can_expand = getLineCount() <= mExpandLinesCount;
+ bool can_changed = getLineCount() <= line_count || line_count < mPrevExpandedLineCount ;
+ mPrevExpandedLineCount = line_count;
// true if pasted text has more lines than expand height limit and expand limit is not reached yet
- bool text_pasted = (getLineCount() > mExpandLinesCount) && (visible_lines_count < mExpandLinesCount);
+ bool text_pasted = (getLineCount() > line_count) && (visible_lines_count < line_count);
- if (mIsExpandable && (can_expand || text_pasted) && getLineCount() != mPrevLinesCount)
+ if (mIsExpandable && (can_changed || text_pasted || mSingleLineMode) && getLineCount() != mPrevLinesCount)
{
int lines_height = 0;
if (text_pasted)
{
// text is pasted and now mLineInfoList.size() > mExpandLineCounts and mLineInfoList is not empty,
- // so lines_height is the sum of the last 'mExpandLinesCount' lines height
- lines_height = (mLineInfoList.end() - mExpandLinesCount)->mRect.mTop - mLineInfoList.back().mRect.mBottom;
+ // so lines_height is the sum of the last 'expanded_line_count' lines height
+ lines_height = (mLineInfoList.end() - line_count)->mRect.mTop - mLineInfoList.back().mRect.mBottom;
}
else
{
@@ -114,6 +120,8 @@ void LLChatEntry::expandText()
{
(*mTextExpandedSignal)(this, LLSD() );
}
+
+ needsReflow();
}
}
@@ -235,3 +243,15 @@ BOOL LLChatEntry::handleSpecialKey(const KEY key, const MASK mask)
return handled;
}
+
+void LLChatEntry::enableSingleLineMode(bool single_line_mode)
+{
+ if (mScroller)
+ {
+ mScroller->setSize(single_line_mode ? 0 : -1);
+ }
+
+ mSingleLineMode = single_line_mode;
+ mPrevLinesCount = -1;
+ setWordWrap(!single_line_mode);
+}
diff --git a/indra/llui/llchatentry.h b/indra/llui/llchatentry.h
index 49181c8d78..49c8d21450 100644
--- a/indra/llui/llchatentry.h
+++ b/indra/llui/llchatentry.h
@@ -65,6 +65,7 @@ public:
/*virtual*/ void onFocusReceived();
/*virtual*/ void onFocusLost();
+ void enableSingleLineMode(bool single_line_mode);
boost::signals2::connection setTextExpandedCallback(const commit_signal_t::slot_type& cb);
private:
@@ -95,9 +96,11 @@ private:
line_history_t mLineHistory; // line history storage
bool mHasHistory; // flag for enabled/disabled line history
bool mIsExpandable;
+ bool mSingleLineMode;
- int mExpandLinesCount;
- int mPrevLinesCount;
+ S32 mExpandLinesCount;
+ S32 mPrevLinesCount;
+ S32 mPrevExpandedLineCount;
};
#endif /* LLCHATENTRY_H_ */
diff --git a/indra/llui/llscrollbar.cpp b/indra/llui/llscrollbar.cpp
index 5d3bf7a670..13887cbe73 100644
--- a/indra/llui/llscrollbar.cpp
+++ b/indra/llui/llscrollbar.cpp
@@ -642,3 +642,8 @@ void LLScrollbar::onLineDownBtnPressed( const LLSD& data )
{
changeLine( mStepSize, TRUE );
}
+
+void LLScrollbar::setThickness(S32 thickness)
+{
+ mThickness = thickness < 0 ? LLUI::sSettingGroups["config"]->getS32("UIScrollbarSize") : thickness;
+}
diff --git a/indra/llui/llscrollbar.h b/indra/llui/llscrollbar.h
index ff74f753b9..21fd2d631e 100644
--- a/indra/llui/llscrollbar.h
+++ b/indra/llui/llscrollbar.h
@@ -124,6 +124,9 @@ public:
void onLineUpBtnPressed(const LLSD& data);
void onLineDownBtnPressed(const LLSD& data);
+
+ S32 getThickness() const { return mThickness; }
+ void setThickness(S32 thickness);
private:
void updateThumbRect();
diff --git a/indra/llui/llscrollcontainer.cpp b/indra/llui/llscrollcontainer.cpp
index 2fd187a526..cbcce0ece5 100644
--- a/indra/llui/llscrollcontainer.cpp
+++ b/indra/llui/llscrollcontainer.cpp
@@ -73,7 +73,8 @@ LLScrollContainer::Params::Params()
hide_scrollbar("hide_scrollbar"),
min_auto_scroll_rate("min_auto_scroll_rate", 100),
max_auto_scroll_rate("max_auto_scroll_rate", 1000),
- reserve_scroll_corner("reserve_scroll_corner", false)
+ reserve_scroll_corner("reserve_scroll_corner", false),
+ size("size", -1)
{}
@@ -88,9 +89,12 @@ LLScrollContainer::LLScrollContainer(const LLScrollContainer::Params& p)
mReserveScrollCorner(p.reserve_scroll_corner),
mMinAutoScrollRate(p.min_auto_scroll_rate),
mMaxAutoScrollRate(p.max_auto_scroll_rate),
- mScrolledView(NULL)
+ mScrolledView(NULL),
+ mSize(p.size)
{
- static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
+ static LLUICachedControl<S32> scrollbar_size_control ("UIScrollbarSize", 0);
+ S32 scrollbar_size = (mSize == -1 ? scrollbar_size_control : mSize);
+
LLRect border_rect( 0, getRect().getHeight(), getRect().getWidth(), 0 );
LLViewBorder::Params params;
params.name("scroll border");
@@ -276,7 +280,6 @@ BOOL LLScrollContainer::handleDragAndDrop(S32 x, S32 y, MASK mask,
EAcceptance* accept,
std::string& tooltip_msg)
{
- static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
// Scroll folder view if needed. Never accepts a drag or drop.
*accept = ACCEPT_NO;
BOOL handled = autoScroll(x, y);
@@ -292,7 +295,8 @@ BOOL LLScrollContainer::handleDragAndDrop(S32 x, S32 y, MASK mask,
bool LLScrollContainer::autoScroll(S32 x, S32 y)
{
- static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
+ static LLUICachedControl<S32> scrollbar_size_control ("UIScrollbarSize", 0);
+ S32 scrollbar_size = (mSize == -1 ? scrollbar_size_control : mSize);
bool scrolling = false;
if( mScrollbar[HORIZONTAL]->getVisible() || mScrollbar[VERTICAL]->getVisible() )
@@ -365,7 +369,9 @@ bool LLScrollContainer::autoScroll(S32 x, S32 y)
void LLScrollContainer::calcVisibleSize( S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const
{
const LLRect& doc_rect = getScrolledViewRect();
- static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
+ static LLUICachedControl<S32> scrollbar_size_control ("UIScrollbarSize", 0);
+ S32 scrollbar_size = (mSize == -1 ? scrollbar_size_control : mSize);
+
S32 doc_width = doc_rect.getWidth();
S32 doc_height = doc_rect.getHeight();
@@ -406,7 +412,9 @@ void LLScrollContainer::calcVisibleSize( S32 *visible_width, S32 *visible_height
void LLScrollContainer::draw()
{
- static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
+ static LLUICachedControl<S32> scrollbar_size_control ("UIScrollbarSize", 0);
+ S32 scrollbar_size = (mSize == -1 ? scrollbar_size_control : mSize);
+
if (mAutoScrolling)
{
// add acceleration to autoscroll
@@ -515,7 +523,9 @@ void LLScrollContainer::updateScroll()
{
return;
}
- static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
+ static LLUICachedControl<S32> scrollbar_size_control ("UIScrollbarSize", 0);
+ S32 scrollbar_size = (mSize == -1 ? scrollbar_size_control : mSize);
+
LLRect doc_rect = mScrolledView->getRect();
S32 doc_width = doc_rect.getWidth();
S32 doc_height = doc_rect.getHeight();
@@ -716,3 +726,9 @@ S32 LLScrollContainer::getBorderWidth() const
return 0;
}
+void LLScrollContainer::setSize(S32 size)
+{
+ mSize = size;
+ mScrollbar[VERTICAL]->setThickness(size);
+ mScrollbar[HORIZONTAL]->setThickness(size);
+}
diff --git a/indra/llui/llscrollcontainer.h b/indra/llui/llscrollcontainer.h
index d87c95b3d7..4eb43539b8 100644
--- a/indra/llui/llscrollcontainer.h
+++ b/indra/llui/llscrollcontainer.h
@@ -68,6 +68,7 @@ public:
max_auto_scroll_rate;
Optional<LLUIColor> bg_color;
Optional<LLScrollbar::callback_t> scroll_callback;
+ Optional<S32> size;
Params();
};
@@ -116,6 +117,9 @@ public:
bool autoScroll(S32 x, S32 y);
+ S32 getSize() const { return mSize; }
+ void setSize(S32 thickness);
+
protected:
LLView* mScrolledView;
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index 8b9fb47d5c..7f04c92b27 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -1801,6 +1801,9 @@ BOOL LLScrollListCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
// (N.B. callbacks don't take const refs as id is local scope)
bool is_group = (mContextMenuType == MENU_GROUP);
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+ registrar.add("Url.ShowProfile", boost::bind(&LLScrollListCtrl::showProfile, id, is_group));
+ registrar.add("Url.SendIM", boost::bind(&LLScrollListCtrl::sendIM, id));
+ registrar.add("Url.AddFriend", boost::bind(&LLScrollListCtrl::addFriend, id));
registrar.add("Url.Execute", boost::bind(&LLScrollListCtrl::showNameDetails, id, is_group));
registrar.add("Url.CopyLabel", boost::bind(&LLScrollListCtrl::copyNameToClipboard, id, is_group));
registrar.add("Url.CopyUrl", boost::bind(&LLScrollListCtrl::copySLURLToClipboard, id, is_group));
@@ -1821,11 +1824,33 @@ BOOL LLScrollListCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
return FALSE;
}
-void LLScrollListCtrl::showNameDetails(std::string id, bool is_group)
+void LLScrollListCtrl::showProfile(std::string id, bool is_group)
{
// show the resident's profile or the group profile
std::string sltype = is_group ? "group" : "agent";
std::string slurl = "secondlife:///app/" + sltype + "/" + id + "/about";
+ LLUrlAction::showProfile(slurl);
+}
+
+void LLScrollListCtrl::sendIM(std::string id)
+{
+ // send im to the resident
+ std::string slurl = "secondlife:///app/agent/" + id + "/about";
+ LLUrlAction::sendIM(slurl);
+}
+
+void LLScrollListCtrl::addFriend(std::string id)
+{
+ // add resident to friends list
+ std::string slurl = "secondlife:///app/agent/" + id + "/about";
+ LLUrlAction::addFriend(slurl);
+}
+
+void LLScrollListCtrl::showNameDetails(std::string id, bool is_group)
+{
+ // open the resident's details or the group details
+ std::string sltype = is_group ? "group" : "agent";
+ std::string slurl = "secondlife:///app/" + sltype + "/" + id + "/about";
LLUrlAction::clickAction(slurl);
}
diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h
index 38450b6313..8fa06cc499 100644
--- a/indra/llui/llscrolllistctrl.h
+++ b/indra/llui/llscrolllistctrl.h
@@ -430,6 +430,9 @@ private:
BOOL setSort(S32 column, BOOL ascending);
S32 getLinesPerPage();
+ static void showProfile(std::string id, bool is_group);
+ static void sendIM(std::string id);
+ static void addFriend(std::string id);
static void showNameDetails(std::string id, bool is_group);
static void copyNameToClipboard(std::string id, bool is_group);
static void copySLURLToClipboard(std::string id, bool is_group);
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 409f1c7f10..e70992129a 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -3201,7 +3201,23 @@ S32 LLNormalTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 lin
LLFontGL::EWordWrapStyle word_wrap_style = (line_offset == 0)
? LLFontGL::WORD_BOUNDARY_IF_POSSIBLE
: LLFontGL::ONLY_WORD_BOUNDARIES;
- S32 num_chars = mStyle->getFont()->maxDrawableChars(text.c_str() + segment_offset + mStart,
+
+
+ LLWString offsetString(text.c_str() + segment_offset + mStart);
+
+ if(getLength() < segment_offset + mStart)
+ {
+ llerrs << "getLength() < segment_offset + mStart\t getLength()\t" << getLength() << "\tsegment_offset:\t"
+ << segment_offset << "\tmStart:\t" << mStart << "\tsegments\t" << mEditor.mSegments.size() << "\tmax_chars\t" << max_chars << llendl;
+ }
+
+ if(offsetString.length() + 1 < max_chars)
+ {
+ llerrs << "offsetString.length() + 1 < max_chars\t max_chars:\t" << max_chars << "\toffsetString.length():\t" << offsetString.length()
+ << getLength() << "\tsegment_offset:\t" << segment_offset << "\tmStart:\t" << mStart << "\tsegments\t" << mEditor.mSegments.size() << llendl;
+ }
+
+ S32 num_chars = mStyle->getFont()->maxDrawableChars(offsetString.c_str(),
(F32)num_pixels,
max_chars,
word_wrap_style);
@@ -3474,3 +3490,7 @@ F32 LLImageTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 select
return 0.0;
}
+void LLTextBase::setWordWrap(bool wrap)
+{
+ mWordWrap = wrap;
+}
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index ad566a36d3..20a73387b5 100644
--- a/indra/llui/lltextbase.h
+++ b/indra/llui/lltextbase.h
@@ -41,6 +41,7 @@
#include <boost/signals2.hpp>
+class LLScrollContainer;
class LLContextMenu;
class LLUrlMatch;
@@ -434,6 +435,9 @@ public:
virtual void appendWidget(const LLInlineViewSegment::Params& params, const std::string& text, bool allow_undo);
boost::signals2::connection setURLClickedCallback(const commit_signal_t::slot_type& cb);
+ void setWordWrap(bool wrap);
+ LLScrollContainer* getScrollContainer() const { return mScroller; }
+
protected:
// helper structs
struct compare_bottom;
@@ -634,7 +638,7 @@ protected:
// support widgets
LLContextMenu* mPopupMenu;
LLView* mDocumentView;
- class LLScrollContainer* mScroller;
+ LLScrollContainer* mScroller;
// transient state
S32 mReflowIndex; // index at which to start reflow. S32_MAX indicates no reflow needed.
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index 3dc1b99edb..834f213097 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -956,12 +956,18 @@ S32 LLTextEditor::insert(S32 pos, const LLWString &wstr, bool group_with_next_op
S32 LLTextEditor::remove(S32 pos, S32 length, bool group_with_next_op)
{
S32 end_pos = getEditableIndex(pos + length, true);
+ BOOL removedChar = FALSE;
segment_vec_t segments_to_remove;
// store text segments
getSegmentsInRange(segments_to_remove, pos, pos + length, false);
+
+ if(pos <= end_pos)
+ {
+ removedChar = execute( new TextCmdRemove( pos, group_with_next_op, end_pos - pos, segments_to_remove ) );
+ }
- return execute( new TextCmdRemove( pos, group_with_next_op, end_pos - pos, segments_to_remove ) );
+ return removedChar;
}
S32 LLTextEditor::overwriteChar(S32 pos, llwchar wc)
diff --git a/indra/llui/lltoolbar.cpp b/indra/llui/lltoolbar.cpp
index f9703256c4..3d9f5cbbc2 100644
--- a/indra/llui/lltoolbar.cpp
+++ b/indra/llui/lltoolbar.cpp
@@ -1055,10 +1055,9 @@ BOOL LLToolBar::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
// Convert drag position into insert position and rank
if (!isReadOnly() && handled && !drop)
{
- LLInventoryItem* inv_item = (LLInventoryItem*)cargo_data;
- LLAssetType::EType type = inv_item->getType();
- if (type == LLAssetType::AT_WIDGET)
+ if (cargo_type == DAD_WIDGET)
{
+ LLInventoryItem* inv_item = (LLInventoryItem*)cargo_data;
LLCommandId dragged_command(inv_item->getUUID());
int orig_rank = getRankFromPosition(dragged_command);
mDragRank = getRankFromPosition(x, y);
diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml
index ada374f892..590f41283b 100644
--- a/indra/newview/app_settings/settings_per_account.xml
+++ b/indra/newview/app_settings/settings_per_account.xml
@@ -292,6 +292,17 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>NearbyChatIsNotCollapsed</key>
+ <map>
+ <key>Comment</key>
+ <string>Saving expanded/collapsed state of the nearby chat between sessions</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>ShowFavoritesOnLogin</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp
index f50a19761a..88884042d4 100644
--- a/indra/newview/llchiclet.cpp
+++ b/indra/newview/llchiclet.cpp
@@ -174,6 +174,7 @@ void LLNotificationChiclet::onMenuItemClicked(const LLSD& user_data)
if("close all" == action)
{
LLNotificationWellWindow::getInstance()->closeAll();
+ LLIMWellWindow::getInstance()->closeAll();
}
}
diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 956abcd586..b6c53e5e30 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -120,7 +120,7 @@ void LLConversationViewSession::setFlashState(bool flash_state)
void LLConversationViewSession::startFlashing()
{
- if (mFlashStateOn && !mFlashStarted)
+ if (isInVisibleChain() && mFlashStateOn && !mFlashStarted)
{
mFlashStarted = true;
mFlashTimer->startFlashing();
diff --git a/indra/newview/lldonotdisturbnotificationstorage.cpp b/indra/newview/lldonotdisturbnotificationstorage.cpp
index be20adeb8a..82affcf068 100644
--- a/indra/newview/lldonotdisturbnotificationstorage.cpp
+++ b/indra/newview/lldonotdisturbnotificationstorage.cpp
@@ -132,6 +132,8 @@ void LLDoNotDisturbNotificationStorage::loadNotifications()
{
LLFastTimer _(FTM_LOAD_DND_NOTIFICATIONS);
+ LL_INFOS("LLDoNotDisturbNotificationStorage") << "start loading notifications" << LL_ENDL;
+
LLSD input;
if (!readNotifications(input) ||input.isUndefined())
{
@@ -225,6 +227,8 @@ void LLDoNotDisturbNotificationStorage::loadNotifications()
//writes out empty .xml file (since LLCommunicationChannel::mHistory is empty)
saveNotifications();
+
+ LL_INFOS("LLDoNotDisturbNotificationStorage") << "finished loading notifications" << LL_ENDL;
}
void LLDoNotDisturbNotificationStorage::updateNotifications()
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 5e0cd8ef78..7296ec3ced 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -626,6 +626,12 @@ void LLFloaterIMContainer::setVisible(BOOL visible)
LLMultiFloater::setVisible(visible);
}
+void LLFloaterIMContainer::setVisibleAndFrontmost(BOOL take_focus, const LLSD& key)
+{
+ LLMultiFloater::setVisibleAndFrontmost(take_focus, key);
+ selectConversationPair(getSelectedSession(), false, take_focus);
+}
+
void LLFloaterIMContainer::updateResizeLimits()
{
LLMultiFloater::updateResizeLimits();
@@ -1331,7 +1337,10 @@ void LLFloaterIMContainer::showConversation(const LLUUID& session_id)
selectConversationPair(session_id, true);
LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::findConversation(session_id);
- session_floater->restoreFloater();
+ if (session_floater)
+ {
+ session_floater->restoreFloater();
+ }
}
void LLFloaterIMContainer::clearAllFlashStates()
@@ -1963,10 +1972,13 @@ bool LLFloaterIMContainer::selectNextorPreviousConversation(bool select_next, bo
void LLFloaterIMContainer::expandConversation()
{
- LLConversationViewSession* widget = dynamic_cast<LLConversationViewSession*>(get_ptr_in_map(mConversationsWidgets,getSelectedSession()));
- if (widget)
+ if(!mConversationsPane->isCollapsed())
{
- widget->setOpen(!widget->isOpen());
+ LLConversationViewSession* widget = dynamic_cast<LLConversationViewSession*>(get_ptr_in_map(mConversationsWidgets,getSelectedSession()));
+ if (widget)
+ {
+ widget->setOpen(!widget->isOpen());
+ }
}
}
diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h
index 2cbc1e99f9..52b672241f 100644
--- a/indra/newview/llfloaterimcontainer.h
+++ b/indra/newview/llfloaterimcontainer.h
@@ -60,6 +60,7 @@ public:
/*virtual*/ void onOpen(const LLSD& key);
/*virtual*/ void draw();
/*virtual*/ void setVisible(BOOL visible);
+ /*virtual*/ void setVisibleAndFrontmost(BOOL take_focus=TRUE, const LLSD& key = LLSD());
/*virtual*/ void updateResizeLimits();
void onCloseFloater(LLUUID& id);
diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp
index b287950c21..d86e1b3fd7 100644
--- a/indra/newview/llfloaterimnearbychat.cpp
+++ b/indra/newview/llfloaterimnearbychat.cpp
@@ -283,6 +283,11 @@ void LLFloaterIMNearbyChat::onTearOffClicked()
void LLFloaterIMNearbyChat::onOpen(const LLSD& key)
{
LLFloaterIMSessionTab::onOpen(key);
+ if(!isMessagePaneExpanded())
+ {
+ restoreFloater();
+ onCollapseToLine(this);
+ }
showTranslationCheckbox(LLTranslate::isTranslationConfigured());
}
@@ -322,11 +327,8 @@ void LLFloaterIMNearbyChat::onChatFontChange(LLFontGL* fontp)
void LLFloaterIMNearbyChat::show()
{
- if (isChatMultiTab())
- {
openFloater(getKey());
}
-}
bool LLFloaterIMNearbyChat::isChatVisible() const
{
@@ -480,11 +482,14 @@ void LLFloaterIMNearbyChat::onChatBoxKeystroke()
if (LLGestureMgr::instance().matchPrefix(utf8_trigger, &utf8_out_str))
{
std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size());
- mInputEditor->setText(utf8_trigger + rest_of_match); // keep original capitalization for user-entered part
+ if (!rest_of_match.empty())
+ {
+ mInputEditor->setText(utf8_trigger + rest_of_match); // keep original capitalization for user-entered part
- // Select to end of line, starting from the character
- // after the last one the user typed.
- mInputEditor->selectNext(rest_of_match, false);
+ // Select to end of line, starting from the character
+ // after the last one the user typed.
+ mInputEditor->selectNext(rest_of_match, false);
+ }
}
else if (matchChatTypeTrigger(utf8_trigger, &utf8_out_str))
{
@@ -741,15 +746,14 @@ void LLFloaterIMNearbyChat::startChat(const char* line)
{
if(!nearby_chat->isTornOff())
{
- nearby_chat->show();
+ LLFloaterIMContainer::getInstance()->selectConversation(LLUUID(NULL));
}
if(nearby_chat->isMinimized())
{
nearby_chat->setMinimized(false);
}
- nearby_chat->setVisible(TRUE);
+ nearby_chat->show();
nearby_chat->setFocus(TRUE);
- nearby_chat->mInputEditor->setFocus(TRUE);
if (line)
{
diff --git a/indra/newview/llfloaterimnearbychathandler.cpp b/indra/newview/llfloaterimnearbychathandler.cpp
index 7afcf288ce..9ce5e12897 100644
--- a/indra/newview/llfloaterimnearbychathandler.cpp
+++ b/indra/newview/llfloaterimnearbychathandler.cpp
@@ -559,9 +559,7 @@ void LLFloaterIMNearbyChatHandler::processChat(const LLChat& chat_msg,
LLFloaterIMContainer* im_box = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
- if(( nearby_chat->hasFocus()
- || im_box->hasFocus()
- || ( chat_msg.mSourceType == CHAT_SOURCE_AGENT
+ if(( ( chat_msg.mSourceType == CHAT_SOURCE_AGENT
&& gSavedSettings.getBOOL("UseChatBubbles") )
|| mChannel.isDead()
|| !mChannel.get()->getShowToasts() )
@@ -606,17 +604,20 @@ void LLFloaterIMNearbyChatHandler::processChat(const LLChat& chat_msg,
toast_msg = chat_msg.mText;
}
- //Don't show nearby toast, if conversation is visible but not focused
- LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::getConversation(LLUUID());
- if (session_floater && session_floater->isMessagePaneExpanded()
- && session_floater->isInVisibleChain() && !session_floater->isMinimized()
- && !(session_floater->getHost() && session_floater->getHost()->isMinimized()))
+ //Don't show nearby toast, if conversation is visible and selected
+ if ((nearby_chat->hasFocus()) ||
+ ((im_box->getSelectedSession().isNull() &&
+ ((LLFloater::isVisible(im_box) && !im_box->isMinimized() && im_box->isFrontmost())
+ || (LLFloater::isVisible(nearby_chat) && !nearby_chat->isMinimized() && nearby_chat->isFrontmost())))))
{
- return;
+ if(nearby_chat->isMessagePaneExpanded())
+ {
+ return;
+ }
}
//Will show toast when chat preference is set
- if((gSavedSettings.getString("NotificationNearbyChatOptions") == "toast") || !session_floater->isMessagePaneExpanded())
+ if((gSavedSettings.getString("NotificationNearbyChatOptions") == "toast") || !nearby_chat->isMessagePaneExpanded())
{
// Add a nearby chat toast.
LLUUID id;
diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp
index 0b1e47dbae..aaefd4aac7 100644
--- a/indra/newview/llfloaterimsession.cpp
+++ b/indra/newview/llfloaterimsession.cpp
@@ -618,6 +618,8 @@ void LLFloaterIMSession::onClose(bool app_quitting)
// Last change:
// EXT-3516 X Button should end IM session, _ button should hide
gIMMgr->leaveSession(mSessionID);
+ // *TODO: Study why we need to restore the floater before we close it.
+ // Might be because we want to save some state data in some clean open state.
LLFloaterIMSessionTab::restoreFloater();
// Clean up the conversation *after* the session has been ended
LLFloaterIMSessionTab::onClose(app_quitting);
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 5df1a382cd..ce6e639305 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -30,6 +30,7 @@
#include "llfloaterimsessiontab.h"
#include "llagent.h"
+#include "llagentcamera.h"
#include "llavataractions.h"
#include "llchatentry.h"
#include "llchathistory.h"
@@ -57,11 +58,14 @@ LLFloaterIMSessionTab::LLFloaterIMSessionTab(const LLSD& session_id)
, mSpeakingIndicator(NULL)
, mChatHistory(NULL)
, mInputEditor(NULL)
- , mInputEditorTopPad(0)
+ , mInputEditorPad(0)
, mRefreshTimer(new LLTimer())
, mIsHostAttached(false)
, mHasVisibleBeenInitialized(false)
, mIsParticipantListExpanded(true)
+ , mChatLayoutPanel(NULL)
+ , mInputPanels(NULL)
+ , mChatLayoutPanelHeight(0)
{
setAutoFocus(FALSE);
mSession = LLIMModel::getInstance()->findIMSession(mSessionID);
@@ -125,8 +129,18 @@ void LLFloaterIMSessionTab::setVisible(BOOL visible)
if(visible && !mHasVisibleBeenInitialized)
{
mHasVisibleBeenInitialized = true;
- LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container")->setVisible(true);
+ if(!gAgentCamera.cameraMouselook())
+ {
+ LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container")->setVisible(true);
+ }
LLFloaterIMSessionTab::addToHost(mSessionID);
+ LLFloaterIMSessionTab* conversp = LLFloaterIMSessionTab::getConversation(mSessionID);
+
+ if (conversp && conversp->isNearbyChat() && gSavedPerAccountSettings.getBOOL("NearbyChatIsNotCollapsed"))
+ {
+ onCollapseToLine(this);
+ }
+ mInputButtonPanel->setVisible(isTornOff());
}
LLTransientDockableFloater::setVisible(visible);
@@ -190,12 +204,29 @@ void LLFloaterIMSessionTab::addToHost(const LLUUID& session_id)
}
}
+void LLFloaterIMSessionTab::assignResizeLimits()
+{
+ bool is_participants_pane_collapsed = mParticipantListPanel->isCollapsed();
+
+ // disable a layoutstack's functionality when participant list panel is collapsed
+ mRightPartPanel->setIgnoreReshape(is_participants_pane_collapsed);
+
+ S32 participants_pane_target_width = is_participants_pane_collapsed?
+ 0 : (mParticipantListPanel->getRect().getWidth() + LLPANEL_BORDER_WIDTH);
+
+ S32 new_min_width = participants_pane_target_width + mRightPartPanel->getExpandedMinDim() + mFloaterExtraWidth;
+
+ setResizeLimits(new_min_width, getMinHeight());
+
+ this->mParticipantListAndHistoryStack->updateLayout();
+}
+
BOOL LLFloaterIMSessionTab::postBuild()
{
BOOL result;
mBodyStack = getChild<LLLayoutStack>("main_stack");
-
+ mParticipantListAndHistoryStack = getChild<LLLayoutStack>("im_panels");
mCloseBtn = getChild<LLButton>("close_btn");
mCloseBtn->setCommitCallback(boost::bind(&LLFloater::onClickClose, this));
@@ -212,6 +243,8 @@ BOOL LLFloaterIMSessionTab::postBuild()
mGearBtn = getChild<LLButton>("gear_btn");
mParticipantListPanel = getChild<LLLayoutPanel>("speakers_list_panel");
+ mRightPartPanel = getChild<LLLayoutPanel>("right_part_holder");
+
mToolbarPanel = getChild<LLLayoutPanel>("toolbar_panel");
mContentPanel = getChild<LLLayoutPanel>("body_panel");
mInputButtonPanel = getChild<LLLayoutPanel>("input_button_layout_panel");
@@ -232,12 +265,17 @@ BOOL LLFloaterIMSessionTab::postBuild()
mChatHistory = getChild<LLChatHistory>("chat_history");
mInputEditor = getChild<LLChatEntry>("chat_editor");
- mInputEditor->setTextExpandedCallback(boost::bind(&LLFloaterIMSessionTab::reshapeChatHistory, this));
+
+ mChatLayoutPanel = getChild<LLLayoutPanel>("chat_layout_panel");
+ mInputPanels = getChild<LLLayoutStack>("input_panels");
+
+ mInputEditor->setTextExpandedCallback(boost::bind(&LLFloaterIMSessionTab::reshapeChatLayoutPanel, this));
mInputEditor->setCommitOnFocusLost( FALSE );
mInputEditor->setPassDelete(TRUE);
mInputEditor->setFont(LLViewerChat::getChatFont());
- mInputEditorTopPad = mChatHistory->getRect().mBottom - mInputEditor->getRect().mTop;
+ mChatLayoutPanelHeight = mChatLayoutPanel->getRect().getHeight();
+ mInputEditorPad = mChatLayoutPanelHeight - mInputEditor->getRect().getHeight();
setOpenPositioning(LLFloaterEnums::POSITIONING_RELATIVE);
@@ -288,6 +326,15 @@ BOOL LLFloaterIMSessionTab::postBuild()
LLFloaterIMSessionTab::onSlide(this);
}
+ // The resize limits for LLFloaterIMSessionTab should be updated, based on current values of width of conversation and message panels
+ mParticipantListPanel->getResizeBar()->setResizeListener(boost::bind(&LLFloaterIMSessionTab::assignResizeLimits, this));
+ mFloaterExtraWidth =
+ getRect().getWidth()
+ - mParticipantListAndHistoryStack->getRect().getWidth()
+ - (mParticipantListPanel->isCollapsed()? 0 : LLPANEL_BORDER_WIDTH);
+
+ assignResizeLimits();
+
return result;
}
@@ -319,7 +366,7 @@ void LLFloaterIMSessionTab::draw()
// Restart the refresh timer
mRefreshTimer->setTimerExpirySec(REFRESH_INTERVAL);
}
-
+
LLTransientDockableFloater::draw();
}
@@ -660,12 +707,13 @@ void LLFloaterIMSessionTab::updateHeaderAndToolbar()
&& mIsParticipantListExpanded
&& !mIsP2PChat;
- mParticipantListPanel->setVisible(is_participant_list_visible);
-
+ mParticipantListAndHistoryStack->collapsePanel(mParticipantListPanel, !is_participant_list_visible);
+ mParticipantListPanel->setVisible(is_participant_list_visible);
// Display collapse image (<<) if the floater is hosted
// or if it is torn off but has an open control panel.
bool is_expanded = is_not_torn_off || is_participant_list_visible;
+
mExpandCollapseBtn->setImageOverlay(getString(is_expanded ? "collapse_icon" : "expand_icon"));
mExpandCollapseBtn->setToolTip(
is_not_torn_off?
@@ -703,15 +751,9 @@ void LLFloaterIMSessionTab::forceReshape()
}
-void LLFloaterIMSessionTab::reshapeChatHistory()
+void LLFloaterIMSessionTab::reshapeChatLayoutPanel()
{
- LLRect chat_rect = mChatHistory->getRect();
- LLRect input_rect = mInputEditor->getRect();
-
- int delta_height = chat_rect.mBottom - (input_rect.mTop + mInputEditorTopPad);
-
- chat_rect.setLeftTopAndSize(chat_rect.mLeft, chat_rect.mTop, chat_rect.getWidth(), chat_rect.getHeight() + delta_height);
- mChatHistory->setShape(chat_rect);
+ mChatLayoutPanel->reshape(mChatLayoutPanel->getRect().getWidth(), mInputEditor->getRect().getHeight() + mInputEditorPad, FALSE);
}
void LLFloaterIMSessionTab::showTranslationCheckbox(BOOL show)
@@ -786,15 +828,19 @@ void LLFloaterIMSessionTab::onSlide(LLFloaterIMSessionTab* self)
{
if (!self->mIsP2PChat)
{
- bool expand = !self->mParticipantListPanel->getVisible();
-
- // Expand/collapse the IM control panel
- self->mParticipantListPanel->setVisible(expand);
- gSavedSettings.setBOOL("IMShowControlPanel", expand);
- self->mIsParticipantListExpanded = expand;
- self->mExpandCollapseBtn->setImageOverlay(self->getString(expand ? "collapse_icon" : "expand_icon"));
+ // The state must toggle the collapsed state of the panel
+ bool should_be_expanded = self->mParticipantListPanel->isCollapsed();
+
+ // Update the expand/collapse flag of the participant list panel and save it
+ gSavedSettings.setBOOL("IMShowControlPanel", should_be_expanded);
+ self->mIsParticipantListExpanded = should_be_expanded;
+
+ // Refresh for immediate feedback
+ self->refreshConversation();
}
}
+
+ self->assignResizeLimits();
}
void LLFloaterIMSessionTab::onCollapseToLine(LLFloaterIMSessionTab* self)
@@ -806,6 +852,7 @@ void LLFloaterIMSessionTab::onCollapseToLine(LLFloaterIMSessionTab* self)
self->mExpandCollapseLineBtn->setImageOverlay(self->getString(expand ? "collapseline_icon" : "expandline_icon"));
self->mContentPanel->setVisible(!expand);
self->mToolbarPanel->setVisible(!expand);
+ self->mInputEditor->enableSingleLineMode(expand);
self->reshapeFloater(expand);
self->setMessagePaneExpanded(!expand);
}
@@ -818,20 +865,20 @@ void LLFloaterIMSessionTab::reshapeFloater(bool collapse)
if(collapse)
{
mFloaterHeight = floater_rect.getHeight();
- S32 height = mContentPanel->getRect().getHeight() + mToolbarPanel->getRect().getHeight();
+ S32 height = mContentPanel->getRect().getHeight() + mToolbarPanel->getRect().getHeight()
+ + mChatLayoutPanel->getRect().getHeight() - mChatLayoutPanelHeight + 2;
floater_rect.mTop -= height;
- enableResizeCtrls(true, true, false);
}
else
{
floater_rect.mTop = floater_rect.mBottom + mFloaterHeight;
- enableResizeCtrls(true, true, true);
-
}
+ enableResizeCtrls(true, true, !collapse);
+
+ saveCollapsedState();
setShape(floater_rect, true);
mBodyStack->updateLayout();
-
}
void LLFloaterIMSessionTab::restoreFloater()
@@ -850,6 +897,7 @@ void LLFloaterIMSessionTab::restoreFloater()
mBodyStack->updateLayout();
mExpandCollapseLineBtn->setImageOverlay(getString("expandline_icon"));
setMessagePaneExpanded(true);
+ saveCollapsedState();
enableResizeCtrls(true, true, true);
}
}
@@ -1025,6 +1073,14 @@ LLConversationItem* LLFloaterIMSessionTab::getCurSelectedViewModelItem()
return conversationItem;
}
+void LLFloaterIMSessionTab::saveCollapsedState()
+{
+ LLFloaterIMSessionTab* conversp = LLFloaterIMSessionTab::getConversation(mSessionID);
+ if(conversp->isNearbyChat())
+ {
+ gSavedPerAccountSettings.setBOOL("NearbyChatIsNotCollapsed", isMessagePaneExpanded());
+ }
+}
BOOL LLFloaterIMSessionTab::handleKeyHere(KEY key, MASK mask )
{
if(mask == MASK_ALT)
diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h
index f22e2b5744..302d5a8066 100644
--- a/indra/newview/llfloaterimsessiontab.h
+++ b/indra/newview/llfloaterimsessiontab.h
@@ -101,6 +101,7 @@ public:
bool isMessagePaneExpanded(){return mMessagePaneExpanded;}
void setMessagePaneExpanded(bool expanded){mMessagePaneExpanded = expanded;}
void restoreFloater();
+ void saveCollapsedState();
protected:
@@ -140,6 +141,9 @@ protected:
void appendMessage(const LLChat& chat, const LLSD &args = 0);
std::string appendTime();
+ void assignResizeLimits();
+
+ S32 mFloaterExtraWidth;
bool mIsNearbyChat;
bool mIsP2PChat;
@@ -155,7 +159,9 @@ protected:
LLUUID mSessionID;
LLLayoutStack* mBodyStack;
+ LLLayoutStack* mParticipantListAndHistoryStack;
LLLayoutPanel* mParticipantListPanel; // add the widgets to that see mConversationsListPanel
+ LLLayoutPanel* mRightPartPanel;
LLLayoutPanel* mContentPanel;
LLLayoutPanel* mToolbarPanel;
LLLayoutPanel* mInputButtonPanel;
@@ -168,17 +174,15 @@ protected:
LLOutputMonitorCtrl* mSpeakingIndicator;
LLChatHistory* mChatHistory;
LLChatEntry* mInputEditor;
- int mInputEditorTopPad; // padding between input field and chat history
-
+ LLLayoutPanel * mChatLayoutPanel;
+ LLLayoutStack * mInputPanels;
+
LLButton* mExpandCollapseLineBtn;
LLButton* mExpandCollapseBtn;
LLButton* mTearOffBtn;
LLButton* mCloseBtn;
LLButton* mGearBtn;
- S32 mFloaterHeight;
-
-
private:
// Handling selection and contextual menu
void doToSelected(const LLSD& userdata);
@@ -195,13 +199,17 @@ private:
* and avoid overlapping, since input chat field can be vertically expanded.
* Implementation: chat history bottom "follows" top+top_pad of input chat field
*/
- void reshapeChatHistory();
+ void reshapeChatLayoutPanel();
bool checkIfTornOff();
bool mIsHostAttached;
bool mHasVisibleBeenInitialized;
LLTimer* mRefreshTimer; ///< Defines the rate at which refresh() is called.
+
+ S32 mInputEditorPad;
+ S32 mChatLayoutPanelHeight;
+ S32 mFloaterHeight;
};
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index b379939cfa..425f9d67a2 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -160,163 +160,156 @@ static void on_avatar_name_cache_toast(const LLUUID& agent_id,
void on_new_message(const LLSD& msg)
{
- std::string action;
+ std::string user_preferences;
LLUUID participant_id = msg["from_id"].asUUID();
LLUUID session_id = msg["session_id"].asUUID();
LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(session_id);
- // determine action for this session
+ // do not show notification which goes from agent
+ if (gAgent.getID() == participant_id)
+ {
+ return;
+ }
+
+ // determine state of conversations floater
+ enum {CLOSED, NOT_ON_TOP, ON_TOP, ON_TOP_AND_ITEM_IS_SELECTED} conversations_floater_status;
+
+ conversations_floater_status = ON_TOP;
+
+ LLFloaterIMContainer* im_box = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
+ LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::getConversation(session_id);
+
+ if (!LLFloater::isVisible(im_box) || im_box->isMinimized())
+ {
+ conversations_floater_status = CLOSED;
+ }
+ else if (!session_floater || !LLFloater::isVisible(session_floater)
+ || session_floater->isMinimized() || !session_floater->hasFocus())
+ {
+ conversations_floater_status = NOT_ON_TOP;
+ }
+ else if (session_floater->hasFocus())
+ {
+ conversations_floater_status = ON_TOP;
+ }
+ else if((session_floater->hasFocus()) && (im_box->getSelectedSession() == session_id))
+ {
+ conversations_floater_status = ON_TOP_AND_ITEM_IS_SELECTED;
+ }
+ // determine user prefs for this session
if (session_id.isNull())
{
- action = gSavedSettings.getString("NotificationNearbyChatOptions");
+ user_preferences = gSavedSettings.getString("NotificationNearbyChatOptions");
}
else if(session->isP2PSessionType())
{
if (LLAvatarTracker::instance().isBuddy(participant_id))
{
- action = gSavedSettings.getString("NotificationFriendIMOptions");
+ user_preferences = gSavedSettings.getString("NotificationFriendIMOptions");
}
else
{
- action = gSavedSettings.getString("NotificationNonFriendIMOptions");
+ user_preferences = gSavedSettings.getString("NotificationNonFriendIMOptions");
}
}
else if(session->isAdHocSessionType())
{
- action = gSavedSettings.getString("NotificationConferenceIMOptions");
+ user_preferences = gSavedSettings.getString("NotificationConferenceIMOptions");
}
else if(session->isGroupSessionType())
{
- action = gSavedSettings.getString("NotificationGroupChatOptions");
+ user_preferences = gSavedSettings.getString("NotificationGroupChatOptions");
}
- // do not show notification which goes from agent
- if (gAgent.getID() == participant_id)
- {
- return;
- }
+ // actions:
- // execution of the action
-
- LLFloaterIMContainer* im_box = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
- LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::getConversation(session_id);
-
- if (im_box->isFrontmost() && im_box->getSelectedSession() == session_id
- && !(session_floater->getHost() ? im_box->isMinimized() : session_floater->isMinimized()))
- {
- return;
- }
-
- //session floater not focused (visible or not)
- bool session_floater_not_focused = session_floater && !session_floater->hasFocus();
-
- //conv. floater is closed
- bool conversation_floater_is_closed =
- !( im_box
- && im_box->isInVisibleChain()
- && !im_box->isMinimized());
-
- //conversation floater not focused (visible or not)
- bool conversation_floater_not_focused =
- conversation_floater_is_closed || !im_box->hasFocus();
- // sess. floater is open
- bool session_floater_is_open =
- session_floater
- && session_floater->isInVisibleChain()
- && !session_floater->isMinimized()
- && !(session_floater->getHost() && session_floater->getHost()->isMinimized());
-
- bool conversation_floater_collapsed = !session_floater->isMessagePaneExpanded();
- if (("toast" == action && !session_floater_is_open) || conversation_floater_collapsed)
+ // 0. nothing - exit
+ if (("none" == user_preferences ||
+ ON_TOP_AND_ITEM_IS_SELECTED == conversations_floater_status)
+ && session_floater->isMessagePaneExpanded())
{
- //User is not focused on conversation containing the message
- if(session_floater_not_focused || conversation_floater_collapsed)
- {
- if(!LLMuteList::getInstance()->isMuted(participant_id))
- {
- im_box->flashConversationItemWidget(session_id, true);
- }
- //The conversation floater isn't focused/open
- if(conversation_floater_not_focused || conversation_floater_collapsed)
- {
- if(!LLMuteList::getInstance()->isMuted(participant_id)
- && !gAgent.isDoNotDisturb())
- {
- gToolBarView->flashCommand(LLCommandId("chat"), true);
- }
-
- //Show IM toasts (upper right toasts)
- // Skip toasting for system messages and for nearby chat
- if(session_id.notNull() && participant_id.notNull())
- {
- LLAvatarNameCache::get(participant_id, boost::bind(&on_avatar_name_cache_toast, _1, _2, msg));
- }
- }
- }
+ return;
}
- else if ("flash" == action)
+ // 1. open floater and [optional] surface it
+ if ("openconversations" == user_preferences &&
+ (CLOSED == conversations_floater_status
+ || NOT_ON_TOP == conversations_floater_status))
{
- if (!gAgent.isDoNotDisturb())
- {
- im_box->flashConversationItemWidget(session_id, true);
- if(conversation_floater_not_focused)
- {
- //User is not focused on conversation containing the message
- gToolBarView->flashCommand(LLCommandId("chat"), true);
- }
- }
- else if(session_id.notNull() && participant_id.notNull())
- {
- //If a DND message, allow notification to be stored so upon DND exit
- //useMostItrusiveIMNotification will be called to notify user a message exists
- LLAvatarNameCache::get(participant_id, boost::bind(&on_avatar_name_cache_toast, _1, _2, msg));
- }
- }
-
- else if("openconversations" == action)
- {
- //User is not focused on conversation containing the message
- if(session_floater_not_focused)
+ if(!gAgent.isDoNotDisturb())
{
- //Flash line item
- im_box->flashConversationItemWidget(session_id, true);
-
- if(!gAgent.isDoNotDisturb())
- {
- //Surface conversations floater
- LLFloaterReg::showInstance("im_container");
- im_box->collapseMessagesPane(false);
- if (session_floater)
+ // Open conversations floater
+ LLFloaterReg::showInstance("im_container");
+ im_box->collapseMessagesPane(false);
+ if (session_floater)
+ {
+ if (session_floater->getHost())
{
- if (session_floater->getHost())
+ if (NULL != im_box && im_box->isMinimized())
{
- if (NULL != im_box && im_box->isMinimized())
- {
- LLFloater::onClickMinimize(im_box);
- }
+ LLFloater::onClickMinimize(im_box);
}
- else
+ }
+ else
+ {
+ if (session_floater->isMinimized())
{
- if (session_floater->isMinimized())
- {
- LLFloater::onClickMinimize(session_floater);
- }
+ LLFloater::onClickMinimize(session_floater);
}
}
}
-
- //If in DND mode, allow notification to be stored so upon DND exit
+ }
+ else
+ {
+ //If in DND mode, allow notification to be stored so upon DND exit
//useMostItrusiveIMNotification will be called to notify user a message exists
- if(session_id.notNull()
- && participant_id.notNull()
- && gAgent.isDoNotDisturb()
- && !session_floater_is_open)
+ if(session_id.notNull()
+ && participant_id.notNull()
+ && !session_floater->isShown())
{
LLAvatarNameCache::get(participant_id, boost::bind(&on_avatar_name_cache_toast, _1, _2, msg));
- }
- }
+ }
+ }
+ }
+
+ // 2. Flash line item
+ if ("openconversations" == user_preferences
+ || ON_TOP == conversations_floater_status
+ || ("toast" == user_preferences && ON_TOP != conversations_floater_status)
+ || ("flash" == user_preferences && CLOSED == conversations_floater_status))
+ {
+ if(!LLMuteList::getInstance()->isMuted(participant_id))
+ {
+ im_box->flashConversationItemWidget(session_id, true);
+ }
+ }
+
+ // 3. Flash FUI button
+ if (("toast" == user_preferences || "flash" == user_preferences) &&
+ (CLOSED == conversations_floater_status
+ || NOT_ON_TOP == conversations_floater_status))
+ {
+ if(!LLMuteList::getInstance()->isMuted(participant_id)
+ && !gAgent.isDoNotDisturb())
+ {
+ gToolBarView->flashCommand(LLCommandId("chat"), true);
+ }
+ }
+
+ // 4. Toast
+ if ((("toast" == user_preferences) &&
+ (CLOSED == conversations_floater_status
+ || NOT_ON_TOP == conversations_floater_status))
+ || !session_floater->isMessagePaneExpanded())
+
+ {
+ //Show IM toasts (upper right toasts)
+ // Skip toasting for system messages and for nearby chat
+ if(session_id.notNull() && participant_id.notNull())
+ {
+ LLAvatarNameCache::get(participant_id, boost::bind(&on_avatar_name_cache_toast, _1, _2, msg));
+ }
}
}
diff --git a/indra/newview/llnotificationstorage.cpp b/indra/newview/llnotificationstorage.cpp
index b6184f09bf..2923221c90 100644
--- a/indra/newview/llnotificationstorage.cpp
+++ b/indra/newview/llnotificationstorage.cpp
@@ -105,6 +105,8 @@ bool LLNotificationStorage::writeNotifications(const LLSD& pNotificationData) co
bool LLNotificationStorage::readNotifications(LLSD& pNotificationData) const
{
+ LL_INFOS("LLNotificationStorage") << "starting read '" << mFileName << "'" << LL_ENDL;
+
bool didFileRead;
pNotificationData.clear();
@@ -126,6 +128,8 @@ bool LLNotificationStorage::readNotifications(LLSD& pNotificationData) const
}
}
+ LL_INFOS("LLNotificationStorage") << "ending read '" << mFileName << "'" << LL_ENDL;
+
return didFileRead;
}
diff --git a/indra/newview/llpersistentnotificationstorage.cpp b/indra/newview/llpersistentnotificationstorage.cpp
index 11c12e6c10..666f10df96 100644
--- a/indra/newview/llpersistentnotificationstorage.cpp
+++ b/indra/newview/llpersistentnotificationstorage.cpp
@@ -87,6 +87,8 @@ void LLPersistentNotificationStorage::loadNotifications()
{
LLFastTimer _(FTM_LOAD_NOTIFICATIONS);
+ LL_INFOS("LLPersistentNotificationStorage") << "start loading notifications" << LL_ENDL;
+
LLNotifications::instance().getChannel("Persistent")->
connectChanged(boost::bind(&LLPersistentNotificationStorage::onPersistentChannelChanged, this, _1));
@@ -129,6 +131,8 @@ void LLPersistentNotificationStorage::loadNotifications()
notification_channel->hideToast(notification->getID());
}
}
+
+ LL_INFOS("LLPersistentNotificationStorage") << "finished loading notifications" << LL_ENDL;
}
bool LLPersistentNotificationStorage::onPersistentChannelChanged(const LLSD& payload)
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index d492524789..6329d53913 100755
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -680,7 +680,7 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
mBelowWater(FALSE),
mLastAppearanceBlendTime(0.f),
mAppearanceAnimating(FALSE),
- mNameString(),
+ mNameIsSet(false),
mTitle(),
mNameAway(false),
mNameDoNotDisturb(false),
@@ -2637,8 +2637,7 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
}
// Rebuild name tag if state change detected
- if (mNameString.empty()
- || (mNameString.size() == 2 && mNameString[0] == 10 && mNameString[1] == 10) // *TODO : find out why mNameString is sometimes ""
+ if (!mNameIsSet
|| new_name
|| (!title && !mTitle.empty())
|| (title && mTitle != title->getString())
@@ -2831,17 +2830,16 @@ void LLVOAvatar::addNameTagLine(const std::string& line, const LLColor4& color,
{
mNameText->addLine(line, color, (LLFontGL::StyleFlags)style, font);
}
- mNameString += line;
- mNameString += '\n';
+ mNameIsSet |= !line.empty();
}
void LLVOAvatar::clearNameTag()
{
- mNameString.clear();
+ mNameIsSet = false;
if (mNameText)
{
mNameText->setLabel("");
- mNameText->setString( "" );
+ mNameText->setString("");
}
mTimeVisible.reset();
}
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index c2adaac18e..ac31e7252c 100755
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -855,7 +855,7 @@ protected:
static void getAnimLabels(LLDynamicArray<std::string>* labels);
static void getAnimNames(LLDynamicArray<std::string>* names);
private:
- std::string mNameString; // UTF-8 title + name + status
+ bool mNameIsSet;
std::string mTitle;
bool mNameAway;
bool mNameDoNotDisturb;
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index f94ab67026..9b5d981aa5 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -1259,7 +1259,7 @@ void LLVivoxVoiceClient::stateMachine()
//MARK: stateCreatingSessionGroup
case stateCreatingSessionGroup:
- if(mSessionTerminateRequested || !mVoiceEnabled && mIsInitialized)
+ if(mSessionTerminateRequested || (!mVoiceEnabled && mIsInitialized))
{
// *TODO: Question: is this the right way out of this state
setState(stateSessionTerminated);
@@ -1275,7 +1275,7 @@ void LLVivoxVoiceClient::stateMachine()
//MARK: stateRetrievingParcelVoiceInfo
case stateRetrievingParcelVoiceInfo:
// wait until parcel voice info is received.
- if(mSessionTerminateRequested || !mVoiceEnabled && mIsInitialized)
+ if(mSessionTerminateRequested || (!mVoiceEnabled && mIsInitialized))
{
// if a terminate request has been received,
// bail and go to the stateSessionTerminated
@@ -1295,7 +1295,7 @@ void LLVivoxVoiceClient::stateMachine()
// Otherwise, if you log in but don't join a proximal channel (such as when your login location has voice disabled), your friends list won't sync.
sendFriendsListUpdates();
- if(mSessionTerminateRequested || !mVoiceEnabled && mIsInitialized)
+ if(mSessionTerminateRequested || (!mVoiceEnabled && mIsInitialized))
{
// TODO: Question: Is this the right way out of this state?
setState(stateSessionTerminated);
@@ -1443,7 +1443,7 @@ void LLVivoxVoiceClient::stateMachine()
//MARK: stateRunning
case stateRunning: // steady state
// Disabling voice or disconnect requested.
- if(!mVoiceEnabled && mIsInitialized || mSessionTerminateRequested)
+ if((!mVoiceEnabled && mIsInitialized) || mSessionTerminateRequested)
{
leaveAudioSession();
}
@@ -2673,33 +2673,19 @@ void LLVivoxVoiceClient::checkFriend(const LLUUID& id)
{
buddyListEntry *buddy = findBuddy(id);
- // Make sure we don't add a name before it's been looked up.
+ // Make sure we don't add a name before it's been looked up in the avatar name cache
LLAvatarName av_name;
- if(LLAvatarNameCache::get(id, &av_name))
+ if (LLAvatarNameCache::get(id, &av_name))
{
- // *NOTE: For now, we feed legacy names to Vivox because I don't know
- // if their service can support a mix of new and old clients with
- // different sorts of names.
+ // *NOTE: We feed legacy names to Vivox because we don't know if their service
+ // can support a mix of new and old clients with different sorts of names.
std::string name = av_name.getAccountName();
-
- const LLRelationship* relationInfo = LLAvatarTracker::instance().getBuddyInfo(id);
- bool canSeeMeOnline = false;
- if(relationInfo && relationInfo->isRightGrantedTo(LLRelationship::GRANT_ONLINE_STATUS))
- canSeeMeOnline = true;
-
- // When we get here, mNeedsSend is true and mInSLFriends is false. Change them as necessary.
- if(buddy)
+ if (buddy)
{
- // This buddy is already in both lists.
-
- if(name != buddy->mDisplayName)
- {
- // The buddy is in the list with the wrong name. Update it with the correct name.
- LL_WARNS("Voice") << "Buddy " << id << " has wrong name (\"" << buddy->mDisplayName << "\" should be \"" << name << "\"), updating."<< LL_ENDL;
- buddy->mDisplayName = name;
- buddy->mNeedsNameUpdate = true; // This will cause the buddy to be resent.
- }
+ // This buddy is already in both lists (vivox buddies and avatar cache).
+ // Trust the avatar cache more for the display name (vivox display name are notoriously wrong)
+ buddy->mDisplayName = name;
}
else
{
@@ -2708,20 +2694,19 @@ void LLVivoxVoiceClient::checkFriend(const LLUUID& id)
buddy->mUUID = id;
}
- // In all the above cases, the buddy is in the SL friends list (which is how we got here).
- buddy->mInSLFriends = true;
- buddy->mCanSeeMeOnline = canSeeMeOnline;
+ const LLRelationship* relationInfo = LLAvatarTracker::instance().getBuddyInfo(id);
+ buddy->mCanSeeMeOnline = (relationInfo && relationInfo->isRightGrantedTo(LLRelationship::GRANT_ONLINE_STATUS));
+ // In all the above cases, the buddy is in the SL friends list and tha name has been resolved (which is how we got here).
buddy->mNameResolved = true;
-
+ buddy->mInSLFriends = true;
}
else
{
- // This name hasn't been looked up yet. Don't do anything with this buddy list entry until it has.
- if(buddy)
+ // This name hasn't been looked up yet in the avatar cache. Don't do anything with this buddy list entry until it has.
+ if (buddy)
{
buddy->mNameResolved = false;
}
-
// Initiate a lookup.
// The "lookup completed" callback will ensure that the friends list is rechecked after it completes.
lookupName(id);
@@ -2829,13 +2814,12 @@ void LLVivoxVoiceClient::sendFriendsListUpdates()
{
std::ostringstream stream;
- if(buddy->mInSLFriends && (!buddy->mInVivoxBuddies || buddy->mNeedsNameUpdate))
+ if(buddy->mInSLFriends && !buddy->mInVivoxBuddies)
{
if(mNumberOfAliases > 0)
{
// Add (or update) this entry in the vivox buddy list
buddy->mInVivoxBuddies = true;
- buddy->mNeedsNameUpdate = false;
LL_DEBUGS("Voice") << "add/update " << buddy->mURI << " (" << buddy->mDisplayName << ")" << LL_ENDL;
stream
<< "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Account.BuddySet.1\">"
@@ -5859,7 +5843,6 @@ LLVivoxVoiceClient::buddyListEntry::buddyListEntry(const std::string &uri) :
mNameResolved = false;
mInVivoxBuddies = false;
mInSLFriends = false;
- mNeedsNameUpdate = false;
}
void LLVivoxVoiceClient::processBuddyListEntry(const std::string &uri, const std::string &displayName)
@@ -5884,25 +5867,21 @@ LLVivoxVoiceClient::buddyListEntry *LLVivoxVoiceClient::addBuddy(const std::stri
buddyListEntry *result = NULL;
buddyListMap::iterator iter = mBuddyListMap.find(uri);
- if(iter != mBuddyListMap.end())
+ if (iter != mBuddyListMap.end())
{
// Found a matching buddy already in the map.
LL_DEBUGS("Voice") << "adding existing buddy " << uri << LL_ENDL;
result = iter->second;
}
- if(!result)
+ if (!result)
{
// participant isn't already in one list or the other.
LL_DEBUGS("Voice") << "adding new buddy " << uri << LL_ENDL;
result = new buddyListEntry(uri);
result->mDisplayName = displayName;
- if(IDFromName(uri, result->mUUID))
- {
- // Extracted UUID from name successfully.
- }
- else
+ if (!IDFromName(uri, result->mUUID))
{
LL_DEBUGS("Voice") << "Couldn't find ID for buddy " << uri << " (\"" << displayName << "\")" << LL_ENDL;
}
@@ -7272,7 +7251,7 @@ void LLVivoxProtocolParser::StartTag(const char *tag, const char **attr)
void LLVivoxProtocolParser::EndTag(const char *tag)
{
const std::string& string = textBuffer;
-
+
responseDepth--;
if (ignoringTags)
@@ -7371,6 +7350,8 @@ void LLVivoxProtocolParser::EndTag(const char *tag)
}
else if (!stricmp("Buddy", tag))
{
+ // NOTE : Vivox does *not* give reliable display name for Buddy tags
+ // We don't take those very seriously as a result...
LLVivoxVoiceClient::getInstance()->processBuddyListEntry(uriString, displayNameString);
}
else if (!stricmp("BlockRule", tag))
diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h
index 574027de42..a6f40eb3e9 100644
--- a/indra/newview/llvoicevivox.h
+++ b/indra/newview/llvoicevivox.h
@@ -584,7 +584,6 @@ protected:
bool mNameResolved;
bool mInSLFriends;
bool mInVivoxBuddies;
- bool mNeedsNameUpdate;
};
typedef std::map<std::string, buddyListEntry*> buddyListMap;
diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index e081ea8e74..3b56e974d2 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -14,7 +14,6 @@
width="394"
can_resize="true"
can_tear_off="false"
- min_width="340"
min_height="190"
positioning="relative">
<floater.string name="call_btn_start">Conv_toolbar_open_call</floater.string>
@@ -43,58 +42,52 @@
<floater.string
name="multiple_participants_added"
value="[NAME] were invited to the conversation."/>
- <floater.string
+ <floater.string
name="tooltip_to_separate_window"
value="Move this conversation to a separate window"/>
- <floater.string
+ <floater.string
name="tooltip_to_main_window"
value="Move this conversation back to main window"/>
- <floater.string
+ <floater.string
name="start_call_button_tooltip"
value="Open voice connection"/>
- <floater.string
+ <floater.string
name="end_call_button_tooltip"
value="Close voice connection"/>
- <floater.string
+ <floater.string
name="expcol_button_not_tearoff_tooltip"
value="Collapse this pane"/>
- <floater.string
+ <floater.string
name="expcol_button_tearoff_and_expanded_tooltip"
value="Collapse participant list"/>
- <floater.string
+ <floater.string
name="expcol_button_tearoff_and_collapsed_tooltip"
value="Expand participant list"/>
<view
- follows="all"
- layout="topleft"
- name="contents_view"
- top="0"
- left="0"
- height="355"
- width="394">
- <layout_stack
- animate="false"
- default_tab_group="2"
- follows="all"
- height="355"
- width="394"
- layout="topleft"
- orientation="vertical"
- name="main_stack"
- tab_group="1"
- top="0"
- left="0">
-
- <layout_panel
- follows="left|top|right"
+ follows="all"
+ layout="topleft"
+ name="contents_view"
+ top="0"
+ left="0"
+ right="-1"
+ bottom="-1">
+ <layout_stack
+ animate="false"
+ default_tab_group="2"
+ follows="all"
+ right="-5"
+ bottom="-1"
layout="topleft"
- name="toolbar_panel"
+ orientation="vertical"
+ name="main_stack"
+ tab_group="1"
top="0"
- left="0"
- height="35"
- min_height="35"
- width="394">
- <menu_button
+ left="5">
+ <layout_panel
+ auto_resize="false"
+ name="toolbar_panel"
+ height="35">
+ <menu_button
menu_filename="menu_im_session_showmodes.xml"
follows="top|left"
height="25"
@@ -108,22 +101,22 @@
tool_tip="View/sort options"
top="5"
width="31" />
- <menu_button
- menu_filename="menu_im_conversation.xml"
- follows="top|left"
- height="25"
- image_hover_unselected="Toolbar_Middle_Over"
- image_overlay="OptionsMenu_Off"
- image_selected="Toolbar_Middle_Selected"
- image_unselected="Toolbar_Middle_Off"
- layout="topleft"
- top="5"
- left_pad="2"
- name="gear_btn"
- visible="false"
- tool_tip="Actions on selected person"
- width="31"/>
- <button
+ <menu_button
+ menu_filename="menu_im_conversation.xml"
+ follows="top|left"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="OptionsMenu_Off"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ layout="topleft"
+ top="5"
+ left_pad="2"
+ name="gear_btn"
+ visible="false"
+ tool_tip="Actions on selected person"
+ width="31"/>
+ <button
enabled="false"
follows="top|left"
height="25"
@@ -137,7 +130,7 @@
name="add_btn"
tool_tip="Add someone to this conversation"
width="31"/>
- <button
+ <button
follows="top|left"
height="25"
image_hover_unselected="Toolbar_Middle_Over"
@@ -150,19 +143,19 @@
name="voice_call_btn"
tool_tip="Open voice connection"
width="31"/>
- <output_monitor
- auto_update="true"
- follows="top|left"
- draw_border="false"
- height="16"
- layout="topleft"
- top="10"
- left_pad="10"
- mouse_opaque="true"
- name="speaking_indicator"
- visible="false"
- width="20" />
- <button
+ <output_monitor
+ auto_update="true"
+ follows="top|left"
+ draw_border="false"
+ height="16"
+ layout="topleft"
+ top="10"
+ left_pad="10"
+ mouse_opaque="true"
+ name="speaking_indicator"
+ visible="false"
+ width="20" />
+ <button
follows="right|top"
height="25"
image_hover_unselected="Toolbar_Middle_Over"
@@ -171,229 +164,155 @@
image_unselected="Toolbar_Middle_Off"
layout="topleft"
top="5"
- left="292"
+ right="-70"
name="close_btn"
tool_tip="End this conversation"
width="31" />
- <button
+ <button
follows="right|top"
height="25"
image_hover_unselected="Toolbar_Middle_Over"
image_overlay="Conv_toolbar_collapse"
image_selected="Toolbar_Middle_Selected"
- image_unselected="Toolbar_Middle_Off"
+ image_unselected="Toolbar_Middle_Off"
layout="topleft"
top="5"
left_pad="2"
name="expand_collapse_btn"
tool_tip="Collapse/Expand this pane"
width="31" />
- <button
+ <button
follows="right|top"
height="25"
image_hover_unselected="Toolbar_Middle_Over"
image_overlay="Conv_toolbar_arrow_ne"
image_selected="Toolbar_Middle_Selected"
- image_unselected="Toolbar_Middle_Off"
+ image_unselected="Toolbar_Middle_Off"
layout="topleft"
- top="5"
left_pad="2"
name="tear_off_btn"
+ top="5"
width="31" />
- </layout_panel>
- <layout_panel
- name="body_panel"
- follows="all"
- width="394"
- height="235"
- user_resize="false"
- auto_resize="true">
- <layout_stack
- animate="true"
- default_tab_group="2"
- follows="all"
- height="275"
- width="394"
- layout="topleft"
- orientation="horizontal"
- name="im_panels"
- tab_group="1"
- top_pad="0"
- left="0">
- <layout_panel
- name="speakers_list_panel"
- follows="all"
- min_width="115"
- width="150"
- height="275"
- user_resize="true"
- auto_resize="false">
- </layout_panel>
- <layout_panel
- default_tab_group="3"
- left="0"
- tab_group="2"
- follows="all"
- top="0"
- height="275"
- width="244"
- layout="topleft"
- user_resize="true"
- auto_resize="true"
- visible="true"
- name="left_part_holder"
- min_width="221">
- <panel
- name="trnsAndChat_panel"
- follows="all"
- layout="topleft"
- visible="true"
- height="240"
- width="244">
- <layout_stack
- animate="true"
- default_tab_group="2"
- follows="all"
- height="240"
- width="244"
- layout="topleft"
- visible="true"
- orientation="vertical"
- name="translate_and_chat_stack"
- tab_group="1"
- left_pad="0"
- top="0"
- left="0">
- <layout_panel
- auto_resize="false"
- height="26"
- layout="topleft"
- left_delta="0"
- name="translate_chat_checkbox_lp"
- top_delta="0"
- visible="true"
- width="210">
- <check_box
- top="10"
- control_name="TranslateChat"
- enabled="true"
- height="16"
- label="Translate chat"
- layout="topleft"
- left="5"
- name="translate_chat_checkbox"
- width="230" />
</layout_panel>
<layout_panel
- height="233"
- width="210"
- layout="topleft"
- follows="all"
- left_delta="0"
- top_delta="0"
- bottom="0"
- visible="true"
- user_resize="true"
- auto_resize="true"
- name="chat_holder">
- <chat_history
- font="SansSerifSmall"
- follows="all"
- visible="true"
- height="225"
- name="chat_history"
- parse_highlights="true"
- parse_urls="true"
- right="-5"
- left="5">
- </chat_history>
+ name="body_panel"
+ height="235">
+ <layout_stack
+ default_tab_group="2"
+ follows="all"
+ orientation="horizontal"
+ name="im_panels"
+ tab_group="1"
+ top="0"
+ right="-1"
+ bottom="-1"
+ left="0">
+ <layout_panel
+ name="speakers_list_panel"
+ expanded_min_dim="115"
+ min_dim="0"
+ width="150"
+ user_resize="true"
+ auto_resize="false" />
+ <layout_panel
+ default_tab_group="3"
+ tab_group="2"
+ name="right_part_holder"
+ min_width="221">
+ <layout_stack
+ animate="true"
+ default_tab_group="2"
+ follows="all"
+ orientation="vertical"
+ name="translate_and_chat_stack"
+ tab_group="1"
+ top="0"
+ left="0"
+ right="-1"
+ bottom="-1">
+ <layout_panel
+ auto_resize="false"
+ height="26"
+ name="translate_chat_checkbox_lp">
+ <check_box
+ top="10"
+ control_name="TranslateChat"
+ enabled="true"
+ height="16"
+ label="Translate chat"
+ left="5"
+ name="translate_chat_checkbox"
+ width="230" />
+ </layout_panel>
+ <layout_panel
+ name="chat_holder">
+ <chat_history
+ font="SansSerifSmall"
+ follows="all"
+ name="chat_history"
+ parse_highlights="true"
+ parse_urls="true"
+ right="-1"
+ left="5"
+ top="0"
+ bottom="-1" />
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
</layout_panel>
- </layout_stack>
- </panel>
- </layout_panel>
- </layout_stack>
- </layout_panel>
- <layout_panel
+ <layout_panel
height="35"
- layout="topleft"
- follows="left|right|bottom"
- left_delta="0"
- right="0"
- top_delta="0"
- bottom="0"
- visible="true"
- user_resize="false"
auto_resize="false"
name="chat_layout_panel">
- <layout_stack
- animate="true"
- default_tab_group="2"
- follows="all"
- height="35"
- right="0"
- layout="topleft"
- orientation="horizontal"
- name="input_panels"
- top_pad="0"
- left="0">
- <layout_panel
- height="35"
- layout="topleft"
- follows="left|right|bottom"
- left_delta="0"
- top_delta="0"
- bottom="0"
- visible="true"
- user_resize="false"
- auto_resize="true"
- name="input_editor_layout_panel">
- <chat_editor
- top="6"
- expand_lines_count="5"
- follows="left|right|bottom"
- font="SansSerifSmall"
- visible="true"
- height="20"
- is_expandable="true"
- label="To"
- text_tentative_color="TextFgTentativeColor"
- layout="topleft"
- name="chat_editor"
- max_length="1023"
- spellcheck="true"
- tab_group="3"
- width="160"
- left="5"
- right="-5"
- wrap="true">
- </chat_editor>
+ <layout_stack
+ animate="false"
+ default_tab_group="2"
+ follows="all"
+ right="-1"
+ orientation="horizontal"
+ name="input_panels"
+ top="0"
+ bottom="-1"
+ left="0">
+ <layout_panel
+ name="input_editor_layout_panel">
+ <chat_editor
+ layout="topleft"
+ expand_lines_count="5"
+ follows="left|right|bottom"
+ font="SansSerifSmall"
+ height="20"
+ is_expandable="true"
+ text_tentative_color="TextFgTentativeColor"
+ name="chat_editor"
+ max_length="1023"
+ spellcheck="true"
+ tab_group="3"
+ bottom="-8"
+ left="5"
+ right="-5"
+ wrap="true" />
+ </layout_panel>
+ <layout_panel
+ auto_resize="false"
+ name="input_button_layout_panel"
+ width="32">
+ <button
+ left="1"
+ top="4"
+ follows="left|right|top"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="Conv_expand_one_line"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ name="minz_btn"
+ tool_tip="Shows/hides message panel"
+ width="28" />
+ </layout_panel>
+ </layout_stack>
</layout_panel>
- <layout_panel
- height="35"
- layout="topleft"
- follows="left|right|bottom"
- left_delta="0"
- top_delta="0"
- bottom="0"
- width="35"
- visible="true"
- user_resize="false"
- auto_resize="false"
- name="input_button_layout_panel">
- <button
- follows="left|right|bottom"
- height="25"
- image_hover_unselected="Toolbar_Middle_Over"
- image_overlay="Conv_expand_one_line"
- image_selected="Toolbar_Middle_Selected"
- image_unselected="Toolbar_Middle_Off"
- layout="topleft"
- name="minz_btn"
- tool_tip="Shows/hides message panel"
- width="28"/>
- </layout_panel>
- </layout_stack>
- </layout_panel>
- </layout_stack>
+ </layout_stack>
</view>
</floater>