diff --git a/indra/llaudio/llaudioengine.cpp b/indra/llaudio/llaudioengine.cpp index ed06c85e1a..b92ccd1d77 100644 --- a/indra/llaudio/llaudioengine.cpp +++ b/indra/llaudio/llaudioengine.cpp @@ -592,7 +592,7 @@ LLAudioBuffer * LLAudioEngine::getFreeBuffer() if (buffer_id >= 0) { - llinfos << "Taking over unused buffer " << buffer_id << llendl; + lldebugs << "Taking over unused buffer " << buffer_id << llendl; //llinfos << "Flushing unused buffer!" << llendl; mBuffers[buffer_id]->mAudioDatap->mBufferp = NULL; delete mBuffers[buffer_id]; diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp index 0ed700b9da..0272c55db2 100644 --- a/indra/llcommon/llsys.cpp +++ b/indra/llcommon/llsys.cpp @@ -775,33 +775,6 @@ void LLMemoryInfo::stream(std::ostream& s) const #endif } -S32 LLDisplayInfo::getDisplayWidth() const -{ -#if LL_WINDOWS - return ::GetSystemMetrics(SM_CXVIRTUALSCREEN); -#elif LL_DARWIN - return 1024; //*FIXME -#elif LL_SOLARIS - return 1024; //*FIXME -#else - return 1024; //*FIXME -#endif -} - -S32 LLDisplayInfo::getDisplayHeight() const -{ -#if LL_WINDOWS - return ::GetSystemMetrics(SM_CYVIRTUALSCREEN); -#elif LL_DARWIN - return 768; //*FIXME -#elif LL_SOLARIS - return 768; //*FIXME -#else - return 768; //*FIXME -#endif -} - - std::ostream& operator<<(std::ostream& s, const LLOSInfo& info) { info.stream(s); diff --git a/indra/llcommon/llsys.h b/indra/llcommon/llsys.h index aa3fdd485b..f1dda1b2e2 100644 --- a/indra/llcommon/llsys.h +++ b/indra/llcommon/llsys.h @@ -122,22 +122,6 @@ public: U32 getPhysicalMemoryClamped() const; ///< Memory size in clamped bytes }; -//============================================================================= -// -// CLASS LLDisplayInfo -class LL_COMMON_API LLDisplayInfo - -/*! @brief Class to query the information about some display settings -*/ -{ -public: - LLDisplayInfo(){}; ///< Default constructor - - S32 getDisplayWidth() const; ///< display width - S32 getDisplayHeight() const; ///< display height - -}; - LL_COMMON_API std::ostream& operator<<(std::ostream& s, const LLOSInfo& info); LL_COMMON_API std::ostream& operator<<(std::ostream& s, const LLCPUInfo& info); LL_COMMON_API std::ostream& operator<<(std::ostream& s, const LLMemoryInfo& info); diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp index ce25ee32b3..c1d512e148 100644 --- a/indra/llui/llcombobox.cpp +++ b/indra/llui/llcombobox.cpp @@ -323,15 +323,19 @@ void LLComboBox::setValue(const LLSD& value) LLScrollListItem* item = mList->getFirstSelected(); if (item) { - setLabel( mList->getSelectedItemLabel() ); + setLabel(getSelectedItemLabel()); } mLastSelectedIndex = mList->getFirstSelectedIndex(); } + else + { + mLastSelectedIndex = -1; + } } const std::string LLComboBox::getSimple() const { - const std::string res = mList->getSelectedItemLabel(); + const std::string res = getSelectedItemLabel(); if (res.empty() && mAllowTextEntry) { return mTextEntry->getText(); @@ -410,7 +414,7 @@ BOOL LLComboBox::remove(S32 index) if (index < mList->getItemCount()) { mList->deleteSingleItem(index); - setLabel(mList->getSelectedItemLabel()); + setLabel(getSelectedItemLabel()); return TRUE; } return FALSE; @@ -451,7 +455,7 @@ BOOL LLComboBox::setCurrentByIndex( S32 index ) BOOL found = mList->selectNthItem( index ); if (found) { - setLabel(mList->getSelectedItemLabel()); + setLabel(getSelectedItemLabel()); mLastSelectedIndex = index; } return found; @@ -904,7 +908,7 @@ void LLComboBox::updateSelection() } else if (mList->selectItemByPrefix(left_wstring, FALSE)) { - LLWString selected_item = utf8str_to_wstring(mList->getSelectedItemLabel()); + LLWString selected_item = utf8str_to_wstring(getSelectedItemLabel()); LLWString wtext = left_wstring + selected_item.substr(left_wstring.size(), selected_item.size()); mTextEntry->setText(wstring_to_utf8str(wtext)); mTextEntry->setSelection(left_wstring.size(), mTextEntry->getWText().size()); @@ -1006,7 +1010,7 @@ BOOL LLComboBox::setCurrentByID(const LLUUID& id) if (found) { - setLabel(mList->getSelectedItemLabel()); + setLabel(getSelectedItemLabel()); mLastSelectedIndex = mList->getFirstSelectedIndex(); } @@ -1022,7 +1026,7 @@ BOOL LLComboBox::setSelectedByValue(const LLSD& value, BOOL selected) BOOL found = mList->setSelectedByValue(value, selected); if (found) { - setLabel(mList->getSelectedItemLabel()); + setLabel(getSelectedItemLabel()); } return found; } @@ -1084,10 +1088,19 @@ void LLIconsComboBox::setValue(const LLSD& value) LLScrollListItem* item = mList->getFirstSelected(); if (item) { - mButton->setImageOverlay(mList->getSelectedItemLabel(mIconColumnIndex), mButton->getImageOverlayHAlign()); - - setLabel(mList->getSelectedItemLabel(mLabelColumnIndex)); + setLabel(getSelectedItemLabel()); } mLastSelectedIndex = mList->getFirstSelectedIndex(); } + else + { + mLastSelectedIndex = -1; + } +} + +const std::string LLIconsComboBox::getSelectedItemLabel(S32 column) const +{ + mButton->setImageOverlay(LLComboBox::getSelectedItemLabel(mIconColumnIndex), mButton->getImageOverlayHAlign()); + + return LLComboBox::getSelectedItemLabel(mLabelColumnIndex); } diff --git a/indra/llui/llcombobox.h b/indra/llui/llcombobox.h index c694724248..965061ead2 100644 --- a/indra/llui/llcombobox.h +++ b/indra/llui/llcombobox.h @@ -150,7 +150,7 @@ public: // Get name of current item. Returns an empty string if not found. const std::string getSimple() const; // Get contents of column x of selected row - const std::string getSelectedItemLabel(S32 column = 0) const; + virtual const std::string getSelectedItemLabel(S32 column = 0) const; // Sets the label, which doesn't have to exist in the label. // This is probably a UI abuse. @@ -248,6 +248,7 @@ public: }; /*virtual*/ void setValue(const LLSD& value); + /*virtual*/ const std::string getSelectedItemLabel(S32 column = 0) const; private: enum EColumnIndex diff --git a/indra/llui/llflatlistview.cpp b/indra/llui/llflatlistview.cpp index 2481249f91..2e5aeec41d 100644 --- a/indra/llui/llflatlistview.cpp +++ b/indra/llui/llflatlistview.cpp @@ -492,6 +492,12 @@ void LLFlatListView::onItemMouseClick(item_pair_t* item_pair, MASK mask) { if (!item_pair) return; + if (!item_pair->first) + { + llwarning("Attempt to selet an item pair containing null panel item", 0); + return; + } + setFocus(TRUE); bool select_item = !isSelected(item_pair); diff --git a/indra/llwindow/llwindow.cpp b/indra/llwindow/llwindow.cpp index 1c6c9e6e9d..b77deb003f 100644 --- a/indra/llwindow/llwindow.cpp +++ b/indra/llwindow/llwindow.cpp @@ -407,3 +407,30 @@ BOOL LLWindowManager::isWindowValid(LLWindow *window) { return sWindowList.find(window) != sWindowList.end(); } + +S32 LLDisplayInfo::getDisplayWidth() const +{ +#if LL_WINDOWS + return LLWindowWin32::getDisplayWidth(); +#elif LL_DARWIN + return LLWindowMacOSX::getDisplayWidth(); +#elif LL_SDL + return LLWindowSDL::getDisplayWidth(); +#else + return 1024; //*FIXME +#endif +} + +S32 LLDisplayInfo::getDisplayHeight() const +{ +#if LL_WINDOWS + return LLWindowWin32::getDisplayHeight(); +#elif LL_DARWIN + return LLWindowMacOSX::getDisplayHeight(); +#elif LL_SDL + return LLWindowSDL::getDisplayHeight(); +#else + return 768; //*FIXME +#endif +} + diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h index 55b221e716..b769f5071b 100644 --- a/indra/llwindow/llwindow.h +++ b/indra/llwindow/llwindow.h @@ -281,4 +281,19 @@ extern const std::string gURLProtocolWhitelistHandler[]; void simpleEscapeString ( std::string& stringIn ); +//============================================================================= +// +// CLASS LLDisplayInfo +class LLDisplayInfo + +/*! @brief Class to query the information about some display settings +*/ +{ +public: + LLDisplayInfo(){}; ///< Default constructor + + S32 getDisplayWidth() const; ///< display width + S32 getDisplayHeight() const; ///< display height +}; + #endif // _LL_window_h_ diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h index ed5d7b1e74..ed8c874dcb 100644 --- a/indra/llwindow/llwindowmacosx-objc.h +++ b/indra/llwindow/llwindowmacosx-objc.h @@ -40,4 +40,5 @@ void setupCocoa(); CursorRef createImageCursor(const char *fullpath, int hotspotX, int hotspotY); OSErr releaseImageCursor(CursorRef ref); OSErr setImageCursor(CursorRef ref); - +void getScreenSize(int* width, int* height); +void getVisibleScreen(int *x, int *y, int* width, int* height); diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm index 59b25e1726..5cab2619fd 100644 --- a/indra/llwindow/llwindowmacosx-objc.mm +++ b/indra/llwindow/llwindowmacosx-objc.mm @@ -116,3 +116,22 @@ OSErr setImageCursor(CursorRef ref) return noErr; } +void getScreenSize(int* width, int* height) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + NSRect screen_rect = [[NSScreen mainScreen] frame]; + if (width) *width = (int)(screen_rect.size.width); + if (height) *height = (int)(screen_rect.size.height); + [pool release]; +} + +void getVisibleScreen(int *x, int *y, int* width, int* height) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + NSRect visible_rect = [[NSScreen mainScreen] visibleFrame]; + if (width) *width = (int)(visible_rect.size.width); + if (height) *height = (int)(visible_rect.size.height); + if (x) *x = (int)(visible_rect.origin.x); + if (y) *y = (int)(visible_rect.origin.y); + [pool release]; +} diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index ad97bc45fc..924acaf148 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -1122,7 +1122,33 @@ BOOL LLWindowMacOSX::getMaximized() BOOL LLWindowMacOSX::maximize() { - // TODO + if (mWindow) + { + // *HACK: Because Mac OSX doesn't have a concept of a "maximized" window, we just + // stretch it out to the visible screen size. + Rect win_rect; + + int visible_x; + int visible_y; + int visible_width; + int visible_height; + int screen_width; + int screen_height; + + getScreenSize(&screen_width, &screen_height); + getVisibleScreen(&visible_x, &visible_y, &visible_width, &visible_height); + + int mac_os_menu_bar_height = screen_height - (visible_height + visible_y); + ::SetRect(&win_rect, + visible_x, + mac_os_menu_bar_height, + visible_width + visible_x, + visible_height + mac_os_menu_bar_height); + + ::SetWindowBounds(mWindow, kWindowStructureRgn, &win_rect); + + return TRUE; + } return FALSE; } @@ -3464,6 +3490,26 @@ MASK LLWindowMacOSX::modifiersToMask(SInt16 modifiers) return mask; } +// static +S32 LLWindowMacOSX::getDisplayWidth() +{ + S32 width = 1024; + // Need to invoke cocoa before use getScreenSize() + setupCocoa(); + getScreenSize(&width, NULL); + return width; +} + +// static +S32 LLWindowMacOSX::getDisplayHeight() +{ + S32 height = 768; + // Need to invoke cocoa before use getScreenSize() + setupCocoa(); + getScreenSize(NULL, &height); + return height; +} + #if LL_OS_DRAGDROP_ENABLED OSErr LLWindowMacOSX::dragTrackingHandler(DragTrackingMessage message, WindowRef theWindow, diff --git a/indra/llwindow/llwindowmacosx.h b/indra/llwindow/llwindowmacosx.h index 7c6b324029..86036a261c 100644 --- a/indra/llwindow/llwindowmacosx.h +++ b/indra/llwindow/llwindowmacosx.h @@ -123,6 +123,8 @@ public: // Provide native key event data /*virtual*/ LLSD getNativeKeyData(); + static S32 getDisplayWidth(); + static S32 getDisplayHeight(); protected: LLWindowMacOSX(LLWindowCallbacks* callbacks, diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp index 1f705f9e60..cb4e04511c 100644 --- a/indra/llwindow/llwindowsdl.cpp +++ b/indra/llwindow/llwindowsdl.cpp @@ -187,6 +187,47 @@ Display* LLWindowSDL::get_SDL_Display(void) } #endif // LL_X11 +// static +S32 LLWindowSDL::getDisplayWidth() +{ +#if LL_GTK + if (LLWindowSDL::ll_try_gtk_init()) + { + return gdk_screen_width(); + } +#endif // LL_GTK + +#if LL_X11 + Display *display = XOpenDisplay(NULL); + int screen_num = DefaultScreen(display); + S32 width = DisplayWidth(display, screen_num); + XCloseDisplay(display); + return width; +#endif //LL_X11 + + return 1024; +} + +// static +S32 LLWindowSDL::getDisplayHeight() +{ +#if LL_GTK + if (LLWindowSDL::ll_try_gtk_init()) + { + return gdk_screen_height(); + } +#endif // LL_GTK + +#if LL_X11 + Display *display = XOpenDisplay(NULL); + int screen_num = DefaultScreen(display); + S32 height = DisplayHeight(display, screen_num); + XCloseDisplay(display); + return height; +#endif //LL_X11 + + return 768; +} LLWindowSDL::LLWindowSDL(LLWindowCallbacks* callbacks, const std::string& title, S32 x, S32 y, S32 width, @@ -909,7 +950,68 @@ BOOL LLWindowSDL::getMaximized() if (mWindow) { - // TODO +#if LL_X11 + if (mSDL_Display) + { + maybe_lock_display(); + + // Return data in the specified format, XA_ATOM. + U8* prop; + // Actual format of the property. + int format; + // Actual number of items stored in the prop return data. + unsigned long nitems; + // Number of bytes remaining to be read in the property if a partial read was performed. + unsigned long bytes_after; + // Atom identifier that defines the actual type of the property. + Atom type; + + // Atom used to obtain list of hints describing the window state. + Atom wm_state = XInternAtom(mSDL_Display, "_NET_WM_STATE", False); + + // Atoms indicates that the window is vertically/horizontally maximized. + Atom max_vert = XInternAtom(mSDL_Display, "_NET_WM_STATE_MAXIMIZED_VERT", False); + Atom max_horz = XInternAtom(mSDL_Display, "_NET_WM_STATE_MAXIMIZED_HORZ", False); + + // How many atoms in which we interested are present in list of hints. + U32 pass = 0; + + do + { + nitems = 0; + bytes_after = 0; + type = None; + if ( (XGetWindowProperty (mSDL_Display, + mSDL_XWindowID, + wm_state, + 0, UINT_MAX, + False, XA_ATOM, + &type, &format, + &nitems, &bytes_after, + &prop) == Success) + && type != None ) + { + Atom *atoms = (Atom *)prop; + for (unsigned long i=0; i 0); + + result = (pass == 2); + + maybe_unlock_display(); + } +#endif // LL_X11 } return(result); @@ -917,7 +1019,103 @@ BOOL LLWindowSDL::getMaximized() BOOL LLWindowSDL::maximize() { - // TODO +#if LL_X11 + if (mSDL_Display && !mFullscreen) + { + maybe_lock_display(); + + BOOL is_maximize_allowed = FALSE; + + // Check if maximize is allowed + { + // Return data in the specified format, XA_ATOM. + U8* prop; + // Actual format of the property. + int format; + // Actual number of items stored in the prop return data. + unsigned long nitems; + // Number of bytes remaining to be read in the property if a partial read was performed. + unsigned long bytes_after; + // Atom identifier that defines the actual type of the property. + Atom type; + + // Atom used to obtain a list of atoms indicating user operations that the Window Manager supports for this window. + Atom allowed_act = XInternAtom(mSDL_Display, "_NET_WM_ALLOWED_ACTIONS", False); + + // Atoms that indicates that the window may be vertically/horizontally maximized. + Atom max_vert_act = XInternAtom(mSDL_Display, "_NET_WM_ACTION_MAXIMIZE_HORZ", False); + Atom max_horz_act = XInternAtom(mSDL_Display, "_NET_WM_ACTION_MAXIMIZE_VERT", False); + + // How many atoms in which we interested are present in list of hints. + U32 pass = 0; + + do + { + nitems = 0; + bytes_after = 0; + type = None; + if ( (XGetWindowProperty (mSDL_Display, + mSDL_XWindowID, + allowed_act, + 0, UINT_MAX, + False, XA_ATOM, + &type, &format, + &nitems, &bytes_after, + &prop) == Success) + && type != None ) + { + Atom *atoms = (Atom *)prop; + for (unsigned long i=0; i 0); + + is_maximize_allowed = (pass == 2); + } + + // Send maximize event to X11 system + if (is_maximize_allowed) + { + XEvent xev; + + // Atom describing the window state. + Atom wm_state = XInternAtom(mSDL_Display, "_NET_WM_STATE", False); + + // Atoms indicates that the window is vertically/horizontally maximized. + Atom max_vert = XInternAtom(mSDL_Display, "_NET_WM_STATE_MAXIMIZED_VERT", False); + Atom max_horz = XInternAtom(mSDL_Display, "_NET_WM_STATE_MAXIMIZED_HORZ", False); + + memset(&xev, 0, sizeof(xev)); + xev.type = ClientMessage; + xev.xclient.window = mSDL_XWindowID; + xev.xclient.message_type = wm_state; + xev.xclient.format = 32; + xev.xclient.data.l[0] = 1; // add/set property + xev.xclient.data.l[1] = max_vert; + xev.xclient.data.l[2] = max_horz; + xev.xclient.data.l[3] = 0; + xev.xclient.data.l[4] = 0; + + XSendEvent(mSDL_Display, + DefaultRootWindow(mSDL_Display), + False, + SubstructureNotifyMask, &xev); + } + + maybe_unlock_display(); + return is_maximize_allowed; + } +#endif // LL_X11 return FALSE; } diff --git a/indra/llwindow/llwindowsdl.h b/indra/llwindow/llwindowsdl.h index e6bdd46a77..2311a361fa 100644 --- a/indra/llwindow/llwindowsdl.h +++ b/indra/llwindow/llwindowsdl.h @@ -148,6 +148,9 @@ public: static Display* get_SDL_Display(void); #endif // LL_X11 + static S32 getDisplayWidth(); + static S32 getDisplayHeight(); + protected: LLWindowSDL(LLWindowCallbacks* callbacks, const std::string& title, int x, int y, int width, int height, U32 flags, diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index c80392ad45..4be5d06c2b 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -3714,5 +3714,16 @@ std::vector LLWindowWin32::getDynamicFallbackFontList() return std::vector(); } +// static +S32 LLWindowWin32::getDisplayWidth() +{ + return ::GetSystemMetrics(SM_CXVIRTUALSCREEN); +} + +// static +S32 LLWindowWin32::getDisplayHeight() +{ + return ::GetSystemMetrics(SM_CYVIRTUALSCREEN); +} #endif // LL_WINDOWS diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h index 9d57735772..c221ec0192 100644 --- a/indra/llwindow/llwindowwin32.h +++ b/indra/llwindow/llwindowwin32.h @@ -120,6 +120,9 @@ public: static std::vector getDynamicFallbackFontList(); + static S32 getDisplayWidth(); + static S32 getDisplayHeight(); + protected: LLWindowWin32(LLWindowCallbacks* callbacks, const std::string& title, const std::string& name, int x, int y, int width, int height, U32 flags, diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index f08d8decfe..f686eccf37 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -494,11 +494,12 @@ bool LLWearableHoldingPattern::pollFetchCompletion() bool completed = isFetchCompleted(); bool timed_out = isTimedOut(); bool done = completed || timed_out; - - llinfos << "polling, done status: " << completed << " timed out " << timed_out << " elapsed " << mWaitTime.getElapsedTimeF32() << llendl; if (done) { + llinfos << "polling, done status: " << completed << " timed out " << timed_out + << " elapsed " << mWaitTime.getElapsedTimeF32() << llendl; + mFired = true; if (timed_out) diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index e3bfb823d0..abac1164f9 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -307,7 +307,7 @@ static std::string gLaunchFileOnQuit; // Used on Win32 for other apps to identify our window (eg, win_setup) const char* const VIEWER_WINDOW_CLASSNAME = "Second Life"; static const S32 FIRST_RUN_WINDOW_WIDTH = 1024; -static const S32 FIRST_RUN_WINDOW_HRIGHT = 768; +static const S32 FIRST_RUN_WINDOW_HIGHT = 768; //---------------------------------------------------------------------------- // List of entries from strings.xml to always replace @@ -2407,12 +2407,12 @@ bool LLAppViewer::initWindow() if (first_run)//for first login { window_width = FIRST_RUN_WINDOW_WIDTH;//yep hardcoded - window_height = FIRST_RUN_WINDOW_HRIGHT; + window_height = FIRST_RUN_WINDOW_HIGHT; //if screen resolution is lower then 1024*768 then show maximized LLDisplayInfo display_info; if(display_info.getDisplayWidth() <= FIRST_RUN_WINDOW_WIDTH - || display_info.getDisplayHeight()<=FIRST_RUN_WINDOW_HRIGHT) + || display_info.getDisplayHeight()<=FIRST_RUN_WINDOW_HIGHT) { show_maximized = true; } diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index 26c6db9652..26a179074d 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -86,6 +86,7 @@ static std::string OWNER_ONLINE = "0"; static std::string OWNER_OFFLINE = "1"; static std::string OWNER_GROUP = "2"; +static std::string MATURITY = "[MATURITY]"; // constants used in callbacks below - syntactic sugar. static const BOOL BUY_GROUP_LAND = TRUE; @@ -102,6 +103,22 @@ public: virtual void changed() { LLFloaterLand::refreshAll(); } }; +// class needed to get full access to textbox inside checkbox, because LLCheckBoxCtrl::setLabel() has string as its argument. +// It was introduced while implementing EXT-4706 +class LLCheckBoxWithTBAcess : public LLCheckBoxCtrl +{ +public: + LLTextBox* getTextBox() + { + return mLabel; + } +}; + +// inserts maturity info(icon and text) into target textbox +// names_floater - pointer to floater which contains strings with maturity icons filenames +// str_to_parse is string in format "txt1[MATURITY]txt2" where maturity icon and text will be inserted instead of [MATURITY] +void insert_maturity_into_textbox(LLTextBox* target_textbox, LLFloater* names_floater, std::string str_to_parse); + //--------------------------------------------------------------------------- // LLFloaterLand //--------------------------------------------------------------------------- @@ -554,7 +571,7 @@ void LLPanelLandGeneral::refresh() if (regionp) { - mContentRating->setText(regionp->getSimAccessString()); + insert_maturity_into_textbox(mContentRating, gFloaterView->getParentFloater(this), MATURITY); mLandType->setText(regionp->getSimProductName()); } @@ -2058,8 +2075,14 @@ void LLPanelLandOptions::refresh() { // not teen so fill in the data for the maturity control mMatureCtrl->setVisible(TRUE); - mMatureCtrl->setLabel(getString("mature_check_mature")); - mMatureCtrl->setToolTip(getString("mature_check_mature_tooltip")); + LLStyle::Params style; + style.image(LLUI::getUIImage(gFloaterView->getParentFloater(this)->getString("maturity_icon_moderate"))); + LLCheckBoxWithTBAcess* fullaccess_mature_ctrl = (LLCheckBoxWithTBAcess*)mMatureCtrl; + fullaccess_mature_ctrl->getTextBox()->setText(std::string("icon"),style); + fullaccess_mature_ctrl->getTextBox()->appendText(getString("mature_check_mature"), false); + fullaccess_mature_ctrl->setToolTip(getString("mature_check_mature_tooltip")); + fullaccess_mature_ctrl->reshape(fullaccess_mature_ctrl->getRect().getWidth(), fullaccess_mature_ctrl->getRect().getHeight(), FALSE); + // they can see the checkbox, but its disposition depends on the // state of the region LLViewerRegion* regionp = LLViewerParcelMgr::getInstance()->getSelectionRegion(); @@ -2460,19 +2483,26 @@ void LLPanelLandAccess::refresh() } } + LLCheckBoxWithTBAcess* maturity_checkbox = (LLCheckBoxWithTBAcess*) getChild( "public_access"); LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion(); if(region) { - std::string region_access = "("; - region_access += region->getSimAccessString(); - region_access += ")"; - childSetLabelArg( "public_access", "[MATURITY]", region_access ); + LLTextBox* maturity_textbox = maturity_checkbox->getTextBox(); + insert_maturity_into_textbox(maturity_textbox, gFloaterView->getParentFloater(this), getString("allow_public_access")); + maturity_checkbox->reshape(maturity_checkbox->getRect().getWidth(), maturity_checkbox->getRect().getHeight(), FALSE); } else { - childSetLabelArg( "public_access", "[MATURITY]", std::string() ); - } + std::string maturity_string = getString("allow_public_access"); + size_t maturity_pos = maturity_string.find(MATURITY); + if (maturity_pos != std::string::npos) + { + maturity_string.replace(maturity_pos, MATURITY.length(), std::string("")); + } + + maturity_checkbox->setLabel(maturity_string); + } if(parcel->getRegionDenyAnonymousOverride()) { @@ -2858,7 +2888,7 @@ void LLPanelLandCovenant::refresh() LLTextBox* region_maturity = getChild("region_maturity_text"); if (region_maturity) { - region_maturity->setText(region->getSimAccessString()); + insert_maturity_into_textbox(region_maturity, gFloaterView->getParentFloater(this), MATURITY); } LLTextBox* resellable_clause = getChild("resellable_clause"); @@ -2939,3 +2969,51 @@ void LLPanelLandCovenant::updateEstateOwnerName(const std::string& name) if (editor) editor->setText(name); } } + +// inserts maturity info(icon and text) into target textbox +// names_floater - pointer to floater which contains strings with maturity icons filenames +// str_to_parse is string in format "txt1[MATURITY]txt2" where maturity icon and text will be inserted instead of [MATURITY] +void insert_maturity_into_textbox(LLTextBox* target_textbox, LLFloater* names_floater, std::string str_to_parse) +{ + LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion(); + if (!region) + return; + + LLStyle::Params style; + + U8 sim_access = region->getSimAccess(); + + switch(sim_access) + { + case SIM_ACCESS_PG: + style.image(LLUI::getUIImage(names_floater->getString("maturity_icon_general"))); + break; + + case SIM_ACCESS_ADULT: + style.image(LLUI::getUIImage(names_floater->getString("maturity_icon_adult"))); + break; + + case SIM_ACCESS_MATURE: + style.image(LLUI::getUIImage(names_floater->getString("maturity_icon_moderate"))); + break; + + default: + break; + } + + size_t maturity_pos = str_to_parse.find(MATURITY); + + if (maturity_pos == std::string::npos) + { + return; + } + + std::string text_before_rating = str_to_parse.substr(0, maturity_pos); + std::string text_after_rating = str_to_parse.substr(maturity_pos + MATURITY.length()); + + target_textbox->setText(text_before_rating); + // any text may be here instead of "icon" except "" + target_textbox->appendText(std::string("icon"), false, style); + target_textbox->appendText(LLViewerParcelMgr::getInstance()->getSelectionRegion()->getSimAccessString(), false); + target_textbox->appendText(text_after_rating, false); +} diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp index cc807c2370..23062bafec 100644 --- a/indra/newview/llfolderview.cpp +++ b/indra/newview/llfolderview.cpp @@ -837,11 +837,14 @@ void LLFolderView::sanitizeSelection() void LLFolderView::clearSelection() { - if (mSelectedItems.size() > 0) + for (selected_items_t::const_iterator item_it = mSelectedItems.begin(); + item_it != mSelectedItems.end(); + ++item_it) { - recursiveDeselect(FALSE); - mSelectedItems.clear(); + (*item_it)->setUnselected(); } + + mSelectedItems.clear(); mSelectThisID.setNull(); } diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp index 76607e4874..d3e3d2b57b 100644 --- a/indra/newview/llfolderviewitem.cpp +++ b/indra/newview/llfolderviewitem.cpp @@ -121,7 +121,6 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p) mHasVisibleChildren(FALSE), mIndentation(0), mItemHeight(p.item_height), - mNumDescendantsSelected(0), mPassedFilter(FALSE), mLastFilterGeneration(-1), mStringMatchOffset(std::string::npos), @@ -497,22 +496,6 @@ BOOL LLFolderViewItem::changeSelection(LLFolderViewItem* selection, BOOL selecte return FALSE; } -void LLFolderViewItem::recursiveDeselect(BOOL deselect_self) -{ - if (mIsSelected && deselect_self) - { - mIsSelected = FALSE; - - // update ancestors' count of selected descendents - LLFolderViewFolder* parent_folder = getParentFolder(); - while(parent_folder) - { - parent_folder->mNumDescendantsSelected--; - parent_folder = parent_folder->getParentFolder(); - } - } -} - BOOL LLFolderViewItem::isMovable() { @@ -1459,7 +1442,6 @@ BOOL LLFolderViewFolder::setSelection(LLFolderViewItem* selection, BOOL openitem { rv = TRUE; child_selected = TRUE; - mNumDescendantsSelected++; } } for (items_t::iterator iter = mItems.begin(); @@ -1470,7 +1452,6 @@ BOOL LLFolderViewFolder::setSelection(LLFolderViewItem* selection, BOOL openitem { rv = TRUE; child_selected = TRUE; - mNumDescendantsSelected++; } } if(openitem && child_selected) @@ -1503,14 +1484,6 @@ BOOL LLFolderViewFolder::changeSelection(LLFolderViewItem* selection, folders_t::iterator fit = iter++; if((*fit)->changeSelection(selection, selected)) { - if (selected) - { - mNumDescendantsSelected++; - } - else - { - mNumDescendantsSelected--; - } rv = TRUE; } } @@ -1520,14 +1493,6 @@ BOOL LLFolderViewFolder::changeSelection(LLFolderViewItem* selection, items_t::iterator iit = iter++; if((*iit)->changeSelection(selection, selected)) { - if (selected) - { - mNumDescendantsSelected++; - } - else - { - mNumDescendantsSelected--; - } rv = TRUE; } } @@ -1544,7 +1509,6 @@ S32 LLFolderViewFolder::extendSelection(LLFolderViewItem* selection, LLFolderVie { folders_t::iterator fit = iter++; num_selected += (*fit)->extendSelection(selection, last_selected, selected_items); - mNumDescendantsSelected += num_selected; } // handle selection of our immediate children... @@ -1637,7 +1601,6 @@ S32 LLFolderViewFolder::extendSelection(LLFolderViewItem* selection, LLFolderVie if (item->changeSelection(item, TRUE)) { selected_items.put(item); - mNumDescendantsSelected++; num_selected++; } } @@ -1648,7 +1611,6 @@ S32 LLFolderViewFolder::extendSelection(LLFolderViewItem* selection, LLFolderVie if (selection->changeSelection(selection, TRUE)) { selected_items.put(selection); - mNumDescendantsSelected++; num_selected++; } } @@ -1656,47 +1618,6 @@ S32 LLFolderViewFolder::extendSelection(LLFolderViewItem* selection, LLFolderVie return num_selected; } -void LLFolderViewFolder::recursiveDeselect(BOOL deselect_self) -{ - // make sure we don't have negative values - llassert(mNumDescendantsSelected >= 0); - - if (mIsSelected && deselect_self) - { - mIsSelected = FALSE; - - // update ancestors' count of selected descendents - LLFolderViewFolder* parent_folder = getParentFolder(); - while(parent_folder) - { - parent_folder->mNumDescendantsSelected--; - parent_folder = parent_folder->getParentFolder(); - } - } - - if (0 == mNumDescendantsSelected) - { - return; - } - - for (items_t::iterator iter = mItems.begin(); - iter != mItems.end();) - { - items_t::iterator iit = iter++; - LLFolderViewItem* item = (*iit); - item->recursiveDeselect(TRUE); - } - - for (folders_t::iterator iter = mFolders.begin(); - iter != mFolders.end();) - { - folders_t::iterator fit = iter++; - LLFolderViewFolder* folder = (*fit); - folder->recursiveDeselect(TRUE); - } - -} - void LLFolderViewFolder::destroyView() { for (items_t::iterator iter = mItems.begin(); @@ -1730,8 +1651,6 @@ BOOL LLFolderViewFolder::removeItem(LLFolderViewItem* item) { if(item->remove()) { - //RN: this seem unneccessary as remove() moves to trash - //removeView(item); return TRUE; } return FALSE; @@ -1746,7 +1665,6 @@ void LLFolderViewFolder::removeView(LLFolderViewItem* item) return; } // deselect without traversing hierarchy - item->recursiveDeselect(TRUE); getRoot()->removeFromSelectionList(item); extractItem(item); delete item; diff --git a/indra/newview/llfolderviewitem.h b/indra/newview/llfolderviewitem.h index be8e73a5a9..655ad89e99 100644 --- a/indra/newview/llfolderviewitem.h +++ b/indra/newview/llfolderviewitem.h @@ -150,7 +150,6 @@ protected: BOOL mHasVisibleChildren; S32 mIndentation; S32 mItemHeight; - S32 mNumDescendantsSelected; BOOL mPassedFilter; S32 mLastFilterGeneration; std::string::size_type mStringMatchOffset; @@ -231,9 +230,6 @@ public: // this method is used to group select items virtual S32 extendSelection(LLFolderViewItem* selection, LLFolderViewItem* last_selected, LLDynamicArray& items){ return FALSE; } - // this method is used to group select items - virtual void recursiveDeselect(BOOL deselect_self); - // gets multiple-element selection virtual BOOL getSelectionList(std::set &selection) const {return TRUE;} @@ -246,10 +242,10 @@ public: // destroys this item recursively virtual void destroyView(); - S32 getNumSelectedDescendants() { return mNumDescendantsSelected; } - BOOL isSelected() { return mIsSelected; } + void setUnselected() { mIsSelected = FALSE; } + void setIsCurSelection(BOOL select) { mIsCurSelection = select; } BOOL getIsCurSelection() { return mIsCurSelection; } @@ -441,8 +437,6 @@ public: // this method is used to group select items virtual S32 extendSelection(LLFolderViewItem* selection, LLFolderViewItem* last_selected, LLDynamicArray& items); - virtual void recursiveDeselect(BOOL deselect_self); - // Returns true is this object and all of its children can be removed. virtual BOOL isRemovable(); diff --git a/indra/newview/llgrouplist.cpp b/indra/newview/llgrouplist.cpp index bcfb516b81..8a056f836f 100644 --- a/indra/newview/llgrouplist.cpp +++ b/indra/newview/llgrouplist.cpp @@ -127,7 +127,7 @@ BOOL LLGroupList::handleRightMouseDown(S32 x, S32 y, MASK mask) BOOL handled = LLUICtrl::handleRightMouseDown(x, y, mask); LLMenuGL* context_menu = (LLMenuGL*)mContextMenuHandle.get(); - if (context_menu) + if (context_menu && size() > 0) { context_menu->buildDrawLabels(); context_menu->updateParent(LLMenuGL::sMenuContainer); diff --git a/indra/newview/llloginhandler.cpp b/indra/newview/llloginhandler.cpp index 1be3430e07..e3817eecc4 100644 --- a/indra/newview/llloginhandler.cpp +++ b/indra/newview/llloginhandler.cpp @@ -35,6 +35,7 @@ #include "llloginhandler.h" // viewer includes +#include "lllogininstance.h" // to check if logged in yet #include "llpanellogin.h" // save_password_to_disk() #include "llstartup.h" // getStartupState() #include "llurlsimstring.h" @@ -169,6 +170,13 @@ bool LLLoginHandler::handle(const LLSD& tokens, const LLSD& query_map, LLMediaCtrl* web) { + // do nothing if we are already logged in + if (LLLoginInstance::getInstance()->authSuccess()) + { + LL_WARNS_ONCE("SLURL") << "Already logged in! Ignoring login SLapp." << LL_ENDL; + return true; + } + if (tokens.size() == 1 && tokens[0].asString() == "show") { diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp index bf33d8527e..05cb6ddc4a 100644 --- a/indra/newview/llmediactrl.cpp +++ b/indra/newview/llmediactrl.cpp @@ -80,8 +80,8 @@ LLMediaCtrl::LLMediaCtrl( const Params& p) : mForceUpdate( false ), mOpenLinksInExternalBrowser( false ), mOpenLinksInInternalBrowser( false ), - mTrusted( false ), mHomePageUrl( "" ), + mTrusted(false), mIgnoreUIScale( true ), mAlwaysRefresh( false ), mMediaSource( 0 ), @@ -183,6 +183,10 @@ void LLMediaCtrl::setOpenInInternalBrowser( bool valIn ) //////////////////////////////////////////////////////////////////////////////// void LLMediaCtrl::setTrusted( bool valIn ) { + if(mMediaSource) + { + mMediaSource->setTrustedBrowser(valIn); + } mTrusted = valIn; } @@ -632,6 +636,7 @@ bool LLMediaCtrl::ensureMediaSourceExists() mMediaSource->setVisible( getVisible() ); mMediaSource->addObserver( this ); mMediaSource->setBackgroundColor( getBackgroundColor() ); + mMediaSource->setTrustedBrowser(mTrusted); if(mClearCache) { mMediaSource->clearCache(); @@ -946,7 +951,6 @@ void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) case MEDIA_EVENT_CLICK_LINK_NOFOLLOW: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CLICK_LINK_NOFOLLOW, uri is " << self->getClickURL() << LL_ENDL; - onClickLinkNoFollow(self); }; break; @@ -1062,15 +1066,6 @@ void LLMediaCtrl::clickLinkWithTarget(const std::string& url, const S32& target_ } } -//////////////////////////////////////////////////////////////////////////////// -// -void LLMediaCtrl::onClickLinkNoFollow( LLPluginClassMedia* self ) -{ - // let the dispatcher handle blocking/throttling of SLURLs - std::string url = self->getClickURL(); - LLURLDispatcher::dispatch(url, this, mTrusted); -} - //////////////////////////////////////////////////////////////////////////////// // std::string LLMediaCtrl::getCurrentNavUrl() diff --git a/indra/newview/llmediactrl.h b/indra/newview/llmediactrl.h index 60e0c4073b..e55d2f7cd0 100644 --- a/indra/newview/llmediactrl.h +++ b/indra/newview/llmediactrl.h @@ -164,7 +164,6 @@ public: // handlers for individual events (could be done inside the switch in handleMediaEvent, they're just individual functions for clarity) void onClickLinkHref( LLPluginClassMedia* self ); - void onClickLinkNoFollow( LLPluginClassMedia* self ); protected: void convertInputCoords(S32& x, S32& y); diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp index 9f24ddc799..021e1f5159 100644 --- a/indra/newview/llpanelclassified.cpp +++ b/indra/newview/llpanelclassified.cpp @@ -114,6 +114,23 @@ public: }; static LLDispatchClassifiedClickThrough sClassifiedClickThrough; +// Just to debug errors. Can be thrown away later. +class LLClassifiedClickMessageResponder : public LLHTTPClient::Responder +{ + LOG_CLASS(LLClassifiedClickMessageResponder); + +public: + // If we get back an error (not found, etc...), handle it here + virtual void errorWithContent( + U32 status, + const std::string& reason, + const LLSD& content) + { + llwarns << "Sending click message failed (" << status << "): [" << reason << "]" << llendl; + llwarns << "Content: [" << content << "]" << llendl; + } +}; + /* Re-expose this if we need to have classified ad HTML detail pages. JC @@ -1237,7 +1254,7 @@ void LLPanelClassifiedInfo::reshape(S32 width, S32 height, BOOL called_from_pare void LLPanelClassifiedInfo::onOpen(const LLSD& key) { - LLUUID avatar_id = key["avatar_id"]; + LLUUID avatar_id = key["classified_creator_id"]; if(avatar_id.isNull()) { return; @@ -1255,9 +1272,12 @@ void LLPanelClassifiedInfo::onOpen(const LLSD& key) scrollToTop(); setClassifiedId(key["classified_id"]); - setClassifiedName(key["name"]); - setDescription(key["desc"]); - setSnapshotId(key["snapshot_id"]); + setClassifiedName(key["classified_name"]); + setDescription(key["classified_desc"]); + setSnapshotId(key["classified_snapshot_id"]); + setFromSearch(key["from_search"]); + + llinfos << "Opening classified [" << getClassifiedName() << "] (" << getClassifiedId() << ")" << llendl; LLAvatarPropertiesProcessor::getInstance()->addObserver(getAvatarId(), this); LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoRequest(getClassifiedId()); @@ -1274,6 +1294,10 @@ void LLPanelClassifiedInfo::onOpen(const LLSD& key) LLHTTPClient::post(url, body, new LLClassifiedStatsResponder(getClassifiedId())); } + // Update classified click stats. + // *TODO: Should we do this when opening not from search? + sendClickMessage("profile"); + setInfoLoaded(false); } @@ -1289,6 +1313,8 @@ void LLPanelClassifiedInfo::processProperties(void* data, EAvatarProcessorType t setSnapshotId(c_info->snapshot_id); setParcelId(c_info->parcel_id); setPosGlobal(c_info->pos_global); + setSimName(c_info->sim_name); + setClassifiedLocation(createLocationText(c_info->parcel_name, c_info->sim_name, c_info->pos_global)); childSetValue("category", LLClassifiedInfo::sCategories[c_info->category]); @@ -1299,6 +1325,8 @@ void LLPanelClassifiedInfo::processProperties(void* data, EAvatarProcessorType t bool mature = is_cf_mature(c_info->flags); childSetValue("content_type", mature ? mature_str : pg_str); + getChild("content_type_moderate")->setVisible(mature); + getChild("content_type_general")->setVisible(!mature); std::string auto_renew_str = is_cf_auto_renew(c_info->flags) ? getString("auto_renew_on") : getString("auto_renew_off"); @@ -1323,7 +1351,19 @@ void LLPanelClassifiedInfo::resetData() setClassifiedLocation(LLStringUtil::null); setClassifiedId(LLUUID::null); setSnapshotId(LLUUID::null); - mPosGlobal.clearVec(); + setPosGlobal(LLVector3d::zero); + setParcelId(LLUUID::null); + setSimName(LLStringUtil::null); + setFromSearch(false); + + // reset click stats + mTeleportClicksOld = 0; + mMapClicksOld = 0; + mProfileClicksOld = 0; + mTeleportClicksNew = 0; + mMapClicksNew = 0; + mProfileClicksNew = 0; + childSetText("category", LLStringUtil::null); childSetText("content_type", LLStringUtil::null); childSetText("click_through_text", LLStringUtil::null); @@ -1331,6 +1371,8 @@ void LLPanelClassifiedInfo::resetData() childSetText("auto_renew", LLStringUtil::null); childSetText("creation_date", LLStringUtil::null); childSetText("click_through_text", LLStringUtil::null); + getChild("content_type_moderate")->setVisible(FALSE); + getChild("content_type_general")->setVisible(FALSE); } void LLPanelClassifiedInfo::resetControls() @@ -1368,6 +1410,11 @@ void LLPanelClassifiedInfo::setClassifiedLocation(const std::string& location) childSetValue("classified_location", location); } +std::string LLPanelClassifiedInfo::getClassifiedLocation() +{ + return childGetValue("classified_location").asString(); +} + void LLPanelClassifiedInfo::setSnapshotId(const LLUUID& id) { mSnapshotCtrl->setValue(id); @@ -1444,6 +1491,13 @@ void LLPanelClassifiedInfo::setClickThrough( ct_str.setArg("[PROFILE]", llformat("%d", self->mProfileClicksNew + self->mProfileClicksOld)); self->childSetText("click_through_text", ct_str.getString()); + // *HACK: remove this when there is enough room for click stats in the info panel + self->childSetToolTip("click_through_text", ct_str.getString()); + + llinfos << "teleport: " << llformat("%d", self->mTeleportClicksNew + self->mTeleportClicksOld) + << ", map: " << llformat("%d", self->mMapClicksNew + self->mMapClicksOld) + << ", profile: " << llformat("%d", self->mProfileClicksNew + self->mProfileClicksOld) + << llendl; } } @@ -1532,8 +1586,46 @@ void LLPanelClassifiedInfo::scrollToTop() scrollContainer->goToTop(); } +// static +// *TODO: move out of the panel +void LLPanelClassifiedInfo::sendClickMessage( + const std::string& type, + bool from_search, + const LLUUID& classified_id, + const LLUUID& parcel_id, + const LLVector3d& global_pos, + const std::string& sim_name) +{ + // You're allowed to click on your own ads to reassure yourself + // that the system is working. + LLSD body; + body["type"] = type; + body["from_search"] = from_search; + body["classified_id"] = classified_id; + body["parcel_id"] = parcel_id; + body["dest_pos_global"] = global_pos.getValue(); + body["region_name"] = sim_name; + + std::string url = gAgent.getRegion()->getCapability("SearchStatTracking"); + llinfos << "Sending click msg via capability (url=" << url << ")" << llendl; + llinfos << "body: [" << body << "]" << llendl; + LLHTTPClient::post(url, body, new LLClassifiedClickMessageResponder()); +} + +void LLPanelClassifiedInfo::sendClickMessage(const std::string& type) +{ + sendClickMessage( + type, + fromSearch(), + getClassifiedId(), + getParcelId(), + getPosGlobal(), + getSimName()); +} + void LLPanelClassifiedInfo::onMapClick() { + sendClickMessage("map"); LLFloaterWorldMap::getInstance()->trackLocation(getPosGlobal()); LLFloaterReg::showInstance("world_map", "center"); } @@ -1542,6 +1634,7 @@ void LLPanelClassifiedInfo::onTeleportClick() { if (!getPosGlobal().isExactlyZero()) { + sendClickMessage("teleport"); gAgent.teleportViaLocation(getPosGlobal()); LLFloaterWorldMap::getInstance()->trackLocation(getPosGlobal()); } @@ -1563,6 +1656,7 @@ static const S32 CB_ITEM_PG = 1; LLPanelClassifiedEdit::LLPanelClassifiedEdit() : LLPanelClassifiedInfo() , mIsNew(false) + , mIsNewWithErrors(false) , mCanClose(false) , mPublishFloater(NULL) { @@ -1621,21 +1715,12 @@ BOOL LLPanelClassifiedEdit::postBuild() return TRUE; } -void LLPanelClassifiedEdit::onOpen(const LLSD& key) +void LLPanelClassifiedEdit::fillIn(const LLSD& key) { - LLUUID classified_id = key["classified_id"]; + setAvatarId(gAgent.getID()); - mIsNew = classified_id.isNull(); - - scrollToTop(); - - if(mIsNew) + if(key.isUndefined()) { - setAvatarId(gAgent.getID()); - - resetData(); - resetControls(); - setPosGlobal(gAgent.getPositionGlobal()); LLUUID snapshot_id = LLUUID::null; @@ -1658,25 +1743,55 @@ void LLPanelClassifiedEdit::onOpen(const LLSD& key) childSetValue("classified_name", makeClassifiedName()); childSetValue("classified_desc", desc); setSnapshotId(snapshot_id); - setClassifiedLocation(createLocationText(getLocationNotice(), region_name, getPosGlobal())); - // server will set valid parcel id setParcelId(LLUUID::null); + } + else + { + setClassifiedId(key["classified_id"]); + setClassifiedName(key["name"]); + setDescription(key["desc"]); + setSnapshotId(key["snapshot_id"]); + setCategory((U32)key["category"].asInteger()); + setContentType((U32)key["content_type"].asInteger()); + setClassifiedLocation(key["location_text"]); + childSetValue("auto_renew", key["auto_renew"]); + childSetValue("price_for_listing", key["price_for_listing"].asInteger()); + } +} - enableVerbs(true); - enableEditing(true); +void LLPanelClassifiedEdit::onOpen(const LLSD& key) +{ + mIsNew = key.isUndefined(); + + scrollToTop(); + + // classified is not created yet + bool is_new = isNew() || isNewWithErrors(); + + if(is_new) + { + resetData(); + resetControls(); + + fillIn(key); + + if(isNew()) + { + LLAvatarPropertiesProcessor::getInstance()->addObserver(getAvatarId(), this); + } } else { LLPanelClassifiedInfo::onOpen(key); - enableVerbs(false); - enableEditing(false); } - std::string save_btn_label = isNew() ? getString("publish_label") : getString("save_label"); + std::string save_btn_label = is_new ? getString("publish_label") : getString("save_label"); childSetLabelArg("save_changes_btn", "[LABEL]", save_btn_label); + enableVerbs(is_new); + enableEditing(is_new); resetDirty(); setInfoLoaded(false); } @@ -1688,6 +1803,14 @@ void LLPanelClassifiedEdit::processProperties(void* data, EAvatarProcessorType t LLAvatarClassifiedInfo* c_info = static_cast(data); if(c_info && getClassifiedId() == c_info->classified_id) { + // see LLPanelClassifiedEdit::sendUpdate() for notes + mIsNewWithErrors = false; + // for just created classified - panel will probably be closed when we get here. + if(!getVisible()) + { + return; + } + enableEditing(true); setClassifiedName(c_info->name); @@ -1697,19 +1820,22 @@ void LLPanelClassifiedEdit::processProperties(void* data, EAvatarProcessorType t setClassifiedLocation(createLocationText(c_info->parcel_name, c_info->sim_name, c_info->pos_global)); // *HACK see LLPanelClassifiedEdit::sendUpdate() - getChild("category")->setCurrentByIndex(c_info->category - 1); - getChild("category")->resetDirty(); + setCategory(c_info->category - 1); bool mature = is_cf_mature(c_info->flags); bool auto_renew = is_cf_auto_renew(c_info->flags); - getChild("content_type")->setCurrentByIndex(mature ? CB_ITEM_MATURE : CB_ITEM_PG); + setContentType(mature ? CB_ITEM_MATURE : CB_ITEM_PG); childSetValue("auto_renew", auto_renew); childSetValue("price_for_listing", c_info->price_for_listing); childSetEnabled("price_for_listing", isNew()); resetDirty(); setInfoLoaded(true); + enableVerbs(false); + + // for just created classified - in case user opened edit panel before processProperties() callback + childSetLabelArg("save_changes_btn", "[LABEL]", getString("save_label")); } } } @@ -1740,7 +1866,12 @@ void LLPanelClassifiedEdit::resetDirty() LLPanelClassifiedInfo::resetDirty(); getChild("classified_snapshot")->resetDirty(); getChild("classified_name")->resetDirty(); - getChild("classified_desc")->resetDirty(); + + LLTextEditor* desc = getChild("classified_desc"); + // call blockUndo() to really reset dirty(and make isDirty work as intended) + desc->blockUndo(); + desc->resetDirty(); + getChild("category")->resetDirty(); getChild("content_type")->resetDirty(); getChild("auto_renew")->resetDirty(); @@ -1762,7 +1893,7 @@ void LLPanelClassifiedEdit::resetControls() LLPanelClassifiedInfo::resetControls(); getChild("category")->setCurrentByIndex(0); - getChild("content_type")->setCurrentByIndex(0); + getChild("content_type")->setCurrentByIndex(0); childSetValue("auto_renew", false); childSetValue("price_for_listing", MINIMUM_PRICE_FOR_LISTING); childSetEnabled("price_for_listing", TRUE); @@ -1789,15 +1920,31 @@ void LLPanelClassifiedEdit::stretchSnapshot() getChild("edit_icon")->setShape(mSnapshotCtrl->getRect()); } +U32 LLPanelClassifiedEdit::getContentType() +{ + LLComboBox* ct_cb = getChild("content_type"); + return ct_cb->getCurrentIndex(); +} + +void LLPanelClassifiedEdit::setContentType(U32 content_type) +{ + LLIconsComboBox* ct_cb = getChild("content_type"); + ct_cb->setCurrentByIndex(content_type); + ct_cb->resetDirty(); +} + +bool LLPanelClassifiedEdit::getAutoRenew() +{ + return childGetValue("auto_renew").asBoolean(); +} + void LLPanelClassifiedEdit::sendUpdate() { LLAvatarClassifiedInfo c_data; if(getClassifiedId().isNull()) { - LLUUID id; - id.generate(); - setClassifiedId(id); + setClassifiedId(LLUUID::generateNewID()); } c_data.agent_id = gAgent.getID(); @@ -1814,6 +1961,14 @@ void LLPanelClassifiedEdit::sendUpdate() c_data.price_for_listing = getPriceForListing(); LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoUpdate(&c_data); + + if(isNew()) + { + // Lets assume there will be some error. + // Successful sendClassifiedInfoUpdate will trigger processProperties and + // let us know there was no error. + mIsNewWithErrors = true; + } } U32 LLPanelClassifiedEdit::getCategory() @@ -1822,11 +1977,18 @@ U32 LLPanelClassifiedEdit::getCategory() return cat_cb->getCurrentIndex(); } +void LLPanelClassifiedEdit::setCategory(U32 category) +{ + LLComboBox* cat_cb = getChild("category"); + cat_cb->setCurrentByIndex(category); + cat_cb->resetDirty(); +} + U8 LLPanelClassifiedEdit::getFlags() { bool auto_renew = childGetValue("auto_renew").asBoolean(); - LLComboBox* content_cb = getChild("content_type"); + LLComboBox* content_cb = getChild("content_type"); bool mature = content_cb->getCurrentIndex() == CB_ITEM_MATURE; return pack_classified_flags_request(auto_renew, false, mature, false); @@ -1917,17 +2079,14 @@ void LLPanelClassifiedEdit::onSaveClick() notifyInvalidName(); return; } - if(isNew()) + if(isNew() || isNewWithErrors()) { if(gStatusBar->getBalance() < getPriceForListing()) { LLNotificationsUtil::add("ClassifiedInsufficientFunds"); return; } - } - if(isNew()) - { mPublishFloater = LLFloaterReg::findTypedInstance( "publish_classified", LLSD()); diff --git a/indra/newview/llpanelclassified.h b/indra/newview/llpanelclassified.h index 78f095a9bb..1157649a16 100644 --- a/indra/newview/llpanelclassified.h +++ b/indra/newview/llpanelclassified.h @@ -221,6 +221,7 @@ private: class LLPanelClassifiedInfo : public LLPanel, public LLAvatarPropertiesObserver { + LOG_CLASS(LLPanelClassifiedInfo); public: static LLPanelClassifiedInfo* create(); @@ -255,6 +256,8 @@ public: void setClassifiedLocation(const std::string& location); + std::string getClassifiedLocation(); + void setPosGlobal(const LLVector3d& pos) { mPosGlobal = pos; } LLVector3d& getPosGlobal() { return mPosGlobal; } @@ -263,6 +266,14 @@ public: LLUUID getParcelId() { return mParcelId; } + void setSimName(const std::string& sim_name) { mSimName = sim_name; } + + std::string getSimName() { return mSimName; } + + void setFromSearch(bool val) { mFromSearch = val; } + + bool fromSearch() { return mFromSearch; } + bool getInfoLoaded() { return mInfoLoaded; } void setInfoLoaded(bool loaded) { mInfoLoaded = loaded; } @@ -274,6 +285,14 @@ public: S32 profile, bool from_new_table); + static void sendClickMessage( + const std::string& type, + bool from_search, + const LLUUID& classified_id, + const LLUUID& parcel_id, + const LLVector3d& global_pos, + const std::string& sim_name); + void setExitCallback(const commit_callback_t& cb); void setEditClassifiedCallback(const commit_callback_t& cb); @@ -296,6 +315,7 @@ protected: const LLVector3d& pos_global); void stretchSnapshot(); + void sendClickMessage(const std::string& type); LLRect getDefaultSnapshotRect(); @@ -315,6 +335,8 @@ private: LLUUID mClassifiedId; LLVector3d mPosGlobal; LLUUID mParcelId; + std::string mSimName; + bool mFromSearch; bool mInfoLoaded; LLScrollContainer* mScrollContainer; @@ -337,6 +359,7 @@ private: class LLPanelClassifiedEdit : public LLPanelClassifiedInfo { + LOG_CLASS(LLPanelClassifiedEdit); public: static LLPanelClassifiedEdit* create(); @@ -345,6 +368,8 @@ public: /*virtual*/ BOOL postBuild(); + void fillIn(const LLSD& key); + /*virtual*/ void onOpen(const LLSD& key); /*virtual*/ void processProperties(void* data, EAvatarProcessorType type); @@ -361,28 +386,38 @@ public: bool isNew() { return mIsNew; } + bool isNewWithErrors() { return mIsNewWithErrors; } + bool canClose(); void draw(); void stretchSnapshot(); + U32 getCategory(); + + void setCategory(U32 category); + + U32 getContentType(); + + void setContentType(U32 content_type); + + bool getAutoRenew(); + + S32 getPriceForListing(); + protected: LLPanelClassifiedEdit(); void sendUpdate(); - U32 getCategory(); - void enableVerbs(bool enable); void enableEditing(bool enable); std::string makeClassifiedName(); - S32 getPriceForListing(); - void setPriceForListing(S32 price); U8 getFlags(); @@ -408,6 +443,7 @@ protected: private: bool mIsNew; + bool mIsNewWithErrors; bool mCanClose; LLPublishClassifiedFloater* mPublishFloater; diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp index 13697cb8ba..ae310e5a79 100644 --- a/indra/newview/llpanelobjectinventory.cpp +++ b/indra/newview/llpanelobjectinventory.cpp @@ -770,8 +770,8 @@ BOOL LLTaskCategoryBridge::startDrag(EDragAndDropType* type, LLUUID* id) const LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID()); if(object) { - LLInventoryItem* inv = NULL; - if((inv = (LLInventoryItem*)object->getInventoryObject(mUUID))) + const LLInventoryItem *inv = dynamic_cast(object->getInventoryObject(mUUID)); + if (inv) { const LLPermissions& perm = inv->getPermissions(); bool can_copy = gAgent.allowOperation(PERM_COPY, perm, @@ -1759,7 +1759,7 @@ void LLPanelObjectInventory::updateInventory() // We're still interested in this task's inventory. std::set selected_items; BOOL inventory_has_focus = FALSE; - if (mHaveInventory && mFolders->getNumSelectedDescendants()) + if (mHaveInventory) { mFolders->getSelectionList(selected_items); inventory_has_focus = gFocusMgr.childHasKeyboardFocus(mFolders); diff --git a/indra/newview/llpanelpicks.cpp b/indra/newview/llpanelpicks.cpp index 2ff2597f08..0a7c39db46 100644 --- a/indra/newview/llpanelpicks.cpp +++ b/indra/newview/llpanelpicks.cpp @@ -140,10 +140,11 @@ public: params["open_tab_name"] = "panel_picks"; params["show_tab_panel"] = "classified_details"; params["classified_id"] = c_info->classified_id; - params["classified_avatar_id"] = c_info->creator_id; + params["classified_creator_id"] = c_info->creator_id; params["classified_snapshot_id"] = c_info->snapshot_id; params["classified_name"] = c_info->name; params["classified_desc"] = c_info->description; + params["from_search"] = true; LLSideTray::getInstance()->showPanel("panel_profile_view", params); } @@ -174,31 +175,6 @@ LLClassifiedHandler gClassifiedHandler; ////////////////////////////////////////////////////////////////////////// -/** - * Copy&Pasted from old LLPanelClassified. This class does nothing at the moment. - * Subscribing to "classifiedclickthrough" removes a few warnings. - */ -class LLClassifiedClickThrough : public LLDispatchHandler -{ -public: - - // "classifiedclickthrough" - // strings[0] = classified_id - // strings[1] = teleport_clicks - // strings[2] = map_clicks - // strings[3] = profile_clicks - virtual bool operator()( - const LLDispatcher* dispatcher, - const std::string& key, - const LLUUID& invoice, - const sparam_t& strings) - { - if (strings.size() != 4) - return false; - - return true; - } -}; //----------------------------------------------------------------------------- // LLPanelPicks @@ -216,13 +192,9 @@ LLPanelPicks::LLPanelPicks() mPicksAccTab(NULL), mClassifiedsAccTab(NULL), mPanelClassifiedInfo(NULL), - mPanelClassifiedEdit(NULL), - mClickThroughDisp(NULL), mNoClassifieds(false), mNoPicks(false) { - mClickThroughDisp = new LLClassifiedClickThrough(); - gGenericDispatcher.addHandler("classifiedclickthrough", mClickThroughDisp); } LLPanelPicks::~LLPanelPicks() @@ -231,8 +203,6 @@ LLPanelPicks::~LLPanelPicks() { LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(),this); } - - delete mClickThroughDisp; } void* LLPanelPicks::create(void* data /* = NULL */) @@ -414,6 +384,9 @@ BOOL LLPanelPicks::postBuild() registar.add("Pick.Teleport", boost::bind(&LLPanelPicks::onClickTeleport, this)); registar.add("Pick.Map", boost::bind(&LLPanelPicks::onClickMap, this)); registar.add("Pick.Delete", boost::bind(&LLPanelPicks::onClickDelete, this)); + LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registar; + enable_registar.add("Pick.Enable", boost::bind(&LLPanelPicks::onEnableMenuItem, this, _2)); + mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile("menu_picks.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); LLUICtrl::CommitCallbackRegistry::ScopedRegistrar plus_registar; @@ -450,6 +423,22 @@ bool LLPanelPicks::isActionEnabled(const LLSD& userdata) const return true; } +bool LLPanelPicks::isClassifiedPublished(LLClassifiedItem* c_item) +{ + if(c_item) + { + LLPanelClassifiedEdit* panel = mEditClassifiedPanels[c_item->getClassifiedId()]; + if(panel) + { + return !panel->isNewWithErrors(); + } + + // we've got this classified from server - it's published + return true; + } + return false; +} + void LLPanelPicks::onAccordionStateChanged(const LLAccordionCtrlTab* acc_tab) { if(!mPicksAccTab->getDisplayChildren()) @@ -607,7 +596,11 @@ void LLPanelPicks::onClickTeleport() if(pick_item) pos = pick_item->getPosGlobal(); else if(c_item) + { pos = c_item->getPosGlobal(); + LLPanelClassifiedInfo::sendClickMessage("teleport", false, + c_item->getClassifiedId(), LLUUID::null, pos, LLStringUtil::null); + } if (!pos.isExactlyZero()) { @@ -626,7 +619,11 @@ void LLPanelPicks::onClickMap() if (pick_item) pos = pick_item->getPosGlobal(); else if(c_item) + { + LLPanelClassifiedInfo::sendClickMessage("map", false, + c_item->getClassifiedId(), LLUUID::null, pos, LLStringUtil::null); pos = c_item->getPosGlobal(); + } LLFloaterWorldMap::getInstance()->trackLocation(pos); LLFloaterReg::showInstance("world_map", "center"); @@ -678,6 +675,12 @@ void LLPanelPicks::updateButtons() childSetEnabled(XML_BTN_INFO, has_selected); childSetEnabled(XML_BTN_TELEPORT, has_selected); childSetEnabled(XML_BTN_SHOW_ON_MAP, has_selected); + + LLClassifiedItem* c_item = dynamic_cast(mClassifiedsList->getSelectedItem()); + if(c_item) + { + childSetEnabled(XML_BTN_INFO, isClassifiedPublished(c_item)); + } } void LLPanelPicks::setProfilePanel(LLPanelProfile* profile_panel) @@ -714,9 +717,10 @@ void LLPanelPicks::createNewPick() void LLPanelPicks::createNewClassified() { - createClassifiedEditPanel(); + LLPanelClassifiedEdit* panel = NULL; + createClassifiedEditPanel(&panel); - getProfilePanel()->openPanel(mPanelClassifiedEdit, LLSD()); + getProfilePanel()->openPanel(panel, LLSD()); } void LLPanelPicks::onClickInfo() @@ -756,26 +760,20 @@ void LLPanelPicks::openClassifiedInfo() if (selected_value.isUndefined()) return; LLClassifiedItem* c_item = getSelectedClassifiedItem(); + LLSD params; + params["classified_id"] = c_item->getClassifiedId(); + params["classified_creator_id"] = c_item->getAvatarId(); + params["classified_snapshot_id"] = c_item->getSnapshotId(); + params["classified_name"] = c_item->getClassifiedName(); + params["classified_desc"] = c_item->getDescription(); + params["from_search"] = false; - openClassifiedInfo(c_item->getClassifiedId(), c_item->getAvatarId(), - c_item->getSnapshotId(), c_item->getClassifiedName(), - c_item->getDescription()); + openClassifiedInfo(params); } -void LLPanelPicks::openClassifiedInfo(const LLUUID &classified_id, - const LLUUID &avatar_id, - const LLUUID &snapshot_id, - const std::string &name, const std::string &desc) +void LLPanelPicks::openClassifiedInfo(const LLSD ¶ms) { createClassifiedInfoPanel(); - - LLSD params; - params["classified_id"] = classified_id; - params["avatar_id"] = avatar_id; - params["snapshot_id"] = snapshot_id; - params["name"] = name; - params["desc"] = desc; - getProfilePanel()->openPanel(mPanelClassifiedInfo, params); } @@ -807,11 +805,10 @@ void LLPanelPicks::onPanelClassifiedSave(LLPanelClassifiedEdit* panel) if(panel->isNew()) { + mEditClassifiedPanels[panel->getClassifiedId()] = panel; + LLClassifiedItem* c_item = new LLClassifiedItem(getAvatarId(), panel->getClassifiedId()); - - c_item->setClassifiedName(panel->getClassifiedName()); - c_item->setDescription(panel->getDescription()); - c_item->setSnapshotId(panel->getSnapshotId()); + c_item->fillIn(panel); LLSD c_value; c_value.insert(CLASSIFIED_ID, c_item->getClassifiedId()); @@ -827,6 +824,11 @@ void LLPanelPicks::onPanelClassifiedSave(LLPanelClassifiedEdit* panel) mClassifiedsAccTab->changeOpenClose(false); showAccordion("tab_classifieds", true); } + else if(panel->isNewWithErrors()) + { + LLClassifiedItem* c_item = dynamic_cast(mClassifiedsList->getSelectedItem()); + c_item->fillIn(panel); + } else { onPanelClassifiedClose(panel); @@ -887,15 +889,16 @@ void LLPanelPicks::createClassifiedInfoPanel() } } -void LLPanelPicks::createClassifiedEditPanel() +void LLPanelPicks::createClassifiedEditPanel(LLPanelClassifiedEdit** panel) { - if(!mPanelClassifiedEdit) + if(panel) { - mPanelClassifiedEdit = LLPanelClassifiedEdit::create(); - mPanelClassifiedEdit->setExitCallback(boost::bind(&LLPanelPicks::onPanelClassifiedClose, this, mPanelClassifiedEdit)); - mPanelClassifiedEdit->setSaveCallback(boost::bind(&LLPanelPicks::onPanelClassifiedSave, this, mPanelClassifiedEdit)); - mPanelClassifiedEdit->setCancelCallback(boost::bind(&LLPanelPicks::onPanelClassifiedClose, this, mPanelClassifiedEdit)); - mPanelClassifiedEdit->setVisible(FALSE); + LLPanelClassifiedEdit* new_panel = LLPanelClassifiedEdit::create(); + new_panel->setExitCallback(boost::bind(&LLPanelPicks::onPanelClassifiedClose, this, new_panel)); + new_panel->setSaveCallback(boost::bind(&LLPanelPicks::onPanelClassifiedSave, this, new_panel)); + new_panel->setCancelCallback(boost::bind(&LLPanelPicks::onPanelClassifiedClose, this, new_panel)); + new_panel->setVisible(FALSE); + *panel = new_panel; } } @@ -968,16 +971,26 @@ void LLPanelPicks::onPanelClassifiedEdit() LLClassifiedItem* c_item = dynamic_cast(mClassifiedsList->getSelectedItem()); - createClassifiedEditPanel(); - LLSD params; params["classified_id"] = c_item->getClassifiedId(); - params["avatar_id"] = c_item->getAvatarId(); + params["classified_creator_id"] = c_item->getAvatarId(); params["snapshot_id"] = c_item->getSnapshotId(); params["name"] = c_item->getClassifiedName(); params["desc"] = c_item->getDescription(); + params["category"] = (S32)c_item->getCategory(); + params["content_type"] = (S32)c_item->getContentType(); + params["auto_renew"] = c_item->getAutoRenew(); + params["price_for_listing"] = c_item->getPriceForListing(); + params["location_text"] = c_item->getLocationText(); - getProfilePanel()->openPanel(mPanelClassifiedEdit, params); + LLPanelClassifiedEdit* panel = mEditClassifiedPanels[c_item->getClassifiedId()]; + if(!panel) + { + createClassifiedEditPanel(&panel); + mEditClassifiedPanels[c_item->getClassifiedId()] = panel; + } + getProfilePanel()->openPanel(panel, params); + panel->setPosGlobal(c_item->getPosGlobal()); } void LLPanelPicks::onClickMenuEdit() @@ -992,6 +1005,20 @@ void LLPanelPicks::onClickMenuEdit() } } +bool LLPanelPicks::onEnableMenuItem(const LLSD& user_data) +{ + std::string param = user_data.asString(); + + LLClassifiedItem* c_item = dynamic_cast(mClassifiedsList->getSelectedItem()); + if(c_item && "info" == param) + { + // dont show Info panel if classified was not created + return isClassifiedPublished(c_item); + } + + return true; +} + inline LLPanelProfile* LLPanelPicks::getProfilePanel() { llassert_always(NULL != mProfilePanel); @@ -1180,6 +1207,24 @@ void LLClassifiedItem::setValue(const LLSD& value) childSetVisible("selected_icon", value["selected"]); } +void LLClassifiedItem::fillIn(LLPanelClassifiedEdit* panel) +{ + if(!panel) + { + return; + } + + setClassifiedName(panel->getClassifiedName()); + setDescription(panel->getDescription()); + setSnapshotId(panel->getSnapshotId()); + setCategory(panel->getCategory()); + setContentType(panel->getContentType()); + setAutoRenew(panel->getAutoRenew()); + setPriceForListing(panel->getPriceForListing()); + setPosGlobal(panel->getPosGlobal()); + setLocationText(panel->getClassifiedLocation()); +} + void LLClassifiedItem::setClassifiedName(const std::string& name) { childSetValue("name", name); diff --git a/indra/newview/llpanelpicks.h b/indra/newview/llpanelpicks.h index 3f757e482e..a98b8c413e 100644 --- a/indra/newview/llpanelpicks.h +++ b/indra/newview/llpanelpicks.h @@ -55,7 +55,6 @@ class LLPanelPickEdit; class LLToggleableMenu; class LLPanelClassifiedInfo; class LLPanelClassifiedEdit; -class LLClassifiedClickThrough; // *TODO // Panel Picks has been consolidated with Classifieds (EXT-2095), give LLPanelPicks @@ -99,6 +98,8 @@ private: void onPlusMenuItemClicked(const LLSD& param); bool isActionEnabled(const LLSD& userdata) const; + bool isClassifiedPublished(LLClassifiedItem* c_item); + void onListCommit(const LLFlatListView* f_list); void onAccordionStateChanged(const LLAccordionCtrlTab* acc_tab); @@ -115,14 +116,14 @@ private: void onPanelClassifiedEdit(); void onClickMenuEdit(); + bool onEnableMenuItem(const LLSD& user_data); + void createNewPick(); void createNewClassified(); void openPickInfo(); void openClassifiedInfo(); - void openClassifiedInfo(const LLUUID &classified_id, const LLUUID &avatar_id, - const LLUUID &snapshot_id, const std::string &name, - const std::string &desc); + void openClassifiedInfo(const LLSD& params); friend class LLPanelProfile; void showAccordion(const std::string& name, bool show); @@ -143,7 +144,7 @@ private: void createPickInfoPanel(); void createPickEditPanel(); void createClassifiedInfoPanel(); - void createClassifiedEditPanel(); + void createClassifiedEditPanel(LLPanelClassifiedEdit** panel); LLMenuGL* mPopupMenu; LLPanelProfile* mProfilePanel; @@ -152,15 +153,19 @@ private: LLFlatListView* mClassifiedsList; LLPanelPickInfo* mPanelPickInfo; LLPanelClassifiedInfo* mPanelClassifiedInfo; - LLPanelClassifiedEdit* mPanelClassifiedEdit; LLPanelPickEdit* mPanelPickEdit; LLToggleableMenu* mPlusMenu; + // + typedef std::map panel_classified_edit_map_t; + + // This map is needed for newly created classifieds. The purpose of panel is to + // sit in this map and listen to LLPanelClassifiedEdit::processProperties callback. + panel_classified_edit_map_t mEditClassifiedPanels; + LLAccordionCtrlTab* mPicksAccTab; LLAccordionCtrlTab* mClassifiedsAccTab; - LLClassifiedClickThrough* mClickThroughDisp; - //true if picks list is empty after processing picks bool mNoPicks; //true if classifieds list is empty after processing classifieds @@ -250,6 +255,8 @@ public: /*virtual*/ void setValue(const LLSD& value); + void fillIn(LLPanelClassifiedEdit* panel); + LLUUID getAvatarId() {return mAvatarId;} void setAvatarId(const LLUUID& avatar_id) {mAvatarId = avatar_id;} @@ -260,7 +267,11 @@ public: void setPosGlobal(const LLVector3d& pos) { mPosGlobal = pos; } - const LLVector3d& getPosGlobal() { return mPosGlobal; } + const LLVector3d getPosGlobal() { return mPosGlobal; } + + void setLocationText(const std::string location) { mLocationText = location; } + + std::string getLocationText() { return mLocationText; } void setClassifiedName (const std::string& name); @@ -274,10 +285,31 @@ public: LLUUID getSnapshotId(); + void setCategory(U32 cat) { mCategory = cat; } + + U32 getCategory() { return mCategory; } + + void setContentType(U32 ct) { mContentType = ct; } + + U32 getContentType() { return mContentType; } + + void setAutoRenew(U32 renew) { mAutoRenew = renew; } + + bool getAutoRenew() { return mAutoRenew; } + + void setPriceForListing(S32 price) { mPriceForListing = price; } + + S32 getPriceForListing() { return mPriceForListing; } + private: LLUUID mAvatarId; LLUUID mClassifiedId; LLVector3d mPosGlobal; + std::string mLocationText; + U32 mCategory; + U32 mContentType; + bool mAutoRenew; + S32 mPriceForListing; }; #endif // LL_LLPANELPICKS_H diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index b5d85dfd4b..18da8dd48c 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -171,15 +171,13 @@ void LLPanelProfile::onOpen(const LLSD& key) } else if (panel == "classified_details") { - LLUUID classified_id = key["classified_id"].asUUID(); - LLUUID avatar_id = key["classified_avatar_id"].asUUID(); - LLUUID snapshot_id = key["classified_snapshot_id"].asUUID(); - std::string name = key["classified_name"].asString(); - std::string desc = key["classified_desc"].asString(); LLPanelPicks* picks = dynamic_cast(getTabContainer()[PANEL_PICKS]); if (picks) { - picks->openClassifiedInfo(classified_id, avatar_id, snapshot_id, name, desc); + LLSD params = key; + params.erase("show_tab_panel"); + params.erase("open_tab_name"); + picks->openClassifiedInfo(params); } } } diff --git a/indra/newview/llpopupview.cpp b/indra/newview/llpopupview.cpp index 1668a91eed..d8ad59c90c 100644 --- a/indra/newview/llpopupview.cpp +++ b/indra/newview/llpopupview.cpp @@ -220,10 +220,6 @@ void LLPopupView::removePopup(LLView* popup) { if (popup) { - if (gFocusMgr.childHasKeyboardFocus(popup)) - { - gFocusMgr.setKeyboardFocus(NULL); - } popup_list_t::iterator iter = std::find(mPopups.begin(), mPopups.end(), popup->getHandle()); if(iter != mPopups.end()) { diff --git a/indra/newview/llscriptfloater.cpp b/indra/newview/llscriptfloater.cpp index eb71cc52c8..f35cb3516a 100644 --- a/indra/newview/llscriptfloater.cpp +++ b/indra/newview/llscriptfloater.cpp @@ -154,14 +154,17 @@ void LLScriptFloater::createForm(const LLUUID& notification_id) } // create new form - mScriptForm = new LLToastNotifyPanel(notification); + LLRect toast_rect = getRect(); + // LLToastNotifyPanel will fit own content in vertical direction, + // but it needs an initial rect to properly calculate its width + // Use an initial rect of the script floater to make the floater window more configurable. + mScriptForm = new LLToastNotifyPanel(notification, toast_rect); addChild(mScriptForm); // position form on floater mScriptForm->setOrigin(0, 0); // make floater size fit form size - LLRect toast_rect = getRect(); LLRect panel_rect = mScriptForm->getRect(); toast_rect.setLeftTopAndSize(toast_rect.mLeft, toast_rect.mTop, panel_rect.getWidth(), panel_rect.getHeight() + getHeaderHeight()); setShape(toast_rect); diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index 3116c8feb0..4649b9cbef 100644 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -751,6 +751,7 @@ LLTextureCache::LLTextureCache(bool threaded) LLTextureCache::~LLTextureCache() { clearDeleteList() ; + writeUpdatedEntries() ; } ////////////////////////////////////////////////////////////////////////////// @@ -758,6 +759,9 @@ LLTextureCache::~LLTextureCache() //virtual S32 LLTextureCache::update(U32 max_time_ms) { + static LLFrameTimer timer ; + static const F32 MAX_TIME_INTERVAL = 300.f ; //seconds. + S32 res; res = LLWorkerThread::update(max_time_ms); @@ -793,6 +797,12 @@ S32 LLTextureCache::update(U32 max_time_ms) responder->completed(success); } + if(!res && timer.getElapsedTimeF32() > MAX_TIME_INTERVAL) + { + timer.reset() ; + writeUpdatedEntries() ; + } + return res; } @@ -1083,6 +1093,8 @@ S32 LLTextureCache::openAndReadEntry(const LLUUID& id, Entry& entry, bool create entry.init(id, time(NULL)); // Update Header writeEntriesHeader(); + + //the new entry, write immediately. // Write Entry S32 offset = sizeof(EntriesInfo) + idx * sizeof(Entry); LLAPRFile* aprfile = openHeaderEntriesFile(false, offset); @@ -1098,12 +1110,20 @@ S32 LLTextureCache::openAndReadEntry(const LLUUID& id, Entry& entry, bool create // Remove this entry from the LRU if it exists mLRU.erase(id); // Read the entry - S32 offset = sizeof(EntriesInfo) + idx * sizeof(Entry); - LLAPRFile* aprfile = openHeaderEntriesFile(true, offset); - S32 bytes_read = aprfile->read((void*)&entry, (S32)sizeof(Entry)); - llassert_always(bytes_read == sizeof(Entry)); + idx_entry_map_t::iterator iter = mUpdatedEntryMap.find(idx) ; + if(iter != mUpdatedEntryMap.end()) + { + entry = iter->second ; + } + else + { + S32 offset = sizeof(EntriesInfo) + idx * sizeof(Entry); + LLAPRFile* aprfile = openHeaderEntriesFile(true, offset); + S32 bytes_read = aprfile->read((void*)&entry, (S32)sizeof(Entry)); + llassert_always(bytes_read == sizeof(Entry)); + closeHeaderEntriesFile(); + } llassert_always(entry.mImageSize == 0 || entry.mImageSize == -1 || entry.mImageSize > entry.mBodySize); - closeHeaderEntriesFile(); } return idx; } @@ -1121,12 +1141,8 @@ void LLTextureCache::writeEntryAndClose(S32 idx, Entry& entry) mTexturesSizeMap[entry.mID] = entry.mBodySize; } // llinfos << "Updating TE: " << idx << ": " << id << " Size: " << entry.mBodySize << " Time: " << entry.mTime << llendl; - S32 offset = sizeof(EntriesInfo) + idx * sizeof(Entry); - LLAPRFile* aprfile = openHeaderEntriesFile(false, offset); - S32 bytes_written = aprfile->write((void*)&entry, (S32)sizeof(Entry)); - llassert_always(bytes_written == sizeof(Entry)); mHeaderEntriesMaxWriteIdx = llmax(mHeaderEntriesMaxWriteIdx, idx); - closeHeaderEntriesFile(); + mUpdatedEntryMap[idx] = entry ; } } } @@ -1141,6 +1157,7 @@ U32 LLTextureCache::openAndReadEntries(std::vector& entries) mTexturesSizeTotal = 0; LLAPRFile* aprfile = openHeaderEntriesFile(false, (S32)sizeof(EntriesInfo)); + updatedHeaderEntriesFile() ; for (U32 idx=0; idx& entries) } } +void LLTextureCache::writeUpdatedEntries() +{ + lockHeaders() ; + if (!mReadOnly && !mUpdatedEntryMap.empty()) + { + openHeaderEntriesFile(false, 0); + updatedHeaderEntriesFile() ; + closeHeaderEntriesFile(); + } + unlockHeaders() ; +} + +//mHeaderMutex is locked and mHeaderAPRFile is created before calling this. +void LLTextureCache::updatedHeaderEntriesFile() +{ + if (!mReadOnly && !mUpdatedEntryMap.empty() && mHeaderAPRFile) + { + //entriesInfo + mHeaderAPRFile->seek(APR_SET, 0); + S32 bytes_written = mHeaderAPRFile->write((U8*)&mHeaderEntriesInfo, sizeof(EntriesInfo)) ; + llassert_always(bytes_written == sizeof(EntriesInfo)); + + //write each updated entry + S32 entry_size = (S32)sizeof(Entry) ; + S32 prev_idx = -1 ; + S32 delta_idx ; + for (idx_entry_map_t::iterator iter = mUpdatedEntryMap.begin(); iter != mUpdatedEntryMap.end(); ++iter) + { + delta_idx = iter->first - prev_idx - 1; + prev_idx = iter->first ; + if(delta_idx) + { + mHeaderAPRFile->seek(APR_CUR, delta_idx * entry_size); + } + + bytes_written = mHeaderAPRFile->write((void*)(&iter->second), entry_size); + llassert_always(bytes_written == entry_size); + } + mUpdatedEntryMap.clear() ; + } +} //---------------------------------------------------------------------------- // Called from either the main thread or the worker thread diff --git a/indra/newview/lltexturecache.h b/indra/newview/lltexturecache.h index 64ec881fc3..b840619c1f 100644 --- a/indra/newview/lltexturecache.h +++ b/indra/newview/lltexturecache.h @@ -68,6 +68,7 @@ private: Entry(const LLUUID& id, S32 imagesize, S32 bodysize, U32 time) : mID(id), mImageSize(imagesize), mBodySize(bodysize), mTime(time) {} void init(const LLUUID& id, U32 time) { mID = id, mImageSize = 0; mBodySize = 0; mTime = time; } + Entry& operator=(const Entry& entry) {mID = entry.mID, mImageSize = entry.mImageSize; mBodySize = entry.mBodySize; mTime = entry.mTime; return *this;} LLUUID mID; // 16 bytes S32 mImageSize; // total size of image if known S32 mBodySize; // size of body file in body cache @@ -166,6 +167,8 @@ private: S32 getHeaderCacheEntry(const LLUUID& id, S32& imagesize); S32 setHeaderCacheEntry(const LLUUID& id, S32 imagesize); bool removeHeaderCacheEntry(const LLUUID& id); + void writeUpdatedEntries() ; + void updatedHeaderEntriesFile() ; void lockHeaders() { mHeaderMutex.lock(); } void unlockHeaders() { mHeaderMutex.unlock(); } @@ -204,6 +207,9 @@ private: S64 mTexturesSizeTotal; LLAtomic32 mDoPurge; + typedef std::map idx_entry_map_t; + idx_entry_map_t mUpdatedEntryMap; + // Statics static F32 sHeaderCacheVersion; static U32 sCacheMaxEntries; diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp index 98731f90f4..6cd8a78b25 100644 --- a/indra/newview/lltextureview.cpp +++ b/indra/newview/lltextureview.cpp @@ -658,6 +658,14 @@ struct compare_decode_pair } }; +struct KillView +{ + void operator()(LLView* viewp) const + { + viewp->die(); + } +}; + void LLTextureView::draw() { if (!mFreezeView) @@ -665,12 +673,12 @@ void LLTextureView::draw() // LLViewerObject *objectp; // S32 te; - for_each(mTextureBars.begin(), mTextureBars.end(), DeletePointer()); + for_each(mTextureBars.begin(), mTextureBars.end(), KillView()); mTextureBars.clear(); - - delete mGLTexMemBar; + + delete mGLTexMemBar; mGLTexMemBar = 0; - + typedef std::multiset display_list_t; display_list_t display_image_list; @@ -683,6 +691,10 @@ void LLTextureView::draw() iter != gTextureList.mImageList.end(); ) { LLPointer imagep = *iter++; + if(!imagep->hasFetcher()) + { + continue ; + } S32 cur_discard = imagep->getDiscardLevel(); S32 desired_discard = imagep->mDesiredDiscardLevel; diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp index c47c017143..e6d13a7613 100644 --- a/indra/newview/lltoastnotifypanel.cpp +++ b/indra/newview/lltoastnotifypanel.cpp @@ -53,7 +53,7 @@ S32 BUTTON_WIDTH = 90; const LLFontGL* LLToastNotifyPanel::sFont = NULL; const LLFontGL* LLToastNotifyPanel::sFontSmall = NULL; -LLToastNotifyPanel::LLToastNotifyPanel(LLNotificationPtr& notification) : +LLToastNotifyPanel::LLToastNotifyPanel(LLNotificationPtr& notification, const LLRect& rect) : LLToastPanel(notification), mTextBox(NULL), mInfoPanel(NULL), @@ -63,6 +63,10 @@ mNumButtons(0), mAddedDefaultBtn(false) { LLUICtrlFactory::getInstance()->buildPanel(this, "panel_notification.xml"); + if(rect != LLRect::null) + { + this->setShape(rect); + } mInfoPanel = getChild("info_panel"); mControlPanel = getChild("control_panel"); BUTTON_WIDTH = gSavedSettings.getS32("ToastButtonWidth"); @@ -159,7 +163,12 @@ mAddedDefaultBtn(false) * for a scriptdialog toast h_pad can be < 2*HPAD if we have a lot of buttons. * In last case set default h_pad to avoid heaping of buttons */ - h_pad = 2*HPAD; + S32 button_per_row = button_panel_width / BUTTON_WIDTH; + h_pad = (button_panel_width % BUTTON_WIDTH) / (button_per_row - 1);// -1 because we do not need space after last button in a row + if(h_pad < 2*HPAD) // still not enough space between buttons ? + { + h_pad = 2*HPAD; + } } if (mIsScriptDialog) { @@ -224,7 +233,7 @@ LLButton* LLToastNotifyPanel::createButton(const LLSD& form_element, BOOL is_opt p.click_callback.function(boost::bind(&LLToastNotifyPanel::onClickButton, userdata)); p.rect.width = BUTTON_WIDTH; p.auto_resize = false; - p.follows.flags(FOLLOWS_RIGHT | FOLLOWS_LEFT | FOLLOWS_BOTTOM); + p.follows.flags(FOLLOWS_LEFT | FOLLOWS_BOTTOM); if (mIsCaution) { p.image_color(LLUIColorTable::instance().getColor("ButtonCautionImageColor")); diff --git a/indra/newview/lltoastnotifypanel.h b/indra/newview/lltoastnotifypanel.h index e791eea469..152975e7de 100644 --- a/indra/newview/lltoastnotifypanel.h +++ b/indra/newview/lltoastnotifypanel.h @@ -53,7 +53,15 @@ class LLNotificationForm; class LLToastNotifyPanel: public LLToastPanel { public: - LLToastNotifyPanel(LLNotificationPtr&); + /** + * Constructor for LLToastNotifyPanel. + * + * @param pNotification a shared pointer to LLNotification + * @param rect an initial rectangle of the toast panel. + * If it is null then a loaded from xml rectangle will be used. + * @see LLNotification + */ + LLToastNotifyPanel(LLNotificationPtr& pNotification, const LLRect& rect = LLRect::null); virtual ~LLToastNotifyPanel(); LLPanel * getControlPanel() { return mControlPanel; } @@ -77,7 +85,7 @@ private: /* * It lays out buttons of the notification in mControlPanel. * Buttons will be placed from BOTTOM to TOP. - * @param h_pad horizontal space between buttons. It is depent on number of buttons. + * @param h_pad horizontal space between buttons. It is depend on number of buttons. * @param buttons vector of button to be added. */ void updateButtonsLayout(const std::vector& buttons, S32 h_pad); diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 8acd343cf5..85efe2724e 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -50,6 +50,7 @@ #include "llcallbacklist.h" #include "llparcel.h" #include "llaudioengine.h" // for gAudiop +#include "llurldispatcher.h" #include "llvoavatar.h" #include "llvoavatarself.h" #include "llviewerregion.h" @@ -1090,7 +1091,8 @@ LLViewerMediaImpl::LLViewerMediaImpl( const LLUUID& texture_id, mBackgroundColor(LLColor4::white), mNavigateSuspended(false), mNavigateSuspendedDeferred(false), - mIsUpdated(false) + mIsUpdated(false), + mTrustedBrowser(false) { // Set up the mute list observer if it hasn't been set up already. @@ -2353,6 +2355,14 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginCla { switch(event) { + case MEDIA_EVENT_CLICK_LINK_NOFOLLOW: + { + LL_DEBUGS("Media") << "MEDIA_EVENT_CLICK_LINK_NOFOLLOW, uri is: " << plugin->getClickURL() << LL_ENDL; + std::string url = plugin->getClickURL(); + LLURLDispatcher::dispatch(url, NULL, mTrustedBrowser); + + } + break; case MEDIA_EVENT_PLUGIN_FAILED_LAUNCH: { // The plugin failed to load properly. Make sure the timer doesn't retry. diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h index 9dbffa78b3..bc51e713a1 100644 --- a/indra/newview/llviewermedia.h +++ b/indra/newview/llviewermedia.h @@ -322,6 +322,9 @@ public: void setLowPrioritySizeLimit(int size); void setTextureID(LLUUID id = LLUUID::null); + + bool isTrustedBrowser() { return mTrustedBrowser; } + void setTrustedBrowser(bool trusted) { mTrustedBrowser = trusted; } typedef enum { @@ -405,6 +408,7 @@ private: LLColor4 mBackgroundColor; bool mNavigateSuspended; bool mNavigateSuspendedDeferred; + bool mTrustedBrowser; private: BOOL mIsUpdated ; diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index d0c3768b34..0eb7ac9cb2 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -82,7 +82,7 @@ LLTexturePipelineTester* LLViewerTextureManager::sTesterp = NULL ; S32 LLViewerTexture::sImageCount = 0; S32 LLViewerTexture::sRawCount = 0; S32 LLViewerTexture::sAuxCount = 0; -LLTimer LLViewerTexture::sEvaluationTimer; +LLFrameTimer LLViewerTexture::sEvaluationTimer; F32 LLViewerTexture::sDesiredDiscardBias = 0.f; F32 LLViewerTexture::sDesiredDiscardScale = 1.1f; S32 LLViewerTexture::sBoundTextureMemoryInBytes = 0; @@ -102,7 +102,7 @@ F32 LLViewerTexture::sCurrentTime = 0.0f ; BOOL LLViewerTexture::sUseTextureAtlas = FALSE ; const F32 desired_discard_bias_min = -2.0f; // -max number of levels to improve image quality by -const F32 desired_discard_bias_max = 1.5f; // max number of levels to reduce image quality by +const F32 desired_discard_bias_max = (F32)MAX_DISCARD_LEVEL; // max number of levels to reduce image quality by const F64 log_2 = log(2.0); //---------------------------------------------------------------------------------------------- @@ -369,7 +369,7 @@ S32 LLViewerTexture::getCategoryFromIndex(S32 index) } // tuning params -const F32 discard_bias_delta = .05f; +const F32 discard_bias_delta = .25f; const F32 discard_delta_time = 0.5f; const S32 min_non_tex_system_mem = (128<<20); // 128 MB // non-const (used externally @@ -1424,9 +1424,8 @@ BOOL LLViewerFetchedTexture::createTexture(S32 usename/*= 0*/) if (!mForceToSaveRawImage) { mNeedsAux = FALSE; - } destroyRawImage(); - + } return res; } @@ -2749,7 +2748,7 @@ void LLViewerLODTexture::processTextureStats() mCalculatedDiscardLevel = discard_level; } } - if (mBoostLevel < LLViewerTexture::BOOST_HIGH) + if (mBoostLevel < LLViewerTexture::BOOST_SCULPTED) { discard_level += sDesiredDiscardBias; discard_level *= sDesiredDiscardScale; // scale @@ -2775,8 +2774,7 @@ void LLViewerLODTexture::processTextureStats() // S32 current_discard = getDiscardLevel(); - if ((sDesiredDiscardBias > 0.0f) && - (current_discard >= 0 && mDesiredDiscardLevel >= current_discard)) + if (sDesiredDiscardBias > 0.0f && mBoostLevel < LLViewerTexture::BOOST_SCULPTED && current_discard >= 0) { // Limit the amount of GL memory bound each frame if ( BYTES_TO_MEGA_BYTES(sBoundTextureMemoryInBytes) > sMaxBoundTextureMemInMegaBytes * texmem_middle_bound_scale && diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index 84377198eb..a09a711cc7 100644 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -300,7 +300,7 @@ public: static S32 sImageCount; static S32 sRawCount; static S32 sAuxCount; - static LLTimer sEvaluationTimer; + static LLFrameTimer sEvaluationTimer; static F32 sDesiredDiscardBias; static F32 sDesiredDiscardScale; static S32 sBoundTextureMemoryInBytes; @@ -455,6 +455,7 @@ public: F32 getElapsedLastReferencedSavedRawImageTime() const ; BOOL isFullyLoaded() const; + BOOL hasFetcher() const { return mHasFetcher;} protected: /*virtual*/ void switchToCachedImage(); S32 getCurrentDiscardLevelForFetching() ; diff --git a/indra/newview/skins/default/xui/da/floater_tools.xml b/indra/newview/skins/default/xui/da/floater_tools.xml index 77459aca67..2e35811133 100644 --- a/indra/newview/skins/default/xui/da/floater_tools.xml +++ b/indra/newview/skins/default/xui/da/floater_tools.xml @@ -212,8 +212,8 @@ Næste ejer: - - + + B: diff --git a/indra/newview/skins/default/xui/de/floater_about_land.xml b/indra/newview/skins/default/xui/de/floater_about_land.xml index 05e2d4d754..186c2932c3 100644 --- a/indra/newview/skins/default/xui/de/floater_about_land.xml +++ b/indra/newview/skins/default/xui/de/floater_about_land.xml @@ -1,5 +1,14 @@ + + "Parcel_PG_Dark" + + + "Parcel_M_Dark" + + + "Parcel_R_Dark" + [MINUTES] Minuten @@ -15,7 +24,7 @@ - Nur neue Benutzer + Nur neue Einwohner Jeder @@ -388,10 +397,6 @@ Nur große Parzellen können in der Suche aufgeführt werden. Homepage: