summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/llprimitive/llmediaentry.cpp8
-rw-r--r--indra/llprimitive/tests/llmediaentry_test.cpp197
-rw-r--r--indra/llui/llstyle.cpp1
-rw-r--r--indra/llui/llstyle.h7
-rw-r--r--indra/llui/lltabcontainer.cpp41
-rw-r--r--indra/llui/lltextbase.cpp5
-rw-r--r--indra/llui/lltexteditor.cpp3
-rw-r--r--indra/llui/lltooltip.cpp4
-rw-r--r--indra/llui/lltooltip.h6
-rw-r--r--indra/llui/lluiimage.cpp7
-rw-r--r--indra/newview/llfloatersearch.cpp7
-rw-r--r--indra/newview/llfloatertools.cpp41
-rwxr-xr-xindra/newview/llmediadataclient.cpp21
-rwxr-xr-xindra/newview/llmediadataclient.h8
-rw-r--r--indra/newview/lltoolpie.cpp46
-rw-r--r--indra/newview/llviewermedia.cpp38
-rw-r--r--indra/newview/llvovolume.cpp8
-rw-r--r--indra/newview/llvovolume.h5
-rw-r--r--indra/newview/skins/default/xui/en/floater_search.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_test_textbox.xml92
-rw-r--r--indra/newview/skins/default/xui/en/fonts.xml8
-rw-r--r--indra/newview/skins/default/xui/en/widgets/inspector.xml8
-rw-r--r--indra/newview/tests/llmediadataclient_test.cpp35
23 files changed, 345 insertions, 253 deletions
diff --git a/indra/llprimitive/llmediaentry.cpp b/indra/llprimitive/llmediaentry.cpp
index 701300163a..2fc1e5e60c 100644
--- a/indra/llprimitive/llmediaentry.cpp
+++ b/indra/llprimitive/llmediaentry.cpp
@@ -389,8 +389,12 @@ U32 LLMediaEntry::setWhiteList( const std::vector<std::string> &whitelist )
U32 LLMediaEntry::setWhiteList( const LLSD &whitelist )
{
- // If whitelist is undef, this is a no-op.
- if (whitelist.isUndefined()) return LSL_STATUS_OK;
+ // If whitelist is undef, the whitelist is cleared
+ if (whitelist.isUndefined())
+ {
+ mWhiteList.clear();
+ return LSL_STATUS_OK;
+ }
// However, if the whitelist is an empty array, erase it.
if (whitelist.isArray())
diff --git a/indra/llprimitive/tests/llmediaentry_test.cpp b/indra/llprimitive/tests/llmediaentry_test.cpp
index cd9608d56b..dfac5f26c7 100644
--- a/indra/llprimitive/tests/llmediaentry_test.cpp
+++ b/indra/llprimitive/tests/llmediaentry_test.cpp
@@ -190,9 +190,9 @@ namespace tut
entry.setWhiteList(tokens);
}
- void whitelist_test(bool enable, const char *whitelist, const char *candidate_url, bool expected_pass)
+ void whitelist_test(int num, bool enable, const char *whitelist, const char *candidate_url, bool expected_pass)
{
- std::string message = "Whitelist test";
+ std::string message = "Whitelist test " + boost::lexical_cast<std::string>(num);
LLMediaEntry entry;
entry.setWhiteListEnable(enable);
set_whitelist(entry, whitelist);
@@ -209,13 +209,13 @@ namespace tut
ensure(message, expected_pass == passed_whitelist);
}
- void whitelist_test(const char *whitelist, const char *candidate_url, bool expected_pass)
+ void whitelist_test(int num, const char *whitelist, const char *candidate_url, bool expected_pass)
{
- whitelist_test(true, whitelist, candidate_url, expected_pass);
+ whitelist_test(num, true, whitelist, candidate_url, expected_pass);
}
- void whitelist_test(const char *whitelist, const char *candidate_url)
+ void whitelist_test(int num, const char *whitelist, const char *candidate_url)
{
- whitelist_test(true, whitelist, candidate_url, true);
+ whitelist_test(num, true, whitelist, candidate_url, true);
}
template<> template<>
@@ -265,12 +265,30 @@ namespace tut
ensure_llsd_equals(get_test_name() + " failed", defaultMediaEntryLLSD, sd);
}
+
+ template<> template<>
+ void object::test<5>()
+ {
+ set_test_name("Test LLMediaEntry::asLLSD() -> LLMediaEntry::fromLLSD()");
+ LLMediaEntry entry1, entry2;
+ // Add a whitelist to entry2
+ std::vector<std::string> whitelist;
+ whitelist.push_back("*.example.com");
+ entry2.setWhiteList(whitelist);
+ // Render entry1 (which has no whitelist) as an LLSD
+ LLSD sd;
+ entry1.asLLSD(sd);
+ // "read" that LLSD into entry 2
+ entry2.fromLLSD(sd);
+ ensure_llsd_equals(get_test_name() + " failed", defaultMediaEntryLLSD, entry2.asLLSD());
+ }
+
// limit tests
const char *URL_OK = "http://www.example.com";
const char *URL_TOO_BIG = "http://www.example.com.qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq";
template<> template<>
- void object::test<5>()
+ void object::test<6>()
{
set_test_name("Test Limits on setting current URL");
LLMediaEntry entry;
@@ -281,7 +299,7 @@ namespace tut
}
template<> template<>
- void object::test<6>()
+ void object::test<7>()
{
set_test_name("Test Limits on setting home URL");
LLMediaEntry entry;
@@ -292,7 +310,7 @@ namespace tut
}
template<> template<>
- void object::test<7>()
+ void object::test<8>()
{
set_test_name("Test Limits on setting whitelist");
@@ -306,7 +324,7 @@ namespace tut
}
template<> template<>
- void object::test<8>()
+ void object::test<9>()
{
set_test_name("Test Limits on setting whitelist too big");
@@ -321,7 +339,7 @@ namespace tut
}
template<> template<>
- void object::test<9>()
+ void object::test<10>()
{
set_test_name("Test Limits on setting whitelist too many");
@@ -337,7 +355,7 @@ namespace tut
}
template<> template<>
- void object::test<10>()
+ void object::test<11>()
{
set_test_name("Test to make sure both setWhiteList() functions behave the same");
@@ -355,7 +373,7 @@ namespace tut
}
template<> template<>
- void object::test<11>()
+ void object::test<12>()
{
set_test_name("Test to make sure both setWhiteList() functions behave the same");
@@ -376,7 +394,7 @@ namespace tut
}
template<> template<>
- void object::test<12>()
+ void object::test<13>()
{
set_test_name("Test to make sure both setWhiteList() functions behave the same");
@@ -396,103 +414,70 @@ namespace tut
empty == entry2.getWhiteList());
}
- // Whitelist check tests
-
- // Check the "empty whitelist" case
template<> template<>
- void object::test<13>() { whitelist_test("", "http://www.example.com", true); }
+ void object::test<14>()
+ {
+ // Whitelist check tests
+ int n=0;
+
+ // Check the "empty whitelist" case
+ whitelist_test(++n, "", "http://www.example.com", true);
- // Check the "missing scheme" case
- template<> template<>
- void object::test<14>() { whitelist_test("www.example.com", "http://www.example.com", true); }
+ // Check the "missing scheme" case
+ whitelist_test(++n, "www.example.com", "http://www.example.com", true);
- // Check the "exactly the same" case
- template<> template<>
- void object::test<15>() { whitelist_test("http://example.com", "http://example.com", true); }
+ // Check the "exactly the same" case
+ whitelist_test(++n, "http://example.com", "http://example.com", true);
- // Check the enable flag
- template<> template<>
- void object::test<16>() { whitelist_test(false, "www.example.com", "http://www.secondlife.com", true); }
- template<> template<>
- void object::test<17>() { whitelist_test(true, "www.example.com", "http://www.secondlife.com", false); }
+ // Check the enable flag
+ whitelist_test(++n, false, "www.example.com", "http://www.secondlife.com", true);
+ whitelist_test(++n, true, "www.example.com", "http://www.secondlife.com", false);
- // Check permutations of trailing slash:
- template<> template<>
- void object::test<18>() { whitelist_test("http://www.example.com", "http://www.example.com/", true); }
- template<> template<>
- void object::test<19>() { whitelist_test("http://www.example.com/", "http://www.example.com/", true); }
- template<> template<>
- void object::test<20>() { whitelist_test("http://www.example.com/", "http://www.example.com", false); }
- template<> template<>
- void object::test<21>() { whitelist_test("http://www.example.com", "http://www.example.com/foobar", true); }
- template<> template<>
- void object::test<22>() { whitelist_test("http://www.example.com/", "http://www.example.com/foobar", false); }
+ // Check permutations of trailing slash:
+ whitelist_test(++n, "http://www.example.com", "http://www.example.com/", true);
+ whitelist_test(++n, "http://www.example.com/", "http://www.example.com/", true);
+ whitelist_test(++n, "http://www.example.com/", "http://www.example.com", false);
+ whitelist_test(++n, "http://www.example.com", "http://www.example.com/foobar", true);
+ whitelist_test(++n, "http://www.example.com/", "http://www.example.com/foobar", false);
- // More cases...
- template<> template<>
- void object::test<23>() { whitelist_test("http://example.com", "http://example.com/wiki", true); }
- template<> template<>
- void object::test<24>() { whitelist_test("www.example.com", "http://www.example.com/help", true); }
- template<> template<>
- void object::test<25>() { whitelist_test("http://www.example.com", "http://wwwexample.com", false); }
- template<> template<>
- void object::test<26>() { whitelist_test("http://www.example.com", "http://www.example.com/wiki", true); }
- template<> template<>
- void object::test<27>() { whitelist_test("example.com", "http://wwwexample.com", false); }
- template<> template<>
- void object::test<28>() { whitelist_test("http://www.example.com/", "http://www.amazon.com/wiki", false); }
- template<> template<>
- void object::test<29>() { whitelist_test("www.example.com", "http://www.amazon.com", false); }
-
- // regexp cases
- template<> template<>
- void object::test<30>() { whitelist_test("*.example.com", "http://www.example.com", true); }
- template<> template<>
- void object::test<31>() { whitelist_test("*.example.com", "http://www.amazon.com", false); }
- template<> template<>
- void object::test<32>() { whitelist_test("*.example.com", "http://www.example.com/foo/bar", true); }
- template<> template<>
- void object::test<33>() { whitelist_test("*.example.com", "http:/example.com/foo/bar", false); }
- template<> template<>
- void object::test<34>() { whitelist_test("*example.com", "http://example.com/foo/bar", true); }
- template<> template<>
- void object::test<35>() { whitelist_test("*example.com", "http://my.virus.com/foo/bar?example.com", false); }
- template<> template<>
- void object::test<36>() { whitelist_test("example.com", "http://my.virus.com/foo/bar?example.com", false); }
- template<> template<>
- void object::test<37>() { whitelist_test("*example.com", "http://my.virus.com/foo/bar?*example.com", false); }
- template<> template<>
- void object::test<38>() { whitelist_test("http://*example.com", "http://www.example.com", true); }
- template<> template<>
- void object::test<39>() { whitelist_test("http://*.example.com", "http://www.example.com", true); }
- template<> template<>
- void object::test<40>() { whitelist_test("http://*.e$?^.com", "http://www.e$?^.com", true); }
- template<> template<>
- void object::test<41>() { whitelist_test("*.example.com/foo/bar", "http://www.example.com/", false); }
- template<> template<>
- void object::test<42>() { whitelist_test("*.example.com/foo/bar", "http://example.com/foo/bar", false); }
- template<> template<>
- void object::test<43>() { whitelist_test("http://*.example.com/foo/bar", "http://www.example.com", false); }
- template<> template<>
- void object::test<44>() { whitelist_test("http://*.example.com", "https://www.example.com", false); }
- template<> template<>
- void object::test<45>() { whitelist_test("http*://*.example.com", "rtsp://www.example.com", false); }
- template<> template<>
- void object::test<46>() { whitelist_test("http*://*.example.com", "https://www.example.com", true); }
- template<> template<>
- void object::test<47>() { whitelist_test("example.com", "http://www.example.com", false); }
- template<> template<>
- void object::test<48>() { whitelist_test("www.example.com", "http://www.example.com:80", false); }
- template<> template<>
- void object::test<49>() { whitelist_test("www.example.com", "http://www.example.com", true); }
- template<> template<>
- void object::test<50>() { whitelist_test("www.example.com/", "http://www.example.com", false); }
- template<> template<>
- void object::test<51>() { whitelist_test("www.example.com/foo/bar/*", "http://www.example.com/foo/bar/baz", true); }
- // Path only
- template<> template<>
- void object::test<52>() { whitelist_test("/foo/*/baz", "http://www.example.com/foo/bar/baz", true); }
- template<> template<>
- void object::test<53>() { whitelist_test("/foo/*/baz", "http://www.example.com/foo/bar/", false); }
+ // More cases...
+ whitelist_test(++n, "http://example.com", "http://example.com/wiki", true);
+ whitelist_test(++n, "www.example.com", "http://www.example.com/help", true);
+ whitelist_test(++n, "http://www.example.com", "http://wwwexample.com", false);
+ whitelist_test(++n, "http://www.example.com", "http://www.example.com/wiki", true);
+ whitelist_test(++n, "example.com", "http://wwwexample.com", false);
+ whitelist_test(++n, "http://www.example.com/", "http://www.amazon.com/wiki", false);
+ whitelist_test(++n, "www.example.com", "http://www.amazon.com", false);
+
+ // regexp cases
+ whitelist_test(++n, "*.example.com", "http://www.example.com", true);
+ whitelist_test(++n, "*.example.com", "http://www.amazon.com", false);
+ whitelist_test(++n, "*.example.com", "http://www.example.com/foo/bar", true);
+ whitelist_test(++n, "*.example.com", "http:/example.com/foo/bar", false);
+ whitelist_test(++n, "*example.com", "http://example.com/foo/bar", true);
+ whitelist_test(++n, "*example.com", "http://my.virus.com/foo/bar?example.com", false);
+ whitelist_test(++n, "example.com", "http://my.virus.com/foo/bar?example.com", false);
+ whitelist_test(++n, "*example.com", "http://my.virus.com/foo/bar?*example.com", false);
+ whitelist_test(++n, "http://*example.com", "http://www.example.com", true);
+ whitelist_test(++n, "http://*.example.com", "http://www.example.com", true);
+ whitelist_test(++n, "http://*.e$?^.com", "http://www.e$?^.com", true);
+ whitelist_test(++n, "*.example.com/foo/bar", "http://www.example.com/", false);
+ whitelist_test(++n, "*.example.com/foo/bar", "http://example.com/foo/bar", false);
+ whitelist_test(++n, "http://*.example.com/foo/bar", "http://www.example.com", false);
+ whitelist_test(++n, "http://*.example.com", "https://www.example.com", false);
+ whitelist_test(++n, "http*://*.example.com", "rtsp://www.example.com", false);
+ whitelist_test(++n, "http*://*.example.com", "https://www.example.com", true);
+ whitelist_test(++n, "example.com", "http://www.example.com", false);
+ whitelist_test(++n, "www.example.com", "http://www.example.com:80", false);
+ whitelist_test(++n, "www.example.com", "http://www.example.com", true);
+ whitelist_test(++n, "www.example.com/", "http://www.example.com", false);
+ whitelist_test(++n, "www.example.com/foo/bar/*", "http://www.example.com/foo/bar/baz", true);
+
+ // Path only
+ whitelist_test(++n, "/foo/*/baz", "http://www.example.com/foo/bar/baz", true);
+ whitelist_test(++n, "/foo/*/baz", "http://www.example.com/foo/bar/", false);
+ }
+
}
+
diff --git a/indra/llui/llstyle.cpp b/indra/llui/llstyle.cpp
index fd3f88d1f6..71511f69a4 100644
--- a/indra/llui/llstyle.cpp
+++ b/indra/llui/llstyle.cpp
@@ -51,6 +51,7 @@ LLStyle::Params::Params()
LLStyle::LLStyle(const LLStyle::Params& p)
: mVisible(p.visible),
mColor(p.color()),
+ mReadOnlyColor(p.readonly_color()),
mFont(p.font()),
mLink(p.link_href),
mDropShadow(p.drop_shadow),
diff --git a/indra/llui/llstyle.h b/indra/llui/llstyle.h
index c769964136..ee9ca730e9 100644
--- a/indra/llui/llstyle.h
+++ b/indra/llui/llstyle.h
@@ -46,7 +46,8 @@ public:
{
Optional<bool> visible;
Optional<LLFontGL::ShadowType> drop_shadow;
- Optional<LLUIColor> color;
+ Optional<LLUIColor> color,
+ readonly_color;
Optional<const LLFontGL*> font;
Optional<LLUIImage*> image;
Optional<std::string> link_href;
@@ -57,6 +58,8 @@ public:
const LLColor4& getColor() const { return mColor; }
void setColor(const LLColor4 &color) { mColor = color; }
+ const LLColor4& getReadOnlyColor() const { return mReadOnlyColor; }
+
BOOL isVisible() const;
void setVisible(BOOL is_visible);
@@ -81,6 +84,7 @@ public:
return
mVisible == rhs.mVisible
&& mColor == rhs.mColor
+ && mReadOnlyColor == rhs.mReadOnlyColor
&& mFont == rhs.mFont
&& mLink == rhs.mLink
&& mImagep == rhs.mImagep
@@ -104,6 +108,7 @@ protected:
private:
BOOL mVisible;
LLUIColor mColor;
+ LLUIColor mReadOnlyColor;
std::string mFontName;
const LLFontGL* mFont; // cached for performance
std::string mLink;
diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp
index b67f753d39..44eff8d357 100644
--- a/indra/llui/lltabcontainer.cpp
+++ b/indra/llui/lltabcontainer.cpp
@@ -346,7 +346,13 @@ void LLTabContainer::draw()
}
}
- LLPanel::draw();
+ {
+ LLRect clip_rect = getLocalRect();
+ clip_rect.mLeft+=(LLPANEL_BORDER_WIDTH + 2);
+ clip_rect.mRight-=(LLPANEL_BORDER_WIDTH + 2);
+ LLLocalClipRect clip(clip_rect);
+ LLPanel::draw();
+ }
// if tabs are hidden, don't draw them and leave them in the invisible state
if (!getTabsHidden())
@@ -358,24 +364,6 @@ void LLTabContainer::draw()
tuple->mButton->setVisible( TRUE );
}
- // Draw some of the buttons...
- LLRect clip_rect = getLocalRect();
- if (has_scroll_arrows)
- {
- // ...but clip them.
- if (mIsVertical)
- {
- clip_rect.mBottom = mNextArrowBtn->getRect().mTop + 3*tabcntrv_pad;
- clip_rect.mTop = mPrevArrowBtn->getRect().mBottom - 3*tabcntrv_pad;
- }
- else
- {
- clip_rect.mLeft = mPrevArrowBtn->getRect().mRight;
- clip_rect.mRight = mNextArrowBtn->getRect().mLeft;
- }
- }
- LLLocalClipRect clip(clip_rect);
-
S32 max_scroll_visible = getTabCount() - getMaxScrollPos() + getScrollPos();
S32 idx = 0;
for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter)
@@ -403,7 +391,7 @@ void LLTabContainer::draw()
mNextArrowBtn->setFlashing( TRUE );
}
}
- }
+ }
idx++;
}
@@ -1039,6 +1027,11 @@ void LLTabContainer::addTabPanel(const TabPanelParams& panel)
{
LLUICtrl::addChild(child, 1);
}
+
+ sendChildToFront(mPrevArrowBtn);
+ sendChildToFront(mNextArrowBtn);
+ sendChildToFront(mJumpPrevArrowBtn);
+ sendChildToFront(mJumpNextArrowBtn);
if( select )
{
@@ -1672,23 +1665,23 @@ void LLTabContainer::initButtons()
S32 btn_top = (getTabPosition() == TOP ) ? getRect().getHeight() - getTopBorderHeight() : tabcntr_arrow_btn_size + 1;
LLRect left_arrow_btn_rect;
- left_arrow_btn_rect.setLeftTopAndSize( LLPANEL_BORDER_WIDTH+1+tabcntr_arrow_btn_size, btn_top + arrow_fudge, tabcntr_arrow_btn_size, tabcntr_arrow_btn_size );
+ left_arrow_btn_rect.setLeftTopAndSize( LLPANEL_BORDER_WIDTH+1+tabcntr_arrow_btn_size, btn_top + arrow_fudge, tabcntr_arrow_btn_size, mTabHeight );
LLRect jump_left_arrow_btn_rect;
- jump_left_arrow_btn_rect.setLeftTopAndSize( LLPANEL_BORDER_WIDTH+1, btn_top + arrow_fudge, tabcntr_arrow_btn_size, tabcntr_arrow_btn_size );
+ jump_left_arrow_btn_rect.setLeftTopAndSize( LLPANEL_BORDER_WIDTH+1, btn_top + arrow_fudge, tabcntr_arrow_btn_size, mTabHeight );
S32 right_pad = tabcntr_arrow_btn_size + LLPANEL_BORDER_WIDTH + 1;
LLRect right_arrow_btn_rect;
right_arrow_btn_rect.setLeftTopAndSize( getRect().getWidth() - mRightTabBtnOffset - right_pad - tabcntr_arrow_btn_size,
btn_top + arrow_fudge,
- tabcntr_arrow_btn_size, tabcntr_arrow_btn_size );
+ tabcntr_arrow_btn_size, mTabHeight );
LLRect jump_right_arrow_btn_rect;
jump_right_arrow_btn_rect.setLeftTopAndSize( getRect().getWidth() - mRightTabBtnOffset - right_pad,
btn_top + arrow_fudge,
- tabcntr_arrow_btn_size, tabcntr_arrow_btn_size );
+ tabcntr_arrow_btn_size, mTabHeight );
LLButton::Params p;
p.name(std::string("Jump Left Arrow"));
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 97ba691341..8d36c9c616 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -286,8 +286,7 @@ bool LLTextBase::truncate()
LLStyle::Params LLTextBase::getDefaultStyle()
{
- LLColor4 text_color = ( mReadOnly ? mReadOnlyFgColor.get() : mFgColor.get() );
- return LLStyle::Params().color(text_color).font(mDefaultFont).drop_shadow(mFontShadow);
+ return LLStyle::Params().color(mFgColor.get()).readonly_color(mReadOnlyFgColor.get()).font(mDefaultFont).drop_shadow(mFontShadow);
}
void LLTextBase::onValueChange(S32 start, S32 end)
@@ -2232,7 +2231,7 @@ F32 LLNormalTextSegment::drawClippedSegment(S32 seg_start, S32 seg_end, S32 sele
const LLFontGL* font = mStyle->getFont();
- LLColor4 color = mStyle->getColor() % alpha;
+ LLColor4 color = (mEditor.getReadOnly() ? mStyle->getReadOnlyColor() : mStyle->getColor()) % alpha;
font = mStyle->getFont();
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index 3ce5a0320b..d136c6b49d 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -2005,7 +2005,8 @@ void LLTextEditor::setEnabled(BOOL enabled)
bool read_only = !enabled;
if (read_only != mReadOnly)
{
- mReadOnly = read_only;
+ //mReadOnly = read_only;
+ LLTextBase::setReadOnly(read_only);
updateSegments();
updateAllowingLanguageInput();
}
diff --git a/indra/llui/lltooltip.cpp b/indra/llui/lltooltip.cpp
index fe1c2ba67c..984a534da6 100644
--- a/indra/llui/lltooltip.cpp
+++ b/indra/llui/lltooltip.cpp
@@ -139,6 +139,10 @@ void LLToolTipView::drawStickyRect()
{
gl_rect_2d(LLToolTipMgr::instance().getMouseNearRect(), LLColor4::white, false);
}
+
+// defaults for floater param block pulled from widgets/floater.xml
+static LLWidgetNameRegistry::StaticRegistrar sRegisterInspectorParams(&typeid(LLInspector::Params), "inspector");
+
//
// LLToolTip
//
diff --git a/indra/llui/lltooltip.h b/indra/llui/lltooltip.h
index 30d251266c..774ca507c1 100644
--- a/indra/llui/lltooltip.h
+++ b/indra/llui/lltooltip.h
@@ -116,6 +116,12 @@ private:
S32 mPadding; // pixels
};
+// used for the inspector tooltips which need different background images etc.
+class LLInspector : public LLToolTip
+{
+public:
+ struct Params : public LLInitParam::Block<Params, LLToolTip::Params> {};
+};
class LLToolTipMgr : public LLSingleton<LLToolTipMgr>
{
diff --git a/indra/llui/lluiimage.cpp b/indra/llui/lluiimage.cpp
index 6c1a32722f..a8683e55c3 100644
--- a/indra/llui/lluiimage.cpp
+++ b/indra/llui/lluiimage.cpp
@@ -142,6 +142,13 @@ namespace LLInitParam
{
LLUIImage* TypedParam<LLUIImage*>::getValueFromBlock() const
{
+ // The keyword "none" is specifically requesting a null image
+ // do not default to current value. Used to overwrite template images.
+ if (name() == "none")
+ {
+ return NULL;
+ }
+
LLUIImage* imagep = LLUI::getUIImage(name());
if (!imagep)
{
diff --git a/indra/newview/llfloatersearch.cpp b/indra/newview/llfloatersearch.cpp
index 97c573ddea..ca2cdffcf8 100644
--- a/indra/newview/llfloatersearch.cpp
+++ b/indra/newview/llfloatersearch.cpp
@@ -36,6 +36,7 @@
#include "llmediactrl.h"
#include "lllogininstance.h"
#include "lluri.h"
+#include "llagent.h"
LLFloaterSearch::LLFloaterSearch(const LLSD& key) :
LLFloater(key),
@@ -122,6 +123,12 @@ void LLFloaterSearch::search(const LLSD &key)
LLSD search_token = LLLoginInstance::getInstance()->getResponse("search_token");
url += "&p=" + search_token.asString();
+ // also append the user's preferred maturity (can be changed via prefs)
+ std::string maturity = "pg";
+ if (gAgent.prefersMature()) maturity += ",mature";
+ if (gAgent.prefersAdult()) maturity += ",adult";
+ url += "&r=" + maturity;
+
// and load the URL in the web view
mBrowser->navigateTo(url);
}
diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp
index 3aef15a35c..3c3dfb760e 100644
--- a/indra/newview/llfloatertools.cpp
+++ b/indra/newview/llfloatertools.cpp
@@ -86,6 +86,7 @@
#include "llviewermenu.h"
#include "llviewerparcelmgr.h"
#include "llviewerwindow.h"
+#include "llvovolume.h"
#include "lluictrlfactory.h"
// Globals
@@ -1079,21 +1080,45 @@ void LLFloaterTools::getMediaState()
}
bool editable = (first_object->permModify() || selectedMediaEditable());
-
+
+ // Check modify permissions and whether any selected objects are in
+ // the process of being fetched. If they are, then we're not editable
+ if (editable)
+ {
+ LLObjectSelection::iterator iter = selected_objects->begin();
+ LLObjectSelection::iterator end = selected_objects->end();
+ for ( ; iter != end; ++iter)
+ {
+ LLSelectNode* node = *iter;
+ LLVOVolume* object = dynamic_cast<LLVOVolume*>(node->getObject());
+ if (NULL != object)
+ {
+ if (!object->permModify() || object->isMediaDataBeingFetched())
+ {
+ editable = false;
+ break;
+ }
+ }
+ }
+ }
+
// Media settings
- U8 has_media = (U8)0;
- struct media_functor : public LLSelectedTEGetFunctor<U8>
+ bool bool_has_media = false;
+ struct media_functor : public LLSelectedTEGetFunctor<bool>
{
- U8 get(LLViewerObject* object, S32 face)
+ bool get(LLViewerObject* object, S32 face)
{
- return (object->getTE(face)->getMediaTexGen());
+ LLTextureEntry *te = object->getTE(face);
+ if (te)
+ {
+ return te->hasMedia();
+ }
+ return false;
}
} func;
// check if all faces have media(or, all dont have media)
- LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo = selected_objects->getSelectedTEValue( &func, has_media );
- bool bool_has_media = (has_media & LLTextureEntry::MF_HAS_MEDIA);
-
+ LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo = selected_objects->getSelectedTEValue( &func, bool_has_media );
const LLMediaEntry default_media_data;
diff --git a/indra/newview/llmediadataclient.cpp b/indra/newview/llmediadataclient.cpp
index 512104a2f4..986c14acff 100755
--- a/indra/newview/llmediadataclient.cpp
+++ b/indra/newview/llmediadataclient.cpp
@@ -324,6 +324,22 @@ std::ostream& operator<<(std::ostream &s, const LLMediaDataClient::PriorityQueue
return s;
}
+// find the given object in the queue.
+bool LLMediaDataClient::PriorityQueue::find(const LLMediaDataClientObject::ptr_t &obj) const
+{
+ std::vector<LLMediaDataClient::request_ptr_t>::const_iterator iter = c.begin();
+ std::vector<LLMediaDataClient::request_ptr_t>::const_iterator end = c.end();
+ while (iter < end)
+ {
+ if (obj->getID() == (*iter)->getObject()->getID())
+ {
+ return true;
+ }
+ iter++;
+ }
+ return false;
+}
+
//////////////////////////////////////////////////////////////////////////////////////
//
// LLMediaDataClient::QueueTimer
@@ -491,6 +507,11 @@ bool LLMediaDataClient::isEmpty() const
return (NULL == pRequestQueue) ? true : pRequestQueue->empty();
}
+bool LLMediaDataClient::isInQueue(const LLMediaDataClientObject::ptr_t &object) const
+{
+ return (NULL == pRequestQueue) ? false : pRequestQueue->find(object);
+}
+
//////////////////////////////////////////////////////////////////////////////////////
//
// LLObjectMediaDataClient
diff --git a/indra/newview/llmediadataclient.h b/indra/newview/llmediadataclient.h
index 9d0aa0981e..0d1450ffbe 100755
--- a/indra/newview/llmediadataclient.h
+++ b/indra/newview/llmediadataclient.h
@@ -89,7 +89,10 @@ public:
F32 getRetryTimerDelay() const { return mRetryTimerDelay; }
// Returns true iff the queue is empty
- bool isEmpty() const;
+ bool isEmpty() const;
+
+ // Returns true iff the given object is in the queue
+ bool isInQueue(const LLMediaDataClientObject::ptr_t &object) const;
protected:
// Destructor
@@ -206,6 +209,9 @@ private:
Comparator >
{
public:
+ // Return whether the given object is in the queue
+ bool find(const LLMediaDataClientObject::ptr_t &obj) const;
+
friend std::ostream& operator<<(std::ostream &s, const PriorityQueue &q);
};
diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp
index 93da32b115..d49ea5109d 100644
--- a/indra/newview/lltoolpie.cpp
+++ b/indra/newview/lltoolpie.cpp
@@ -700,13 +700,17 @@ BOOL LLToolPie::handleToolTip(S32 local_x, S32 local_y, MASK mask)
// *HACK: We may select this object, so pretend it was clicked
mPick = mHoverPick;
- LLToolTipMgr::instance().show(LLToolTip::Params()
- .message(avatar_name)
- .image(LLUI::getUIImage("Info"))
- .click_callback(boost::bind(showAvatarInspector, hover_object->getID()))
- .visible_time_near(6.f)
- .visible_time_far(3.f)
- .wrap(false));
+ LLInspector::Params p;
+ p.message(avatar_name);
+ p.image(LLUI::getUIImage("Info"));
+ p.click_callback(boost::bind(showAvatarInspector, hover_object->getID()));
+ p.visible_time_near(6.f);
+ p.visible_time_far(3.f);
+ p.wrap(false);
+
+ p.fillFrom(LLUICtrlFactory::instance().getDefaultParams<LLInspector>());
+
+ LLToolTipMgr::instance().show(p);
}
}
else
@@ -787,18 +791,22 @@ BOOL LLToolPie::handleToolTip(S32 local_x, S32 local_y, MASK mask)
{
// We may select this object, so pretend it was clicked
mPick = mHoverPick;
- LLToolTipMgr::instance().show(LLToolTip::Params()
- .message(tooltip_msg)
- .image(LLUI::getUIImage("Info_Off"))
- .click_callback(boost::bind(showObjectInspector, hover_object->getID(), mHoverPick.mObjectFace))
- .time_based_media(is_time_based_media)
- .web_based_media(is_web_based_media)
- .media_playing(is_media_playing)
- .click_playmedia_callback(boost::bind(playCurrentMedia, mHoverPick))
- .click_homepage_callback(boost::bind(VisitHomePage, mHoverPick))
- .visible_time_near(6.f)
- .visible_time_far(3.f)
- .wrap(false));
+ LLInspector::Params p;
+ p.message(tooltip_msg);
+ p.image(LLUI::getUIImage("Info_Off"));
+ p.click_callback(boost::bind(showObjectInspector, hover_object->getID(), mHoverPick.mObjectFace));
+ p.time_based_media(is_time_based_media);
+ p.web_based_media(is_web_based_media);
+ p.media_playing(is_media_playing);
+ p.click_playmedia_callback(boost::bind(playCurrentMedia, mHoverPick));
+ p.click_homepage_callback(boost::bind(VisitHomePage, mHoverPick));
+ p.visible_time_near(6.f);
+ p.visible_time_far(3.f);
+ p.wrap(false);
+
+ p.fillFrom(LLUICtrlFactory::instance().getDefaultParams<LLInspector>());
+
+ LLToolTipMgr::instance().show(p);
}
}
}
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 66d48fadd1..605861f1cb 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -1133,11 +1133,15 @@ void LLViewerMediaImpl::mouseMove(S32 x, S32 y, MASK mask)
void LLViewerMediaImpl::mouseDown(const LLVector2& texture_coords, MASK mask, S32 button)
{
if(mMediaSource)
- {
- mouseDown(
- llround(texture_coords.mV[VX] * mMediaSource->getTextureWidth()),
- llround((1.0f - texture_coords.mV[VY]) * mMediaSource->getTextureHeight()),
- mask, button);
+ {
+ // scale x and y to texel units.
+ S32 x = llround(texture_coords.mV[VX] * mMediaSource->getTextureWidth());
+ S32 y = llround((1.0f - texture_coords.mV[VY]) * mMediaSource->getTextureHeight());
+
+ // Adjust for the difference between the actual texture height and the amount of the texture in use.
+ y -= (mMediaSource->getTextureHeight() - mMediaSource->getHeight());
+
+ mouseDown(x, y, mask, button);
}
}
@@ -1145,10 +1149,14 @@ void LLViewerMediaImpl::mouseUp(const LLVector2& texture_coords, MASK mask, S32
{
if(mMediaSource)
{
- mouseUp(
- llround(texture_coords.mV[VX] * mMediaSource->getTextureWidth()),
- llround((1.0f - texture_coords.mV[VY]) * mMediaSource->getTextureHeight()),
- mask, button);
+ // scale x and y to texel units.
+ S32 x = llround(texture_coords.mV[VX] * mMediaSource->getTextureWidth());
+ S32 y = llround((1.0f - texture_coords.mV[VY]) * mMediaSource->getTextureHeight());
+
+ // Adjust for the difference between the actual texture height and the amount of the texture in use.
+ y -= (mMediaSource->getTextureHeight() - mMediaSource->getHeight());
+
+ mouseUp(x, y, mask, button);
}
}
@@ -1156,10 +1164,14 @@ void LLViewerMediaImpl::mouseMove(const LLVector2& texture_coords, MASK mask)
{
if(mMediaSource)
{
- mouseMove(
- llround(texture_coords.mV[VX] * mMediaSource->getTextureWidth()),
- llround((1.0f - texture_coords.mV[VY]) * mMediaSource->getTextureHeight()),
- mask);
+ // scale x and y to texel units.
+ S32 x = llround(texture_coords.mV[VX] * mMediaSource->getTextureWidth());
+ S32 y = llround((1.0f - texture_coords.mV[VY]) * mMediaSource->getTextureHeight());
+
+ // Adjust for the difference between the actual texture height and the amount of the texture in use.
+ y -= (mMediaSource->getTextureHeight() - mMediaSource->getHeight());
+
+ mouseMove(x, y, mask);
}
}
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 5ac6dcce5a..2def905bbb 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -109,6 +109,7 @@ public:
{
result = te->getMediaData()->asLLSD();
// XXX HACK: workaround bug in asLLSD() where whitelist is not set properly
+ // See DEV-41949
if (!result.has(LLMediaEntry::WHITELIST_KEY))
{
result[LLMediaEntry::WHITELIST_KEY] = LLSD::emptyArray();
@@ -1668,6 +1669,13 @@ void LLVOVolume::requestMediaDataUpdate()
sObjectMediaClient->fetchMedia(new LLMediaDataClientObjectImpl(this));
}
+bool LLVOVolume::isMediaDataBeingFetched() const
+{
+ // I know what I'm doing by const_casting this away: this is just
+ // a wrapper class that is only going to do a lookup.
+ return sObjectMediaClient->isInQueue(new LLMediaDataClientObjectImpl(const_cast<LLVOVolume*>(this)));
+}
+
void LLVOVolume::cleanUpMediaImpls()
{
// Iterate through our TEs and remove any Impls that are no longer used
diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h
index 784ef16ba3..10fc8865fc 100644
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -265,7 +265,10 @@ public:
bool hasMedia() const;
LLVector3 getApproximateFaceNormal(U8 face_id);
-
+
+ // Returns 'true' iff the media data for this object is in flight
+ bool isMediaDataBeingFetched() const;
+
protected:
S32 computeLODDetail(F32 distance, F32 radius);
BOOL calcLOD();
diff --git a/indra/newview/skins/default/xui/en/floater_search.xml b/indra/newview/skins/default/xui/en/floater_search.xml
index edc1fb8838..b9cf456842 100644
--- a/indra/newview/skins/default/xui/en/floater_search.xml
+++ b/indra/newview/skins/default/xui/en/floater_search.xml
@@ -2,7 +2,7 @@
<floater
legacy_header_height="18"
can_resize="true"
- height="400"
+ height="512"
layout="topleft"
min_height="140"
min_width="467"
diff --git a/indra/newview/skins/default/xui/en/floater_test_textbox.xml b/indra/newview/skins/default/xui/en/floater_test_textbox.xml
index 8dba05f1ee..3aeb7c93e7 100644
--- a/indra/newview/skins/default/xui/en/floater_test_textbox.xml
+++ b/indra/newview/skins/default/xui/en/floater_test_textbox.xml
@@ -10,83 +10,64 @@
<text
type="string"
length="1"
- height="10"
- layout="topleft"
- left="10"
- top="30"
- width="300">
- Bottom and left specified
- </text>
- <text
- type="string"
- length="1"
- height="10"
- layout="topleft"
- left_delta="200"
- top_delta="0"
- width="300">
- Bottom delta left delta
- </text>
- <text
- type="string"
- length="1"
- height="10"
+ height="90"
layout="topleft"
left="10"
- top="50"
- width="300">
- Bottom delta -20
- </text>
- <text
- type="string"
- length="1"
- height="10"
- layout="topleft"
- left_delta="0"
top_pad="30"
width="300">
First line of multiple lines
- Second line of multiple lines
+Second line of multiple lines
+Third line of multiple lines
+Fourth line of multiple lines
+Fifth line of multiple lines
</text>
<text
top_pad="10"
left="10"
- right="-10"
+ right="-10"
+ height="20"
follows="top|left"
font.name="SansSerifSmall"
name="test_text10"
tool_tip="text">
- SansSerifSmall. Русский 中文 (简体) The quick brown fox jumped over the lazy dog.
+ SansSerifSmall
+The 华文细黑 brown fox ヒラキjumped over the lazy dog.
</text>
<text
top_pad="10"
left="10"
- right="-10"
+ right="-10"
+ height="25"
follows="top|left"
- font.name="SansSerif"
+ font.name="SansSerifMedium"
name="test_text11"
tool_tip="text">
- SansSerif. Русский 中文 (简体) The quick brown fox jumped over the lazy dog.
+ SansSerif
+The 华文细黑 brown fox ヒラキjumped over the lazy dog.
</text>
<text
top_pad="10"
left="10"
- right="-10"
+ right="-10"
follows="top|left"
+ height="26"
font.name="SansSerifLarge"
name="test_text12"
tool_tip="text">
- SansSerifLarge. Русский 中文 (简体) The quick brown fox jumped over the lazy dog.
+ SansSerifLarge
+The 华文细黑 brown fox ヒラキjumped over the lazy dog.
</text>
<text
top_pad="10"
left="10"
- right="-10"
+ height="35"
+ right="-10"
follows="top|left"
font.name="SansSerifHuge"
name="test_text13"
tool_tip="text">
- SansSerifHuge. Русский 中文 (简体) The quick brown fox jumped over the lazy dog.
+ SansSerifHuge
+The 华文细黑 brown fox ヒラキjumped over the lazy dog.
</text>
<text
type="string"
@@ -113,27 +94,6 @@
SansSerif BOLD UNDERLINE
</text>
<text
- type="string"
- length="1"
- font="SansSerif"
- height="10"
- layout="topleft"
- left_delta="0"
- top_pad="10"
- width="300">
- SansSerif UNDERLINE
- </text>
- <text
- type="string"
- length="1"
- height="10"
- layout="topleft"
- left_delta="0"
- top_pad="10"
- width="300">
- Escaped greater than &gt;
- </text>
- <text
type="string"
length="1"
bottom="390"
@@ -142,8 +102,7 @@
left="10"
name="right_aligned_text"
width="380"
- halign="right"
- text_color="1 1 1 0.7"
+ halign="right"
top_pad="10">
Right aligned text
</text>
@@ -157,21 +116,19 @@
name="centered_text"
width="380"
halign="center"
- text_color="1 1 1 0.7"
top_pad="10">
Centered text
</text>
<text
type="string"
length="1"
- height="60"
+ height="60"
label="N"
layout="topleft"
left="10"
name="left_aligned_text"
width="380"
halign="left"
- text_color="1 1 1 0.7"
top_pad="10">
Left aligned text
</text>
@@ -184,7 +141,6 @@
left="10"
name="floater_map_north"
right="30"
- text_color="1 1 1 0.7"
top="370">
N
</text>
diff --git a/indra/newview/skins/default/xui/en/fonts.xml b/indra/newview/skins/default/xui/en/fonts.xml
index f3da62a896..ebbb53729d 100644
--- a/indra/newview/skins/default/xui/en/fonts.xml
+++ b/indra/newview/skins/default/xui/en/fonts.xml
@@ -144,18 +144,18 @@
/>
<font_size name="Huge"
comment="Size of huge font (points, or 1/72 of an inch)"
- size="15.0"
+ size="16.0"
/>
<font_size name="Large"
comment="Size of large font (points, or 1/72 of an inch)"
- size="10.0"
+ size="10.6"
/>
<font_size name="Medium"
comment="Size of medium font (points, or 1/72 of an inch)"
- size="9.0"
+ size="8.6"
/>
<font_size name="Small"
comment="Size of small font (points, or 1/72 of an inch)"
- size="7.8"
+ size="7.6"
/>
</fonts>
diff --git a/indra/newview/skins/default/xui/en/widgets/inspector.xml b/indra/newview/skins/default/xui/en/widgets/inspector.xml
new file mode 100644
index 0000000000..61950d7554
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/inspector.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<!-- See also settings.xml UIFloater* settings for configuration -->
+<inspector name="inspector"
+ bg_opaque_color="ToolTipBgColor"
+ background_visible="true"
+ bg_opaque_image="none"
+ bg_alpha_image="none"
+ />
diff --git a/indra/newview/tests/llmediadataclient_test.cpp b/indra/newview/tests/llmediadataclient_test.cpp
index 445ec7aa34..3ac631d96e 100644
--- a/indra/newview/tests/llmediadataclient_test.cpp
+++ b/indra/newview/tests/llmediadataclient_test.cpp
@@ -497,5 +497,38 @@ namespace tut
ensure("REF COUNT", o->getNumRefs(), 1);
}
-
+ template<> template<>
+ void mediadataclient_object_t::test<7>()
+ {
+ // Test LLMediaDataClient::isInQueue()
+ LOG_TEST(7);
+
+ LLMediaDataClientObject::ptr_t o1 = new LLMediaDataClientObjectTest(
+ _DATA(VALID_OBJECT_ID_1,"3.0","1.0"));
+ LLMediaDataClientObject::ptr_t o2 = new LLMediaDataClientObjectTest(
+ _DATA(VALID_OBJECT_ID_2,"1.0","1.0"));
+ int num_refs_start = o1->getNumRefs();
+ {
+ LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(NO_PERIOD,NO_PERIOD);
+
+ ensure("not in queue yet 1", ! mdc->isInQueue(o1));
+ ensure("not in queue yet 2", ! mdc->isInQueue(o2));
+
+ mdc->fetchMedia(o1);
+
+ ensure("is in queue", mdc->isInQueue(o1));
+ ensure("is not in queue", ! mdc->isInQueue(o2));
+
+ ::pump_timers();
+
+ ensure("not in queue anymore", ! mdc->isInQueue(o1));
+ ensure("still is not in queue", ! mdc->isInQueue(o2));
+
+ ensure("queue empty", mdc->isEmpty());
+ }
+
+ // Make sure everyone's destroyed properly
+ ensure("REF COUNT", o1->getNumRefs(), num_refs_start);
+
+ }
}