diff options
235 files changed, 10500 insertions, 6207 deletions
diff --git a/indra/integration_tests/llui_libtest/llui_libtest.cpp b/indra/integration_tests/llui_libtest/llui_libtest.cpp index f8caa7990b..1e5de74e92 100644 --- a/indra/integration_tests/llui_libtest/llui_libtest.cpp +++ b/indra/integration_tests/llui_libtest/llui_libtest.cpp @@ -104,25 +104,27 @@ static std::string get_xui_dir() return gDirUtilp->getAppRODataDir() + delim + std::string("skins") + delim + "default" + delim + "xui" + delim; } -int main(int argc, char** argv) +void init_llui() { - // Must init LLError for llerrs to actually cause errors. - LLError::initForApplication("."); - // Font lookup needs directory support - gDirUtilp->initAppDirs("SecondLife", "../../../newview"); +#if LL_DARWIN + const char* newview_path = "../../../../newview"; +#else + const char* newview_path = "../../../newview"; +#endif + gDirUtilp->initAppDirs("SecondLife", newview_path); gDirUtilp->setSkinFolder("default"); - + std::string config_filename = gDirUtilp->getExpandedFilename( - LL_PATH_APP_SETTINGS, "settings.xml"); + LL_PATH_APP_SETTINGS, "settings.xml"); LLControlGroup config_group("config"); config_group.loadFromFile(config_filename); - + std::string color_filename = gDirUtilp->getExpandedFilename( - LL_PATH_DEFAULT_SKIN, "colors.xml"); + LL_PATH_DEFAULT_SKIN, "colors.xml"); LLControlGroup color_group("color"); color_group.loadFromFile(color_filename); - + LLControlGroup floater_group("floater"); LLControlGroup ignores_group("ignores"); LLUI::settings_map_t settings; @@ -130,14 +132,14 @@ int main(int argc, char** argv) settings["color"] = &color_group; settings["floater"] = &floater_group; settings["ignores"] = &ignores_group; - + // Don't use real images as we don't have a GL context TestImageProvider image_provider; LLUI::initClass(settings, &image_provider); - + const bool no_register_widgets = false; LLWidgetReg::initClass( no_register_widgets ); - + // Unclear if this is needed LLUI::setupPaths(); // Otherwise we get translation warnings when setting up floaters @@ -146,14 +148,14 @@ int main(int argc, char** argv) LLTrans::parseStrings("strings.xml", default_args); LLFontManager::initClass(); - + // Creating widgets apparently requires fonts to be initialized, // otherwise it crashes. LLFontGL::initClass(96.f, 1.f, 1.f, - gDirUtilp->getAppRODataDir(), - LLUI::getXUIPaths(), - false ); // don't create gl textures - + gDirUtilp->getAppRODataDir(), + LLUI::getXUIPaths(), + false ); // don't create gl textures + LLFloaterView::Params fvparams; fvparams.name("Floater View"); fvparams.rect( LLRect(0,480,640,0) ); @@ -161,7 +163,10 @@ int main(int argc, char** argv) fvparams.follows.flags(FOLLOWS_ALL); fvparams.tab_stop(false); gFloaterView = LLUICtrlFactory::create<LLFloaterView> (fvparams); +} +void export_test_floaters() +{ // Convert all test floaters to new XML format std::string delim = gDirUtilp->getDirDelimiter(); std::string xui_dir = get_xui_dir() + "en" + delim; @@ -178,19 +183,30 @@ int main(int argc, char** argv) LLXMLNodePtr output_node = new LLXMLNode(); LLFloater* floater = new LLFloater(); LLUICtrlFactory::getInstance()->buildFloater(floater, - filename, - FALSE, // don't open floater - output_node); + filename, + FALSE, // don't open floater + output_node); std::string out_filename = xui_dir + filename; std::string::size_type extension_pos = out_filename.rfind(".xml"); out_filename.resize(extension_pos); out_filename += "_new.xml"; - + llinfos << "Output: " << out_filename << llendl; LLFILE* floater_file = LLFile::fopen(out_filename.c_str(), "w"); LLXMLNode::writeHeaderToFile(floater_file); output_node->writeToFile(floater_file); fclose(floater_file); } +} + +int main(int argc, char** argv) +{ + // Must init LLError for llerrs to actually cause errors. + LLError::initForApplication("."); + + init_llui(); + + export_test_floaters(); + return 0; } diff --git a/indra/integration_tests/llui_libtest/llwidgetreg.cpp b/indra/integration_tests/llui_libtest/llwidgetreg.cpp index 417f3059d6..4e59971f29 100644 --- a/indra/integration_tests/llui_libtest/llwidgetreg.cpp +++ b/indra/integration_tests/llui_libtest/llwidgetreg.cpp @@ -62,45 +62,45 @@ void LLWidgetReg::initClass(bool register_widgets) // references to the object files. if (register_widgets) { - LLDefaultWidgetRegistry::Register<LLButton> button("button"); - LLDefaultWidgetRegistry::Register<LLCheckBoxCtrl> check_box("check_box"); - LLDefaultWidgetRegistry::Register<LLComboBox> combo_box("combo_box"); - LLDefaultWidgetRegistry::Register<LLFlyoutButton> flyout_button("flyout_button"); - LLDefaultWidgetRegistry::Register<LLContainerView> container_view("container_view"); - LLDefaultWidgetRegistry::Register<LLIconCtrl> icon("icon"); - LLDefaultWidgetRegistry::Register<LLLineEditor> line_editor("line_editor"); - LLDefaultWidgetRegistry::Register<LLSearchEditor> search_editor("search_editor"); - LLDefaultWidgetRegistry::Register<LLMenuItemSeparatorGL> menu_item_separator("menu_item_separator"); - LLDefaultWidgetRegistry::Register<LLMenuItemCallGL> menu_item_call_gl("menu_item_call"); - LLDefaultWidgetRegistry::Register<LLMenuItemCheckGL> menu_item_check_gl("menu_item_check"); - LLDefaultWidgetRegistry::Register<LLMenuGL> menu("menu"); - LLDefaultWidgetRegistry::Register<LLMenuBarGL> menu_bar("menu_bar"); - LLDefaultWidgetRegistry::Register<LLContextMenu> context_menu("context_menu"); - LLDefaultWidgetRegistry::Register<LLMultiSlider> multi_slider_bar("multi_slider_bar"); - LLDefaultWidgetRegistry::Register<LLMultiSliderCtrl> multi_slider("multi_slider"); - LLDefaultWidgetRegistry::Register<LLPanel> panel("panel", &LLPanel::fromXML); - LLDefaultWidgetRegistry::Register<LLLayoutStack> layout_stack("layout_stack", &LLLayoutStack::fromXML); - LLDefaultWidgetRegistry::Register<LLProgressBar> progress_bar("progress_bar"); - LLDefaultWidgetRegistry::Register<LLRadioGroup> radio_group("radio_group"); - LLDefaultWidgetRegistry::Register<LLRadioCtrl> radio_item("radio_item"); - LLDefaultWidgetRegistry::Register<LLScrollContainer> scroll_container("scroll_container"); - LLDefaultWidgetRegistry::Register<LLScrollingPanelList> scrolling_panel_list("scrolling_panel_list"); - LLDefaultWidgetRegistry::Register<LLScrollListCtrl> scroll_list("scroll_list"); - LLDefaultWidgetRegistry::Register<LLSlider> slider_bar("slider_bar"); - LLDefaultWidgetRegistry::Register<LLSliderCtrl> slider("slider"); - LLDefaultWidgetRegistry::Register<LLSpinCtrl> spinner("spinner"); - LLDefaultWidgetRegistry::Register<LLStatBar> stat_bar("stat_bar"); - //LLDefaultWidgetRegistry::Register<LLPlaceHolderPanel> placeholder("placeholder"); - LLDefaultWidgetRegistry::Register<LLTabContainer> tab_container("tab_container"); - LLDefaultWidgetRegistry::Register<LLTextBox> text("text"); - LLDefaultWidgetRegistry::Register<LLTextEditor> simple_text_editor("simple_text_editor"); - LLDefaultWidgetRegistry::Register<LLUICtrl> ui_ctrl("ui_ctrl"); - LLDefaultWidgetRegistry::Register<LLStatView> stat_view("stat_view"); - //LLDefaultWidgetRegistry::Register<LLUICtrlLocate> locate("locate"); - //LLDefaultWidgetRegistry::Register<LLUICtrlLocate> pad("pad"); - LLDefaultWidgetRegistry::Register<LLViewBorder> view_border("view_border"); + LLDefaultChildRegistry::Register<LLButton> button("button"); + LLDefaultChildRegistry::Register<LLCheckBoxCtrl> check_box("check_box"); + LLDefaultChildRegistry::Register<LLComboBox> combo_box("combo_box"); + LLDefaultChildRegistry::Register<LLFlyoutButton> flyout_button("flyout_button"); + LLDefaultChildRegistry::Register<LLContainerView> container_view("container_view"); + LLDefaultChildRegistry::Register<LLIconCtrl> icon("icon"); + LLDefaultChildRegistry::Register<LLLineEditor> line_editor("line_editor"); + LLDefaultChildRegistry::Register<LLSearchEditor> search_editor("search_editor"); + LLDefaultChildRegistry::Register<LLMenuItemSeparatorGL> menu_item_separator("menu_item_separator"); + LLDefaultChildRegistry::Register<LLMenuItemCallGL> menu_item_call_gl("menu_item_call"); + LLDefaultChildRegistry::Register<LLMenuItemCheckGL> menu_item_check_gl("menu_item_check"); + LLDefaultChildRegistry::Register<LLMenuGL> menu("menu"); + LLDefaultChildRegistry::Register<LLMenuBarGL> menu_bar("menu_bar"); + LLDefaultChildRegistry::Register<LLContextMenu> context_menu("context_menu"); + LLDefaultChildRegistry::Register<LLMultiSlider> multi_slider_bar("multi_slider_bar"); + LLDefaultChildRegistry::Register<LLMultiSliderCtrl> multi_slider("multi_slider"); + LLDefaultChildRegistry::Register<LLPanel> panel("panel", &LLPanel::fromXML); + LLDefaultChildRegistry::Register<LLLayoutStack> layout_stack("layout_stack", &LLLayoutStack::fromXML); + LLDefaultChildRegistry::Register<LLProgressBar> progress_bar("progress_bar"); + LLDefaultChildRegistry::Register<LLRadioGroup> radio_group("radio_group"); + LLDefaultChildRegistry::Register<LLRadioCtrl> radio_item("radio_item"); + LLDefaultChildRegistry::Register<LLScrollContainer> scroll_container("scroll_container"); + LLDefaultChildRegistry::Register<LLScrollingPanelList> scrolling_panel_list("scrolling_panel_list"); + LLDefaultChildRegistry::Register<LLScrollListCtrl> scroll_list("scroll_list"); + LLDefaultChildRegistry::Register<LLSlider> slider_bar("slider_bar"); + LLDefaultChildRegistry::Register<LLSliderCtrl> slider("slider"); + LLDefaultChildRegistry::Register<LLSpinCtrl> spinner("spinner"); + LLDefaultChildRegistry::Register<LLStatBar> stat_bar("stat_bar"); + //LLDefaultChildRegistry::Register<LLPlaceHolderPanel> placeholder("placeholder"); + LLDefaultChildRegistry::Register<LLTabContainer> tab_container("tab_container"); + LLDefaultChildRegistry::Register<LLTextBox> text("text"); + LLDefaultChildRegistry::Register<LLTextEditor> simple_text_editor("simple_text_editor"); + LLDefaultChildRegistry::Register<LLUICtrl> ui_ctrl("ui_ctrl"); + LLDefaultChildRegistry::Register<LLStatView> stat_view("stat_view"); + //LLDefaultChildRegistry::Register<LLUICtrlLocate> locate("locate"); + //LLDefaultChildRegistry::Register<LLUICtrlLocate> pad("pad"); + LLDefaultChildRegistry::Register<LLViewBorder> view_border("view_border"); } // *HACK: Usually this is registered as a viewer text editor - LLDefaultWidgetRegistry::Register<LLTextEditor> text_editor("text_editor"); + LLDefaultChildRegistry::Register<LLTextEditor> text_editor("text_editor"); } diff --git a/indra/integration_tests/llui_libtest/llwidgetreg.h b/indra/integration_tests/llui_libtest/llwidgetreg.h index eac818608d..4e0bc5377a 100644 --- a/indra/integration_tests/llui_libtest/llwidgetreg.h +++ b/indra/integration_tests/llui_libtest/llwidgetreg.h @@ -33,7 +33,7 @@ // Register all widgets with the builder registry. // Useful on Windows where linker discards all references to the -// static LLDefaultWidgetRegistry::Register<> calls. +// static LLDefaultChildRegistry::Register<> calls. class LLWidgetReg { public: diff --git a/indra/llinventory/llpermissionsflags.h b/indra/llinventory/llpermissionsflags.h index afa2adbd90..f810929d68 100644 --- a/indra/llinventory/llpermissionsflags.h +++ b/indra/llinventory/llpermissionsflags.h @@ -32,9 +32,6 @@ #ifndef LL_LLPERMISSIONSFLAGS_H #define LL_LLPERMISSIONSFLAGS_H -// llpermissionsflags.h -// Copyright 2002, Linden Research, Inc. -// // Flags for various permissions bits. // Shared between viewer and simulator. diff --git a/indra/llrender/llfontgl.h b/indra/llrender/llfontgl.h index 204c6908af..77cd12250c 100644 --- a/indra/llrender/llfontgl.h +++ b/indra/llrender/llfontgl.h @@ -264,7 +264,7 @@ protected: typedef std::map<llwchar,embedded_data_t*> embedded_map_t; mutable embedded_map_t mEmbeddedChars; - LLFontDescriptor mFontDesc; + LLFontDescriptor mFontDescriptor; // Registry holds all instantiated fonts. static LLFontRegistry* sFontRegistry; @@ -276,8 +276,8 @@ public: static LLCoordFont sCurOrigin; static std::vector<LLCoordFont> sOriginStack; - const LLFontDescriptor &getFontDesc() const { return mFontDesc; } - void setFontDesc(const LLFontDescriptor& font_desc) { mFontDesc = font_desc; } + const LLFontDescriptor &getFontDesc() const { return mFontDescriptor; } + void setFontDesc(const LLFontDescriptor& font_desc) { mFontDescriptor = font_desc; } }; #endif diff --git a/indra/llrender/llfontregistry.cpp b/indra/llrender/llfontregistry.cpp index 18e4a6915d..3b5c62a5ea 100644 --- a/indra/llrender/llfontregistry.cpp +++ b/indra/llrender/llfontregistry.cpp @@ -104,7 +104,7 @@ bool removeSubString(std::string& str, const std::string& substr) size_t pos = str.find(substr); if (pos != string::npos) { - str.replace(pos,substr.length(),(const char *)NULL, 0); + str.erase(pos); return true; } return false; diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp index f2aa9c0d4c..9ad27e7c41 100644 --- a/indra/llui/llbutton.cpp +++ b/indra/llui/llbutton.cpp @@ -32,7 +32,6 @@ #include "linden_common.h" -#define INSTANTIATE_GETCHILD_BUTTON #include "llbutton.h" // Linden library includes @@ -53,7 +52,7 @@ #include "llrender.h" #include "lluictrlfactory.h" -static LLDefaultWidgetRegistry::Register<LLButton> r("button"); +static LLDefaultChildRegistry::Register<LLButton> r("button"); // globals loaded from settings.xml S32 LLBUTTON_H_PAD = 0; @@ -61,8 +60,6 @@ S32 LLBUTTON_V_PAD = 0; S32 BTN_HEIGHT_SMALL= 0; S32 BTN_HEIGHT = 0; -template LLButton* LLView::getChild<LLButton>( const std::string& name, BOOL recurse, BOOL create_if_missing ) const; - LLButton::Params::Params() : label_selected("label_selected"), // requires is_toggle true label_dropshadow("label_shadow", true), @@ -146,7 +143,7 @@ LLButton::LLButton(const LLButton::Params& p) mFadeWhenDisabled(FALSE) { static LLUICachedControl<S32> llbutton_orig_h_pad ("UIButtonOrigHPad", 0); - static Params default_params(LLUICtrlFactory::getDefaultParams<Params>()); + static Params default_params(LLUICtrlFactory::getDefaultParams<LLButton>()); //if we aren't a picture_style button set label as name if not provided if (!p.picture_style.isProvided() || !p.picture_style) @@ -328,25 +325,27 @@ BOOL LLButton::handleKeyHere(KEY key, MASK mask ) BOOL LLButton::handleMouseDown(S32 x, S32 y, MASK mask) { - // Route future Mouse messages here preemptively. (Release on mouse up.) - gFocusMgr.setMouseCapture( this ); - - if (hasTabStop() && !getIsChrome()) + if (!childrenHandleMouseDown(x, y, mask)) { - setFocus(TRUE); - } + // Route future Mouse messages here preemptively. (Release on mouse up.) + gFocusMgr.setMouseCapture( this ); - mMouseDownSignal(this, LLSD()); + if (hasTabStop() && !getIsChrome()) + { + setFocus(TRUE); + } - mMouseDownTimer.start(); - mMouseDownFrame = (S32) LLFrameTimer::getFrameCount(); - mMouseHeldDownCount = 0; - - if (getSoundFlags() & MOUSE_DOWN) - { - make_ui_sound("UISndClick"); - } + mMouseDownSignal(this, LLSD()); + mMouseDownTimer.start(); + mMouseDownFrame = (S32) LLFrameTimer::getFrameCount(); + mMouseHeldDownCount = 0; + + if (getSoundFlags() & MOUSE_DOWN) + { + make_ui_sound("UISndClick"); + } + } return TRUE; } @@ -381,20 +380,26 @@ BOOL LLButton::handleMouseUp(S32 x, S32 y, MASK mask) LLUICtrl::onCommit(); } } + else + { + childrenHandleMouseUp(x, y, mask); + } return TRUE; } BOOL LLButton::handleRightMouseDown(S32 x, S32 y, MASK mask) { - // Route future Mouse messages here preemptively. (Release on mouse up.) - gFocusMgr.setMouseCapture( this ); - - if (hasTabStop() && !getIsChrome()) + if (!childrenHandleRightMouseDown(x, y, mask)) { - setFocus(TRUE); - } + // Route future Mouse messages here preemptively. (Release on mouse up.) + gFocusMgr.setMouseCapture( this ); + if (hasTabStop() && !getIsChrome()) + { + setFocus(TRUE); + } + } return TRUE; } @@ -412,6 +417,10 @@ BOOL LLButton::handleRightMouseUp(S32 x, S32 y, MASK mask) mRightClickSignal(this, getValue()); } } + else + { + childrenHandleRightMouseUp(x, y, mask); + } return TRUE; } @@ -429,21 +438,23 @@ void LLButton::onMouseLeave(S32 x, S32 y, MASK mask) BOOL LLButton::handleHover(S32 x, S32 y, MASK mask) { - if (mMouseDownTimer.getStarted()) + if (!childrenHandleHover(x, y, mask)) { - F32 elapsed = getHeldDownTime(); - if( mHeldDownDelay <= elapsed && mHeldDownFrameDelay <= (S32)LLFrameTimer::getFrameCount() - mMouseDownFrame) + if (mMouseDownTimer.getStarted()) { - LLSD param; - param["count"] = mMouseHeldDownCount++; - mHeldDownSignal(this, param); + F32 elapsed = getHeldDownTime(); + if( mHeldDownDelay <= elapsed && mHeldDownFrameDelay <= (S32)LLFrameTimer::getFrameCount() - mMouseDownFrame) + { + LLSD param; + param["count"] = mMouseHeldDownCount++; + mHeldDownSignal(this, param); + } } - } - - // We only handle the click if the click both started and ended within us - getWindow()->setCursor(UI_CURSOR_ARROW); - lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << llendl; + // We only handle the click if the click both started and ended within us + getWindow()->setCursor(UI_CURSOR_ARROW); + lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << llendl; + } return TRUE; } diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h index 1398e5c14b..3fa62cc351 100644 --- a/indra/llui/llbutton.h +++ b/indra/llui/llbutton.h @@ -352,11 +352,5 @@ private: LLFrameTimer mFlashingTimer; }; -#ifdef LL_WINDOWS -#ifndef INSTANTIATE_GETCHILD_BUTTON -#pragma warning (disable : 4231) -extern template LLButton* LLView::getChild<LLButton>( const std::string& name, BOOL recurse, BOOL create_if_missing ) const; -#endif -#endif #endif // LL_LLBUTTON_H diff --git a/indra/llui/llcheckboxctrl.cpp b/indra/llui/llcheckboxctrl.cpp index 932a1b6297..b43f91e766 100644 --- a/indra/llui/llcheckboxctrl.cpp +++ b/indra/llui/llcheckboxctrl.cpp @@ -31,8 +31,6 @@ */ // The mutants are coming! -#define INSTANTIATE_GETCHILD_CHECKBOX - #include "linden_common.h" #include "llcheckboxctrl.h" @@ -50,9 +48,7 @@ const U32 MAX_STRING_LENGTH = 10; -template LLCheckBoxCtrl* LLView::getChild<LLCheckBoxCtrl>( const std::string& name, BOOL recurse, BOOL create_if_missing ) const; - -static LLDefaultWidgetRegistry::Register<LLCheckBoxCtrl> r("check_box"); +static LLDefaultChildRegistry::Register<LLCheckBoxCtrl> r("check_box"); LLCheckBoxCtrl::Params::Params() : text_enabled_color("text_enabled_color"), diff --git a/indra/llui/llcheckboxctrl.h b/indra/llui/llcheckboxctrl.h index 2f8f088a3e..2f8e8fdd23 100644 --- a/indra/llui/llcheckboxctrl.h +++ b/indra/llui/llcheckboxctrl.h @@ -126,11 +126,4 @@ protected: }; -#ifdef LL_WINDOWS -#ifndef INSTANTIATE_GETCHILD_CHECKBOX -#pragma warning (disable : 4231) -extern template LLCheckBoxCtrl* LLView::getChild<LLCheckBoxCtrl>( const std::string& name, BOOL recurse, BOOL create_if_missing ) const; -#endif -#endif - #endif // LL_LLCHECKBOXCTRL_H diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp index e19eacb774..5dfca4be16 100644 --- a/indra/llui/llcombobox.cpp +++ b/indra/llui/llcombobox.cpp @@ -33,8 +33,6 @@ // A control that displays the name of the chosen item, which when // clicked shows a scrolling box of options. -#define INSTANTIATE_GETCHILD_COMBOBOX - #include "linden_common.h" // file includes @@ -63,9 +61,7 @@ S32 LLCOMBOBOX_HEIGHT = 0; S32 LLCOMBOBOX_WIDTH = 0; S32 MAX_COMBO_WIDTH = 500; -template LLComboBox* LLView::getChild<LLComboBox>( const std::string& name, BOOL recurse, BOOL create_if_missing ) const; - -static LLDefaultWidgetRegistry::Register<LLComboBox> register_combo_box("combo_box"); +static LLDefaultChildRegistry::Register<LLComboBox> register_combo_box("combo_box"); void LLComboBox::PreferredPositionValues::declareValues() { diff --git a/indra/llui/llcombobox.h b/indra/llui/llcombobox.h index cb5f72dcbe..4c0d10dc40 100644 --- a/indra/llui/llcombobox.h +++ b/indra/llui/llcombobox.h @@ -234,12 +234,4 @@ private: commit_callback_t mTextEntryCallback; commit_callback_t mSelectionCallback; }; - -#ifdef LL_WINDOWS -#ifndef INSTANTIATE_GETCHILD_COMBOBOX -#pragma warning (disable : 4231) -extern template LLComboBox* LLView::getChild<LLComboBox>( const std::string& name, BOOL recurse, BOOL create_if_missing ) const; -#endif -#endif - #endif diff --git a/indra/llui/llcontainerview.cpp b/indra/llui/llcontainerview.cpp index 40cc430e25..96948b659f 100644 --- a/indra/llui/llcontainerview.cpp +++ b/indra/llui/llcontainerview.cpp @@ -42,7 +42,7 @@ #include "llscrollcontainer.h" #include "lluictrlfactory.h" -static LLDefaultWidgetRegistry::Register<LLContainerView> r("container_view"); +static LLDefaultChildRegistry::Register<LLContainerView> r("container_view"); LLContainerView::LLContainerView(const LLContainerView::Params& p) : LLView(p), diff --git a/indra/llui/lldraghandle.h b/indra/llui/lldraghandle.h index 0448c20068..86eef7c42c 100644 --- a/indra/llui/lldraghandle.h +++ b/indra/llui/lldraghandle.h @@ -53,8 +53,8 @@ public: Optional<LLUIColor> drag_shadow_color; Params() - : drag_highlight_color("", LLUIColorTable::instance().getColor("DefaultHighlightLight")), - drag_shadow_color("", LLUIColorTable::instance().getColor("DefaultShadowDark")) + : drag_highlight_color("drag_highlight_color", LLUIColorTable::instance().getColor("DefaultHighlightLight")), + drag_shadow_color("drag_shadow_color", LLUIColorTable::instance().getColor("DefaultShadowDark")) { mouse_opaque(true); follows.flags(FOLLOWS_ALL); diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index d37459c040..c8bbdb0a56 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -191,7 +191,7 @@ bool LLFloater::KeyCompare::equate(const LLSD& a, const LLSD& b) //static const LLFloater::Params& LLFloater::getDefaultParams() { - return LLUICtrlFactory::getDefaultParams<LLFloater::Params>(); + return LLUICtrlFactory::getDefaultParams<LLFloater>(); } @@ -560,6 +560,7 @@ void LLFloater::openFloater(const LLSD& key) setVisibleAndFrontmost(mAutoFocus); } + mOpenSignal(this, getValue()); onOpen(key); } @@ -623,6 +624,7 @@ void LLFloater::closeFloater(bool app_quitting) } // Let floater do cleanup. + mCloseSignal(this, getValue()); onClose(app_quitting); } } @@ -1709,6 +1711,33 @@ void LLFloater::buildButtons() updateButtons(); } +void LLFloater::initOpenCallback(const OpenCallbackParam& cb, open_signal_t& sig) +{ + if (cb.function.isProvided()) + { + if (cb.parameter.isProvided()) + sig.connect(boost::bind(cb.function(), _1, cb.parameter)); + else + sig.connect(cb.function()); + } + else + { + std::string function_name = cb.function_name; + open_callback_t* func = (CallbackRegistry<open_callback_t>::getValue(function_name)); + if (func) + { + if (cb.parameter.isProvided()) + sig.connect(boost::bind((*func), _1, cb.parameter)); + else + sig.connect(*func); + } + else if (!function_name.empty()) + { + llwarns << "No callback found for: '" << function_name << "' in control: " << getName() << llendl; + } + } +} + ///////////////////////////////////////////////////// // LLFloaterView @@ -2462,18 +2491,25 @@ void LLFloater::initFromParams(const LLFloater::Params& p) { mVisibilityControl = "t"; // flag to build mVisibilityControl name once mInstanceName is set } + + // open callback + if (p.open_callback.isProvided()) + initOpenCallback(p.open_callback, mOpenSignal); + // close callback + if (p.close_callback.isProvided()) + initOpenCallback(p.close_callback, mCloseSignal); } void LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, BOOL open_floater, LLXMLNodePtr output_node) { - Params params(LLUICtrlFactory::getDefaultParams<LLFloater::Params>()); + Params params(LLUICtrlFactory::getDefaultParams<LLFloater>()); LLXUIParser::instance().readXUI(node, params); if (output_node) { Params output_params(params); setupParamsForExport(output_params, parent); - Params default_params(LLUICtrlFactory::getDefaultParams<LLFloater::Params>()); + Params default_params(LLUICtrlFactory::getDefaultParams<LLFloater>()); output_node->setName(node->getName()->mString); LLXUIParser::instance().writeXUI( output_node, output_params, &default_params); @@ -2490,7 +2526,7 @@ void LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, BOOL open_floa LLFloater::setFloaterHost((LLMultiFloater*) this); } - LLUICtrlFactory::createChildren(this, node, output_node); + LLUICtrlFactory::createChildren(this, node, child_registry_t::instance(), output_node); if (node->hasName("multi_floater")) { diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h index 3e80f1b284..c639f90390 100644 --- a/indra/llui/llfloater.h +++ b/indra/llui/llfloater.h @@ -105,6 +105,17 @@ public: BUTTON_COUNT }; + typedef boost::function<void (LLUICtrl* ctrl, const LLSD& param)> open_callback_t; + typedef boost::signals2::signal<void (LLUICtrl* ctrl, const LLSD& param)> open_signal_t; + + typedef boost::function<void (LLUICtrl* ctrl, const LLSD& param)> close_callback_t; + typedef boost::signals2::signal<void (LLUICtrl* ctrl, const LLSD& param)> close_signal_t; + + struct OpenCallbackParam : public LLInitParam::Block<OpenCallbackParam, CallbackParam > + { + Optional<open_callback_t> function; + }; + struct Params : public LLInitParam::Block<Params, LLPanel::Params> { @@ -120,7 +131,10 @@ public: can_tear_off, save_rect, save_visibility; - + + Optional<OpenCallbackParam> open_callback, + close_callback; + Params() : title("title"), short_title("short_title"), @@ -132,7 +146,9 @@ public: can_drag_on_left("can_drag_on_left", false), can_tear_off("can_tear_off", true), save_rect("save_rect", false), - save_visibility("save_visibility", false) + save_visibility("save_visibility", false), + open_callback("open_callback"), + close_callback("close_callback") { name = "floater"; // defaults that differ from LLPanel: @@ -289,8 +305,9 @@ protected: void destroy() { die(); } // Don't call this directly. You probably want to call close(). JC + void initOpenCallback(const OpenCallbackParam& cb, open_signal_t& sig); + private: - void setForeground(BOOL b); // called only by floaterview void cleanupHandles(); // remove handles to dead floaters void createMinimizeButton(); @@ -299,11 +316,15 @@ private: BOOL offerClickToButton(S32 x, S32 y, MASK mask, EFloaterButtons index); void addResizeCtrls(); void addDragHandle(); - + +public: + typedef CallbackRegistry<open_callback_t> OpenCallbackRegistry; + protected: std::string mRectControl; std::string mVisibilityControl; - + open_signal_t mOpenSignal; + open_signal_t mCloseSignal; LLSD mKey; // Key used for retrieving instances; set (for now) by LLFLoaterReg private: @@ -378,6 +399,7 @@ private: LLRootHandle<LLFloater> mHandle; }; + ///////////////////////////////////////////////////////////// // LLFloaterView // Parent of all floating panels @@ -441,9 +463,6 @@ private: S32 mSnapOffsetRight; }; -// singleton implementation for floaters -// https://wiki.lindenlab.com/mediawiki/index.php?title=LLFloaterSingleton&oldid=164990 - //******************************************************* //* TO BE DEPRECATED //******************************************************* @@ -460,14 +479,6 @@ public: static void hide(LLFloater* instance, const LLSD& key); }; - -// singleton implementation for floaters (provides visibility policy) -// https://wiki.lindenlab.com/mediawiki/index.php?title=LLFloaterSingleton&oldid=164990 - -template <class T> class LLFloaterSingleton : public LLUISingleton<T, VisibilityPolicy<LLFloater> > -{ -}; - // // Globals // diff --git a/indra/llui/llflyoutbutton.cpp b/indra/llui/llflyoutbutton.cpp index a99c3a4fe6..536919c072 100644 --- a/indra/llui/llflyoutbutton.cpp +++ b/indra/llui/llflyoutbutton.cpp @@ -35,7 +35,7 @@ // file includes #include "llflyoutbutton.h" -//static LLDefaultWidgetRegistry::Register<LLFlyoutButton> r2("flyout_button"); +//static LLDefaultChildRegistry::Register<LLFlyoutButton> r2("flyout_button"); const S32 FLYOUT_BUTTON_ARROW_WIDTH = 24; diff --git a/indra/llui/lliconctrl.cpp b/indra/llui/lliconctrl.cpp index eddfc71284..5c6ea663f3 100644 --- a/indra/llui/lliconctrl.cpp +++ b/indra/llui/lliconctrl.cpp @@ -42,7 +42,7 @@ #include "lluictrlfactory.h" #include "lluiimage.h" -static LLDefaultWidgetRegistry::Register<LLIconCtrl> r("icon"); +static LLDefaultChildRegistry::Register<LLIconCtrl> r("icon"); LLIconCtrl::Params::Params() : image("image_name"), diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp index 39dac296ea..f1e7d791d4 100644 --- a/indra/llui/lllayoutstack.cpp +++ b/indra/llui/lllayoutstack.cpp @@ -38,7 +38,7 @@ #include "llresizebar.h" #include "llcriticaldamp.h" -static LLDefaultWidgetRegistry::Register<LLLayoutStack> register_layout_stack("layout_stack", &LLLayoutStack::fromXML); +static LLDefaultChildRegistry::Register<LLLayoutStack> register_layout_stack("layout_stack", &LLLayoutStack::fromXML); // @@ -223,7 +223,7 @@ static void get_attribute_bool_and_write(LLXMLNodePtr node, //static LLView* LLLayoutStack::fromXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node) { - LLLayoutStack::Params p(LLUICtrlFactory::getDefaultParams<LLLayoutStack::Params>()); + LLLayoutStack::Params p(LLUICtrlFactory::getDefaultParams<LLLayoutStack>()); LLXUIParser::instance().readXUI(node, p); // Export must happen before setupParams() mungles rectangles and before @@ -233,7 +233,7 @@ LLView* LLLayoutStack::fromXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr o { Params output_params(p); setupParamsForExport(output_params, parent); - LLLayoutStack::Params default_params(LLUICtrlFactory::getDefaultParams<LLLayoutStack::Params>()); + LLLayoutStack::Params default_params(LLUICtrlFactory::getDefaultParams<LLLayoutStack>()); output_node->setName(node->getName()->mString); LLXUIParser::instance().writeXUI( output_node, output_params, &default_params); @@ -296,7 +296,7 @@ LLView* LLLayoutStack::fromXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr o LLPanel::Params p; LLPanel* panelp = LLUICtrlFactory::create<LLPanel>(p); - LLView* new_child = LLUICtrlFactory::getInstance()->createFromXML(child_node, panelp, LLStringUtil::null, output_child, parent ? parent->getChildRegistry() : LLDefaultWidgetRegistry::instance()); + LLView* new_child = LLUICtrlFactory::getInstance()->createFromXML(child_node, panelp, LLStringUtil::null, LLPanel::child_registry_t::instance(), output_child); if (new_child) { // put child in new embedded panel diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index 925f22d94e..f3afadca15 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -34,8 +34,6 @@ #include "linden_common.h" -#define INSTANTIATE_GETCHILD_LINEEDITOR - #include "lllineeditor.h" #include "lltexteditor.h" @@ -72,9 +70,7 @@ const S32 SCROLL_INCREMENT_DEL = 4; // make space for baskspacing const F32 AUTO_SCROLL_TIME = 0.05f; const F32 TRIPLE_CLICK_INTERVAL = 0.3f; // delay between double and triple click. *TODO: make this equal to the double click interval? -static LLDefaultWidgetRegistry::Register<LLLineEditor> r1("line_editor"); - -template LLLineEditor* LLView::getChild<LLLineEditor>( const std::string& name, BOOL recurse, BOOL create_if_missing ) const; +static LLDefaultChildRegistry::Register<LLLineEditor> r1("line_editor"); // // Member functions @@ -180,7 +176,7 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p) LLViewBorder::Params border_p(p.border); border_p.rect = border_rect; border_p.follows.flags = FOLLOWS_ALL; - border_p.bevel_type = LLViewBorder::BEVEL_IN; + border_p.bevel_style = LLViewBorder::BEVEL_IN; mBorder = LLUICtrlFactory::create<LLViewBorder>(border_p); addChild( mBorder ); diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h index eb021bace9..4362cff2fe 100644 --- a/indra/llui/lllineeditor.h +++ b/indra/llui/lllineeditor.h @@ -392,12 +392,6 @@ private: }; // end class LLLineEditor -#ifdef LL_WINDOWS -#ifndef INSTANTIATE_GETCHILD_LINEEDITOR -#pragma warning (disable : 4231) -extern template LLLineEditor* LLView::getChild<LLLineEditor>( const std::string& name, BOOL recurse, BOOL create_if_missing ) const; -#endif -#endif namespace LLInitParam { diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index e79afe76d8..4d2374a7e8 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -119,16 +119,12 @@ const F32 PIE_SHRINK_TIME = 0.2f; // time of transition between unbounded and bo const F32 ACTIVATE_HIGHLIGHT_TIME = 0.3f; -// widget registrars -struct MenuRegistry : public LLWidgetRegistry<MenuRegistry> -{}; - static MenuRegistry::Register<LLMenuItemSeparatorGL> register_separator("menu_item_separator"); static MenuRegistry::Register<LLMenuItemCallGL> register_menu_item_call("menu_item_call"); static MenuRegistry::Register<LLMenuItemCheckGL> register_menu_item_check("menu_item_check"); static MenuRegistry::Register<LLMenuGL> register_menu("menu"); -static LLDefaultWidgetRegistry::Register<LLMenuGL> register_menu_default("menu"); +static LLDefaultChildRegistry::Register<LLMenuGL> register_menu_default("menu"); @@ -1666,12 +1662,6 @@ BOOL LLMenuGL::postBuild() return LLUICtrl::postBuild(); } -const widget_registry_t& LLMenuGL::getChildRegistry() const -{ - return MenuRegistry::instance(); -} - - // are we the childmost active menu and hence our jump keys should be enabled? // or are we a free-standing torn-off menu (which uses jump keys too) BOOL LLMenuGL::jumpKeysActive() @@ -2885,7 +2875,7 @@ void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y) /// Class LLMenuBarGL ///============================================================================ -static LLDefaultWidgetRegistry::Register<LLMenuBarGL> r2("menu_bar"); +static LLDefaultChildRegistry::Register<LLMenuBarGL> r2("menu_bar"); LLMenuBarGL::LLMenuBarGL( const Params& p ) : LLMenuGL(p), @@ -3571,7 +3561,7 @@ void LLContextMenuBranch::setHighlight( BOOL highlight ) // class LLContextMenu // A context menu //----------------------------------------------------------------------------- -static LLDefaultWidgetRegistry::Register<LLContextMenu> context_menu_register("context_menu"); +static LLDefaultChildRegistry::Register<LLContextMenu> context_menu_register("context_menu"); static MenuRegistry::Register<LLContextMenu> context_menu_register2("context_menu"); diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h index ad257f46c2..ef27c2c9c8 100644 --- a/indra/llui/llmenugl.h +++ b/indra/llui/llmenugl.h @@ -81,7 +81,7 @@ public: Params() : shortcut("shortcut"), - jump_key("", KEY_NONE), + jump_key("jump_key", KEY_NONE), use_mac_ctrl("use_mac_ctrl", false), rect("rect"), left("left"), @@ -356,6 +356,11 @@ private: // it in the appendMenu() method. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// child widget registry +struct MenuRegistry : public LLChildRegistry<MenuRegistry> +{}; + + class LLMenuGL : public LLUICtrl { @@ -374,7 +379,7 @@ public: Optional<LLUIColor> bg_color; Params() - : jump_key("", KEY_NONE), + : jump_key("jump_key", KEY_NONE), can_tear_off("tear_off", false), drop_shadow("drop_shadow", true), bg_visible("bg_visible", true), @@ -388,6 +393,10 @@ public: name = "menu"; } }; + + // my valid children are contained in MenuRegistry + typedef MenuRegistry child_registry_t; + void initFromParams(const Params&); protected: @@ -410,7 +419,6 @@ public: /*virtual*/ bool addChild(LLView* view, S32 tab_group = 0); /*virtual*/ void removeChild( LLView* ctrl); /*virtual*/ BOOL postBuild(); - /*virtual*/ const widget_registry_t& getChildRegistry() const; virtual BOOL handleAcceleratorKey(KEY key, MASK mask); diff --git a/indra/llui/llmultifloater.cpp b/indra/llui/llmultifloater.cpp index c0fe7ff32d..22683d7950 100644 --- a/indra/llui/llmultifloater.cpp +++ b/indra/llui/llmultifloater.cpp @@ -275,6 +275,7 @@ void LLMultiFloater::selectPrevFloater() void LLMultiFloater::showFloater(LLFloater* floaterp, LLTabContainer::eInsertionPoint insertion_point) { + if(!floaterp) return; // we won't select a panel that already is selected // it is hard to do this internally to tab container // as tab selection is handled via index and the tab at a given @@ -288,7 +289,7 @@ void LLMultiFloater::showFloater(LLFloater* floaterp, LLTabContainer::eInsertion void LLMultiFloater::removeFloater(LLFloater* floaterp) { - if ( floaterp->getHost() != this ) + if (!floaterp || floaterp->getHost() != this ) return; floater_data_map_t::iterator found_data_it = mFloaterDataMap.find(floaterp->getHandle()); diff --git a/indra/llui/llmultislider.cpp b/indra/llui/llmultislider.cpp index 099a79278a..0454771511 100644 --- a/indra/llui/llmultislider.cpp +++ b/indra/llui/llmultislider.cpp @@ -45,7 +45,7 @@ #include <sstream> -static LLDefaultWidgetRegistry::Register<LLMultiSlider> r("multi_slider_bar"); +static LLDefaultChildRegistry::Register<LLMultiSlider> r("multi_slider_bar"); const F32 FLOAT_THRESHOLD = 0.00001f; diff --git a/indra/llui/llmultisliderctrl.cpp b/indra/llui/llmultisliderctrl.cpp index 312aceaaa2..1523d5d527 100644 --- a/indra/llui/llmultisliderctrl.cpp +++ b/indra/llui/llmultisliderctrl.cpp @@ -52,7 +52,7 @@ #include "llresmgr.h" #include "lluictrlfactory.h" -static LLDefaultWidgetRegistry::Register<LLMultiSliderCtrl> r("multi_slider"); +static LLDefaultChildRegistry::Register<LLMultiSliderCtrl> r("multi_slider"); const U32 MAX_STRING_LENGTH = 10; LLMultiSliderCtrl::Params::Params() diff --git a/indra/llui/llpanel.cpp b/indra/llui/llpanel.cpp index 6a6e15867b..2119ed4daf 100644 --- a/indra/llui/llpanel.cpp +++ b/indra/llui/llpanel.cpp @@ -56,11 +56,11 @@ #include "llbutton.h" #include "lltabcontainer.h" -static LLDefaultWidgetRegistry::Register<LLPanel> r1("panel", &LLPanel::fromXML); +static LLDefaultChildRegistry::Register<LLPanel> r1("panel", &LLPanel::fromXML); const LLPanel::Params& LLPanel::getDefaultParams() { - return LLUICtrlFactory::getDefaultParams<LLPanel::Params>(); + return LLUICtrlFactory::getDefaultParams<LLPanel>(); } LLPanel::Params::Params() @@ -433,7 +433,7 @@ void LLPanel::initFromParams(const LLPanel::Params& p) parseFollowsFlags(p); setToolTip(p.tool_tip()); - setSaveToXML(p.serializable); + setSaveToXML(p.from_xui); mHoverCursor = getCursorFromString(p.hover_cursor); @@ -462,7 +462,7 @@ static LLFastTimer::DeclareTimer FTM_PANEL_POSTBUILD("Panel PostBuild"); BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node) { - const LLPanel::Params& default_params(LLUICtrlFactory::getDefaultParams<LLPanel::Params>()); + const LLPanel::Params& default_params(LLUICtrlFactory::getDefaultParams<LLPanel>()); Params params(default_params); { @@ -499,7 +499,7 @@ BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr outpu // add children using dimensions from referenced xml for consistent layout setShape(params.rect); - LLUICtrlFactory::createChildren(this, referenced_xml); + LLUICtrlFactory::createChildren(this, referenced_xml, child_registry_t::instance()); } LLXUIParser::instance().readXUI(node, params); @@ -520,7 +520,7 @@ BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr outpu } // add children - LLUICtrlFactory::createChildren(this, node, output_node); + LLUICtrlFactory::createChildren(this, node, child_registry_t::instance(), output_node); // Connect to parent after children are built, because tab containers // do a reshape() on their child panels, which requires that the children @@ -539,12 +539,6 @@ BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr outpu return TRUE; } -const widget_registry_t& LLPanel::getChildRegistry() const -{ - // use default widget registry - return LLDefaultWidgetRegistry::instance(); -} - bool LLPanel::hasString(const std::string& name) { return mUIStrings.find(name) != mUIStrings.end(); diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h index c38e9df53b..ca3b2e7e23 100644 --- a/indra/llui/llpanel.h +++ b/indra/llui/llpanel.h @@ -93,6 +93,9 @@ public: Params(); }; + // valid children for LLPanel are stored in this registry + typedef LLDefaultChildRegistry child_registry_t; + protected: friend class LLUICtrlFactory; // RN: for some reason you can't just use LLUICtrlFactory::getDefaultParams as a default argument in VC8 @@ -165,7 +168,6 @@ public: void initFromParams(const Params& p); BOOL initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node = NULL); - /*virtual*/ const widget_registry_t& getChildRegistry() const; bool hasString(const std::string& name); std::string getString(const std::string& name, const LLStringUtil::format_map_t& args) const; diff --git a/indra/llui/llprogressbar.cpp b/indra/llui/llprogressbar.cpp index 779967940a..12353e4c3e 100644 --- a/indra/llui/llprogressbar.cpp +++ b/indra/llui/llprogressbar.cpp @@ -46,7 +46,7 @@ #include "llfocusmgr.h" #include "lluictrlfactory.h" -static LLDefaultWidgetRegistry::Register<LLProgressBar> r("progress_bar"); +static LLDefaultChildRegistry::Register<LLProgressBar> r("progress_bar"); LLProgressBar::Params::Params() : image_bar("image_bar"), diff --git a/indra/llui/llradiogroup.cpp b/indra/llui/llradiogroup.cpp index 70f98bd908..30adbb023c 100644 --- a/indra/llui/llradiogroup.cpp +++ b/indra/llui/llradiogroup.cpp @@ -44,10 +44,8 @@ #include "llfocusmgr.h" #include "lluictrlfactory.h" -static LLDefaultWidgetRegistry::Register<LLRadioGroup> r1("radio_group"); +static LLDefaultChildRegistry::Register<LLRadioGroup> r1("radio_group"); -struct RadioGroupRegistry : public LLWidgetRegistry<RadioGroupRegistry> -{}; static RadioGroupRegistry::Register<LLRadioCtrl> register_radio_ctrl("radio_item"); @@ -72,7 +70,7 @@ LLRadioGroup::LLRadioGroup(const LLRadioGroup::Params& p) LLViewBorder::Params params; params.name("radio group border"); params.rect(LLRect(0, getRect().getHeight(), getRect().getWidth(), 0)); - params.bevel_type(LLViewBorder::BEVEL_NONE); + params.bevel_style(LLViewBorder::BEVEL_NONE); LLViewBorder * vb = LLUICtrlFactory::create<LLViewBorder> (params); addChild (vb); } @@ -82,11 +80,6 @@ LLRadioGroup::~LLRadioGroup() { } -const widget_registry_t& LLRadioGroup::getChildRegistry() const -{ - return RadioGroupRegistry::instance(); -} - // virtual BOOL LLRadioGroup::postBuild() { diff --git a/indra/llui/llradiogroup.h b/indra/llui/llradiogroup.h index 850d896e29..d04473fa44 100644 --- a/indra/llui/llradiogroup.h +++ b/indra/llui/llradiogroup.h @@ -70,6 +70,10 @@ protected: friend class LLUICtrlFactory; }; + +struct RadioGroupRegistry : public LLChildRegistry<RadioGroupRegistry> +{}; + /* * An invisible view containing multiple mutually exclusive toggling * buttons (usually radio buttons). Automatically handles the mutex @@ -86,6 +90,9 @@ public: Params(); }; + // my valid children are stored in this registry + typedef RadioGroupRegistry child_registry_t; + protected: LLRadioGroup(const Params&); friend class LLUICtrlFactory; @@ -118,8 +125,6 @@ public: // Update the control as needed. Userdata must be a pointer to the button. void onClickButton(LLUICtrl* clicked_radio); - virtual const widget_registry_t& getChildRegistry() const; - //======================================================================== LLCtrlSelectionInterface* getSelectionInterface() { return (LLCtrlSelectionInterface*)this; }; diff --git a/indra/llui/llresizebar.h b/indra/llui/llresizebar.h index 4ad3d5035a..a7bc3c60f5 100644 --- a/indra/llui/llresizebar.h +++ b/indra/llui/llresizebar.h @@ -52,11 +52,11 @@ public: Optional<bool> allow_double_click_snapping; Params() - : max_size("", S32_MAX), - snapping_enabled("", true), + : max_size("max_size", S32_MAX), + snapping_enabled("snapping_enabled", true), resizing_view("resizing_view"), side("side"), - allow_double_click_snapping("", true) + allow_double_click_snapping("allow_double_click_snapping", true) { name = "resize_bar"; } diff --git a/indra/llui/llscrollbar.cpp b/indra/llui/llscrollbar.cpp index 3f1ff34419..3312064131 100644 --- a/indra/llui/llscrollbar.cpp +++ b/indra/llui/llscrollbar.cpp @@ -48,7 +48,7 @@ #include "llrender.h" #include "lluictrlfactory.h" -static LLDefaultWidgetRegistry::Register<LLScrollbar> register_scrollbar("scroll_bar"); +static LLDefaultChildRegistry::Register<LLScrollbar> register_scrollbar("scroll_bar"); LLScrollbar::Params::Params() : orientation ("orientation", HORIZONTAL), diff --git a/indra/llui/llscrollcontainer.cpp b/indra/llui/llscrollcontainer.cpp index 2a2e56a92c..ea4bd2526e 100644 --- a/indra/llui/llscrollcontainer.cpp +++ b/indra/llui/llscrollcontainer.cpp @@ -63,7 +63,7 @@ static const F32 AUTO_SCROLL_RATE_ACCEL = 120.f; /// Class LLScrollContainer ///---------------------------------------------------------------------------- -static LLDefaultWidgetRegistry::Register<LLScrollContainer> r("scroll_container"); +static LLDefaultChildRegistry::Register<LLScrollContainer> r("scroll_container"); LLScrollContainer::Params::Params() : is_opaque("opaque"), @@ -91,7 +91,7 @@ LLScrollContainer::LLScrollContainer(const LLScrollContainer::Params& p) LLViewBorder::Params params; params.name("scroll border"); params.rect(border_rect); - params.bevel_type(LLViewBorder::BEVEL_IN); + params.bevel_style(LLViewBorder::BEVEL_IN); mBorder = LLUICtrlFactory::create<LLViewBorder> (params); LLView::addChild( mBorder ); @@ -517,12 +517,6 @@ bool LLScrollContainer::addChild(LLView* view, S32 tab_group) return ret_val; } -const widget_registry_t& LLScrollContainer::getChildRegistry() const -{ - // a scroll container can contain any default widget - return LLDefaultWidgetRegistry::instance(); -} - void LLScrollContainer::updateScroll() { if (!mScrolledView) diff --git a/indra/llui/llscrollcontainer.h b/indra/llui/llscrollcontainer.h index 26d8cc824e..9cbfbc94a1 100644 --- a/indra/llui/llscrollcontainer.h +++ b/indra/llui/llscrollcontainer.h @@ -68,6 +68,10 @@ public: Params(); }; + + // my valid children are stored in this registry + typedef LLDefaultChildRegistry child_registry_t; + protected: LLScrollContainer(const Params&); friend class LLUICtrlFactory; @@ -104,7 +108,6 @@ public: virtual BOOL handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect); virtual void draw(); virtual bool addChild(LLView* view, S32 tab_group = 0); - virtual const widget_registry_t& getChildRegistry() const; private: // internal scrollbar handlers diff --git a/indra/llui/llscrollingpanellist.cpp b/indra/llui/llscrollingpanellist.cpp index 1f3a7f9fcf..0159cdd12c 100644 --- a/indra/llui/llscrollingpanellist.cpp +++ b/indra/llui/llscrollingpanellist.cpp @@ -35,7 +35,7 @@ #include "llscrollingpanellist.h" -static LLDefaultWidgetRegistry::Register<LLScrollingPanelList> r("scrolling_panel_list"); +static LLDefaultChildRegistry::Register<LLScrollingPanelList> r("scrolling_panel_list"); ///////////////////////////////////////////////////////////////////// diff --git a/indra/llui/llscrolllistcolumn.cpp b/indra/llui/llscrolllistcolumn.cpp index 02f09bd9b4..686e0b6cb7 100644 --- a/indra/llui/llscrolllistcolumn.cpp +++ b/indra/llui/llscrolllistcolumn.cpp @@ -291,7 +291,7 @@ void LLScrollListColumn::SortNames::declareValues() //static const LLScrollListColumn::Params& LLScrollListColumn::getDefaultParams() { - return LLUICtrlFactory::getDefaultParams<LLScrollListColumn::Params>(); + return LLUICtrlFactory::getDefaultParams<LLScrollListColumn>(); } diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index 6d91c784f7..75afbffc11 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -31,8 +31,6 @@ * $/LicenseInfo$ */ -#define INSTANTIATE_GETCHILD_SCROLLLIST - #include "linden_common.h" #include "llscrolllistctrl.h" @@ -60,9 +58,7 @@ #include "lltextbox.h" #include "llsdparam.h" -template LLScrollListCtrl* LLView::getChild<LLScrollListCtrl>( const std::string& name, BOOL recurse, BOOL create_if_missing ) const; - -static LLDefaultWidgetRegistry::Register<LLScrollListCtrl> r("scroll_list"); +static LLDefaultChildRegistry::Register<LLScrollListCtrl> r("scroll_list"); // local structures & classes. struct SortScrollListItem @@ -225,7 +221,7 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p) LLViewBorder::Params params; params.name("dig border"); params.rect(border_rect); - params.bevel_type(LLViewBorder::BEVEL_IN); + params.bevel_style(LLViewBorder::BEVEL_IN); mBorder = LLUICtrlFactory::create<LLViewBorder> (params); addChild(mBorder); } diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h index 8d200fb73f..63d07cecfd 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -453,11 +453,4 @@ private: LLTextBox* mCommentTextBox; }; // end class LLScrollListCtrl -#ifdef LL_WINDOWS -#ifndef INSTANTIATE_GETCHILD_SCROLLLIST -#pragma warning (disable : 4231) -extern template LLScrollListCtrl* LLView::getChild<LLScrollListCtrl>( const std::string& name, BOOL recurse, BOOL create_if_missing ) const; -#endif -#endif - #endif // LL_SCROLLLISTCTRL_H diff --git a/indra/llui/llsearcheditor.cpp b/indra/llui/llsearcheditor.cpp index 9522d32a8b..64583071a6 100644 --- a/indra/llui/llsearcheditor.cpp +++ b/indra/llui/llsearcheditor.cpp @@ -36,7 +36,7 @@ #include "llsearcheditor.h" -//static LLDefaultWidgetRegistry::Register<LLSearchEditor> r2("search_editor"); +//static LLDefaultChildRegistry::Register<LLSearchEditor> r2("search_editor"); LLSearchEditor::LLSearchEditor(const LLSearchEditor::Params& p) : LLUICtrl(p) diff --git a/indra/llui/llslider.cpp b/indra/llui/llslider.cpp index 66ed0d4e88..fa782a1063 100644 --- a/indra/llui/llslider.cpp +++ b/indra/llui/llslider.cpp @@ -43,7 +43,7 @@ #include "llimagegl.h" #include "lluictrlfactory.h" -static LLDefaultWidgetRegistry::Register<LLSlider> r1("slider_bar"); +static LLDefaultChildRegistry::Register<LLSlider> r1("slider_bar"); LLSlider::Params::Params() : track_color("track_color"), diff --git a/indra/llui/llsliderctrl.cpp b/indra/llui/llsliderctrl.cpp index 3abd960792..12953fc261 100644 --- a/indra/llui/llsliderctrl.cpp +++ b/indra/llui/llsliderctrl.cpp @@ -53,7 +53,7 @@ const U32 MAX_STRING_LENGTH = 10; -static LLDefaultWidgetRegistry::Register<LLSliderCtrl> r("slider"); +static LLDefaultChildRegistry::Register<LLSliderCtrl> r("slider"); LLSliderCtrl::LLSliderCtrl(const LLSliderCtrl::Params& p) : LLF32UICtrl(p), diff --git a/indra/llui/llspinctrl.cpp b/indra/llui/llspinctrl.cpp index 943891c572..5893fcd64b 100644 --- a/indra/llui/llspinctrl.cpp +++ b/indra/llui/llspinctrl.cpp @@ -53,7 +53,7 @@ const U32 MAX_STRING_LENGTH = 32; -static LLDefaultWidgetRegistry::Register<LLSpinCtrl> r2("spinner"); +static LLDefaultChildRegistry::Register<LLSpinCtrl> r2("spinner"); LLSpinCtrl::Params::Params() : label_width("label_width"), diff --git a/indra/llui/llstatview.cpp b/indra/llui/llstatview.cpp index 6691f16c1e..ab4b0be97a 100644 --- a/indra/llui/llstatview.cpp +++ b/indra/llui/llstatview.cpp @@ -65,16 +65,6 @@ LLStatView::~LLStatView() } -// widget registrars -struct StatViewRegistry : public LLWidgetRegistry<StatViewRegistry> -{}; - static StatViewRegistry::Register<LLStatBar> r1("stat_bar"); -const widget_registry_t& LLStatView::getChildRegistry() const -{ - return StatViewRegistry::instance(); -} - - diff --git a/indra/llui/llstatview.h b/indra/llui/llstatview.h index 20aba7782b..eee4e2b7e4 100644 --- a/indra/llui/llstatview.h +++ b/indra/llui/llstatview.h @@ -39,6 +39,10 @@ class LLStatBar; +// widget registrars +struct StatViewRegistry : public LLChildRegistry<StatViewRegistry> +{}; + class LLStatView : public LLContainerView { public: @@ -51,9 +55,11 @@ public: follows.flags(FOLLOWS_TOP | FOLLOWS_LEFT); } }; - ~LLStatView(); - virtual const widget_registry_t& getChildRegistry() const; + // my valid children are stored in this registry + typedef StatViewRegistry child_registry_t; + + ~LLStatView(); protected: LLStatView(const Params&); diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp index 3391b1275c..3d5b5caead 100644 --- a/indra/llui/lltabcontainer.cpp +++ b/indra/llui/lltabcontainer.cpp @@ -99,8 +99,8 @@ struct LLPlaceHolderPanel : public LLPanel LLPlaceHolderPanel(const Params& p) : LLPanel(p) {} }; -static LLDefaultWidgetRegistry::Register<LLPlaceHolderPanel> r1("placeholder"); -static LLDefaultWidgetRegistry::Register<LLTabContainer> r2("tab_container"); +static LLDefaultChildRegistry::Register<LLPlaceHolderPanel> r1("placeholder"); +static LLDefaultChildRegistry::Register<LLTabContainer> r2("tab_container"); LLTabContainer::Params::Params() : tab_width("tab_width"), diff --git a/indra/llui/lltextbox.cpp b/indra/llui/lltextbox.cpp index b812e876ef..56019171e1 100644 --- a/indra/llui/lltextbox.cpp +++ b/indra/llui/lltextbox.cpp @@ -30,17 +30,13 @@ * $/LicenseInfo$ */ -#define INSTANTIATE_GETCHILD_TEXTBOX - #include "linden_common.h" #include "lltextbox.h" #include "lluictrlfactory.h" #include "llfocusmgr.h" #include "llwindow.h" -template LLTextBox* LLView::getChild<LLTextBox>( const std::string& name, BOOL recurse, BOOL create_if_missing ) const; - -static LLDefaultWidgetRegistry::Register<LLTextBox> r("text"); +static LLDefaultChildRegistry::Register<LLTextBox> r("text"); LLTextBox::Params::Params() : text_color("text_color"), diff --git a/indra/llui/lltextbox.h b/indra/llui/lltextbox.h index dca906decc..53d57ff785 100644 --- a/indra/llui/lltextbox.h +++ b/indra/llui/lltextbox.h @@ -159,11 +159,4 @@ private: callback_t mClickedCallback; }; -#ifdef LL_WINDOWS -#ifndef INSTANTIATE_GETCHILD_TEXTBOX -#pragma warning (disable : 4231) -extern template LLTextBox* LLView::getChild<LLTextBox>( const std::string& name, BOOL recurse, BOOL create_if_missing ) const; -#endif -#endif - #endif diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index 6649264d9a..ce16f11d33 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -63,7 +63,7 @@ // // Globals // -static LLDefaultWidgetRegistry::Register<LLTextEditor> r("simple_text_editor"); +static LLDefaultChildRegistry::Register<LLTextEditor> r("simple_text_editor"); // // Constants @@ -304,7 +304,7 @@ LLTextEditor::LLTextEditor(const LLTextEditor::Params& p) LLViewBorder::Params params; params.name("text ed border"); params.rect(getLocalRect()); - params.bevel_type(LLViewBorder::BEVEL_IN); + params.bevel_style(LLViewBorder::BEVEL_IN); params.border_thickness(text_editor_border); mBorder = LLUICtrlFactory::create<LLViewBorder> (params); addChild( mBorder ); diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp index 12875b4ed1..c08abf3caf 100644 --- a/indra/llui/llui.cpp +++ b/indra/llui/llui.cpp @@ -90,8 +90,8 @@ std::list<std::string> gUntranslated; /*static*/ std::vector<std::string> LLUI::sXUIPaths; // register searcheditor here -static LLDefaultWidgetRegistry::Register<LLSearchEditor> register_search_editor("search_editor"); -static LLDefaultWidgetRegistry::Register<LLFlyoutButton> register_flyout_button("flyout_button"); +static LLDefaultChildRegistry::Register<LLSearchEditor> register_search_editor("search_editor"); +static LLDefaultChildRegistry::Register<LLFlyoutButton> register_flyout_button("flyout_button"); // @@ -1934,8 +1934,8 @@ LLLocalClipRect::LLLocalClipRect(const LLRect &rect, BOOL enabled) namespace LLInitParam { - TypedParam<LLUIColor >::TypedParam(BlockDescriptor& descriptor, const char* name, const LLUIColor& value, ParamDescriptor::validation_func_t func) - : super_t(descriptor, name, value, func), + TypedParam<LLUIColor >::TypedParam(BlockDescriptor& descriptor, const char* name, const LLUIColor& value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count) + : super_t(descriptor, name, value, func, min_count, max_count), red("red"), green("green"), blue("blue"), @@ -1964,11 +1964,11 @@ namespace LLInitParam declare("blue", LLColor4::blue); } - TypedParam<const LLFontGL*>::TypedParam(BlockDescriptor& descriptor, const char* name, const LLFontGL*const value, ParamDescriptor::validation_func_t func) - : super_t(descriptor, name, value, func), - name("", std::string("")), - size("size", std::string("")), - style("style", std::string("")) + TypedParam<const LLFontGL*>::TypedParam(BlockDescriptor& descriptor, const char* name, const LLFontGL*const value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count) + : super_t(descriptor, name, value, func, min_count, max_count), + name(""), + size("size"), + style("style") {} const LLFontGL* TypedParam<const LLFontGL*>::getValueFromBlock() const @@ -1995,8 +1995,8 @@ namespace LLInitParam return mData.mValue; } - TypedParam<LLRect>::TypedParam(BlockDescriptor& descriptor, const char* name, const LLRect& value, ParamDescriptor::validation_func_t func) - : super_t(descriptor, name, value, func), + TypedParam<LLRect>::TypedParam(BlockDescriptor& descriptor, const char* name, const LLRect& value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count) + : super_t(descriptor, name, value, func, min_count, max_count), left("left"), top("top"), right("right"), diff --git a/indra/llui/llui.h b/indra/llui/llui.h index c0873247c0..c4cdbf2c14 100644 --- a/indra/llui/llui.h +++ b/indra/llui/llui.h @@ -706,7 +706,7 @@ namespace LLInitParam width, height; - TypedParam(BlockDescriptor& descriptor, const char* name, const LLRect& value, ParamDescriptor::validation_func_t func); + TypedParam(BlockDescriptor& descriptor, const char* name, const LLRect& value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count); LLRect getValueFromBlock() const; }; @@ -729,7 +729,7 @@ namespace LLInitParam Optional<F32> alpha; Optional<std::string> control; - TypedParam(BlockDescriptor& descriptor, const char* name, const LLUIColor& value, ParamDescriptor::validation_func_t func); + TypedParam(BlockDescriptor& descriptor, const char* name, const LLUIColor& value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count); LLUIColor getValueFromBlock() const; }; @@ -743,7 +743,7 @@ namespace LLInitParam Optional<std::string> size; Optional<std::string> style; - TypedParam(BlockDescriptor& descriptor, const char* name, const LLFontGL* const value, ParamDescriptor::validation_func_t func); + TypedParam(BlockDescriptor& descriptor, const char* name, const LLFontGL* const value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count); const LLFontGL* getValueFromBlock() const; }; diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp index 395bed7959..43430cba24 100644 --- a/indra/llui/lluictrl.cpp +++ b/indra/llui/lluictrl.cpp @@ -38,7 +38,7 @@ #include "llpanel.h" #include "lluictrlfactory.h" -static LLDefaultWidgetRegistry::Register<LLUICtrl> r("ui_ctrl"); +static LLDefaultChildRegistry::Register<LLUICtrl> r("ui_ctrl"); LLUICtrl::Params::Params() : tab_stop("tab_stop", true), @@ -116,7 +116,7 @@ void LLFocusableElement::setFocus(BOOL b) //static const LLUICtrl::Params& LLUICtrl::getDefaultParams() { - return LLUICtrlFactory::getDefaultParams<LLUICtrl::Params>(); + return LLUICtrlFactory::getDefaultParams<LLUICtrl>(); } diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h index 2b9caa2a82..f4c7cf36f2 100644 --- a/indra/llui/lluictrl.h +++ b/indra/llui/lluictrl.h @@ -130,8 +130,8 @@ public: Alternative<std::string> invisible; ControlVisibility() - : visible("make_visible_control"), - invisible("make_invisible_control") + : visible("visiblity_control"), + invisible("invisiblity_control") {} }; struct Params : public LLInitParam::Block<Params, LLView::Params> @@ -324,6 +324,10 @@ namespace LLInitParam bool ParamCompare<LLUICtrl::focus_callback_t>::equals( const LLUICtrl::focus_callback_t &a, const LLUICtrl::focus_callback_t &b); + + template<> + bool ParamCompare<LLLazyValue<LLColor4> >::equals( + const LLLazyValue<LLColor4> &a, const LLLazyValue<LLColor4> &b); } #endif // LL_LLUICTRL_H diff --git a/indra/llui/lluictrlfactory.cpp b/indra/llui/lluictrlfactory.cpp index 24caf51159..9df22e39b4 100644 --- a/indra/llui/lluictrlfactory.cpp +++ b/indra/llui/lluictrlfactory.cpp @@ -85,7 +85,8 @@ LLFastTimer::DeclareTimer FTM_WIDGET_SETUP("Widget Setup"); //----------------------------------------------------------------------------- // Register widgets that are purely data driven here so they get linked in #include "llstatview.h" -static LLDefaultWidgetRegistry::Register<LLStatView> register_stat_view("stat_view"); +static LLDefaultChildRegistry::Register<LLStatView> + register_stat_view("stat_view"); //----------------------------------------------------------------------------- @@ -107,7 +108,7 @@ public: }; -static LLDefaultWidgetRegistry::Register<LLUICtrlLocate> r1("locate"); +static LLDefaultChildRegistry::Register<LLUICtrlLocate> r1("locate"); //----------------------------------------------------------------------------- // LLUICtrlFactory() @@ -135,7 +136,7 @@ void LLUICtrlFactory::loadWidgetTemplate(const std::string& widget_tag, LLInitPa } //static -void LLUICtrlFactory::createChildren(LLView* viewp, LLXMLNodePtr node, LLXMLNodePtr output_node) +void LLUICtrlFactory::createChildren(LLView* viewp, LLXMLNodePtr node, const widget_registry_t& registry, LLXMLNodePtr output_node) { if (node.isNull()) return; @@ -147,7 +148,7 @@ void LLUICtrlFactory::createChildren(LLView* viewp, LLXMLNodePtr node, LLXMLNode outputChild = output_node->createChild("", FALSE); } - if (!instance().createFromXML(child_node, viewp, LLStringUtil::null, outputChild, viewp->getChildRegistry())) + if (!instance().createFromXML(child_node, viewp, LLStringUtil::null, registry, outputChild)) { std::string child_name = std::string(child_node->getName()->mString); llwarns << "Could not create widget named " << child_node->getName()->mString << llendl; @@ -338,12 +339,12 @@ BOOL LLUICtrlFactory::buildPanel(LLPanel* panelp, const std::string& filename, L LLFastTimer::DeclareTimer FTM_CREATE_FROM_XML("Create child widget"); -LLView *LLUICtrlFactory::createFromXML(LLXMLNodePtr node, LLView* parent, const std::string& filename, LLXMLNodePtr output_node, const widget_registry_t& registry) +LLView *LLUICtrlFactory::createFromXML(LLXMLNodePtr node, LLView* parent, const std::string& filename, const widget_registry_t& registry, LLXMLNodePtr output_node) { LLFastTimer timer(FTM_CREATE_FROM_XML); std::string ctrl_type = node->getName()->mString; LLStringUtil::toLower(ctrl_type); - + const LLWidgetCreatorFunc* funcp = registry.getValue(ctrl_type); if (funcp == NULL) { @@ -448,11 +449,497 @@ void LLUICtrlFactory::popFactoryFunctions() } } -const widget_registry_t& LLUICtrlFactory::getWidgetRegistry(LLView* viewp) + +// +// LLRNGWriter - writes Relax NG schema files based on a param block +// +LLRNGWriter::LLRNGWriter() +{ + // register various callbacks for inspecting the contents of a param block + registerInspectFunc<bool>(boost::bind(&LLRNGWriter::writeAttribute, this, "boolean", _1, _2, _3, _4)); + registerInspectFunc<std::string>(boost::bind(&LLRNGWriter::writeAttribute, this, "string", _1, _2, _3, _4)); + registerInspectFunc<U8>(boost::bind(&LLRNGWriter::writeAttribute, this, "unsignedByte", _1, _2, _3, _4)); + registerInspectFunc<S8>(boost::bind(&LLRNGWriter::writeAttribute, this, "signedByte", _1, _2, _3, _4)); + registerInspectFunc<U16>(boost::bind(&LLRNGWriter::writeAttribute, this, "unsignedShort", _1, _2, _3, _4)); + registerInspectFunc<S16>(boost::bind(&LLRNGWriter::writeAttribute, this, "signedShort", _1, _2, _3, _4)); + registerInspectFunc<U32>(boost::bind(&LLRNGWriter::writeAttribute, this, "unsignedInt", _1, _2, _3, _4)); + registerInspectFunc<S32>(boost::bind(&LLRNGWriter::writeAttribute, this, "integer", _1, _2, _3, _4)); + registerInspectFunc<F32>(boost::bind(&LLRNGWriter::writeAttribute, this, "float", _1, _2, _3, _4)); + registerInspectFunc<F64>(boost::bind(&LLRNGWriter::writeAttribute, this, "double", _1, _2, _3, _4)); + registerInspectFunc<LLColor4>(boost::bind(&LLRNGWriter::writeAttribute, this, "string", _1, _2, _3, _4)); + registerInspectFunc<LLUIColor>(boost::bind(&LLRNGWriter::writeAttribute, this, "string", _1, _2, _3, _4)); + registerInspectFunc<LLUUID>(boost::bind(&LLRNGWriter::writeAttribute, this, "string", _1, _2, _3, _4)); + registerInspectFunc<LLSD>(boost::bind(&LLRNGWriter::writeAttribute, this, "string", _1, _2, _3, _4)); +} + +void LLRNGWriter::writeRNG(const std::string& type_name, LLXMLNodePtr node, const LLInitParam::BaseBlock& block, const std::string& xml_namespace) +{ + mGrammarNode = node; + mGrammarNode->setName("grammar"); + mGrammarNode->createChild("xmlns", true)->setStringValue("http://relaxng/ns/structure/1.0"); + mGrammarNode->createChild("datatypeLibrary", true)->setStringValue("http://www.w3.org/2001/XMLSchema-datatypes"); + mGrammarNode->createChild("ns", true)->setStringValue(xml_namespace); + + node = mGrammarNode->createChild("start", false); + node = node->createChild("ref", false); + node->createChild("name", true)->setStringValue(type_name); + + node = mGrammarNode->createChild("define", false); + node->createChild("name", true)->setStringValue(type_name); + + mElementNode = node->createChild("element", false); + mElementNode->createChild("name", true)->setStringValue(type_name); + + block.inspectBlock(*this); +} + +void LLRNGWriter::writeAttribute(const std::string& type, const Parser::name_stack_t& stack, S32 min_count, S32 max_count, const std::vector<std::string>* possible_values) +{ + name_stack_t non_empty_names; + std::string attribute_name; + for (name_stack_t::const_iterator it = stack.begin(); + it != stack.end(); + ++it) + { + const std::string& name = it->first; + if (!name.empty()) + { + non_empty_names.push_back(*it); + } + } + + if (non_empty_names.empty()) return; + + for (name_stack_t::const_iterator it = non_empty_names.begin(); + it != non_empty_names.end(); + ++it) + { + if (!attribute_name.empty()) + { + attribute_name += "."; + } + attribute_name += it->first; + } + + // singular attribute + if (non_empty_names.size() == 1) + { + if (max_count == 1) + { + LLXMLNodePtr node = getCardinalityNode(mElementNode, min_count, max_count)->createChild("attribute", false); + node->createChild("name", true)->setStringValue(attribute_name); + node->createChild("data", false)->createChild("type", true)->setStringValue(type); + } + } + // compound attribute + else + { + std::string element_name; + + // traverse all but last element, leaving that as an attribute name + name_stack_t::const_iterator end_it = non_empty_names.end(); + end_it--; + + for (name_stack_t::const_iterator it = non_empty_names.begin(); + it != end_it; + ++it) + { + if (it != non_empty_names.begin()) + { + element_name += "."; + } + element_name += it->first; + } + + elements_map_t::iterator found_it = mElementsWritten.find(element_name); + if (found_it != mElementsWritten.end()) + { + // reuse existing element + LLXMLNodePtr choice_node = found_it->second; + + LLXMLNodePtr node = choice_node->mChildren->head; + node = getCardinalityNode(node, min_count, max_count)->createChild("attribute", false); + node->createChild("name", true)->setStringValue(attribute_name); + node->createChild("data", false)->createChild("type", true)->setStringValue(type); + + node = choice_node->mChildren->head->mNext->mChildren->head; + node = getCardinalityNode(node, min_count, max_count)->createChild("attribute", false); + node->createChild("name", true)->setStringValue(non_empty_names.back().first); + node->createChild("data", false)->createChild("type", true)->setStringValue(type); + } + else + { + LLXMLNodePtr choice_node = mElementNode->createChild("choice", false); + + LLXMLNodePtr node = choice_node->createChild("group", false); + node = getCardinalityNode(node, min_count, max_count)->createChild("attribute", false); + node->createChild("name", true)->setStringValue(attribute_name); + node->createChild("data", false)->createChild("type", true)->setStringValue(type); + + node = choice_node->createChild("element", false); + node->createChild("name", true)->setStringValue(element_name); + node = getCardinalityNode(node, min_count, max_count)->createChild("attribute", false); + node->createChild("name", true)->setStringValue(non_empty_names.back().first); + node->createChild("data", false)->createChild("type", true)->setStringValue(type); + + node = choice_node->createChild("element", false); + node->createChild("name", true)->setStringValue(type + "." + element_name); + node->createChild("ref", true)->createChild("name", true)->setStringValue(element_name); + + mElementsWritten[element_name] = choice_node; + } + } +} + +LLXMLNodePtr LLRNGWriter::getCardinalityNode(LLXMLNodePtr parent_node, S32 min_count, S32 max_count) +{ + // unlinked by default, meaning this attribute is forbidden + LLXMLNodePtr count_node = new LLXMLNode(); + if (min_count >= 1) + { + if (max_count == 1 && min_count == 1) + { + // just add raw element, will count as 1 and only 1 + count_node = mElementNode; + } + else + { + count_node = mElementNode->createChild("oneOrMore", false); + } + } + else + { + if (max_count == 1) + { + count_node = mElementNode->createChild("optional", false); + } + else if (max_count > 1) + { + count_node = mElementNode->createChild("zeroOrMore", false); + } + } + return count_node; +} +// +// LLXSDWriter +// +LLXSDWriter::LLXSDWriter() +{ + registerInspectFunc<bool>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:boolean", _1, _2, _3, _4)); + registerInspectFunc<std::string>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:string", _1, _2, _3, _4)); + registerInspectFunc<U8>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:unsignedByte", _1, _2, _3, _4)); + registerInspectFunc<S8>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:signedByte", _1, _2, _3, _4)); + registerInspectFunc<U16>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:unsignedShort", _1, _2, _3, _4)); + registerInspectFunc<S16>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:signedShort", _1, _2, _3, _4)); + registerInspectFunc<U32>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:unsignedInt", _1, _2, _3, _4)); + registerInspectFunc<S32>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:integer", _1, _2, _3, _4)); + registerInspectFunc<F32>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:float", _1, _2, _3, _4)); + registerInspectFunc<F64>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:double", _1, _2, _3, _4)); + registerInspectFunc<LLColor4>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:string", _1, _2, _3, _4)); + registerInspectFunc<LLUIColor>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:string", _1, _2, _3, _4)); + registerInspectFunc<LLUUID>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:string", _1, _2, _3, _4)); + registerInspectFunc<LLSD>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:string", _1, _2, _3, _4)); +} + +void LLXSDWriter::writeXSD(const std::string& type_name, LLXMLNodePtr node, const LLInitParam::BaseBlock& block, const std::string& xml_namespace) +{ + mSchemaNode = node; + node->setName("xs:schema"); + node->createChild("attributeFormDefault", true)->setStringValue("unqualified"); + node->createChild("elementFormDefault", true)->setStringValue("qualified"); + node->createChild("targetNamespace", true)->setStringValue(xml_namespace); + node->createChild("xmlns:xs", true)->setStringValue("http://www.w3.org/2001/XMLSchema"); + node->createChild("xmlns", true)->setStringValue(xml_namespace); + + node = node->createChild("xs:complexType", false); + node->createChild("name", true)->setStringValue(type_name); + node->createChild("mixed", true)->setStringValue("true"); + + mAttributeNode = node; + mElementNode = node->createChild("xs:choice", false); + mElementNode->createChild("minOccurs", true)->setStringValue("0"); + mElementNode->createChild("maxOccurs", true)->setStringValue("unbounded"); + block.inspectBlock(*this); + + // duplicate element choices + LLXMLNodeList children; + mElementNode->getChildren("xs:element", children, FALSE); + for (LLXMLNodeList::iterator child_it = children.begin(); child_it != children.end(); ++child_it) + { + LLXMLNodePtr child_copy = child_it->second->deepCopy(); + std::string child_name; + child_copy->getAttributeString("name", child_name); + child_copy->setAttributeString("name", type_name + "." + child_name); + mElementNode->addChild(child_copy); + } + + LLXMLNodePtr element_declaration_node = mSchemaNode->createChild("xs:element", false); + element_declaration_node->createChild("name", true)->setStringValue(type_name); + element_declaration_node->createChild("type", true)->setStringValue(type_name); +} + +void LLXSDWriter::writeAttribute(const std::string& type, const Parser::name_stack_t& stack, S32 min_count, S32 max_count, const std::vector<std::string>* possible_values) +{ + name_stack_t non_empty_names; + std::string attribute_name; + for (name_stack_t::const_iterator it = stack.begin(); + it != stack.end(); + ++it) + { + const std::string& name = it->first; + if (!name.empty()) + { + non_empty_names.push_back(*it); + } + } + + for (name_stack_t::const_iterator it = non_empty_names.begin(); + it != non_empty_names.end(); + ++it) + { + if (!attribute_name.empty()) + { + attribute_name += "."; + } + attribute_name += it->first; + } + + // only flag non-nested attributes as mandatory, nested attributes have variant syntax + // that can't be properly constrained in XSD + // e.g. <foo mandatory.value="bar"/> vs <foo><mandatory value="bar"/></foo> + bool attribute_mandatory = min_count == 1 && max_count == 1 && non_empty_names.size() == 1; + + // don't bother supporting "Multiple" params as xml attributes + if (max_count <= 1) + { + // add compound attribute to root node + addAttributeToSchema(mAttributeNode, attribute_name, type, attribute_mandatory, possible_values); + } + + // now generated nested elements for compound attributes + if (non_empty_names.size() > 1 && !attribute_mandatory) + { + std::string element_name; + + // traverse all but last element, leaving that as an attribute name + name_stack_t::const_iterator end_it = non_empty_names.end(); + end_it--; + + for (name_stack_t::const_iterator it = non_empty_names.begin(); + it != end_it; + ++it) + { + if (it != non_empty_names.begin()) + { + element_name += "."; + } + element_name += it->first; + } + + std::string short_attribute_name = non_empty_names.back().first; + + LLXMLNodePtr complex_type_node; + + // find existing element node here, starting at tail of child list + if (mElementNode->mChildren.notNull()) + { + for(LLXMLNodePtr element = mElementNode->mChildren->tail; + element.notNull(); + element = element->mPrev) + { + std::string name; + if(element->getAttributeString("name", name) && name == element_name) + { + complex_type_node = element->mChildren->head; + break; + } + } + } + //create complex_type node + // + //<xs:element + // maxOccurs="1" + // minOccurs="0" + // name="name"> + // <xs:complexType> + // </xs:complexType> + //</xs:element> + if(complex_type_node.isNull()) + { + complex_type_node = mElementNode->createChild("xs:element", false); + + complex_type_node->createChild("minOccurs", true)->setIntValue(min_count); + complex_type_node->createChild("maxOccurs", true)->setIntValue(max_count); + complex_type_node->createChild("name", true)->setStringValue(element_name); + complex_type_node = complex_type_node->createChild("xs:complexType", false); + } + + addAttributeToSchema(complex_type_node, short_attribute_name, type, false, possible_values); + } +} + +void LLXSDWriter::addAttributeToSchema(LLXMLNodePtr type_declaration_node, const std::string& attribute_name, const std::string& type, bool mandatory, const std::vector<std::string>* possible_values) { - return viewp->getChildRegistry(); + if (!attribute_name.empty()) + { + LLXMLNodePtr new_enum_type_node; + if (possible_values != NULL) + { + // custom attribute type, for example + //<xs:simpleType> + // <xs:restriction + // base="xs:string"> + // <xs:enumeration + // value="a" /> + // <xs:enumeration + // value="b" /> + // </xs:restriction> + // </xs:simpleType> + new_enum_type_node = new LLXMLNode("xs:simpleType", false); + + LLXMLNodePtr restriction_node = new_enum_type_node->createChild("xs:restriction", false); + restriction_node->createChild("base", true)->setStringValue("xs:string"); + + for (std::vector<std::string>::const_iterator it = possible_values->begin(); + it != possible_values->end(); + ++it) + { + LLXMLNodePtr enum_node = restriction_node->createChild("xs:enumeration", false); + enum_node->createChild("value", true)->setStringValue(*it); + } + } + + string_set_t& attributes_written = mAttributesWritten[type_declaration_node]; + + string_set_t::iterator found_it = std::lower_bound(attributes_written.begin(), attributes_written.end(), attribute_name); + + // attribute not yet declared + if (found_it == attributes_written.end() || attributes_written.key_comp()(attribute_name, *found_it)) + { + attributes_written.insert(found_it, attribute_name); + + LLXMLNodePtr attribute_node = type_declaration_node->createChild("xs:attribute", false); + + // attribute name + attribute_node->createChild("name", true)->setStringValue(attribute_name); + + if (new_enum_type_node.notNull()) + { + attribute_node->addChild(new_enum_type_node); + } + else + { + // simple attribute type + attribute_node->createChild("type", true)->setStringValue(type); + } + + // required or optional + attribute_node->createChild("use", true)->setStringValue(mandatory ? "required" : "optional"); + } + // attribute exists...handle collision of same name attributes with potentially different types + else + { + LLXMLNodePtr attribute_declaration; + if (type_declaration_node.notNull()) + { + for(LLXMLNodePtr node = type_declaration_node->mChildren->tail; + node.notNull(); + node = node->mPrev) + { + std::string name; + if (node->getAttributeString("name", name) && name == attribute_name) + { + attribute_declaration = node; + break; + } + } + } + + bool new_type_is_enum = new_enum_type_node.notNull(); + bool existing_type_is_enum = !attribute_declaration->hasAttribute("type"); + + // either type is enum, revert to string in collision + // don't bother to check for enum equivalence + if (new_type_is_enum || existing_type_is_enum) + { + if (attribute_declaration->hasAttribute("type")) + { + attribute_declaration->setAttributeString("type", "xs:string"); + } + else + { + attribute_declaration->createChild("type", true)->setStringValue("xs:string"); + } + attribute_declaration->deleteChildren("xs:simpleType"); + } + else + { + // check for collision of different standard types + std::string existing_type; + attribute_declaration->getAttributeString("type", existing_type); + // if current type is not the same as the new type, revert to strnig + if (existing_type != type) + { + // ...than use most general type, string + attribute_declaration->setAttributeString("type", "string"); + } + } + } + } } +// +// LLXUIXSDWriter +// +void LLXUIXSDWriter::writeXSD(const std::string& type_name, const std::string& path, const LLInitParam::BaseBlock& block) +{ + std::string file_name(path); + file_name += type_name + ".xsd"; + LLXMLNodePtr root_nodep = new LLXMLNode(); + + LLXSDWriter::writeXSD(type_name, root_nodep, block, "http://www.lindenlab.com/xui"); + + // add includes for all possible children + const std::type_info* type = *LLWidgetTypeRegistry::instance().getValue(type_name); + const widget_registry_t* widget_registryp = LLChildRegistryRegistry::instance().getValue(type); + + // add include declarations for all valid children + for (widget_registry_t::Registrar::registry_map_t::const_iterator it = widget_registryp->currentRegistrar().beginItems(); + it != widget_registryp->currentRegistrar().endItems(); + ++it) + { + std::string widget_name = it->first; + if (widget_name == type_name) + { + continue; + } + LLXMLNodePtr nodep = new LLXMLNode("xs:include", false); + nodep->createChild("schemaLocation", true)->setStringValue(widget_name + ".xsd"); + + // add to front of schema + mSchemaNode->addChild(nodep, mSchemaNode); + } + + // add choices for valid children + if (widget_registryp) + { + for (widget_registry_t::Registrar::registry_map_t::const_iterator it = widget_registryp->currentRegistrar().beginItems(); + it != widget_registryp->currentRegistrar().endItems(); + ++it) + { + std::string widget_name = it->first; + //<xs:element name="widget_name" type="widget_name"> + LLXMLNodePtr widget_node = mElementNode->createChild("xs:element", false); + widget_node->createChild("name", true)->setStringValue(widget_name); + widget_node->createChild("type", true)->setStringValue(widget_name); + } + } + + LLFILE* xsd_file = LLFile::fopen(file_name.c_str(), "w"); + LLXMLNode::writeHeaderToFile(xsd_file); + root_nodep->writeToFile(xsd_file); + fclose(xsd_file); +} // // LLXUIParser diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h index f8d584bc75..894c77888c 100644 --- a/indra/llui/lluictrlfactory.h +++ b/indra/llui/lluictrlfactory.h @@ -41,11 +41,64 @@ #include <boost/function.hpp> #include <iosfwd> #include <stack> +#include <set> class LLPanel; class LLFloater; class LLView; +class LLRNGWriter : public LLInitParam::Parser +{ + LOG_CLASS(LLRNGWriter); +public: + void writeRNG(const std::string& name, LLXMLNodePtr node, const LLInitParam::BaseBlock& block, const std::string& xml_namespace); + + /*virtual*/ std::string getCurrentElementName() { return LLStringUtil::null; } + + LLRNGWriter(); + +private: + LLXMLNodePtr getCardinalityNode(LLXMLNodePtr parent_node, S32 min_count, S32 max_count); + + void writeAttribute(const std::string& type, const Parser::name_stack_t&, S32 min_count, S32 max_count, const std::vector<std::string>* possible_values); + LLXMLNodePtr mElementNode; + LLXMLNodePtr mGrammarNode; + + typedef std::map<std::string, LLXMLNodePtr> elements_map_t; + elements_map_t mElementsWritten; +}; + + +class LLXSDWriter : public LLInitParam::Parser +{ + LOG_CLASS(LLXSDWriter); +public: + void writeXSD(const std::string& name, LLXMLNodePtr node, const LLInitParam::BaseBlock& block, const std::string& xml_namespace); + + /*virtual*/ std::string getCurrentElementName() { return LLStringUtil::null; } + + LLXSDWriter(); + +protected: + void writeAttribute(const std::string& type, const Parser::name_stack_t&, S32 min_count, S32 max_count, const std::vector<std::string>* possible_values); + void addAttributeToSchema(LLXMLNodePtr nodep, const std::string& attribute_name, const std::string& type, bool mandatory, const std::vector<std::string>* possible_values); + LLXMLNodePtr mAttributeNode; + LLXMLNodePtr mElementNode; + LLXMLNodePtr mSchemaNode; + + typedef std::set<std::string> string_set_t; + typedef std::map<LLXMLNodePtr, string_set_t> attributes_map_t; + attributes_map_t mAttributesWritten; +}; + +// NOTE: DOES NOT WORK YET +// should support child widgets for XUI +class LLXUIXSDWriter : public LLXSDWriter +{ +public: + void writeXSD(const std::string& name, const std::string& path, const LLInitParam::BaseBlock& block); +}; + class LLXUIParser : public LLInitParam::Parser, public LLSingleton<LLXUIParser> { LOG_CLASS(LLXUIParser); @@ -118,13 +171,23 @@ typedef boost::function<LLView* (LLXMLNodePtr node, LLView *parent, LLXMLNodePtr typedef LLRegistry<std::string, LLWidgetCreatorFunc> widget_registry_t; +// sort functor for typeid maps +struct LLCompareTypeID +{ + bool operator()(const std::type_info* lhs, const std::type_info* rhs) const + { + return lhs->before(*rhs); + } +}; + +// lookup widget constructor funcs by widget name template <typename DERIVED_TYPE> -class LLWidgetRegistry : public LLRegistrySingleton<std::string, LLWidgetCreatorFunc, DERIVED_TYPE> +class LLChildRegistry : public LLRegistrySingleton<std::string, LLWidgetCreatorFunc, DERIVED_TYPE> { public: typedef LLRegistrySingleton<std::string, LLWidgetCreatorFunc, DERIVED_TYPE> super_t; // local static instance for registering a particular widget - template<typename T, typename PARAM_BLOCK = typename T::Params> + template<typename T> class Register : public super_t::StaticRegistrar { public: @@ -133,35 +196,40 @@ public: }; protected: - LLWidgetRegistry() {} + LLChildRegistry() {} }; -class LLDefaultWidgetRegistry : public LLWidgetRegistry<LLDefaultWidgetRegistry> +class LLDefaultChildRegistry : public LLChildRegistry<LLDefaultChildRegistry> { protected: - LLDefaultWidgetRegistry() {} - friend class LLSingleton<LLDefaultWidgetRegistry>; -}; - -struct LLCompareTypeID -{ - bool operator()(const std::type_info* lhs, const std::type_info* rhs) const - { - return lhs->before(*rhs); - } + LLDefaultChildRegistry(){} + friend class LLSingleton<LLDefaultChildRegistry>; }; +// lookup widget name by type +class LLWidgetNameRegistry +: public LLRegistrySingleton<const std::type_info*, std::string, LLWidgetNameRegistry , LLCompareTypeID> +{}; -class LLWidgetTemplateRegistry -: public LLRegistrySingleton<const std::type_info*, std::string, LLWidgetTemplateRegistry, LLCompareTypeID> +// lookup widget type by name +class LLWidgetTypeRegistry +: public LLRegistrySingleton<std::string, const std::type_info*, LLWidgetTypeRegistry> {}; -// function used to create new default widgets via LLView::getChild<T> +// lookup factory functions for default widget instances by widget type typedef LLView* (*dummy_widget_creator_func_t)(const std::string&); +class LLDefaultWidgetRegistry +: public LLRegistrySingleton<const std::type_info*, dummy_widget_creator_func_t, LLDefaultWidgetRegistry, LLCompareTypeID> +{}; -// used to register factory functions for default widget instances -class LLDummyWidgetRegistry -: public LLRegistrySingleton<const std::type_info*, dummy_widget_creator_func_t, LLDummyWidgetRegistry, LLCompareTypeID> +// lookup function for generating empty param block by widget type +typedef const LLInitParam::BaseBlock& (*empty_param_block_func_t)(); +class LLDefaultParamBlockRegistry +: public LLRegistrySingleton<const std::type_info*, empty_param_block_func_t, LLDefaultParamBlockRegistry, LLCompareTypeID> +{}; + +class LLChildRegistryRegistry +: public LLRegistrySingleton<const std::type_info*, widget_registry_t, LLChildRegistryRegistry> {}; extern LLFastTimer::DeclareTimer FTM_WIDGET_SETUP; @@ -176,26 +244,26 @@ private: ~LLUICtrlFactory(); // only partial specialization allowed in inner classes, so use extra dummy parameter - template <typename T, int DUMMY> - class ParamDefaults : public LLSingleton<ParamDefaults<T, DUMMY> > + template <typename PARAM_BLOCK, int DUMMY> + class ParamDefaults : public LLSingleton<ParamDefaults<PARAM_BLOCK, DUMMY> > { public: ParamDefaults() { // recursively initialize from base class param block - ((typename T::base_block_t&)mPrototype).fillFrom(ParamDefaults<typename T::base_block_t, DUMMY>::instance().get()); + ((typename PARAM_BLOCK::base_block_t&)mPrototype).fillFrom(ParamDefaults<typename PARAM_BLOCK::base_block_t, DUMMY>::instance().get()); // after initializing base classes, look up template file for this param block - std::string* param_block_tag = LLWidgetTemplateRegistry::instance().getValue(&typeid(T)); + std::string* param_block_tag = LLWidgetNameRegistry::instance().getValue(&typeid(PARAM_BLOCK)); if (param_block_tag) { LLUICtrlFactory::loadWidgetTemplate(*param_block_tag, mPrototype); } } - const T& get() { return mPrototype; } + const PARAM_BLOCK& get() { return mPrototype; } private: - T mPrototype; + PARAM_BLOCK mPrototype; }; // base case for recursion, there are NO base classes of LLInitParam::BaseBlock @@ -210,11 +278,12 @@ private: public: + // get default parameter block for widget of a specific type template<typename T> - static const T& getDefaultParams() + static const typename T::Params& getDefaultParams() { //#pragma message("Generating ParamDefaults") - return ParamDefaults<T, 0>::instance().get(); + return ParamDefaults<typename T::Params, 0>::instance().get(); } void buildFloater(LLFloater* floaterp, const std::string &filename, BOOL open_floater = TRUE, LLXMLNodePtr output_node = NULL); @@ -252,12 +321,10 @@ public: return widget; } - LLView* createFromXML(LLXMLNodePtr node, LLView* parent, const std::string& filename, LLXMLNodePtr output_node, const widget_registry_t& ); + LLView* createFromXML(LLXMLNodePtr node, LLView* parent, const std::string& filename, const widget_registry_t&, LLXMLNodePtr output_node ); - static const widget_registry_t& getWidgetRegistry(LLView*); - template<typename T> - static T* createFromFile(const std::string &filename, LLView *parent, LLXMLNodePtr output_node = NULL) + static T* createFromFile(const std::string &filename, LLView *parent, const widget_registry_t& registry, LLXMLNodePtr output_node = NULL) { //#pragma message("Generating LLUICtrlFactory::createFromFile") T* widget = NULL; @@ -283,7 +350,7 @@ public: goto fail; } - LLView* view = getInstance()->createFromXML(root_node, parent, filename, output_node, getWidgetRegistry(parent)); + LLView* view = getInstance()->createFromXML(root_node, parent, filename, registry, output_node); if (view) { widget = dynamic_cast<T*>(view); @@ -304,7 +371,7 @@ fail: template<class T> static T* getDefaultWidget(const std::string& name) { - dummy_widget_creator_func_t* dummy_func = LLDummyWidgetRegistry::instance().getValue(&typeid(T)); + dummy_widget_creator_func_t* dummy_func = LLDefaultWidgetRegistry::instance().getValue(&typeid(T)); return dummy_func ? dynamic_cast<T*>((*dummy_func)(name)) : NULL; } @@ -317,23 +384,23 @@ fail: return create<T>(params); } - template<typename T, typename PARAM_BLOCK> + template<typename T> static T* defaultBuilder(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node) { LLFastTimer timer(FTM_WIDGET_SETUP); //#pragma message("Generating LLUICtrlFactory::defaultBuilder") - PARAM_BLOCK params(getDefaultParams<PARAM_BLOCK>()); + typename T::Params params(getDefaultParams<T>()); LLXUIParser::instance().readXUI(node, params); if (output_node) { // We always want to output top-left coordinates - PARAM_BLOCK output_params(params); + typename T::Params output_params(params); T::setupParamsForExport(output_params, parent); // Export only the differences between this any default params - PARAM_BLOCK default_params(getDefaultParams<PARAM_BLOCK>()); + typename T::Params default_params(getDefaultParams<T>()); output_node->setName(node->getName()->mString); LLXUIParser::instance().writeXUI( output_node, output_params, &default_params); @@ -361,8 +428,10 @@ fail: S32 tab_group = params.tab_group.isProvided() ? params.tab_group() : -1; setCtrlParent(widget, parent, tab_group); } + + typedef typename T::child_registry_t registry_t; - createChildren(widget, node, output_node); + createChildren(widget, node, registry_t::instance(), output_node); if (!widget->postBuild()) { @@ -373,7 +442,7 @@ fail: return widget; } - static void createChildren(LLView* viewp, LLXMLNodePtr node, LLXMLNodePtr output_node = NULL); + static void createChildren(LLView* viewp, LLXMLNodePtr node, const widget_registry_t&, LLXMLNodePtr output_node = NULL); static bool getLayeredXMLNode(const std::string &filename, LLXMLNodePtr& root); @@ -395,16 +464,28 @@ private: std::vector<std::string> mFileNames; }; +template<typename T> +const LLInitParam::BaseBlock& getEmptyParamBlock() +{ + static typename T::Params params; + return params; +} + // this is here to make gcc happy with reference to LLUICtrlFactory template<typename DERIVED> -template<typename T, typename PARAM_BLOCK> -LLWidgetRegistry<DERIVED>::Register<T, PARAM_BLOCK>::Register(const char* tag, LLWidgetCreatorFunc func) -: LLWidgetRegistry<DERIVED>::StaticRegistrar(tag, func.empty() ? (LLWidgetCreatorFunc)&LLUICtrlFactory::defaultBuilder<T, PARAM_BLOCK> : func) +template<typename T> +LLChildRegistry<DERIVED>::Register<T>::Register(const char* tag, LLWidgetCreatorFunc func) +: LLChildRegistry<DERIVED>::StaticRegistrar(tag, func.empty() ? (LLWidgetCreatorFunc)&LLUICtrlFactory::defaultBuilder<T> : func) { + const std::type_info* widget_type_infop = &typeid(T); // associate parameter block type with template .xml file - LLWidgetTemplateRegistry::instance().defaultRegistrar().add(&typeid(PARAM_BLOCK), tag); + LLWidgetNameRegistry ::instance().defaultRegistrar().add(&typeid(typename T::Params), tag); // associate widget type with factory function - LLDummyWidgetRegistry::instance().defaultRegistrar().add(&typeid(T), &LLUICtrlFactory::createDefaultWidget<T>); + LLDefaultWidgetRegistry::instance().defaultRegistrar().add(widget_type_infop, &LLUICtrlFactory::createDefaultWidget<T>); + LLWidgetTypeRegistry::instance().defaultRegistrar().add(tag, widget_type_infop); + LLDefaultParamBlockRegistry::instance().defaultRegistrar().add(widget_type_infop, &getEmptyParamBlock<T>); + typedef typename T::child_registry_t registry_t; + LLChildRegistryRegistry::instance().defaultRegistrar().add(widget_type_infop, registry_t::instance()); } diff --git a/indra/llui/lluiimage.h b/indra/llui/lluiimage.h index e3b473b5f6..0fb16876bf 100644 --- a/indra/llui/lluiimage.h +++ b/indra/llui/lluiimage.h @@ -95,8 +95,8 @@ namespace LLInitParam public: Optional<std::string> name; - TypedParam(BlockDescriptor& descriptor, const char* name, super_t::value_assignment_t value, ParamDescriptor::validation_func_t func) - : super_t(descriptor, name, value, func) + TypedParam(BlockDescriptor& descriptor, const char* name, super_t::value_assignment_t value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count) + : super_t(descriptor, name, value, func, min_count, max_count) { } diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index 29d0f6a168..777cf096ac 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -99,10 +99,15 @@ LLView::Params::Params() left_delta("left_delta", S32_MAX), center_horiz("center_horiz", false), center_vert("center_vert", false), - serializable("", false), + from_xui("from_xui", false), user_resize("user_resize"), auto_resize("auto_resize"), - needs_translate("translate") + needs_translate("translate"), + xmlns("xmlns"), + xmlns_xsi("xmlns:xsi"), + xsi_schemaLocation("xsi:schemaLocation"), + xsi_type("xsi:type") + { addSynonym(rect, ""); } @@ -111,7 +116,7 @@ LLView::LLView(const LLView::Params& p) : mName(p.name), mParentView(NULL), mReshapeFlags(FOLLOWS_NONE), - mSaveToXML(p.serializable), + mSaveToXML(p.from_xui), mIsFocusRoot(FALSE), mLastVisible(FALSE), mNextInsertionOrdinal(0), @@ -2291,13 +2296,6 @@ LLControlVariable *LLView::findControl(const std::string& name) return control_group.getControl(name); } -const widget_registry_t& LLView::getChildRegistry() const -{ - static widget_registry_t empty_registry; - return empty_registry; -} - - const S32 FLOATER_H_MARGIN = 15; const S32 MIN_WIDGET_HEIGHT = 10; const S32 VPAD = 4; @@ -2418,7 +2416,7 @@ void LLView::setupParams(LLView::Params& p, LLView* parent) const S32 VPAD = 4; const S32 MIN_WIDGET_HEIGHT = 10; - p.serializable(true); + p.from_xui(true); // *NOTE: This will confuse export of floater/panel coordinates unless // the default is also "topleft". JC diff --git a/indra/llui/llview.h b/indra/llui/llview.h index 422f62f602..5f6341daa6 100644 --- a/indra/llui/llview.h +++ b/indra/llui/llview.h @@ -138,6 +138,9 @@ virtual BOOL handleUnicodeCharHere(llwchar uni_char); * */ +class LLViewWidgetRegistry : public LLChildRegistry<LLViewWidgetRegistry> +{}; + class LLView : public LLMouseHandler, public LLMortician { public: @@ -157,15 +160,16 @@ public: Mandatory<std::string> name; Optional<bool> enabled, - visible; - Optional<bool> mouse_opaque; - Optional<bool> use_bounding_rect; + visible, + mouse_opaque, + use_bounding_rect; + Optional<S32> tab_group, default_tab_group; Optional<std::string> tool_tip; Optional<S32> sound_flags; - Optional<bool> serializable; + Optional<bool> from_xui; Optional<Follows> follows; Optional<std::string> hover_cursor; @@ -192,10 +196,17 @@ public: //FIXME: get parent context involved in parsing traversal Ignored user_resize, auto_resize, - needs_translate; + needs_translate, + xmlns, + xmlns_xsi, + xsi_schemaLocation, + xsi_type; Params(); }; + + typedef LLViewWidgetRegistry child_registry_t; + void initFromParams(const LLView::Params&); protected: @@ -496,9 +507,6 @@ public: return dynamic_cast<T*>(found_it->second); } - // determines allowable children when parsing XUI - virtual const widget_registry_t& getChildRegistry() const; - ////////////////////////////////////////////// // statics ////////////////////////////////////////////// @@ -647,6 +655,9 @@ template <class T> T* LLView::getChild(const std::string& name, BOOL recurse, BO if (result) { + // *NOTE: You cannot call mFoo = getChild<LLFoo>("bar") + // in a floater or panel constructor. The widgets will not + // be ready. Instead, put it in postBuild(). llwarns << "Making dummy " << typeid(T).name() << " named \"" << name << "\" in " << getName() << llendl; } else diff --git a/indra/llui/llviewborder.cpp b/indra/llui/llviewborder.cpp index a5b09671bb..860aa3302e 100644 --- a/indra/llui/llviewborder.cpp +++ b/indra/llui/llviewborder.cpp @@ -35,7 +35,7 @@ #include "llfocusmgr.h" #include "lluictrlfactory.h" -static LLDefaultWidgetRegistry::Register<LLViewBorder> r("view_border"); +static LLDefaultChildRegistry::Register<LLViewBorder> r("view_border"); void LLViewBorder::BevelValues::declareValues() { @@ -52,7 +52,7 @@ void LLViewBorder::StyleValues::declareValues() } LLViewBorder::Params::Params() -: bevel_type("bevel_style", BEVEL_OUT), +: bevel_style("bevel_style", BEVEL_OUT), render_style("border_style", STYLE_LINE), border_thickness("border_thickness"), highlight_light_color("highlight_light_color"), @@ -60,6 +60,8 @@ LLViewBorder::Params::Params() shadow_light_color("shadow_light_color"), shadow_dark_color("shadow_dark_color") { + addSynonym(border_thickness, "thickness"); + addSynonym(render_style, "style"); name = "view_border"; mouse_opaque = false; follows.flags = FOLLOWS_ALL; @@ -75,7 +77,7 @@ LLViewBorder::LLViewBorder(const LLViewBorder::Params& p) mHighlightDark(p.highlight_dark_color()), mShadowLight(p.shadow_light_color()), mShadowDark(p.shadow_dark_color()), - mBevel(p.bevel_type), + mBevel(p.bevel_style), mStyle(p.render_style) {} diff --git a/indra/llui/llviewborder.h b/indra/llui/llviewborder.h index 37e13fb181..92fd569325 100644 --- a/indra/llui/llviewborder.h +++ b/indra/llui/llviewborder.h @@ -55,7 +55,7 @@ public: struct Params : public LLInitParam::Block<Params, LLView::Params> { - Optional<EBevel, BevelValues> bevel_type; + Optional<EBevel, BevelValues> bevel_style; Optional<EStyle, StyleValues> render_style; Optional<S32> border_thickness; diff --git a/indra/llxml/llxmlnode.cpp b/indra/llxml/llxmlnode.cpp index e97aa55190..5d43ac11e4 100644 --- a/indra/llxml/llxmlnode.cpp +++ b/indra/llxml/llxmlnode.cpp @@ -149,7 +149,7 @@ LLXMLNodePtr LLXMLNode::deepCopy() if (mChildren.notNull()) { for (LLXMLChildList::iterator iter = mChildren->map.begin(); - iter != mChildren->map.end(); ++iter) + iter != mChildren->map.end(); ++iter) { newnode->addChild(iter->second->deepCopy()); } @@ -302,6 +302,22 @@ void LLXMLNode::addChild(LLXMLNodePtr new_child, LLXMLNodePtr after_child) mChildren->tail = new_child; } } + // if after_child == parent, then put new_child at beginning + else if (after_child == this) + { + // add to front of list + new_child->mNext = mChildren->head; + if (mChildren->head) + { + mChildren->head->mPrev = new_child; + mChildren->head = new_child; + } + else // no children + { + mChildren->head = new_child; + mChildren->tail = new_child; + } + } else { if (after_child->mNext.notNull()) diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index f96c8fdca0..6ec4fbbcd5 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -82,6 +82,7 @@ set(viewer_SOURCE_FILES llbbox.cpp llbottomtray.cpp llbox.cpp + llbreadcrumbview.cpp llcallbacklist.cpp llcallingcard.cpp llcapabilitylistener.cpp @@ -173,6 +174,7 @@ set(viewer_SOURCE_FILES llfloaterhud.cpp llfloaterimagepreview.cpp llfloaterinspect.cpp + llfloaterinventory.cpp llfloaterjoystick.cpp llfloaterlagmeter.cpp llfloaterland.cpp @@ -198,6 +200,7 @@ set(viewer_SOURCE_FILES llfloatersettingsdebug.cpp llfloatersnapshot.cpp llfloatertelehub.cpp + llfloatertestlistview.cpp llfloatertools.cpp llfloatertopobjects.cpp llfloatertos.cpp @@ -209,6 +212,7 @@ set(viewer_SOURCE_FILES llfloaterwindlight.cpp llfloaterworldmap.cpp llfolderview.cpp + llfolderviewitem.cpp llfollowcam.cpp llfriendactions.cpp llgesturemgr.cpp @@ -236,10 +240,12 @@ set(viewer_SOURCE_FILES llimcontrolpanel.cpp llinventorybridge.cpp llinventoryclipboard.cpp + llinventoryfilter.cpp llinventorymodel.cpp - llinventoryview.cpp lljoystickbutton.cpp lllandmarklist.cpp + lllistbrowser.cpp + lllistview.cpp lllocationhistory.cpp lllocationinputctrl.cpp lllogchat.cpp @@ -495,6 +501,7 @@ set(viewer_HEADER_FILES llbbox.h llbottomtray.h llbox.h + llbreadcrumbview.h llcallbacklist.h llcallingcard.h llcapabilitylistener.h @@ -588,6 +595,7 @@ set(viewer_HEADER_FILES llfloaterhud.h llfloaterimagepreview.h llfloaterinspect.h + llfloaterinventory.h llfloaterjoystick.h llfloaterlagmeter.h llfloaterland.h @@ -613,6 +621,7 @@ set(viewer_HEADER_FILES llfloatersettingsdebug.h llfloatersnapshot.h llfloatertelehub.h + llfloatertestlistview.h llfloatertools.h llfloatertopobjects.h llfloatertos.h @@ -624,6 +633,8 @@ set(viewer_HEADER_FILES llfloaterwindlight.h llfloaterworldmap.h llfolderview.h + llfoldervieweventlistener.h + llfolderviewitem.h llfollowcam.h llfriendactions.h llgesturemgr.h @@ -650,11 +661,13 @@ set(viewer_HEADER_FILES llimcontrolpanel.h llinventorybridge.h llinventoryclipboard.h + llinventoryfilter.h llinventorymodel.h - llinventoryview.h lljoystickbutton.h lllandmarklist.h lllightconstants.h + lllistbrowser.h + lllistview.h lllocationhistory.h lllocationinputctrl.h lllogchat.h diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 567fda0034..38eeca2bf8 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -9425,6 +9425,17 @@ <key>Value</key> <real>150000.0</real> </map> + <key>XUIEditor</key> + <map> + <key>Comment</key> + <string>Path to program used to edit XUI files</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>String</string> + <key>Value</key> + <real>150000.0</real> + </map> <key>YawFromMousePosition</key> <map> <key>Comment</key> diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 22d54fe627..c8240de0a7 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -2153,7 +2153,6 @@ void LLAgent::setBusy() { gBusyMenu->setLabel(LLTrans::getString("AvatarSetNotBusy")); } - LLFloaterReg::getTypedInstance<LLFloaterMute>("mute")->updateButtons(); } //----------------------------------------------------------------------------- @@ -2167,7 +2166,6 @@ void LLAgent::clearBusy() { gBusyMenu->setLabel(LLTrans::getString("AvatarSetBusy")); } - LLFloaterReg::getTypedInstance<LLFloaterMute>("mute")->updateButtons(); } //----------------------------------------------------------------------------- @@ -2490,7 +2488,7 @@ void LLAgent::autoPilot(F32 *delta_yaw) void LLAgent::propagate(const F32 dt) { // Update UI based on agent motion - LLFloaterMove *floater_move = LLFloaterMove::getInstance(); + LLFloaterMove *floater_move = LLFloaterReg::getTypedInstance<LLFloaterMove>("moveview"); if (floater_move) { floater_move->mForwardButton ->setToggleState( mAtKey > 0 || mWalkKey > 0 ); @@ -3056,21 +3054,25 @@ void LLAgent::updateCamera() } // Update UI with our camera inputs - LLFloaterCamera::getInstance()->mRotate->setToggleState( - mOrbitRightKey > 0.f, // left - mOrbitUpKey > 0.f, // top - mOrbitLeftKey > 0.f, // right - mOrbitDownKey > 0.f); // bottom - - LLFloaterCamera::getInstance()->mZoom->setToggleState( - mOrbitInKey > 0.f, // top - mOrbitOutKey > 0.f); // bottom - - LLFloaterCamera::getInstance()->mTrack->setToggleState( - mPanLeftKey > 0.f, // left - mPanUpKey > 0.f, // top - mPanRightKey > 0.f, // right - mPanDownKey > 0.f); // bottom + LLFloaterCamera* camera_instance = LLFloaterReg::getTypedInstance<LLFloaterCamera>("camera"); + if(camera_instance) + { + camera_instance->mRotate->setToggleState( + mOrbitRightKey > 0.f, // left + mOrbitUpKey > 0.f, // top + mOrbitLeftKey > 0.f, // right + mOrbitDownKey > 0.f); // bottom + + camera_instance->mZoom->setToggleState( + mOrbitInKey > 0.f, // top + mOrbitOutKey > 0.f); // bottom + + camera_instance->mTrack->setToggleState( + mPanLeftKey > 0.f, // left + mPanUpKey > 0.f, // top + mPanRightKey > 0.f, // right + mPanDownKey > 0.f); // bottom + } // Handle camera movement based on keyboard. const F32 ORBIT_OVER_RATE = 90.f * DEG_TO_RAD; // radians per second @@ -6074,7 +6076,7 @@ bool LLAgent::teleportCore(bool is_local) LLFloaterReg::hideInstance("search"); // hide land floater too - it'll be out of date - LLFloaterLand::hideInstance(); + LLFloaterReg::hideInstance("about_land"); LLViewerParcelMgr::getInstance()->deselectLand(); diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h index 743784b2ef..22b3790c6b 100644 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -182,10 +182,7 @@ private: public: LLVOAvatarSelf* getAvatarObject() const { return mAvatarObject; } - const LLUUID& getInventoryRootID() const { return mInventoryRootID; } - LLUUID& getInventoryRootID() { return mInventoryRootID; } private: - LLUUID mInventoryRootID; LLPointer<LLVOAvatarSelf> mAvatarObject; // NULL until avatar object sent down from simulator /** General Accessors diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index 1da54ad08c..f053bfe118 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -36,7 +36,7 @@ #include "llagentwearables.h" #include "llfloatercustomize.h" -#include "llinventoryview.h" +#include "llfloaterinventory.h" #include "llinventorymodel.h" #include "llnotify.h" #include "llviewerregion.h" @@ -1076,7 +1076,7 @@ void LLAgentWearables::makeNewOutfitDone(S32 type, U32 index) // Open the inventory and select the first item we added. if (first_item_id.notNull()) { - LLInventoryView* view = LLInventoryView::getActiveInventory(); + LLFloaterInventory* view = LLFloaterInventory::getActiveInventory(); if (view) { view->getPanel()->setSelection(first_item_id, TAKE_FOCUS_NO); diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 0253d9e8d5..de3cf1a81b 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -152,8 +152,9 @@ #include "llviewerfloaterreg.h" #include "llcommandlineparser.h" #include "llfloatermemleak.h" +#include "llfloaterreg.h" #include "llfloatersnapshot.h" -#include "llinventoryview.h" +#include "llfloaterinventory.h" // includes for idle() idleShutdown() #include "llviewercontrol.h" @@ -235,9 +236,6 @@ LLTimer gLogoutTimer; static const F32 LOGOUT_REQUEST_TIME = 6.f; // this will be cut short by the LogoutReply msg. F32 gLogoutMaxTime = LOGOUT_REQUEST_TIME; -LLUUID gInventoryLibraryOwner; -LLUUID gInventoryLibraryRoot; - BOOL gDisconnected = FALSE; // Map scale in pixels per region @@ -930,9 +928,10 @@ bool LLAppViewer::mainLoop() #endif //memory leaking simulation - if(LLFloaterMemLeak::getInstance()) + LLFloaterMemLeak* mem_leak_instance = LLFloaterReg::getTypedInstance<LLFloaterMemLeak>("mem_leaking"); + if(mem_leak_instance) { - LLFloaterMemLeak::getInstance()->idle() ; + mem_leak_instance->idle() ; } // canonical per-frame event @@ -1099,9 +1098,10 @@ bool LLAppViewer::mainLoop() catch(std::bad_alloc) { //stop memory leaking simulation - if(LLFloaterMemLeak::getInstance()) + LLFloaterMemLeak* mem_leak_instance = LLFloaterReg::getTypedInstance<LLFloaterMemLeak>("mem_leaking"); + if(mem_leak_instance) { - LLFloaterMemLeak::getInstance()->stop() ; + mem_leak_instance->stop() ; llwarns << "Bad memory allocation in LLAppViewer::mainLoop()!" << llendl ; } else @@ -1126,9 +1126,10 @@ bool LLAppViewer::mainLoop() llwarns << "Bad memory allocation when saveFinalSnapshot() is called!" << llendl ; //stop memory leaking simulation - if(LLFloaterMemLeak::getInstance()) + LLFloaterMemLeak* mem_leak_instance = LLFloaterReg::getTypedInstance<LLFloaterMemLeak>("mem_leaking"); + if(mem_leak_instance) { - LLFloaterMemLeak::getInstance()->stop() ; + mem_leak_instance->stop() ; } } } @@ -3864,20 +3865,20 @@ void LLAppViewer::disconnectViewer() LLSelectMgr::getInstance()->deselectAll(); } - if (!gNoRender) + // save inventory if appropriate + gInventory.cache(gInventory.getRootFolderID(), gAgent.getID()); + if (gInventory.getLibraryRootFolderID().notNull() + && gInventory.getLibraryOwnerID().notNull()) { - // save inventory if appropriate - gInventory.cache(gAgent.getInventoryRootID(), gAgent.getID()); - if(gInventoryLibraryRoot.notNull() && gInventoryLibraryOwner.notNull()) - { - gInventory.cache(gInventoryLibraryRoot, gInventoryLibraryOwner); - } + gInventory.cache( + gInventory.getLibraryRootFolderID(), + gInventory.getLibraryOwnerID()); } saveNameCache(); // close inventory interface, close all windows - LLInventoryView::cleanup(); + LLFloaterInventory::cleanup(); gAgentWearables.cleanup(); diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index 3e3b523169..7bda16d256 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -313,9 +313,6 @@ extern LLTimer gLogoutTimer; extern F32 gSimLastTime; extern F32 gSimFrames; -extern LLUUID gInventoryLibraryOwner; -extern LLUUID gInventoryLibraryRoot; - extern BOOL gDisconnected; // Map scale in pixels per region diff --git a/indra/newview/llassetuploadresponders.cpp b/indra/newview/llassetuploadresponders.cpp index 1379073bba..802c90f531 100644 --- a/indra/newview/llassetuploadresponders.cpp +++ b/indra/newview/llassetuploadresponders.cpp @@ -41,7 +41,7 @@ #include "llfilepicker.h" #include "llnotify.h" #include "llinventorymodel.h" -#include "llinventoryview.h" +#include "llfloaterinventory.h" #include "llpermissionsflags.h" #include "llpreviewnotecard.h" #include "llpreviewscript.h" @@ -285,7 +285,7 @@ void LLNewAgentInventoryResponder::uploadComplete(const LLSD& content) // Show the preview panel for textures and sounds to let // user know that the image (or snapshot) arrived intact. - LLInventoryView* view = LLInventoryView::getActiveInventory(); + LLFloaterInventory* view = LLFloaterInventory::getActiveInventory(); if(view) { LLUICtrl* focus_ctrl = gFocusMgr.getKeyboardFocus(); @@ -295,7 +295,7 @@ void LLNewAgentInventoryResponder::uploadComplete(const LLSD& content) { view->getPanel()->openSelected(); } - //LLInventoryView::dumpSelectionInformation((void*)view); + //LLFloaterInventory::dumpSelectionInformation((void*)view); // restore keyboard focus gFocusMgr.setKeyboardFocus(focus_ctrl); } diff --git a/indra/newview/llavatariconctrl.cpp b/indra/newview/llavatariconctrl.cpp index 3cd6126739..bf18abfdb3 100644 --- a/indra/newview/llavatariconctrl.cpp +++ b/indra/newview/llavatariconctrl.cpp @@ -46,7 +46,7 @@ #define MENU_ITEM_VIEW_PROFILE 0 #define MENU_ITEM_SEND_IM 1 -static LLDefaultWidgetRegistry::Register<LLAvatarIconCtrl> r("avatar_icon"); +static LLDefaultChildRegistry::Register<LLAvatarIconCtrl> r("avatar_icon"); LLAvatarIconCtrl::LLAvatarIconCtrl(const LLAvatarIconCtrl::Params& p) : LLIconCtrl(p), @@ -106,7 +106,7 @@ LLAvatarIconCtrl::LLAvatarIconCtrl(const LLAvatarIconCtrl::Params& p) registrar.add("AvatarIcon.Action", boost::bind(&LLAvatarIconCtrl::onAvatarIconContextMenuItemClicked, this, _2)); - LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_avatar_icon.xml", gMenuHolder); + LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_avatar_icon.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); mPopupMenuHandle = menu->getHandle(); } diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp index 449bcc4f0b..7b5ce765d3 100644 --- a/indra/newview/llavatarlist.cpp +++ b/indra/newview/llavatarlist.cpp @@ -38,7 +38,7 @@ #include "llcallingcard.h" // for LLAvatarTracker #include "llcachename.h" -static LLDefaultWidgetRegistry::Register<LLAvatarList> r("avatar_list"); +static LLDefaultChildRegistry::Register<LLAvatarList> r("avatar_list"); LLAvatarList::Params::Params() { diff --git a/indra/newview/llbreadcrumbview.cpp b/indra/newview/llbreadcrumbview.cpp new file mode 100644 index 0000000000..342994ee30 --- /dev/null +++ b/indra/newview/llbreadcrumbview.cpp @@ -0,0 +1,37 @@ +/** + * @file llbreadcrumbview.cpp + * @brief UI widget for displaying position in a folder hierarchy and allowing + * the user to click on a location in the hierarchy. + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ +#include "llviewerprecompiledheaders.h" + +#include "llbreadcrumbview.h" + +// TODO diff --git a/indra/newview/llbreadcrumbview.h b/indra/newview/llbreadcrumbview.h new file mode 100644 index 0000000000..ca6fbe7fb2 --- /dev/null +++ b/indra/newview/llbreadcrumbview.h @@ -0,0 +1,36 @@ +/** + * @file llbreadcrumbview.h + * @brief UI widget for displaying position in a folder hierarchy and allowing + * the user to click on a location in the hierarchy. + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ +#ifndef LLBREADCRUMBVIEW_H +#define LLBREADCRUMBVIEW_H + +#endif // LLBREADCRUMBVIEW_H diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp index a97e56d60b..29845fff5e 100644 --- a/indra/newview/llchiclet.cpp +++ b/indra/newview/llchiclet.cpp @@ -41,6 +41,7 @@ #include "lloutputmonitorctrl.h" #include "llimview.h" #include "llbottomtray.h" +#include "llimpanel.h" static const S32 CHICLET_HEIGHT = 25; static const S32 CHICLET_SPACING = 0; @@ -52,10 +53,10 @@ static const S32 SCROLL_BUTTON_WIDTH = 19; static const S32 SCROLL_BUTTON_HEIGHT = 20; static const S32 NOTIFICATION_TEXT_TOP_PAD = 5; -static LLDefaultWidgetRegistry::Register<LLChicletPanel> t1("chiclet_panel"); -static LLDefaultWidgetRegistry::Register<LLTalkButton> t2("chiclet_talk"); -static LLDefaultWidgetRegistry::Register<LLNotificationChiclet> t3("chiclet_notification"); -static LLDefaultWidgetRegistry::Register<LLChicletPanel> t4("chiclet_panel"); +static LLDefaultChildRegistry::Register<LLChicletPanel> t1("chiclet_panel"); +static LLDefaultChildRegistry::Register<LLTalkButton> t2("chiclet_talk"); +static LLDefaultChildRegistry::Register<LLNotificationChiclet> t3("chiclet_notification"); +static LLDefaultChildRegistry::Register<LLChicletPanel> t4("chiclet_panel"); ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// @@ -317,6 +318,29 @@ LLChicletPanel::~LLChicletPanel() } +void im_chiclet_callback(LLChicletPanel* panel, const LLSD& data){ + + LLChiclet* chiclet = panel->findIMChiclet(&data["session_id"]); + + if (chiclet) + { + chiclet->setCounter(data["num_unread"].asInteger()); + } + else + { + llwarns << "Unable to set counter for chiclet " << data["session_id"].asUUID() << llendl; + } +} + + +BOOL LLChicletPanel::postBuild() +{ + LLPanel::postBuild(); + LLIMModel::instance().addChangedCallback(boost::bind(im_chiclet_callback, this, _1)); + + return TRUE; +} + LLChiclet* LLChicletPanel::createChiclet(LLSD* imSessionId, S32 pos) { LLChiclet* chiclet = LLIMChiclet::create(imSessionId); @@ -366,11 +390,18 @@ void LLChicletPanel::onChicletClick(LLUICtrl*ctrl,const LLSD¶m) { LLFloaterReg::showInstance("communicate", chiclet->getIMSessionId().asUUID()); } + + S32 x, y; + LLRect rect = chiclet->getRect(); + + localPointToScreen(rect.getCenterX(), 0, &x, &y); + LLIMFloater::show(chiclet->getIMSessionId().asUUID(), x); mCommitSignal(ctrl,param); } -LLChiclet* LLChicletPanel::findIMChiclet(LLSD* imSessionId) + +LLChiclet* LLChicletPanel::findIMChiclet(const LLSD* imSessionId) { chiclet_list_t::const_iterator it = mChicletList.begin(); for( ; mChicletList.end() != it; ++it) @@ -441,7 +472,7 @@ void LLChicletPanel::removeChiclet(LLChiclet*chiclet) } } -void LLChicletPanel::removeIMChiclet(LLSD* imSessionId) +void LLChicletPanel::removeIMChiclet(const LLSD* imSessionId) { chiclet_list_t::iterator it = mChicletList.begin(); for( ; mChicletList.end() != it; ++it) diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h index 65be9e183a..d861a528b5 100644 --- a/indra/newview/llchiclet.h +++ b/indra/newview/llchiclet.h @@ -188,7 +188,7 @@ public: LLChiclet* getChiclet(S32 pos); - LLChiclet* findIMChiclet(LLSD* imSessionId); + LLChiclet* findIMChiclet(const LLSD* imSessionId); S32 getChicletCount() {return mChicletList.size();}; @@ -196,7 +196,7 @@ public: void removeChiclet(LLChiclet*); - void removeIMChiclet(LLSD* imSessionId); + void removeIMChiclet(const LLSD* imSessionId); void removeAll(); @@ -215,6 +215,7 @@ public: //overrides public: + /*virtual*/ BOOL postBuild(); void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE ); diff --git a/indra/newview/llcolorswatch.cpp b/indra/newview/llcolorswatch.cpp index 33aaac542b..531e6d709a 100644 --- a/indra/newview/llcolorswatch.cpp +++ b/indra/newview/llcolorswatch.cpp @@ -51,7 +51,7 @@ #include "llviewerimagelist.h" #include "llfocusmgr.h" -static LLDefaultWidgetRegistry::Register<LLColorSwatchCtrl> r("color_swatch"); +static LLDefaultChildRegistry::Register<LLColorSwatchCtrl> r("color_swatch"); LLColorSwatchCtrl::Params::Params() : color("color", LLColor4::white), diff --git a/indra/newview/llcolorswatch.h b/indra/newview/llcolorswatch.h index a05926c2f5..db771df6b3 100644 --- a/indra/newview/llcolorswatch.h +++ b/indra/newview/llcolorswatch.h @@ -60,13 +60,13 @@ public: struct Params : public LLInitParam::Block<Params, LLUICtrl::Params> { - Optional<LLColor4> color; - Optional<bool> can_apply_immediately; - Optional<LLUIImage*> alpha_background_image; - Optional<commit_callback_t> cancel_callback; - Optional<commit_callback_t> select_callback; - Optional<LLUIColor> border_color; - Optional<S32> label_width; + Optional<LLColor4> color; + Optional<bool> can_apply_immediately; + Optional<LLUIImage*> alpha_background_image; + Optional<commit_callback_t> cancel_callback; + Optional<commit_callback_t> select_callback; + Optional<LLUIColor> border_color; + Optional<S32> label_width; Optional<LLTextBox::Params> caption_text; Optional<LLViewBorder::Params> border; diff --git a/indra/newview/lleventnotifier.cpp b/indra/newview/lleventnotifier.cpp index c0fe327815..2c52cf9565 100644 --- a/indra/newview/lleventnotifier.cpp +++ b/indra/newview/lleventnotifier.cpp @@ -192,9 +192,12 @@ bool LLEventNotification::handleResponse(const LLSD& notification, const LLSD& r switch (option) { case 0: - gAgent.teleportViaLocation(getEventPosGlobal()); - LLFloaterWorldMap::getInstance()->trackLocation(getEventPosGlobal()); - break; + { + gAgent.teleportViaLocation(getEventPosGlobal()); + LLFloaterWorldMap* floater_world_map = LLFloaterWorldMap::getInstance(); + if(floater_world_map) floater_world_map->trackLocation(getEventPosGlobal()); + break; + } case 1: gDisplayEventHack = TRUE; LLFloaterReg::showInstance("search", LLSD().insert("panel", "event").insert("id", S32(getEventID()))); diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp index f43b625d17..92e2d3563a 100644 --- a/indra/newview/llfavoritesbar.cpp +++ b/indra/newview/llfavoritesbar.cpp @@ -47,7 +47,7 @@ #include "llviewermenu.h" #include "llviewermenu.h" -static LLDefaultWidgetRegistry::Register<LLFavoritesBarCtrl> r("favorites_bar"); +static LLDefaultChildRegistry::Register<LLFavoritesBarCtrl> r("favorites_bar"); // updateButtons's helper struct LLFavoritesSort @@ -213,7 +213,7 @@ void LLFavoritesBarCtrl::updateButtons(U32 bar_width) const S32 buttonHPad = LLUI::sSettingGroups["config"]->getS32("ButtonHPad"); const S32 buttonHGap = 2; const S32 buttonVGap = 2; - static LLButton::Params default_button_params(LLUICtrlFactory::getDefaultParams<LLButton::Params>()); + static LLButton::Params default_button_params(LLUICtrlFactory::getDefaultParams<LLButton>()); std::string flat_icon = "transparent.j2c"; std::string hover_icon = default_button_params.image_unselected.name; std::string hover_icon_selected = default_button_params.image_selected.name; @@ -364,7 +364,7 @@ void LLFavoritesBarCtrl::updateButtons(U32 bar_width) BOOL LLFavoritesBarCtrl::postBuild() { // make the popup menu available - LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_favorites.xml", gMenuHolder); + LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_favorites.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); if (!menu) { menu = LLUICtrlFactory::getDefaultWidget<LLMenuGL>("inventory_menu"); diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp index bdd34dfca8..7332ca4b5c 100644 --- a/indra/newview/llfloaterabout.cpp +++ b/indra/newview/llfloaterabout.cpp @@ -78,7 +78,7 @@ static std::string get_viewer_release_notes_url(); // Default constructor LLFloaterAbout::LLFloaterAbout(const LLSD& key) -: LLFloater() +: LLFloater(key) { //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_about.xml"); diff --git a/indra/newview/llfloaterabout.h b/indra/newview/llfloaterabout.h index 1b0f3cddd3..c15a20d549 100644 --- a/indra/newview/llfloaterabout.h +++ b/indra/newview/llfloaterabout.h @@ -36,12 +36,11 @@ #include "llfloater.h" class LLFloaterAbout - : public LLFloater, public LLFloaterSingleton<LLFloaterAbout> + : public LLFloater { - friend class LLUISingleton<LLFloaterAbout, VisibilityPolicy<LLFloater> >; -public: + friend class LLFloaterReg; +private: LLFloaterAbout(const LLSD& key); -protected: virtual ~LLFloaterAbout(); public: diff --git a/indra/newview/llfloaterauction.cpp b/indra/newview/llfloaterauction.cpp index 8ad5a19d02..f5d950a9a5 100644 --- a/indra/newview/llfloaterauction.cpp +++ b/indra/newview/llfloaterauction.cpp @@ -72,7 +72,7 @@ void auction_tga_upload_done(const LLUUID& asset_id, // Default constructor LLFloaterAuction::LLFloaterAuction(const LLSD& key) - : LLFloater(), + : LLFloater(key), mParcelID(-1) { // LLUICtrlFactory::getInstance()->buildFloater(this, "floater_auction.xml"); diff --git a/indra/newview/llfloaterauction.h b/indra/newview/llfloaterauction.h index b018316c64..ebb1a0d1ae 100644 --- a/indra/newview/llfloaterauction.h +++ b/indra/newview/llfloaterauction.h @@ -46,18 +46,20 @@ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class LLParcelSelection; -class LLFloaterAuction : public LLFloater, public LLFloaterSingleton<LLFloaterAuction> +class LLFloaterAuction : public LLFloater { - friend class LLUISingleton<LLFloaterAuction, VisibilityPolicy<LLFloater> >; + friend class LLFloaterReg; public: // LLFloater interface /*virtual*/ void onClose(bool app_quitting) { setVisible(FALSE); } /*virtual*/ void onOpen(const LLSD& key); /*virtual*/ void draw(); + +private: LLFloaterAuction(const LLSD& key); ~LLFloaterAuction(); -private: + void initialize(); static void onClickSnapshot(void* data); diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp index 2c2dcda633..92ce44fa42 100644 --- a/indra/newview/llfloateravatarpicker.cpp +++ b/indra/newview/llfloateravatarpicker.cpp @@ -33,22 +33,25 @@ #include "llfloateravatarpicker.h" -#include "message.h" - +// Viewer includes #include "llagent.h" -#include "llbutton.h" #include "llfocusmgr.h" -#include "llinventoryview.h" +#include "llfloaterinventory.h" +#include "llfoldervieweventlistener.h" #include "llinventorymodel.h" +#include "llviewercontrol.h" +#include "llworld.h" + +// Linden libraries +#include "llbutton.h" #include "lllineeditor.h" #include "llscrolllistctrl.h" #include "llscrolllistitem.h" #include "llscrolllistcell.h" +#include "lltabcontainer.h" #include "lltextbox.h" #include "lluictrlfactory.h" -#include "llviewercontrol.h" -#include "llworld.h" -#include "lltabcontainer.h" +#include "message.h" // static LLFloaterAvatarPicker* LLFloaterAvatarPicker::sInstance = NULL; diff --git a/indra/newview/llfloateravatarpicker.h b/indra/newview/llfloateravatarpicker.h index 0f47401f23..0f28d8250b 100644 --- a/indra/newview/llfloateravatarpicker.h +++ b/indra/newview/llfloateravatarpicker.h @@ -87,6 +87,7 @@ private: static LLFloaterAvatarPicker* sInstance; +private: // do not call these directly LLFloaterAvatarPicker(); virtual ~LLFloaterAvatarPicker(); diff --git a/indra/newview/llfloaterbeacons.cpp b/indra/newview/llfloaterbeacons.cpp index 052f334285..1c7ef77718 100644 --- a/indra/newview/llfloaterbeacons.cpp +++ b/indra/newview/llfloaterbeacons.cpp @@ -40,9 +40,9 @@ LLFloaterBeacons::LLFloaterBeacons(const LLSD& seed) -: LLFloater() +: LLFloater(seed) { - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_beacons.xml"); +// LLUICtrlFactory::getInstance()->buildFloater(this, "floater_beacons.xml"); // Initialize pipeline states from saved settings. // OK to do at floater constructor time because beacons do not display unless the floater is open @@ -56,17 +56,11 @@ LLFloaterBeacons::LLFloaterBeacons(const LLSD& seed) LLPipeline::setRenderParticleBeacons( gSavedSettings.getBOOL("particlesbeacon")); LLPipeline::setRenderHighlights( gSavedSettings.getBOOL("renderhighlights")); LLPipeline::setRenderBeacons( gSavedSettings.getBOOL("renderbeacons")); + mCommitCallbackRegistrar.add("Beacons.UICheck", boost::bind(&LLFloaterBeacons::onClickUICheck, this,_1)); } BOOL LLFloaterBeacons::postBuild() { - childSetCommitCallback("touch_only", onClickUICheck, this); - childSetCommitCallback("scripted", onClickUICheck, this); - childSetCommitCallback("physical", onClickUICheck, this); - childSetCommitCallback("sounds", onClickUICheck, this); - childSetCommitCallback("particles", onClickUICheck, this); - childSetCommitCallback("highlights", onClickUICheck, this); - childSetCommitCallback("beacons", onClickUICheck, this); return TRUE; } @@ -87,12 +81,11 @@ void LLFloaterBeacons::onClose(bool app_quitting) // Callback attached to each check box control to both affect their main purpose // and to implement the couple screwy interdependency rules that some have. -//static -void LLFloaterBeacons::onClickUICheck(LLUICtrl *ctrl, void* data) + +void LLFloaterBeacons::onClickUICheck(LLUICtrl *ctrl) { LLCheckBoxCtrl *check = (LLCheckBoxCtrl *)ctrl; std::string name = check->getName(); - LLFloaterBeacons* view = (LLFloaterBeacons*)data; if( name == "touch_only") { LLPipeline::toggleRenderScriptedTouchBeacons(NULL); @@ -102,8 +95,8 @@ void LLFloaterBeacons::onClickUICheck(LLUICtrl *ctrl, void* data) LLPipeline::getRenderScriptedBeacons(NULL) ) { LLPipeline::setRenderScriptedBeacons(FALSE); - view->getChild<LLCheckBoxCtrl>("scripted")->setControlValue(LLSD(FALSE)); - view->getChild<LLCheckBoxCtrl>("touch_only")->setControlValue(LLSD(TRUE)); // just to be sure it's in sync with llpipeline + getChild<LLCheckBoxCtrl>("scripted")->setControlValue(LLSD(FALSE)); + getChild<LLCheckBoxCtrl>("touch_only")->setControlValue(LLSD(TRUE)); // just to be sure it's in sync with llpipeline } } else if(name == "scripted") @@ -115,8 +108,8 @@ void LLFloaterBeacons::onClickUICheck(LLUICtrl *ctrl, void* data) LLPipeline::getRenderScriptedBeacons(NULL) ) { LLPipeline::setRenderScriptedTouchBeacons(FALSE); - view->getChild<LLCheckBoxCtrl>("touch_only")->setControlValue(LLSD(FALSE)); - view->getChild<LLCheckBoxCtrl>("scripted")->setControlValue(LLSD(TRUE)); // just to be sure it's in sync with llpipeline + getChild<LLCheckBoxCtrl>("touch_only")->setControlValue(LLSD(FALSE)); + getChild<LLCheckBoxCtrl>("scripted")->setControlValue(LLSD(TRUE)); // just to be sure it's in sync with llpipeline } } else if(name == "physical") LLPipeline::setRenderPhysicalBeacons(check->get()); @@ -131,8 +124,8 @@ void LLFloaterBeacons::onClickUICheck(LLUICtrl *ctrl, void* data) !LLPipeline::getRenderHighlights(NULL) ) { LLPipeline::setRenderBeacons(TRUE); - view->getChild<LLCheckBoxCtrl>("beacons")->setControlValue(LLSD(TRUE)); - view->getChild<LLCheckBoxCtrl>("highlights")->setControlValue(LLSD(FALSE)); // just to be sure it's in sync with llpipeline + getChild<LLCheckBoxCtrl>("beacons")->setControlValue(LLSD(TRUE)); + getChild<LLCheckBoxCtrl>("highlights")->setControlValue(LLSD(FALSE)); // just to be sure it's in sync with llpipeline } } else if(name == "beacons") @@ -144,8 +137,8 @@ void LLFloaterBeacons::onClickUICheck(LLUICtrl *ctrl, void* data) !LLPipeline::getRenderHighlights(NULL) ) { LLPipeline::setRenderHighlights(TRUE); - view->getChild<LLCheckBoxCtrl>("highlights")->setControlValue(LLSD(TRUE)); - view->getChild<LLCheckBoxCtrl>("beacons")->setControlValue(LLSD(FALSE)); // just to be sure it's in sync with llpipeline + getChild<LLCheckBoxCtrl>("highlights")->setControlValue(LLSD(TRUE)); + getChild<LLCheckBoxCtrl>("beacons")->setControlValue(LLSD(FALSE)); // just to be sure it's in sync with llpipeline } } } diff --git a/indra/newview/llfloaterbeacons.h b/indra/newview/llfloaterbeacons.h index 8156e82ac3..94f853978a 100644 --- a/indra/newview/llfloaterbeacons.h +++ b/indra/newview/llfloaterbeacons.h @@ -36,22 +36,22 @@ #include "llfloater.h" -class LLFloaterBeacons : public LLFloater, public LLFloaterSingleton<LLFloaterBeacons> +class LLFloaterBeacons : public LLFloater { - friend class LLUISingleton<LLFloaterBeacons, VisibilityPolicy<LLFloater> >; + friend class LLFloaterReg; public: + /*virtual*/ BOOL postBuild(); // Needed to make the floater visibility toggle the beacons. // Too bad we can't just add control_name="BeaconAlwaysOn" to the XML. /*virtual*/ void onOpen(const LLSD& key); /*virtual*/ void onClose(bool app_quitting); + void onClickUICheck(LLUICtrl *ctrl); private: LLFloaterBeacons(const LLSD& seed); - - static void onClickUICheck(LLUICtrl *ctrl, void* data); }; #endif diff --git a/indra/newview/llfloaterbuildoptions.cpp b/indra/newview/llfloaterbuildoptions.cpp index 9dbd1db38e..30e9428df9 100644 --- a/indra/newview/llfloaterbuildoptions.cpp +++ b/indra/newview/llfloaterbuildoptions.cpp @@ -44,7 +44,7 @@ // Methods // LLFloaterBuildOptions::LLFloaterBuildOptions(const LLSD& key) - : LLFloater() + : LLFloater(key) { //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_build_options.xml"); } diff --git a/indra/newview/llfloaterbuildoptions.h b/indra/newview/llfloaterbuildoptions.h index 61db303ba2..43cbb201c2 100644 --- a/indra/newview/llfloaterbuildoptions.h +++ b/indra/newview/llfloaterbuildoptions.h @@ -42,10 +42,10 @@ class LLFloaterBuildOptions - : public LLFloater, public LLFloaterSingleton<LLFloaterBuildOptions> + : public LLFloater { - friend class LLUISingleton<LLFloaterBuildOptions, VisibilityPolicy<LLFloater> >; -public: + friend class LLFloaterReg; +private: LLFloaterBuildOptions(const LLSD& key); ~LLFloaterBuildOptions(); }; diff --git a/indra/newview/llfloaterbulkpermission.cpp b/indra/newview/llfloaterbulkpermission.cpp index 65dc3cd9f0..efaebe311a 100644 --- a/indra/newview/llfloaterbulkpermission.cpp +++ b/indra/newview/llfloaterbulkpermission.cpp @@ -58,22 +58,22 @@ LLFloaterBulkPermission::LLFloaterBulkPermission(const LLSD& seed) -: LLFloater(), +: LLFloater(seed), mDone(FALSE) { mID.generate(); - LLUICtrlFactory::getInstance()->buildFloater(this,"floater_bulk_perms.xml"); +// LLUICtrlFactory::getInstance()->buildFloater(this,"floater_bulk_perms.xml"); + mCommitCallbackRegistrar.add("BulkPermission.Apply", boost::bind(&LLFloaterBulkPermission::onApplyBtn, this)); + mCommitCallbackRegistrar.add("BulkPermission.Close", boost::bind(&LLFloaterBulkPermission::onCloseBtn, this)); + mCommitCallbackRegistrar.add("BulkPermission.CheckAll", boost::bind(&LLFloaterBulkPermission::onCheckAll, this)); + mCommitCallbackRegistrar.add("BulkPermission.UncheckAll", boost::bind(&LLFloaterBulkPermission::onUncheckAll, this)); + mCommitCallbackRegistrar.add("BulkPermission.CommitCopy", boost::bind(&LLFloaterBulkPermission::onCommitCopy, this)); } BOOL LLFloaterBulkPermission::postBuild() { - childSetEnabled("next_owner_transfer", gSavedSettings.getBOOL("BulkChangeNextOwnerCopy")); - childSetAction("help", onHelpBtn, this); - childSetAction("apply", onApplyBtn, this); - childSetAction("close", onCloseBtn, this); - childSetAction("check_all", onCheckAll, this); - childSetAction("check_none", onUncheckAll, this); - childSetCommitCallback("next_owner_copy", &onCommitCopy, this); +// childSetAction("help", onHelpBtn, this); // this is not in use + return TRUE; } @@ -152,34 +152,32 @@ void LLFloaterBulkPermission::inventoryChanged(LLViewerObject* viewer_object, } } -void LLFloaterBulkPermission::onApplyBtn(void* user_data) +void LLFloaterBulkPermission::onApplyBtn() { - LLFloaterBulkPermission* self = static_cast<LLFloaterBulkPermission*>(user_data); - self->doApply(); + doApply(); } -void LLFloaterBulkPermission::onHelpBtn(void* user_data) -{ - LLNotifications::instance().add("HelpBulkPermission"); -} +// angela -- this is not in use +//void LLFloaterBulkPermission::onHelpBtn(void* user_data) +//{ +// LLNotifications::instance().add("HelpBulkPermission"); +//} -void LLFloaterBulkPermission::onCloseBtn(void* user_data) +void LLFloaterBulkPermission::onCloseBtn() { - LLFloaterBulkPermission* self = static_cast<LLFloaterBulkPermission*>(user_data); - self->onClose(false); + onClose(false); } //static -void LLFloaterBulkPermission::onCommitCopy(LLUICtrl* ctrl, void* data) +void LLFloaterBulkPermission::onCommitCopy() { - LLFloaterBulkPermission* self = static_cast<LLFloaterBulkPermission*>(data); // Implements fair use BOOL copyable = gSavedSettings.getBOOL("BulkChangeNextOwnerCopy"); if(!copyable) { gSavedSettings.setBOOL("BulkChangeNextOwnerTransfer", TRUE); } - LLCheckBoxCtrl* xfer = self->getChild<LLCheckBoxCtrl>("next_owner_transfer"); + LLCheckBoxCtrl* xfer =getChild<LLCheckBoxCtrl>("next_owner_transfer"); xfer->setEnabled(copyable); } diff --git a/indra/newview/llfloaterbulkpermission.h b/indra/newview/llfloaterbulkpermission.h index 2ea12fbe69..c34e4413cc 100644 --- a/indra/newview/llfloaterbulkpermission.h +++ b/indra/newview/llfloaterbulkpermission.h @@ -46,14 +46,16 @@ #include "llviewerinventory.h" -class LLFloaterBulkPermission : public LLFloater, public LLVOInventoryListener, public LLFloaterSingleton<LLFloaterBulkPermission> +class LLFloaterBulkPermission : public LLFloater, public LLVOInventoryListener { + friend class LLFloaterReg; public: - LLFloaterBulkPermission(const LLSD& seed); BOOL postBuild(); private: + + LLFloaterBulkPermission(const LLSD& seed); virtual ~LLFloaterBulkPermission() {} BOOL start(); // returns TRUE if the queue has started, otherwise FALSE. @@ -77,12 +79,12 @@ private: U8 key, bool is_new); - static void onHelpBtn(void* user_data); - static void onCloseBtn(void* user_data); - static void onApplyBtn(void* user_data); - static void onCommitCopy(LLUICtrl* ctrl, void* data); - static void onCheckAll( void* user_data) { ((LLFloaterBulkPermission*)user_data)->doCheckUncheckAll(TRUE); } - static void onUncheckAll(void* user_data) { ((LLFloaterBulkPermission*)user_data)->doCheckUncheckAll(FALSE); } +// static void onHelpBtn(void* user_data); + void onCloseBtn(); + void onApplyBtn(); + void onCommitCopy(); + void onCheckAll() { doCheckUncheckAll(TRUE); } + void onUncheckAll() { doCheckUncheckAll(FALSE); } // returns true if this is done BOOL isDone() const { return (mCurrentObjectID.isNull() || (mObjectIDs.count() == 0)); } diff --git a/indra/newview/llfloaterbump.cpp b/indra/newview/llfloaterbump.cpp index e4e1c7efa2..8b64f913e0 100644 --- a/indra/newview/llfloaterbump.cpp +++ b/indra/newview/llfloaterbump.cpp @@ -45,11 +45,13 @@ ///---------------------------------------------------------------------------- /// Class LLFloaterBump ///---------------------------------------------------------------------------- +extern BOOL gNoRender; // Default constructor LLFloaterBump::LLFloaterBump(const LLSD& key) -: LLFloater() +: LLFloater(key) { + if(gNoRender) return; //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_bumps.xml"); } diff --git a/indra/newview/llfloaterbump.h b/indra/newview/llfloaterbump.h index b56817436c..1f2cb6d6ab 100644 --- a/indra/newview/llfloaterbump.h +++ b/indra/newview/llfloaterbump.h @@ -40,14 +40,17 @@ class LLMeanCollisionData; class LLScrollListCtrl; class LLFloaterBump -: public LLFloater, public LLFloaterSingleton<LLFloaterBump> +: public LLFloater { - friend class LLUISingleton<LLFloaterBump, VisibilityPolicy<LLFloater> >; + friend class LLFloaterReg; protected: void add(LLScrollListCtrl* list, LLMeanCollisionData *mcd); public: /*virtual*/ void onOpen(const LLSD& key); + +private: + LLFloaterBump(const LLSD& key); virtual ~LLFloaterBump(); }; diff --git a/indra/newview/llfloaterbuy.cpp b/indra/newview/llfloaterbuy.cpp index 9c523522fd..aba2402b0c 100644 --- a/indra/newview/llfloaterbuy.cpp +++ b/indra/newview/llfloaterbuy.cpp @@ -43,7 +43,7 @@ #include "llagent.h" // for agent id #include "llalertdialog.h" #include "llinventorymodel.h" // for gInventory -#include "llinventoryview.h" // for get_item_icon +#include "llfloaterinventory.h" // for get_item_icon #include "llselectmgr.h" #include "llscrolllistctrl.h" #include "llviewerobject.h" diff --git a/indra/newview/llfloaterbuycontents.cpp b/indra/newview/llfloaterbuycontents.cpp index 7a90275201..db4547e5bc 100644 --- a/indra/newview/llfloaterbuycontents.cpp +++ b/indra/newview/llfloaterbuycontents.cpp @@ -46,7 +46,7 @@ #include "llalertdialog.h" #include "llcheckboxctrl.h" #include "llinventorymodel.h" // for gInventory -#include "llinventoryview.h" // for get_item_icon +#include "llfloaterinventory.h" // for get_item_icon #include "llselectmgr.h" #include "llscrolllistctrl.h" #include "llviewerobject.h" @@ -287,7 +287,7 @@ void LLFloaterBuyContents::onClickBuy(void*) // We may want to wear this item if (sInstance->childGetValue("wear_check")) { - LLInventoryView::sWearNewClothing = TRUE; + LLFloaterInventory::sWearNewClothing = TRUE; } // Put the items where we put new folders. diff --git a/indra/newview/llfloatercamera.cpp b/indra/newview/llfloatercamera.cpp index e79142513b..1c99776c11 100644 --- a/indra/newview/llfloatercamera.cpp +++ b/indra/newview/llfloatercamera.cpp @@ -48,11 +48,11 @@ const F32 CAMERA_BUTTON_DELAY = 0.0f; // Member functions // LLFloaterCamera::LLFloaterCamera(const LLSD& val) -: LLFloater() +: LLFloater(val) { - // For now, only used for size and tooltip strings - const BOOL DONT_OPEN = FALSE; - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_camera.xml", DONT_OPEN); + //// For now, only used for size and tooltip strings + //const BOOL DONT_OPEN = FALSE; + //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_camera.xml", DONT_OPEN); } // virtual diff --git a/indra/newview/llfloatercamera.h b/indra/newview/llfloatercamera.h index f954e329eb..daea9ecee1 100644 --- a/indra/newview/llfloatercamera.h +++ b/indra/newview/llfloatercamera.h @@ -40,12 +40,12 @@ class LLJoystickCameraZoom; class LLJoystickCameraTrack; class LLFloaterCamera - : public LLFloater, - public LLFloaterSingleton<LLFloaterCamera> + : public LLFloater { - friend class LLUISingleton<LLFloaterCamera, VisibilityPolicy<LLFloater> >; + friend class LLFloaterReg; private: + LLFloaterCamera(const LLSD& val); ~LLFloaterCamera() {}; @@ -53,6 +53,7 @@ private: /*virtual*/ void onClose(bool app_quitting); /*virtual*/ BOOL postBuild(); public: + LLJoystickCameraRotate* mRotate; LLJoystickCameraZoom* mZoom; LLJoystickCameraTrack* mTrack; diff --git a/indra/newview/llfloaterchat.cpp b/indra/newview/llfloaterchat.cpp index 5250c798f9..1bfb11e3ae 100644 --- a/indra/newview/llfloaterchat.cpp +++ b/indra/newview/llfloaterchat.cpp @@ -96,7 +96,7 @@ LLColor4 get_text_color(const LLChat& chat); // Member Functions // LLFloaterChat::LLFloaterChat(const LLSD& seed) - : LLFloater(), + : LLFloater(seed), mPanel(NULL) { mFactoryMap["chat_panel"] = LLCallbackMap(createChatPanel, NULL); @@ -558,6 +558,6 @@ void LLFloaterChat::onClickToggleActiveSpeakers(void* userdata) //static LLFloaterChat* LLFloaterChat::getInstance() { - LLFloater* inst = LLFloaterReg::getInstance("chat", LLSD()) ; - return dynamic_cast<LLFloaterChat*>(inst); + return LLFloaterReg::getTypedInstance<LLFloaterChat>("chat", LLSD()) ; + } diff --git a/indra/newview/llfloaterchatterbox.cpp b/indra/newview/llfloaterchatterbox.cpp index a283b445f5..3389770b2f 100644 --- a/indra/newview/llfloaterchatterbox.cpp +++ b/indra/newview/llfloaterchatterbox.cpp @@ -98,8 +98,7 @@ void* LLFloaterMyFriends::createGroupsPanel(void* data) //static LLFloaterMyFriends* LLFloaterMyFriends::getInstance() { - LLFloater* inst = LLFloaterReg::getInstance("contacts", "friends") ; - return dynamic_cast<LLFloaterMyFriends*>(inst); + return LLFloaterReg::getTypedInstance<LLFloaterMyFriends>("contacts", "friends") ; } // @@ -123,11 +122,14 @@ BOOL LLFloaterChatterBox::postBuild() if (gSavedSettings.getBOOL("ContactsTornOff")) { LLFloaterMyFriends* floater_contacts = LLFloaterMyFriends::getInstance(); - // add then remove to set up relationship for re-attach - addFloater(floater_contacts, FALSE); - removeFloater(floater_contacts); - // reparent to floater view - gFloaterView->addChild(floater_contacts); + if(floater_contacts) + { + // add then remove to set up relationship for re-attach + addFloater(floater_contacts, FALSE); + removeFloater(floater_contacts); + // reparent to floater view + gFloaterView->addChild(floater_contacts); + } } else { @@ -137,11 +139,14 @@ BOOL LLFloaterChatterBox::postBuild() if (gSavedSettings.getBOOL("ChatHistoryTornOff")) { LLFloaterChat* floater_chat = LLFloaterChat::getInstance(); - // add then remove to set up relationship for re-attach - addFloater(floater_chat, FALSE); - removeFloater(floater_chat); - // reparent to floater view - gFloaterView->addChild(floater_chat); + if(floater_chat) + { + // add then remove to set up relationship for re-attach + addFloater(floater_chat, FALSE); + removeFloater(floater_chat); + // reparent to floater view + gFloaterView->addChild(floater_chat); + } } else { @@ -249,11 +254,17 @@ void LLFloaterChatterBox::setMinimized(BOOL minimized) { LLFloater::setMinimized(minimized); // HACK: potentially need to toggle console - LLFloaterChat::getInstance()->updateConsoleVisibility(); + LLFloaterChat* instance = LLFloaterChat::getInstance(); + if(instance) + { + instance->updateConsoleVisibility(); + } } void LLFloaterChatterBox::removeFloater(LLFloater* floaterp) { + if(!floaterp) return; + if (floaterp->getName() == "chat floater") { // only my friends floater now locked @@ -275,6 +286,8 @@ void LLFloaterChatterBox::addFloater(LLFloater* floaterp, BOOL select_added_floater, LLTabContainer::eInsertionPoint insertion_point) { + if(!floaterp) return; + S32 num_locked_tabs = mTabContainer->getNumLockedTabs(); // already here @@ -332,8 +345,7 @@ void LLFloaterChatterBox::addFloater(LLFloater* floaterp, //static LLFloaterChatterBox* LLFloaterChatterBox::getInstance() { - LLFloater* inst = LLFloaterReg::getInstance("communicate", LLSD()) ; - return dynamic_cast<LLFloaterChatterBox*>(inst); + return LLFloaterReg::getTypedInstance<LLFloaterChatterBox>("communicate", LLSD()) ; } //static @@ -351,6 +363,7 @@ LLFloater* LLFloaterChatterBox::getCurrentVoiceFloater() else { LLFloaterChatterBox* floater = LLFloaterChatterBox::getInstance(); + if(!floater) return NULL; // iterator over all IM tabs (skip friends and near me) for (S32 i = 0; i < floater->getFloaterCount(); i++) { diff --git a/indra/newview/llfloaterfonttest.cpp b/indra/newview/llfloaterfonttest.cpp index 02791b711e..413992910e 100644 --- a/indra/newview/llfloaterfonttest.cpp +++ b/indra/newview/llfloaterfonttest.cpp @@ -42,25 +42,11 @@ #include "lluictrlfactory.h" -LLFloaterFontTest* LLFloaterFontTest::sInstance = NULL; - -LLFloaterFontTest::LLFloaterFontTest() +LLFloaterFontTest::LLFloaterFontTest(const LLSD& key) : LLFloater("floater_font_test") { - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_font_test.xml"); } LLFloaterFontTest::~LLFloaterFontTest() { - sInstance = NULL; -} - -// static -void LLFloaterFontTest::show(void *unused) -{ - if (!sInstance) - sInstance = new LLFloaterFontTest(); - - sInstance->openFloater(); - sInstance->setFocus(TRUE); } diff --git a/indra/newview/llfloaterfonttest.h b/indra/newview/llfloaterfonttest.h index eb2d410387..4406a9f36a 100644 --- a/indra/newview/llfloaterfonttest.h +++ b/indra/newview/llfloaterfonttest.h @@ -39,14 +39,10 @@ class LLFloaterFontTest: public LLFloater { -public: - static void show(void* unused); - + friend class LLFloaterReg; private: - LLFloaterFontTest(); + LLFloaterFontTest(const LLSD& key); ~LLFloaterFontTest(); - - static LLFloaterFontTest* sInstance; }; #endif diff --git a/indra/newview/llfloatergesture.cpp b/indra/newview/llfloatergesture.cpp index c3448d52c9..9999b58e5b 100644 --- a/indra/newview/llfloatergesture.cpp +++ b/indra/newview/llfloatergesture.cpp @@ -44,7 +44,7 @@ #include "llcombobox.h" #include "llgesturemgr.h" #include "llinventorymodel.h" -#include "llinventoryview.h" +#include "llfloaterinventory.h" #include "llkeyboard.h" #include "lllineeditor.h" #include "llpreviewgesture.h" @@ -322,7 +322,7 @@ void LLFloaterGesture::onClickInventory(void* data) if (!list) return; const LLUUID& item_id = list->getCurrentID(); - LLInventoryView* inv = LLInventoryView::showAgentInventory(); + LLFloaterInventory* inv = LLFloaterInventory::showAgentInventory(); if (!inv) return; inv->getPanel()->setSelection(item_id, TRUE); } diff --git a/indra/newview/llfloatergodtools.cpp b/indra/newview/llfloatergodtools.cpp index 58cbe02d6d..6d603fa5c8 100644 --- a/indra/newview/llfloatergodtools.cpp +++ b/indra/newview/llfloatergodtools.cpp @@ -50,6 +50,7 @@ #include "llcombobox.h" #include "lldraghandle.h" #include "llfloater.h" +#include "llfloaterreg.h" #include "llfocusmgr.h" #include "llfloatertopobjects.h" #include "lllineeditor.h" @@ -105,7 +106,7 @@ void LLFloaterGodTools::onOpen(const LLSD& key) // static void LLFloaterGodTools::refreshAll() { - LLFloaterGodTools* god_tools = getInstance(); + LLFloaterGodTools* god_tools = LLFloaterReg::getTypedInstance<LLFloaterGodTools>("god_tools"); if (god_tools) { if (gAgent.getRegionHost() != god_tools->mCurrentHost) @@ -119,7 +120,7 @@ void LLFloaterGodTools::refreshAll() LLFloaterGodTools::LLFloaterGodTools(const LLSD& key) -: LLFloater(), +: LLFloater(key), mCurrentHost(LLHost::invalid), mUpdateTimer() { @@ -127,13 +128,16 @@ LLFloaterGodTools::LLFloaterGodTools(const LLSD& key) mFactoryMap["region"] = LLCallbackMap(createPanelRegion, this); mFactoryMap["objects"] = LLCallbackMap(createPanelObjects, this); mFactoryMap["request"] = LLCallbackMap(createPanelRequest, this); - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_god_tools.xml"); +// LLUICtrlFactory::getInstance()->buildFloater(this, "floater_god_tools.xml"); - sendRegionInfoRequest(); +} +BOOL LLFloaterGodTools::postBuild() +{ + sendRegionInfoRequest(); childShowTab("GodTools Tabs", "region"); + return TRUE; } - // static void* LLFloaterGodTools::createPanelGrid(void *userdata) { @@ -166,10 +170,7 @@ LLFloaterGodTools::~LLFloaterGodTools() { // children automatically deleted } -BOOL LLFloaterGodTools::postBuild() -{ - return TRUE; -} + U32 LLFloaterGodTools::computeRegionFlags() const { @@ -187,10 +188,10 @@ void LLFloaterGodTools::updatePopup(LLCoordGL center, MASK mask) // virtual void LLFloaterGodTools::onClose(bool app_quitting) { - if (getInstance()) - { - getInstance()->setVisible(FALSE); - } + LLFloaterGodTools* god_tools = LLFloaterReg::getTypedInstance<LLFloaterGodTools>("god_tools"); + if(!god_tools) return; + god_tools->setVisible(FALSE); + } // virtual @@ -271,16 +272,19 @@ void LLFloaterGodTools::processRegionInfo(LLMessageSystem* msg) regionp->setWaterHeight(water_height); regionp->setBillableFactor(billable_factor); } + + LLFloaterGodTools* god_tools = LLFloaterReg::getTypedInstance<LLFloaterGodTools>("god_tools"); + if (!god_tools) return; // push values to god tools, if available if ( gAgent.isGodlike() - && instanceVisible() - && getInstance()->mPanelRegionTools - && getInstance()->mPanelObjectTools + && LLFloaterReg::instanceVisible("god_tools") + && god_tools->mPanelRegionTools + && god_tools->mPanelObjectTools && msg ) { - LLPanelRegionTools* rtool = getInstance()->mPanelRegionTools; - getInstance()->mCurrentHost = host; + LLPanelRegionTools* rtool = god_tools->mPanelRegionTools; + god_tools->mCurrentHost = host; // store locally rtool->setSimName(sim_name); @@ -293,7 +297,7 @@ void LLFloaterGodTools::processRegionInfo(LLMessageSystem* msg) rtool->setRedirectGridY(redirect_grid_y); rtool->enableAllWidgets(); - LLPanelObjectTools *otool = getInstance()->mPanelObjectTools; + LLPanelObjectTools *otool = god_tools->mPanelObjectTools; otool->setCheckFlags(region_flags); otool->enableAllWidgets(); @@ -336,14 +340,17 @@ void LLFloaterGodTools::sendRegionInfoRequest() void LLFloaterGodTools::sendGodUpdateRegionInfo() { + LLFloaterGodTools* god_tools = LLFloaterReg::getTypedInstance<LLFloaterGodTools>("god_tools"); + if (!god_tools) return; + LLViewerRegion *regionp = gAgent.getRegion(); if (gAgent.isGodlike() - && getInstance()->mPanelRegionTools + && god_tools->mPanelRegionTools && regionp && gAgent.getRegionHost() == mCurrentHost) { LLMessageSystem *msg = gMessageSystem; - LLPanelRegionTools *rtool = getInstance()->mPanelRegionTools; + LLPanelRegionTools *rtool = god_tools->mPanelRegionTools; msg->newMessage("GodUpdateRegionInfo"); msg->nextBlockFast(_PREHASH_AgentData); @@ -403,58 +410,31 @@ const F32 PRICE_PER_METER_MAX = 100.f; LLPanelRegionTools::LLPanelRegionTools() : LLPanel() { + mCommitCallbackRegistrar.add("RegionTools.ChangeAnything", boost::bind(&LLPanelRegionTools::onChangeAnything, this)); + mCommitCallbackRegistrar.add("RegionTools.ChangePrelude", boost::bind(&LLPanelRegionTools::onChangePrelude, this)); + mCommitCallbackRegistrar.add("RegionTools.BakeTerrain", boost::bind(&LLPanelRegionTools::onBakeTerrain, this)); + mCommitCallbackRegistrar.add("RegionTools.RevertTerrain", boost::bind(&LLPanelRegionTools::onRevertTerrain, this)); + mCommitCallbackRegistrar.add("RegionTools.SwapTerrain", boost::bind(&LLPanelRegionTools::onSwapTerrain, this)); + mCommitCallbackRegistrar.add("RegionTools.Refresh", boost::bind(&LLPanelRegionTools::onRefresh, this)); + mCommitCallbackRegistrar.add("RegionTools.ApplyChanges", boost::bind(&LLPanelRegionTools::onApplyChanges, this)); + mCommitCallbackRegistrar.add("RegionTools.SelectRegion", boost::bind(&LLPanelRegionTools::onSelectRegion, this)); + mCommitCallbackRegistrar.add("RegionTools.SaveState", boost::bind(&LLPanelRegionTools::onSaveState, this)); } BOOL LLPanelRegionTools::postBuild() { - childSetCommitCallback("region name", onChangeAnything, this); getChild<LLLineEditor>("region name")->setKeystrokeCallback(onChangeSimName, this); childSetPrevalidate("region name", &LLLineEditor::prevalidatePrintableNotPipe); - - childSetCommitCallback("check prelude", onChangePrelude, this); - childSetCommitCallback("check fixed sun", onChangeAnything, this); - childSetCommitCallback("check reset home", onChangeAnything, this); - childSetCommitCallback("check visible", onChangeAnything, this); - childSetCommitCallback("check damage", onChangeAnything, this); - childSetCommitCallback("block dwell", onChangeAnything, this); - childSetCommitCallback("block terraform", onChangeAnything, this); - childSetCommitCallback("allow transfer", onChangeAnything, this); - childSetCommitCallback("is sandbox", onChangeAnything, this); - - childSetAction("Bake Terrain", onBakeTerrain, this); - childSetAction("Revert Terrain", onRevertTerrain, this); - childSetAction("Swap Terrain", onSwapTerrain, this); - - childSetCommitCallback("estate", onChangeAnything, this); childSetPrevalidate("estate", &LLLineEditor::prevalidatePositiveS32); - - childSetCommitCallback("parentestate", onChangeAnything, this); childSetPrevalidate("parentestate", &LLLineEditor::prevalidatePositiveS32); childDisable("parentestate"); - - childSetCommitCallback("gridposx", onChangeAnything, this); childSetPrevalidate("gridposx", &LLLineEditor::prevalidatePositiveS32); childDisable("gridposx"); - - childSetCommitCallback("gridposy", onChangeAnything, this); childSetPrevalidate("gridposy", &LLLineEditor::prevalidatePositiveS32); childDisable("gridposy"); - - childSetCommitCallback("redirectx", onChangeAnything, this); + childSetPrevalidate("redirectx", &LLLineEditor::prevalidatePositiveS32); - - childSetCommitCallback("redirecty", onChangeAnything, this); childSetPrevalidate("redirecty", &LLLineEditor::prevalidatePositiveS32); - - childSetCommitCallback("billable factor", onChangeAnything, this); - - childSetCommitCallback("land cost", onChangeAnything, this); - - childSetAction("Refresh", onRefresh, this); - childSetAction("Apply", onApplyChanges, this); - - childSetAction("Select Region", onSelectRegion, this); - childSetAction("Autosave now", onSaveState, this); return TRUE; } @@ -541,8 +521,6 @@ void LLPanelRegionTools::enableAllWidgets() childEnable("Autosave now"); } - -// static void LLPanelRegionTools::onSaveState(void* userdata) { if (gAgent.isGodlike()) @@ -739,28 +717,25 @@ void LLPanelRegionTools::setPricePerMeter(S32 price) childSetValue("land cost", price); } -// static -void LLPanelRegionTools::onChangeAnything(LLUICtrl* ctrl, void* userdata) +void LLPanelRegionTools::onChangeAnything() { - if (userdata && gAgent.isGodlike()) + if (gAgent.isGodlike()) { - LLPanelRegionTools* region_tools = (LLPanelRegionTools*) userdata; - region_tools->childEnable("Apply"); + childEnable("Apply"); } } -// static -void LLPanelRegionTools::onChangePrelude(LLUICtrl* ctrl, void* data) +void LLPanelRegionTools::onChangePrelude() { // checking prelude auto-checks fixed sun - LLPanelRegionTools* self = (LLPanelRegionTools*)data; - if (self->childGetValue("check prelude").asBoolean()) + if (childGetValue("check prelude").asBoolean()) { - self->childSetValue("check fixed sun", TRUE); - self->childSetValue("check reset home", TRUE); + childSetValue("check fixed sun", TRUE); + childSetValue("check reset home", TRUE); + onChangeAnything(); } // pass on to default onChange handler - onChangeAnything(ctrl, data); + } // static @@ -773,49 +748,50 @@ void LLPanelRegionTools::onChangeSimName(LLLineEditor* caller, void* userdata ) } } -//static -void LLPanelRegionTools::onRefresh(void* userdata) + +void LLPanelRegionTools::onRefresh() { + LLFloaterGodTools* god_tools = LLFloaterReg::getTypedInstance<LLFloaterGodTools>("god_tools"); + if(!god_tools) return; LLViewerRegion *region = gAgent.getRegion(); if (region && gAgent.isGodlike()) { - LLFloaterGodTools::getInstance()->sendRegionInfoRequest(); + god_tools->sendRegionInfoRequest(); + //LLFloaterGodTools::getInstance()->sendRegionInfoRequest(); + //LLFloaterReg::getTypedInstance<LLFloaterGodTools>("god_tools")->sendRegionInfoRequest(); } } -// static -void LLPanelRegionTools::onApplyChanges(void* userdata) +void LLPanelRegionTools::onApplyChanges() { + LLFloaterGodTools* god_tools = LLFloaterReg::getTypedInstance<LLFloaterGodTools>("god_tools"); + if(!god_tools) return; LLViewerRegion *region = gAgent.getRegion(); - if (region && userdata && gAgent.isGodlike()) + if (region && gAgent.isGodlike()) { - LLPanelRegionTools* region_tools = (LLPanelRegionTools*) userdata; - - region_tools->childDisable("Apply"); - LLFloaterGodTools::getInstance()->sendGodUpdateRegionInfo(); + childDisable("Apply"); + god_tools->sendGodUpdateRegionInfo(); + //LLFloaterReg::getTypedInstance<LLFloaterGodTools>("god_tools")->sendGodUpdateRegionInfo(); } } -// static -void LLPanelRegionTools::onBakeTerrain(void *userdata) +void LLPanelRegionTools::onBakeTerrain() { LLPanelRequestTools::sendRequest("terrain", "bake", gAgent.getRegionHost()); } -// static -void LLPanelRegionTools::onRevertTerrain(void *userdata) +void LLPanelRegionTools::onRevertTerrain() { LLPanelRequestTools::sendRequest("terrain", "revert", gAgent.getRegionHost()); } -// static -void LLPanelRegionTools::onSwapTerrain(void *userdata) + +void LLPanelRegionTools::onSwapTerrain() { LLPanelRequestTools::sendRequest("terrain", "swap", gAgent.getRegionHost()); } -// static -void LLPanelRegionTools::onSelectRegion(void* userdata) +void LLPanelRegionTools::onSelectRegion() { llinfos << "LLPanelRegionTools::onSelectRegion" << llendl; @@ -860,6 +836,8 @@ const F32 HOURS_TO_RADIANS = (2.f*F_PI)/24.f; LLPanelGridTools::LLPanelGridTools() : LLPanel() { + mCommitCallbackRegistrar.add("GridTools.KickAll", boost::bind(&LLPanelGridTools::onClickKickAll, this)); + mCommitCallbackRegistrar.add("GridTools.FlushMapVisibilityCaches", boost::bind(&LLPanelGridTools::onClickFlushMapVisibilityCaches, this)); } // Destroys the object @@ -869,9 +847,6 @@ LLPanelGridTools::~LLPanelGridTools() BOOL LLPanelGridTools::postBuild() { - childSetAction("Kick all users", onClickKickAll, this); - childSetAction("Flush This Region's Map Visibility Caches", onClickFlushMapVisibilityCaches, this); - return TRUE; } @@ -879,9 +854,7 @@ void LLPanelGridTools::refresh() { } - -// static -void LLPanelGridTools::onClickKickAll(void* userdata) +void LLPanelGridTools::onClickKickAll() { LLNotifications::instance().add("KickAllUsers", LLSD(), LLSD(), LLPanelGridTools::confirmKick); } @@ -921,9 +894,7 @@ bool LLPanelGridTools::finishKick(const LLSD& notification, const LLSD& response return false; } - -// static -void LLPanelGridTools::onClickFlushMapVisibilityCaches(void* data) +void LLPanelGridTools::onClickFlushMapVisibilityCaches() { LLNotifications::instance().add("FlushMapVisibilityCaches", LLSD(), LLSD(), flushMapVisibilityCachesConfirm); } @@ -981,6 +952,15 @@ LLPanelObjectTools::LLPanelObjectTools() : LLPanel(), mTargetAvatar() { + mCommitCallbackRegistrar.add("ObjectTools.ChangeAnything", boost::bind(&LLPanelObjectTools::onChangeAnything, this)); + mCommitCallbackRegistrar.add("ObjectTools.DeletePublicOwnedBy", boost::bind(&LLPanelObjectTools::onClickDeletePublicOwnedBy, this)); + mCommitCallbackRegistrar.add("ObjectTools.DeleteAllScriptedOwnedBy", boost::bind(&LLPanelObjectTools::onClickDeleteAllScriptedOwnedBy, this)); + mCommitCallbackRegistrar.add("ObjectTools.DeleteAllOwnedBy", boost::bind(&LLPanelObjectTools::onClickDeleteAllOwnedBy, this)); + mCommitCallbackRegistrar.add("ObjectTools.ApplyChanges", boost::bind(&LLPanelObjectTools::onApplyChanges, this)); + mCommitCallbackRegistrar.add("ObjectTools.Set", boost::bind(&LLPanelObjectTools::onClickSet, this)); + mCommitCallbackRegistrar.add("ObjectTools.GetTopColliders", boost::bind(&LLPanelObjectTools::onGetTopColliders, this)); + mCommitCallbackRegistrar.add("ObjectTools.GetTopScripts", boost::bind(&LLPanelObjectTools::onGetTopScripts, this)); + mCommitCallbackRegistrar.add("ObjectTools.GetScriptDigest", boost::bind(&LLPanelObjectTools::onGetScriptDigest, this)); } // Destroys the object @@ -991,22 +971,6 @@ LLPanelObjectTools::~LLPanelObjectTools() BOOL LLPanelObjectTools::postBuild() { - childSetCommitCallback("disable scripts", onChangeAnything, this); - childSetCommitCallback("disable collisions", onChangeAnything, this); - childSetCommitCallback("disable physics", onChangeAnything, this); - - childSetAction("Apply", onApplyChanges, this); - - childSetAction("Set Target", onClickSet, this); - - childSetAction("Delete Target's Scripted Objects On Others Land", onClickDeletePublicOwnedBy, this); - childSetAction("Delete Target's Scripted Objects On *Any* Land", onClickDeleteAllScriptedOwnedBy, this); - childSetAction("Delete *ALL* Of Target's Objects", onClickDeleteAllOwnedBy, this); - - childSetAction("Get Top Colliders", onGetTopColliders, this); - childSetAction("Get Top Scripts", onGetTopScripts, this); - childSetAction("Scripts digest", onGetScriptDigest, this); - return TRUE; } @@ -1095,30 +1059,33 @@ void LLPanelObjectTools::enableAllWidgets() } -// static -void LLPanelObjectTools::onGetTopColliders(void* userdata) +void LLPanelObjectTools::onGetTopColliders() { + LLFloaterTopObjects* instance = LLFloaterReg::getTypedInstance<LLFloaterTopObjects>("top_objects"); + if(!instance) return; + if (gAgent.isGodlike()) { - LLFloaterTopObjects::show(); + LLFloaterReg::showInstance("top_objects"); LLFloaterTopObjects::setMode(STAT_REPORT_TOP_COLLIDERS); - LLFloaterTopObjects::onRefresh(NULL); + instance->onRefresh(); } } -// static -void LLPanelObjectTools::onGetTopScripts(void* userdata) +void LLPanelObjectTools::onGetTopScripts() { + LLFloaterTopObjects* instance = LLFloaterReg::getTypedInstance<LLFloaterTopObjects>("top_objects"); + if(!instance) return; + if (gAgent.isGodlike()) { - LLFloaterTopObjects::show(); + LLFloaterReg::showInstance("top_objects"); LLFloaterTopObjects::setMode(STAT_REPORT_TOP_SCRIPTS); - LLFloaterTopObjects::onRefresh(NULL); + instance->onRefresh(); } } -// static -void LLPanelObjectTools::onGetScriptDigest(void* userdata) +void LLPanelObjectTools::onGetScriptDigest() { if (gAgent.isGodlike()) { @@ -1128,20 +1095,20 @@ void LLPanelObjectTools::onGetScriptDigest(void* userdata) } } -void LLPanelObjectTools::onClickDeletePublicOwnedBy(void* userdata) +void LLPanelObjectTools::onClickDeletePublicOwnedBy() { // Bring up view-modal dialog - LLPanelObjectTools* panelp = (LLPanelObjectTools*)userdata; - if (!panelp->mTargetAvatar.isNull()) + + if (!mTargetAvatar.isNull()) { - panelp->mSimWideDeletesFlags = + mSimWideDeletesFlags = SWD_SCRIPTED_ONLY | SWD_OTHERS_LAND_ONLY; LLSD args; - args["AVATAR_NAME"] = panelp->childGetValue("target_avatar_name").asString(); + args["AVATAR_NAME"] = childGetValue("target_avatar_name").asString(); LLSD payload; - payload["avatar_id"] = panelp->mTargetAvatar; - payload["flags"] = (S32)panelp->mSimWideDeletesFlags; + payload["avatar_id"] = mTargetAvatar; + payload["flags"] = (S32)mSimWideDeletesFlags; LLNotifications::instance().add( "GodDeleteAllScriptedPublicObjectsByUser", args, @@ -1150,20 +1117,18 @@ void LLPanelObjectTools::onClickDeletePublicOwnedBy(void* userdata) } } -// static -void LLPanelObjectTools::onClickDeleteAllScriptedOwnedBy(void* userdata) +void LLPanelObjectTools::onClickDeleteAllScriptedOwnedBy() { // Bring up view-modal dialog - LLPanelObjectTools* panelp = (LLPanelObjectTools*)userdata; - if (!panelp->mTargetAvatar.isNull()) + if (!mTargetAvatar.isNull()) { - panelp->mSimWideDeletesFlags = SWD_SCRIPTED_ONLY; + mSimWideDeletesFlags = SWD_SCRIPTED_ONLY; LLSD args; - args["AVATAR_NAME"] = panelp->childGetValue("target_avatar_name").asString(); + args["AVATAR_NAME"] = childGetValue("target_avatar_name").asString(); LLSD payload; - payload["avatar_id"] = panelp->mTargetAvatar; - payload["flags"] = (S32)panelp->mSimWideDeletesFlags; + payload["avatar_id"] = mTargetAvatar; + payload["flags"] = (S32)mSimWideDeletesFlags; LLNotifications::instance().add( "GodDeleteAllScriptedObjectsByUser", args, @@ -1172,20 +1137,18 @@ void LLPanelObjectTools::onClickDeleteAllScriptedOwnedBy(void* userdata) } } -// static -void LLPanelObjectTools::onClickDeleteAllOwnedBy(void* userdata) +void LLPanelObjectTools::onClickDeleteAllOwnedBy() { // Bring up view-modal dialog - LLPanelObjectTools* panelp = (LLPanelObjectTools*)userdata; - if (!panelp->mTargetAvatar.isNull()) + if (!mTargetAvatar.isNull()) { - panelp->mSimWideDeletesFlags = 0; + mSimWideDeletesFlags = 0; LLSD args; - args["AVATAR_NAME"] = panelp->childGetValue("target_avatar_name").asString(); + args["AVATAR_NAME"] = childGetValue("target_avatar_name").asString(); LLSD payload; - payload["avatar_id"] = panelp->mTargetAvatar; - payload["flags"] = (S32)panelp->mSimWideDeletesFlags; + payload["avatar_id"] = mTargetAvatar; + payload["flags"] = (S32)mSimWideDeletesFlags; LLNotifications::instance().add( "GodDeleteAllObjectsByUser", args, @@ -1209,11 +1172,10 @@ bool LLPanelObjectTools::callbackSimWideDeletes( const LLSD& notification, const return false; } -void LLPanelObjectTools::onClickSet(void* data) +void LLPanelObjectTools::onClickSet() { - LLPanelObjectTools* panelp = (LLPanelObjectTools*) data; // grandparent is a floater, which can have a dependent - gFloaterView->getParentFloater(panelp)->addDependentFloater(LLFloaterAvatarPicker::show(callbackAvatarID, data)); + gFloaterView->getParentFloater(this)->addDependentFloater(LLFloaterAvatarPicker::show(callbackAvatarID, this)); } void LLPanelObjectTools::onClickSetBySelection(void* data) @@ -1247,28 +1209,25 @@ void LLPanelObjectTools::callbackAvatarID(const std::vector<std::string>& names, object_tools->refresh(); } - -// static -void LLPanelObjectTools::onChangeAnything(LLUICtrl* ctrl, void* userdata) +void LLPanelObjectTools::onChangeAnything() { - if (userdata && gAgent.isGodlike()) + if (gAgent.isGodlike()) { - LLPanelObjectTools* object_tools = (LLPanelObjectTools*) userdata; - object_tools->childEnable("Apply"); + childEnable("Apply"); } } -// static -void LLPanelObjectTools::onApplyChanges(void* userdata) +void LLPanelObjectTools::onApplyChanges() { + LLFloaterGodTools* god_tools = LLFloaterReg::getTypedInstance<LLFloaterGodTools>("god_tools"); + if(!god_tools) return; LLViewerRegion *region = gAgent.getRegion(); if (region && gAgent.isGodlike()) { - LLPanelObjectTools* object_tools = (LLPanelObjectTools*) userdata; // TODO -- implement this - - object_tools->childDisable("Apply"); - LLFloaterGodTools::getInstance()->sendGodUpdateRegionInfo(); + childDisable("Apply"); + god_tools->sendGodUpdateRegionInfo(); + //LLFloaterReg::getTypedInstance<LLFloaterGodTools>("god_tools")->sendGodUpdateRegionInfo(); } } @@ -1283,6 +1242,7 @@ const std::string AGENT_REGION = "Agent Region"; LLPanelRequestTools::LLPanelRequestTools(): LLPanel() { + mCommitCallbackRegistrar.add("GodTools.Request", boost::bind(&LLPanelRequestTools::onClickRequest, this)); } LLPanelRequestTools::~LLPanelRequestTools() @@ -1291,8 +1251,6 @@ LLPanelRequestTools::~LLPanelRequestTools() BOOL LLPanelRequestTools::postBuild() { - childSetAction("Make Request", onClickRequest, this); - refresh(); return TRUE; @@ -1353,21 +1311,19 @@ void LLPanelRequestTools::sendRequest(const std::string& request, msg->sendReliable(host); } -// static -void LLPanelRequestTools::onClickRequest(void* data) +void LLPanelRequestTools::onClickRequest() { - LLPanelRequestTools* self = (LLPanelRequestTools*)data; - const std::string dest = self->childGetValue("destination").asString(); + const std::string dest = childGetValue("destination").asString(); if(dest == SELECTION) { - std::string req = self->childGetValue("request"); + std::string req =childGetValue("request"); req = req.substr(0, req.find_first_of(" ")); - std::string param = self->childGetValue("parameter"); + std::string param = childGetValue("parameter"); LLSelectMgr::getInstance()->sendGodlikeRequest(req, param); } else if(dest == AGENT_REGION) { - self->sendRequest(gAgent.getRegionHost()); + sendRequest(gAgent.getRegionHost()); } else { @@ -1379,7 +1335,7 @@ void LLPanelRequestTools::onClickRequest(void* data) if(dest == regionp->getName()) { // found it - self->sendRequest(regionp->getHost()); + sendRequest(regionp->getHost()); } } } diff --git a/indra/newview/llfloatergodtools.h b/indra/newview/llfloatergodtools.h index 6c4b438808..2564b15b37 100644 --- a/indra/newview/llfloatergodtools.h +++ b/indra/newview/llfloatergodtools.h @@ -57,9 +57,9 @@ class LLTextBox; class LLMessageSystem; class LLFloaterGodTools - : public LLFloater, public LLFloaterSingleton<LLFloaterGodTools> + : public LLFloater { - friend class LLUISingleton<LLFloaterGodTools, VisibilityPolicy<LLFloater> >; + friend class LLFloaterReg; public: enum EGodPanel @@ -98,12 +98,16 @@ public: // Send possibly changed values to simulator. void sendGodUpdateRegionInfo(); +private: + + LLFloaterGodTools(const LLSD& key); + ~LLFloaterGodTools(); + protected: U32 computeRegionFlags() const; protected: - LLFloaterGodTools(const LLSD& key); - ~LLFloaterGodTools(); + /*virtual*/ BOOL postBuild(); // When the floater is going away, reset any options that need to be // cleared. @@ -133,16 +137,17 @@ public: /*virtual*/ void refresh(); - static void onSaveState(void* data); - static void onChangeAnything(LLUICtrl* ctrl, void* userdata); - static void onChangePrelude(LLUICtrl* ctrl, void* data); + static void onSaveState(void* userdata); static void onChangeSimName(LLLineEditor* caller, void* userdata); - static void onApplyChanges(void* userdata); - static void onBakeTerrain(void *userdata); - static void onRevertTerrain(void *userdata); - static void onSwapTerrain(void *userdata); - static void onSelectRegion(void *userdata); - static void onRefresh(void* userdata); + + void onChangeAnything(); + void onChangePrelude(); + void onApplyChanges(); + void onBakeTerrain(); + void onRevertTerrain(); + void onSwapTerrain(); + void onSelectRegion(); + void onRefresh(); // set internal checkboxes/spinners/combos const std::string getSimName() const; @@ -194,11 +199,11 @@ public: void refresh(); - static void onClickKickAll(void *data); + void onClickKickAll(); static bool confirmKick(const LLSD& notification, const LLSD& response); static bool finishKick(const LLSD& notification, const LLSD& response); static void onDragSunPhase(LLUICtrl *ctrl, void *userdata); - static void onClickFlushMapVisibilityCaches(void* data); + void onClickFlushMapVisibilityCaches(); static bool flushMapVisibilityCachesConfirm(const LLSD& notification, const LLSD& response); protected: @@ -227,17 +232,17 @@ public: void enableAllWidgets(); void setCheckFlags(U32 flags); - static void onChangeAnything(LLUICtrl* ctrl, void* data); - static void onApplyChanges(void* data); - static void onClickSet(void* data); + void onChangeAnything(); + void onApplyChanges(); + void onClickSet(); static void callbackAvatarID(const std::vector<std::string>& names, const std::vector<LLUUID>& ids, void* data); - static void onClickDeletePublicOwnedBy(void* data); - static void onClickDeleteAllScriptedOwnedBy(void* data); - static void onClickDeleteAllOwnedBy(void* data); + void onClickDeletePublicOwnedBy(); + void onClickDeleteAllScriptedOwnedBy(); + void onClickDeleteAllOwnedBy(); static bool callbackSimWideDeletes(const LLSD& notification, const LLSD& response); - static void onGetTopColliders(void* data); - static void onGetTopScripts(void* data); - static void onGetScriptDigest(void* data); + void onGetTopColliders(); + void onGetTopScripts(); + void onGetScriptDigest(); static void onClickSetBySelection(void* data); protected: @@ -267,7 +272,7 @@ public: const LLHost& host); protected: - static void onClickRequest(void *data); + void onClickRequest(); void sendRequest(const LLHost& host); }; diff --git a/indra/newview/llfloaterhud.cpp b/indra/newview/llfloaterhud.cpp index 4379d25a66..dd70560bb7 100644 --- a/indra/newview/llfloaterhud.cpp +++ b/indra/newview/llfloaterhud.cpp @@ -42,8 +42,6 @@ // Linden libs #include "lluictrlfactory.h" -// statics -LLFloaterHUD* LLFloaterHUD::sInstance = 0; ///---------------------------------------------------------------------------- /// Class LLFloaterHUD @@ -51,12 +49,18 @@ LLFloaterHUD* LLFloaterHUD::sInstance = 0; #define super LLFloater /* superclass */ // Default constructor -LLFloaterHUD::LLFloaterHUD() -: LLFloater(), +LLFloaterHUD::LLFloaterHUD(const LLSD& key) +: LLFloater(key), mWebBrowser(0) { - // Create floater from its XML definition - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_hud.xml"); + // do not build the floater if there the url is empty + if (gSavedSettings.getString("TutorialURL") == "") + { + LLNotifications::instance().add("TutorialNotFound"); + return; + } + + //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_hud.xml"); // Don't grab the focus as it will impede performing in-world actions // while using the HUD @@ -68,62 +72,35 @@ LLFloaterHUD::LLFloaterHUD() // Opaque background since we never get the focus setBackgroundOpaque(TRUE); +} +BOOL LLFloaterHUD::postBuild() +{ mWebBrowser = getChild<LLWebBrowserCtrl>("floater_hud_browser" ); if (mWebBrowser) { // Open links in internal browser mWebBrowser->setOpenInExternalBrowser(false); - + // This is a "chrome" floater, so we don't want anything to // take focus (as the user needs to be able to walk with // arrow keys during tutorial). mWebBrowser->setTakeFocusOnClick(false); - + std::string language = LLUI::getLanguage(); std::string base_url = gSavedSettings.getString("TutorialURL"); - + std::string url = base_url + language + "/"; mWebBrowser->navigateTo(url); } -} - -// Get the instance -LLFloaterHUD* LLFloaterHUD::getInstance() -{ - if (!sInstance) - { - sInstance = new LLFloaterHUD(); - } - return sInstance; + + return TRUE; } // Destructor LLFloaterHUD::~LLFloaterHUD() { - // Clear out the one instance if it's ours - if (sInstance == this) - { - sInstance = NULL; - } } - -// Show the HUD -void LLFloaterHUD::showHUD() -{ - // do not build the floater if there the url is empty - if (gSavedSettings.getString("TutorialURL") == "") - { - LLNotifications::instance().add("TutorialNotFound"); - return; - } - - // Create the instance if necessary - LLFloaterHUD* hud = getInstance(); - hud->openFloater(); - hud->setFrontmost(FALSE); -} - // Save our visibility state on close in case the user accidentally // quit the application while the tutorial was visible. // virtual diff --git a/indra/newview/llfloaterhud.h b/indra/newview/llfloaterhud.h index 2d58685b58..33ed9faa67 100644 --- a/indra/newview/llfloaterhud.h +++ b/indra/newview/llfloaterhud.h @@ -39,22 +39,20 @@ class LLWebBrowserCtrl; class LLFloaterHUD : public LLFloater { + friend class LLFloaterReg; public: - static LLFloaterHUD* getInstance(); ///< get instance creating if necessary - - static void showHUD(); ///< show the HUD // Save our visibility state during close /*virtual*/ void onClose(bool app_quitting); - + BOOL postBuild(); + private: // Handles its own construction and destruction, so private. - LLFloaterHUD(); + LLFloaterHUD(const LLSD& key); /*virtual*/ ~LLFloaterHUD(); private: LLWebBrowserCtrl* mWebBrowser; ///< the actual web browser control - static LLFloaterHUD* sInstance; }; #endif // LL_LLFLOATERHUD_H diff --git a/indra/newview/llfloaterinspect.cpp b/indra/newview/llfloaterinspect.cpp index 4b29a304ac..aa615ef342 100644 --- a/indra/newview/llfloaterinspect.cpp +++ b/indra/newview/llfloaterinspect.cpp @@ -47,13 +47,32 @@ #include "llviewerobject.h" #include "lluictrlfactory.h" -LLFloaterInspect* LLFloaterInspect::sInstance = NULL; +//LLFloaterInspect* LLFloaterInspect::sInstance = NULL; -LLFloaterInspect::LLFloaterInspect(void) - : LLFloater(), +LLFloaterInspect::LLFloaterInspect(const LLSD& key) + : LLFloater(key), mDirty(FALSE) { - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_inspect.xml"); + //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_inspect.xml"); + mCommitCallbackRegistrar.add("Inspect.OwnerProfile", boost::bind(&LLFloaterInspect::onClickOwnerProfile, this)); + mCommitCallbackRegistrar.add("Inspect.CreatorProfile", boost::bind(&LLFloaterInspect::onClickCreatorProfile, this)); + mCommitCallbackRegistrar.add("Inspect.SelectObject", boost::bind(&LLFloaterInspect::onSelectObject, this)); +} + +BOOL LLFloaterInspect::postBuild() +{ + mObjectList = getChild<LLScrollListCtrl>("object_list"); +// childSetAction("button owner",onClickOwnerProfile, this); +// childSetAction("button creator",onClickCreatorProfile, this); +// childSetCommitCallback("object_list", onSelectObject, NULL); + + BOOL forcesel = LLSelectMgr::getInstance()->setForceSelection(TRUE); + LLToolMgr::getInstance()->setTransientTool(LLToolCompInspect::getInstance()); + LLSelectMgr::getInstance()->setForceSelection(forcesel); // restore previouis value + mObjectSelection = LLSelectMgr::getInstance()->getSelection(); + refresh(); + + return TRUE; } LLFloaterInspect::~LLFloaterInspect(void) @@ -71,14 +90,14 @@ LLFloaterInspect::~LLFloaterInspect(void) { LLFloaterReg::showInstance("build", LLSD(), TRUE); } - sInstance = NULL; + //sInstance = NULL; } - +/* BOOL LLFloaterInspect::isVisible() { return (!!sInstance); -} - +}*/ +/* void LLFloaterInspect::show(void* ignored) { // setForceSelection ensures that the pie menu does not deselect things when it @@ -98,15 +117,14 @@ void LLFloaterInspect::show(void* ignored) sInstance->mObjectSelection = LLSelectMgr::getInstance()->getSelection(); sInstance->refresh(); } - -void LLFloaterInspect::onClickCreatorProfile(void* ctrl) +*/ +void LLFloaterInspect::onClickCreatorProfile() { - if(sInstance->mObjectList->getAllSelected().size() == 0) + if(mObjectList->getAllSelected().size() == 0) { return; } - LLScrollListItem* first_selected = - sInstance->mObjectList->getFirstSelected(); + LLScrollListItem* first_selected =mObjectList->getFirstSelected(); if (first_selected) { @@ -119,7 +137,7 @@ void LLFloaterInspect::onClickCreatorProfile(void* ctrl) return (obj_id == node->getObject()->getID()); } } func(first_selected->getUUID()); - LLSelectNode* node = sInstance->mObjectSelection->getFirstNode(&func); + LLSelectNode* node = mObjectSelection->getFirstNode(&func); if(node) { LLFriendActions::showProfile(node->mPermissions->getCreator()); @@ -127,11 +145,10 @@ void LLFloaterInspect::onClickCreatorProfile(void* ctrl) } } -void LLFloaterInspect::onClickOwnerProfile(void* ctrl) +void LLFloaterInspect::onClickOwnerProfile() { - if(sInstance->mObjectList->getAllSelected().size() == 0) return; - LLScrollListItem* first_selected = - sInstance->mObjectList->getFirstSelected(); + if(mObjectList->getAllSelected().size() == 0) return; + LLScrollListItem* first_selected =mObjectList->getFirstSelected(); if (first_selected) { @@ -145,7 +162,7 @@ void LLFloaterInspect::onClickOwnerProfile(void* ctrl) return (obj_id == node->getObject()->getID()); } } func(selected_id); - LLSelectNode* node = sInstance->mObjectSelection->getFirstNode(&func); + LLSelectNode* node = mObjectSelection->getFirstNode(&func); if(node) { const LLUUID& owner_id = node->mPermissions->getOwner(); @@ -154,37 +171,25 @@ void LLFloaterInspect::onClickOwnerProfile(void* ctrl) } } -BOOL LLFloaterInspect::postBuild() -{ - mObjectList = getChild<LLScrollListCtrl>("object_list"); - childSetAction("button owner",onClickOwnerProfile, this); - childSetAction("button creator",onClickCreatorProfile, this); - childSetCommitCallback("object_list", onSelectObject, NULL); - return TRUE; -} - -void LLFloaterInspect::onSelectObject(LLUICtrl* ctrl, void* user_data) +void LLFloaterInspect::onSelectObject() { if(LLFloaterInspect::getSelectedUUID() != LLUUID::null) { - sInstance->childSetEnabled("button owner", true); - sInstance->childSetEnabled("button creator", true); + childSetEnabled("button owner", true); + childSetEnabled("button creator", true); } } LLUUID LLFloaterInspect::getSelectedUUID() { - if(sInstance) + if(mObjectList->getAllSelected().size() > 0) { - if(sInstance->mObjectList->getAllSelected().size() > 0) + LLScrollListItem* first_selected =mObjectList->getFirstSelected(); + if (first_selected) { - LLScrollListItem* first_selected = - sInstance->mObjectList->getFirstSelected(); - if (first_selected) - { - return first_selected->getUUID(); - } + return first_selected->getUUID(); } + } return LLUUID::null; } @@ -262,7 +267,7 @@ void LLFloaterInspect::refresh() { mObjectList->selectNthItem(0); } - onSelectObject(this, NULL); + onSelectObject(); mObjectList->setScrollPos(pos); } @@ -274,10 +279,7 @@ void LLFloaterInspect::onFocusReceived() void LLFloaterInspect::dirty() { - if(sInstance) - { - sInstance->setDirty(); - } + setDirty(); } void LLFloaterInspect::draw() diff --git a/indra/newview/llfloaterinspect.h b/indra/newview/llfloaterinspect.h index 57bba6864f..a65ccaa66e 100644 --- a/indra/newview/llfloaterinspect.h +++ b/indra/newview/llfloaterinspect.h @@ -44,29 +44,32 @@ class LLUICtrl; class LLFloaterInspect : public LLFloater { + friend class LLFloaterReg; public: - virtual ~LLFloaterInspect(void); - static void show(void* ignored = NULL); + +// static void show(void* ignored = NULL); virtual BOOL postBuild(); - static void dirty(); - static LLUUID getSelectedUUID(); + void dirty(); + LLUUID getSelectedUUID(); virtual void draw(); virtual void refresh(); - static BOOL isVisible(); +// static BOOL isVisible(); virtual void onFocusReceived(); - static void onClickCreatorProfile(void* ctrl); - static void onClickOwnerProfile(void* ctrl); - static void onSelectObject(LLUICtrl* ctrl, void* user_data); + void onClickCreatorProfile(); + void onClickOwnerProfile(); + void onSelectObject(); LLScrollListCtrl* mObjectList; protected: // protected members - LLFloaterInspect(); void setDirty() { mDirty = TRUE; } bool mDirty; private: + + LLFloaterInspect(const LLSD& key); + virtual ~LLFloaterInspect(void); // static data - static LLFloaterInspect* sInstance; +// static LLFloaterInspect* sInstance; LLSafeHandle<LLObjectSelection> mObjectSelection; }; diff --git a/indra/newview/llfloaterinventory.cpp b/indra/newview/llfloaterinventory.cpp new file mode 100644 index 0000000000..0dd1d6adcd --- /dev/null +++ b/indra/newview/llfloaterinventory.cpp @@ -0,0 +1,1941 @@ +/** + * @file llfloaterinventory.cpp + * @brief Implementation of the inventory view and associated stuff. + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include <utility> // for std::pair<> + +#include "llfloaterinventory.h" + +// library includes +#include "llagent.h" +#include "llagentwearables.h" +#include "llcallingcard.h" +#include "llfloaterreg.h" +#include "llsdserialize.h" +#include "llsearcheditor.h" +#include "llspinctrl.h" +#include "llui.h" +#include "message.h" + +// newview includes +#include "llappviewer.h" +#include "llfirstuse.h" +#include "llfloateravatarinfo.h" +#include "llfloaterchat.h" +#include "llfloatercustomize.h" +#include "llfocusmgr.h" +#include "llfolderview.h" +#include "llgesturemgr.h" +#include "lliconctrl.h" +#include "llimview.h" +#include "llinventorybridge.h" +#include "llinventoryclipboard.h" +#include "llinventorymodel.h" +#include "lllineeditor.h" +#include "llmenugl.h" +#include "llpreviewanim.h" +#include "llpreviewgesture.h" +#include "llpreviewlandmark.h" +#include "llpreviewnotecard.h" +#include "llpreviewscript.h" +#include "llpreviewsound.h" +#include "llpreviewtexture.h" +#include "llresmgr.h" +#include "llscrollbar.h" +#include "llscrollcontainer.h" +#include "llselectmgr.h" +#include "lltabcontainer.h" +#include "lltooldraganddrop.h" +#include "lluictrlfactory.h" +#include "llviewerimagelist.h" +#include "llviewerinventory.h" +#include "llviewermessage.h" +#include "llviewerobjectlist.h" +#include "llviewerregion.h" +#include "llviewerwindow.h" +#include "llvoavatarself.h" +#include "llwearablelist.h" + +static LLDefaultChildRegistry::Register<LLInventoryPanel> r("inventory_panel"); + +//BOOL LLFloaterInventory::sOpenNextNewItem = FALSE; +BOOL LLFloaterInventory::sWearNewClothing = FALSE; +LLUUID LLFloaterInventory::sWearNewClothingTransactionID; + +///---------------------------------------------------------------------------- +/// LLFloaterInventoryFinder +///---------------------------------------------------------------------------- + +LLFloaterInventoryFinder::LLFloaterInventoryFinder(LLFloaterInventory* inventory_view) +: LLFloater(), + mFloaterInventory(inventory_view), + mFilter(inventory_view->mActivePanel->getFilter()) +{ + LLUICtrlFactory::getInstance()->buildFloater(this, "floater_inventory_view_finder.xml"); + updateElementsFromFilter(); +} + + +void LLFloaterInventoryFinder::onCheckSinceLogoff(LLUICtrl *ctrl, void *user_data) +{ + LLFloaterInventoryFinder *self = (LLFloaterInventoryFinder *)user_data; + if (!self) return; + + bool since_logoff= self->childGetValue("check_since_logoff"); + + if (!since_logoff && + !( self->mSpinSinceDays->get() || self->mSpinSinceHours->get() ) ) + { + self->mSpinSinceHours->set(1.0f); + } +} +BOOL LLFloaterInventoryFinder::postBuild() +{ + const LLRect& viewrect = mFloaterInventory->getRect(); + setRect(LLRect(viewrect.mLeft - getRect().getWidth(), viewrect.mTop, viewrect.mLeft, viewrect.mTop - getRect().getHeight())); + + childSetAction("All", selectAllTypes, this); + childSetAction("None", selectNoTypes, this); + + mSpinSinceHours = getChild<LLSpinCtrl>("spin_hours_ago"); + childSetCommitCallback("spin_hours_ago", onTimeAgo, this); + + mSpinSinceDays = getChild<LLSpinCtrl>("spin_days_ago"); + childSetCommitCallback("spin_days_ago", onTimeAgo, this); + + // mCheckSinceLogoff = getChild<LLSpinCtrl>("check_since_logoff"); + childSetCommitCallback("check_since_logoff", onCheckSinceLogoff, this); + + childSetAction("Close", onCloseBtn, this); + + updateElementsFromFilter(); + return TRUE; +} +void LLFloaterInventoryFinder::onTimeAgo(LLUICtrl *ctrl, void *user_data) +{ + LLFloaterInventoryFinder *self = (LLFloaterInventoryFinder *)user_data; + if (!self) return; + + bool since_logoff=true; + if ( self->mSpinSinceDays->get() || self->mSpinSinceHours->get() ) + { + since_logoff = false; + } + self->childSetValue("check_since_logoff", since_logoff); +} + +void LLFloaterInventoryFinder::changeFilter(LLInventoryFilter* filter) +{ + mFilter = filter; + updateElementsFromFilter(); +} + +void LLFloaterInventoryFinder::updateElementsFromFilter() +{ + if (!mFilter) + return; + + // Get data needed for filter display + U32 filter_types = mFilter->getFilterTypes(); + std::string filter_string = mFilter->getFilterSubString(); + LLInventoryFilter::EFolderShow show_folders = mFilter->getShowFolderState(); + U32 hours = mFilter->getHoursAgo(); + + // update the ui elements + LLFloater::setTitle(mFilter->getName()); + childSetValue("check_animation", (S32) (filter_types & 0x1 << LLInventoryType::IT_ANIMATION)); + + childSetValue("check_calling_card", (S32) (filter_types & 0x1 << LLInventoryType::IT_CALLINGCARD)); + childSetValue("check_clothing", (S32) (filter_types & 0x1 << LLInventoryType::IT_WEARABLE)); + childSetValue("check_gesture", (S32) (filter_types & 0x1 << LLInventoryType::IT_GESTURE)); + childSetValue("check_landmark", (S32) (filter_types & 0x1 << LLInventoryType::IT_LANDMARK)); + childSetValue("check_notecard", (S32) (filter_types & 0x1 << LLInventoryType::IT_NOTECARD)); + childSetValue("check_object", (S32) (filter_types & 0x1 << LLInventoryType::IT_OBJECT)); + childSetValue("check_script", (S32) (filter_types & 0x1 << LLInventoryType::IT_LSL)); + childSetValue("check_sound", (S32) (filter_types & 0x1 << LLInventoryType::IT_SOUND)); + childSetValue("check_texture", (S32) (filter_types & 0x1 << LLInventoryType::IT_TEXTURE)); + childSetValue("check_snapshot", (S32) (filter_types & 0x1 << LLInventoryType::IT_SNAPSHOT)); + childSetValue("check_show_empty", show_folders == LLInventoryFilter::SHOW_ALL_FOLDERS); + childSetValue("check_since_logoff", mFilter->isSinceLogoff()); + mSpinSinceHours->set((F32)(hours % 24)); + mSpinSinceDays->set((F32)(hours / 24)); +} + +void LLFloaterInventoryFinder::draw() +{ + LLMemType mt(LLMemType::MTYPE_INVENTORY_DRAW); + U32 filter = 0xffffffff; + BOOL filtered_by_all_types = TRUE; + + if (!childGetValue("check_animation")) + { + filter &= ~(0x1 << LLInventoryType::IT_ANIMATION); + filtered_by_all_types = FALSE; + } + + + if (!childGetValue("check_calling_card")) + { + filter &= ~(0x1 << LLInventoryType::IT_CALLINGCARD); + filtered_by_all_types = FALSE; + } + + if (!childGetValue("check_clothing")) + { + filter &= ~(0x1 << LLInventoryType::IT_WEARABLE); + filtered_by_all_types = FALSE; + } + + if (!childGetValue("check_gesture")) + { + filter &= ~(0x1 << LLInventoryType::IT_GESTURE); + filtered_by_all_types = FALSE; + } + + if (!childGetValue("check_landmark")) + + + { + filter &= ~(0x1 << LLInventoryType::IT_LANDMARK); + filtered_by_all_types = FALSE; + } + + if (!childGetValue("check_notecard")) + { + filter &= ~(0x1 << LLInventoryType::IT_NOTECARD); + filtered_by_all_types = FALSE; + } + + if (!childGetValue("check_object")) + { + filter &= ~(0x1 << LLInventoryType::IT_OBJECT); + filter &= ~(0x1 << LLInventoryType::IT_ATTACHMENT); + filtered_by_all_types = FALSE; + } + + if (!childGetValue("check_script")) + { + filter &= ~(0x1 << LLInventoryType::IT_LSL); + filtered_by_all_types = FALSE; + } + + if (!childGetValue("check_sound")) + { + filter &= ~(0x1 << LLInventoryType::IT_SOUND); + filtered_by_all_types = FALSE; + } + + if (!childGetValue("check_texture")) + { + filter &= ~(0x1 << LLInventoryType::IT_TEXTURE); + filtered_by_all_types = FALSE; + } + + if (!childGetValue("check_snapshot")) + { + filter &= ~(0x1 << LLInventoryType::IT_SNAPSHOT); + filtered_by_all_types = FALSE; + } + + if (!filtered_by_all_types) + { + // don't include folders in filter, unless I've selected everything + filter &= ~(0x1 << LLInventoryType::IT_CATEGORY); + } + + // update the panel, panel will update the filter + mFloaterInventory->mActivePanel->setShowFolderState(getCheckShowEmpty() ? + LLInventoryFilter::SHOW_ALL_FOLDERS : LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS); + mFloaterInventory->mActivePanel->setFilterTypes(filter); + if (getCheckSinceLogoff()) + { + mSpinSinceDays->set(0); + mSpinSinceHours->set(0); + } + U32 days = (U32)mSpinSinceDays->get(); + U32 hours = (U32)mSpinSinceHours->get(); + if (hours > 24) + { + days += hours / 24; + hours = (U32)hours % 24; + mSpinSinceDays->set((F32)days); + mSpinSinceHours->set((F32)hours); + } + hours += days * 24; + mFloaterInventory->mActivePanel->setHoursAgo(hours); + mFloaterInventory->mActivePanel->setSinceLogoff(getCheckSinceLogoff()); + mFloaterInventory->setFilterTextFromFilter(); + + LLFloater::draw(); +} + +void LLFloaterInventoryFinder::onClose(bool app_quitting) +{ + gSavedSettings.setBOOL("Inventory.ShowFilters", FALSE); + // If you want to reset the filter on close, do it here. This functionality was + // hotly debated - Paulm +#if 0 + if (mFloaterInventory) + { + LLFloaterInventory::onResetFilter((void *)mFloaterInventory); + } +#endif + destroy(); +} + + +BOOL LLFloaterInventoryFinder::getCheckShowEmpty() +{ + return childGetValue("check_show_empty"); +} + +BOOL LLFloaterInventoryFinder::getCheckSinceLogoff() +{ + return childGetValue("check_since_logoff"); +} + +void LLFloaterInventoryFinder::onCloseBtn(void* user_data) +{ + LLFloaterInventoryFinder* finderp = (LLFloaterInventoryFinder*)user_data; + finderp->closeFloater(); +} + +// static +void LLFloaterInventoryFinder::selectAllTypes(void* user_data) +{ + LLFloaterInventoryFinder* self = (LLFloaterInventoryFinder*)user_data; + if(!self) return; + + self->childSetValue("check_animation", TRUE); + self->childSetValue("check_calling_card", TRUE); + self->childSetValue("check_clothing", TRUE); + self->childSetValue("check_gesture", TRUE); + self->childSetValue("check_landmark", TRUE); + self->childSetValue("check_notecard", TRUE); + self->childSetValue("check_object", TRUE); + self->childSetValue("check_script", TRUE); + self->childSetValue("check_sound", TRUE); + self->childSetValue("check_texture", TRUE); + self->childSetValue("check_snapshot", TRUE); + +/* + self->mCheckCallingCard->set(TRUE); + self->mCheckClothing->set(TRUE); + self->mCheckGesture->set(TRUE); + self->mCheckLandmark->set(TRUE); + self->mCheckNotecard->set(TRUE); + self->mCheckObject->set(TRUE); + self->mCheckScript->set(TRUE); + self->mCheckSound->set(TRUE); + self->mCheckTexture->set(TRUE); + self->mCheckSnapshot->set(TRUE);*/ +} + +//static +void LLFloaterInventoryFinder::selectNoTypes(void* user_data) +{ + LLFloaterInventoryFinder* self = (LLFloaterInventoryFinder*)user_data; + if(!self) return; + + /* + self->childSetValue("check_animation", FALSE); + self->mCheckCallingCard->set(FALSE); + self->mCheckClothing->set(FALSE); + self->mCheckGesture->set(FALSE); + self->mCheckLandmark->set(FALSE); + self->mCheckNotecard->set(FALSE); + self->mCheckObject->set(FALSE); + self->mCheckScript->set(FALSE); + self->mCheckSound->set(FALSE); + self->mCheckTexture->set(FALSE); + self->mCheckSnapshot->set(FALSE);*/ + + + self->childSetValue("check_animation", FALSE); + self->childSetValue("check_calling_card", FALSE); + self->childSetValue("check_clothing", FALSE); + self->childSetValue("check_gesture", FALSE); + self->childSetValue("check_landmark", FALSE); + self->childSetValue("check_notecard", FALSE); + self->childSetValue("check_object", FALSE); + self->childSetValue("check_script", FALSE); + self->childSetValue("check_sound", FALSE); + self->childSetValue("check_texture", FALSE); + self->childSetValue("check_snapshot", FALSE); +} + + +///---------------------------------------------------------------------------- +/// LLFloaterInventory +///---------------------------------------------------------------------------- +void LLSaveFolderState::setApply(BOOL apply) +{ + mApply = apply; + // before generating new list of open folders, clear the old one + if(!apply) + { + clearOpenFolders(); + } +} + +void LLSaveFolderState::doFolder(LLFolderViewFolder* folder) +{ + LLMemType mt(LLMemType::MTYPE_INVENTORY_DO_FOLDER); + if(mApply) + { + // we're applying the open state + LLInvFVBridge* bridge = (LLInvFVBridge*)folder->getListener(); + if(!bridge) return; + LLUUID id(bridge->getUUID()); + if(mOpenFolders.find(id) != mOpenFolders.end()) + { + folder->setOpen(TRUE); + } + else + { + // keep selected filter in its current state, this is less jarring to user + if (!folder->isSelected()) + { + folder->setOpen(FALSE); + } + } + } + else + { + // we're recording state at this point + if(folder->isOpen()) + { + LLInvFVBridge* bridge = (LLInvFVBridge*)folder->getListener(); + if(!bridge) return; + mOpenFolders.insert(bridge->getUUID()); + } + } +} + +LLFloaterInventory::LLFloaterInventory(const LLSD& key) + : LLFloater(key) +{ + LLMemType mt(LLMemType::MTYPE_INVENTORY_VIEW_INIT); + // Menu Callbacks (non contex menus) + mCommitCallbackRegistrar.add("Inventory.DoToSelected", boost::bind(&LLFloaterInventory::doToSelected, this, _2)); + mCommitCallbackRegistrar.add("Inventory.CloseAllFolders", boost::bind(&LLFloaterInventory::closeAllFolders, this)); + mCommitCallbackRegistrar.add("Inventory.EmptyTrash", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyTrash", LLAssetType::AT_TRASH)); + mCommitCallbackRegistrar.add("Inventory.EmptyLostAndFound", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyLostAndFound", LLAssetType::AT_LOST_AND_FOUND)); + mCommitCallbackRegistrar.add("Inventory.DoCreate", boost::bind(&LLFloaterInventory::doCreate, this, _2)); + mCommitCallbackRegistrar.add("Inventory.NewWindow", boost::bind(&LLFloaterInventory::newWindow, this)); + mCommitCallbackRegistrar.add("Inventory.ShowFilters", boost::bind(&LLFloaterInventory::toggleFindOptions, this)); + mCommitCallbackRegistrar.add("Inventory.ResetFilters", boost::bind(&LLFloaterInventory::resetFilters, this)); + mCommitCallbackRegistrar.add("Inventory.SetSortBy", boost::bind(&LLFloaterInventory::setSortBy, this, _2)); + + // Controls + // *TODO: Just use persistant settings for each of these + U32 sort_order = gSavedSettings.getU32("InventorySortOrder"); + BOOL sort_by_name = ! ( sort_order & LLInventoryFilter::SO_DATE ); + BOOL sort_folders_by_name = ( sort_order & LLInventoryFilter::SO_FOLDERS_BY_NAME ); + BOOL sort_system_folders_to_top = ( sort_order & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP ); + + gSavedSettings.declareBOOL("Inventory.ShowFilters", FALSE, "Declared in code", FALSE); + gSavedSettings.declareBOOL("Inventory.SortByName", sort_by_name, "Declared in code", FALSE); + gSavedSettings.declareBOOL("Inventory.SortByDate", !sort_by_name, "Declared in code", FALSE); + gSavedSettings.declareBOOL("Inventory.FoldersAlwaysByName", sort_folders_by_name, "Declared in code", FALSE); + gSavedSettings.declareBOOL("Inventory.SystemFoldersToTop", sort_system_folders_to_top, "Declared in code", FALSE); + + mSavedFolderState = new LLSaveFolderState(); + mSavedFolderState->setApply(FALSE); + + //Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this, "floater_inventory.xml"); +} + +BOOL LLFloaterInventory::postBuild() +{ + gInventory.addObserver(this); + + mFilterTabs = getChild<LLTabContainer>("inventory filter tabs"); + mFilterTabs->setCommitCallback(boost::bind(&LLFloaterInventory::onFilterSelected, this)); + + //panel->getFilter()->markDefault(); + + // Set up the default inv. panel/filter settings. + mActivePanel = getChild<LLInventoryPanel>("All Items"); + if (mActivePanel) + { + // "All Items" is the previous only view, so it gets the InventorySortOrder + mActivePanel->setSortOrder(gSavedSettings.getU32("InventorySortOrder")); + mActivePanel->getFilter()->markDefault(); + mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState); + mActivePanel->setSelectCallback(boost::bind(&LLInventoryPanel::onSelectionChange, mActivePanel, _1, _2)); + } + LLInventoryPanel* recent_items_panel = getChild<LLInventoryPanel>("Recent Items"); + if (recent_items_panel) + { + recent_items_panel->setSinceLogoff(TRUE); + recent_items_panel->setSortOrder(LLInventoryFilter::SO_DATE); + recent_items_panel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS); + recent_items_panel->getFilter()->markDefault(); + recent_items_panel->setSelectCallback(boost::bind(&LLInventoryPanel::onSelectionChange, recent_items_panel, _1, _2)); + } + + // Now load the stored settings from disk, if available. + std::ostringstream filterSaveName; + filterSaveName << gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "filters.xml"); + llinfos << "LLFloaterInventory::init: reading from " << filterSaveName << llendl; + llifstream file(filterSaveName.str()); + LLSD savedFilterState; + if (file.is_open()) + { + LLSDSerialize::fromXML(savedFilterState, file); + file.close(); + + // Load the persistent "Recent Items" settings. + // Note that the "All Items" settings do not persist. + if(recent_items_panel) + { + if(savedFilterState.has(recent_items_panel->getFilter()->getName())) + { + LLSD recent_items = savedFilterState.get( + recent_items_panel->getFilter()->getName()); + recent_items_panel->getFilter()->fromLLSD(recent_items); + } + } + + } + + + mSearchEditor = getChild<LLSearchEditor>("inventory search editor"); + if (mSearchEditor) + { + mSearchEditor->setSearchCallback(boost::bind(&LLFloaterInventory::onSearchEdit, this, _1)); + } + + // *TODO:Get the cost info from the server + const std::string upload_cost("10"); + childSetLabelArg("Upload Image", "[COST]", upload_cost); + childSetLabelArg("Upload Sound", "[COST]", upload_cost); + childSetLabelArg("Upload Animation", "[COST]", upload_cost); + childSetLabelArg("Bulk Upload", "[COST]", upload_cost); + + return TRUE; +} + +// Destroys the object +LLFloaterInventory::~LLFloaterInventory( void ) +{ + // Save the filters state. + LLSD filterRoot; + LLInventoryPanel* all_items_panel = getChild<LLInventoryPanel>("All Items"); + if (all_items_panel) + { + LLInventoryFilter* filter = all_items_panel->getFilter(); + LLSD filterState; + filter->toLLSD(filterState); + filterRoot[filter->getName()] = filterState; + } + + LLInventoryPanel* recent_items_panel = getChild<LLInventoryPanel>("Recent Items"); + if (recent_items_panel) + { + LLInventoryFilter* filter = recent_items_panel->getFilter(); + LLSD filterState; + filter->toLLSD(filterState); + filterRoot[filter->getName()] = filterState; + } + + std::ostringstream filterSaveName; + filterSaveName << gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "filters.xml"); + llofstream filtersFile(filterSaveName.str()); + if(!LLSDSerialize::toPrettyXML(filterRoot, filtersFile)) + { + llwarns << "Could not write to filters save file " << filterSaveName << llendl; + } + else + filtersFile.close(); + + gInventory.removeObserver(this); + delete mSavedFolderState; +} + +void LLFloaterInventory::draw() +{ + if (LLInventoryModel::isEverythingFetched()) + { + LLLocale locale(LLLocale::USER_LOCALE); + std::ostringstream title; + //title << "Inventory"; + title<<getString("Title"); + std::string item_count_string; + LLResMgr::getInstance()->getIntegerString(item_count_string, gInventory.getItemCount()); + title << " (" << item_count_string << getString("Items")<<")"; + //TODO:: Translate mFilterText + title << mFilterText; + setTitle(title.str()); + } + if (mActivePanel && mSearchEditor) + { + mSearchEditor->setText(mActivePanel->getFilterSubString()); + } + LLFloater::draw(); +} + +void LLOpenFilteredFolders::doItem(LLFolderViewItem *item) +{ + if (item->getFiltered()) + { + item->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP); + } +} + +void LLOpenFilteredFolders::doFolder(LLFolderViewFolder* folder) +{ + if (folder->getFiltered() && folder->getParentFolder()) + { + folder->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP); + } + // if this folder didn't pass the filter, and none of its descendants did + else if (!folder->getFiltered() && !folder->hasFilteredDescendants()) + { + folder->setOpenArrangeRecursively(FALSE, LLFolderViewFolder::RECURSE_NO); + } +} + +void LLSelectFirstFilteredItem::doItem(LLFolderViewItem *item) +{ + if (item->getFiltered() && !mItemSelected) + { + item->getRoot()->setSelection(item, FALSE, FALSE); + if (item->getParentFolder()) + { + item->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP); + } + item->getRoot()->scrollToShowSelection(); + mItemSelected = TRUE; + } +} + +void LLSelectFirstFilteredItem::doFolder(LLFolderViewFolder* folder) +{ + if (folder->getFiltered() && !mItemSelected) + { + folder->getRoot()->setSelection(folder, FALSE, FALSE); + if (folder->getParentFolder()) + { + folder->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP); + } + folder->getRoot()->scrollToShowSelection(); + mItemSelected = TRUE; + } +} + +void LLOpenFoldersWithSelection::doItem(LLFolderViewItem *item) +{ + if (item->getParentFolder() && item->isSelected()) + { + item->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP); + } +} + +void LLOpenFoldersWithSelection::doFolder(LLFolderViewFolder* folder) +{ + if (folder->getParentFolder() && folder->isSelected()) + { + folder->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP); + } +} + +void LLFloaterInventory::startSearch() +{ + // this forces focus to line editor portion of search editor + if (mSearchEditor) + { + mSearchEditor->focusFirstItem(TRUE); + } +} + +// virtual, from LLView +void LLFloaterInventory::setVisible( BOOL visible ) +{ + LLFloater::setVisible(visible); +} + +void LLFloaterInventory::onOpen(const LLSD& key) +{ + LLFirstUse::useInventory(); +} + +// Destroy all but the last floater, which is made invisible. +void LLFloaterInventory::onClose(bool app_quitting) +{ + if (getKey().asInteger() != 0) + { + destroy(); + } + else + { + // clear filters, but save user's folder state first + if (!mActivePanel->getRootFolder()->isFilterModified()) + { + mSavedFolderState->setApply(FALSE); + mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState); + } + setVisible(FALSE); + } +} + +BOOL LLFloaterInventory::handleKeyHere(KEY key, MASK mask) +{ + LLFolderView* root_folder = mActivePanel ? mActivePanel->getRootFolder() : NULL; + if (root_folder) + { + // first check for user accepting current search results + if (mSearchEditor + && mSearchEditor->hasFocus() + && (key == KEY_RETURN + || key == KEY_DOWN) + && mask == MASK_NONE) + { + // move focus to inventory proper + mActivePanel->setFocus(TRUE); + root_folder->scrollToShowSelection(); + return TRUE; + } + + if (mActivePanel->hasFocus() && key == KEY_UP) + { + startSearch(); + } + } + + return LLFloater::handleKeyHere(key, mask); + +} + +void LLFloaterInventory::changed(U32 mask) +{ + std::ostringstream title; + //title << "Inventory"; + title<<getString("Title"); + if (LLInventoryModel::backgroundFetchActive()) + { + LLLocale locale(LLLocale::USER_LOCALE); + std::string item_count_string; + LLResMgr::getInstance()->getIntegerString(item_count_string, gInventory.getItemCount()); + title << " ( "<< getString("Fetched") << item_count_string << getString("Items")<<")"; + } + //TODO:: Translate mFilterText + title << mFilterText; + setTitle(title.str()); + +} + +//static +LLFloaterInventory* LLFloaterInventory::newInstance() +{ + LLMemType mt(LLMemType::MTYPE_INVENTORY_VIEW_SHOW); + static S32 inst_count = 1; + return LLFloaterReg::getTypedInstance<LLFloaterInventory>("inventory", LLSD(inst_count++)); +} + +//---------------------------------------------------------------------------- +// menu callbacks + +void LLFloaterInventory::doToSelected(const LLSD& userdata) +{ + getPanel()->getRootFolder()->doToSelected(&gInventory, userdata); +} + +void LLFloaterInventory::closeAllFolders() +{ + getPanel()->getRootFolder()->closeAllFolders(); +} + +void LLFloaterInventory::doCreate(const LLSD& userdata) +{ + menu_create_inventory_item(getPanel()->getRootFolder(), NULL, userdata); +} + +void LLFloaterInventory::newWindow() +{ + LLFloaterInventory* iv = newInstance(); + iv->getActivePanel()->setFilterTypes(getActivePanel()->getFilterTypes()); + iv->getActivePanel()->setFilterSubString(getActivePanel()->getFilterSubString()); + iv->openFloater(); + + // force onscreen + gFloaterView->adjustToFitScreen(iv, FALSE); +} + +void LLFloaterInventory::resetFilters() +{ + LLFloaterInventoryFinder *finder = getFinder(); + getActivePanel()->getFilter()->resetDefault(); + if (finder) + { + finder->updateElementsFromFilter(); + } + + setFilterTextFromFilter(); +} + +void LLFloaterInventory::setSortBy(const LLSD& userdata) +{ + std::string sort_field = userdata.asString(); + if (sort_field == "name") + { + U32 order = getActivePanel()->getSortOrder(); + getActivePanel()->setSortOrder( order & ~LLInventoryFilter::SO_DATE ); + + gSavedSettings.setBOOL("Inventory.SortByName", TRUE ); + gSavedSettings.setBOOL("Inventory.SortByDate", FALSE ); + } + else if (sort_field == "date") + { + U32 order = getActivePanel()->getSortOrder(); + getActivePanel()->setSortOrder( order | LLInventoryFilter::SO_DATE ); + + gSavedSettings.setBOOL("Inventory.SortByName", FALSE ); + gSavedSettings.setBOOL("Inventory.SortByDate", TRUE ); + } + else if (sort_field == "foldersalwaysbyname") + { + U32 order = getActivePanel()->getSortOrder(); + if ( order & LLInventoryFilter::SO_FOLDERS_BY_NAME ) + { + order &= ~LLInventoryFilter::SO_FOLDERS_BY_NAME; + + gSavedSettings.setBOOL("Inventory.FoldersAlwaysByName", FALSE ); + } + else + { + order |= LLInventoryFilter::SO_FOLDERS_BY_NAME; + + gSavedSettings.setBOOL("Inventory.FoldersAlwaysByName", TRUE ); + } + getActivePanel()->setSortOrder( order ); + } + else if (sort_field == "systemfolderstotop") + { + U32 order = getActivePanel()->getSortOrder(); + if ( order & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP ) + { + order &= ~LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP; + + gSavedSettings.setBOOL("Inventory.SystemFoldersToTop", FALSE ); + } + else + { + order |= LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP; + + gSavedSettings.setBOOL("Inventory.SystemFoldersToTop", TRUE ); + } + getActivePanel()->setSortOrder( order ); + } +} + +//---------------------------------------------------------------------------- + +// static +LLFloaterInventory* LLFloaterInventory::showAgentInventory() +{ + LLFloaterInventory* iv = NULL; + if (!gAgent.cameraMouselook()) + { + iv = LLFloaterReg::showTypedInstance<LLFloaterInventory>("inventory", LLSD()); + } + return iv; +} + +// static +LLFloaterInventory* LLFloaterInventory::getActiveInventory() +{ + LLFloaterInventory* res = NULL; + LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("inventory"); + S32 z_min = S32_MAX; + for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); iter != inst_list.end(); ++iter) + { + LLFloaterInventory* iv = dynamic_cast<LLFloaterInventory*>(*iter); + if (iv) + { + S32 z_order = gFloaterView->getZOrder(iv); + if (z_order < z_min) + { + res = iv; + z_min = z_order; + } + } + } + return res; +} + +// static +void LLFloaterInventory::cleanup() +{ + LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("inventory"); + for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); iter != inst_list.end();) + { + LLFloaterInventory* iv = dynamic_cast<LLFloaterInventory*>(*iter++); + if (iv) + { + iv->destroy(); + } + } +} + +void LLFloaterInventory::toggleFindOptions() +{ + LLMemType mt(LLMemType::MTYPE_INVENTORY_VIEW_TOGGLE); + LLFloater *floater = getFinder(); + if (!floater) + { + LLFloaterInventoryFinder * finder = new LLFloaterInventoryFinder(this); + mFinderHandle = finder->getHandle(); + finder->openFloater(); + addDependentFloater(mFinderHandle); + + // start background fetch of folders + gInventory.startBackgroundFetch(); + + gSavedSettings.setBOOL("Inventory.ShowFilters", TRUE); + } + else + { + floater->closeFloater(); + + gSavedSettings.setBOOL("Inventory.ShowFilters", FALSE); + } +} + +// static +BOOL LLFloaterInventory::filtersVisible(void* user_data) +{ + LLFloaterInventory* self = (LLFloaterInventory*)user_data; + if(!self) return FALSE; + + return self->getFinder() != NULL; +} + +void LLFloaterInventory::onClearSearch() +{ + LLFloater *finder = getFinder(); + if (mActivePanel) + { + mActivePanel->setFilterSubString(LLStringUtil::null); + mActivePanel->setFilterTypes(0xffffffff); + } + + if (finder) + { + LLFloaterInventoryFinder::selectAllTypes(finder); + } + + // re-open folders that were initially open + if (mActivePanel) + { + mSavedFolderState->setApply(TRUE); + mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState); + LLOpenFoldersWithSelection opener; + mActivePanel->getRootFolder()->applyFunctorRecursively(opener); + mActivePanel->getRootFolder()->scrollToShowSelection(); + } +} + +void LLFloaterInventory::onSearchEdit(const std::string& search_string ) +{ + if (search_string == "") + { + onClearSearch(); + } + if (!mActivePanel) + { + return; + } + + gInventory.startBackgroundFetch(); + + std::string filter_text = search_string; + std::string uppercase_search_string = filter_text; + LLStringUtil::toUpper(uppercase_search_string); + if (mActivePanel->getFilterSubString().empty() && uppercase_search_string.empty()) + { + // current filter and new filter empty, do nothing + return; + } + + // save current folder open state if no filter currently applied + if (!mActivePanel->getRootFolder()->isFilterModified()) + { + mSavedFolderState->setApply(FALSE); + mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState); + } + + // set new filter string + mActivePanel->setFilterSubString(uppercase_search_string); +} + + + //static + BOOL LLFloaterInventory::incrementalFind(LLFolderViewItem* first_item, const char *find_text, BOOL backward) + { + LLFloaterInventory* active_view = NULL; + + LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("inventory"); + for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); iter != inst_list.end(); ++iter) + { + LLFloaterInventory* iv = dynamic_cast<LLFloaterInventory*>(*iter); + if (iv) + { + if (gFocusMgr.childHasKeyboardFocus(iv)) + { + active_view = iv; + break; + } + } + } + + if (!active_view) + { + return FALSE; + } + + std::string search_string(find_text); + + if (search_string.empty()) + { + return FALSE; + } + + if (active_view->mActivePanel && + active_view->mActivePanel->getRootFolder()->search(first_item, search_string, backward)) + { + return TRUE; + } + + return FALSE; + } + +void LLFloaterInventory::onFilterSelected() +{ + // Find my index + mActivePanel = (LLInventoryPanel*)childGetVisibleTab("inventory filter tabs"); + + if (!mActivePanel) + { + return; + } + LLInventoryFilter* filter = mActivePanel->getFilter(); + LLFloaterInventoryFinder *finder = getFinder(); + if (finder) + { + finder->changeFilter(filter); + } + if (filter->isActive()) + { + // If our filter is active we may be the first thing requiring a fetch so we better start it here. + gInventory.startBackgroundFetch(); + } + setFilterTextFromFilter(); +} + +BOOL LLFloaterInventory::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, + EDragAndDropType cargo_type, + void* cargo_data, + EAcceptance* accept, + std::string& tooltip_msg) +{ + // Check to see if we are auto scrolling from the last frame + LLInventoryPanel* panel = (LLInventoryPanel*)this->getActivePanel(); + BOOL needsToScroll = panel->getScrollableContainer()->needsToScroll(x, y, LLScrollContainer::VERTICAL); + if(mFilterTabs) + { + if(needsToScroll) + { + mFilterTabs->startDragAndDropDelayTimer(); + } + } + + BOOL handled = LLFloater::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg); + + return handled; +} +const std::string& get_item_icon_name(LLAssetType::EType asset_type, + LLInventoryType::EType inventory_type, + U32 attachment_point, + BOOL item_is_multi ) +{ + EInventoryIcon idx = OBJECT_ICON_NAME; + if ( item_is_multi ) + { + idx = OBJECT_MULTI_ICON_NAME; + } + + switch(asset_type) + { + case LLAssetType::AT_TEXTURE: + if(LLInventoryType::IT_SNAPSHOT == inventory_type) + { + idx = SNAPSHOT_ICON_NAME; + } + else + { + idx = TEXTURE_ICON_NAME; + } + break; + + case LLAssetType::AT_SOUND: + idx = SOUND_ICON_NAME; + break; + case LLAssetType::AT_CALLINGCARD: + if(attachment_point!= 0) + { + idx = CALLINGCARD_ONLINE_ICON_NAME; + } + else + { + idx = CALLINGCARD_OFFLINE_ICON_NAME; + } + break; + case LLAssetType::AT_LANDMARK: + if(attachment_point!= 0) + { + idx = LANDMARK_VISITED_ICON_NAME; + } + else + { + idx = LANDMARK_ICON_NAME; + } + break; + case LLAssetType::AT_SCRIPT: + case LLAssetType::AT_LSL_TEXT: + case LLAssetType::AT_LSL_BYTECODE: + idx = SCRIPT_ICON_NAME; + break; + case LLAssetType::AT_CLOTHING: + idx = CLOTHING_ICON_NAME; + case LLAssetType::AT_BODYPART : + if(LLAssetType::AT_BODYPART == asset_type) + { + idx = BODYPART_ICON_NAME; + } + switch(LLInventoryItem::II_FLAGS_WEARABLES_MASK & attachment_point) + { + case WT_SHAPE: + idx = BODYPART_SHAPE_ICON_NAME; + break; + case WT_SKIN: + idx = BODYPART_SKIN_ICON_NAME; + break; + case WT_HAIR: + idx = BODYPART_HAIR_ICON_NAME; + break; + case WT_EYES: + idx = BODYPART_EYES_ICON_NAME; + break; + case WT_SHIRT: + idx = CLOTHING_SHIRT_ICON_NAME; + break; + case WT_PANTS: + idx = CLOTHING_PANTS_ICON_NAME; + break; + case WT_SHOES: + idx = CLOTHING_SHOES_ICON_NAME; + break; + case WT_SOCKS: + idx = CLOTHING_SOCKS_ICON_NAME; + break; + case WT_JACKET: + idx = CLOTHING_JACKET_ICON_NAME; + break; + case WT_GLOVES: + idx = CLOTHING_GLOVES_ICON_NAME; + break; + case WT_UNDERSHIRT: + idx = CLOTHING_UNDERSHIRT_ICON_NAME; + break; + case WT_UNDERPANTS: + idx = CLOTHING_UNDERPANTS_ICON_NAME; + break; + case WT_SKIRT: + idx = CLOTHING_SKIRT_ICON_NAME; + break; + case WT_ALPHA: + idx = CLOTHING_ALPHA_ICON_NAME; + break; + case WT_TATTOO: + idx = CLOTHING_TATTOO_ICON_NAME; + break; + default: + // no-op, go with choice above + break; + } + break; + case LLAssetType::AT_NOTECARD: + idx = NOTECARD_ICON_NAME; + break; + case LLAssetType::AT_ANIMATION: + idx = ANIMATION_ICON_NAME; + break; + case LLAssetType::AT_GESTURE: + idx = GESTURE_ICON_NAME; + break; + case LLAssetType::AT_FAVORITE: + //TODO - need bette idx + idx = LANDMARK_ICON_NAME; + break; + default: + break; + } + + return ICON_NAME[idx]; +} + +LLUIImagePtr get_item_icon(LLAssetType::EType asset_type, + LLInventoryType::EType inventory_type, + U32 attachment_point, + BOOL item_is_multi) +{ + const std::string& icon_name = get_item_icon_name(asset_type, inventory_type, attachment_point, item_is_multi ); + return LLUI::getUIImage(icon_name); +} + +const std::string LLInventoryPanel::DEFAULT_SORT_ORDER = std::string("InventorySortOrder"); +const std::string LLInventoryPanel::RECENTITEMS_SORT_ORDER = std::string("RecentItemsSortOrder"); +const std::string LLInventoryPanel::INHERIT_SORT_ORDER = std::string(""); + +LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) +: LLPanel(p), + mInventoryObserver(NULL), + mFolders(NULL), + mScroller(NULL), + mSortOrderSetting(p.sort_order_setting), + mInventory(p.inventory), + mAllowMultiSelect(p.allow_multi_select) +{ + // contex menu callbacks + mCommitCallbackRegistrar.add("Inventory.DoToSelected", boost::bind(&LLInventoryPanel::doToSelected, this, _2)); + mCommitCallbackRegistrar.add("Inventory.EmptyTrash", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyTrash", LLAssetType::AT_TRASH)); + mCommitCallbackRegistrar.add("Inventory.EmptyLostAndFound", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyLostAndFound", LLAssetType::AT_LOST_AND_FOUND)); + mCommitCallbackRegistrar.add("Inventory.DoCreate", boost::bind(&LLInventoryPanel::doCreate, this, _2)); + mCommitCallbackRegistrar.add("Inventory.AttachObject", boost::bind(&LLInventoryPanel::attachObject, this, _2)); + mCommitCallbackRegistrar.add("Inventory.BeginIMSession", boost::bind(&LLInventoryPanel::beginIMSession, this)); + + setBackgroundColor(LLUIColorTable::instance().getColor("InventoryBackgroundColor")); + setBackgroundVisible(TRUE); + setBackgroundOpaque(TRUE); +} + +BOOL LLInventoryPanel::postBuild() +{ + LLMemType mt(LLMemType::MTYPE_INVENTORY_POST_BUILD); + + mCommitCallbackRegistrar.pushScope(); // registered as a widget; need to push callback scope ourselves + + // create root folder + { + LLRect folder_rect(0, + 0, + getRect().getWidth(), + 0); + LLFolderView::Params p; + p.name = getName(); + p.rect = folder_rect; + p.parent_panel = this; + mFolders = LLUICtrlFactory::create<LLFolderView>(p); + mFolders->setAllowMultiSelect(mAllowMultiSelect); + } + + mCommitCallbackRegistrar.popScope(); + + mFolders->setCallbackRegistrar(&mCommitCallbackRegistrar); + + // scroller + { + LLRect scroller_view_rect = getRect(); + scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom); + LLScrollContainer::Params p; + p.name("Inventory Scroller"); + p.rect(scroller_view_rect); + p.follows.flags(FOLLOWS_ALL); + p.reserve_scroll_corner(true); + p.tab_stop(true); + mScroller = LLUICtrlFactory::create<LLScrollContainer>(p); + } + addChild(mScroller); + mScroller->addChild(mFolders); + + mFolders->setScrollContainer(mScroller); + + // set up the callbacks from the inventory we're viewing, and then + // build everything. + mInventoryObserver = new LLInventoryPanelObserver(this); + mInventory->addObserver(mInventoryObserver); + rebuildViewsFor(LLUUID::null, LLInventoryObserver::ADD); + + // bit of a hack to make sure the inventory is open. + mFolders->openFolder(std::string("My Inventory")); + + if (mSortOrderSetting != INHERIT_SORT_ORDER) + { + setSortOrder(gSavedSettings.getU32(mSortOrderSetting)); + } + else + { + setSortOrder(gSavedSettings.getU32(DEFAULT_SORT_ORDER)); + } + mFolders->setSortOrder(mFolders->getFilter()->getSortOrder()); + + return TRUE; +} + +LLInventoryPanel::~LLInventoryPanel() +{ + // should this be a global setting? + U32 sort_order = mFolders->getSortOrder(); + if (mSortOrderSetting != INHERIT_SORT_ORDER) + { + gSavedSettings.setU32(mSortOrderSetting, sort_order); + } + + // LLView destructor will take care of the sub-views. + mInventory->removeObserver(mInventoryObserver); + delete mInventoryObserver; + mScroller = NULL; +} + + LLMemType mt(LLMemType::MTYPE_INVENTORY_FROM_XML); +void LLInventoryPanel::draw() +{ + // select the desired item (in case it wasn't loaded when the selection was requested) + mFolders->updateSelection(); + LLPanel::draw(); +} + +void LLInventoryPanel::setFilterTypes(U32 filter_types) +{ + mFolders->getFilter()->setFilterTypes(filter_types); +} + +void LLInventoryPanel::setFilterPermMask(PermissionMask filter_perm_mask) +{ + mFolders->getFilter()->setFilterPermissions(filter_perm_mask); +} + +void LLInventoryPanel::setFilterSubString(const std::string& string) +{ + mFolders->getFilter()->setFilterSubString(string); +} + +void LLInventoryPanel::setSortOrder(U32 order) +{ + mFolders->getFilter()->setSortOrder(order); + if (mFolders->getFilter()->isModified()) + { + mFolders->setSortOrder(order); + // try to keep selection onscreen, even if it wasn't to start with + mFolders->scrollToShowSelection(); + } +} + +void LLInventoryPanel::setSinceLogoff(BOOL sl) +{ + mFolders->getFilter()->setDateRangeLastLogoff(sl); +} + +void LLInventoryPanel::setHoursAgo(U32 hours) +{ + mFolders->getFilter()->setHoursAgo(hours); +} + +void LLInventoryPanel::setShowFolderState(LLInventoryFilter::EFolderShow show) +{ + mFolders->getFilter()->setShowFolderState(show); +} + +LLInventoryFilter::EFolderShow LLInventoryPanel::getShowFolderState() +{ + return mFolders->getFilter()->getShowFolderState(); +} + +void LLInventoryPanel::modelChanged(U32 mask) +{ + LLFastTimer t2(LLFastTimer::FTM_REFRESH); + + bool handled = false; + if(mask & LLInventoryObserver::LABEL) + { + handled = true; + // label change - empty out the display name for each object + // in this change set. + const std::set<LLUUID>& changed_items = gInventory.getChangedIDs(); + std::set<LLUUID>::const_iterator id_it = changed_items.begin(); + std::set<LLUUID>::const_iterator id_end = changed_items.end(); + LLFolderViewItem* view = NULL; + LLInvFVBridge* bridge = NULL; + for (;id_it != id_end; ++id_it) + { + view = mFolders->getItemByID(*id_it); + if(view) + { + // request refresh on this item (also flags for filtering) + bridge = (LLInvFVBridge*)view->getListener(); + if(bridge) + { // Clear the display name first, so it gets properly re-built during refresh() + bridge->clearDisplayName(); + } + view->refresh(); + } + } + } + if((mask & (LLInventoryObserver::STRUCTURE + | LLInventoryObserver::ADD + | LLInventoryObserver::REMOVE)) != 0) + { + handled = true; + // Record which folders are open by uuid. + LLInventoryModel* model = getModel(); + if (model) + { + const std::set<LLUUID>& changed_items = gInventory.getChangedIDs(); + + std::set<LLUUID>::const_iterator id_it = changed_items.begin(); + std::set<LLUUID>::const_iterator id_end = changed_items.end(); + for (;id_it != id_end; ++id_it) + { + // sync view with model + LLInventoryObject* model_item = model->getObject(*id_it); + LLFolderViewItem* view_item = mFolders->getItemByID(*id_it); + + if (model_item) + { + if (!view_item) + { + // this object was just created, need to build a view for it + if ((mask & LLInventoryObserver::ADD) != LLInventoryObserver::ADD) + { + llwarns << *id_it << " is in model but not in view, but ADD flag not set" << llendl; + } + buildNewViews(*id_it); + + // select any newly created object + // that has the auto rename at top of folder + // root set + if(mFolders->getRoot()->needsAutoRename()) + { + setSelection(*id_it, FALSE); + } + } + else + { + // this object was probably moved, check its parent + if ((mask & LLInventoryObserver::STRUCTURE) != LLInventoryObserver::STRUCTURE) + { + llwarns << *id_it << " is in model and in view, but STRUCTURE flag not set" << llendl; + } + + LLFolderViewFolder* new_parent = (LLFolderViewFolder*)mFolders->getItemByID(model_item->getParentUUID()); + if (view_item->getParentFolder() != new_parent) + { + view_item->getParentFolder()->extractItem(view_item); + view_item->addToFolder(new_parent, mFolders); + } + } + } + else + { + if (view_item) + { + if ((mask & LLInventoryObserver::REMOVE) != LLInventoryObserver::REMOVE) + { + llwarns << *id_it << " is not in model but in view, but REMOVE flag not set" << llendl; + } + // item in view but not model, need to delete view + view_item->destroyView(); + } + else + { + llwarns << *id_it << "Item does not exist in either view or model, but notification triggered" << llendl; + } + } + } + } + } + + if (!handled) + { + // it's a small change that only requires a refresh. + // *TODO: figure out a more efficient way to do the refresh + // since it is expensive on large inventories + mFolders->refresh(); + } +} + +void LLInventoryPanel::rebuildViewsFor(const LLUUID& id, U32 mask) +{ + LLFolderViewItem* old_view = NULL; + + // get old LLFolderViewItem + old_view = mFolders->getItemByID(id); + if (old_view && id.notNull()) + { + old_view->destroyView(); + } + + buildNewViews(id); +} + +void LLInventoryPanel::buildNewViews(const LLUUID& id) +{ + LLMemType mt(LLMemType::MTYPE_INVENTORY_BUILD_NEW_VIEWS); + LLFolderViewItem* itemp = NULL; + LLInventoryObject* objectp = gInventory.getObject(id); + + if (objectp) + { + if (objectp->getType() <= LLAssetType::AT_NONE || + objectp->getType() >= LLAssetType::AT_COUNT) + { + llwarns << "LLInventoryPanel::buildNewViews called with objectp->mType == " + << ((S32) objectp->getType()) + << " (shouldn't happen)" << llendl; + } + else if (objectp->getType() == LLAssetType::AT_CATEGORY) // build new view for category + { + LLInvFVBridge* new_listener = LLInvFVBridge::createBridge(objectp->getType(), + LLInventoryType::IT_CATEGORY, + this, + objectp->getUUID()); + + if (new_listener) + { + LLFolderViewFolder::Params p; + p.name = new_listener->getDisplayName(); + p.icon = new_listener->getIcon(); + p.root = mFolders; + p.listener = new_listener; + LLFolderViewFolder* folderp = LLUICtrlFactory::create<LLFolderViewFolder>(p); + + folderp->setItemSortOrder(mFolders->getSortOrder()); + itemp = folderp; + } + } + else // build new view for item + { + LLInventoryItem* item = (LLInventoryItem*)objectp; + LLInvFVBridge* new_listener = LLInvFVBridge::createBridge( + item->getType(), + item->getInventoryType(), + this, + item->getUUID(), + item->getFlags()); + if (new_listener) + { + LLFolderViewItem::Params params; + params.name(new_listener->getDisplayName()); + params.icon(new_listener->getIcon()); + params.creation_date(new_listener->getCreationDate()); + params.root(mFolders); + params.listener(new_listener); + params.rect(LLRect (0, 0, 0, 0)); + itemp = LLUICtrlFactory::create<LLFolderViewItem> (params); + } + } + + LLFolderViewFolder* parent_folder = (LLFolderViewFolder*)mFolders->getItemByID(objectp->getParentUUID()); + + if (itemp) + { + if (parent_folder) + { + itemp->addToFolder(parent_folder, mFolders); + } + else + { + llwarns << "Couldn't find parent folder for child " << itemp->getLabel() << llendl; + delete itemp; + } + } + } + if ((id.isNull() || + (objectp && objectp->getType() == LLAssetType::AT_CATEGORY))) + { + LLViewerInventoryCategory::cat_array_t* categories; + LLViewerInventoryItem::item_array_t* items; + + mInventory->lockDirectDescendentArrays(id, categories, items); + if(categories) + { + S32 count = categories->count(); + for(S32 i = 0; i < count; ++i) + { + LLInventoryCategory* cat = categories->get(i); + buildNewViews(cat->getUUID()); + } + } + if(items) + { + S32 count = items->count(); + for(S32 i = 0; i < count; ++i) + { + LLInventoryItem* item = items->get(i); + buildNewViews(item->getUUID()); + } + } + mInventory->unlockDirectDescendentArrays(id); + } +} + +struct LLConfirmPurgeData +{ + LLUUID mID; + LLInventoryModel* mModel; +}; + +class LLIsNotWorn : public LLInventoryCollectFunctor +{ +public: + LLIsNotWorn() {} + virtual ~LLIsNotWorn() {} + virtual bool operator()(LLInventoryCategory* cat, + LLInventoryItem* item) + { + return !gAgentWearables.isWearingItem(item->getUUID()); + } +}; + +class LLOpenFolderByID : public LLFolderViewFunctor +{ +public: + LLOpenFolderByID(const LLUUID& id) : mID(id) {} + virtual ~LLOpenFolderByID() {} + virtual void doFolder(LLFolderViewFolder* folder) + { + if (folder->getListener() && folder->getListener()->getUUID() == mID) folder->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP); + } + virtual void doItem(LLFolderViewItem* item) {} +protected: + const LLUUID& mID; +}; + + +void LLInventoryPanel::openSelected() +{ + LLFolderViewItem* folder_item = mFolders->getCurSelectedItem(); + if(!folder_item) return; + LLInvFVBridge* bridge = (LLInvFVBridge*)folder_item->getListener(); + if(!bridge) return; + bridge->openItem(); +} + +BOOL LLInventoryPanel::handleHover(S32 x, S32 y, MASK mask) +{ + BOOL handled = LLView::handleHover(x, y, mask); + if(handled) + { + ECursorType cursor = getWindow()->getCursor(); + if (LLInventoryModel::backgroundFetchActive() && cursor == UI_CURSOR_ARROW) + { + // replace arrow cursor with arrow and hourglass cursor + getWindow()->setCursor(UI_CURSOR_WORKING); + } + } + else + { + getWindow()->setCursor(UI_CURSOR_ARROW); + } + return TRUE; +} + +BOOL LLInventoryPanel::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, + EDragAndDropType cargo_type, + void* cargo_data, + EAcceptance* accept, + std::string& tooltip_msg) +{ + + BOOL handled = LLPanel::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg); + + if (handled) + { + mFolders->setDragAndDropThisFrame(); + } + + return handled; +} + +void LLInventoryPanel::onFocusLost() +{ + // inventory no longer handles cut/copy/paste/delete + if (LLEditMenuHandler::gEditMenuHandler == mFolders) + { + LLEditMenuHandler::gEditMenuHandler = NULL; + } + + LLPanel::onFocusLost(); +} + +void LLInventoryPanel::onFocusReceived() +{ + // inventory now handles cut/copy/paste/delete + LLEditMenuHandler::gEditMenuHandler = mFolders; + + LLPanel::onFocusReceived(); +} + + +void LLInventoryPanel::openAllFolders() +{ + mFolders->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_DOWN); + mFolders->arrangeAll(); +} + +void LLInventoryPanel::openDefaultFolderForType(LLAssetType::EType type) +{ + LLUUID category_id = mInventory->findCategoryUUIDForType(type); + LLOpenFolderByID opener(category_id); + mFolders->applyFunctorRecursively(opener); +} + +void LLInventoryPanel::setSelection(const LLUUID& obj_id, BOOL take_keyboard_focus) +{ + mFolders->setSelectionByID(obj_id, take_keyboard_focus); +} + +void LLInventoryPanel::clearSelection() +{ + mFolders->clearSelection(); +} + +void LLInventoryPanel::onSelectionChange(const std::deque<LLFolderViewItem*>& items, BOOL user_action) +{ + LLFolderView* fv = getRootFolder(); + if (fv->needsAutoRename()) // auto-selecting a new user-created asset and preparing to rename + { + fv->setNeedsAutoRename(FALSE); + if (items.size()) // new asset is visible and selected + { + fv->startRenamingSelectedItem(); + } + } +} + +//---------------------------------------------------------------------------- + +void LLInventoryPanel::doToSelected(const LLSD& userdata) +{ + mFolders->doToSelected(&gInventory, userdata); +} + +void LLInventoryPanel::doCreate(const LLSD& userdata) +{ + menu_create_inventory_item(mFolders, LLFolderBridge::sSelf, userdata); +} + +bool LLInventoryPanel::beginIMSession() +{ + std::set<LLUUID> selected_items; + mFolders->getSelectionList(selected_items); + + std::string name; + static int session_num = 1; + + LLDynamicArray<LLUUID> members; + EInstantMessage type = IM_SESSION_CONFERENCE_START; + + std::set<LLUUID>::const_iterator iter; + for (iter = selected_items.begin(); iter != selected_items.end(); iter++) + { + + LLUUID item = *iter; + LLFolderViewItem* folder_item = mFolders->getItemByID(item); + + if(folder_item) + { + LLFolderViewEventListener* fve_listener = folder_item->getListener(); + if (fve_listener && (fve_listener->getInventoryType() == LLInventoryType::IT_CATEGORY)) + { + + LLFolderBridge* bridge = (LLFolderBridge*)folder_item->getListener(); + if(!bridge) return true; + LLViewerInventoryCategory* cat = bridge->getCategory(); + if(!cat) return true; + name = cat->getName(); + LLUniqueBuddyCollector is_buddy; + LLInventoryModel::cat_array_t cat_array; + LLInventoryModel::item_array_t item_array; + gInventory.collectDescendentsIf(bridge->getUUID(), + cat_array, + item_array, + LLInventoryModel::EXCLUDE_TRASH, + is_buddy); + S32 count = item_array.count(); + if(count > 0) + { + LLFloaterReg::showInstance("communicate"); + // create the session + LLAvatarTracker& at = LLAvatarTracker::instance(); + LLUUID id; + for(S32 i = 0; i < count; ++i) + { + id = item_array.get(i)->getCreatorUUID(); + if(at.isBuddyOnline(id)) + { + members.put(id); + } + } + } + } + else + { + LLFolderViewItem* folder_item = mFolders->getItemByID(item); + if(!folder_item) return true; + LLInvFVBridge* listenerp = (LLInvFVBridge*)folder_item->getListener(); + + if (listenerp->getInventoryType() == LLInventoryType::IT_CALLINGCARD) + { + LLInventoryItem* inv_item = gInventory.getItem(listenerp->getUUID()); + + if (inv_item) + { + LLAvatarTracker& at = LLAvatarTracker::instance(); + LLUUID id = inv_item->getCreatorUUID(); + + if(at.isBuddyOnline(id)) + { + members.put(id); + } + } + } //if IT_CALLINGCARD + } //if !IT_CATEGORY + } + } //for selected_items + + // the session_id is randomly generated UUID which will be replaced later + // with a server side generated number + + if (name.empty()) + { + name = llformat("Session %d", session_num++); + } + + gIMMgr->addSession(name, type, members[0], members); + + return true; +} + +bool LLInventoryPanel::attachObject(const LLSD& userdata) +{ + std::set<LLUUID> selected_items; + mFolders->getSelectionList(selected_items); + LLUUID id = *selected_items.begin(); + + std::string joint_name = userdata.asString(); + LLVOAvatar *avatarp = static_cast<LLVOAvatar*>(gAgent.getAvatarObject()); + LLViewerJointAttachment* attachmentp = NULL; + for (LLVOAvatar::attachment_map_t::iterator iter = avatarp->mAttachmentPoints.begin(); + iter != avatarp->mAttachmentPoints.end(); ) + { + LLVOAvatar::attachment_map_t::iterator curiter = iter++; + LLViewerJointAttachment* attachment = curiter->second; + if (attachment->getName() == joint_name) + { + attachmentp = attachment; + break; + } + } + if (attachmentp == NULL) + { + return true; + } + LLViewerInventoryItem* item = (LLViewerInventoryItem*)gInventory.getItem(id); + + if(item && gInventory.isObjectDescendentOf(id, gInventory.getRootFolderID())) + { + rez_attachment(item, attachmentp); + } + else if(item && item->isComplete()) + { + // must be in library. copy it to our inventory and put it on. + LLPointer<LLInventoryCallback> cb = new RezAttachmentCallback(attachmentp); + copy_inventory_item(gAgent.getID(), + item->getPermissions().getOwner(), + item->getUUID(), + LLUUID::null, + std::string(), + cb); + } + gFocusMgr.setKeyboardFocus(NULL); + + return true; +} + + +//---------------------------------------------------------------------------- + +// static DEBUG ONLY: +void LLInventoryPanel::dumpSelectionInformation(void* user_data) +{ + LLInventoryPanel* iv = (LLInventoryPanel*)user_data; + iv->mFolders->dumpSelectionInformation(); +} + +BOOL LLInventoryPanel::getSinceLogoff() +{ + return mFolders->getFilter()->isSinceLogoff(); +} + +void example_param_block_usage() +{ + LLInventoryPanel::Params param_block; + param_block.name(std::string("inventory")); + + param_block.sort_order_setting(LLInventoryPanel::RECENTITEMS_SORT_ORDER); + param_block.allow_multi_select(true); + param_block.filter(LLInventoryPanel::Filter() + .sort_order(1) + .types(0xffff0000)); + param_block.inventory(&gInventory); + param_block.has_border(true); + + LLUICtrlFactory::create<LLInventoryPanel>(param_block); + + param_block = LLInventoryPanel::Params(); + param_block.name(std::string("inventory")); + + //LLSD param_block_sd; + //param_block_sd["sort_order_setting"] = LLInventoryPanel::RECENTITEMS_SORT_ORDER; + //param_block_sd["allow_multi_select"] = true; + //param_block_sd["filter"]["sort_order"] = 1; + //param_block_sd["filter"]["types"] = (S32)0xffff0000; + //param_block_sd["has_border"] = true; + + //LLInitParam::LLSDParser(param_block_sd).parse(param_block); + + LLUICtrlFactory::create<LLInventoryPanel>(param_block); +} diff --git a/indra/newview/llfloaterinventory.h b/indra/newview/llfloaterinventory.h new file mode 100644 index 0000000000..cd60407507 --- /dev/null +++ b/indra/newview/llfloaterinventory.h @@ -0,0 +1,369 @@ +/** + * @file llfloaterinventory.h + * @brief LLFloaterInventory, LLInventoryFolder, and LLInventoryItem + * class definition + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLINVENTORYVIEW_H +#define LL_LLINVENTORYVIEW_H + +#include "llassetstorage.h" +#include "lldarray.h" +#include "llfloater.h" +#include "llinventory.h" +#include "llinventoryfilter.h" +#include "llfolderview.h" +#include "llinventorymodel.h" +#include "lluictrlfactory.h" +#include <set> + + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// Class LLFloaterInventory +// +// This is the agent inventory _floater_. +// It deals with the buttons and views used to navigate as +// well as controls the behavior of the overall object. +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +class LLFolderViewItem; +class LLInventoryFilter; +class LLInventoryModel; +class LLInvFVBridge; +class LLMenuBarGL; +class LLCheckBoxCtrl; +class LLSpinCtrl; +class LLScrollContainer; +class LLTextBox; +class LLIconCtrl; +class LLSaveFolderState; +class LLSearchEditor; +class LLTabContainer; + +class LLInventoryPanel : public LLPanel +{ +public: + static const std::string DEFAULT_SORT_ORDER; + static const std::string RECENTITEMS_SORT_ORDER; + static const std::string INHERIT_SORT_ORDER; + + struct Filter : public LLInitParam::Block<Filter> + { + Optional<U32> sort_order; + Optional<U32> types; + Optional<std::string> search_string; + + Filter() + : sort_order("sort_order"), + types("types", 0xffffffff), + search_string("search_string") + {} + }; + + struct Params + : public LLInitParam::Block<Params, LLPanel::Params> + { + Optional<std::string> sort_order_setting; + Optional<LLInventoryModel*> inventory; + Optional<bool> allow_multi_select; + Optional<Filter> filter; + + Params() + : sort_order_setting("sort_order_setting"), + inventory("", &gInventory), + allow_multi_select("allow_multi_select", true), + filter("filter") + {} + }; + +protected: + LLInventoryPanel(const Params&); + friend class LLUICtrlFactory; + +public: + ~LLInventoryPanel(); + + LLInventoryModel* getModel() { return mInventory; } + + BOOL postBuild(); + + // LLView methods + void draw(); + BOOL handleHover(S32 x, S32 y, MASK mask); + BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, + EDragAndDropType cargo_type, + void* cargo_data, + EAcceptance* accept, + std::string& tooltip_msg); + // LLUICtrl methods + /*virtual*/ void onFocusLost(); + /*virtual*/ void onFocusReceived(); + + // Call this method to set the selection. + void openAllFolders(); + void openDefaultFolderForType(LLAssetType::EType); + void setSelection(const LLUUID& obj_id, BOOL take_keyboard_focus); + void setSelectCallback(const LLFolderView::signal_t::slot_type& cb) { if (mFolders) mFolders->setSelectCallback(cb); } + void clearSelection(); + LLInventoryFilter* getFilter() { return mFolders->getFilter(); } + void setFilterTypes(U32 filter); + U32 getFilterTypes() const { return mFolders->getFilterTypes(); } + void setFilterPermMask(PermissionMask filter_perm_mask); + U32 getFilterPermMask() const { return mFolders->getFilterPermissions(); } + void setFilterSubString(const std::string& string); + const std::string getFilterSubString() { return mFolders->getFilterSubString(); } + void setSortOrder(U32 order); + U32 getSortOrder() { return mFolders->getSortOrder(); } + void setSinceLogoff(BOOL sl); + void setHoursAgo(U32 hours); + BOOL getSinceLogoff(); + + void setShowFolderState(LLInventoryFilter::EFolderShow show); + LLInventoryFilter::EFolderShow getShowFolderState(); + void setAllowMultiSelect(BOOL allow) { mFolders->setAllowMultiSelect(allow); } + // This method is called when something has changed about the inventory. + void modelChanged(U32 mask); + LLFolderView* getRootFolder() { return mFolders; } + LLScrollContainer* getScrollableContainer() { return mScroller; } + + void onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action); + + // Callbacks + void doToSelected(const LLSD& userdata); + void doCreate(const LLSD& userdata); + bool beginIMSession(); + bool attachObject(const LLSD& userdata); + + // DEBUG ONLY: + static void dumpSelectionInformation(void* user_data); + + void openSelected(); + void unSelectAll() { mFolders->setSelection(NULL, FALSE, FALSE); } + +protected: + // Given the id and the parent, build all of the folder views. + void rebuildViewsFor(const LLUUID& id, U32 mask); + void buildNewViews(const LLUUID& id); + +protected: + LLInventoryModel* mInventory; + LLInventoryObserver* mInventoryObserver; + LLFolderView* mFolders; + LLScrollContainer* mScroller; + BOOL mAllowMultiSelect; + std::string mSortOrderSetting; +}; + +class LLFloaterInventory; + +class LLFloaterInventoryFinder : public LLFloater +{ +public: + LLFloaterInventoryFinder( LLFloaterInventory* inventory_view); + virtual void draw(); + virtual void onClose(bool app_quitting); + /*virtual*/ BOOL postBuild(); + void changeFilter(LLInventoryFilter* filter); + void updateElementsFromFilter(); + BOOL getCheckShowEmpty(); + BOOL getCheckSinceLogoff(); + + static void onTimeAgo(LLUICtrl*, void *); + static void onCheckSinceLogoff(LLUICtrl*, void *); + static void onCloseBtn(void* user_data); + static void selectAllTypes(void* user_data); + static void selectNoTypes(void* user_data); + +protected: + LLFloaterInventory* mFloaterInventory; + LLSpinCtrl* mSpinSinceDays; + LLSpinCtrl* mSpinSinceHours; + LLInventoryFilter* mFilter; +}; + +class LLFloaterInventory : public LLFloater, LLInventoryObserver +{ +friend class LLFloaterInventoryFinder; + +public: + LLFloaterInventory(const LLSD& key); + ~LLFloaterInventory(); + + /*virtual*/ void changed(U32 mask); + + BOOL postBuild(); + + // + // Misc functions + // + void setFilterTextFromFilter() { mFilterText = mActivePanel->getFilter()->getFilterText(); } + void startSearch(); + + // Spawn a new inventory view + static LLFloaterInventory* newInstance(); + + // This method makes sure that an inventory view exists, is + // visible, and has focus. The view chosen is returned. + static LLFloaterInventory* showAgentInventory(); + + // Return the active inventory view if there is one. Active is + // defined as the inventory that is the closest to the front, and + // is visible. + static LLFloaterInventory* getActiveInventory(); + + // This method calls showAgentInventory() if no views are visible, + // or hides/destroyes them all if any are visible. + static void toggleVisibility(); + static void toggleVisibility(void*) { toggleVisibility(); } + + // Final cleanup, destroy all open inventory views. + static void cleanup(); + + // LLView & LLFloater functionality + virtual void onOpen(const LLSD& key); + virtual void onClose(bool app_quitting); + virtual void setVisible(BOOL visible); + virtual void draw(); + virtual BOOL handleKeyHere(KEY key, MASK mask); + + BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, + EDragAndDropType cargo_type, + void* cargo_data, + EAcceptance* accept, + std::string& tooltip_msg); + + + LLInventoryPanel* getPanel() { return mActivePanel; } + LLInventoryPanel* getActivePanel() { return mActivePanel; } + + static BOOL filtersVisible(void* user_data); + void onClearSearch(); + static void onFoldersByName(void *user_data); + static BOOL checkFoldersByName(void *user_data); + void onSearchEdit(const std::string& search_string ); + static BOOL incrementalFind(LLFolderViewItem* first_item, const char *find_text, BOOL backward); + void onFilterSelected(); + + const std::string getFilterSubString() { return mActivePanel->getFilterSubString(); } + void setFilterSubString(const std::string& string) { mActivePanel->setFilterSubString(string); } + + // menu callbacks + void doToSelected(const LLSD& userdata); + void closeAllFolders(); + void doCreate(const LLSD& userdata); + void newWindow(); + void resetFilters(); + void setSortBy(const LLSD& userdata); + + // HACK: Until we can route this info through the instant message hierarchy + static BOOL sWearNewClothing; + static LLUUID sWearNewClothingTransactionID; // wear all clothing in this transaction + + void toggleFindOptions(); + + LLFloaterInventoryFinder* getFinder() { return (LLFloaterInventoryFinder*)mFinderHandle.get(); } + +protected: + LLSearchEditor* mSearchEditor; + LLTabContainer* mFilterTabs; + LLHandle<LLFloater> mFinderHandle; + LLInventoryPanel* mActivePanel; + LLSaveFolderState* mSavedFolderState; + + std::string mFilterText; +}; + +class LLSelectFirstFilteredItem : public LLFolderViewFunctor +{ +public: + LLSelectFirstFilteredItem() : mItemSelected(FALSE) {} + virtual ~LLSelectFirstFilteredItem() {} + virtual void doFolder(LLFolderViewFolder* folder); + virtual void doItem(LLFolderViewItem* item); + BOOL wasItemSelected() { return mItemSelected; } +protected: + BOOL mItemSelected; +}; + +class LLOpenFilteredFolders : public LLFolderViewFunctor +{ +public: + LLOpenFilteredFolders() {} + virtual ~LLOpenFilteredFolders() {} + virtual void doFolder(LLFolderViewFolder* folder); + virtual void doItem(LLFolderViewItem* item); +}; + +class LLSaveFolderState : public LLFolderViewFunctor +{ +public: + LLSaveFolderState() : mApply(FALSE) {} + virtual ~LLSaveFolderState() {} + virtual void doFolder(LLFolderViewFolder* folder); + virtual void doItem(LLFolderViewItem* item) {} + void setApply(BOOL apply); + void clearOpenFolders() { mOpenFolders.clear(); } +protected: + std::set<LLUUID> mOpenFolders; + BOOL mApply; +}; + +class LLOpenFoldersWithSelection : public LLFolderViewFunctor +{ +public: + LLOpenFoldersWithSelection() {} + virtual ~LLOpenFoldersWithSelection() {} + virtual void doFolder(LLFolderViewFolder* folder); + virtual void doItem(LLFolderViewItem* item); +}; + +///---------------------------------------------------------------------------- +/// Function declarations, constants, enums, and typedefs +///---------------------------------------------------------------------------- + +// useful functions with the inventory view + +class LLInventoryCategory; +class LLInventoryItem; + +const std::string& get_item_icon_name(LLAssetType::EType asset_type, + LLInventoryType::EType inventory_type, + U32 attachment_point, + BOOL item_is_multi ); + +LLUIImagePtr get_item_icon(LLAssetType::EType asset_type, + LLInventoryType::EType inventory_type, + U32 attachment_point, + BOOL item_is_multi ); + +#endif // LL_LLINVENTORYVIEW_H + + + diff --git a/indra/newview/llfloaterjoystick.cpp b/indra/newview/llfloaterjoystick.cpp index c73218cd0f..06fe2a84c8 100644 --- a/indra/newview/llfloaterjoystick.cpp +++ b/indra/newview/llfloaterjoystick.cpp @@ -48,7 +48,7 @@ #include "llcheckboxctrl.h" LLFloaterJoystick::LLFloaterJoystick(const LLSD& data) - : LLFloater() + : LLFloater(data) { //Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this, "floater_joystick.xml"); diff --git a/indra/newview/llfloaterjoystick.h b/indra/newview/llfloaterjoystick.h index 9c66b3a895..f3559c28e9 100644 --- a/indra/newview/llfloaterjoystick.h +++ b/indra/newview/llfloaterjoystick.h @@ -38,11 +38,11 @@ class LLCheckBoxCtrl; -class LLFloaterJoystick : public LLFloater, public LLFloaterSingleton<LLFloaterJoystick > +class LLFloaterJoystick : public LLFloater { + friend class LLFloaterReg; + public: - LLFloaterJoystick(const LLSD& data); - virtual ~LLFloaterJoystick(); virtual BOOL postBuild(); virtual void refresh(); @@ -52,6 +52,10 @@ public: static void setSNDefaults(); private: + + LLFloaterJoystick(const LLSD& data); + virtual ~LLFloaterJoystick(); + static void onCommitJoystickEnabled(LLUICtrl*, void*); static void onClickRestoreSNDefaults(void*); static void onClickCancel(void*); diff --git a/indra/newview/llfloaterlagmeter.cpp b/indra/newview/llfloaterlagmeter.cpp index 82deaef4a9..262102b820 100644 --- a/indra/newview/llfloaterlagmeter.cpp +++ b/indra/newview/llfloaterlagmeter.cpp @@ -51,7 +51,7 @@ const std::string LAG_WARNING_IMAGE_NAME = "lag_status_warning.tga"; const std::string LAG_GOOD_IMAGE_NAME = "lag_status_good.tga"; LLFloaterLagMeter::LLFloaterLagMeter(const LLSD& key) - : LLFloater() + : LLFloater(key) { // LLUICtrlFactory::getInstance()->buildFloater(this, "floater_lagmeter.xml"); mCommitCallbackRegistrar.add("LagMeter.ClickShrink", boost::bind(&LLFloaterLagMeter::onClickShrink, this)); diff --git a/indra/newview/llfloaterlagmeter.h b/indra/newview/llfloaterlagmeter.h index 6d2086839e..592630636a 100644 --- a/indra/newview/llfloaterlagmeter.h +++ b/indra/newview/llfloaterlagmeter.h @@ -37,18 +37,17 @@ class LLTextBox; -class LLFloaterLagMeter : public LLFloater, public LLFloaterSingleton<LLFloaterLagMeter> +class LLFloaterLagMeter : public LLFloater { - friend class LLUISingleton<LLFloaterLagMeter, VisibilityPolicy<LLFloater> >; + friend class LLFloaterReg; public: - LLFloaterLagMeter(const LLSD& key); - /*virtual*/ ~LLFloaterLagMeter(); - /*virtual*/ void draw(); /*virtual*/ BOOL postBuild(); private: - + + LLFloaterLagMeter(const LLSD& key); + /*virtual*/ ~LLFloaterLagMeter(); void determineClient(); void determineNetwork(); void determineServer(); diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index f3275913e4..039873691d 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -149,23 +149,50 @@ void send_parcel_select_objects(S32 parcel_local_id, S32 return_type, //static LLPanelLandObjects* LLFloaterLand::getCurrentPanelLandObjects() { - return LLFloaterLand::getInstance()->mPanelObjects; + LLFloaterLand* land_instance = LLFloaterReg::getTypedInstance<LLFloaterLand>("about_land"); + if(land_instance) + { + return land_instance->mPanelObjects; + } + else + { + return NULL; + } } //static LLPanelLandCovenant* LLFloaterLand::getCurrentPanelLandCovenant() { - return LLFloaterLand::getInstance()->mPanelCovenant; + LLFloaterLand* land_instance = LLFloaterReg::getTypedInstance<LLFloaterLand>("about_land"); + if(land_instance) + { + return land_instance->mPanelCovenant; + } + else + { + return NULL; + } } // static void LLFloaterLand::refreshAll() { - LLFloaterLand::getInstance()->refresh(); + LLFloaterLand* land_instance = LLFloaterReg::getTypedInstance<LLFloaterLand>("about_land"); + if(land_instance) + { + land_instance->refresh(); + } } void LLFloaterLand::onOpen(const LLSD& key) { + // moved from triggering show instance in llviwermenu.cpp + + if (LLViewerParcelMgr::getInstance()->selectionEmpty()) + { + LLViewerParcelMgr::getInstance()->selectParcelAt(gAgent.getPositionGlobal()); + } + // Done automatically when the selected parcel's properties arrive // (and hence we have the local id). // LLViewerParcelMgr::getInstance()->sendParcelAccessListRequest(AL_ACCESS | AL_BAN | AL_RENTER); @@ -196,7 +223,7 @@ void LLFloaterLand::onClose(bool app_quitting) LLFloaterLand::LLFloaterLand(const LLSD& seed) -: LLFloater() +: LLFloater(seed) { mFactoryMap["land_general_panel"] = LLCallbackMap(createPanelLandGeneral, this); mFactoryMap["land_covenant_panel"] = LLCallbackMap(createPanelLandCovenant, this); @@ -205,7 +232,7 @@ LLFloaterLand::LLFloaterLand(const LLSD& seed) mFactoryMap["land_media_panel"] = LLCallbackMap(createPanelLandMedia, this); mFactoryMap["land_access_panel"] = LLCallbackMap(createPanelLandAccess, this); - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_about_land.xml", false); + //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_about_land.xml", false); sObserver = new LLParcelSelectionObserver(); LLViewerParcelMgr::getInstance()->addObserver( sObserver ); diff --git a/indra/newview/llfloaterland.h b/indra/newview/llfloaterland.h index 74c1205e1f..ee49da3f05 100644 --- a/indra/newview/llfloaterland.h +++ b/indra/newview/llfloaterland.h @@ -71,9 +71,9 @@ class LLPanelLandRenters; class LLPanelLandCovenant; class LLFloaterLand -: public LLFloater, public LLFloaterSingleton<LLFloaterLand> +: public LLFloater { - friend class LLUISingleton<LLFloaterLand, VisibilityPolicy<LLFloater> >; + friend class LLFloaterReg; public: static void refreshAll(); @@ -85,13 +85,14 @@ public: virtual void onOpen(const LLSD& key); virtual BOOL postBuild(); -protected: - +private: // Does its own instance management, so clients not allowed // to allocate or destroy. LLFloaterLand(const LLSD& seed); virtual ~LLFloaterLand(); +protected: + /*virtual*/ void refresh(); static void* createPanelLandGeneral(void* data); diff --git a/indra/newview/llfloaterlandholdings.cpp b/indra/newview/llfloaterlandholdings.cpp index 223cca50b2..fbefd40c60 100644 --- a/indra/newview/llfloaterlandholdings.cpp +++ b/indra/newview/llfloaterlandholdings.cpp @@ -292,15 +292,16 @@ void LLFloaterLandHoldings::buttonCore(S32 which) F64 global_z = gAgent.getPositionGlobal().mdV[VZ]; LLVector3d pos_global(global_x, global_y, global_z); + LLFloaterWorldMap* floater_world_map = LLFloaterWorldMap::getInstance(); switch(which) { case 0: gAgent.teleportViaLocation(pos_global); - LLFloaterWorldMap::getInstance()->trackLocation(pos_global); + if(floater_world_map) floater_world_map->trackLocation(pos_global); break; case 1: - LLFloaterWorldMap::getInstance()->trackLocation(pos_global); + if(floater_world_map) floater_world_map->trackLocation(pos_global); LLFloaterReg::showInstance("world_map", "center"); break; default: diff --git a/indra/newview/llfloatermap.cpp b/indra/newview/llfloatermap.cpp index 6660650c56..f9fc467c05 100644 --- a/indra/newview/llfloatermap.cpp +++ b/indra/newview/llfloatermap.cpp @@ -94,7 +94,7 @@ BOOL LLFloaterMap::postBuild() registrar.add("Minimap.Zoom", boost::bind(&LLFloaterMap::handleZoom, this, _2)); registrar.add("Minimap.Tracker", boost::bind(&LLFloaterMap::handleStopTracking, this, _2)); - mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_minimap.xml", gMenuHolder); + mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_minimap.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); if (mPopupMenu && !LLTracker::isTracking(0)) { mPopupMenu->setItemEnabled ("Stop Tracking", false); diff --git a/indra/newview/llfloatermemleak.cpp b/indra/newview/llfloatermemleak.cpp index 3f2fcc26db..529bd68e03 100644 --- a/indra/newview/llfloatermemleak.cpp +++ b/indra/newview/llfloatermemleak.cpp @@ -42,26 +42,56 @@ #include "llmath.h" #include "llviewerwindow.h" -LLFloaterMemLeak* LLFloaterMemLeak::sInstance = NULL; U32 LLFloaterMemLeak::sMemLeakingSpeed = 0 ; //bytes leaked per frame U32 LLFloaterMemLeak::sMaxLeakedMem = 0 ; //maximum allowed leaked memory U32 LLFloaterMemLeak::sTotalLeaked = 0 ; S32 LLFloaterMemLeak::sStatus = LLFloaterMemLeak::STOP ; BOOL LLFloaterMemLeak::sbAllocationFailed = FALSE ; -LLFloaterMemLeak::LLFloaterMemLeak() - : LLFloater() +LLFloaterMemLeak::LLFloaterMemLeak(const LLSD& key) + : LLFloater(key) { setTitle("Memory Leaking Simulation Floater"); + mCommitCallbackRegistrar.add("MemLeak.ChangeLeakingSpeed", boost::bind(&LLFloaterMemLeak::onChangeLeakingSpeed, this)); + mCommitCallbackRegistrar.add("MemLeak.ChangeMaxMemLeaking", boost::bind(&LLFloaterMemLeak::onChangeMaxMemLeaking, this)); + mCommitCallbackRegistrar.add("MemLeak.Start", boost::bind(&LLFloaterMemLeak::onClickStart, this)); + mCommitCallbackRegistrar.add("MemLeak.Stop", boost::bind(&LLFloaterMemLeak::onClickStop, this)); + mCommitCallbackRegistrar.add("MemLeak.Release", boost::bind(&LLFloaterMemLeak::onClickRelease, this)); + mCommitCallbackRegistrar.add("MemLeak.Close", boost::bind(&LLFloaterMemLeak::onClickClose, this)); } +//---------------------------------------------- +BOOL LLFloaterMemLeak::postBuild(void) +{ + F32 a, b ; + a = childGetValue("leak_speed").asReal(); + if(a > (F32)(0xFFFFFFFF)) + { + sMemLeakingSpeed = 0xFFFFFFFF ; + } + else + { + sMemLeakingSpeed = (U32)a ; + } + b = childGetValue("max_leak").asReal(); + if(b > (F32)0xFFF) + { + sMaxLeakedMem = 0xFFFFFFFF ; + } + else + { + sMaxLeakedMem = ((U32)b) << 20 ; + } + + sbAllocationFailed = FALSE ; + return TRUE ; +} LLFloaterMemLeak::~LLFloaterMemLeak() { release() ; sMemLeakingSpeed = 0 ; //bytes leaked per frame sMaxLeakedMem = 0 ; //maximum allowed leaked memory - sInstance = NULL ; } void LLFloaterMemLeak::release() @@ -117,79 +147,56 @@ void LLFloaterMemLeak::idle() } //---------------------- -void LLFloaterMemLeak::onChangeLeakingSpeed(LLUICtrl* ctrl, void* userData) +void LLFloaterMemLeak::onChangeLeakingSpeed() { - LLFloaterMemLeak *mem_leak = (LLFloaterMemLeak *)userData; - if (mem_leak) - { - F32 tmp ; - tmp = mem_leak->childGetValue("leak_speed").asReal(); + F32 tmp ; + tmp =childGetValue("leak_speed").asReal(); - if(tmp > (F32)0xFFFFFFFF) - { - sMemLeakingSpeed = 0xFFFFFFFF ; - } - else - { - sMemLeakingSpeed = (U32)tmp ; - } + if(tmp > (F32)0xFFFFFFFF) + { + sMemLeakingSpeed = 0xFFFFFFFF ; } + else + { + sMemLeakingSpeed = (U32)tmp ; + } + } -void LLFloaterMemLeak::onChangeMaxMemLeaking(LLUICtrl* ctrl, void* userData) +void LLFloaterMemLeak::onChangeMaxMemLeaking() { - LLFloaterMemLeak *mem_leak = (LLFloaterMemLeak *)userData; - if (mem_leak) + + F32 tmp ; + tmp =childGetValue("max_leak").asReal(); + if(tmp > (F32)0xFFF) { - F32 tmp ; - tmp = mem_leak->childGetValue("max_leak").asReal(); - if(tmp > (F32)0xFFF) - { - sMaxLeakedMem = 0xFFFFFFFF ; - } - else - { - sMaxLeakedMem = ((U32)tmp) << 20 ; - } + sMaxLeakedMem = 0xFFFFFFFF ; } + else + { + sMaxLeakedMem = ((U32)tmp) << 20 ; + } + } -void LLFloaterMemLeak::onClickStart(void* userData) +void LLFloaterMemLeak::onClickStart() { sStatus = START ; } -void LLFloaterMemLeak::onClickStop(void* userData) +void LLFloaterMemLeak::onClickStop() { sStatus = STOP ; } -void LLFloaterMemLeak::onClickRelease(void* userData) +void LLFloaterMemLeak::onClickRelease() { sStatus = RELEASE ; } -void LLFloaterMemLeak::onClickClose(void* userData) -{ - if (sInstance) - { - sInstance->setVisible(FALSE); - } -} - -//---------------------------------------------- - -BOOL LLFloaterMemLeak::postBuild(void) +void LLFloaterMemLeak::onClickClose() { - childSetCommitCallback("leak_speed", onChangeLeakingSpeed, this); - childSetCommitCallback("max_leak", onChangeMaxMemLeaking, this); - - childSetAction("start_btn", onClickStart, this); - childSetAction("stop_btn", onClickStop, this); - childSetAction("release_btn", onClickRelease, this); - childSetAction("close_btn", onClickClose, this); - - return TRUE ; + setVisible(FALSE); } void LLFloaterMemLeak::draw() @@ -219,50 +226,3 @@ void LLFloaterMemLeak::draw() LLFloater::draw(); } - -// static instance of it -LLFloaterMemLeak* LLFloaterMemLeak::instance() -{ - if (!sInstance) - { - sInstance = new LLFloaterMemLeak(); - LLUICtrlFactory::getInstance()->buildFloater(sInstance, "floater_mem_leaking.xml", FALSE); - - if(sInstance) - { - F32 a, b ; - a = sInstance->childGetValue("leak_speed").asReal(); - if(a > (F32)(0xFFFFFFFF)) - { - sMemLeakingSpeed = 0xFFFFFFFF ; - } - else - { - sMemLeakingSpeed = (U32)a ; - } - b = sInstance->childGetValue("max_leak").asReal(); - if(b > (F32)0xFFF) - { - sMaxLeakedMem = 0xFFFFFFFF ; - } - else - { - sMaxLeakedMem = ((U32)b) << 20 ; - } - - sbAllocationFailed = FALSE ; - } - } - return sInstance ; -} - -void LLFloaterMemLeak::show(void*) -{ - instance()->openFloater(); -} - -LLFloaterMemLeak* LLFloaterMemLeak::getInstance() -{ - return sInstance ; -} - diff --git a/indra/newview/llfloatermemleak.h b/indra/newview/llfloatermemleak.h index 7d9d5f9c5f..763af943ba 100644 --- a/indra/newview/llfloatermemleak.h +++ b/indra/newview/llfloatermemleak.h @@ -37,34 +37,28 @@ class LLFloaterMemLeak : public LLFloater { + friend class LLFloaterReg; public: - LLFloaterMemLeak(); - virtual ~LLFloaterMemLeak(); - /// initialize all the callbacks for the menu - //void initCallbacks(void); + virtual BOOL postBuild() ; virtual void draw() ; - - /// one and one instance only - static LLFloaterMemLeak* instance(); - static void onChangeLeakingSpeed(LLUICtrl* ctrl, void* userData); - static void onChangeMaxMemLeaking(LLUICtrl* ctrl, void* userData); - static void onClickStart(void* userData); - static void onClickStop(void* userData); - static void onClickRelease(void* userData); - static void onClickClose(void* userData); - - /// show off our menu - static void show(void*); + void onChangeLeakingSpeed(); + void onChangeMaxMemLeaking(); + void onClickStart(); + void onClickStop(); + void onClickRelease(); + void onClickClose(); public: - static LLFloaterMemLeak* getInstance() ; void idle() ; void stop() ; private: + + LLFloaterMemLeak(const LLSD& key); + virtual ~LLFloaterMemLeak(); void release() ; private: @@ -75,9 +69,6 @@ private: START } ; - // one instance on the inside - static LLFloaterMemLeak* sInstance; - static U32 sMemLeakingSpeed ; //bytes leaked per frame static U32 sMaxLeakedMem ; //maximum allowed leaked memory static U32 sTotalLeaked ; diff --git a/indra/newview/llfloaternotificationsconsole.cpp b/indra/newview/llfloaternotificationsconsole.cpp index 3d5d2b733f..f06af5ca1e 100644 --- a/indra/newview/llfloaternotificationsconsole.cpp +++ b/indra/newview/llfloaternotificationsconsole.cpp @@ -161,7 +161,7 @@ bool LLNotificationChannelPanel::update(const LLSD& payload, bool passed_filter) // LLFloaterNotificationConsole // LLFloaterNotificationConsole::LLFloaterNotificationConsole(const LLSD& key) -: LLFloater() +: LLFloater(key) { mCommitCallbackRegistrar.add("ClickAdd", boost::bind(&LLFloaterNotificationConsole::onClickAdd, this)); diff --git a/indra/newview/llfloaternotificationsconsole.h b/indra/newview/llfloaternotificationsconsole.h index b85437c3c5..fe161e66f0 100644 --- a/indra/newview/llfloaternotificationsconsole.h +++ b/indra/newview/llfloaternotificationsconsole.h @@ -38,11 +38,11 @@ #include "llnotifications.h" class LLFloaterNotificationConsole : - public LLFloater, - public LLFloaterSingleton<LLFloaterNotificationConsole> + public LLFloater { + friend class LLFloaterReg; + public: - LLFloaterNotificationConsole(const LLSD& key); // LLPanel BOOL postBuild(); @@ -55,6 +55,7 @@ public: void updateResizeLimits(); private: + LLFloaterNotificationConsole(const LLSD& key); void onClickAdd(); }; diff --git a/indra/newview/llfloateropenobject.cpp b/indra/newview/llfloateropenobject.cpp index 4d782a1814..09460e41ad 100644 --- a/indra/newview/llfloateropenobject.cpp +++ b/indra/newview/llfloateropenobject.cpp @@ -46,9 +46,10 @@ #include "llagent.h" // for agent id #include "llalertdialog.h" #include "llinventorybridge.h" -#include "llinventoryview.h" +#include "llfloaterinventory.h" #include "llinventorymodel.h" #include "llpanelinventory.h" +#include "llfloaterreg.h" #include "llselectmgr.h" #include "lluiconstants.h" #include "llviewerobject.h" @@ -56,29 +57,44 @@ #include "llviewerwindow.h" -LLFloaterOpenObject* LLFloaterOpenObject::sInstance = NULL; - -LLFloaterOpenObject::LLFloaterOpenObject() -: LLFloater(), +LLFloaterOpenObject::LLFloaterOpenObject(const LLSD& key) +: LLFloater(key), mPanelInventory(NULL), mDirty(TRUE) { - LLUICtrlFactory::getInstance()->buildFloater(this,"floater_openobject.xml"); +// LLUICtrlFactory::getInstance()->buildFloater(this,"floater_openobject.xml"); + mCommitCallbackRegistrar.add("OpenObject.MoveToInventory", boost::bind(&LLFloaterOpenObject::onClickMoveToInventory, this)); + mCommitCallbackRegistrar.add("OpenObject.MoveAndWear", boost::bind(&LLFloaterOpenObject::onClickMoveAndWear, this)); } LLFloaterOpenObject::~LLFloaterOpenObject() { - sInstance = NULL; +// sInstance = NULL; } // virtual BOOL LLFloaterOpenObject::postBuild() { - childSetAction("copy_to_inventory_button", onClickMoveToInventory, this); - childSetAction("copy_and_wear_button", onClickMoveAndWear, this); + mObjectSelection = LLSelectMgr::getInstance()->getEditSelection(); childSetTextArg("object_name", "[DESC]", std::string("Object") ); // *Note: probably do not want to translate this mPanelInventory = getChild<LLPanelInventory>("object_contents"); return TRUE; } + +void LLFloaterOpenObject::onOpen(const LLSD& key) +{ + LLObjectSelectionHandle object_selection = LLSelectMgr::getInstance()->getSelection(); + if (object_selection->getRootObjectCount() != 1) + { + LLNotifications::instance().add("UnableToViewContentsMoreThanOne"); + closeFloater(); + return; + } + if(!(object_selection->getPrimaryObject())) + { + closeFloater(); + return; + } +} void LLFloaterOpenObject::refresh() { mPanelInventory->refresh(); @@ -99,7 +115,6 @@ void LLFloaterOpenObject::refresh() } childSetTextArg("object_name", "[DESC]", name); - childSetEnabled("copy_to_inventory_button", enabled); childSetEnabled("copy_and_wear_button", enabled); @@ -115,34 +130,11 @@ void LLFloaterOpenObject::draw() LLFloater::draw(); } -// static void LLFloaterOpenObject::dirty() { - if (sInstance) sInstance->mDirty = TRUE; + mDirty = TRUE; } -// static -void LLFloaterOpenObject::show() -{ - LLObjectSelectionHandle object_selection = LLSelectMgr::getInstance()->getSelection(); - if (object_selection->getRootObjectCount() != 1) - { - LLNotifications::instance().add("UnableToViewContentsMoreThanOne"); - return; - } - - // Create a new instance only if needed - if (!sInstance) - { - sInstance = new LLFloaterOpenObject(); - sInstance->center(); - } - - sInstance->openFloater(); - sInstance->setFocus(TRUE); - - sInstance->mObjectSelection = LLSelectMgr::getInstance()->getEditSelection(); -} void LLFloaterOpenObject::moveToInventory(bool wear) @@ -170,7 +162,7 @@ void LLFloaterOpenObject::moveToInventory(bool wear) } else { - parent_category_id = gAgent.getInventoryRootID(); + parent_category_id = gInventory.getRootFolderID(); } LLUUID category_id = gInventory.createNewCategory(parent_category_id, LLAssetType::AT_NONE, @@ -201,8 +193,8 @@ void LLFloaterOpenObject::callbackMoveInventory(S32 result, void* data) if (result == 0) { - LLInventoryView::showAgentInventory(); - LLInventoryView* view = LLInventoryView::getActiveInventory(); + LLFloaterInventory::showAgentInventory(); + LLFloaterInventory* view = LLFloaterInventory::getActiveInventory(); if (view) { view->getPanel()->setSelection(cat->mCatID, TAKE_FOCUS_NO); @@ -212,20 +204,15 @@ void LLFloaterOpenObject::callbackMoveInventory(S32 result, void* data) delete cat; } - -// static -void LLFloaterOpenObject::onClickMoveToInventory(void* data) +void LLFloaterOpenObject::onClickMoveToInventory() { - LLFloaterOpenObject* self = (LLFloaterOpenObject*)data; - self->moveToInventory(false); - self->closeFloater(); + moveToInventory(false); + closeFloater(); } -// static -void LLFloaterOpenObject::onClickMoveAndWear(void* data) +void LLFloaterOpenObject::onClickMoveAndWear() { - LLFloaterOpenObject* self = (LLFloaterOpenObject*)data; - self->moveToInventory(true); - self->closeFloater(); + moveToInventory(true); + closeFloater(); } diff --git a/indra/newview/llfloateropenobject.h b/indra/newview/llfloateropenobject.h index 0097a85690..0df3780ac4 100644 --- a/indra/newview/llfloateropenobject.h +++ b/indra/newview/llfloateropenobject.h @@ -46,9 +46,10 @@ class LLPanelInventory; class LLFloaterOpenObject : public LLFloater { + friend class LLFloaterReg; public: - static void show(); - static void dirty(); + + void dirty(); struct LLCatAndWear { @@ -57,20 +58,25 @@ public: }; protected: - LLFloaterOpenObject(); - ~LLFloaterOpenObject(); + /*virtual*/ BOOL postBuild(); void refresh(); void draw(); + virtual void onOpen(const LLSD& key); +// virtual void onClose(); void moveToInventory(bool wear); - static void onClickMoveToInventory(void* data); - static void onClickMoveAndWear(void* data); + void onClickMoveToInventory(); + void onClickMoveAndWear(); static void callbackMoveInventory(S32 result, void* data); +private: + + LLFloaterOpenObject(const LLSD& key); + ~LLFloaterOpenObject(); + protected: - static LLFloaterOpenObject* sInstance; LLPanelInventory* mPanelInventory; LLSafeHandle<LLObjectSelection> mObjectSelection; diff --git a/indra/newview/llfloaterperms.cpp b/indra/newview/llfloaterperms.cpp index 1ef71a9d53..c4f1ebe8aa 100644 --- a/indra/newview/llfloaterperms.cpp +++ b/indra/newview/llfloaterperms.cpp @@ -42,51 +42,44 @@ LLFloaterPerms::LLFloaterPerms(const LLSD& seed) -: LLFloater() +: LLFloater(seed) { - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_perm_prefs.xml"); + //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_perm_prefs.xml"); + mCommitCallbackRegistrar.add("Perms.Copy", boost::bind(&LLFloaterPerms::onCommitCopy, this)); + mCommitCallbackRegistrar.add("Perms.OK", boost::bind(&LLFloaterPerms::onClickOK, this)); + mCommitCallbackRegistrar.add("Perms.Cancel", boost::bind(&LLFloaterPerms::onClickCancel, this)); + } BOOL LLFloaterPerms::postBuild() { - childSetEnabled("next_owner_transfer", gSavedSettings.getBOOL("NextOwnerCopy")); - childSetAction("help", onClickHelp, this); - childSetAction("ok", onClickOK, this); - childSetAction("cancel", onClickCancel, this); - childSetCommitCallback("next_owner_copy", &onCommitCopy, this); refresh(); return TRUE; } -//static -void LLFloaterPerms::onClickOK(void* data) +void LLFloaterPerms::onClickOK() { - LLFloaterPerms* self = static_cast<LLFloaterPerms*>(data); - self->ok(); - self->closeFloater(); + ok(); + closeFloater(); } -//static -void LLFloaterPerms::onClickCancel(void* data) +void LLFloaterPerms::onClickCancel() { - LLFloaterPerms* self = static_cast<LLFloaterPerms*>(data); - self->cancel(); - self->closeFloater(); + cancel(); + closeFloater(); } -//static -void LLFloaterPerms::onCommitCopy(LLUICtrl* ctrl, void* data) +void LLFloaterPerms::onCommitCopy() { - LLFloaterPerms* self = static_cast<LLFloaterPerms*>(data); // Implements fair use BOOL copyable = gSavedSettings.getBOOL("NextOwnerCopy"); if(!copyable) { gSavedSettings.setBOOL("NextOwnerTransfer", TRUE); } - LLCheckBoxCtrl* xfer = self->getChild<LLCheckBoxCtrl>("next_owner_transfer"); + LLCheckBoxCtrl* xfer = getChild<LLCheckBoxCtrl>("next_owner_transfer"); xfer->setEnabled(copyable); } @@ -152,9 +145,3 @@ U32 LLFloaterPerms::getNextOwnerPerms(std::string prefix) return flags; } - -//static -void LLFloaterPerms::onClickHelp(void* data) -{ - LLNotifications::instance().add("ClickUploadHelpPermissions"); -} diff --git a/indra/newview/llfloaterperms.h b/indra/newview/llfloaterperms.h index 805039efe4..a1897a5c00 100644 --- a/indra/newview/llfloaterperms.h +++ b/indra/newview/llfloaterperms.h @@ -36,18 +36,18 @@ #include "llfloater.h" -class LLFloaterPerms : public LLFloater, public LLFloaterSingleton<LLFloaterPerms> +class LLFloaterPerms : public LLFloater { - friend class LLUISingleton<LLFloaterPerms, VisibilityPolicy<LLFloater> >; + friend class LLFloaterReg; public: /*virtual*/ void onClose(bool app_quitting = false); /*virtual*/ BOOL postBuild(); void ok(); void cancel(); - static void onClickOK(void*); - static void onClickCancel(void*); - static void onCommitCopy(LLUICtrl* ctrl, void* data); + void onClickOK(); + void onClickCancel(); + void onCommitCopy(); // Convenience methods to get current permission preference bitfields from saved settings: static U32 getEveryonePerms(std::string prefix=""); // prefix + "EveryoneCopy" static U32 getGroupPerms(std::string prefix=""); // prefix + "ShareWithGroup" @@ -57,9 +57,6 @@ private: LLFloaterPerms(const LLSD& seed); void refresh(); - /// callback for the menus help button - static void onClickHelp(void* data); - BOOL // cached values only for implementing cancel. mShareWithGroup, mEveryoneCopy, diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index 57a3bf9445..99c1414461 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -58,6 +58,7 @@ #include "llfloatergodtools.h" // for send_sim_wide_deletes() #include "llfloatertopobjects.h" // added to fix SL-32336 #include "llfloatergroups.h" +#include "llfloaterreg.h" #include "llfloatertelehub.h" #include "llfloaterwindlight.h" #include "llinventorymodel.h" @@ -164,9 +165,9 @@ bool estate_dispatch_initialized = false; LLUUID LLFloaterRegionInfo::sRequestInvoice; LLFloaterRegionInfo::LLFloaterRegionInfo(const LLSD& seed) - : LLFloater() + : LLFloater(seed) { - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_region_info.xml", FALSE); + //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_region_info.xml", FALSE); } BOOL LLFloaterRegionInfo::postBuild() @@ -247,7 +248,8 @@ void LLFloaterRegionInfo::requestRegionInfo() void LLFloaterRegionInfo::processEstateOwnerRequest(LLMessageSystem* msg,void**) { static LLDispatcher dispatch; - if(!findInstance()) + LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance<LLFloaterRegionInfo>("region_info"); + if(!floater) { return; } @@ -257,7 +259,7 @@ void LLFloaterRegionInfo::processEstateOwnerRequest(LLMessageSystem* msg,void**) LLPanelEstateInfo::initDispatch(dispatch); } - LLTabContainer* tab = findInstance()->getChild<LLTabContainer>("region_panels"); + LLTabContainer* tab = floater->getChild<LLTabContainer>("region_panels"); LLPanelEstateInfo* panel = (LLPanelEstateInfo*)tab->getChild<LLPanel>("Estate"); // unpack the message @@ -283,14 +285,14 @@ void LLFloaterRegionInfo::processEstateOwnerRequest(LLMessageSystem* msg,void**) void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg) { LLPanel* panel; - + LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance<LLFloaterRegionInfo>("region_info"); llinfos << "LLFloaterRegionInfo::processRegionInfo" << llendl; - if(!findInstance()) + if(!floater) { return; } - LLTabContainer* tab = findInstance()->getChild<LLTabContainer>("region_panels"); + LLTabContainer* tab = floater->getChild<LLTabContainer>("region_panels"); LLViewerRegion* region = gAgent.getRegion(); BOOL allow_modify = gAgent.isGodlike() || (region && region->canManageEstate()); @@ -377,13 +379,13 @@ void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg) panel->childSetEnabled("sun_hour_slider", allow_modify && !use_estate_sun); panel->setCtrlsEnabled(allow_modify); - getInstance()->refreshFromRegion( gAgent.getRegion() ); + floater->refreshFromRegion( gAgent.getRegion() ); } // static LLPanelEstateInfo* LLFloaterRegionInfo::getPanelEstate() { - LLFloaterRegionInfo* floater = LLFloaterRegionInfo::getInstance(); + LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance<LLFloaterRegionInfo>("region_info"); if (!floater) return NULL; LLTabContainer* tab = floater->getChild<LLTabContainer>("region_panels"); LLPanelEstateInfo* panel = (LLPanelEstateInfo*)tab->getChild<LLPanel>("Estate"); @@ -393,7 +395,7 @@ LLPanelEstateInfo* LLFloaterRegionInfo::getPanelEstate() // static LLPanelEstateCovenant* LLFloaterRegionInfo::getPanelCovenant() { - LLFloaterRegionInfo* floater = LLFloaterRegionInfo::getInstance(); + LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance<LLFloaterRegionInfo>("region_info"); if (!floater) return NULL; LLTabContainer* tab = floater->getChild<LLTabContainer>("region_panels"); LLPanelEstateCovenant* panel = (LLPanelEstateCovenant*)tab->getChild<LLPanel>("Covenant"); @@ -611,7 +613,8 @@ BOOL LLPanelRegionGeneralInfo::postBuild() childSetAction("kick_btn", onClickKick, this); childSetAction("kick_all_btn", onClickKickAll, this); childSetAction("im_btn", onClickMessage, this); - childSetAction("manage_telehub_btn", onClickManageTelehub, this); +// childSetAction("manage_telehub_btn", onClickManageTelehub, this); + mCommitCallbackRegistrar.add("RegionInfo.Cancel", boost::bind(&LLPanelRegionGeneralInfo::onClickManageTelehub, this)); return LLPanelRegionInfo::postBuild(); } @@ -719,11 +722,9 @@ bool LLPanelRegionGeneralInfo::onMessageCommit(const LLSD& notification, const L return false; } -// static -void LLPanelRegionGeneralInfo::onClickManageTelehub(void* data) +void LLPanelRegionGeneralInfo::onClickManageTelehub() { - LLFloaterRegionInfo::getInstance()->closeFloater(); - + LLFloaterReg::getInstance("region_info")->closeFloater(); LLFloaterTelehub::show(); } @@ -958,8 +959,10 @@ void LLPanelRegionDebugInfo::onClickTopColliders(void* data) strings_t strings; strings.push_back("1"); // one physics step LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); - LLFloaterTopObjects::show(); - LLFloaterTopObjects::clearList(); + LLFloaterTopObjects* instance = LLFloaterReg::getTypedInstance<LLFloaterTopObjects>("top_objects"); + if(!instance) return; + LLFloaterReg::showInstance("top_objects"); + instance->clearList(); self->sendEstateOwnerMessage(gMessageSystem, "colliders", invoice, strings); } @@ -970,8 +973,10 @@ void LLPanelRegionDebugInfo::onClickTopScripts(void* data) strings_t strings; strings.push_back("6"); // top 5 scripts LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); - LLFloaterTopObjects::show(); - LLFloaterTopObjects::clearList(); + LLFloaterTopObjects* instance = LLFloaterReg::getTypedInstance<LLFloaterTopObjects>("top_objects"); + if(!instance) return; + LLFloaterReg::showInstance("top_objects"); + instance->clearList(); self->sendEstateOwnerMessage(gMessageSystem, "scripts", invoice, strings); } @@ -1254,7 +1259,7 @@ BOOL LLPanelRegionTerrainInfo::sendUpdate() // Grab estate information in case the user decided to set the // region back to estate time. JC - LLFloaterRegionInfo* floater = LLFloaterRegionInfo::getInstance(); + LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance<LLFloaterRegionInfo>("region_info"); if (!floater) return true; LLTabContainer* tab = floater->getChild<LLTabContainer>("region_panels"); diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h index b3a1fcb7ca..be4becf7e7 100644 --- a/indra/newview/llfloaterregioninfo.h +++ b/indra/newview/llfloaterregioninfo.h @@ -59,11 +59,11 @@ class LLPanelRegionTerrainInfo; class LLPanelEstateInfo; class LLPanelEstateCovenant; -class LLFloaterRegionInfo : public LLFloater, public LLFloaterSingleton<LLFloaterRegionInfo> +class LLFloaterRegionInfo : public LLFloater { - friend class LLUISingleton<LLFloaterRegionInfo, VisibilityPolicy<LLFloater> >; + friend class LLFloaterReg; public: - ~LLFloaterRegionInfo(); + /*virtual*/ void onOpen(const LLSD& key); /*virtual*/ BOOL postBuild(); @@ -86,8 +86,12 @@ public: void requestRegionInfo(); -protected: +private: + LLFloaterRegionInfo(const LLSD& seed); + ~LLFloaterRegionInfo(); + +protected: void refreshFromRegion(LLViewerRegion* region); // member data @@ -166,7 +170,7 @@ protected: bool onKickAllCommit(const LLSD& notification, const LLSD& response); static void onClickMessage(void* userdata); bool onMessageCommit(const LLSD& notification, const LLSD& response); - static void onClickManageTelehub(void* data); + void onClickManageTelehub(); }; ///////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp index 4b175cdc27..513a6a06b1 100644 --- a/indra/newview/llfloaterreporter.cpp +++ b/indra/newview/llfloaterreporter.cpp @@ -53,7 +53,7 @@ #include "llagent.h" #include "llbutton.h" #include "llcheckboxctrl.h" -#include "llinventoryview.h" +#include "llfloaterinventory.h" #include "lllineeditor.h" #include "lltexturectrl.h" #include "llscrolllistctrl.h" diff --git a/indra/newview/llfloatersettingsdebug.h b/indra/newview/llfloatersettingsdebug.h index 87833793af..e7dda3a5f4 100644 --- a/indra/newview/llfloatersettingsdebug.h +++ b/indra/newview/llfloatersettingsdebug.h @@ -38,14 +38,11 @@ #include "lltexteditor.h" class LLFloaterSettingsDebug -: public LLFloater, - public LLFloaterSingleton<LLFloaterSettingsDebug> +: public LLFloater { + friend class LLFloaterReg; + public: - // key - selects which settings to show, one of: - // "all", "base", "account", "skin" - LLFloaterSettingsDebug(const LLSD& key); - virtual ~LLFloaterSettingsDebug(); virtual BOOL postBuild(); virtual void draw(); @@ -56,6 +53,12 @@ public: void onCommitSettings(); void onClickDefault(); +private: + // key - selects which settings to show, one of: + // "all", "base", "account", "skin" + LLFloaterSettingsDebug(const LLSD& key); + virtual ~LLFloaterSettingsDebug(); + protected: LLTextEditor* mComment; }; diff --git a/indra/newview/llfloatertestlistview.cpp b/indra/newview/llfloatertestlistview.cpp new file mode 100644 index 0000000000..f7a327c088 --- /dev/null +++ b/indra/newview/llfloatertestlistview.cpp @@ -0,0 +1,77 @@ +/** +* @file llfloatertestlistview.cpp +* @brief Tests of programmatic manipulation of LLListView widgets +* +* $LicenseInfo:firstyear=2009&license=viewergpl$ +* +* Copyright (c) 2009, Linden Research, Inc. +* +* Second Life Viewer Source Code +* The source code in this file ("Source Code") is provided by Linden Lab +* to you under the terms of the GNU General Public License, version 2.0 +* ("GPL"), unless you have obtained a separate licensing agreement +* ("Other License"), formally executed by you and Linden Lab. Terms of +* the GPL can be found in doc/GPL-license.txt in this distribution, or +* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 +* +* There are special exceptions to the terms and conditions of the GPL as +* it is applied to this Source Code. View the full text of the exception +* in the file doc/FLOSS-exception.txt in this software distribution, or +* online at +* http://secondlifegrid.net/programs/open_source/licensing/flossexception +* +* By copying, modifying or distributing this software, you acknowledge +* that you have read and understood your obligations described above, +* and agree to abide by those obligations. +* +* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO +* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +* COMPLETENESS OR PERFORMANCE. +* $/LicenseInfo$ +*/ +#include "llviewerprecompiledheaders.h" + +#include "llfloatertestlistview.h" + +// Viewer includes +#include "lllistview.h" + +// Linden library includes +//#include "lluictrlfactory.h" + +LLFloaterTestListView::LLFloaterTestListView(const LLSD& seed) +: LLFloater(seed), + mListView(NULL) +{ + // set up named callback functions for test buttons + mCommitCallbackRegistrar.add("TestListView.Test1", + boost::bind(&LLFloaterTestListView::onClickTest1, this)); + mCommitCallbackRegistrar.add("TestListView.Test2", + boost::bind(&LLFloaterTestListView::onClickTest2, this)); +} + +LLFloaterTestListView::~LLFloaterTestListView() +{} + +BOOL LLFloaterTestListView::postBuild() +{ + mListView = getChild<LLListView>("test_list_view"); + // just set a random property + mListView->setString("set programmatically"); + return LLFloater::postBuild(); +} + +void LLFloaterTestListView::onListViewChanged() +{ + llinfos << "JAMESDEBUG list view changed" << llendl; +} + +void LLFloaterTestListView::onClickTest1() +{ + llinfos << "JAMESDEBUG test 1" << llendl; +} + +void LLFloaterTestListView::onClickTest2() +{ + llinfos << "JAMESDEBUG test 2" << llendl; +} diff --git a/indra/newview/llfloatertestlistview.h b/indra/newview/llfloatertestlistview.h new file mode 100644 index 0000000000..053da95def --- /dev/null +++ b/indra/newview/llfloatertestlistview.h @@ -0,0 +1,64 @@ +/** +* @file llfloatertestlistview.h +* @brief Tests of programmatic manipulation of LLListView widgets +* +* $LicenseInfo:firstyear=2009&license=viewergpl$ +* +* Copyright (c) 2009, Linden Research, Inc. +* +* Second Life Viewer Source Code +* The source code in this file ("Source Code") is provided by Linden Lab +* to you under the terms of the GNU General Public License, version 2.0 +* ("GPL"), unless you have obtained a separate licensing agreement +* ("Other License"), formally executed by you and Linden Lab. Terms of +* the GPL can be found in doc/GPL-license.txt in this distribution, or +* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 +* +* There are special exceptions to the terms and conditions of the GPL as +* it is applied to this Source Code. View the full text of the exception +* in the file doc/FLOSS-exception.txt in this software distribution, or +* online at +* http://secondlifegrid.net/programs/open_source/licensing/flossexception +* +* By copying, modifying or distributing this software, you acknowledge +* that you have read and understood your obligations described above, +* and agree to abide by those obligations. +* +* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO +* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +* COMPLETENESS OR PERFORMANCE. +* $/LicenseInfo$ +*/ +#ifndef LLFLOATERTESTLISTVIEW_H +#define LLFLOATERTESTLISTVIEW_H + +#include "llfloater.h" + +class LLListView; +class LLSD; + +class LLFloaterTestListView : public LLFloater +{ + friend class LLFloaterReg; +public: + // nothing yet + +private: + // Construction handled by LLFloaterReg + LLFloaterTestListView(const LLSD& seed); + ~LLFloaterTestListView(); + + /*virtual*/ BOOL postBuild(); + + // Perform some debug action when the list-view sends change notification + void onListViewChanged(); + + // Debug function hookups for buttons + void onClickTest1(); + void onClickTest2(); + +private: + LLListView* mListView; +}; + +#endif diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp index 4bcf470317..4704630147 100644 --- a/indra/newview/llfloatertools.cpp +++ b/indra/newview/llfloatertools.cpp @@ -445,7 +445,8 @@ void LLFloaterTools::draw() void LLFloaterTools::dirty() { mDirty = TRUE; - LLFloaterOpenObject::dirty(); + LLFloaterOpenObject* instance = LLFloaterReg::getTypedInstance<LLFloaterOpenObject>("openobject"); + if (instance) instance->dirty(); } // Clean up any tool state that should not persist when the diff --git a/indra/newview/llfloatertopobjects.cpp b/indra/newview/llfloatertopobjects.cpp index 29ac0c66f8..bf5a1141a6 100644 --- a/indra/newview/llfloatertopobjects.cpp +++ b/indra/newview/llfloatertopobjects.cpp @@ -40,6 +40,7 @@ #include "llagent.h" #include "llbutton.h" #include "llfloatergodtools.h" +#include "llfloaterreg.h" #include "llparcel.h" #include "llscrolllistctrl.h" #include "llscrolllistitem.h" @@ -53,11 +54,11 @@ #include "lluictrlfactory.h" #include "llviewerwindow.h" -LLFloaterTopObjects* LLFloaterTopObjects::sInstance = NULL; +//LLFloaterTopObjects* LLFloaterTopObjects::sInstance = NULL; // Globals // const U32 TIME_STR_LENGTH = 30; - +/* // static void LLFloaterTopObjects::show() { @@ -68,21 +69,28 @@ void LLFloaterTopObjects::show() } sInstance = new LLFloaterTopObjects(); - LLUICtrlFactory::getInstance()->buildFloater(sInstance, "floater_top_objects.xml"); +// LLUICtrlFactory::getInstance()->buildFloater(sInstance, "floater_top_objects.xml"); sInstance->center(); } - -LLFloaterTopObjects::LLFloaterTopObjects() -: LLFloater(), +*/ +LLFloaterTopObjects::LLFloaterTopObjects(const LLSD& key) +: LLFloater(key), mInitialized(FALSE), mtotalScore(0.f) { - sInstance = this; + mCommitCallbackRegistrar.add("TopObjects.ShowBeacon", boost::bind(&LLFloaterTopObjects::onClickShowBeacon, this)); + mCommitCallbackRegistrar.add("TopObjects.ReturnSelected", boost::bind(&LLFloaterTopObjects::onReturnSelected, this)); + mCommitCallbackRegistrar.add("TopObjects.ReturnAll", boost::bind(&LLFloaterTopObjects::onReturnAll, this)); + mCommitCallbackRegistrar.add("TopObjects.DisableSelected", boost::bind(&LLFloaterTopObjects::onDisableSelected, this)); + mCommitCallbackRegistrar.add("TopObjects.DisableAll", boost::bind(&LLFloaterTopObjects::onDisableAll, this)); + mCommitCallbackRegistrar.add("TopObjects.Refresh", boost::bind(&LLFloaterTopObjects::onRefresh, this)); + mCommitCallbackRegistrar.add("TopObjects.GetByObjectName", boost::bind(&LLFloaterTopObjects::onGetByObjectName, this)); + mCommitCallbackRegistrar.add("TopObjects.GetByOwnerName", boost::bind(&LLFloaterTopObjects::onGetByOwnerName, this)); + mCommitCallbackRegistrar.add("TopObjects.CommitObjectsList",boost::bind(&LLFloaterTopObjects::onCommitObjectsList, this)); } LLFloaterTopObjects::~LLFloaterTopObjects() { - sInstance = NULL; } // virtual @@ -90,24 +98,11 @@ BOOL LLFloaterTopObjects::postBuild() { LLScrollListCtrl *objects_list = getChild<LLScrollListCtrl>("objects_list"); childSetFocus("objects_list"); - childSetCommitCallback("objects_list", onCommitObjectsList, this); objects_list->setDoubleClickCallback(onDoubleClickObjectsList, this); objects_list->setCommitOnSelectionChange(TRUE); - childSetAction("show_beacon_btn", onClickShowBeacon, this); setDefaultBtn("show_beacon_btn"); - childSetAction("return_selected_btn", onReturnSelected, this); - childSetAction("return_all_btn", onReturnAll, this); - childSetAction("disable_selected_btn", onDisableSelected, this); - childSetAction("disable_all_btn", onDisableAll, this); - childSetAction("refresh_btn", onRefresh, this); - - - childSetAction("filter_object_btn", onGetByObjectNameClicked, this); - childSetAction("filter_owner_btn", onGetByOwnerNameClicked, this); - - /* LLLineEditor* line_editor = getChild<LLLineEditor>("owner_name_editor"); if (line_editor) @@ -129,19 +124,29 @@ BOOL LLFloaterTopObjects::postBuild() return TRUE; } +// static +void LLFloaterTopObjects::setMode(U32 mode) +{ + LLFloaterTopObjects* instance = LLFloaterReg::getTypedInstance<LLFloaterTopObjects>("top_objects"); + if(!instance) return; + instance->mCurrentMode = mode; +} +// static void LLFloaterTopObjects::handle_land_reply(LLMessageSystem* msg, void** data) { + LLFloaterTopObjects* instance = LLFloaterReg::getTypedInstance<LLFloaterTopObjects>("top_objects"); + if(!instance) return; // Make sure dialog is on screen - show(); - sInstance->handleReply(msg, data); + LLFloaterReg::showInstance("top_objects"); + instance->handleReply(msg, data); //HACK: for some reason sometimes top scripts originally comes back //with no results even though they're there - if (!sInstance->mObjectListIDs.size() && !sInstance->mInitialized) + if (!instance->mObjectListIDs.size() && !instance->mInitialized) { - sInstance->onRefresh(NULL); - sInstance->mInitialized = TRUE; + instance->onRefresh(); + instance->mInitialized = TRUE; } } @@ -260,12 +265,9 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data) } } -// static -void LLFloaterTopObjects::onCommitObjectsList(LLUICtrl* ctrl, void* data) +void LLFloaterTopObjects::onCommitObjectsList() { - LLFloaterTopObjects* self = (LLFloaterTopObjects*)data; - - self->updateSelectionInfo(); + updateSelectionInfo(); } void LLFloaterTopObjects::updateSelectionInfo() @@ -292,11 +294,9 @@ void LLFloaterTopObjects::onDoubleClickObjectsList(void* data) } // static -void LLFloaterTopObjects::onClickShowBeacon(void* data) +void LLFloaterTopObjects::onClickShowBeacon() { - LLFloaterTopObjects* self = (LLFloaterTopObjects*)data; - if (!self) return; - self->showBeacon(); + showBeacon(); } void LLFloaterTopObjects::doToObjects(int action, bool all) @@ -360,22 +360,24 @@ void LLFloaterTopObjects::doToObjects(int action, bool all) bool LLFloaterTopObjects::callbackReturnAll(const LLSD& notification, const LLSD& response) { S32 option = LLNotification::getSelectedOption(notification, response); + LLFloaterTopObjects* instance = LLFloaterReg::getTypedInstance<LLFloaterTopObjects>("top_objects"); + if(!instance) return false; if (option == 0) { - sInstance->doToObjects(ACTION_RETURN, true); + instance->doToObjects(ACTION_RETURN, true); } return false; } -void LLFloaterTopObjects::onReturnAll(void* data) +void LLFloaterTopObjects::onReturnAll() { LLNotifications::instance().add("ReturnAllTopObjects", LLSD(), LLSD(), &callbackReturnAll); } -void LLFloaterTopObjects::onReturnSelected(void* data) +void LLFloaterTopObjects::onReturnSelected() { - sInstance->doToObjects(ACTION_RETURN, false); + doToObjects(ACTION_RETURN, false); } @@ -383,52 +385,52 @@ void LLFloaterTopObjects::onReturnSelected(void* data) bool LLFloaterTopObjects::callbackDisableAll(const LLSD& notification, const LLSD& response) { S32 option = LLNotification::getSelectedOption(notification, response); + LLFloaterTopObjects* instance = LLFloaterReg::getTypedInstance<LLFloaterTopObjects>("top_objects"); + if(!instance) return false; if (option == 0) { - sInstance->doToObjects(ACTION_DISABLE, true); + instance->doToObjects(ACTION_DISABLE, true); } return false; } -void LLFloaterTopObjects::onDisableAll(void* data) +void LLFloaterTopObjects::onDisableAll() { LLNotifications::instance().add("DisableAllTopObjects", LLSD(), LLSD(), callbackDisableAll); } -void LLFloaterTopObjects::onDisableSelected(void* data) +void LLFloaterTopObjects::onDisableSelected() { - sInstance->doToObjects(ACTION_DISABLE, false); + doToObjects(ACTION_DISABLE, false); } -//static + void LLFloaterTopObjects::clearList() { - LLCtrlListInterface *list = sInstance->childGetListInterface("objects_list"); + LLCtrlListInterface *list = childGetListInterface("objects_list"); if (list) { list->operateOnAll(LLCtrlListInterface::OP_DELETE); } - sInstance->mObjectListData.clear(); - sInstance->mObjectListIDs.clear(); - sInstance->mtotalScore = 0.f; + mObjectListData.clear(); + mObjectListIDs.clear(); + mtotalScore = 0.f; } -//static -void LLFloaterTopObjects::onRefresh(void* data) + +void LLFloaterTopObjects::onRefresh() { U32 mode = STAT_REPORT_TOP_SCRIPTS; U32 flags = 0; std::string filter = ""; - if (sInstance) - { - mode = sInstance->mCurrentMode; - flags = sInstance->mFlags; - filter = sInstance->mFilter; - sInstance->clearList(); - } + mode = mCurrentMode; + flags = mFlags; + filter = mFilter; + clearList(); + LLMessageSystem *msg = gMessageSystem; msg->newMessageFast(_PREHASH_LandStatRequest); @@ -443,31 +445,22 @@ void LLFloaterTopObjects::onRefresh(void* data) msg->sendReliable(gAgent.getRegionHost()); - if (sInstance) - { - sInstance->mFilter.clear(); - sInstance->mFlags = 0; - } + mFilter.clear(); + mFlags = 0; } -void LLFloaterTopObjects::onGetByObjectName(LLUICtrl* ctrl, void* data) +void LLFloaterTopObjects::onGetByObjectName() { - if (sInstance) - { - sInstance->mFlags = STAT_FILTER_BY_OBJECT; - sInstance->mFilter = sInstance->childGetText("object_name_editor"); - onRefresh(NULL); - } + mFlags = STAT_FILTER_BY_OBJECT; + mFilter = childGetText("object_name_editor"); + onRefresh(); } -void LLFloaterTopObjects::onGetByOwnerName(LLUICtrl* ctrl, void* data) +void LLFloaterTopObjects::onGetByOwnerName() { - if (sInstance) - { - sInstance->mFlags = STAT_FILTER_BY_OWNER; - sInstance->mFilter = sInstance->childGetText("owner_name_editor"); - onRefresh(NULL); - } + mFlags = STAT_FILTER_BY_OWNER; + mFilter = childGetText("owner_name_editor"); + onRefresh(); } void LLFloaterTopObjects::showBeacon() diff --git a/indra/newview/llfloatertopobjects.h b/indra/newview/llfloatertopobjects.h index 58cbf5d2ce..ee3c5d3cce 100644 --- a/indra/newview/llfloatertopobjects.h +++ b/indra/newview/llfloatertopobjects.h @@ -39,48 +39,49 @@ class LLUICtrl; class LLFloaterTopObjects : public LLFloater { + friend class LLFloaterReg; public: // Opens the floater on screen. - static void show(); +// static void show(); // Opens the floater if it's not on-screen. // Juggles the UI based on method = "scripts" or "colliders" static void handle_land_reply(LLMessageSystem* msg, void** data); void handleReply(LLMessageSystem* msg, void** data); - static void clearList(); + void clearList(); void updateSelectionInfo(); virtual BOOL postBuild(); - static void onRefresh(void* data); + void onRefresh(); - static void setMode(U32 mode) { if (sInstance) sInstance->mCurrentMode = mode; } + static void setMode(U32 mode); private: - LLFloaterTopObjects(); + LLFloaterTopObjects(const LLSD& key); ~LLFloaterTopObjects(); void initColumns(LLCtrlListInterface *list); - static void onCommitObjectsList(LLUICtrl* ctrl, void* data); + void onCommitObjectsList(); static void onDoubleClickObjectsList(void* data); - static void onClickShowBeacon(void* data); + void onClickShowBeacon(); void doToObjects(int action, bool all); - static void onReturnAll(void* data); - static void onReturnSelected(void* data); - static void onDisableAll(void* data); - static void onDisableSelected(void* data); + void onReturnAll(); + void onReturnSelected(); + void onDisableAll(); + void onDisableSelected(); static bool callbackReturnAll(const LLSD& notification, const LLSD& response); static bool callbackDisableAll(const LLSD& notification, const LLSD& response); - static void onGetByOwnerName(LLUICtrl* ctrl, void* data); - static void onGetByObjectName(LLUICtrl* ctrl, void* data); + void onGetByOwnerName(); + void onGetByObjectName(); - static void onGetByOwnerNameClicked(void* data) { onGetByOwnerName(NULL, data); }; - static void onGetByObjectNameClicked(void* data) { onGetByObjectName(NULL, data); }; +// static void onGetByOwnerNameClicked(void* data) { onGetByOwnerName(NULL, data); }; +// static void onGetByObjectNameClicked(void* data) { onGetByObjectName(NULL, data); }; void showBeacon(); diff --git a/indra/newview/llfloateruipreview.cpp b/indra/newview/llfloateruipreview.cpp index 34db895b52..e7304ea5a9 100644 --- a/indra/newview/llfloateruipreview.cpp +++ b/indra/newview/llfloateruipreview.cpp @@ -264,6 +264,8 @@ BOOL LLFloaterUIPreview::postBuild() main_panel_tmp->getChild<LLButton>("save_floater")->setClickedCallback(onClickSaveFloater, (void*)&PRIMARY_FLOATER); main_panel_tmp->getChild<LLButton>("save_all_floaters")->setClickedCallback(onClickSaveAll, (void*)&PRIMARY_FLOATER); + getChild<LLButton>("export_schema")->setClickedCallback(boost::bind(&LLFloaterUIPreview::onClickExportSchema, this)); + // get pointers to text fields mEditorPathTextBox = editor_panel_tmp->getChild<LLLineEditor>("executable_path_field"); mEditorArgsTextBox = editor_panel_tmp->getChild<LLLineEditor>("executable_args_field"); @@ -354,6 +356,34 @@ void LLFloaterUIPreview::onLanguageComboSelect(LLUICtrl* ctrl) } +void LLFloaterUIPreview::onClickExportSchema() +{ + std::string template_path = gDirUtilp->getExpandedFilename(LL_PATH_DEFAULT_SKIN, "xui", "schema"); + + typedef LLWidgetTypeRegistry::Registrar::registry_map_t::const_iterator registry_it; + registry_it end_it = LLWidgetTypeRegistry::defaultRegistrar().endItems(); + for(registry_it it = LLWidgetTypeRegistry::defaultRegistrar().beginItems(); + it != end_it; + ++it) + { + std::string widget_name = it->first; + const LLInitParam::BaseBlock& block = + (*LLDefaultParamBlockRegistry::instance().getValue(*LLWidgetTypeRegistry::instance().getValue(widget_name)))(); + LLXMLNodePtr root_nodep = new LLXMLNode(); + LLRNGWriter().writeRNG(widget_name, root_nodep, block, "http://www.lindenlab.com/xui"); + + std::string file_name(template_path + gDirUtilp->getDirDelimiter() + widget_name + ".rng"); + + LLFILE* rng_file = LLFile::fopen(file_name.c_str(), "w"); + { + LLXMLNode::writeHeaderToFile(rng_file); + root_nodep->writeToFile(rng_file); + } + fclose(rng_file); + } +} + + // Close click handler -- delete my displayed floater if it exists void LLFloaterUIPreview::onClose(bool app_quitting) { @@ -614,7 +644,7 @@ void LLFloaterUIPreview::displayFloater(BOOL click, S32 ID, bool save) if (save) { LLXMLNodePtr menu_write = new LLXMLNode(); - LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>(path, gMenuHolder, menu_write); + LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>(path, gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance(), menu_write); if (!menu_write->isNull()) { @@ -779,6 +809,10 @@ void LLFloaterUIPreview::onClickEditFloater(void*) { exe_path_char = path_in_textfield.c_str(); } + else if (!LLUI::sSettingGroups["config"]->getString("XUIEditor").empty()) + { + exe_path_char = LLUI::sSettingGroups["config"]->getString("XUIEditor").c_str(); + } else // otherwise use the path specified by the environment variable { exe_path_char = getenv("LL_XUI_EDITOR"); diff --git a/indra/newview/llfloateruipreview.h b/indra/newview/llfloateruipreview.h index b0af841e11..1307d60689 100644 --- a/indra/newview/llfloateruipreview.h +++ b/indra/newview/llfloateruipreview.h @@ -211,6 +211,7 @@ private: static void onClickToggleOverlapping(void*); static void onClickCloseDisplayedFloater(void*); void onLanguageComboSelect(LLUICtrl* ctrl); + void onClickExportSchema(); }; #endif // LL_LLUIPREVIEW_H diff --git a/indra/newview/llfloaterurldisplay.cpp b/indra/newview/llfloaterurldisplay.cpp index 7f7d05e1d2..3b9321a876 100644 --- a/indra/newview/llfloaterurldisplay.cpp +++ b/indra/newview/llfloaterurldisplay.cpp @@ -45,11 +45,10 @@ LLFloaterURLDisplay::LLFloaterURLDisplay(const LLSD& sd) - : LLFloater() + : LLFloater(sd) { mFactoryMap["place_details_panel"] = LLCallbackMap(LLFloaterURLDisplay::createPlaceDetail, this); - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_preview_url.xml"); - this->setVisible(false); +// LLUICtrlFactory::getInstance()->buildFloater(this, "floater_preview_url.xml"); // If positioned at 0,0 the teleport button is behind the toolbar. LLRect r = getRect(); diff --git a/indra/newview/llfloaterurldisplay.h b/indra/newview/llfloaterurldisplay.h index 91c544ae86..22f5a95ad0 100644 --- a/indra/newview/llfloaterurldisplay.h +++ b/indra/newview/llfloaterurldisplay.h @@ -40,11 +40,10 @@ class LLPanelPlace; class LLSD; class LLUUID; -class LLFloaterURLDisplay : public LLFloater, public LLFloaterSingleton<LLFloaterURLDisplay> +class LLFloaterURLDisplay : public LLFloater { + friend class LLFloaterReg; public: - LLFloaterURLDisplay(const LLSD& sd); - virtual ~LLFloaterURLDisplay(); void displayParcelInfo(U64 region_handle, const LLVector3& pos); void setSnapshotDisplay(const LLUUID& snapshot_id); @@ -54,6 +53,9 @@ public: static void* createPlaceDetail(void* userdata); private: + LLFloaterURLDisplay(const LLSD& sd); + virtual ~LLFloaterURLDisplay(); + LLVector3 mRegionPosition; U64 mRegionHandle; LLPanelPlace* mPlacePanel; diff --git a/indra/newview/llfloatervoicedevicesettings.cpp b/indra/newview/llfloatervoicedevicesettings.cpp index 16f4ecef07..0cbeaa591d 100644 --- a/indra/newview/llfloatervoicedevicesettings.cpp +++ b/indra/newview/llfloatervoicedevicesettings.cpp @@ -284,7 +284,7 @@ void LLPanelVoiceDeviceSettings::onCommitOutputDevice(LLUICtrl* ctrl, void* user // LLFloaterVoiceDeviceSettings::LLFloaterVoiceDeviceSettings(const LLSD& seed) - : LLFloater(), + : LLFloater(seed), mDevicePanel(NULL) { mFactoryMap["device_settings"] = LLCallbackMap(createPanelVoiceDeviceSettings, this); diff --git a/indra/newview/llfloatervoicedevicesettings.h b/indra/newview/llfloatervoicedevicesettings.h index 47f41d6d7e..ed8840a9f9 100644 --- a/indra/newview/llfloatervoicedevicesettings.h +++ b/indra/newview/llfloatervoicedevicesettings.h @@ -62,17 +62,21 @@ protected: BOOL mDevicesUpdated; }; -class LLFloaterVoiceDeviceSettings : public LLFloater, public LLFloaterSingleton<LLFloaterVoiceDeviceSettings> +class LLFloaterVoiceDeviceSettings : public LLFloater { + friend class LLFloaterReg; + public: - LLFloaterVoiceDeviceSettings(const LLSD& seed); + virtual BOOL postBuild(); /*virtual*/ void onOpen(const LLSD& key); /*virtual*/ void onClose(bool app_quitting); /*virtual*/ void draw(); void apply(); void cancel(); - +private: + LLFloaterVoiceDeviceSettings(const LLSD& seed); + protected: static void* createPanelVoiceDeviceSettings(void* user_data); diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp index 9711e02f69..d435ec86a2 100644 --- a/indra/newview/llfloaterworldmap.cpp +++ b/indra/newview/llfloaterworldmap.cpp @@ -161,6 +161,16 @@ LLFloaterWorldMap::LLFloaterWorldMap(const LLSD& key) mFactoryMap["terrain_mapview"] = LLCallbackMap(createWorldMapView, NULL); //Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this, "floater_world_map.xml", FALSE); + mCommitCallbackRegistrar.add("WMap.Location", boost::bind(&LLFloaterWorldMap::onLocationCommit, this)); + mCommitCallbackRegistrar.add("WMap.AvatarCombo", boost::bind(&LLFloaterWorldMap::onAvatarComboCommit, this)); + mCommitCallbackRegistrar.add("WMap.SearchResult", boost::bind(&LLFloaterWorldMap::onCommitSearchResult, this)); + mCommitCallbackRegistrar.add("WMap.CommitLocation", boost::bind(&LLFloaterWorldMap::onCommitLocation, this)); + mCommitCallbackRegistrar.add("WMap.GoHome", boost::bind(&LLFloaterWorldMap::onGoHome, this)); + mCommitCallbackRegistrar.add("WMap.Teleport", boost::bind(&LLFloaterWorldMap::onClickTeleportBtn, this)); + mCommitCallbackRegistrar.add("WMap.ShowTarget", boost::bind(&LLFloaterWorldMap::onShowTargetBtn, this)); + mCommitCallbackRegistrar.add("WMap.ShowAgent", boost::bind(&LLFloaterWorldMap::onShowAgentBtn, this)); + mCommitCallbackRegistrar.add("WMap.Clear", boost::bind(&LLFloaterWorldMap::onClearBtn, this)); + mCommitCallbackRegistrar.add("WMap.CopySLURL", boost::bind(&LLFloaterWorldMap::onCopySLURL, this)); } // static @@ -183,8 +193,6 @@ BOOL LLFloaterWorldMap::postBuild() // //onCommitBackground(); - childSetCommitCallback("friend combo", onAvatarComboCommit, this); - LLComboBox *avatar_combo = getChild<LLComboBox>("friend combo"); if (avatar_combo) { @@ -193,8 +201,6 @@ BOOL LLFloaterWorldMap::postBuild() avatar_combo->setTextEntryCallback( boost::bind(&LLFloaterWorldMap::onComboTextEntry, this) ); } - childSetAction("DoSearch", onLocationCommit, this); - getChild<LLScrollListCtrl>("location")->setFocusChangedCallback(boost::bind(&LLFloaterWorldMap::onLocationFocusChanged, this, _1)); LLLineEditor *location_editor = getChild<LLLineEditor>("location"); @@ -203,13 +209,7 @@ BOOL LLFloaterWorldMap::postBuild() location_editor->setKeystrokeCallback( boost::bind(&LLFloaterWorldMap::onSearchTextEntry, this, _1), NULL ); } - childSetCommitCallback("search_results", onCommitSearchResult, this); getChild<LLScrollListCtrl>("search_results")->setDoubleClickCallback(onClickTeleportBtn, this); - childSetCommitCallback("spin x", onCommitLocation, this); - childSetCommitCallback("spin y", onCommitLocation, this); - childSetCommitCallback("spin z", onCommitLocation, this); - - childSetCommitCallback("landmark combo", onLandmarkComboCommit, this); LLComboBox *landmark_combo = getChild<LLComboBox>( "landmark combo"); if (landmark_combo) @@ -219,15 +219,6 @@ BOOL LLFloaterWorldMap::postBuild() landmark_combo->setTextEntryCallback( boost::bind(&LLFloaterWorldMap::onComboTextEntry, this) ); } - childSetAction("Go Home", onGoHome, this); - - childSetAction("Teleport", onClickTeleportBtn, this); - - childSetAction("Show Destination", onShowTargetBtn, this); - childSetAction("Show My Location", onShowAgentBtn, this); - childSetAction("Clear", onClearBtn, this); - childSetAction("copy_slurl", onCopySLURL, this); - mCurZoomVal = log(gMapScale)/log(2.f); childSetValue("zoom slider", gMapScale); @@ -863,7 +854,7 @@ void LLFloaterWorldMap::buildLandmarkIDLists() LLInventoryModel::cat_array_t cats; LLInventoryModel::item_array_t items; LLIsType is_landmark(LLAssetType::AT_LANDMARK); - gInventory.collectDescendentsIf(gAgent.getInventoryRootID(), + gInventory.collectDescendentsIf(gInventory.getRootFolderID(), cats, items, LLInventoryModel::EXCLUDE_TRASH, @@ -1020,8 +1011,7 @@ void LLFloaterWorldMap::onPanBtn( void* userdata ) map_panel->translatePan( pan_x, pan_y ); } -// static -void LLFloaterWorldMap::onGoHome(void*) +void LLFloaterWorldMap::onGoHome() { gAgent.teleportHome(); gFloaterWorldMap->closeFloater(); @@ -1063,8 +1053,8 @@ void LLFloaterWorldMap::onSearchTextEntry( LLLineEditor* ctrl ) updateSearchEnabled(); } -// static -void LLFloaterWorldMap::onLandmarkComboCommit( LLUICtrl* ctrl, void* userdata ) + +void LLFloaterWorldMap::onLandmarkComboCommit() { LLFloaterWorldMap* self = gFloaterWorldMap; @@ -1106,7 +1096,7 @@ void LLFloaterWorldMap::onLandmarkComboCommit( LLUICtrl* ctrl, void* userdata ) } self->trackLandmark( item_id); - onShowTargetBtn(self); + onShowTargetBtn(); // Reset to user postion if nothing is tracked self->mSetToUserPosition = ( LLTracker::getTrackingStatus() == LLTracker::TRACKING_NOTHING ); @@ -1138,9 +1128,7 @@ void LLFloaterWorldMap::onAvatarComboPrearrange( ) } } - -// static -void LLFloaterWorldMap::onAvatarComboCommit( LLUICtrl* ctrl, void* userdata ) +void LLFloaterWorldMap::onAvatarComboCommit() { LLFloaterWorldMap* self = gFloaterWorldMap; if( !self || self->mIsClosing ) @@ -1158,7 +1146,7 @@ void LLFloaterWorldMap::onAvatarComboCommit( LLUICtrl* ctrl, void* userdata ) LLComboBox* combo = gFloaterWorldMap->getChild<LLComboBox>("friend combo"); if (combo) name = combo->getSimple(); self->trackAvatar(new_avatar_id, name); - onShowTargetBtn(self); + onShowTargetBtn(); } else { // Reset to user postion if nothing is tracked @@ -1184,8 +1172,7 @@ void LLFloaterWorldMap::updateSearchEnabled() } } -// static -void LLFloaterWorldMap::onLocationCommit( void* userdata ) +void LLFloaterWorldMap::onLocationCommit() { LLFloaterWorldMap *self = gFloaterWorldMap; if( !self || self->mIsClosing ) @@ -1222,16 +1209,13 @@ void LLFloaterWorldMap::onLocationCommit( void* userdata ) } } - -// static -void LLFloaterWorldMap::onClearBtn(void* data) +void LLFloaterWorldMap::onClearBtn() { - LLFloaterWorldMap* self = (LLFloaterWorldMap*)data; - self->mTrackedStatus = LLTracker::TRACKING_NOTHING; + mTrackedStatus = LLTracker::TRACKING_NOTHING; LLTracker::stopTracking((void *)(intptr_t)TRUE); LLWorldMap::getInstance()->mIsTrackingUnknownLocation = FALSE; - self->mSLURL = ""; // Clear the SLURL since it's invalid - self->mSetToUserPosition = TRUE; // Revert back to the current user position + mSLURL = ""; // Clear the SLURL since it's invalid + mSetToUserPosition = TRUE; // Revert back to the current user position } // static @@ -1241,36 +1225,30 @@ void LLFloaterWorldMap::onFlyBtn(void* data) self->fly(); } -void LLFloaterWorldMap::onShowTargetBtn(void* data) +void LLFloaterWorldMap::onShowTargetBtn() { - LLFloaterWorldMap* self = (LLFloaterWorldMap*)data; - self->centerOnTarget(TRUE); + centerOnTarget(TRUE); } -void LLFloaterWorldMap::onShowAgentBtn(void* data) +void LLFloaterWorldMap::onShowAgentBtn() { LLWorldMapView::setPan( 0, 0, FALSE); // FALSE == animate - // Set flag so user's location will be displayed if not tracking anything else - LLFloaterWorldMap* self = (LLFloaterWorldMap*)data; - self->mSetToUserPosition = TRUE; + mSetToUserPosition = TRUE; } -// static void LLFloaterWorldMap::onClickTeleportBtn(void* data) { LLFloaterWorldMap* self = (LLFloaterWorldMap*)data; self->teleport(); } -// static -void LLFloaterWorldMap::onCopySLURL(void* data) +void LLFloaterWorldMap::onCopySLURL() { - LLFloaterWorldMap* self = (LLFloaterWorldMap*)data; - self->getWindow()->copyTextToClipboard(utf8str_to_wstring(self->mSLURL)); + getWindow()->copyTextToClipboard(utf8str_to_wstring(mSLURL)); LLSD args; - args["SLURL"] = self->mSLURL; + args["SLURL"] = mSLURL; LLNotifications::instance().add("CopySLURL", args); } @@ -1553,13 +1531,13 @@ void LLFloaterWorldMap::updateSims(bool found_null_sim) { mExactMatch = TRUE; childSetFocus("search_results"); - onCommitSearchResult(NULL, this); + onCommitSearchResult(); } else if (!mExactMatch && num_results > 0) { list->selectFirstItem(); // select first item by default childSetFocus("search_results"); - onCommitSearchResult(NULL, this); + onCommitSearchResult(); } else if (num_results == 0) { @@ -1568,30 +1546,25 @@ void LLFloaterWorldMap::updateSims(bool found_null_sim) } } -// static -void LLFloaterWorldMap::onCommitLocation(LLUICtrl* ctrl, void* userdata) +void LLFloaterWorldMap::onCommitLocation() { - LLFloaterWorldMap* self = (LLFloaterWorldMap*) userdata; LLTracker::ETrackingStatus tracking_status = LLTracker::getTrackingStatus(); if ( LLTracker::TRACKING_LOCATION == tracking_status) { LLVector3d pos_global = LLTracker::getTrackedPositionGlobal(); - F64 local_x = self->childGetValue("spin x"); - F64 local_y = self->childGetValue("spin y"); - F64 local_z = self->childGetValue("spin z"); + F64 local_x = childGetValue("spin x"); + F64 local_y = childGetValue("spin y"); + F64 local_z = childGetValue("spin z"); pos_global.mdV[VX] += -fmod(pos_global.mdV[VX], 256.0) + local_x; pos_global.mdV[VY] += -fmod(pos_global.mdV[VY], 256.0) + local_y; pos_global.mdV[VZ] = local_z; - self->trackLocation(pos_global); + trackLocation(pos_global); } } -// static -void LLFloaterWorldMap::onCommitSearchResult(LLUICtrl*, void* userdata) +void LLFloaterWorldMap::onCommitSearchResult() { - LLFloaterWorldMap* self = (LLFloaterWorldMap*) userdata; - - LLCtrlListInterface *list = self->childGetListInterface("search_results"); + LLCtrlListInterface *list = childGetListInterface("search_results"); if (!list) return; LLSD selected_value = list->getSelectedValue(); @@ -1612,19 +1585,19 @@ void LLFloaterWorldMap::onCommitSearchResult(LLUICtrl*, void* userdata) if (sim_name == info_sim_name) { LLVector3d pos_global = from_region_handle( info->mHandle ); - F64 local_x = self->childGetValue("spin x"); - F64 local_y = self->childGetValue("spin y"); - F64 local_z = self->childGetValue("spin z"); + F64 local_x = childGetValue("spin x"); + F64 local_y = childGetValue("spin y"); + F64 local_z = childGetValue("spin z"); pos_global.mdV[VX] += local_x; pos_global.mdV[VY] += local_y; pos_global.mdV[VZ] = local_z; - self->childSetValue("location", sim_name); - self->trackLocation(pos_global); - self->setDefaultBtn("Teleport"); + childSetValue("location", sim_name); + trackLocation(pos_global); + setDefaultBtn("Teleport"); break; } } - onShowTargetBtn(self); + onShowTargetBtn(); } diff --git a/indra/newview/llfloaterworldmap.h b/indra/newview/llfloaterworldmap.h index a7d7051b40..2f537fb735 100644 --- a/indra/newview/llfloaterworldmap.h +++ b/indra/newview/llfloaterworldmap.h @@ -114,25 +114,25 @@ public: protected: static void onPanBtn( void* userdata ); - static void onGoHome(void* data); + void onGoHome(); - void onLandmarkComboPrearrange( ); - static void onLandmarkComboCommit( LLUICtrl* ctrl, void* data ); + void onLandmarkComboPrearrange(); + void onLandmarkComboCommit(); - void onAvatarComboPrearrange( ); - static void onAvatarComboCommit( LLUICtrl* ctrl, void* data ); + void onAvatarComboPrearrange(); + void onAvatarComboCommit(); void onCommitBackground(); void onComboTextEntry( ); void onSearchTextEntry( LLLineEditor* ctrl ); - static void onClearBtn(void*); + void onClearBtn(); static void onFlyBtn(void*); static void onClickTeleportBtn(void*); - static void onShowTargetBtn(void*); - static void onShowAgentBtn(void*); - static void onCopySLURL(void*); + void onShowTargetBtn(); + void onShowAgentBtn(); + void onCopySLURL(); static void onCheckEvents(LLUICtrl* ctrl, void*); @@ -152,11 +152,11 @@ protected: void flyToAvatar(); void teleportToAvatar(); - void updateSearchEnabled( ); + void updateSearchEnabled(); void onLocationFocusChanged( LLFocusableElement* ctrl ); - static void onLocationCommit( void* userdata ); - static void onCommitLocation( LLUICtrl* ctrl, void* userdata ); - static void onCommitSearchResult( LLUICtrl* ctrl, void* userdata ); + void onLocationCommit(); + void onCommitLocation(); + void onCommitSearchResult(); void cacheLandmarkPosition(); diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp index ebda8b25fd..d0a82f283c 100644 --- a/indra/newview/llfolderview.cpp +++ b/indra/newview/llfolderview.cpp @@ -34,20 +34,11 @@ #include "llfolderview.h" -#include <algorithm> - -#include "llviewercontrol.h" -#include "lldbstrings.h" -#include "llfocusmgr.h" -#include "llfontgl.h" -#include "llgl.h" -#include "llrender.h" -#include "llinventory.h" - #include "llcallbacklist.h" #include "llinventorybridge.h" #include "llinventoryclipboard.h" // *TODO: remove this once hack below gone. -#include "llinventoryview.h"// hacked in for the bonus context menu items. +#include "llinventoryfilter.h" +#include "llfloaterinventory.h"// hacked in for the bonus context menu items. #include "llkeyboard.h" #include "lllineeditor.h" #include "llmenugl.h" @@ -61,34 +52,35 @@ #include "llviewerjointattachment.h" #include "llviewermenu.h" #include "lluictrlfactory.h" +#include "llviewercontrol.h" #include "llviewerwindow.h" #include "llvoavatar.h" #include "llfloaterproperties.h" -// RN: HACK -// We need these because some of the code below relies on things like -// gAgent root folder. Remove them once the abstraction leak is fixed. -#include "llagent.h" -#include "llappviewer.h" +// Linden library includes +#include "lldbstrings.h" +#include "llfocusmgr.h" +#include "llfontgl.h" +#include "llgl.h" +#include "llrender.h" +#include "llinventory.h" + +// Third-party library includes +#include <algorithm> ///---------------------------------------------------------------------------- /// Local function declarations, constants, enums, and typedefs ///---------------------------------------------------------------------------- -const S32 LEFT_PAD = 5; -const S32 LEFT_INDENTATION = 13; -const S32 ICON_PAD = 2; -const S32 ICON_WIDTH = 16; -const S32 TEXT_PAD = 1; -const S32 ARROW_SIZE = 12; const S32 RENAME_WIDTH_PAD = 4; const S32 RENAME_HEIGHT_PAD = 2; const S32 AUTO_OPEN_STACK_DEPTH = 16; -const S32 MIN_ITEM_WIDTH_VISIBLE = ICON_WIDTH + ICON_PAD + ARROW_SIZE + TEXT_PAD + /*first few characters*/ 40; +const S32 MIN_ITEM_WIDTH_VISIBLE = LLFolderViewItem::ICON_WIDTH + + LLFolderViewItem::ICON_PAD + + LLFolderViewItem::ARROW_SIZE + + LLFolderViewItem::TEXT_PAD + + /*first few characters*/ 40; const S32 MINIMUM_RENAMER_WIDTH = 80; -const F32 FOLDER_CLOSE_TIME_CONSTANT = 0.02f; -const F32 FOLDER_OPEN_TIME_CONSTANT = 0.03f; -const S32 MAX_FOLDER_ITEM_OVERLAP = 2; enum { SIGNAL_NO_KEYBOARD_FOCUS = 1, @@ -104,2332 +96,6 @@ void properties_selected_items(void* user_data); void paste_items(void* user_data); void renamer_focus_lost( LLFocusableElement* handler, void* user_data ); -///---------------------------------------------------------------------------- -/// Class LLFolderViewItem -///---------------------------------------------------------------------------- - -// statics -const LLFontGL* LLFolderViewItem::sFont = NULL; -const LLFontGL* LLFolderViewItem::sSmallFont = NULL; -LLUIImagePtr LLFolderViewItem::sArrowImage; -LLUIImagePtr LLFolderViewItem::sBoxImage; - -const LLColor4U DEFAULT_WHITE(255, 255, 255); - -//static -void LLFolderViewItem::initClass() -{ - sFont = LLFontGL::getFontSansSerifSmall(); - sSmallFont = LLFontGL::getFontMonospace(); - sArrowImage = LLUI::getUIImage("folder_arrow.tga"); - sBoxImage = LLUI::getUIImage("rounded_square.tga"); -} - -//static -void LLFolderViewItem::cleanupClass() -{ - sArrowImage = NULL; - sBoxImage = NULL; -} - -// NOTE: Optimize this, we call it a *lot* when opening a large inventory - -// Default constructor -LLFolderViewItem::LLFolderViewItem(LLFolderViewItem::Params p) -: LLView(p), - mLabelWidth(0), - mLabelWidthDirty(false), - mParentFolder( NULL ), - mIsSelected( FALSE ), - mIsCurSelection( FALSE ), - mSelectPending(FALSE), - mLabelStyle( LLFontGL::NORMAL ), - mHasVisibleChildren(FALSE), - mIndentation(0), - mNumDescendantsSelected(0), - mFiltered(FALSE), - mLastFilterGeneration(-1), - mStringMatchOffset(std::string::npos), - mControlLabelRotation(0.f), - mDragAndDropTarget(FALSE), - mIsLoading(FALSE), - mLabel(p.name), - mRoot(p.root), - mCreationDate(p.creation_date), - mListener(p.listener), - mArrowImage(p.folder_arrow_image), - mBoxImage(p.selection_image) -{ - refresh(); -} - -// Destroys the object -LLFolderViewItem::~LLFolderViewItem( void ) -{ - delete mListener; - mListener = NULL; -} - -LLFolderView* LLFolderViewItem::getRoot() -{ - return mRoot; -} - -// Returns true if this object is a child (or grandchild, etc.) of potential_ancestor. -BOOL LLFolderViewItem::isDescendantOf( const LLFolderViewFolder* potential_ancestor ) -{ - LLFolderViewItem* root = this; - while( root->mParentFolder ) - { - if( root->mParentFolder == potential_ancestor ) - { - return TRUE; - } - root = root->mParentFolder; - } - return FALSE; -} - -LLFolderViewItem* LLFolderViewItem::getNextOpenNode(BOOL include_children) -{ - if (!mParentFolder) - { - return NULL; - } - - LLFolderViewItem* itemp = mParentFolder->getNextFromChild( this, include_children ); - while(itemp && !itemp->getVisible()) - { - LLFolderViewItem* next_itemp = itemp->mParentFolder->getNextFromChild( itemp, include_children ); - if (itemp == next_itemp) - { - // hit last item - return itemp->getVisible() ? itemp : this; - } - itemp = next_itemp; - } - - return itemp; -} - -LLFolderViewItem* LLFolderViewItem::getPreviousOpenNode(BOOL include_children) -{ - if (!mParentFolder) - { - return NULL; - } - - LLFolderViewItem* itemp = mParentFolder->getPreviousFromChild( this, include_children ); - while(itemp && !itemp->getVisible()) - { - LLFolderViewItem* next_itemp = itemp->mParentFolder->getPreviousFromChild( itemp, include_children ); - if (itemp == next_itemp) - { - // hit first item - return itemp->getVisible() ? itemp : this; - } - itemp = next_itemp; - } - - return itemp; -} - -// is this item something we think we should be showing? -// for example, if we haven't gotten around to filtering it yet, then the answer is yes -// until we find out otherwise -BOOL LLFolderViewItem::potentiallyVisible() -{ - // we haven't been checked against min required filter - // or we have and we passed - return getLastFilterGeneration() < getRoot()->getFilter()->getMinRequiredGeneration() || getFiltered(); -} - -BOOL LLFolderViewItem::getFiltered() -{ - return mFiltered && mLastFilterGeneration >= getRoot()->getFilter()->getMinRequiredGeneration(); -} - -BOOL LLFolderViewItem::getFiltered(S32 filter_generation) -{ - return mFiltered && mLastFilterGeneration >= filter_generation; -} - -void LLFolderViewItem::setFiltered(BOOL filtered, S32 filter_generation) -{ - mFiltered = filtered; - mLastFilterGeneration = filter_generation; -} - -void LLFolderViewItem::setIcon(LLUIImagePtr icon) -{ - mIcon = icon; -} - -// refresh information from the listener -void LLFolderViewItem::refreshFromListener() -{ - if(mListener) - { - mLabel = mListener->getDisplayName(); - LLAssetType::EType preferred_type = mListener->getPreferredType(); - - // *TODO: to be removed when database supports multi language. This is a - // temporary attempt to display the inventory folder in the user locale. - if (preferred_type != LLAssetType::AT_NONE) - { - mLabel = LLTrans::getString("InvFolder " + mLabel); - }; - - setIcon(mListener->getIcon()); - time_t creation_date = mListener->getCreationDate(); - if (mCreationDate != creation_date) - { - mCreationDate = mListener->getCreationDate(); - dirtyFilter(); - } - mLabelStyle = mListener->getLabelStyle(); - mLabelSuffix = mListener->getLabelSuffix(); - } -} - -void LLFolderViewItem::refresh() -{ - refreshFromListener(); - - std::string searchable_label(mLabel); - searchable_label.append(mLabelSuffix); - LLStringUtil::toUpper(searchable_label); - - if (mSearchableLabel.compare(searchable_label)) - { - mSearchableLabel.assign(searchable_label); - dirtyFilter(); - // some part of label has changed, so overall width has potentially changed, and sort order too - if (mParentFolder) - { - mParentFolder->requestSort(); - mParentFolder->requestArrange(); - } - } - - mLabelWidthDirty = true; -} - -void LLFolderViewItem::applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor) -{ - functor(mListener); -} - -// This function is called when items are added or view filters change. It's -// implemented here but called by derived classes when folding the -// views. -void LLFolderViewItem::filterFromRoot( void ) -{ - LLFolderViewItem* root = getRoot(); - - root->filter(*((LLFolderView*)root)->getFilter()); -} - -// This function is called when the folder view is dirty. It's -// implemented here but called by derived classes when folding the -// views. -void LLFolderViewItem::arrangeFromRoot() -{ - LLFolderViewItem* root = getRoot(); - - S32 height = 0; - S32 width = 0; - root->arrange( &width, &height, 0 ); -} - -// This function clears the currently selected item, and records the -// specified selected item appropriately for display and use in the -// UI. If open is TRUE, then folders are opened up along the way to -// the selection. -void LLFolderViewItem::setSelectionFromRoot(LLFolderViewItem* selection, - BOOL openitem, - BOOL take_keyboard_focus) -{ - getRoot()->setSelection(selection, openitem, take_keyboard_focus); -} - -// helper function to change the selection from the root. -void LLFolderViewItem::changeSelectionFromRoot(LLFolderViewItem* selection, BOOL selected) -{ - getRoot()->changeSelection(selection, selected); -} - -void LLFolderViewItem::extendSelectionFromRoot(LLFolderViewItem* selection) -{ - LLDynamicArray<LLFolderViewItem*> selected_items; - - getRoot()->extendSelection(selection, NULL, selected_items); -} - -EInventorySortGroup LLFolderViewItem::getSortGroup() const -{ - return SG_ITEM; -} - -// addToFolder() returns TRUE if it succeeds. FALSE otherwise -BOOL LLFolderViewItem::addToFolder(LLFolderViewFolder* folder, LLFolderView* root) -{ - if (!folder) - { - return FALSE; - } - mParentFolder = folder; - root->addItemID(getListener()->getUUID(), this); - return folder->addItem(this); -} - - -// Finds width and height of this object and it's children. Also -// makes sure that this view and it's children are the right size. -S32 LLFolderViewItem::arrange( S32* width, S32* height, S32 filter_generation) -{ - mIndentation = mParentFolder ? mParentFolder->getIndentation() + LEFT_INDENTATION : 0; - if (mLabelWidthDirty) - { - mLabelWidth = ARROW_SIZE + TEXT_PAD + ICON_WIDTH + ICON_PAD + sFont->getWidth(mSearchableLabel); - mLabelWidthDirty = false; - } - - *width = llmax(*width, mLabelWidth + mIndentation); - *height = getItemHeight(); - return *height; -} - -S32 LLFolderViewItem::getItemHeight() -{ - S32 icon_height = mIcon->getHeight(); - S32 label_height = llround(sFont->getLineHeight()); - return llmax( icon_height, label_height ) + ICON_PAD; -} - -void LLFolderViewItem::filter( LLInventoryFilter& filter) -{ - BOOL filtered = mListener && filter.check(this); - - // if our visibility will change as a result of this filter, then - // we need to be rearranged in our parent folder - if (getVisible() != filtered) - { - if (mParentFolder) - { - mParentFolder->requestArrange(); - } - } - - setFiltered(filtered, filter.getCurrentGeneration()); - mStringMatchOffset = filter.getStringMatchOffset(); - filter.decrementFilterCount(); - - if (getRoot()->getDebugFilters()) - { - mStatusText = llformat("%d", mLastFilterGeneration); - } -} - -void LLFolderViewItem::dirtyFilter() -{ - mLastFilterGeneration = -1; - // bubble up dirty flag all the way to root - if (getParentFolder()) - { - getParentFolder()->setCompletedFilterGeneration(-1, TRUE); - } -} - -// *TODO: This can be optimized a lot by simply recording that it is -// selected in the appropriate places, and assuming that set selection -// means 'deselect' for a leaf item. Do this optimization after -// multiple selection is implemented to make sure it all plays nice -// together. -BOOL LLFolderViewItem::setSelection(LLFolderViewItem* selection, BOOL openitem, BOOL take_keyboard_focus) -{ - if( selection == this ) - { - mIsSelected = TRUE; - if(mListener) - { - mListener->selectItem(); - } - } - else - { - mIsSelected = FALSE; - } - return mIsSelected; -} - -BOOL LLFolderViewItem::changeSelection(LLFolderViewItem* selection, BOOL selected) -{ - if(selection == this && mIsSelected != selected) - { - mIsSelected = selected; - if(mListener) - { - mListener->selectItem(); - } - return TRUE; - } - 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() -{ - if( mListener ) - { - return mListener->isItemMovable(); - } - else - { - return TRUE; - } -} - -BOOL LLFolderViewItem::isRemovable() -{ - if( mListener ) - { - return mListener->isItemRemovable(); - } - else - { - return TRUE; - } -} - -void LLFolderViewItem::destroyView() -{ - if (mParentFolder) - { - // removeView deletes me - mParentFolder->removeView(this); - } -} - -// Call through to the viewed object and return true if it can be -// removed. -//BOOL LLFolderViewItem::removeRecursively(BOOL single_item) -BOOL LLFolderViewItem::remove() -{ - if(!isRemovable()) - { - return FALSE; - } - if(mListener) - { - return mListener->removeItem(); - } - return TRUE; -} - -// Build an appropriate context menu for the item. -void LLFolderViewItem::buildContextMenu(LLMenuGL& menu, U32 flags) -{ - if(mListener) - { - mListener->buildContextMenu(menu, flags); - } -} - -void LLFolderViewItem::openItem( void ) -{ - if( mListener ) - { - mListener->openItem(); - } -} - -void LLFolderViewItem::preview( void ) -{ - if (mListener) - { - mListener->previewItem(); - } -} - -void LLFolderViewItem::rename(const std::string& new_name) -{ - if( !new_name.empty() ) - { - if( mListener ) - { - mListener->renameItem(new_name); - - if(mParentFolder) - { - mParentFolder->requestSort(); - } - } - } -} - -const std::string& LLFolderViewItem::getSearchableLabel() const -{ - return mSearchableLabel; -} - -const std::string& LLFolderViewItem::getName( void ) const -{ - if(mListener) - { - return mListener->getName(); - } - return mLabel; -} - -// LLView functionality -BOOL LLFolderViewItem::handleRightMouseDown( S32 x, S32 y, MASK mask ) -{ - if(!mIsSelected) - { - setSelectionFromRoot(this, FALSE); - } - make_ui_sound("UISndClick"); - return TRUE; -} - -BOOL LLFolderViewItem::handleMouseDown( S32 x, S32 y, MASK mask ) -{ - // No handler needed for focus lost since this class has no - // state that depends on it. - gFocusMgr.setMouseCapture( this ); - - if (!mIsSelected) - { - if(mask & MASK_CONTROL) - { - changeSelectionFromRoot(this, !mIsSelected); - } - else if (mask & MASK_SHIFT) - { - extendSelectionFromRoot(this); - } - else - { - setSelectionFromRoot(this, FALSE); - } - make_ui_sound("UISndClick"); - } - else - { - mSelectPending = TRUE; - } - - if( isMovable() ) - { - S32 screen_x; - S32 screen_y; - localPointToScreen(x, y, &screen_x, &screen_y ); - LLToolDragAndDrop::getInstance()->setDragStart( screen_x, screen_y ); - } - return TRUE; -} - -BOOL LLFolderViewItem::handleHover( S32 x, S32 y, MASK mask ) -{ - if( hasMouseCapture() && isMovable() ) - { - S32 screen_x; - S32 screen_y; - localPointToScreen(x, y, &screen_x, &screen_y ); - BOOL can_drag = TRUE; - if( LLToolDragAndDrop::getInstance()->isOverThreshold( screen_x, screen_y ) ) - { - LLFolderView* root = getRoot(); - - if(root->getCurSelectedItem()) - { - LLToolDragAndDrop::ESource src = LLToolDragAndDrop::SOURCE_WORLD; - - // *TODO: push this into listener and remove - // dependency on llagent - if(mListener && gInventory.isObjectDescendentOf(mListener->getUUID(), gAgent.getInventoryRootID())) - { - src = LLToolDragAndDrop::SOURCE_AGENT; - } - else if (mListener && gInventory.isObjectDescendentOf(mListener->getUUID(), gInventoryLibraryRoot)) - { - src = LLToolDragAndDrop::SOURCE_LIBRARY; - } - - can_drag = root->startDrag(src); - if (can_drag) - { - // if (mListener) mListener->startDrag(); - // RN: when starting drag and drop, clear out last auto-open - root->autoOpenTest(NULL); - root->setShowSelectionContext(TRUE); - - // Release keyboard focus, so that if stuff is dropped into the - // world, pressing the delete key won't blow away the inventory - // item. - gFocusMgr.setKeyboardFocus(NULL); - - return LLToolDragAndDrop::getInstance()->handleHover( x, y, mask ); - } - } - } - - if (can_drag) - { - gViewerWindow->setCursor(UI_CURSOR_ARROW); - } - else - { - gViewerWindow->setCursor(UI_CURSOR_NOLOCKED); - } - return TRUE; - } - else - { - getRoot()->setShowSelectionContext(FALSE); - gViewerWindow->setCursor(UI_CURSOR_ARROW); - // let parent handle this then... - return FALSE; - } -} - - -BOOL LLFolderViewItem::handleDoubleClick( S32 x, S32 y, MASK mask ) -{ - preview(); - return TRUE; -} - -BOOL LLFolderViewItem::handleScrollWheel(S32 x, S32 y, S32 clicks) -{ - if (getParent()) - { - return getParent()->handleScrollWheel(x, y, clicks); - } - return FALSE; -} - -BOOL LLFolderViewItem::handleMouseUp( S32 x, S32 y, MASK mask ) -{ - // if mouse hasn't moved since mouse down... - if ( pointInView(x, y) && mSelectPending ) - { - //...then select - if(mask & MASK_CONTROL) - { - changeSelectionFromRoot(this, !mIsSelected); - } - else if (mask & MASK_SHIFT) - { - extendSelectionFromRoot(this); - } - else - { - setSelectionFromRoot(this, FALSE); - } - } - - mSelectPending = FALSE; - - if( hasMouseCapture() ) - { - getRoot()->setShowSelectionContext(FALSE); - gFocusMgr.setMouseCapture( NULL ); - } - return TRUE; -} - -BOOL LLFolderViewItem::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, - EDragAndDropType cargo_type, - void* cargo_data, - EAcceptance* accept, - std::string& tooltip_msg) -{ - BOOL accepted = FALSE; - BOOL handled = FALSE; - if(mListener) - { - accepted = mListener->dragOrDrop(mask,drop,cargo_type,cargo_data); - handled = accepted; - if (accepted) - { - mDragAndDropTarget = TRUE; - *accept = ACCEPT_YES_MULTI; - } - else - { - *accept = ACCEPT_NO; - } - } - if(mParentFolder && !handled) - { - handled = mParentFolder->handleDragAndDropFromChild(mask,drop,cargo_type,cargo_data,accept,tooltip_msg); - } - if (handled) - { - lldebugst(LLERR_USER_INPUT) << "dragAndDrop handled by LLFolderViewItem" << llendl; - } - - return handled; -} - - -void LLFolderViewItem::draw() -{ - static LLUIColor sFgColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE); - static LLUIColor sHighlightBgColor = LLUIColorTable::instance().getColor("MenuItemHighlightBgColor", DEFAULT_WHITE); - static LLUIColor sHighlightFgColor = LLUIColorTable::instance().getColor("MenuItemHighlightFgColor", DEFAULT_WHITE); - static LLUIColor sFilterBGColor = LLUIColorTable::instance().getColor("FilterBackgroundColor", DEFAULT_WHITE); - static LLUIColor sFilterTextColor = LLUIColorTable::instance().getColor("FilterTextColor", DEFAULT_WHITE); - static LLUIColor sSuffixColor = LLUIColorTable::instance().getColor("InventoryItemSuffixColor", DEFAULT_WHITE); - static LLUIColor sSearchStatusColor = LLUIColorTable::instance().getColor("InventorySearchStatusColor", DEFAULT_WHITE); - - bool possibly_has_children = false; - bool up_to_date = mListener && mListener->isUpToDate(); - if((up_to_date && hasVisibleChildren() ) || // we fetched our children and some of them have passed the filter... - (!up_to_date && mListener && mListener->hasChildren())) // ...or we know we have children but haven't fetched them (doesn't obey filter) - { - possibly_has_children = true; - } - if(/*mControlLabel[0] != '\0' && */possibly_has_children) - { - if (sArrowImage) - { - gl_draw_scaled_rotated_image(mIndentation, getRect().getHeight() - ARROW_SIZE - TEXT_PAD, - ARROW_SIZE, ARROW_SIZE, mControlLabelRotation, sArrowImage->getImage(), sFgColor); - } - } - - F32 text_left = (F32)(ARROW_SIZE + TEXT_PAD + ICON_WIDTH + ICON_PAD + mIndentation); - - // If we have keyboard focus, draw selection filled - BOOL show_context = getRoot()->getShowSelectionContext(); - BOOL filled = show_context || (getRoot()->getParentPanel()->hasFocus()); - - // always render "current" item, only render other selected items if - // mShowSingleSelection is FALSE - if( mIsSelected ) - { - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - LLColor4 bg_color = sHighlightBgColor; - //const S32 TRAILING_PAD = 5; // It just looks better with this. - if (!mIsCurSelection) - { - // do time-based fade of extra objects - F32 fade_time = getRoot()->getSelectionFadeElapsedTime(); - if (getRoot()->getShowSingleSelection()) - { - // fading out - bg_color.mV[VALPHA] = clamp_rescale(fade_time, 0.f, 0.4f, bg_color.mV[VALPHA], 0.f); - } - else - { - // fading in - bg_color.mV[VALPHA] = clamp_rescale(fade_time, 0.f, 0.4f, 0.f, bg_color.mV[VALPHA]); - } - } - - gl_rect_2d( - 0, - getRect().getHeight(), - getRect().getWidth() - 2, - llfloor(getRect().getHeight() - sFont->getLineHeight() - ICON_PAD), - bg_color, filled); - if (mIsCurSelection) - { - gl_rect_2d( - 0, - getRect().getHeight(), - getRect().getWidth() - 2, - llfloor(getRect().getHeight() - sFont->getLineHeight() - ICON_PAD), - sHighlightFgColor, FALSE); - } - if (getRect().getHeight() > llround(sFont->getLineHeight()) + ICON_PAD + 2) - { - gl_rect_2d( - 0, - llfloor(getRect().getHeight() - sFont->getLineHeight() - ICON_PAD) - 2, - getRect().getWidth() - 2, - 2, - sHighlightFgColor, FALSE); - if (show_context) - { - gl_rect_2d( - 0, - llfloor(getRect().getHeight() - sFont->getLineHeight() - ICON_PAD) - 2, - getRect().getWidth() - 2, - 2, - sHighlightBgColor, TRUE); - } - } - } - if (mDragAndDropTarget) - { - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gl_rect_2d( - 0, - getRect().getHeight(), - getRect().getWidth() - 2, - llfloor(getRect().getHeight() - sFont->getLineHeight() - ICON_PAD), - sHighlightBgColor, FALSE); - - if (getRect().getHeight() > llround(sFont->getLineHeight()) + ICON_PAD + 2) - { - gl_rect_2d( - 0, - llfloor(getRect().getHeight() - sFont->getLineHeight() - ICON_PAD) - 2, - getRect().getWidth() - 2, - 2, - sHighlightBgColor, FALSE); - } - mDragAndDropTarget = FALSE; - } - - - if(mIcon) - { - mIcon->draw(mIndentation + ARROW_SIZE + TEXT_PAD, getRect().getHeight() - mIcon->getHeight()); - } - - if (!mLabel.empty()) - { - // highlight filtered text - BOOL debug_filters = getRoot()->getDebugFilters(); - LLColor4 color = ( (mIsSelected && filled) ? sHighlightFgColor : sFgColor ); - F32 right_x; - F32 y = (F32)getRect().getHeight() - sFont->getLineHeight() - (F32)TEXT_PAD; - - if (debug_filters) - { - if (!getFiltered() && !possibly_has_children) - { - color.mV[VALPHA] *= 0.5f; - } - - LLColor4 filter_color = mLastFilterGeneration >= getRoot()->getFilter()->getCurrentGeneration() ? LLColor4(0.5f, 0.8f, 0.5f, 1.f) : LLColor4(0.8f, 0.5f, 0.5f, 1.f); - sSmallFont->renderUTF8(mStatusText, 0, text_left, y, filter_color, - LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, - S32_MAX, S32_MAX, &right_x, FALSE ); - text_left = right_x; - } - - - if ( mIsLoading && mTimeSinceRequestStart.getElapsedTimeF32() >= gSavedSettings.getF32("FolderLoadingMessageWaitTime") ) - { - sFont->renderUTF8(LLTrans::getString("LoadingData"), 0, text_left, y, sSearchStatusColor, - LLFontGL::LEFT, LLFontGL::BOTTOM, mLabelStyle, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, &right_x, FALSE); - text_left = right_x; - } - - sFont->renderUTF8( mLabel, 0, text_left, y, color, - LLFontGL::LEFT, LLFontGL::BOTTOM, mLabelStyle, LLFontGL::NO_SHADOW, - S32_MAX, S32_MAX, &right_x, FALSE ); - if (!mLabelSuffix.empty()) - { - sFont->renderUTF8( mLabelSuffix, 0, right_x, y, sSuffixColor, - LLFontGL::LEFT, LLFontGL::BOTTOM, mLabelStyle, LLFontGL::NO_SHADOW, - S32_MAX, S32_MAX, &right_x, FALSE ); - } - - if (sBoxImage.notNull() && mStringMatchOffset != std::string::npos) - { - // don't draw backgrounds for zero-length strings - S32 filter_string_length = getRoot()->getFilterSubString().size(); - if (filter_string_length > 0) - { - std::string combined_string = mLabel + mLabelSuffix; - S32 left = llround(text_left) + sFont->getWidth(combined_string, 0, mStringMatchOffset) - 1; - S32 right = left + sFont->getWidth(combined_string, mStringMatchOffset, filter_string_length) + 2; - S32 bottom = llfloor(getRect().getHeight() - sFont->getLineHeight() - 3); - S32 top = getRect().getHeight(); - - LLRect box_rect(left, top, right, bottom); - sBoxImage->draw(box_rect, sFilterBGColor); - F32 match_string_left = text_left + sFont->getWidthF32(combined_string, 0, mStringMatchOffset); - F32 y = (F32)getRect().getHeight() - sFont->getLineHeight() - (F32)TEXT_PAD; - sFont->renderUTF8( combined_string, mStringMatchOffset, match_string_left, y, - sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, mLabelStyle, LLFontGL::NO_SHADOW, - filter_string_length, S32_MAX, &right_x, FALSE ); - } - } - } - - if( sDebugRects ) - { - drawDebugRect(); - } - - //// *HACK: also draw debug rectangles around currently-being-edited LLView, and any elements that are being highlighted by GUI preview code (see LLFloaterUIPreview) - //std::set<LLView*>::iterator iter = std::find(sPreviewHighlightedElements.begin(), sPreviewHighlightedElements.end(), this); - //if ((sEditingUI && this == sEditingUIView) || (iter != sPreviewHighlightedElements.end() && sDrawPreviewHighlights)) - //{ - // drawDebugRect(); - //} -} - - -///---------------------------------------------------------------------------- -/// Class LLFolderViewFolder -///---------------------------------------------------------------------------- - -LLFolderViewFolder::LLFolderViewFolder( const LLFolderViewItem::Params& p ): - LLFolderViewItem( p ), // 0 = no create time - mIsOpen(FALSE), - mExpanderHighlighted(FALSE), - mCurHeight(0.f), - mTargetHeight(0.f), - mAutoOpenCountdown(0.f), - mSubtreeCreationDate(0), - mAmTrash(LLFolderViewFolder::UNKNOWN), - mLastArrangeGeneration( -1 ), - mLastCalculatedWidth(0), - mCompletedFilterGeneration(-1), - mMostFilteredDescendantGeneration(-1), - mNeedsSort(false) -{} - -// Destroys the object -LLFolderViewFolder::~LLFolderViewFolder( void ) -{ - // The LLView base class takes care of object destruction. make sure that we - // don't have mouse or keyboard focus - gFocusMgr.releaseFocusIfNeeded( this ); // calls onCommit() -} - -// addToFolder() returns TRUE if it succeeds. FALSE otherwise -BOOL LLFolderViewFolder::addToFolder(LLFolderViewFolder* folder, LLFolderView* root) -{ - if (!folder) - { - return FALSE; - } - mParentFolder = folder; - root->addItemID(getListener()->getUUID(), this); - return folder->addFolder(this); -} - -// Finds width and height of this object and it's children. Also -// makes sure that this view and it's children are the right size. -S32 LLFolderViewFolder::arrange( S32* width, S32* height, S32 filter_generation) -{ - // sort before laying out contents - if (mNeedsSort) - { - mFolders.sort(mSortFunction); - mItems.sort(mSortFunction); - mNeedsSort = false; - } - - mHasVisibleChildren = hasFilteredDescendants(filter_generation); - - LLInventoryFilter::EFolderShow show_folder_state = getRoot()->getShowFolderState(); - - // calculate height as a single item (without any children), and reshapes rectangle to match - LLFolderViewItem::arrange( width, height, filter_generation ); - - // clamp existing animated height so as to never get smaller than a single item - mCurHeight = llmax((F32)*height, mCurHeight); - - // initialize running height value as height of single item in case we have no children - *height = getItemHeight(); - F32 running_height = (F32)*height; - F32 target_height = (F32)*height; - - // are my children visible? - if (needsArrange()) - { - // set last arrange generation first, in case children are animating - // and need to be arranged again - mLastArrangeGeneration = getRoot()->getArrangeGeneration(); - if (mIsOpen) - { - // Add sizes of children - S32 parent_item_height = getRect().getHeight(); - - for(folders_t::iterator fit = mFolders.begin(); fit != mFolders.end(); ++fit) - { - LLFolderViewFolder* folderp = (*fit); - if (getRoot()->getDebugFilters()) - { - folderp->setVisible(TRUE); - } - else - { - folderp->setVisible(show_folder_state == LLInventoryFilter::SHOW_ALL_FOLDERS || // always show folders? - (folderp->getFiltered(filter_generation) || folderp->hasFilteredDescendants(filter_generation))); // passed filter or has descendants that passed filter - } - - if (folderp->getVisible()) - { - S32 child_width = *width; - S32 child_height = 0; - S32 child_top = parent_item_height - llround(running_height); - - target_height += folderp->arrange( &child_width, &child_height, filter_generation ); - - running_height += (F32)child_height; - *width = llmax(*width, child_width); - folderp->setOrigin( 0, child_top - folderp->getRect().getHeight() ); - } - } - for(items_t::iterator iit = mItems.begin(); - iit != mItems.end(); ++iit) - { - LLFolderViewItem* itemp = (*iit); - if (getRoot()->getDebugFilters()) - { - itemp->setVisible(TRUE); - } - else - { - itemp->setVisible(itemp->getFiltered(filter_generation)); - } - - if (itemp->getVisible()) - { - S32 child_width = *width; - S32 child_height = 0; - S32 child_top = parent_item_height - llround(running_height); - - target_height += itemp->arrange( &child_width, &child_height, filter_generation ); - // don't change width, as this item is as wide as its parent folder by construction - itemp->reshape( itemp->getRect().getWidth(), child_height); - - running_height += (F32)child_height; - *width = llmax(*width, child_width); - itemp->setOrigin( 0, child_top - itemp->getRect().getHeight() ); - } - } - } - - mTargetHeight = target_height; - // cache this width so next time we can just return it - mLastCalculatedWidth = *width; - } - else - { - // just use existing width - *width = mLastCalculatedWidth; - } - - // animate current height towards target height - if (llabs(mCurHeight - mTargetHeight) > 1.f) - { - mCurHeight = lerp(mCurHeight, mTargetHeight, LLCriticalDamp::getInterpolant(mIsOpen ? FOLDER_OPEN_TIME_CONSTANT : FOLDER_CLOSE_TIME_CONSTANT)); - - requestArrange(); - - // hide child elements that fall out of current animated height - for (folders_t::iterator iter = mFolders.begin(); - iter != mFolders.end();) - { - folders_t::iterator fit = iter++; - // number of pixels that bottom of folder label is from top of parent folder - if (getRect().getHeight() - (*fit)->getRect().mTop + (*fit)->getItemHeight() - > llround(mCurHeight) + MAX_FOLDER_ITEM_OVERLAP) - { - // hide if beyond current folder height - (*fit)->setVisible(FALSE); - } - } - - for (items_t::iterator iter = mItems.begin(); - iter != mItems.end();) - { - items_t::iterator iit = iter++; - // number of pixels that bottom of item label is from top of parent folder - if (getRect().getHeight() - (*iit)->getRect().mBottom - > llround(mCurHeight) + MAX_FOLDER_ITEM_OVERLAP) - { - (*iit)->setVisible(FALSE); - } - } - } - else - { - mCurHeight = mTargetHeight; - } - - // don't change width as this item is already as wide as its parent folder - reshape(getRect().getWidth(),llround(mCurHeight)); - - // pass current height value back to parent - *height = llround(mCurHeight); - - return llround(mTargetHeight); -} - -BOOL LLFolderViewFolder::needsArrange() -{ - return mLastArrangeGeneration < getRoot()->getArrangeGeneration(); -} - -void LLFolderViewFolder::requestSort() -{ - mNeedsSort = true; - // whenever item order changes, we need to lay things out again - requestArrange(); -} - -void LLFolderViewFolder::setCompletedFilterGeneration(S32 generation, BOOL recurse_up) -{ - mMostFilteredDescendantGeneration = llmin(mMostFilteredDescendantGeneration, generation); - mCompletedFilterGeneration = generation; - // only aggregate up if we are a lower (older) value - if (recurse_up && mParentFolder && generation < mParentFolder->getCompletedFilterGeneration()) - { - mParentFolder->setCompletedFilterGeneration(generation, TRUE); - } -} - -void LLFolderViewFolder::filter( LLInventoryFilter& filter) -{ - S32 filter_generation = filter.getCurrentGeneration(); - // if failed to pass filter newer than must_pass_generation - // you will automatically fail this time, so we only - // check against items that have passed the filter - S32 must_pass_generation = filter.getMustPassGeneration(); - - // if we have already been filtered against this generation, skip out - if (getCompletedFilterGeneration() >= filter_generation) - { - return; - } - - // filter folder itself - if (getLastFilterGeneration() < filter_generation) - { - if (getLastFilterGeneration() >= must_pass_generation && // folder has been compared to a valid precursor filter - !mFiltered) // and did not pass the filter - { - // go ahead and flag this folder as done - mLastFilterGeneration = filter_generation; - } - else - { - // filter self only on first pass through - LLFolderViewItem::filter( filter ); - } - } - - if (getRoot()->getDebugFilters()) - { - mStatusText = llformat("%d", mLastFilterGeneration); - mStatusText += llformat("(%d)", mCompletedFilterGeneration); - mStatusText += llformat("+%d", mMostFilteredDescendantGeneration); - } - - // all descendants have been filtered later than must pass generation - // but none passed - if(getCompletedFilterGeneration() >= must_pass_generation && !hasFilteredDescendants(must_pass_generation)) - { - // don't traverse children if we've already filtered them since must_pass_generation - // and came back with nothing - return; - } - - // we entered here with at least one filter iteration left - // check to see if we have any more before continuing on to children - if (filter.getFilterCount() < 0) - { - return; - } - - // when applying a filter, matching folders get their contents downloaded first - if (filter.isNotDefault() && getFiltered(filter.getMinRequiredGeneration()) && (mListener && !gInventory.isCategoryComplete(mListener->getUUID()))) - { - gInventory.startBackgroundFetch(mListener->getUUID()); - } - - // now query children - for (folders_t::iterator iter = mFolders.begin(); - iter != mFolders.end();) - { - folders_t::iterator fit = iter++; - // have we run out of iterations this frame? - if (filter.getFilterCount() < 0) - { - break; - } - - // mMostFilteredDescendantGeneration might have been reset - // in which case we need to update it even for folders that - // don't need to be filtered anymore - if ((*fit)->getCompletedFilterGeneration() >= filter_generation) - { - // track latest generation to pass any child items - if ((*fit)->getFiltered() || (*fit)->hasFilteredDescendants(filter.getMinRequiredGeneration())) - { - mMostFilteredDescendantGeneration = filter_generation; - if (getRoot()->needsAutoSelect()) - { - (*fit)->setOpenArrangeRecursively(TRUE); - } - } - // just skip it, it has already been filtered - continue; - } - - // update this folders filter status (and children) - (*fit)->filter( filter ); - - // track latest generation to pass any child items - if ((*fit)->getFiltered() || (*fit)->hasFilteredDescendants(filter_generation)) - { - mMostFilteredDescendantGeneration = filter_generation; - if (getRoot()->needsAutoSelect()) - { - (*fit)->setOpenArrangeRecursively(TRUE); - } - } - } - - for (items_t::iterator iter = mItems.begin(); - iter != mItems.end();) - { - items_t::iterator iit = iter++; - if (filter.getFilterCount() < 0) - { - break; - } - if ((*iit)->getLastFilterGeneration() >= filter_generation) - { - if ((*iit)->getFiltered()) - { - mMostFilteredDescendantGeneration = filter_generation; - } - continue; - } - - if ((*iit)->getLastFilterGeneration() >= must_pass_generation && - !(*iit)->getFiltered(must_pass_generation)) - { - // failed to pass an earlier filter that was a subset of the current one - // go ahead and flag this item as done - (*iit)->setFiltered(FALSE, filter_generation); - continue; - } - - (*iit)->filter( filter ); - - if ((*iit)->getFiltered(filter.getMinRequiredGeneration())) - { - mMostFilteredDescendantGeneration = filter_generation; - } - } - - // if we didn't use all filter iterations - // that means we filtered all of our descendants - // instead of exhausting the filter count for this frame - if (filter.getFilterCount() > 0) - { - // flag this folder as having completed filter pass for all descendants - setCompletedFilterGeneration(filter_generation, FALSE/*dont recurse up to root*/); - } -} - -void LLFolderViewFolder::setFiltered(BOOL filtered, S32 filter_generation) -{ - // if this folder is now filtered, but wasn't before - // (it just passed) - if (filtered && !mFiltered) - { - // reset current height, because last time we drew it - // it might have had more visible items than now - mCurHeight = 0.f; - } - - LLFolderViewItem::setFiltered(filtered, filter_generation); -} - -void LLFolderViewFolder::dirtyFilter() -{ - // we're a folder, so invalidate our completed generation - setCompletedFilterGeneration(-1, FALSE); - LLFolderViewItem::dirtyFilter(); -} - -BOOL LLFolderViewFolder::hasFilteredDescendants() -{ - return mMostFilteredDescendantGeneration >= getRoot()->getFilter()->getCurrentGeneration(); -} - -// Passes selection information on to children and record selection -// information if necessary. -BOOL LLFolderViewFolder::setSelection(LLFolderViewItem* selection, BOOL openitem, - BOOL take_keyboard_focus) -{ - BOOL rv = FALSE; - if( selection == this ) - { - mIsSelected = TRUE; - if(mListener) - { - mListener->selectItem(); - } - rv = TRUE; - } - else - { - mIsSelected = FALSE; - rv = FALSE; - } - BOOL child_selected = FALSE; - - for (folders_t::iterator iter = mFolders.begin(); - iter != mFolders.end();) - { - folders_t::iterator fit = iter++; - if((*fit)->setSelection(selection, openitem, take_keyboard_focus)) - { - rv = TRUE; - child_selected = TRUE; - mNumDescendantsSelected++; - } - } - for (items_t::iterator iter = mItems.begin(); - iter != mItems.end();) - { - items_t::iterator iit = iter++; - if((*iit)->setSelection(selection, openitem, take_keyboard_focus)) - { - rv = TRUE; - child_selected = TRUE; - mNumDescendantsSelected++; - } - } - if(openitem && child_selected) - { - setOpenArrangeRecursively(TRUE); - } - return rv; -} - -// This method is used to change the selection of an item. If -// selection is 'this', then note selection as true. Returns TRUE -// if this or a child is now selected. -BOOL LLFolderViewFolder::changeSelection(LLFolderViewItem* selection, - BOOL selected) -{ - BOOL rv = FALSE; - if(selection == this) - { - mIsSelected = selected; - if(mListener && selected) - { - mListener->selectItem(); - } - rv = TRUE; - } - - for (folders_t::iterator iter = mFolders.begin(); - iter != mFolders.end();) - { - folders_t::iterator fit = iter++; - if((*fit)->changeSelection(selection, selected)) - { - if (selected) - { - mNumDescendantsSelected++; - } - else - { - mNumDescendantsSelected--; - } - rv = TRUE; - } - } - for (items_t::iterator iter = mItems.begin(); - iter != mItems.end();) - { - items_t::iterator iit = iter++; - if((*iit)->changeSelection(selection, selected)) - { - if (selected) - { - mNumDescendantsSelected++; - } - else - { - mNumDescendantsSelected--; - } - rv = TRUE; - } - } - return rv; -} - -S32 LLFolderViewFolder::extendSelection(LLFolderViewItem* selection, LLFolderViewItem* last_selected, LLDynamicArray<LLFolderViewItem*>& selected_items) -{ - S32 num_selected = 0; - - // pass on to child folders first - for (folders_t::iterator iter = mFolders.begin(); - iter != mFolders.end();) - { - folders_t::iterator fit = iter++; - num_selected += (*fit)->extendSelection(selection, last_selected, selected_items); - mNumDescendantsSelected += num_selected; - } - - // handle selection of our immediate children... - BOOL reverse_select = FALSE; - BOOL found_last_selected = FALSE; - BOOL found_selection = FALSE; - LLDynamicArray<LLFolderViewItem*> items_to_select; - LLFolderViewItem* item; - - //...folders first... - for (folders_t::iterator iter = mFolders.begin(); - iter != mFolders.end();) - { - folders_t::iterator fit = iter++; - item = (*fit); - if(item == selection) - { - found_selection = TRUE; - } - else if (item == last_selected) - { - found_last_selected = TRUE; - if (found_selection) - { - reverse_select = TRUE; - } - } - - if (found_selection || found_last_selected) - { - // deselect currently selected items so they can be pushed back on queue - if (item->isSelected()) - { - item->changeSelection(item, FALSE); - } - items_to_select.put(item); - } - - if (found_selection && found_last_selected) - { - break; - } - } - - if (!(found_selection && found_last_selected)) - { - //,,,then items - for (items_t::iterator iter = mItems.begin(); - iter != mItems.end();) - { - items_t::iterator iit = iter++; - item = (*iit); - if(item == selection) - { - found_selection = TRUE; - } - else if (item == last_selected) - { - found_last_selected = TRUE; - if (found_selection) - { - reverse_select = TRUE; - } - } - - if (found_selection || found_last_selected) - { - // deselect currently selected items so they can be pushed back on queue - if (item->isSelected()) - { - item->changeSelection(item, FALSE); - } - items_to_select.put(item); - } - - if (found_selection && found_last_selected) - { - break; - } - } - } - - if (found_last_selected && found_selection) - { - // we have a complete selection inside this folder - for (S32 index = reverse_select ? items_to_select.getLength() - 1 : 0; - reverse_select ? index >= 0 : index < items_to_select.getLength(); reverse_select ? index-- : index++) - { - LLFolderViewItem* item = items_to_select[index]; - if (item->changeSelection(item, TRUE)) - { - selected_items.put(item); - mNumDescendantsSelected++; - num_selected++; - } - } - } - else if (found_selection) - { - // last selection was not in this folder....go ahead and select just the new item - if (selection->changeSelection(selection, TRUE)) - { - selected_items.put(selection); - mNumDescendantsSelected++; - num_selected++; - } - } - - 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(); - iter != mItems.end();) - { - items_t::iterator iit = iter++; - LLFolderViewItem* item = (*iit); - getRoot()->removeItemID(item->getListener()->getUUID()); - } - - std::for_each(mItems.begin(), mItems.end(), DeletePointer()); - mItems.clear(); - - while (!mFolders.empty()) - { - LLFolderViewFolder *folderp = mFolders.back(); - folderp->destroyView(); // removes entry from mFolders - } - - deleteAllChildren(); - - if (mParentFolder) - { - mParentFolder->removeView(this); - } -} - -// remove the specified item (and any children) if possible. Return -// TRUE if the item was deleted. -BOOL LLFolderViewFolder::removeItem(LLFolderViewItem* item) -{ - if(item->remove()) - { - //RN: this seem unneccessary as remove() moves to trash - //removeView(item); - return TRUE; - } - return FALSE; -} - -// simply remove the view (and any children) Don't bother telling the -// listeners. -void LLFolderViewFolder::removeView(LLFolderViewItem* item) -{ - if (!item || item->getParentFolder() != this) - { - return; - } - // deselect without traversing hierarchy - item->recursiveDeselect(TRUE); - getRoot()->removeFromSelectionList(item); - extractItem(item); - delete item; -} - -// extractItem() removes the specified item from the folder, but -// doesn't delete it. -void LLFolderViewFolder::extractItem( LLFolderViewItem* item ) -{ - items_t::iterator it = std::find(mItems.begin(), mItems.end(), item); - if(it == mItems.end()) - { - // This is an evil downcast. However, it's only doing - // pointer comparison to find if (which it should be ) the - // item is in the container, so it's pretty safe. - LLFolderViewFolder* f = reinterpret_cast<LLFolderViewFolder*>(item); - folders_t::iterator ft; - ft = std::find(mFolders.begin(), mFolders.end(), f); - if(ft != mFolders.end()) - { - mFolders.erase(ft); - } - } - else - { - mItems.erase(it); - } - //item has been removed, need to update filter - dirtyFilter(); - //because an item is going away regardless of filter status, force rearrange - requestArrange(); - getRoot()->removeItemID(item->getListener()->getUUID()); - removeChild(item); -} - -bool LLFolderViewFolder::isTrash() const -{ - if (mAmTrash == LLFolderViewFolder::UNKNOWN) - { - mAmTrash = mListener->getUUID() == gInventory.findCategoryUUIDForType(LLAssetType::AT_TRASH, false) ? LLFolderViewFolder::TRASH : LLFolderViewFolder::NOT_TRASH; - } - return mAmTrash == LLFolderViewFolder::TRASH; -} - -void LLFolderViewFolder::sortBy(U32 order) -{ - if (!mSortFunction.updateSort(order)) - { - // No changes. - return; - } - - // Propegate this change to sub folders - for (folders_t::iterator iter = mFolders.begin(); - iter != mFolders.end();) - { - folders_t::iterator fit = iter++; - (*fit)->sortBy(order); - } - - mFolders.sort(mSortFunction); - mItems.sort(mSortFunction); - - if (order & LLInventoryFilter::SO_DATE) - { - time_t latest = 0; - - if (!mItems.empty()) - { - LLFolderViewItem* item = *(mItems.begin()); - latest = item->getCreationDate(); - } - - if (!mFolders.empty()) - { - LLFolderViewFolder* folder = *(mFolders.begin()); - if (folder->getCreationDate() > latest) - { - latest = folder->getCreationDate(); - } - } - mSubtreeCreationDate = latest; - } -} - -void LLFolderViewFolder::setItemSortOrder(U32 ordering) -{ - if (mSortFunction.updateSort(ordering)) - { - for (folders_t::iterator iter = mFolders.begin(); - iter != mFolders.end();) - { - folders_t::iterator fit = iter++; - (*fit)->setItemSortOrder(ordering); - } - - mFolders.sort(mSortFunction); - mItems.sort(mSortFunction); - } -} - -EInventorySortGroup LLFolderViewFolder::getSortGroup() const -{ - if (isTrash()) - { - return SG_TRASH_FOLDER; - } - - // Folders that can't be moved are 'system' folders. - if( mListener ) - { - if( !(mListener->isItemMovable()) ) - { - return SG_SYSTEM_FOLDER; - } - } - - return SG_NORMAL_FOLDER; -} - -BOOL LLFolderViewFolder::isMovable() -{ - if( mListener ) - { - if( !(mListener->isItemMovable()) ) - { - return FALSE; - } - - for (items_t::iterator iter = mItems.begin(); - iter != mItems.end();) - { - items_t::iterator iit = iter++; - if(!(*iit)->isMovable()) - { - return FALSE; - } - } - - for (folders_t::iterator iter = mFolders.begin(); - iter != mFolders.end();) - { - folders_t::iterator fit = iter++; - if(!(*fit)->isMovable()) - { - return FALSE; - } - } - } - return TRUE; -} - - -BOOL LLFolderViewFolder::isRemovable() -{ - if( mListener ) - { - if( !(mListener->isItemRemovable()) ) - { - return FALSE; - } - - for (items_t::iterator iter = mItems.begin(); - iter != mItems.end();) - { - items_t::iterator iit = iter++; - if(!(*iit)->isRemovable()) - { - return FALSE; - } - } - - for (folders_t::iterator iter = mFolders.begin(); - iter != mFolders.end();) - { - folders_t::iterator fit = iter++; - if(!(*fit)->isRemovable()) - { - return FALSE; - } - } - } - return TRUE; -} - -// this is an internal method used for adding items to folders. -BOOL LLFolderViewFolder::addItem(LLFolderViewItem* item) -{ - mItems.push_back(item); - item->setRect(LLRect(0, 0, getRect().getWidth(), 0)); - item->setVisible(FALSE); - addChild( item ); - item->dirtyFilter(); - requestArrange(); - requestSort(); - return TRUE; -} - -// this is an internal method used for adding items to folders. -BOOL LLFolderViewFolder::addFolder(LLFolderViewFolder* folder) -{ - mFolders.push_back(folder); - folder->setOrigin(0, 0); - folder->reshape(getRect().getWidth(), 0); - folder->setVisible(FALSE); - addChild( folder ); - folder->dirtyFilter(); - // rearrange all descendants too, as our indentation level might have changed - folder->requestArrange(TRUE); - requestSort(); - return TRUE; -} - -void LLFolderViewFolder::requestArrange(BOOL include_descendants) -{ - mLastArrangeGeneration = -1; - // flag all items up to root - if (mParentFolder) - { - mParentFolder->requestArrange(); - } - - if (include_descendants) - { - for (folders_t::iterator iter = mFolders.begin(); - iter != mFolders.end(); - ++iter) - { - (*iter)->requestArrange(TRUE); - } - } -} - -void LLFolderViewFolder::toggleOpen() -{ - setOpen(!mIsOpen); -} - -// Force a folder open or closed -void LLFolderViewFolder::setOpen(BOOL openitem) -{ - setOpenArrangeRecursively(openitem); -} - -void LLFolderViewFolder::setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse) -{ - BOOL was_open = mIsOpen; - mIsOpen = openitem; - if(!was_open && openitem) - { - if(mListener) - { - mListener->openItem(); - } - } - - if (recurse == RECURSE_DOWN || recurse == RECURSE_UP_DOWN) - { - for (folders_t::iterator iter = mFolders.begin(); - iter != mFolders.end();) - { - folders_t::iterator fit = iter++; - (*fit)->setOpenArrangeRecursively(openitem, RECURSE_DOWN); /* Flawfinder: ignore */ - } - } - if (mParentFolder && (recurse == RECURSE_UP || recurse == RECURSE_UP_DOWN)) - { - mParentFolder->setOpenArrangeRecursively(openitem, RECURSE_UP); - } - - if (was_open != mIsOpen) - { - requestArrange(); - } -} - -BOOL LLFolderViewFolder::handleDragAndDropFromChild(MASK mask, - BOOL drop, - EDragAndDropType c_type, - void* cargo_data, - EAcceptance* accept, - std::string& tooltip_msg) -{ - BOOL accepted = mListener && mListener->dragOrDrop(mask,drop,c_type,cargo_data); - if (accepted) - { - mDragAndDropTarget = TRUE; - *accept = ACCEPT_YES_MULTI; - } - else - { - *accept = ACCEPT_NO; - } - - // drag and drop to child item, so clear pending auto-opens - getRoot()->autoOpenTest(NULL); - - return TRUE; -} - -void LLFolderViewFolder::openItem( void ) -{ - toggleOpen(); -} - -void LLFolderViewFolder::applyFunctorRecursively(LLFolderViewFunctor& functor) -{ - functor.doFolder(this); - - for (folders_t::iterator iter = mFolders.begin(); - iter != mFolders.end();) - { - folders_t::iterator fit = iter++; - (*fit)->applyFunctorRecursively(functor); - } - for (items_t::iterator iter = mItems.begin(); - iter != mItems.end();) - { - items_t::iterator iit = iter++; - functor.doItem((*iit)); - } -} - -void LLFolderViewFolder::applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor) -{ - functor(mListener); - for (folders_t::iterator iter = mFolders.begin(); - iter != mFolders.end();) - { - folders_t::iterator fit = iter++; - (*fit)->applyListenerFunctorRecursively(functor); - } - for (items_t::iterator iter = mItems.begin(); - iter != mItems.end();) - { - items_t::iterator iit = iter++; - (*iit)->applyListenerFunctorRecursively(functor); - } -} - -// LLView functionality -BOOL LLFolderViewFolder::handleDragAndDrop(S32 x, S32 y, MASK mask, - BOOL drop, - EDragAndDropType cargo_type, - void* cargo_data, - EAcceptance* accept, - std::string& tooltip_msg) -{ - LLFolderView* root_view = getRoot(); - - BOOL handled = FALSE; - if(mIsOpen) - { - handled = childrenHandleDragAndDrop(x, y, mask, drop, cargo_type, - cargo_data, accept, tooltip_msg) != NULL; - } - - if (!handled) - { - BOOL accepted = mListener && mListener->dragOrDrop(mask, drop,cargo_type,cargo_data); - - if (accepted) - { - mDragAndDropTarget = TRUE; - *accept = ACCEPT_YES_MULTI; - } - else - { - *accept = ACCEPT_NO; - } - - if (!drop && accepted) - { - root_view->autoOpenTest(this); - } - - lldebugst(LLERR_USER_INPUT) << "dragAndDrop handled by LLFolderViewFolder" << llendl; - } - - return TRUE; -} - - -BOOL LLFolderViewFolder::handleRightMouseDown( S32 x, S32 y, MASK mask ) -{ - BOOL handled = FALSE; - // fetch contents of this folder, as context menu can depend on contents - // still, user would have to open context menu again to see the changes - gInventory.fetchDescendentsOf(mListener->getUUID()); - - if( mIsOpen ) - { - handled = childrenHandleRightMouseDown( x, y, mask ) != NULL; - } - if (!handled) - { - handled = LLFolderViewItem::handleRightMouseDown( x, y, mask ); - } - return handled; -} - - -BOOL LLFolderViewFolder::handleHover(S32 x, S32 y, MASK mask) -{ - BOOL handled = LLView::handleHover(x, y, mask); - - if (!handled) - { - // this doesn't do child processing - handled = LLFolderViewItem::handleHover(x, y, mask); - } - - //if(x < LEFT_INDENTATION + mIndentation && x > mIndentation - LEFT_PAD && y > getRect().getHeight() - ) - //{ - // gViewerWindow->setCursor(UI_CURSOR_ARROW); - // mExpanderHighlighted = TRUE; - // handled = TRUE; - //} - return handled; -} - -BOOL LLFolderViewFolder::handleMouseDown( S32 x, S32 y, MASK mask ) -{ - BOOL handled = FALSE; - if( mIsOpen ) - { - handled = childrenHandleMouseDown(x,y,mask) != NULL; - } - if( !handled ) - { - if(x < LEFT_INDENTATION + mIndentation && x > mIndentation - LEFT_PAD) - { - toggleOpen(); - handled = TRUE; - } - else - { - // do normal selection logic - handled = LLFolderViewItem::handleMouseDown(x, y, mask); - } - } - - return handled; -} - -BOOL LLFolderViewFolder::handleDoubleClick( S32 x, S32 y, MASK mask ) -{ - BOOL handled = FALSE; - if( mIsOpen ) - { - handled = childrenHandleDoubleClick( x, y, mask ) != NULL; - } - if( !handled ) - { - if(x < LEFT_INDENTATION + mIndentation && x > mIndentation - LEFT_PAD) - { - // don't select when user double-clicks plus sign - // so as not to contradict single-click behavior - toggleOpen(); - } - else - { - setSelectionFromRoot(this, FALSE); - toggleOpen(); - } - handled = TRUE; - } - return handled; -} - -void LLFolderViewFolder::draw() -{ - if (mAutoOpenCountdown != 0.f) - { - mControlLabelRotation = mAutoOpenCountdown * -90.f; - } - else if (mIsOpen) - { - mControlLabelRotation = lerp(mControlLabelRotation, -90.f, LLCriticalDamp::getInterpolant(0.04f)); - } - else - { - mControlLabelRotation = lerp(mControlLabelRotation, 0.f, LLCriticalDamp::getInterpolant(0.025f)); - } - - bool possibly_has_children = false; - bool up_to_date = mListener && mListener->isUpToDate(); - if(!up_to_date && mListener && mListener->hasChildren()) // we know we have children but haven't fetched them (doesn't obey filter) - { - possibly_has_children = true; - } - - - BOOL loading = ( mIsOpen && possibly_has_children && !up_to_date ); - - if ( loading && !mIsLoading ) - { - // Measure how long we've been in the loading state - mTimeSinceRequestStart.reset(); - } - - mIsLoading = loading; - - LLFolderViewItem::draw(); - - // draw children if root folder, or any other folder that is open or animating to closed state - if( getRoot() == this || (mIsOpen || mCurHeight != mTargetHeight )) - { - LLView::draw(); - } - - mExpanderHighlighted = FALSE; -} - -time_t LLFolderViewFolder::getCreationDate() const -{ - return llmax<time_t>(mCreationDate, mSubtreeCreationDate); -} - - -BOOL LLFolderViewFolder::potentiallyVisible() -{ - // folder should be visible by it's own filter status - return LLFolderViewItem::potentiallyVisible() - // or one or more of its descendants have passed the minimum filter requirement - || hasFilteredDescendants(getRoot()->getFilter()->getMinRequiredGeneration()) - // or not all of its descendants have been checked against minimum filter requirement - || getCompletedFilterGeneration() < getRoot()->getFilter()->getMinRequiredGeneration(); -} - -// this does prefix traversal, as folders are listed above their contents -LLFolderViewItem* LLFolderViewFolder::getNextFromChild( LLFolderViewItem* item, BOOL include_children ) -{ - BOOL found_item = FALSE; - - LLFolderViewItem* result = NULL; - // when not starting from a given item, start at beginning - if(item == NULL) - { - found_item = TRUE; - } - - // find current item among children - folders_t::iterator fit = mFolders.begin(); - folders_t::iterator fend = mFolders.end(); - - items_t::iterator iit = mItems.begin(); - items_t::iterator iend = mItems.end(); - - // if not trivially starting at the beginning, we have to find the current item - if (!found_item) - { - // first, look among folders, since they are always above items - for(; fit != fend; ++fit) - { - if(item == (*fit)) - { - found_item = TRUE; - // if we are on downwards traversal - if (include_children && (*fit)->isOpen()) - { - // look for first descendant - return (*fit)->getNextFromChild(NULL, TRUE); - } - // otherwise advance to next folder - ++fit; - include_children = TRUE; - break; - } - } - - // didn't find in folders? Check items... - if (!found_item) - { - for(; iit != iend; ++iit) - { - if(item == (*iit)) - { - found_item = TRUE; - // point to next item - ++iit; - break; - } - } - } - } - - if (!found_item) - { - // you should never call this method with an item that isn't a child - // so we should always find something - llassert(FALSE); - return NULL; - } - - // at this point, either iit or fit point to a candidate "next" item - // if both are out of range, we need to punt up to our parent - - // now, starting from found folder, continue through folders - // searching for next visible folder - while(fit != fend && !(*fit)->getVisible()) - { - // turn on downwards traversal for next folder - ++fit; - } - - if (fit != fend) - { - result = (*fit); - } - else - { - // otherwise, scan for next visible item - while(iit != iend && !(*iit)->getVisible()) - { - ++iit; - } - - // check to see if we have a valid item - if (iit != iend) - { - result = (*iit); - } - } - - if( !result && mParentFolder ) - { - // If there are no siblings or children to go to, recurse up one level in the tree - // and skip children for this folder, as we've already discounted them - result = mParentFolder->getNextFromChild(this, FALSE); - } - - return result; -} - -// this does postfix traversal, as folders are listed above their contents -LLFolderViewItem* LLFolderViewFolder::getPreviousFromChild( LLFolderViewItem* item, BOOL include_children ) -{ - BOOL found_item = FALSE; - - LLFolderViewItem* result = NULL; - // when not starting from a given item, start at end - if(item == NULL) - { - found_item = TRUE; - } - - // find current item among children - folders_t::reverse_iterator fit = mFolders.rbegin(); - folders_t::reverse_iterator fend = mFolders.rend(); - - items_t::reverse_iterator iit = mItems.rbegin(); - items_t::reverse_iterator iend = mItems.rend(); - - // if not trivially starting at the end, we have to find the current item - if (!found_item) - { - // first, look among items, since they are always below the folders - for(; iit != iend; ++iit) - { - if(item == (*iit)) - { - found_item = TRUE; - // point to next item - ++iit; - break; - } - } - - // didn't find in items? Check folders... - if (!found_item) - { - for(; fit != fend; ++fit) - { - if(item == (*fit)) - { - found_item = TRUE; - // point to next folder - ++fit; - break; - } - } - } - } - - if (!found_item) - { - // you should never call this method with an item that isn't a child - // so we should always find something - llassert(FALSE); - return NULL; - } - - // at this point, either iit or fit point to a candidate "next" item - // if both are out of range, we need to punt up to our parent - - // now, starting from found item, continue through items - // searching for next visible item - while(iit != iend && !(*iit)->getVisible()) - { - ++iit; - } - - if (iit != iend) - { - // we found an appropriate item - result = (*iit); - } - else - { - // otherwise, scan for next visible folder - while(fit != fend && !(*fit)->getVisible()) - { - ++fit; - } - - // check to see if we have a valid folder - if (fit != fend) - { - // try selecting child element of this folder - if ((*fit)->isOpen()) - { - result = (*fit)->getPreviousFromChild(NULL); - } - else - { - result = (*fit); - } - } - } - - if( !result ) - { - // If there are no siblings or children to go to, recurse up one level in the tree - // which gets back to this folder, which will only be visited if it is a valid, visible item - result = this; - } - - return result; -} - //--------------------------------------------------------------------------- @@ -2514,7 +180,7 @@ LLFolderView::LLFolderView(const Params& p) mNeedsAutoRename(FALSE), mDebugFilters(FALSE), mSortOrder(LLInventoryFilter::SO_FOLDERS_BY_NAME), // This gets overridden by a pref immediately - mFilter(p.name), + mFilter( new LLInventoryFilter(p.name) ), mShowSelectionContext(FALSE), mShowSingleSelection(FALSE), mArrangeGeneration(0), @@ -2557,7 +223,7 @@ LLFolderView::LLFolderView(const Params& p) addChild(mRenamer); // make the popup menu available - LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_inventory.xml", gMenuHolder); + LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_inventory.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); if (!menu) { menu = LLUICtrlFactory::getDefaultWidget<LLMenuGL>("inventory_menu"); @@ -2600,6 +266,9 @@ LLFolderView::~LLFolderView( void ) mFolders.clear(); mItemMap.clear(); + + delete mFilter; + mFilter = NULL; } BOOL LLFolderView::canFocusChildren() const @@ -2646,7 +315,7 @@ U32 LLFolderView::getSortOrder() const BOOL LLFolderView::addFolder( LLFolderViewFolder* folder) { // enforce sort order of My Inventory followed by Library - if (folder->getListener()->getUUID() == gInventoryLibraryRoot) + if (folder->getListener()->getUUID() == gInventory.getLibraryRootFolderID()) { mFolders.push_back(folder); } @@ -2693,14 +362,15 @@ S32 LLFolderView::arrange( S32* unused_width, S32* unused_height, S32 filter_gen { LLFastTimer t2(LLFastTimer::FTM_ARRANGE); - filter_generation = mFilter.getMinRequiredGeneration(); + filter_generation = mFilter->getMinRequiredGeneration(); mMinWidth = 0; mHasVisibleChildren = hasFilteredDescendants(filter_generation); // arrange always finishes, so optimistically set the arrange generation to the most current mLastArrangeGeneration = getRoot()->getArrangeGeneration(); - LLInventoryFilter::EFolderShow show_folder_state = getRoot()->getShowFolderState(); + LLInventoryFilter::EFolderShow show_folder_state = + getRoot()->getFilter()->getShowFolderState(); S32 total_width = LEFT_PAD; S32 running_height = mDebugFilters ? llceil(sSmallFont->getLineHeight()) : 0; @@ -2781,7 +451,7 @@ S32 LLFolderView::arrange( S32* unused_width, S32* unused_height, S32 filter_gen const std::string LLFolderView::getFilterSubString(BOOL trim) { - return mFilter.getFilterSubString(trim); + return mFilter->getFilterSubString(trim); } void LLFolderView::filter( LLInventoryFilter& filter ) @@ -2904,7 +574,7 @@ void LLFolderView::setSelectionByID(const LLUUID& obj_id, BOOL take_keyboard_foc LLFolderViewItem* itemp = getItemByID(obj_id); if(itemp && itemp->getListener()) { - itemp->getListener()->arrangeAndSet(itemp, TRUE, take_keyboard_focus); + itemp->arrangeAndSet(TRUE, take_keyboard_focus); mSelectThisID.setNull(); return; } @@ -2997,7 +667,7 @@ void LLFolderView::sanitizeSelection() LLFolderViewItem* original_selected_item = getCurSelectedItem(); // Cache "Show all folders" filter setting - BOOL show_all_folders = (getRoot()->getShowFolderState() == LLInventoryFilter::SHOW_ALL_FOLDERS); + BOOL show_all_folders = (getRoot()->getFilter()->getShowFolderState() == LLInventoryFilter::SHOW_ALL_FOLDERS); std::vector<LLFolderViewItem*> items_to_remove; selected_items_t::iterator item_iter; @@ -3087,7 +757,7 @@ void LLFolderView::sanitizeSelection() else { // nothing selected to start with, so pick "My Inventory" as best guess - new_selection = getItemByID(gAgent.getInventoryRootID()); + new_selection = getItemByID(gInventory.getRootFolderID()); } if (new_selection) @@ -3148,11 +818,11 @@ void LLFolderView::commitRename( const LLSD& data ) void LLFolderView::draw() { - static LLUIColor sSearchStatusColor = LLUIColorTable::instance().getColor("InventorySearchStatusColor", DEFAULT_WHITE); + static LLUIColor sSearchStatusColor = LLUIColorTable::instance().getColor("InventorySearchStatusColor", LLColor4::white); if (mDebugFilters) { std::string current_filter_string = llformat("Current Filter: %d, Least Filter: %d, Auto-accept Filter: %d", - mFilter.getCurrentGeneration(), mFilter.getMinRequiredGeneration(), mFilter.getMustPassGeneration()); + mFilter->getCurrentGeneration(), mFilter->getMinRequiredGeneration(), mFilter->getMustPassGeneration()); sSmallFont->renderUTF8(current_filter_string, 0, 2, getRect().getHeight() - sSmallFont->getLineHeight(), LLColor4(0.5f, 0.5f, 0.8f, 1.f), LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE ); @@ -3189,13 +859,14 @@ void LLFolderView::draw() mSearchString.clear(); } - if (hasVisibleChildren() || getShowFolderState() == LLInventoryFilter::SHOW_ALL_FOLDERS) + if (hasVisibleChildren() + || mFilter->getShowFolderState() == LLInventoryFilter::SHOW_ALL_FOLDERS) { mStatusText.clear(); } else { - if (gInventory.backgroundFetchActive() || mCompletedFilterGeneration < mFilter.getMinRequiredGeneration()) + if (gInventory.backgroundFetchActive() || mCompletedFilterGeneration < mFilter->getMinRequiredGeneration()) { mStatusText = LLTrans::getString("Searching"); sFont->renderUTF8(mStatusText, 0, 2, 1, sSearchStatusColor, LLFontGL::LEFT, LLFontGL::TOP, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE ); @@ -4292,9 +1963,9 @@ void LLFolderView::doIdle() arrangeAll(); } - mFilter.clearModified(); - BOOL filter_modified_and_active = mCompletedFilterGeneration < mFilter.getCurrentGeneration() && - mFilter.isNotDefault(); + mFilter->clearModified(); + BOOL filter_modified_and_active = mCompletedFilterGeneration < mFilter->getCurrentGeneration() && + mFilter->isNotDefault(); mNeedsAutoSelect = filter_modified_and_active && !(gFocusMgr.childHasKeyboardFocus(this) || gFocusMgr.getMouseCapture()); @@ -4335,7 +2006,7 @@ void LLFolderView::doIdle() { scrollToShowItem(mSelectedItems.back()); // continue scrolling until animated layout change is done - if (getCompletedFilterGeneration() >= mFilter.getMinRequiredGeneration() && + if (getCompletedFilterGeneration() >= mFilter->getMinRequiredGeneration() && (!needsArrange() || !is_visible)) { mNeedsScroll = FALSE; @@ -4402,82 +2073,51 @@ void LLFolderView::updateRenamerPosition() ///---------------------------------------------------------------------------- /// Local function definitions ///---------------------------------------------------------------------------- -bool LLInventorySort::updateSort(U32 order) + +//static +void LLFolderView::onRenamerLost( LLFocusableElement* renamer, void* user_data) { - if (order != mSortOrder) + LLUICtrl* uictrl = dynamic_cast<LLUICtrl*>(renamer); + if (uictrl) { - mSortOrder = order; - mByDate = (order & LLInventoryFilter::SO_DATE); - mSystemToTop = (order & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP); - mFoldersByName = (order & LLInventoryFilter::SO_FOLDERS_BY_NAME); - return true; + uictrl->setVisible(FALSE); } - return false; } -bool LLInventorySort::operator()(const LLFolderViewItem* const& a, const LLFolderViewItem* const& b) +LLInventoryFilter* LLFolderView::getFilter() { - // We sort by name if we aren't sorting by date - // OR if these are folders and we are sorting folders by name. - bool by_name = (!mByDate - || (mFoldersByName - && (a->getSortGroup() != SG_ITEM))); - - if (a->getSortGroup() != b->getSortGroup()) - { - if (mSystemToTop) - { - // Group order is System Folders, Trash, Normal Folders, Items - return (a->getSortGroup() < b->getSortGroup()); - } - else if (mByDate) - { - // Trash needs to go to the bottom if we are sorting by date - if ( (a->getSortGroup() == SG_TRASH_FOLDER) - || (b->getSortGroup() == SG_TRASH_FOLDER)) - { - return (b->getSortGroup() == SG_TRASH_FOLDER); - } - } - } + return mFilter; +} - if (by_name) - { - S32 compare = LLStringUtil::compareDict(a->getLabel(), b->getLabel()); - if (0 == compare) - { - return (a->getCreationDate() > b->getCreationDate()); - } - else - { - return (compare < 0); - } - } - else - { - // BUG: This is very very slow. The getCreationDate() is log n in number - // of inventory items. - time_t first_create = a->getCreationDate(); - time_t second_create = b->getCreationDate(); - if (first_create == second_create) - { - return (LLStringUtil::compareDict(a->getLabel(), b->getLabel()) < 0); - } - else - { - return (first_create > second_create); - } - } +void LLFolderView::setFilterPermMask( PermissionMask filter_perm_mask ) +{ + mFilter->setFilterPermissions(filter_perm_mask); } -//static -void LLFolderView::onRenamerLost( LLFocusableElement* renamer, void* user_data) +U32 LLFolderView::getFilterTypes() const { - LLUICtrl* uictrl = dynamic_cast<LLUICtrl*>(renamer); - if (uictrl) - { - uictrl->setVisible(FALSE); - } + return mFilter->getFilterTypes(); +} + +PermissionMask LLFolderView::getFilterPermissions() const +{ + return mFilter->getFilterPermissions(); +} + +// JAMESDEBUG +//LLInventoryFilter::EFolderShow LLFolderView::getShowFolderState() +//{ +// return mFilter->getShowFolderState(); +//} + +BOOL LLFolderView::isFilterModified() +{ + return mFilter->isNotDefault(); +} + +BOOL LLFolderView::getAllowMultiSelect() +{ + return mAllowMultiSelect; } void delete_selected_item(void* user_data) @@ -4524,610 +2164,3 @@ void properties_selected_items(void* user_data) fv->propertiesSelectedItems(); } } - -///---------------------------------------------------------------------------- -/// Class LLFolderViewEventListener -///---------------------------------------------------------------------------- - -void LLFolderViewEventListener::arrangeAndSet(LLFolderViewItem* focus, - BOOL set_selection, - BOOL take_keyboard_focus) -{ - if(!focus) return; - LLFolderView* root = focus->getRoot(); - focus->getParentFolder()->requestArrange(); - if(set_selection) - { - focus->setSelectionFromRoot(focus, TRUE, take_keyboard_focus); - if(root) - { - root->scrollToShowSelection(); - } - } -} - - -///---------------------------------------------------------------------------- -/// Class LLInventoryFilter -///---------------------------------------------------------------------------- -LLInventoryFilter::LLInventoryFilter(const std::string& name) : - mName(name), - mModified(FALSE), - mNeedTextRebuild(TRUE) -{ - mFilterOps.mFilterTypes = 0xffffffff; - mFilterOps.mMinDate = time_min(); - mFilterOps.mMaxDate = time_max(); - mFilterOps.mHoursAgo = 0; - mFilterOps.mShowFolderState = SHOW_NON_EMPTY_FOLDERS; - mFilterOps.mPermissions = PERM_NONE; - - mOrder = SO_FOLDERS_BY_NAME; // This gets overridden by a pref immediately - - mSubStringMatchOffset = 0; - mFilterSubString.clear(); - mFilterGeneration = 0; - mMustPassGeneration = S32_MAX; - mMinRequiredGeneration = 0; - mFilterCount = 0; - mNextFilterGeneration = mFilterGeneration + 1; - - mLastLogoff = gSavedPerAccountSettings.getU32("LastLogoff"); - mFilterBehavior = FILTER_NONE; - - // copy mFilterOps into mDefaultFilterOps - markDefault(); -} - -LLInventoryFilter::~LLInventoryFilter() -{ -} - -BOOL LLInventoryFilter::check(LLFolderViewItem* item) -{ - time_t earliest; - - earliest = time_corrected() - mFilterOps.mHoursAgo * 3600; - if (mFilterOps.mMinDate > time_min() && mFilterOps.mMinDate < earliest) - { - earliest = mFilterOps.mMinDate; - } - else if (!mFilterOps.mHoursAgo) - { - earliest = 0; - } - LLFolderViewEventListener* listener = item->getListener(); - mSubStringMatchOffset = mFilterSubString.size() ? item->getSearchableLabel().find(mFilterSubString) : std::string::npos; - BOOL passed = (0x1 << listener->getInventoryType() & mFilterOps.mFilterTypes || listener->getInventoryType() == LLInventoryType::IT_NONE) - && (mFilterSubString.size() == 0 || mSubStringMatchOffset != std::string::npos) - && ((listener->getPermissionMask() & mFilterOps.mPermissions) == mFilterOps.mPermissions) - && (listener->getCreationDate() >= earliest && listener->getCreationDate() <= mFilterOps.mMaxDate); - return passed; -} - -const std::string LLInventoryFilter::getFilterSubString(BOOL trim) -{ - return mFilterSubString; -} - -std::string::size_type LLInventoryFilter::getStringMatchOffset() const -{ - return mSubStringMatchOffset; -} - -// has user modified default filter params? -BOOL LLInventoryFilter::isNotDefault() -{ - return mFilterOps.mFilterTypes != mDefaultFilterOps.mFilterTypes - || mFilterSubString.size() - || mFilterOps.mPermissions != mDefaultFilterOps.mPermissions - || mFilterOps.mMinDate != mDefaultFilterOps.mMinDate - || mFilterOps.mMaxDate != mDefaultFilterOps.mMaxDate - || mFilterOps.mHoursAgo != mDefaultFilterOps.mHoursAgo; -} - -BOOL LLInventoryFilter::isActive() -{ - return mFilterOps.mFilterTypes != 0xffffffff - || mFilterSubString.size() - || mFilterOps.mPermissions != PERM_NONE - || mFilterOps.mMinDate != time_min() - || mFilterOps.mMaxDate != time_max() - || mFilterOps.mHoursAgo != 0; -} - -BOOL LLInventoryFilter::isModified() -{ - return mModified; -} - -BOOL LLInventoryFilter::isModifiedAndClear() -{ - BOOL ret = mModified; - mModified = FALSE; - return ret; -} - -void LLInventoryFilter::setFilterTypes(U32 types) -{ - if (mFilterOps.mFilterTypes != types) - { - // keep current items only if no type bits getting turned off - BOOL fewer_bits_set = (mFilterOps.mFilterTypes & ~types); - BOOL more_bits_set = (~mFilterOps.mFilterTypes & types); - - mFilterOps.mFilterTypes = types; - if (more_bits_set && fewer_bits_set) - { - // neither less or more restrive, both simultaneously - // so we need to filter from scratch - setModified(FILTER_RESTART); - } - else if (more_bits_set) - { - // target is only one of all requested types so more type bits == less restrictive - setModified(FILTER_LESS_RESTRICTIVE); - } - else if (fewer_bits_set) - { - setModified(FILTER_MORE_RESTRICTIVE); - } - - } -} - -void LLInventoryFilter::setFilterSubString(const std::string& string) -{ - if (mFilterSubString != string) - { - // hitting BACKSPACE, for example - BOOL less_restrictive = mFilterSubString.size() >= string.size() && !mFilterSubString.substr(0, string.size()).compare(string); - // appending new characters - BOOL more_restrictive = mFilterSubString.size() < string.size() && !string.substr(0, mFilterSubString.size()).compare(mFilterSubString); - mFilterSubString = string; - LLStringUtil::toUpper(mFilterSubString); - LLStringUtil::trimHead(mFilterSubString); - - if (less_restrictive) - { - setModified(FILTER_LESS_RESTRICTIVE); - } - else if (more_restrictive) - { - setModified(FILTER_MORE_RESTRICTIVE); - } - else - { - setModified(FILTER_RESTART); - } - } -} - -void LLInventoryFilter::setFilterPermissions(PermissionMask perms) -{ - if (mFilterOps.mPermissions != perms) - { - // keep current items only if no perm bits getting turned off - BOOL fewer_bits_set = (mFilterOps.mPermissions & ~perms); - BOOL more_bits_set = (~mFilterOps.mPermissions & perms); - mFilterOps.mPermissions = perms; - - if (more_bits_set && fewer_bits_set) - { - setModified(FILTER_RESTART); - } - else if (more_bits_set) - { - // target must have all requested permission bits, so more bits == more restrictive - setModified(FILTER_MORE_RESTRICTIVE); - } - else if (fewer_bits_set) - { - setModified(FILTER_LESS_RESTRICTIVE); - } - } -} - -void LLInventoryFilter::setDateRange(time_t min_date, time_t max_date) -{ - mFilterOps.mHoursAgo = 0; - if (mFilterOps.mMinDate != min_date) - { - mFilterOps.mMinDate = min_date; - setModified(); - } - if (mFilterOps.mMaxDate != llmax(mFilterOps.mMinDate, max_date)) - { - mFilterOps.mMaxDate = llmax(mFilterOps.mMinDate, max_date); - setModified(); - } -} - -void LLInventoryFilter::setDateRangeLastLogoff(BOOL sl) -{ - if (sl && !isSinceLogoff()) - { - setDateRange(mLastLogoff, time_max()); - setModified(); - } - if (!sl && isSinceLogoff()) - { - setDateRange(0, time_max()); - setModified(); - } -} - -BOOL LLInventoryFilter::isSinceLogoff() -{ - return (mFilterOps.mMinDate == (time_t)mLastLogoff) && - (mFilterOps.mMaxDate == time_max()); -} - -void LLInventoryFilter::setHoursAgo(U32 hours) -{ - if (mFilterOps.mHoursAgo != hours) - { - // *NOTE: need to cache last filter time, in case filter goes stale - BOOL less_restrictive = (mFilterOps.mMinDate == time_min() && mFilterOps.mMaxDate == time_max() && hours > mFilterOps.mHoursAgo); - BOOL more_restrictive = (mFilterOps.mMinDate == time_min() && mFilterOps.mMaxDate == time_max() && hours <= mFilterOps.mHoursAgo); - mFilterOps.mHoursAgo = hours; - mFilterOps.mMinDate = time_min(); - mFilterOps.mMaxDate = time_max(); - if (less_restrictive) - { - setModified(FILTER_LESS_RESTRICTIVE); - } - else if (more_restrictive) - { - setModified(FILTER_MORE_RESTRICTIVE); - } - else - { - setModified(FILTER_RESTART); - } - } -} -void LLInventoryFilter::setShowFolderState(EFolderShow state) -{ - if (mFilterOps.mShowFolderState != state) - { - mFilterOps.mShowFolderState = state; - if (state == SHOW_NON_EMPTY_FOLDERS) - { - // showing fewer folders than before - setModified(FILTER_MORE_RESTRICTIVE); - } - else if (state == SHOW_ALL_FOLDERS) - { - // showing same folders as before and then some - setModified(FILTER_LESS_RESTRICTIVE); - } - else - { - setModified(); - } - } -} - -void LLInventoryFilter::setSortOrder(U32 order) -{ - if (mOrder != order) - { - mOrder = order; - setModified(); - } -} - -void LLInventoryFilter::markDefault() -{ - mDefaultFilterOps = mFilterOps; -} - -void LLInventoryFilter::resetDefault() -{ - mFilterOps = mDefaultFilterOps; - setModified(); -} - -void LLInventoryFilter::setModified(EFilterBehavior behavior) -{ - mModified = TRUE; - mNeedTextRebuild = TRUE; - mFilterGeneration = mNextFilterGeneration++; - - if (mFilterBehavior == FILTER_NONE) - { - mFilterBehavior = behavior; - } - else if (mFilterBehavior != behavior) - { - // trying to do both less restrictive and more restrictive filter - // basically means restart from scratch - mFilterBehavior = FILTER_RESTART; - } - - if (isNotDefault()) - { - // if not keeping current filter results, update last valid as well - switch(mFilterBehavior) - { - case FILTER_RESTART: - mMustPassGeneration = mFilterGeneration; - mMinRequiredGeneration = mFilterGeneration; - break; - case FILTER_LESS_RESTRICTIVE: - mMustPassGeneration = mFilterGeneration; - break; - case FILTER_MORE_RESTRICTIVE: - mMinRequiredGeneration = mFilterGeneration; - // must have passed either current filter generation (meaningless, as it hasn't been run yet) - // or some older generation, so keep the value - mMustPassGeneration = llmin(mMustPassGeneration, mFilterGeneration); - break; - default: - llerrs << "Bad filter behavior specified" << llendl; - } - } - else - { - // shortcut disabled filters to show everything immediately - mMinRequiredGeneration = 0; - mMustPassGeneration = S32_MAX; - } -} - -BOOL LLInventoryFilter::isFilterWith(LLInventoryType::EType t) -{ - return mFilterOps.mFilterTypes & (0x01 << t); -} - -std::string LLInventoryFilter::getFilterText() -{ - if (!mNeedTextRebuild) - { - return mFilterText; - } - - mNeedTextRebuild = FALSE; - std::string filtered_types; - std::string not_filtered_types; - BOOL filtered_by_type = FALSE; - BOOL filtered_by_all_types = TRUE; - S32 num_filter_types = 0; - mFilterText.clear(); - - if (isFilterWith(LLInventoryType::IT_ANIMATION)) - { - //filtered_types += " Animations,"; - filtered_types += LLTrans::getString("Animations"); - filtered_by_type = TRUE; - num_filter_types++; - } - else - { - //not_filtered_types += " Animations,"; - not_filtered_types += LLTrans::getString("Animations"); - - filtered_by_all_types = FALSE; - } - - if (isFilterWith(LLInventoryType::IT_CALLINGCARD)) - { - //filtered_types += " Calling Cards,"; - filtered_types += LLTrans::getString("Calling Cards"); - filtered_by_type = TRUE; - num_filter_types++; - } - else - { - //not_filtered_types += " Calling Cards,"; - not_filtered_types += LLTrans::getString("Calling Cards"); - filtered_by_all_types = FALSE; - } - - if (isFilterWith(LLInventoryType::IT_WEARABLE)) - { - //filtered_types += " Clothing,"; - filtered_types += LLTrans::getString("Clothing"); - filtered_by_type = TRUE; - num_filter_types++; - } - else - { - //not_filtered_types += " Clothing,"; - not_filtered_types += LLTrans::getString("Clothing"); - filtered_by_all_types = FALSE; - } - - if (isFilterWith(LLInventoryType::IT_GESTURE)) - { - //filtered_types += " Gestures,"; - filtered_types += LLTrans::getString("Gestures"); - filtered_by_type = TRUE; - num_filter_types++; - } - else - { - //not_filtered_types += " Gestures,"; - not_filtered_types += LLTrans::getString("Gestures"); - filtered_by_all_types = FALSE; - } - - if (isFilterWith(LLInventoryType::IT_LANDMARK)) - { - //filtered_types += " Landmarks,"; - filtered_types += LLTrans::getString("Landmarks"); - filtered_by_type = TRUE; - num_filter_types++; - } - else - { - //not_filtered_types += " Landmarks,"; - not_filtered_types += LLTrans::getString("Landmarks"); - filtered_by_all_types = FALSE; - } - - if (isFilterWith(LLInventoryType::IT_NOTECARD)) - { - //filtered_types += " Notecards,"; - filtered_types += LLTrans::getString("Notecards"); - filtered_by_type = TRUE; - num_filter_types++; - } - else - { - //not_filtered_types += " Notecards,"; - not_filtered_types += LLTrans::getString("Notecards"); - filtered_by_all_types = FALSE; - } - - if (isFilterWith(LLInventoryType::IT_OBJECT) && isFilterWith(LLInventoryType::IT_ATTACHMENT)) - { - //filtered_types += " Objects,"; - filtered_types += LLTrans::getString("Objects"); - filtered_by_type = TRUE; - num_filter_types++; - } - else - { - //not_filtered_types += " Objects,"; - not_filtered_types += LLTrans::getString("Objects"); - filtered_by_all_types = FALSE; - } - - if (isFilterWith(LLInventoryType::IT_LSL)) - { - //filtered_types += " Scripts,"; - filtered_types += LLTrans::getString("Scripts"); - filtered_by_type = TRUE; - num_filter_types++; - } - else - { - //not_filtered_types += " Scripts,"; - not_filtered_types += LLTrans::getString("Scripts"); - filtered_by_all_types = FALSE; - } - - if (isFilterWith(LLInventoryType::IT_SOUND)) - { - //filtered_types += " Sounds,"; - filtered_types += LLTrans::getString("Sounds"); - filtered_by_type = TRUE; - num_filter_types++; - } - else - { - //not_filtered_types += " Sounds,"; - not_filtered_types += LLTrans::getString("Sounds"); - filtered_by_all_types = FALSE; - } - - if (isFilterWith(LLInventoryType::IT_TEXTURE)) - { - //filtered_types += " Textures,"; - filtered_types += LLTrans::getString("Textures"); - filtered_by_type = TRUE; - num_filter_types++; - } - else - { - //not_filtered_types += " Textures,"; - not_filtered_types += LLTrans::getString("Textures"); - filtered_by_all_types = FALSE; - } - - if (isFilterWith(LLInventoryType::IT_SNAPSHOT)) - { - //filtered_types += " Snapshots,"; - filtered_types += LLTrans::getString("Snapshots"); - filtered_by_type = TRUE; - num_filter_types++; - } - else - { - //not_filtered_types += " Snapshots,"; - not_filtered_types += LLTrans::getString("Snapshots"); - filtered_by_all_types = FALSE; - } - - if (!gInventory.backgroundFetchActive() && filtered_by_type && !filtered_by_all_types) - { - mFilterText += " - "; - if (num_filter_types < 5) - { - mFilterText += filtered_types; - } - else - { - //mFilterText += "No "; - mFilterText += LLTrans::getString("No Filters"); - mFilterText += not_filtered_types; - } - // remove the ',' at the end - mFilterText.erase(mFilterText.size() - 1, 1); - } - - if (isSinceLogoff()) - { - //mFilterText += " - Since Logoff"; - mFilterText += LLTrans::getString("Since Logoff"); - } - return mFilterText; -} - -void LLInventoryFilter::toLLSD(LLSD& data) -{ - data["filter_types"] = (LLSD::Integer)getFilterTypes(); - data["min_date"] = (LLSD::Integer)getMinDate(); - data["max_date"] = (LLSD::Integer)getMaxDate(); - data["hours_ago"] = (LLSD::Integer)getHoursAgo(); - data["show_folder_state"] = (LLSD::Integer)getShowFolderState(); - data["permissions"] = (LLSD::Integer)getFilterPermissions(); - data["substring"] = (LLSD::String)getFilterSubString(); - data["sort_order"] = (LLSD::Integer)getSortOrder(); - data["since_logoff"] = (LLSD::Boolean)isSinceLogoff(); -} - -void LLInventoryFilter::fromLLSD(LLSD& data) -{ - if(data.has("filter_types")) - { - setFilterTypes((U32)data["filter_types"].asInteger()); - } - - if(data.has("min_date") && data.has("max_date")) - { - setDateRange(data["min_date"].asInteger(), data["max_date"].asInteger()); - } - - if(data.has("hours_ago")) - { - setHoursAgo((U32)data["hours_ago"].asInteger()); - } - - if(data.has("show_folder_state")) - { - setShowFolderState((EFolderShow)data["show_folder_state"].asInteger()); - } - - if(data.has("permissions")) - { - setFilterPermissions((PermissionMask)data["permissions"].asInteger()); - } - - if(data.has("substring")) - { - setFilterSubString(std::string(data["substring"].asString())); - } - - if(data.has("sort_order")) - { - setSortOrder((U32)data["sort_order"].asInteger()); - } - - if(data.has("since_logoff")) - { - setDateRangeLastLogoff((bool)data["since_logoff"].asBoolean()); - } -} diff --git a/indra/newview/llfolderview.h b/indra/newview/llfolderview.h index 3386a7fb0e..e8f0c4130e 100644 --- a/indra/newview/llfolderview.h +++ b/indra/newview/llfolderview.h @@ -41,6 +41,7 @@ #ifndef LL_LLFOLDERVIEW_H #define LL_LLFOLDERVIEW_H +// JAMESDEBUG - trim this list #include <vector> #include <map> #include <deque> @@ -57,96 +58,8 @@ #include "llviewerimage.h" #include "lldepthstack.h" #include "lltooldraganddrop.h" - -class LLMenuGL; - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// Class LLFolderViewEventListener -// -// This is an abstract base class that users of the folderview classes -// would use to catch the useful events emitted from the folder -// views. -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - -class LLFolderViewItem; -class LLFolderView; -class LLInventoryModel; -class LLScrollContainer; - -class LLFolderViewEventListener -{ -public: - virtual ~LLFolderViewEventListener( void ) {} - virtual const std::string& getName() const = 0; - virtual const std::string& getDisplayName() const = 0; - virtual const LLUUID& getUUID() const = 0; - virtual time_t getCreationDate() const = 0; // UTC seconds - virtual PermissionMask getPermissionMask() const = 0; - virtual LLAssetType::EType getPreferredType() const {return LLAssetType::AT_NONE;}; - virtual LLUIImagePtr getIcon() const = 0; - virtual LLFontGL::StyleFlags getLabelStyle() const = 0; - virtual std::string getLabelSuffix() const = 0; - virtual void openItem( void ) = 0; - virtual void previewItem( void ) = 0; - virtual void selectItem(void) = 0; - virtual void showProperties(void) = 0; - virtual BOOL isItemRenameable() const = 0; - virtual BOOL renameItem(const std::string& new_name) = 0; - virtual BOOL isItemMovable( void ) = 0; // Can be moved to another folder - virtual BOOL isItemRemovable( void ) = 0; // Can be destroyed - virtual BOOL removeItem() = 0; - virtual void removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch) = 0; - virtual void move( LLFolderViewEventListener* parent_listener ) = 0; - virtual BOOL isItemCopyable() const = 0; - virtual BOOL copyToClipboard() const = 0; - virtual void cutToClipboard() = 0; - virtual BOOL isClipboardPasteable() const = 0; - virtual void pasteFromClipboard() = 0; - virtual void pasteLinkFromClipboard() = 0; - virtual void buildContextMenu(LLMenuGL& menu, U32 flags) = 0; - virtual BOOL isUpToDate() const = 0; - virtual BOOL hasChildren() const = 0; - virtual LLInventoryType::EType getInventoryType() const = 0; - virtual void performAction(LLFolderView* folder, LLInventoryModel* model, std::string action) {} - - // This method should be called when a drag begins. returns TRUE - // if the drag can begin, otherwise FALSE. - virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const = 0; - - // This method will be called to determine if a drop can be - // performed, and will set drop to TRUE if a drop is - // requested. Returns TRUE if a drop is possible/happened, - // otherwise FALSE. - virtual BOOL dragOrDrop(MASK mask, BOOL drop, - EDragAndDropType cargo_type, - void* cargo_data) = 0; - - // This method is called when the object being referenced by the - // bridge is actually dropped. This allows for cleanup of the old - // view, reference counting, etc. -// virtual void dropped() = 0; - - // this method accesses the parent and arranges and sets it as - // specified. - void arrangeAndSet(LLFolderViewItem* focus, BOOL set_selection, - BOOL take_keyboard_focus = TRUE); -}; - - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// Class LLFolderViewListenerFunctor -// -// This simple abstract base class can be used to applied to all -// listeners in a hierarchy. -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -class LLFolderViewListenerFunctor -{ -public: - virtual ~LLFolderViewListenerFunctor() {} - virtual void operator()(LLFolderViewEventListener* listener) = 0; -}; +// JAMESDEBUG - move this up +#include "llfolderviewitem.h" // because LLFolderView is-a LLFolderViewFolder //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class LLFolderViewFunctor @@ -168,571 +81,6 @@ public: virtual void doItem(LLFolderViewItem* item) = 0; }; -class LLInventoryFilter -{ -public: - typedef enum e_folder_show - { - SHOW_ALL_FOLDERS, - SHOW_NON_EMPTY_FOLDERS, - SHOW_NO_FOLDERS - } EFolderShow; - - typedef enum e_filter_behavior - { - FILTER_NONE, // nothing to do, already filtered - FILTER_RESTART, // restart filtering from scratch - FILTER_LESS_RESTRICTIVE, // existing filtered items will certainly pass this filter - FILTER_MORE_RESTRICTIVE // if you didn't pass the previous filter, you definitely won't pass this one - } EFilterBehavior; - - static const U32 SO_DATE = 1; - static const U32 SO_FOLDERS_BY_NAME = 2; - static const U32 SO_SYSTEM_FOLDERS_TO_TOP = 4; - - LLInventoryFilter(const std::string& name); - virtual ~LLInventoryFilter(); - - void setFilterTypes(U32 types); - U32 getFilterTypes() const { return mFilterOps.mFilterTypes; } - - void setFilterSubString(const std::string& string); - const std::string getFilterSubString(BOOL trim = FALSE); - - void setFilterPermissions(PermissionMask perms); - PermissionMask getFilterPermissions() const { return mFilterOps.mPermissions; } - - void setDateRange(time_t min_date, time_t max_date); - void setDateRangeLastLogoff(BOOL sl); - time_t getMinDate() const { return mFilterOps.mMinDate; } - time_t getMaxDate() const { return mFilterOps.mMaxDate; } - - void setHoursAgo(U32 hours); - U32 getHoursAgo() const { return mFilterOps.mHoursAgo; } - - void setShowFolderState( EFolderShow state); - EFolderShow getShowFolderState() { return mFilterOps.mShowFolderState; } - - void setSortOrder(U32 order); - U32 getSortOrder() { return mOrder; } - - BOOL check(LLFolderViewItem* item); - std::string::size_type getStringMatchOffset() const; - BOOL isActive(); - BOOL isNotDefault(); - BOOL isModified(); - BOOL isModifiedAndClear(); - BOOL isSinceLogoff(); - void clearModified() { mModified = FALSE; mFilterBehavior = FILTER_NONE; } - const std::string getName() const { return mName; } - std::string getFilterText(); - - void setFilterCount(S32 count) { mFilterCount = count; } - S32 getFilterCount() { return mFilterCount; } - void decrementFilterCount() { mFilterCount--; } - - void markDefault(); - void resetDefault(); - - BOOL isFilterWith(LLInventoryType::EType t); - - S32 getCurrentGeneration() const { return mFilterGeneration; } - S32 getMinRequiredGeneration() const { return mMinRequiredGeneration; } - S32 getMustPassGeneration() const { return mMustPassGeneration; } - - //RN: this is public to allow system to externally force a global refilter - void setModified(EFilterBehavior behavior = FILTER_RESTART); - - void toLLSD(LLSD& data); - void fromLLSD(LLSD& data); - -protected: - struct filter_ops - { - U32 mFilterTypes; - time_t mMinDate; - time_t mMaxDate; - U32 mHoursAgo; - EFolderShow mShowFolderState; - PermissionMask mPermissions; - }; - filter_ops mFilterOps; - filter_ops mDefaultFilterOps; - std::string::size_type mSubStringMatchOffset; - std::string mFilterSubString; - U32 mOrder; - const std::string mName; - S32 mFilterGeneration; - S32 mMustPassGeneration; - S32 mMinRequiredGeneration; - S32 mFilterCount; - S32 mNextFilterGeneration; - EFilterBehavior mFilterBehavior; - -private: - U32 mLastLogoff; - BOOL mModified; - BOOL mNeedTextRebuild; - std::string mFilterText; -}; - -// These are grouping of inventory types. -// Order matters when sorting system folders to the top. -enum EInventorySortGroup -{ - SG_SYSTEM_FOLDER, - SG_TRASH_FOLDER, - SG_NORMAL_FOLDER, - SG_ITEM -}; - -class LLInventorySort -{ -public: - LLInventorySort() - : mSortOrder(0), - mByDate(false), - mSystemToTop(false), - mFoldersByName(false) { } - - // Returns true if order has changed - bool updateSort(U32 order); - U32 getSort() { return mSortOrder; } - - bool operator()(const LLFolderViewItem* const& a, const LLFolderViewItem* const& b); -private: - U32 mSortOrder; - bool mByDate; - bool mSystemToTop; - bool mFoldersByName; -}; - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// Class LLFolderViewItem -// -// An instance of this class represents a single item in a folder view -// such as an inventory item or a file. -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -class LLFontGL; -class LLFolderViewFolder; -class LLFolderView; - -class LLFolderViewItem : public LLView -{ -public: - static void initClass(); - static void cleanupClass(); - struct Params : public LLInitParam::Block<Params, LLUICtrl::Params> - { - Optional<LLUIImage*> icon; - Optional<LLFolderView*> root; - Optional<LLFolderViewEventListener*> listener; - - Optional<LLUIImage*> folder_arrow_image; - Optional<LLUIImage*> selection_image; - - Optional<S32> creation_date; //UTC seconds - Params() - : folder_arrow_image("", LLUI::getUIImage("folder_arrow.tga")), - selection_image("", LLUI::getUIImage("rounded_square.tga")) - { - mouse_opaque(true); - follows.flags(FOLLOWS_LEFT|FOLLOWS_TOP|FOLLOWS_RIGHT); - tab_stop(false); - } - }; - -protected: - friend class LLUICtrlFactory; - friend class LLFolderViewEventListener; - - LLFolderViewItem(Params = LLFolderViewItem::Params()); - - static const LLFontGL* sFont; - static const LLFontGL* sSmallFont; - static LLUIImagePtr sArrowImage; - static LLUIImagePtr sBoxImage; - std::string mLabel; - std::string mSearchableLabel; - S32 mLabelWidth; - bool mLabelWidthDirty; - time_t mCreationDate; - LLFolderViewFolder* mParentFolder; - LLFolderViewEventListener* mListener; - BOOL mIsSelected; - BOOL mIsCurSelection; - BOOL mSelectPending; - LLFontGL::StyleFlags mLabelStyle; - std::string mLabelSuffix; - LLUIImagePtr mIcon; - std::string mStatusText; - BOOL mHasVisibleChildren; - S32 mIndentation; - S32 mNumDescendantsSelected; - BOOL mFiltered; - S32 mLastFilterGeneration; - std::string::size_type mStringMatchOffset; - F32 mControlLabelRotation; - LLFolderView* mRoot; - BOOL mDragAndDropTarget; - LLUIImagePtr mArrowImage; - LLUIImagePtr mBoxImage; - BOOL mIsLoading; - LLTimer mTimeSinceRequestStart; - - // This function clears the currently selected item, and records - // the specified selected item appropriately for display and use - // in the UI. If open is TRUE, then folders are opened up along - // the way to the selection. - void setSelectionFromRoot(LLFolderViewItem* selection, BOOL openitem, - BOOL take_keyboard_focus = TRUE); - - // helper function to change the selection from the root. - void changeSelectionFromRoot(LLFolderViewItem* selection, BOOL selected); - - // helper function to change the selection from the root. - void extendSelectionFromRoot(LLFolderViewItem* selection); - - // this is an internal method used for adding items to folders. A - // no-op at this leve, but reimplemented in derived classes. - virtual BOOL addItem(LLFolderViewItem*) { return FALSE; } - virtual BOOL addFolder(LLFolderViewFolder*) { return FALSE; } - -public: - // This function is called when the folder view is dirty. It's - // implemented here but called by derived classes when folding the - // views. - void arrangeFromRoot(); - void filterFromRoot( void ); - - virtual ~LLFolderViewItem( void ); - - // addToFolder() returns TRUE if it succeeds. FALSE otherwise - enum { ARRANGE = TRUE, DO_NOT_ARRANGE = FALSE }; - virtual BOOL addToFolder(LLFolderViewFolder* folder, LLFolderView* root); - - virtual EInventorySortGroup getSortGroup() const; - - // Finds width and height of this object and it's children. Also - // makes sure that this view and it's children are the right size. - virtual S32 arrange( S32* width, S32* height, S32 filter_generation ); - virtual S32 getItemHeight(); - - // applies filters to control visibility of inventory items - virtual void filter( LLInventoryFilter& filter); - - // updates filter serial number and optionally propagated value up to root - S32 getLastFilterGeneration() { return mLastFilterGeneration; } - - virtual void dirtyFilter(); - - // If the selection is 'this' then note that otherwise - // ignore. Returns TRUE if this object was affected. If open is - // TRUE, then folders are opened up along the way to the - // selection. - virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem, - BOOL take_keyboard_focus); - - // This method is used to toggle the selection of an item. If - // selection is 'this', then note selection, and return TRUE. - virtual BOOL changeSelection(LLFolderViewItem* selection, BOOL selected); - - // this method is used to group select items - virtual S32 extendSelection(LLFolderViewItem* selection, LLFolderViewItem* last_selected, LLDynamicArray<LLFolderViewItem*>& 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<LLUUID> &selection){return TRUE;} - - // Returns true is this object and all of its children can be removed (deleted by user) - virtual BOOL isRemovable(); - - // Returns true is this object and all of its children can be moved - virtual BOOL isMovable(); - - // destroys this item recursively - virtual void destroyView(); - - S32 getNumSelectedDescendants() { return mNumDescendantsSelected; } - - BOOL isSelected() { return mIsSelected; } - - void setIsCurSelection(BOOL select) { mIsCurSelection = select; } - - BOOL getIsCurSelection() { return mIsCurSelection; } - - BOOL hasVisibleChildren() { return mHasVisibleChildren; } - - // Call through to the viewed object and return true if it can be - // removed. Returns true if it's removed. - //virtual BOOL removeRecursively(BOOL single_item); - BOOL remove(); - - // Build an appropriate context menu for the item. Flags unused. - void buildContextMenu(LLMenuGL& menu, U32 flags); - - // This method returns the actual name of the thing being - // viewed. This method will ask the viewed object itself. - const std::string& getName( void ) const; - - const std::string& getSearchableLabel( void ) const; - - // This method returns the label displayed on the view. This - // method was primarily added to allow sorting on the folder - // contents possible before the entire view has been constructed. - const std::string& getLabel() const { return mLabel; } - - // Used for sorting, like getLabel() above. - virtual time_t getCreationDate() const { return mCreationDate; } - - LLFolderViewFolder* getParentFolder( void ) { return mParentFolder; } - const LLFolderViewFolder* getParentFolder( void ) const { return mParentFolder; } - - LLFolderViewItem* getNextOpenNode( BOOL include_children = TRUE ); - LLFolderViewItem* getPreviousOpenNode( BOOL include_children = TRUE ); - - const LLFolderViewEventListener* getListener( void ) const { return mListener; } - LLFolderViewEventListener* getListener( void ) { return mListener; } - - // just rename the object. - void rename(const std::string& new_name); - - // open - virtual void openItem( void ); - virtual void preview(void); - - // Show children (unfortunate that this is called "open") - virtual void setOpen(BOOL open = TRUE) {}; - - virtual BOOL isOpen() { return FALSE; } - - virtual LLFolderView* getRoot(); - BOOL isDescendantOf( const LLFolderViewFolder* potential_ancestor ); - S32 getIndentation() { return mIndentation; } - - virtual BOOL potentiallyVisible(); // do we know for a fact that this item has been filtered out? - - virtual BOOL getFiltered(); - virtual BOOL getFiltered(S32 filter_generation); - virtual void setFiltered(BOOL filtered, S32 filter_generation); - - // change the icon - void setIcon(LLUIImagePtr icon); - - // refresh information from the object being viewed. - void refreshFromListener(); - virtual void refresh(); - - virtual void applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor); - - // LLView functionality - virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask ); - virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask ); - virtual BOOL handleHover( S32 x, S32 y, MASK mask ); - virtual BOOL handleMouseUp( S32 x, S32 y, MASK mask ); - virtual BOOL handleDoubleClick( S32 x, S32 y, MASK mask ); - virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); - - // virtual void handleDropped(); - virtual void draw(); - virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, - EDragAndDropType cargo_type, - void* cargo_data, - EAcceptance* accept, - std::string& tooltip_msg); -}; - - -// function used for sorting. -typedef bool (*sort_order_f)(LLFolderViewItem* a, LLFolderViewItem* b); - - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// Class LLFolderViewFolder -// -// An instance of an LLFolderViewFolder represents a collection of -// more folders and items. This is used to build the hierarchy of -// items found in the folder view. :) -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -class LLFolderViewFolder : public LLFolderViewItem -{ -protected: - LLFolderViewFolder( const LLFolderViewItem::Params& ); - friend class LLUICtrlFactory; - -public: - typedef enum e_trash - { - UNKNOWN, TRASH, NOT_TRASH - } ETrash; - -protected: - typedef std::list<LLFolderViewItem*> items_t; - typedef std::list<LLFolderViewFolder*> folders_t; - items_t mItems; - folders_t mFolders; - LLInventorySort mSortFunction; - - BOOL mIsOpen; - BOOL mExpanderHighlighted; - F32 mCurHeight; - F32 mTargetHeight; - F32 mAutoOpenCountdown; - time_t mSubtreeCreationDate; - mutable ETrash mAmTrash; - S32 mLastArrangeGeneration; - S32 mLastCalculatedWidth; - S32 mCompletedFilterGeneration; - S32 mMostFilteredDescendantGeneration; - bool mNeedsSort; -public: - typedef enum e_recurse_type - { - RECURSE_NO, - RECURSE_UP, - RECURSE_DOWN, - RECURSE_UP_DOWN - } ERecurseType; - - - virtual ~LLFolderViewFolder( void ); - - virtual BOOL potentiallyVisible(); - - LLFolderViewItem* getNextFromChild( LLFolderViewItem*, BOOL include_children = TRUE ); - LLFolderViewItem* getPreviousFromChild( LLFolderViewItem*, BOOL include_children = TRUE ); - - // addToFolder() returns TRUE if it succeeds. FALSE otherwise - virtual BOOL addToFolder(LLFolderViewFolder* folder, LLFolderView* root); - - // Finds width and height of this object and it's children. Also - // makes sure that this view and it's children are the right size. - virtual S32 arrange( S32* width, S32* height, S32 filter_generation ); - - BOOL needsArrange(); - void requestSort(); - - // Returns the sort group (system, trash, folder) for this folder. - virtual EInventorySortGroup getSortGroup() const; - - virtual void setCompletedFilterGeneration(S32 generation, BOOL recurse_up); - virtual S32 getCompletedFilterGeneration() { return mCompletedFilterGeneration; } - - BOOL hasFilteredDescendants(S32 filter_generation) { return mMostFilteredDescendantGeneration >= filter_generation; } - BOOL hasFilteredDescendants(); - - // applies filters to control visibility of inventory items - virtual void filter( LLInventoryFilter& filter); - virtual void setFiltered(BOOL filtered, S32 filter_generation); - virtual void dirtyFilter(); - - // Passes selection information on to children and record - // selection information if necessary. Returns TRUE if this object - // (or a child) was affected. - virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem, - BOOL take_keyboard_focus); - - // This method is used to change the selection of an item. If - // selection is 'this', then note selection as true. Returns TRUE - // if this or a child is now selected. - virtual BOOL changeSelection(LLFolderViewItem* selection, BOOL selected); - - // this method is used to group select items - virtual S32 extendSelection(LLFolderViewItem* selection, LLFolderViewItem* last_selected, LLDynamicArray<LLFolderViewItem*>& items); - - virtual void recursiveDeselect(BOOL deselect_self); - - // Returns true is this object and all of its children can be removed. - virtual BOOL isRemovable(); - - // Returns true is this object and all of its children can be moved - virtual BOOL isMovable(); - - // destroys this folder, and all children - virtual void destroyView(); - - // If this folder can be removed, remove all children that can be - // removed, return TRUE if this is empty after the operation and - // it's viewed folder object can be removed. - //virtual BOOL removeRecursively(BOOL single_item); - //virtual BOOL remove(); - - // remove the specified item (and any children) if - // possible. Return TRUE if the item was deleted. - BOOL removeItem(LLFolderViewItem* item); - - // simply remove the view (and any children) Don't bother telling - // the listeners. - void removeView(LLFolderViewItem* item); - - // extractItem() removes the specified item from the folder, but - // doesn't delete it. - void extractItem( LLFolderViewItem* item ); - - // This function is called by a child that needs to be resorted. - void resort(LLFolderViewItem* item); - - void setItemSortOrder(U32 ordering); - void sortBy(U32); - //BOOL (*func)(LLFolderViewItem* a, LLFolderViewItem* b)); - - void setAutoOpenCountdown(F32 countdown) { mAutoOpenCountdown = countdown; } - - // folders can be opened. This will usually be called by internal - // methods. - virtual void toggleOpen(); - - // Force a folder open or closed - virtual void setOpen(BOOL openitem = TRUE); - - // Called when a child is refreshed. - // don't rearrange child folder contents unless explicitly requested - virtual void requestArrange(BOOL include_descendants = FALSE); - - // internal method which doesn't update the entire view. This - // method was written because the list iterators destroy the state - // of other iterations, thus, we can't arrange while iterating - // through the children (such as when setting which is selected. - virtual void setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse = RECURSE_NO); - - // Get the current state of the folder. - virtual BOOL isOpen() { return mIsOpen; } - - // special case if an object is dropped on the child. - BOOL handleDragAndDropFromChild(MASK mask, - BOOL drop, - EDragAndDropType cargo_type, - void* cargo_data, - EAcceptance* accept, - std::string& tooltip_msg); - - void applyFunctorRecursively(LLFolderViewFunctor& functor); - virtual void applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor); - - virtual void openItem( void ); - virtual BOOL addItem(LLFolderViewItem* item); - virtual BOOL addFolder( LLFolderViewFolder* folder); - - // LLView functionality - virtual BOOL handleHover(S32 x, S32 y, MASK mask); - virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask ); - virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask ); - virtual BOOL handleDoubleClick( S32 x, S32 y, MASK mask ); - virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, - EDragAndDropType cargo_type, - void* cargo_data, - EAcceptance* accept, - std::string& tooltip_msg); - virtual void draw(); - - time_t getCreationDate() const; - bool isTrash() const; -}; - //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class LLFolderView @@ -741,8 +89,12 @@ public: // manages the screen region of the folder view. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -class LLUICtrl; +class LLFolderViewEventListener; +class LLInventoryModel; class LLLineEditor; +class LLMenuGL; +class LLScrollContainer; +class LLUICtrl; class LLFolderView : public LLFolderViewFolder, public LLEditMenuHandler { @@ -765,21 +117,23 @@ public: // and resort the items if necessary. void setSortOrder(U32 order); void checkTreeResortForModelChanged(); - void setFilterPermMask(PermissionMask filter_perm_mask) { mFilter.setFilterPermissions(filter_perm_mask); } + void setFilterPermMask(PermissionMask filter_perm_mask); void setAllowMultiSelect(BOOL allow) { mAllowMultiSelect = allow; } typedef boost::signals2::signal<void (const std::deque<LLFolderViewItem*>& items, BOOL user_action)> signal_t; void setSelectCallback(const signal_t::slot_type& cb) { mSelectSignal.connect(cb); } void setReshapeCallback(const signal_t::slot_type& cb) { mReshapeSignal.connect(cb); } - LLInventoryFilter* getFilter() { return &mFilter; } + // filter is never null + LLInventoryFilter* getFilter(); const std::string getFilterSubString(BOOL trim = FALSE); - U32 getFilterTypes() const { return mFilter.getFilterTypes(); } - PermissionMask getFilterPermissions() const { return mFilter.getFilterPermissions(); } - LLInventoryFilter::EFolderShow getShowFolderState() { return mFilter.getShowFolderState(); } + U32 getFilterTypes() const; + PermissionMask getFilterPermissions() const; + // JAMESDEBUG use getFilter()->getShowFolderState(); + //LLInventoryFilter::EFolderShow getShowFolderState(); U32 getSortOrder() const; - BOOL isFilterModified() { return mFilter.isNotDefault(); } - BOOL getAllowMultiSelect() { return mAllowMultiSelect; } + BOOL isFilterModified(); + BOOL getAllowMultiSelect(); // Close all folders in the view void closeAllFolders(); @@ -914,7 +268,7 @@ public: LLPanel* getParentPanel() { return mParentPanel; } // DEBUG only void dumpSelectionInformation(); - + private: void updateRenamerPosition(); @@ -955,7 +309,7 @@ protected: LLFrameTimer mAutoOpenTimer; LLFrameTimer mSearchTimer; std::string mSearchString; - LLInventoryFilter mFilter; + LLInventoryFilter* mFilter; BOOL mShowSelectionContext; BOOL mShowSingleSelection; LLFrameTimer mMultiSelectionFadeTimer; diff --git a/indra/newview/llfoldervieweventlistener.h b/indra/newview/llfoldervieweventlistener.h new file mode 100644 index 0000000000..eb06123b46 --- /dev/null +++ b/indra/newview/llfoldervieweventlistener.h @@ -0,0 +1,100 @@ +/** + * @file llfoldervieweventlistener.h + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ +#ifndef LLFOLDERVIEWEVENTLISTENER_H +#define LLFOLDERVIEWEVENTLISTENER_H + +#include "lldarray.h" // JAMESDEBUG convert to std::vector +#include "llfontgl.h" // just for StyleFlags enum +#include "llpointer.h" + + +class LLFolderViewItem; +class LLFolderView; +class LLFontGL; +class LLInventoryModel; +class LLMenuGL; +class LLScrollContainer; +class LLUIImage; +class LLUUID; + +// This is an abstract base class that users of the folderview classes +// would use to catch the useful events emitted from the folder +// views. +class LLFolderViewEventListener +{ +public: + virtual ~LLFolderViewEventListener( void ) {} + virtual const std::string& getName() const = 0; + virtual const std::string& getDisplayName() const = 0; + virtual const LLUUID& getUUID() const = 0; + virtual time_t getCreationDate() const = 0; // UTC seconds + virtual PermissionMask getPermissionMask() const = 0; + virtual LLAssetType::EType getPreferredType() const = 0; + virtual LLPointer<LLUIImage> getIcon() const = 0; + virtual LLFontGL::StyleFlags getLabelStyle() const = 0; + virtual std::string getLabelSuffix() const = 0; + virtual void openItem( void ) = 0; + virtual void previewItem( void ) = 0; + virtual void selectItem(void) = 0; + virtual void showProperties(void) = 0; + virtual BOOL isItemRenameable() const = 0; + virtual BOOL renameItem(const std::string& new_name) = 0; + virtual BOOL isItemMovable( void ) = 0; // Can be moved to another folder + virtual BOOL isItemRemovable( void ) = 0; // Can be destroyed + virtual BOOL removeItem() = 0; + virtual void removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch) = 0; + virtual void move( LLFolderViewEventListener* parent_listener ) = 0; + virtual BOOL isItemCopyable() const = 0; + virtual BOOL copyToClipboard() const = 0; + virtual void cutToClipboard() = 0; + virtual BOOL isClipboardPasteable() const = 0; + virtual void pasteFromClipboard() = 0; + virtual void pasteLinkFromClipboard() = 0; + virtual void buildContextMenu(LLMenuGL& menu, U32 flags) = 0; + virtual BOOL isUpToDate() const = 0; + virtual BOOL hasChildren() const = 0; + virtual LLInventoryType::EType getInventoryType() const = 0; + virtual void performAction(LLFolderView* folder, LLInventoryModel* model, std::string action) = 0; + + // This method should be called when a drag begins. returns TRUE + // if the drag can begin, otherwise FALSE. + virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const = 0; + + // This method will be called to determine if a drop can be + // performed, and will set drop to TRUE if a drop is + // requested. Returns TRUE if a drop is possible/happened, + // otherwise FALSE. + virtual BOOL dragOrDrop(MASK mask, BOOL drop, + EDragAndDropType cargo_type, + void* cargo_data) = 0; +}; + +#endif diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp new file mode 100644 index 0000000000..7032e86958 --- /dev/null +++ b/indra/newview/llfolderviewitem.cpp @@ -0,0 +1,2474 @@ +/** +* @file llfolderviewitem.cpp +* @brief Items and folders that can appear in a hierarchical folder view +* +* $LicenseInfo:firstyear=2001&license=viewergpl$ +* +* Copyright (c) 2001-2009, Linden Research, Inc. +* +* Second Life Viewer Source Code +* The source code in this file ("Source Code") is provided by Linden Lab +* to you under the terms of the GNU General Public License, version 2.0 +* ("GPL"), unless you have obtained a separate licensing agreement +* ("Other License"), formally executed by you and Linden Lab. Terms of +* the GPL can be found in doc/GPL-license.txt in this distribution, or +* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 +* +* There are special exceptions to the terms and conditions of the GPL as +* it is applied to this Source Code. View the full text of the exception +* in the file doc/FLOSS-exception.txt in this software distribution, or +* online at +* http://secondlifegrid.net/programs/open_source/licensing/flossexception +* +* By copying, modifying or distributing this software, you acknowledge +* that you have read and understood your obligations described above, +* and agree to abide by those obligations. +* +* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO +* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +* COMPLETENESS OR PERFORMANCE. +* $/LicenseInfo$ +*/ +#include "llviewerprecompiledheaders.h" + +#include "llfolderviewitem.h" + +// viewer includes +#include "llfolderview.h" // Items depend extensively on LLFolderViews +#include "llfoldervieweventlistener.h" +#include "llinventoryfilter.h" +#include "llinventorymodel.h" // *TODO: make it take a pointer to an inventory-model interface +#include "llviewercontrol.h" // gSavedSettings +#include "llviewerwindow.h" // Argh, only for setCursor() + +// linden library includes +#include "llfocusmgr.h" // gFocusMgr +#include "llpanel.h" // panel->hasFocus() +#include "lltrans.h" + +///---------------------------------------------------------------------------- +/// Class LLFolderViewItem +///---------------------------------------------------------------------------- + +// statics +const LLFontGL* LLFolderViewItem::sFont = NULL; +const LLFontGL* LLFolderViewItem::sSmallFont = NULL; +LLUIImagePtr LLFolderViewItem::sArrowImage; +LLUIImagePtr LLFolderViewItem::sBoxImage; + +// only integers can be initialized in header +const F32 LLFolderViewItem::FOLDER_CLOSE_TIME_CONSTANT = 0.02f; +const F32 LLFolderViewItem::FOLDER_OPEN_TIME_CONSTANT = 0.03f; + +const LLColor4U DEFAULT_WHITE(255, 255, 255); + +//static +void LLFolderViewItem::initClass() +{ + sFont = LLFontGL::getFontSansSerifSmall(); + sSmallFont = LLFontGL::getFontMonospace(); + sArrowImage = LLUI::getUIImage("folder_arrow.tga"); + sBoxImage = LLUI::getUIImage("rounded_square.tga"); +} + +//static +void LLFolderViewItem::cleanupClass() +{ + sArrowImage = NULL; + sBoxImage = NULL; +} + + +// NOTE: Optimize this, we call it a *lot* when opening a large inventory +LLFolderViewItem::Params::Params() +: folder_arrow_image("", LLUI::getUIImage("folder_arrow.tga")), + selection_image("", LLUI::getUIImage("rounded_square.tga")) +{ + mouse_opaque(true); + follows.flags(FOLLOWS_LEFT|FOLLOWS_TOP|FOLLOWS_RIGHT); + // JAMESDEBUG tab_stop(false); +} + +// Default constructor +LLFolderViewItem::LLFolderViewItem(LLFolderViewItem::Params p) +: LLView(p), + mLabelWidth(0), + mLabelWidthDirty(false), + mParentFolder( NULL ), + mIsSelected( FALSE ), + mIsCurSelection( FALSE ), + mSelectPending(FALSE), + mLabelStyle( LLFontGL::NORMAL ), + mHasVisibleChildren(FALSE), + mIndentation(0), + mNumDescendantsSelected(0), + mFiltered(FALSE), + mLastFilterGeneration(-1), + mStringMatchOffset(std::string::npos), + mControlLabelRotation(0.f), + mDragAndDropTarget(FALSE), + mIsLoading(FALSE), + mLabel(p.name), + mRoot(p.root), + mCreationDate(p.creation_date), + mListener(p.listener), + mArrowImage(p.folder_arrow_image), + mBoxImage(p.selection_image) +{ + refresh(); +} + +// Destroys the object +LLFolderViewItem::~LLFolderViewItem( void ) +{ + delete mListener; + mListener = NULL; +} + +LLFolderView* LLFolderViewItem::getRoot() +{ + return mRoot; +} + +// Returns true if this object is a child (or grandchild, etc.) of potential_ancestor. +BOOL LLFolderViewItem::isDescendantOf( const LLFolderViewFolder* potential_ancestor ) +{ + LLFolderViewItem* root = this; + while( root->mParentFolder ) + { + if( root->mParentFolder == potential_ancestor ) + { + return TRUE; + } + root = root->mParentFolder; + } + return FALSE; +} + +LLFolderViewItem* LLFolderViewItem::getNextOpenNode(BOOL include_children) +{ + if (!mParentFolder) + { + return NULL; + } + + LLFolderViewItem* itemp = mParentFolder->getNextFromChild( this, include_children ); + while(itemp && !itemp->getVisible()) + { + LLFolderViewItem* next_itemp = itemp->mParentFolder->getNextFromChild( itemp, include_children ); + if (itemp == next_itemp) + { + // hit last item + return itemp->getVisible() ? itemp : this; + } + itemp = next_itemp; + } + + return itemp; +} + +LLFolderViewItem* LLFolderViewItem::getPreviousOpenNode(BOOL include_children) +{ + if (!mParentFolder) + { + return NULL; + } + + LLFolderViewItem* itemp = mParentFolder->getPreviousFromChild( this, include_children ); + while(itemp && !itemp->getVisible()) + { + LLFolderViewItem* next_itemp = itemp->mParentFolder->getPreviousFromChild( itemp, include_children ); + if (itemp == next_itemp) + { + // hit first item + return itemp->getVisible() ? itemp : this; + } + itemp = next_itemp; + } + + return itemp; +} + +// is this item something we think we should be showing? +// for example, if we haven't gotten around to filtering it yet, then the answer is yes +// until we find out otherwise +BOOL LLFolderViewItem::potentiallyVisible() +{ + // we haven't been checked against min required filter + // or we have and we passed + return getLastFilterGeneration() < getRoot()->getFilter()->getMinRequiredGeneration() || getFiltered(); +} + +BOOL LLFolderViewItem::getFiltered() +{ + return mFiltered && mLastFilterGeneration >= getRoot()->getFilter()->getMinRequiredGeneration(); +} + +BOOL LLFolderViewItem::getFiltered(S32 filter_generation) +{ + return mFiltered && mLastFilterGeneration >= filter_generation; +} + +void LLFolderViewItem::setFiltered(BOOL filtered, S32 filter_generation) +{ + mFiltered = filtered; + mLastFilterGeneration = filter_generation; +} + +void LLFolderViewItem::setIcon(LLUIImagePtr icon) +{ + mIcon = icon; +} + +// refresh information from the listener +void LLFolderViewItem::refreshFromListener() +{ + if(mListener) + { + mLabel = mListener->getDisplayName(); + LLAssetType::EType preferred_type = mListener->getPreferredType(); + + // *TODO: to be removed when database supports multi language. This is a + // temporary attempt to display the inventory folder in the user locale. + if (preferred_type != LLAssetType::AT_NONE) + { + mLabel = LLTrans::getString("InvFolder " + mLabel); + }; + + setIcon(mListener->getIcon()); + time_t creation_date = mListener->getCreationDate(); + if (mCreationDate != creation_date) + { + mCreationDate = mListener->getCreationDate(); + dirtyFilter(); + } + mLabelStyle = mListener->getLabelStyle(); + mLabelSuffix = mListener->getLabelSuffix(); + } +} + +void LLFolderViewItem::refresh() +{ + refreshFromListener(); + + std::string searchable_label(mLabel); + searchable_label.append(mLabelSuffix); + LLStringUtil::toUpper(searchable_label); + + if (mSearchableLabel.compare(searchable_label)) + { + mSearchableLabel.assign(searchable_label); + dirtyFilter(); + // some part of label has changed, so overall width has potentially changed, and sort order too + if (mParentFolder) + { + mParentFolder->requestSort(); + mParentFolder->requestArrange(); + } + } + + mLabelWidthDirty = true; +} + +void LLFolderViewItem::applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor) +{ + functor(mListener); +} + +// This function is called when items are added or view filters change. It's +// implemented here but called by derived classes when folding the +// views. +void LLFolderViewItem::filterFromRoot( void ) +{ + LLFolderViewItem* root = getRoot(); + + root->filter(*((LLFolderView*)root)->getFilter()); +} + +// This function is called when the folder view is dirty. It's +// implemented here but called by derived classes when folding the +// views. +void LLFolderViewItem::arrangeFromRoot() +{ + LLFolderViewItem* root = getRoot(); + + S32 height = 0; + S32 width = 0; + root->arrange( &width, &height, 0 ); +} + +// Utility function for LLFolderView +void LLFolderViewItem::arrangeAndSet(BOOL set_selection, + BOOL take_keyboard_focus) +{ + LLFolderView* root = getRoot(); + getParentFolder()->requestArrange(); + if(set_selection) + { + setSelectionFromRoot(this, TRUE, take_keyboard_focus); + if(root) + { + root->scrollToShowSelection(); + } + } +} + +// This function clears the currently selected item, and records the +// specified selected item appropriately for display and use in the +// UI. If open is TRUE, then folders are opened up along the way to +// the selection. +void LLFolderViewItem::setSelectionFromRoot(LLFolderViewItem* selection, + BOOL openitem, + BOOL take_keyboard_focus) +{ + getRoot()->setSelection(selection, openitem, take_keyboard_focus); +} + +// helper function to change the selection from the root. +void LLFolderViewItem::changeSelectionFromRoot(LLFolderViewItem* selection, BOOL selected) +{ + getRoot()->changeSelection(selection, selected); +} + +void LLFolderViewItem::extendSelectionFromRoot(LLFolderViewItem* selection) +{ + LLDynamicArray<LLFolderViewItem*> selected_items; + + getRoot()->extendSelection(selection, NULL, selected_items); +} + +EInventorySortGroup LLFolderViewItem::getSortGroup() const +{ + return SG_ITEM; +} + +// addToFolder() returns TRUE if it succeeds. FALSE otherwise +BOOL LLFolderViewItem::addToFolder(LLFolderViewFolder* folder, LLFolderView* root) +{ + if (!folder) + { + return FALSE; + } + mParentFolder = folder; + root->addItemID(getListener()->getUUID(), this); + return folder->addItem(this); +} + + +// Finds width and height of this object and it's children. Also +// makes sure that this view and it's children are the right size. +S32 LLFolderViewItem::arrange( S32* width, S32* height, S32 filter_generation) +{ + mIndentation = mParentFolder ? mParentFolder->getIndentation() + LEFT_INDENTATION : 0; + if (mLabelWidthDirty) + { + mLabelWidth = ARROW_SIZE + TEXT_PAD + ICON_WIDTH + ICON_PAD + sFont->getWidth(mSearchableLabel); + mLabelWidthDirty = false; + } + + *width = llmax(*width, mLabelWidth + mIndentation); + *height = getItemHeight(); + return *height; +} + +S32 LLFolderViewItem::getItemHeight() +{ + S32 icon_height = mIcon->getHeight(); + S32 label_height = llround(sFont->getLineHeight()); + return llmax( icon_height, label_height ) + ICON_PAD; +} + +void LLFolderViewItem::filter( LLInventoryFilter& filter) +{ + BOOL filtered = mListener && filter.check(this); + + // if our visibility will change as a result of this filter, then + // we need to be rearranged in our parent folder + if (getVisible() != filtered) + { + if (mParentFolder) + { + mParentFolder->requestArrange(); + } + } + + setFiltered(filtered, filter.getCurrentGeneration()); + mStringMatchOffset = filter.getStringMatchOffset(); + filter.decrementFilterCount(); + + if (getRoot()->getDebugFilters()) + { + mStatusText = llformat("%d", mLastFilterGeneration); + } +} + +void LLFolderViewItem::dirtyFilter() +{ + mLastFilterGeneration = -1; + // bubble up dirty flag all the way to root + if (getParentFolder()) + { + getParentFolder()->setCompletedFilterGeneration(-1, TRUE); + } +} + +// *TODO: This can be optimized a lot by simply recording that it is +// selected in the appropriate places, and assuming that set selection +// means 'deselect' for a leaf item. Do this optimization after +// multiple selection is implemented to make sure it all plays nice +// together. +BOOL LLFolderViewItem::setSelection(LLFolderViewItem* selection, BOOL openitem, BOOL take_keyboard_focus) +{ + if( selection == this ) + { + mIsSelected = TRUE; + if(mListener) + { + mListener->selectItem(); + } + } + else + { + mIsSelected = FALSE; + } + return mIsSelected; +} + +BOOL LLFolderViewItem::changeSelection(LLFolderViewItem* selection, BOOL selected) +{ + if(selection == this && mIsSelected != selected) + { + mIsSelected = selected; + if(mListener) + { + mListener->selectItem(); + } + return TRUE; + } + 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() +{ + if( mListener ) + { + return mListener->isItemMovable(); + } + else + { + return TRUE; + } +} + +BOOL LLFolderViewItem::isRemovable() +{ + if( mListener ) + { + return mListener->isItemRemovable(); + } + else + { + return TRUE; + } +} + +void LLFolderViewItem::destroyView() +{ + if (mParentFolder) + { + // removeView deletes me + mParentFolder->removeView(this); + } +} + +// Call through to the viewed object and return true if it can be +// removed. +//BOOL LLFolderViewItem::removeRecursively(BOOL single_item) +BOOL LLFolderViewItem::remove() +{ + if(!isRemovable()) + { + return FALSE; + } + if(mListener) + { + return mListener->removeItem(); + } + return TRUE; +} + +// Build an appropriate context menu for the item. +void LLFolderViewItem::buildContextMenu(LLMenuGL& menu, U32 flags) +{ + if(mListener) + { + mListener->buildContextMenu(menu, flags); + } +} + +void LLFolderViewItem::openItem( void ) +{ + if( mListener ) + { + mListener->openItem(); + } +} + +void LLFolderViewItem::preview( void ) +{ + if (mListener) + { + mListener->previewItem(); + } +} + +void LLFolderViewItem::rename(const std::string& new_name) +{ + if( !new_name.empty() ) + { + if( mListener ) + { + mListener->renameItem(new_name); + + if(mParentFolder) + { + mParentFolder->requestSort(); + } + } + } +} + +const std::string& LLFolderViewItem::getSearchableLabel() const +{ + return mSearchableLabel; +} + +const std::string& LLFolderViewItem::getName( void ) const +{ + if(mListener) + { + return mListener->getName(); + } + return mLabel; +} + +// LLView functionality +BOOL LLFolderViewItem::handleRightMouseDown( S32 x, S32 y, MASK mask ) +{ + if(!mIsSelected) + { + setSelectionFromRoot(this, FALSE); + } + make_ui_sound("UISndClick"); + return TRUE; +} + +BOOL LLFolderViewItem::handleMouseDown( S32 x, S32 y, MASK mask ) +{ + // No handler needed for focus lost since this class has no + // state that depends on it. + gFocusMgr.setMouseCapture( this ); + + if (!mIsSelected) + { + if(mask & MASK_CONTROL) + { + changeSelectionFromRoot(this, !mIsSelected); + } + else if (mask & MASK_SHIFT) + { + extendSelectionFromRoot(this); + } + else + { + setSelectionFromRoot(this, FALSE); + } + make_ui_sound("UISndClick"); + } + else + { + mSelectPending = TRUE; + } + + if( isMovable() ) + { + S32 screen_x; + S32 screen_y; + localPointToScreen(x, y, &screen_x, &screen_y ); + LLToolDragAndDrop::getInstance()->setDragStart( screen_x, screen_y ); + } + return TRUE; +} + +BOOL LLFolderViewItem::handleHover( S32 x, S32 y, MASK mask ) +{ + if( hasMouseCapture() && isMovable() ) + { + S32 screen_x; + S32 screen_y; + localPointToScreen(x, y, &screen_x, &screen_y ); + BOOL can_drag = TRUE; + if( LLToolDragAndDrop::getInstance()->isOverThreshold( screen_x, screen_y ) ) + { + LLFolderView* root = getRoot(); + + if(root->getCurSelectedItem()) + { + LLToolDragAndDrop::ESource src = LLToolDragAndDrop::SOURCE_WORLD; + + // *TODO: push this into listener and remove + // dependency on llagent + if (mListener + && gInventory.isObjectDescendentOf(mListener->getUUID(), gInventory.getRootFolderID())) + { + src = LLToolDragAndDrop::SOURCE_AGENT; + } + else if (mListener + && gInventory.isObjectDescendentOf(mListener->getUUID(), gInventory.getLibraryRootFolderID())) + { + src = LLToolDragAndDrop::SOURCE_LIBRARY; + } + + can_drag = root->startDrag(src); + if (can_drag) + { + // if (mListener) mListener->startDrag(); + // RN: when starting drag and drop, clear out last auto-open + root->autoOpenTest(NULL); + root->setShowSelectionContext(TRUE); + + // Release keyboard focus, so that if stuff is dropped into the + // world, pressing the delete key won't blow away the inventory + // item. + gFocusMgr.setKeyboardFocus(NULL); + + return LLToolDragAndDrop::getInstance()->handleHover( x, y, mask ); + } + } + } + + if (can_drag) + { + gViewerWindow->setCursor(UI_CURSOR_ARROW); + } + else + { + gViewerWindow->setCursor(UI_CURSOR_NOLOCKED); + } + return TRUE; + } + else + { + getRoot()->setShowSelectionContext(FALSE); + gViewerWindow->setCursor(UI_CURSOR_ARROW); + // let parent handle this then... + return FALSE; + } +} + + +BOOL LLFolderViewItem::handleDoubleClick( S32 x, S32 y, MASK mask ) +{ + preview(); + return TRUE; +} + +BOOL LLFolderViewItem::handleScrollWheel(S32 x, S32 y, S32 clicks) +{ + if (getParent()) + { + return getParent()->handleScrollWheel(x, y, clicks); + } + return FALSE; +} + +BOOL LLFolderViewItem::handleMouseUp( S32 x, S32 y, MASK mask ) +{ + // if mouse hasn't moved since mouse down... + if ( pointInView(x, y) && mSelectPending ) + { + //...then select + if(mask & MASK_CONTROL) + { + changeSelectionFromRoot(this, !mIsSelected); + } + else if (mask & MASK_SHIFT) + { + extendSelectionFromRoot(this); + } + else + { + setSelectionFromRoot(this, FALSE); + } + } + + mSelectPending = FALSE; + + if( hasMouseCapture() ) + { + getRoot()->setShowSelectionContext(FALSE); + gFocusMgr.setMouseCapture( NULL ); + } + return TRUE; +} + +BOOL LLFolderViewItem::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, + EDragAndDropType cargo_type, + void* cargo_data, + EAcceptance* accept, + std::string& tooltip_msg) +{ + BOOL accepted = FALSE; + BOOL handled = FALSE; + if(mListener) + { + accepted = mListener->dragOrDrop(mask,drop,cargo_type,cargo_data); + handled = accepted; + if (accepted) + { + mDragAndDropTarget = TRUE; + *accept = ACCEPT_YES_MULTI; + } + else + { + *accept = ACCEPT_NO; + } + } + if(mParentFolder && !handled) + { + handled = mParentFolder->handleDragAndDropFromChild(mask,drop,cargo_type,cargo_data,accept,tooltip_msg); + } + if (handled) + { + lldebugst(LLERR_USER_INPUT) << "dragAndDrop handled by LLFolderViewItem" << llendl; + } + + return handled; +} + + +void LLFolderViewItem::draw() +{ + static LLUIColor sFgColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE); + static LLUIColor sHighlightBgColor = LLUIColorTable::instance().getColor("MenuItemHighlightBgColor", DEFAULT_WHITE); + static LLUIColor sHighlightFgColor = LLUIColorTable::instance().getColor("MenuItemHighlightFgColor", DEFAULT_WHITE); + static LLUIColor sFilterBGColor = LLUIColorTable::instance().getColor("FilterBackgroundColor", DEFAULT_WHITE); + static LLUIColor sFilterTextColor = LLUIColorTable::instance().getColor("FilterTextColor", DEFAULT_WHITE); + static LLUIColor sSuffixColor = LLUIColorTable::instance().getColor("InventoryItemSuffixColor", DEFAULT_WHITE); + static LLUIColor sSearchStatusColor = LLUIColorTable::instance().getColor("InventorySearchStatusColor", DEFAULT_WHITE); + + bool possibly_has_children = false; + bool up_to_date = mListener && mListener->isUpToDate(); + if((up_to_date && hasVisibleChildren() ) || // we fetched our children and some of them have passed the filter... + (!up_to_date && mListener && mListener->hasChildren())) // ...or we know we have children but haven't fetched them (doesn't obey filter) + { + possibly_has_children = true; + } + if(/*mControlLabel[0] != '\0' && */possibly_has_children) + { + if (sArrowImage) + { + gl_draw_scaled_rotated_image(mIndentation, getRect().getHeight() - ARROW_SIZE - TEXT_PAD, + ARROW_SIZE, ARROW_SIZE, mControlLabelRotation, sArrowImage->getImage(), sFgColor); + } + } + + F32 text_left = (F32)(ARROW_SIZE + TEXT_PAD + ICON_WIDTH + ICON_PAD + mIndentation); + + // If we have keyboard focus, draw selection filled + BOOL show_context = getRoot()->getShowSelectionContext(); + BOOL filled = show_context || (getRoot()->getParentPanel()->hasFocus()); + + // always render "current" item, only render other selected items if + // mShowSingleSelection is FALSE + if( mIsSelected ) + { + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + LLColor4 bg_color = sHighlightBgColor; + //const S32 TRAILING_PAD = 5; // It just looks better with this. + if (!mIsCurSelection) + { + // do time-based fade of extra objects + F32 fade_time = getRoot()->getSelectionFadeElapsedTime(); + if (getRoot()->getShowSingleSelection()) + { + // fading out + bg_color.mV[VALPHA] = clamp_rescale(fade_time, 0.f, 0.4f, bg_color.mV[VALPHA], 0.f); + } + else + { + // fading in + bg_color.mV[VALPHA] = clamp_rescale(fade_time, 0.f, 0.4f, 0.f, bg_color.mV[VALPHA]); + } + } + + gl_rect_2d( + 0, + getRect().getHeight(), + getRect().getWidth() - 2, + llfloor(getRect().getHeight() - sFont->getLineHeight() - ICON_PAD), + bg_color, filled); + if (mIsCurSelection) + { + gl_rect_2d( + 0, + getRect().getHeight(), + getRect().getWidth() - 2, + llfloor(getRect().getHeight() - sFont->getLineHeight() - ICON_PAD), + sHighlightFgColor, FALSE); + } + if (getRect().getHeight() > llround(sFont->getLineHeight()) + ICON_PAD + 2) + { + gl_rect_2d( + 0, + llfloor(getRect().getHeight() - sFont->getLineHeight() - ICON_PAD) - 2, + getRect().getWidth() - 2, + 2, + sHighlightFgColor, FALSE); + if (show_context) + { + gl_rect_2d( + 0, + llfloor(getRect().getHeight() - sFont->getLineHeight() - ICON_PAD) - 2, + getRect().getWidth() - 2, + 2, + sHighlightBgColor, TRUE); + } + } + } + if (mDragAndDropTarget) + { + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + gl_rect_2d( + 0, + getRect().getHeight(), + getRect().getWidth() - 2, + llfloor(getRect().getHeight() - sFont->getLineHeight() - ICON_PAD), + sHighlightBgColor, FALSE); + + if (getRect().getHeight() > llround(sFont->getLineHeight()) + ICON_PAD + 2) + { + gl_rect_2d( + 0, + llfloor(getRect().getHeight() - sFont->getLineHeight() - ICON_PAD) - 2, + getRect().getWidth() - 2, + 2, + sHighlightBgColor, FALSE); + } + mDragAndDropTarget = FALSE; + } + + + if(mIcon) + { + mIcon->draw(mIndentation + ARROW_SIZE + TEXT_PAD, getRect().getHeight() - mIcon->getHeight()); + } + + if (!mLabel.empty()) + { + // highlight filtered text + BOOL debug_filters = getRoot()->getDebugFilters(); + LLColor4 color = ( (mIsSelected && filled) ? sHighlightFgColor : sFgColor ); + F32 right_x; + F32 y = (F32)getRect().getHeight() - sFont->getLineHeight() - (F32)TEXT_PAD; + + if (debug_filters) + { + if (!getFiltered() && !possibly_has_children) + { + color.mV[VALPHA] *= 0.5f; + } + + LLColor4 filter_color = mLastFilterGeneration >= getRoot()->getFilter()->getCurrentGeneration() ? LLColor4(0.5f, 0.8f, 0.5f, 1.f) : LLColor4(0.8f, 0.5f, 0.5f, 1.f); + sSmallFont->renderUTF8(mStatusText, 0, text_left, y, filter_color, + LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, + S32_MAX, S32_MAX, &right_x, FALSE ); + text_left = right_x; + } + + + if ( mIsLoading + && mTimeSinceRequestStart.getElapsedTimeF32() >= gSavedSettings.getF32("FolderLoadingMessageWaitTime") ) + { + sFont->renderUTF8(LLTrans::getString("LoadingData"), 0, text_left, y, sSearchStatusColor, + LLFontGL::LEFT, LLFontGL::BOTTOM, mLabelStyle, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, &right_x, FALSE); + text_left = right_x; + } + + sFont->renderUTF8( mLabel, 0, text_left, y, color, + LLFontGL::LEFT, LLFontGL::BOTTOM, mLabelStyle, LLFontGL::NO_SHADOW, + S32_MAX, S32_MAX, &right_x, FALSE ); + if (!mLabelSuffix.empty()) + { + sFont->renderUTF8( mLabelSuffix, 0, right_x, y, sSuffixColor, + LLFontGL::LEFT, LLFontGL::BOTTOM, mLabelStyle, LLFontGL::NO_SHADOW, + S32_MAX, S32_MAX, &right_x, FALSE ); + } + + if (sBoxImage.notNull() && mStringMatchOffset != std::string::npos) + { + // don't draw backgrounds for zero-length strings + S32 filter_string_length = getRoot()->getFilterSubString().size(); + if (filter_string_length > 0) + { + std::string combined_string = mLabel + mLabelSuffix; + S32 left = llround(text_left) + sFont->getWidth(combined_string, 0, mStringMatchOffset) - 1; + S32 right = left + sFont->getWidth(combined_string, mStringMatchOffset, filter_string_length) + 2; + S32 bottom = llfloor(getRect().getHeight() - sFont->getLineHeight() - 3); + S32 top = getRect().getHeight(); + + LLRect box_rect(left, top, right, bottom); + sBoxImage->draw(box_rect, sFilterBGColor); + F32 match_string_left = text_left + sFont->getWidthF32(combined_string, 0, mStringMatchOffset); + F32 y = (F32)getRect().getHeight() - sFont->getLineHeight() - (F32)TEXT_PAD; + sFont->renderUTF8( combined_string, mStringMatchOffset, match_string_left, y, + sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, mLabelStyle, LLFontGL::NO_SHADOW, + filter_string_length, S32_MAX, &right_x, FALSE ); + } + } + } + + if( sDebugRects ) + { + drawDebugRect(); + } + + //// *HACK: also draw debug rectangles around currently-being-edited LLView, and any elements that are being highlighted by GUI preview code (see LLFloaterUIPreview) + //std::set<LLView*>::iterator iter = std::find(sPreviewHighlightedElements.begin(), sPreviewHighlightedElements.end(), this); + //if ((sEditingUI && this == sEditingUIView) || (iter != sPreviewHighlightedElements.end() && sDrawPreviewHighlights)) + //{ + // drawDebugRect(); + //} +} + + +///---------------------------------------------------------------------------- +/// Class LLFolderViewFolder +///---------------------------------------------------------------------------- + +LLFolderViewFolder::LLFolderViewFolder( const LLFolderViewItem::Params& p ): +LLFolderViewItem( p ), // 0 = no create time +mIsOpen(FALSE), +mExpanderHighlighted(FALSE), +mCurHeight(0.f), +mTargetHeight(0.f), +mAutoOpenCountdown(0.f), +mSubtreeCreationDate(0), +mAmTrash(LLFolderViewFolder::UNKNOWN), +mLastArrangeGeneration( -1 ), +mLastCalculatedWidth(0), +mCompletedFilterGeneration(-1), +mMostFilteredDescendantGeneration(-1), +mNeedsSort(false) +{} + +// Destroys the object +LLFolderViewFolder::~LLFolderViewFolder( void ) +{ + // The LLView base class takes care of object destruction. make sure that we + // don't have mouse or keyboard focus + gFocusMgr.releaseFocusIfNeeded( this ); // calls onCommit() +} + +// addToFolder() returns TRUE if it succeeds. FALSE otherwise +BOOL LLFolderViewFolder::addToFolder(LLFolderViewFolder* folder, LLFolderView* root) +{ + if (!folder) + { + return FALSE; + } + mParentFolder = folder; + root->addItemID(getListener()->getUUID(), this); + return folder->addFolder(this); +} + +// Finds width and height of this object and it's children. Also +// makes sure that this view and it's children are the right size. +S32 LLFolderViewFolder::arrange( S32* width, S32* height, S32 filter_generation) +{ + // sort before laying out contents + if (mNeedsSort) + { + mFolders.sort(mSortFunction); + mItems.sort(mSortFunction); + mNeedsSort = false; + } + + mHasVisibleChildren = hasFilteredDescendants(filter_generation); + + LLInventoryFilter::EFolderShow show_folder_state = getRoot()->getFilter()->getShowFolderState(); + + // calculate height as a single item (without any children), and reshapes rectangle to match + LLFolderViewItem::arrange( width, height, filter_generation ); + + // clamp existing animated height so as to never get smaller than a single item + mCurHeight = llmax((F32)*height, mCurHeight); + + // initialize running height value as height of single item in case we have no children + *height = getItemHeight(); + F32 running_height = (F32)*height; + F32 target_height = (F32)*height; + + // are my children visible? + if (needsArrange()) + { + // set last arrange generation first, in case children are animating + // and need to be arranged again + mLastArrangeGeneration = getRoot()->getArrangeGeneration(); + if (mIsOpen) + { + // Add sizes of children + S32 parent_item_height = getRect().getHeight(); + + for(folders_t::iterator fit = mFolders.begin(); fit != mFolders.end(); ++fit) + { + LLFolderViewFolder* folderp = (*fit); + if (getRoot()->getDebugFilters()) + { + folderp->setVisible(TRUE); + } + else + { + folderp->setVisible(show_folder_state == LLInventoryFilter::SHOW_ALL_FOLDERS || // always show folders? + (folderp->getFiltered(filter_generation) || folderp->hasFilteredDescendants(filter_generation))); // passed filter or has descendants that passed filter + } + + if (folderp->getVisible()) + { + S32 child_width = *width; + S32 child_height = 0; + S32 child_top = parent_item_height - llround(running_height); + + target_height += folderp->arrange( &child_width, &child_height, filter_generation ); + + running_height += (F32)child_height; + *width = llmax(*width, child_width); + folderp->setOrigin( 0, child_top - folderp->getRect().getHeight() ); + } + } + for(items_t::iterator iit = mItems.begin(); + iit != mItems.end(); ++iit) + { + LLFolderViewItem* itemp = (*iit); + if (getRoot()->getDebugFilters()) + { + itemp->setVisible(TRUE); + } + else + { + itemp->setVisible(itemp->getFiltered(filter_generation)); + } + + if (itemp->getVisible()) + { + S32 child_width = *width; + S32 child_height = 0; + S32 child_top = parent_item_height - llround(running_height); + + target_height += itemp->arrange( &child_width, &child_height, filter_generation ); + // don't change width, as this item is as wide as its parent folder by construction + itemp->reshape( itemp->getRect().getWidth(), child_height); + + running_height += (F32)child_height; + *width = llmax(*width, child_width); + itemp->setOrigin( 0, child_top - itemp->getRect().getHeight() ); + } + } + } + + mTargetHeight = target_height; + // cache this width so next time we can just return it + mLastCalculatedWidth = *width; + } + else + { + // just use existing width + *width = mLastCalculatedWidth; + } + + // animate current height towards target height + if (llabs(mCurHeight - mTargetHeight) > 1.f) + { + mCurHeight = lerp(mCurHeight, mTargetHeight, LLCriticalDamp::getInterpolant(mIsOpen ? FOLDER_OPEN_TIME_CONSTANT : FOLDER_CLOSE_TIME_CONSTANT)); + + requestArrange(); + + // hide child elements that fall out of current animated height + for (folders_t::iterator iter = mFolders.begin(); + iter != mFolders.end();) + { + folders_t::iterator fit = iter++; + // number of pixels that bottom of folder label is from top of parent folder + if (getRect().getHeight() - (*fit)->getRect().mTop + (*fit)->getItemHeight() + > llround(mCurHeight) + MAX_FOLDER_ITEM_OVERLAP) + { + // hide if beyond current folder height + (*fit)->setVisible(FALSE); + } + } + + for (items_t::iterator iter = mItems.begin(); + iter != mItems.end();) + { + items_t::iterator iit = iter++; + // number of pixels that bottom of item label is from top of parent folder + if (getRect().getHeight() - (*iit)->getRect().mBottom + > llround(mCurHeight) + MAX_FOLDER_ITEM_OVERLAP) + { + (*iit)->setVisible(FALSE); + } + } + } + else + { + mCurHeight = mTargetHeight; + } + + // don't change width as this item is already as wide as its parent folder + reshape(getRect().getWidth(),llround(mCurHeight)); + + // pass current height value back to parent + *height = llround(mCurHeight); + + return llround(mTargetHeight); +} + +BOOL LLFolderViewFolder::needsArrange() +{ + return mLastArrangeGeneration < getRoot()->getArrangeGeneration(); +} + +void LLFolderViewFolder::requestSort() +{ + mNeedsSort = true; + // whenever item order changes, we need to lay things out again + requestArrange(); +} + +void LLFolderViewFolder::setCompletedFilterGeneration(S32 generation, BOOL recurse_up) +{ + mMostFilteredDescendantGeneration = llmin(mMostFilteredDescendantGeneration, generation); + mCompletedFilterGeneration = generation; + // only aggregate up if we are a lower (older) value + if (recurse_up && mParentFolder && generation < mParentFolder->getCompletedFilterGeneration()) + { + mParentFolder->setCompletedFilterGeneration(generation, TRUE); + } +} + +void LLFolderViewFolder::filter( LLInventoryFilter& filter) +{ + S32 filter_generation = filter.getCurrentGeneration(); + // if failed to pass filter newer than must_pass_generation + // you will automatically fail this time, so we only + // check against items that have passed the filter + S32 must_pass_generation = filter.getMustPassGeneration(); + + // if we have already been filtered against this generation, skip out + if (getCompletedFilterGeneration() >= filter_generation) + { + return; + } + + // filter folder itself + if (getLastFilterGeneration() < filter_generation) + { + if (getLastFilterGeneration() >= must_pass_generation && // folder has been compared to a valid precursor filter + !mFiltered) // and did not pass the filter + { + // go ahead and flag this folder as done + mLastFilterGeneration = filter_generation; + } + else + { + // filter self only on first pass through + LLFolderViewItem::filter( filter ); + } + } + + if (getRoot()->getDebugFilters()) + { + mStatusText = llformat("%d", mLastFilterGeneration); + mStatusText += llformat("(%d)", mCompletedFilterGeneration); + mStatusText += llformat("+%d", mMostFilteredDescendantGeneration); + } + + // all descendants have been filtered later than must pass generation + // but none passed + if(getCompletedFilterGeneration() >= must_pass_generation && !hasFilteredDescendants(must_pass_generation)) + { + // don't traverse children if we've already filtered them since must_pass_generation + // and came back with nothing + return; + } + + // we entered here with at least one filter iteration left + // check to see if we have any more before continuing on to children + if (filter.getFilterCount() < 0) + { + return; + } + + // when applying a filter, matching folders get their contents downloaded first + if (filter.isNotDefault() && getFiltered(filter.getMinRequiredGeneration()) && (mListener && !gInventory.isCategoryComplete(mListener->getUUID()))) + { + gInventory.startBackgroundFetch(mListener->getUUID()); + } + + // now query children + for (folders_t::iterator iter = mFolders.begin(); + iter != mFolders.end();) + { + folders_t::iterator fit = iter++; + // have we run out of iterations this frame? + if (filter.getFilterCount() < 0) + { + break; + } + + // mMostFilteredDescendantGeneration might have been reset + // in which case we need to update it even for folders that + // don't need to be filtered anymore + if ((*fit)->getCompletedFilterGeneration() >= filter_generation) + { + // track latest generation to pass any child items + if ((*fit)->getFiltered() || (*fit)->hasFilteredDescendants(filter.getMinRequiredGeneration())) + { + mMostFilteredDescendantGeneration = filter_generation; + if (getRoot()->needsAutoSelect()) + { + (*fit)->setOpenArrangeRecursively(TRUE); + } + } + // just skip it, it has already been filtered + continue; + } + + // update this folders filter status (and children) + (*fit)->filter( filter ); + + // track latest generation to pass any child items + if ((*fit)->getFiltered() || (*fit)->hasFilteredDescendants(filter_generation)) + { + mMostFilteredDescendantGeneration = filter_generation; + if (getRoot()->needsAutoSelect()) + { + (*fit)->setOpenArrangeRecursively(TRUE); + } + } + } + + for (items_t::iterator iter = mItems.begin(); + iter != mItems.end();) + { + items_t::iterator iit = iter++; + if (filter.getFilterCount() < 0) + { + break; + } + if ((*iit)->getLastFilterGeneration() >= filter_generation) + { + if ((*iit)->getFiltered()) + { + mMostFilteredDescendantGeneration = filter_generation; + } + continue; + } + + if ((*iit)->getLastFilterGeneration() >= must_pass_generation && + !(*iit)->getFiltered(must_pass_generation)) + { + // failed to pass an earlier filter that was a subset of the current one + // go ahead and flag this item as done + (*iit)->setFiltered(FALSE, filter_generation); + continue; + } + + (*iit)->filter( filter ); + + if ((*iit)->getFiltered(filter.getMinRequiredGeneration())) + { + mMostFilteredDescendantGeneration = filter_generation; + } + } + + // if we didn't use all filter iterations + // that means we filtered all of our descendants + // instead of exhausting the filter count for this frame + if (filter.getFilterCount() > 0) + { + // flag this folder as having completed filter pass for all descendants + setCompletedFilterGeneration(filter_generation, FALSE/*dont recurse up to root*/); + } +} + +void LLFolderViewFolder::setFiltered(BOOL filtered, S32 filter_generation) +{ + // if this folder is now filtered, but wasn't before + // (it just passed) + if (filtered && !mFiltered) + { + // reset current height, because last time we drew it + // it might have had more visible items than now + mCurHeight = 0.f; + } + + LLFolderViewItem::setFiltered(filtered, filter_generation); +} + +void LLFolderViewFolder::dirtyFilter() +{ + // we're a folder, so invalidate our completed generation + setCompletedFilterGeneration(-1, FALSE); + LLFolderViewItem::dirtyFilter(); +} + +BOOL LLFolderViewFolder::hasFilteredDescendants() +{ + return mMostFilteredDescendantGeneration >= getRoot()->getFilter()->getCurrentGeneration(); +} + +// Passes selection information on to children and record selection +// information if necessary. +BOOL LLFolderViewFolder::setSelection(LLFolderViewItem* selection, BOOL openitem, + BOOL take_keyboard_focus) +{ + BOOL rv = FALSE; + if( selection == this ) + { + mIsSelected = TRUE; + if(mListener) + { + mListener->selectItem(); + } + rv = TRUE; + } + else + { + mIsSelected = FALSE; + rv = FALSE; + } + BOOL child_selected = FALSE; + + for (folders_t::iterator iter = mFolders.begin(); + iter != mFolders.end();) + { + folders_t::iterator fit = iter++; + if((*fit)->setSelection(selection, openitem, take_keyboard_focus)) + { + rv = TRUE; + child_selected = TRUE; + mNumDescendantsSelected++; + } + } + for (items_t::iterator iter = mItems.begin(); + iter != mItems.end();) + { + items_t::iterator iit = iter++; + if((*iit)->setSelection(selection, openitem, take_keyboard_focus)) + { + rv = TRUE; + child_selected = TRUE; + mNumDescendantsSelected++; + } + } + if(openitem && child_selected) + { + setOpenArrangeRecursively(TRUE); + } + return rv; +} + +// This method is used to change the selection of an item. If +// selection is 'this', then note selection as true. Returns TRUE +// if this or a child is now selected. +BOOL LLFolderViewFolder::changeSelection(LLFolderViewItem* selection, + BOOL selected) +{ + BOOL rv = FALSE; + if(selection == this) + { + mIsSelected = selected; + if(mListener && selected) + { + mListener->selectItem(); + } + rv = TRUE; + } + + for (folders_t::iterator iter = mFolders.begin(); + iter != mFolders.end();) + { + folders_t::iterator fit = iter++; + if((*fit)->changeSelection(selection, selected)) + { + if (selected) + { + mNumDescendantsSelected++; + } + else + { + mNumDescendantsSelected--; + } + rv = TRUE; + } + } + for (items_t::iterator iter = mItems.begin(); + iter != mItems.end();) + { + items_t::iterator iit = iter++; + if((*iit)->changeSelection(selection, selected)) + { + if (selected) + { + mNumDescendantsSelected++; + } + else + { + mNumDescendantsSelected--; + } + rv = TRUE; + } + } + return rv; +} + +S32 LLFolderViewFolder::extendSelection(LLFolderViewItem* selection, LLFolderViewItem* last_selected, LLDynamicArray<LLFolderViewItem*>& selected_items) +{ + S32 num_selected = 0; + + // pass on to child folders first + for (folders_t::iterator iter = mFolders.begin(); + iter != mFolders.end();) + { + folders_t::iterator fit = iter++; + num_selected += (*fit)->extendSelection(selection, last_selected, selected_items); + mNumDescendantsSelected += num_selected; + } + + // handle selection of our immediate children... + BOOL reverse_select = FALSE; + BOOL found_last_selected = FALSE; + BOOL found_selection = FALSE; + LLDynamicArray<LLFolderViewItem*> items_to_select; + LLFolderViewItem* item; + + //...folders first... + for (folders_t::iterator iter = mFolders.begin(); + iter != mFolders.end();) + { + folders_t::iterator fit = iter++; + item = (*fit); + if(item == selection) + { + found_selection = TRUE; + } + else if (item == last_selected) + { + found_last_selected = TRUE; + if (found_selection) + { + reverse_select = TRUE; + } + } + + if (found_selection || found_last_selected) + { + // deselect currently selected items so they can be pushed back on queue + if (item->isSelected()) + { + item->changeSelection(item, FALSE); + } + items_to_select.put(item); + } + + if (found_selection && found_last_selected) + { + break; + } + } + + if (!(found_selection && found_last_selected)) + { + //,,,then items + for (items_t::iterator iter = mItems.begin(); + iter != mItems.end();) + { + items_t::iterator iit = iter++; + item = (*iit); + if(item == selection) + { + found_selection = TRUE; + } + else if (item == last_selected) + { + found_last_selected = TRUE; + if (found_selection) + { + reverse_select = TRUE; + } + } + + if (found_selection || found_last_selected) + { + // deselect currently selected items so they can be pushed back on queue + if (item->isSelected()) + { + item->changeSelection(item, FALSE); + } + items_to_select.put(item); + } + + if (found_selection && found_last_selected) + { + break; + } + } + } + + if (found_last_selected && found_selection) + { + // we have a complete selection inside this folder + for (S32 index = reverse_select ? items_to_select.getLength() - 1 : 0; + reverse_select ? index >= 0 : index < items_to_select.getLength(); reverse_select ? index-- : index++) + { + LLFolderViewItem* item = items_to_select[index]; + if (item->changeSelection(item, TRUE)) + { + selected_items.put(item); + mNumDescendantsSelected++; + num_selected++; + } + } + } + else if (found_selection) + { + // last selection was not in this folder....go ahead and select just the new item + if (selection->changeSelection(selection, TRUE)) + { + selected_items.put(selection); + mNumDescendantsSelected++; + num_selected++; + } + } + + 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(); + iter != mItems.end();) + { + items_t::iterator iit = iter++; + LLFolderViewItem* item = (*iit); + getRoot()->removeItemID(item->getListener()->getUUID()); + } + + std::for_each(mItems.begin(), mItems.end(), DeletePointer()); + mItems.clear(); + + while (!mFolders.empty()) + { + LLFolderViewFolder *folderp = mFolders.back(); + folderp->destroyView(); // removes entry from mFolders + } + + deleteAllChildren(); + + if (mParentFolder) + { + mParentFolder->removeView(this); + } +} + +// remove the specified item (and any children) if possible. Return +// TRUE if the item was deleted. +BOOL LLFolderViewFolder::removeItem(LLFolderViewItem* item) +{ + if(item->remove()) + { + //RN: this seem unneccessary as remove() moves to trash + //removeView(item); + return TRUE; + } + return FALSE; +} + +// simply remove the view (and any children) Don't bother telling the +// listeners. +void LLFolderViewFolder::removeView(LLFolderViewItem* item) +{ + if (!item || item->getParentFolder() != this) + { + return; + } + // deselect without traversing hierarchy + item->recursiveDeselect(TRUE); + getRoot()->removeFromSelectionList(item); + extractItem(item); + delete item; +} + +// extractItem() removes the specified item from the folder, but +// doesn't delete it. +void LLFolderViewFolder::extractItem( LLFolderViewItem* item ) +{ + items_t::iterator it = std::find(mItems.begin(), mItems.end(), item); + if(it == mItems.end()) + { + // This is an evil downcast. However, it's only doing + // pointer comparison to find if (which it should be ) the + // item is in the container, so it's pretty safe. + LLFolderViewFolder* f = reinterpret_cast<LLFolderViewFolder*>(item); + folders_t::iterator ft; + ft = std::find(mFolders.begin(), mFolders.end(), f); + if(ft != mFolders.end()) + { + mFolders.erase(ft); + } + } + else + { + mItems.erase(it); + } + //item has been removed, need to update filter + dirtyFilter(); + //because an item is going away regardless of filter status, force rearrange + requestArrange(); + getRoot()->removeItemID(item->getListener()->getUUID()); + removeChild(item); +} + +bool LLFolderViewFolder::isTrash() const +{ + if (mAmTrash == LLFolderViewFolder::UNKNOWN) + { + mAmTrash = mListener->getUUID() == gInventory.findCategoryUUIDForType(LLAssetType::AT_TRASH, false) ? LLFolderViewFolder::TRASH : LLFolderViewFolder::NOT_TRASH; + } + return mAmTrash == LLFolderViewFolder::TRASH; +} + +void LLFolderViewFolder::sortBy(U32 order) +{ + if (!mSortFunction.updateSort(order)) + { + // No changes. + return; + } + + // Propegate this change to sub folders + for (folders_t::iterator iter = mFolders.begin(); + iter != mFolders.end();) + { + folders_t::iterator fit = iter++; + (*fit)->sortBy(order); + } + + mFolders.sort(mSortFunction); + mItems.sort(mSortFunction); + + if (order & LLInventoryFilter::SO_DATE) + { + time_t latest = 0; + + if (!mItems.empty()) + { + LLFolderViewItem* item = *(mItems.begin()); + latest = item->getCreationDate(); + } + + if (!mFolders.empty()) + { + LLFolderViewFolder* folder = *(mFolders.begin()); + if (folder->getCreationDate() > latest) + { + latest = folder->getCreationDate(); + } + } + mSubtreeCreationDate = latest; + } +} + +void LLFolderViewFolder::setItemSortOrder(U32 ordering) +{ + if (mSortFunction.updateSort(ordering)) + { + for (folders_t::iterator iter = mFolders.begin(); + iter != mFolders.end();) + { + folders_t::iterator fit = iter++; + (*fit)->setItemSortOrder(ordering); + } + + mFolders.sort(mSortFunction); + mItems.sort(mSortFunction); + } +} + +EInventorySortGroup LLFolderViewFolder::getSortGroup() const +{ + if (isTrash()) + { + return SG_TRASH_FOLDER; + } + + // Folders that can't be moved are 'system' folders. + if( mListener ) + { + if( !(mListener->isItemMovable()) ) + { + return SG_SYSTEM_FOLDER; + } + } + + return SG_NORMAL_FOLDER; +} + +BOOL LLFolderViewFolder::isMovable() +{ + if( mListener ) + { + if( !(mListener->isItemMovable()) ) + { + return FALSE; + } + + for (items_t::iterator iter = mItems.begin(); + iter != mItems.end();) + { + items_t::iterator iit = iter++; + if(!(*iit)->isMovable()) + { + return FALSE; + } + } + + for (folders_t::iterator iter = mFolders.begin(); + iter != mFolders.end();) + { + folders_t::iterator fit = iter++; + if(!(*fit)->isMovable()) + { + return FALSE; + } + } + } + return TRUE; +} + + +BOOL LLFolderViewFolder::isRemovable() +{ + if( mListener ) + { + if( !(mListener->isItemRemovable()) ) + { + return FALSE; + } + + for (items_t::iterator iter = mItems.begin(); + iter != mItems.end();) + { + items_t::iterator iit = iter++; + if(!(*iit)->isRemovable()) + { + return FALSE; + } + } + + for (folders_t::iterator iter = mFolders.begin(); + iter != mFolders.end();) + { + folders_t::iterator fit = iter++; + if(!(*fit)->isRemovable()) + { + return FALSE; + } + } + } + return TRUE; +} + +// this is an internal method used for adding items to folders. +BOOL LLFolderViewFolder::addItem(LLFolderViewItem* item) +{ + mItems.push_back(item); + item->setRect(LLRect(0, 0, getRect().getWidth(), 0)); + item->setVisible(FALSE); + addChild( item ); + item->dirtyFilter(); + requestArrange(); + requestSort(); + return TRUE; +} + +// this is an internal method used for adding items to folders. +BOOL LLFolderViewFolder::addFolder(LLFolderViewFolder* folder) +{ + mFolders.push_back(folder); + folder->setOrigin(0, 0); + folder->reshape(getRect().getWidth(), 0); + folder->setVisible(FALSE); + addChild( folder ); + folder->dirtyFilter(); + // rearrange all descendants too, as our indentation level might have changed + folder->requestArrange(TRUE); + requestSort(); + return TRUE; +} + +void LLFolderViewFolder::requestArrange(BOOL include_descendants) +{ + mLastArrangeGeneration = -1; + // flag all items up to root + if (mParentFolder) + { + mParentFolder->requestArrange(); + } + + if (include_descendants) + { + for (folders_t::iterator iter = mFolders.begin(); + iter != mFolders.end(); + ++iter) + { + (*iter)->requestArrange(TRUE); + } + } +} + +void LLFolderViewFolder::toggleOpen() +{ + setOpen(!mIsOpen); +} + +// Force a folder open or closed +void LLFolderViewFolder::setOpen(BOOL openitem) +{ + setOpenArrangeRecursively(openitem); +} + +void LLFolderViewFolder::setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse) +{ + BOOL was_open = mIsOpen; + mIsOpen = openitem; + if(!was_open && openitem) + { + if(mListener) + { + mListener->openItem(); + } + } + + if (recurse == RECURSE_DOWN || recurse == RECURSE_UP_DOWN) + { + for (folders_t::iterator iter = mFolders.begin(); + iter != mFolders.end();) + { + folders_t::iterator fit = iter++; + (*fit)->setOpenArrangeRecursively(openitem, RECURSE_DOWN); /* Flawfinder: ignore */ + } + } + if (mParentFolder && (recurse == RECURSE_UP || recurse == RECURSE_UP_DOWN)) + { + mParentFolder->setOpenArrangeRecursively(openitem, RECURSE_UP); + } + + if (was_open != mIsOpen) + { + requestArrange(); + } +} + +BOOL LLFolderViewFolder::handleDragAndDropFromChild(MASK mask, + BOOL drop, + EDragAndDropType c_type, + void* cargo_data, + EAcceptance* accept, + std::string& tooltip_msg) +{ + BOOL accepted = mListener && mListener->dragOrDrop(mask,drop,c_type,cargo_data); + if (accepted) + { + mDragAndDropTarget = TRUE; + *accept = ACCEPT_YES_MULTI; + } + else + { + *accept = ACCEPT_NO; + } + + // drag and drop to child item, so clear pending auto-opens + getRoot()->autoOpenTest(NULL); + + return TRUE; +} + +void LLFolderViewFolder::openItem( void ) +{ + toggleOpen(); +} + +void LLFolderViewFolder::applyFunctorRecursively(LLFolderViewFunctor& functor) +{ + functor.doFolder(this); + + for (folders_t::iterator iter = mFolders.begin(); + iter != mFolders.end();) + { + folders_t::iterator fit = iter++; + (*fit)->applyFunctorRecursively(functor); + } + for (items_t::iterator iter = mItems.begin(); + iter != mItems.end();) + { + items_t::iterator iit = iter++; + functor.doItem((*iit)); + } +} + +void LLFolderViewFolder::applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor) +{ + functor(mListener); + for (folders_t::iterator iter = mFolders.begin(); + iter != mFolders.end();) + { + folders_t::iterator fit = iter++; + (*fit)->applyListenerFunctorRecursively(functor); + } + for (items_t::iterator iter = mItems.begin(); + iter != mItems.end();) + { + items_t::iterator iit = iter++; + (*iit)->applyListenerFunctorRecursively(functor); + } +} + +// LLView functionality +BOOL LLFolderViewFolder::handleDragAndDrop(S32 x, S32 y, MASK mask, + BOOL drop, + EDragAndDropType cargo_type, + void* cargo_data, + EAcceptance* accept, + std::string& tooltip_msg) +{ + LLFolderView* root_view = getRoot(); + + BOOL handled = FALSE; + if(mIsOpen) + { + handled = childrenHandleDragAndDrop(x, y, mask, drop, cargo_type, + cargo_data, accept, tooltip_msg) != NULL; + } + + if (!handled) + { + BOOL accepted = mListener && mListener->dragOrDrop(mask, drop,cargo_type,cargo_data); + + if (accepted) + { + mDragAndDropTarget = TRUE; + *accept = ACCEPT_YES_MULTI; + } + else + { + *accept = ACCEPT_NO; + } + + if (!drop && accepted) + { + root_view->autoOpenTest(this); + } + + lldebugst(LLERR_USER_INPUT) << "dragAndDrop handled by LLFolderViewFolder" << llendl; + } + + return TRUE; +} + + +BOOL LLFolderViewFolder::handleRightMouseDown( S32 x, S32 y, MASK mask ) +{ + BOOL handled = FALSE; + // fetch contents of this folder, as context menu can depend on contents + // still, user would have to open context menu again to see the changes + gInventory.fetchDescendentsOf(mListener->getUUID()); + + if( mIsOpen ) + { + handled = childrenHandleRightMouseDown( x, y, mask ) != NULL; + } + if (!handled) + { + handled = LLFolderViewItem::handleRightMouseDown( x, y, mask ); + } + return handled; +} + + +BOOL LLFolderViewFolder::handleHover(S32 x, S32 y, MASK mask) +{ + BOOL handled = LLView::handleHover(x, y, mask); + + if (!handled) + { + // this doesn't do child processing + handled = LLFolderViewItem::handleHover(x, y, mask); + } + + //if(x < LEFT_INDENTATION + mIndentation && x > mIndentation - LEFT_PAD && y > getRect().getHeight() - ) + //{ + // gViewerWindow->setCursor(UI_CURSOR_ARROW); + // mExpanderHighlighted = TRUE; + // handled = TRUE; + //} + return handled; +} + +BOOL LLFolderViewFolder::handleMouseDown( S32 x, S32 y, MASK mask ) +{ + BOOL handled = FALSE; + if( mIsOpen ) + { + handled = childrenHandleMouseDown(x,y,mask) != NULL; + } + if( !handled ) + { + if(x < LEFT_INDENTATION + mIndentation && x > mIndentation - LEFT_PAD) + { + toggleOpen(); + handled = TRUE; + } + else + { + // do normal selection logic + handled = LLFolderViewItem::handleMouseDown(x, y, mask); + } + } + + return handled; +} + +BOOL LLFolderViewFolder::handleDoubleClick( S32 x, S32 y, MASK mask ) +{ + BOOL handled = FALSE; + if( mIsOpen ) + { + handled = childrenHandleDoubleClick( x, y, mask ) != NULL; + } + if( !handled ) + { + if(x < LEFT_INDENTATION + mIndentation && x > mIndentation - LEFT_PAD) + { + // don't select when user double-clicks plus sign + // so as not to contradict single-click behavior + toggleOpen(); + } + else + { + setSelectionFromRoot(this, FALSE); + toggleOpen(); + } + handled = TRUE; + } + return handled; +} + +void LLFolderViewFolder::draw() +{ + if (mAutoOpenCountdown != 0.f) + { + mControlLabelRotation = mAutoOpenCountdown * -90.f; + } + else if (mIsOpen) + { + mControlLabelRotation = lerp(mControlLabelRotation, -90.f, LLCriticalDamp::getInterpolant(0.04f)); + } + else + { + mControlLabelRotation = lerp(mControlLabelRotation, 0.f, LLCriticalDamp::getInterpolant(0.025f)); + } + + bool possibly_has_children = false; + bool up_to_date = mListener && mListener->isUpToDate(); + if(!up_to_date && mListener && mListener->hasChildren()) // we know we have children but haven't fetched them (doesn't obey filter) + { + possibly_has_children = true; + } + + + BOOL loading = ( mIsOpen && possibly_has_children && !up_to_date ); + + if ( loading && !mIsLoading ) + { + // Measure how long we've been in the loading state + mTimeSinceRequestStart.reset(); + } + + mIsLoading = loading; + + LLFolderViewItem::draw(); + + // draw children if root folder, or any other folder that is open or animating to closed state + if( getRoot() == this || (mIsOpen || mCurHeight != mTargetHeight )) + { + LLView::draw(); + } + + mExpanderHighlighted = FALSE; +} + +time_t LLFolderViewFolder::getCreationDate() const +{ + return llmax<time_t>(mCreationDate, mSubtreeCreationDate); +} + + +BOOL LLFolderViewFolder::potentiallyVisible() +{ + // folder should be visible by it's own filter status + return LLFolderViewItem::potentiallyVisible() + // or one or more of its descendants have passed the minimum filter requirement + || hasFilteredDescendants(getRoot()->getFilter()->getMinRequiredGeneration()) + // or not all of its descendants have been checked against minimum filter requirement + || getCompletedFilterGeneration() < getRoot()->getFilter()->getMinRequiredGeneration(); +} + +// this does prefix traversal, as folders are listed above their contents +LLFolderViewItem* LLFolderViewFolder::getNextFromChild( LLFolderViewItem* item, BOOL include_children ) +{ + BOOL found_item = FALSE; + + LLFolderViewItem* result = NULL; + // when not starting from a given item, start at beginning + if(item == NULL) + { + found_item = TRUE; + } + + // find current item among children + folders_t::iterator fit = mFolders.begin(); + folders_t::iterator fend = mFolders.end(); + + items_t::iterator iit = mItems.begin(); + items_t::iterator iend = mItems.end(); + + // if not trivially starting at the beginning, we have to find the current item + if (!found_item) + { + // first, look among folders, since they are always above items + for(; fit != fend; ++fit) + { + if(item == (*fit)) + { + found_item = TRUE; + // if we are on downwards traversal + if (include_children && (*fit)->isOpen()) + { + // look for first descendant + return (*fit)->getNextFromChild(NULL, TRUE); + } + // otherwise advance to next folder + ++fit; + include_children = TRUE; + break; + } + } + + // didn't find in folders? Check items... + if (!found_item) + { + for(; iit != iend; ++iit) + { + if(item == (*iit)) + { + found_item = TRUE; + // point to next item + ++iit; + break; + } + } + } + } + + if (!found_item) + { + // you should never call this method with an item that isn't a child + // so we should always find something + llassert(FALSE); + return NULL; + } + + // at this point, either iit or fit point to a candidate "next" item + // if both are out of range, we need to punt up to our parent + + // now, starting from found folder, continue through folders + // searching for next visible folder + while(fit != fend && !(*fit)->getVisible()) + { + // turn on downwards traversal for next folder + ++fit; + } + + if (fit != fend) + { + result = (*fit); + } + else + { + // otherwise, scan for next visible item + while(iit != iend && !(*iit)->getVisible()) + { + ++iit; + } + + // check to see if we have a valid item + if (iit != iend) + { + result = (*iit); + } + } + + if( !result && mParentFolder ) + { + // If there are no siblings or children to go to, recurse up one level in the tree + // and skip children for this folder, as we've already discounted them + result = mParentFolder->getNextFromChild(this, FALSE); + } + + return result; +} + +// this does postfix traversal, as folders are listed above their contents +LLFolderViewItem* LLFolderViewFolder::getPreviousFromChild( LLFolderViewItem* item, BOOL include_children ) +{ + BOOL found_item = FALSE; + + LLFolderViewItem* result = NULL; + // when not starting from a given item, start at end + if(item == NULL) + { + found_item = TRUE; + } + + // find current item among children + folders_t::reverse_iterator fit = mFolders.rbegin(); + folders_t::reverse_iterator fend = mFolders.rend(); + + items_t::reverse_iterator iit = mItems.rbegin(); + items_t::reverse_iterator iend = mItems.rend(); + + // if not trivially starting at the end, we have to find the current item + if (!found_item) + { + // first, look among items, since they are always below the folders + for(; iit != iend; ++iit) + { + if(item == (*iit)) + { + found_item = TRUE; + // point to next item + ++iit; + break; + } + } + + // didn't find in items? Check folders... + if (!found_item) + { + for(; fit != fend; ++fit) + { + if(item == (*fit)) + { + found_item = TRUE; + // point to next folder + ++fit; + break; + } + } + } + } + + if (!found_item) + { + // you should never call this method with an item that isn't a child + // so we should always find something + llassert(FALSE); + return NULL; + } + + // at this point, either iit or fit point to a candidate "next" item + // if both are out of range, we need to punt up to our parent + + // now, starting from found item, continue through items + // searching for next visible item + while(iit != iend && !(*iit)->getVisible()) + { + ++iit; + } + + if (iit != iend) + { + // we found an appropriate item + result = (*iit); + } + else + { + // otherwise, scan for next visible folder + while(fit != fend && !(*fit)->getVisible()) + { + ++fit; + } + + // check to see if we have a valid folder + if (fit != fend) + { + // try selecting child element of this folder + if ((*fit)->isOpen()) + { + result = (*fit)->getPreviousFromChild(NULL); + } + else + { + result = (*fit); + } + } + } + + if( !result ) + { + // If there are no siblings or children to go to, recurse up one level in the tree + // which gets back to this folder, which will only be visited if it is a valid, visible item + result = this; + } + + return result; +} + + +bool LLInventorySort::updateSort(U32 order) +{ + if (order != mSortOrder) + { + mSortOrder = order; + mByDate = (order & LLInventoryFilter::SO_DATE); + mSystemToTop = (order & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP); + mFoldersByName = (order & LLInventoryFilter::SO_FOLDERS_BY_NAME); + return true; + } + return false; +} + +bool LLInventorySort::operator()(const LLFolderViewItem* const& a, const LLFolderViewItem* const& b) +{ + // We sort by name if we aren't sorting by date + // OR if these are folders and we are sorting folders by name. + bool by_name = (!mByDate + || (mFoldersByName + && (a->getSortGroup() != SG_ITEM))); + + if (a->getSortGroup() != b->getSortGroup()) + { + if (mSystemToTop) + { + // Group order is System Folders, Trash, Normal Folders, Items + return (a->getSortGroup() < b->getSortGroup()); + } + else if (mByDate) + { + // Trash needs to go to the bottom if we are sorting by date + if ( (a->getSortGroup() == SG_TRASH_FOLDER) + || (b->getSortGroup() == SG_TRASH_FOLDER)) + { + return (b->getSortGroup() == SG_TRASH_FOLDER); + } + } + } + + if (by_name) + { + S32 compare = LLStringUtil::compareDict(a->getLabel(), b->getLabel()); + if (0 == compare) + { + return (a->getCreationDate() > b->getCreationDate()); + } + else + { + return (compare < 0); + } + } + else + { + // BUG: This is very very slow. The getCreationDate() is log n in number + // of inventory items. + time_t first_create = a->getCreationDate(); + time_t second_create = b->getCreationDate(); + if (first_create == second_create) + { + return (LLStringUtil::compareDict(a->getLabel(), b->getLabel()) < 0); + } + else + { + return (first_create > second_create); + } + } +} diff --git a/indra/newview/llfolderviewitem.h b/indra/newview/llfolderviewitem.h new file mode 100644 index 0000000000..57807005c2 --- /dev/null +++ b/indra/newview/llfolderviewitem.h @@ -0,0 +1,528 @@ +/** +* @file llfolderviewitem.h +* @brief Items and folders that can appear in a hierarchical folder view +* +* $LicenseInfo:firstyear=2001&license=viewergpl$ +* +* Copyright (c) 2001-2009, Linden Research, Inc. +* +* Second Life Viewer Source Code +* The source code in this file ("Source Code") is provided by Linden Lab +* to you under the terms of the GNU General Public License, version 2.0 +* ("GPL"), unless you have obtained a separate licensing agreement +* ("Other License"), formally executed by you and Linden Lab. Terms of +* the GPL can be found in doc/GPL-license.txt in this distribution, or +* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 +* +* There are special exceptions to the terms and conditions of the GPL as +* it is applied to this Source Code. View the full text of the exception +* in the file doc/FLOSS-exception.txt in this software distribution, or +* online at +* http://secondlifegrid.net/programs/open_source/licensing/flossexception +* +* By copying, modifying or distributing this software, you acknowledge +* that you have read and understood your obligations described above, +* and agree to abide by those obligations. +* +* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO +* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +* COMPLETENESS OR PERFORMANCE. +* $/LicenseInfo$ +*/ +#ifndef LLFOLDERVIEWITEM_H +#define LLFOLDERVIEWITEM_H + +#include "llview.h" + +class LLFontGL; +class LLFolderView; +class LLFolderViewEventListener; +class LLFolderViewFolder; +class LLFolderViewFunctor; +class LLFolderViewItem; +class LLFolderViewListenerFunctor; +class LLInventoryFilter; +class LLMenuGL; +class LLUIImage; + +// These are grouping of inventory types. +// Order matters when sorting system folders to the top. +enum EInventorySortGroup +{ + SG_SYSTEM_FOLDER, + SG_TRASH_FOLDER, + SG_NORMAL_FOLDER, + SG_ITEM +}; + +// JAMESDEBUG *TODO: do we really need one sort object per folder? +// can we just have one of these per LLFolderView ? +class LLInventorySort +{ +public: + LLInventorySort() + : mSortOrder(0), + mByDate(false), + mSystemToTop(false), + mFoldersByName(false) { } + + // Returns true if order has changed + bool updateSort(U32 order); + U32 getSort() { return mSortOrder; } + + bool operator()(const LLFolderViewItem* const& a, const LLFolderViewItem* const& b); +private: + U32 mSortOrder; + bool mByDate; + bool mSystemToTop; + bool mFoldersByName; +}; + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// Class LLFolderViewItem +// +// An instance of this class represents a single item in a folder view +// such as an inventory item or a file. +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +class LLFolderViewItem : public LLView +{ +public: + static void initClass(); + static void cleanupClass(); + + // jamesdebug was LLUICtrl::Params + struct Params : public LLInitParam::Block<Params, LLView::Params> + { + Optional<LLUIImage*> icon; + Optional<LLFolderView*> root; + Optional<LLFolderViewEventListener*> listener; + + Optional<LLUIImage*> folder_arrow_image; + Optional<LLUIImage*> selection_image; + + Optional<S32> creation_date; //UTC seconds + + Params(); + }; + + // layout constants + static const S32 LEFT_PAD = 5; + static const S32 LEFT_INDENTATION = 13; + static const S32 ICON_PAD = 2; + static const S32 ICON_WIDTH = 16; + static const S32 TEXT_PAD = 1; + static const S32 ARROW_SIZE = 12; + static const S32 MAX_FOLDER_ITEM_OVERLAP = 2; + // animation parameters + static const F32 FOLDER_CLOSE_TIME_CONSTANT; + static const F32 FOLDER_OPEN_TIME_CONSTANT; + +protected: + friend class LLUICtrlFactory; + friend class LLFolderViewEventListener; + + LLFolderViewItem(Params p = LLFolderViewItem::Params()); + + static const LLFontGL* sFont; + static const LLFontGL* sSmallFont; + static LLUIImagePtr sArrowImage; + static LLUIImagePtr sBoxImage; + + std::string mLabel; + std::string mSearchableLabel; + S32 mLabelWidth; + bool mLabelWidthDirty; + time_t mCreationDate; + LLFolderViewFolder* mParentFolder; + LLFolderViewEventListener* mListener; + BOOL mIsSelected; + BOOL mIsCurSelection; + BOOL mSelectPending; + LLFontGL::StyleFlags mLabelStyle; + std::string mLabelSuffix; + LLUIImagePtr mIcon; + std::string mStatusText; + BOOL mHasVisibleChildren; + S32 mIndentation; + S32 mNumDescendantsSelected; + BOOL mFiltered; + S32 mLastFilterGeneration; + std::string::size_type mStringMatchOffset; + F32 mControlLabelRotation; + LLFolderView* mRoot; + BOOL mDragAndDropTarget; + LLUIImagePtr mArrowImage; + LLUIImagePtr mBoxImage; + BOOL mIsLoading; + LLTimer mTimeSinceRequestStart; + + // This function clears the currently selected item, and records + // the specified selected item appropriately for display and use + // in the UI. If open is TRUE, then folders are opened up along + // the way to the selection. + void setSelectionFromRoot(LLFolderViewItem* selection, BOOL openitem, + BOOL take_keyboard_focus = TRUE); + + // helper function to change the selection from the root. + void changeSelectionFromRoot(LLFolderViewItem* selection, BOOL selected); + + // helper function to change the selection from the root. + void extendSelectionFromRoot(LLFolderViewItem* selection); + + // this is an internal method used for adding items to folders. A + // no-op at this leve, but reimplemented in derived classes. + virtual BOOL addItem(LLFolderViewItem*) { return FALSE; } + virtual BOOL addFolder(LLFolderViewFolder*) { return FALSE; } + +public: + // This function is called when the folder view is dirty. It's + // implemented here but called by derived classes when folding the + // views. + void arrangeFromRoot(); + void filterFromRoot( void ); + + void arrangeAndSet(BOOL set_selection, BOOL take_keyboard_focus); + + virtual ~LLFolderViewItem( void ); + + // addToFolder() returns TRUE if it succeeds. FALSE otherwise + enum { ARRANGE = TRUE, DO_NOT_ARRANGE = FALSE }; + virtual BOOL addToFolder(LLFolderViewFolder* folder, LLFolderView* root); + + virtual EInventorySortGroup getSortGroup() const; + + // Finds width and height of this object and it's children. Also + // makes sure that this view and it's children are the right size. + virtual S32 arrange( S32* width, S32* height, S32 filter_generation ); + virtual S32 getItemHeight(); + + // applies filters to control visibility of inventory items + virtual void filter( LLInventoryFilter& filter); + + // updates filter serial number and optionally propagated value up to root + S32 getLastFilterGeneration() { return mLastFilterGeneration; } + + virtual void dirtyFilter(); + + // If the selection is 'this' then note that otherwise + // ignore. Returns TRUE if this object was affected. If open is + // TRUE, then folders are opened up along the way to the + // selection. + virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem, + BOOL take_keyboard_focus); + + // This method is used to toggle the selection of an item. If + // selection is 'this', then note selection, and return TRUE. + virtual BOOL changeSelection(LLFolderViewItem* selection, BOOL selected); + + // this method is used to group select items + virtual S32 extendSelection(LLFolderViewItem* selection, LLFolderViewItem* last_selected, LLDynamicArray<LLFolderViewItem*>& 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<LLUUID> &selection){return TRUE;} + + // Returns true is this object and all of its children can be removed (deleted by user) + virtual BOOL isRemovable(); + + // Returns true is this object and all of its children can be moved + virtual BOOL isMovable(); + + // destroys this item recursively + virtual void destroyView(); + + S32 getNumSelectedDescendants() { return mNumDescendantsSelected; } + + BOOL isSelected() { return mIsSelected; } + + void setIsCurSelection(BOOL select) { mIsCurSelection = select; } + + BOOL getIsCurSelection() { return mIsCurSelection; } + + BOOL hasVisibleChildren() { return mHasVisibleChildren; } + + // Call through to the viewed object and return true if it can be + // removed. Returns true if it's removed. + //virtual BOOL removeRecursively(BOOL single_item); + BOOL remove(); + + // Build an appropriate context menu for the item. Flags unused. + void buildContextMenu(LLMenuGL& menu, U32 flags); + + // This method returns the actual name of the thing being + // viewed. This method will ask the viewed object itself. + const std::string& getName( void ) const; + + const std::string& getSearchableLabel( void ) const; + + // This method returns the label displayed on the view. This + // method was primarily added to allow sorting on the folder + // contents possible before the entire view has been constructed. + const std::string& getLabel() const { return mLabel; } + + // Used for sorting, like getLabel() above. + virtual time_t getCreationDate() const { return mCreationDate; } + + LLFolderViewFolder* getParentFolder( void ) { return mParentFolder; } + const LLFolderViewFolder* getParentFolder( void ) const { return mParentFolder; } + + LLFolderViewItem* getNextOpenNode( BOOL include_children = TRUE ); + LLFolderViewItem* getPreviousOpenNode( BOOL include_children = TRUE ); + + const LLFolderViewEventListener* getListener( void ) const { return mListener; } + LLFolderViewEventListener* getListener( void ) { return mListener; } + + // just rename the object. + void rename(const std::string& new_name); + + // open + virtual void openItem( void ); + virtual void preview(void); + + // Show children (unfortunate that this is called "open") + virtual void setOpen(BOOL open = TRUE) {}; + + virtual BOOL isOpen() { return FALSE; } + + virtual LLFolderView* getRoot(); + BOOL isDescendantOf( const LLFolderViewFolder* potential_ancestor ); + S32 getIndentation() { return mIndentation; } + + virtual BOOL potentiallyVisible(); // do we know for a fact that this item has been filtered out? + + virtual BOOL getFiltered(); + virtual BOOL getFiltered(S32 filter_generation); + virtual void setFiltered(BOOL filtered, S32 filter_generation); + + // change the icon + void setIcon(LLUIImagePtr icon); + + // refresh information from the object being viewed. + void refreshFromListener(); + virtual void refresh(); + + virtual void applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor); + + // LLView functionality + virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask ); + virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask ); + virtual BOOL handleHover( S32 x, S32 y, MASK mask ); + virtual BOOL handleMouseUp( S32 x, S32 y, MASK mask ); + virtual BOOL handleDoubleClick( S32 x, S32 y, MASK mask ); + virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); + + // virtual void handleDropped(); + virtual void draw(); + virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, + EDragAndDropType cargo_type, + void* cargo_data, + EAcceptance* accept, + std::string& tooltip_msg); +}; + + +// function used for sorting. +typedef bool (*sort_order_f)(LLFolderViewItem* a, LLFolderViewItem* b); + + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// Class LLFolderViewFolder +// +// An instance of an LLFolderViewFolder represents a collection of +// more folders and items. This is used to build the hierarchy of +// items found in the folder view. :) +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +class LLFolderViewFolder : public LLFolderViewItem +{ +protected: + LLFolderViewFolder( const LLFolderViewItem::Params& ); + friend class LLUICtrlFactory; + +public: + typedef enum e_trash + { + UNKNOWN, TRASH, NOT_TRASH + } ETrash; + +protected: + typedef std::list<LLFolderViewItem*> items_t; + typedef std::list<LLFolderViewFolder*> folders_t; + items_t mItems; + folders_t mFolders; + LLInventorySort mSortFunction; + + BOOL mIsOpen; + BOOL mExpanderHighlighted; + F32 mCurHeight; + F32 mTargetHeight; + F32 mAutoOpenCountdown; + time_t mSubtreeCreationDate; + mutable ETrash mAmTrash; + S32 mLastArrangeGeneration; + S32 mLastCalculatedWidth; + S32 mCompletedFilterGeneration; + S32 mMostFilteredDescendantGeneration; + bool mNeedsSort; +public: + typedef enum e_recurse_type + { + RECURSE_NO, + RECURSE_UP, + RECURSE_DOWN, + RECURSE_UP_DOWN + } ERecurseType; + + + virtual ~LLFolderViewFolder( void ); + + virtual BOOL potentiallyVisible(); + + LLFolderViewItem* getNextFromChild( LLFolderViewItem*, BOOL include_children = TRUE ); + LLFolderViewItem* getPreviousFromChild( LLFolderViewItem*, BOOL include_children = TRUE ); + + // addToFolder() returns TRUE if it succeeds. FALSE otherwise + virtual BOOL addToFolder(LLFolderViewFolder* folder, LLFolderView* root); + + // Finds width and height of this object and it's children. Also + // makes sure that this view and it's children are the right size. + virtual S32 arrange( S32* width, S32* height, S32 filter_generation ); + + BOOL needsArrange(); + void requestSort(); + + // Returns the sort group (system, trash, folder) for this folder. + virtual EInventorySortGroup getSortGroup() const; + + virtual void setCompletedFilterGeneration(S32 generation, BOOL recurse_up); + virtual S32 getCompletedFilterGeneration() { return mCompletedFilterGeneration; } + + BOOL hasFilteredDescendants(S32 filter_generation) { return mMostFilteredDescendantGeneration >= filter_generation; } + BOOL hasFilteredDescendants(); + + // applies filters to control visibility of inventory items + virtual void filter( LLInventoryFilter& filter); + virtual void setFiltered(BOOL filtered, S32 filter_generation); + virtual void dirtyFilter(); + + // Passes selection information on to children and record + // selection information if necessary. Returns TRUE if this object + // (or a child) was affected. + virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem, + BOOL take_keyboard_focus); + + // This method is used to change the selection of an item. If + // selection is 'this', then note selection as true. Returns TRUE + // if this or a child is now selected. + virtual BOOL changeSelection(LLFolderViewItem* selection, BOOL selected); + + // this method is used to group select items + virtual S32 extendSelection(LLFolderViewItem* selection, LLFolderViewItem* last_selected, LLDynamicArray<LLFolderViewItem*>& items); + + virtual void recursiveDeselect(BOOL deselect_self); + + // Returns true is this object and all of its children can be removed. + virtual BOOL isRemovable(); + + // Returns true is this object and all of its children can be moved + virtual BOOL isMovable(); + + // destroys this folder, and all children + virtual void destroyView(); + + // If this folder can be removed, remove all children that can be + // removed, return TRUE if this is empty after the operation and + // it's viewed folder object can be removed. + //virtual BOOL removeRecursively(BOOL single_item); + //virtual BOOL remove(); + + // remove the specified item (and any children) if + // possible. Return TRUE if the item was deleted. + BOOL removeItem(LLFolderViewItem* item); + + // simply remove the view (and any children) Don't bother telling + // the listeners. + void removeView(LLFolderViewItem* item); + + // extractItem() removes the specified item from the folder, but + // doesn't delete it. + void extractItem( LLFolderViewItem* item ); + + // This function is called by a child that needs to be resorted. + void resort(LLFolderViewItem* item); + + void setItemSortOrder(U32 ordering); + void sortBy(U32); + //BOOL (*func)(LLFolderViewItem* a, LLFolderViewItem* b)); + + void setAutoOpenCountdown(F32 countdown) { mAutoOpenCountdown = countdown; } + + // folders can be opened. This will usually be called by internal + // methods. + virtual void toggleOpen(); + + // Force a folder open or closed + virtual void setOpen(BOOL openitem = TRUE); + + // Called when a child is refreshed. + // don't rearrange child folder contents unless explicitly requested + virtual void requestArrange(BOOL include_descendants = FALSE); + + // internal method which doesn't update the entire view. This + // method was written because the list iterators destroy the state + // of other iterations, thus, we can't arrange while iterating + // through the children (such as when setting which is selected. + virtual void setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse = RECURSE_NO); + + // Get the current state of the folder. + virtual BOOL isOpen() { return mIsOpen; } + + // special case if an object is dropped on the child. + BOOL handleDragAndDropFromChild(MASK mask, + BOOL drop, + EDragAndDropType cargo_type, + void* cargo_data, + EAcceptance* accept, + std::string& tooltip_msg); + + void applyFunctorRecursively(LLFolderViewFunctor& functor); + virtual void applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor); + + virtual void openItem( void ); + virtual BOOL addItem(LLFolderViewItem* item); + virtual BOOL addFolder( LLFolderViewFolder* folder); + + // LLView functionality + virtual BOOL handleHover(S32 x, S32 y, MASK mask); + virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask ); + virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask ); + virtual BOOL handleDoubleClick( S32 x, S32 y, MASK mask ); + virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, + EDragAndDropType cargo_type, + void* cargo_data, + EAcceptance* accept, + std::string& tooltip_msg); + virtual void draw(); + + time_t getCreationDate() const; + bool isTrash() const; +}; + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// Class LLFolderViewListenerFunctor +// +// This simple abstract base class can be used to applied to all +// listeners in a hierarchy. +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +class LLFolderViewListenerFunctor +{ +public: + virtual ~LLFolderViewListenerFunctor() {} + virtual void operator()(LLFolderViewEventListener* listener) = 0; +}; + +#endif // LLFOLDERVIEWITEM_H diff --git a/indra/newview/llgrouplist.cpp b/indra/newview/llgrouplist.cpp index 6473c85775..85da2eb2e3 100644 --- a/indra/newview/llgrouplist.cpp +++ b/indra/newview/llgrouplist.cpp @@ -40,7 +40,7 @@ // newview #include "llagent.h" -static LLDefaultWidgetRegistry::Register<LLGroupList> r("group_list"); +static LLDefaultChildRegistry::Register<LLGroupList> r("group_list"); LLGroupList::LLGroupList(const Params& p) : LLAvatarList(p) diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp index fbf990e1af..e5b05d9f51 100644 --- a/indra/newview/llimpanel.cpp +++ b/indra/newview/llimpanel.cpp @@ -55,8 +55,7 @@ #include "llimview.h" #include "llinventory.h" #include "llinventorymodel.h" -#include "llinventoryview.h" -#include "llfloateractivespeakers.h" +#include "llfloaterinventory.h" #include "llfloaterchat.h" #include "llkeyboard.h" #include "lllineeditor.h" @@ -101,190 +100,7 @@ LLVoiceChannel* LLVoiceChannel::sSuspendedVoiceChannel = NULL; BOOL LLVoiceChannel::sSuspended = FALSE; -void session_starter_helper( - const LLUUID& temp_session_id, - const LLUUID& other_participant_id, - EInstantMessage im_type) -{ - LLMessageSystem *msg = gMessageSystem; - - msg->newMessageFast(_PREHASH_ImprovedInstantMessage); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - - msg->nextBlockFast(_PREHASH_MessageBlock); - msg->addBOOLFast(_PREHASH_FromGroup, FALSE); - msg->addUUIDFast(_PREHASH_ToAgentID, other_participant_id); - msg->addU8Fast(_PREHASH_Offline, IM_ONLINE); - msg->addU8Fast(_PREHASH_Dialog, im_type); - msg->addUUIDFast(_PREHASH_ID, temp_session_id); - msg->addU32Fast(_PREHASH_Timestamp, NO_TIMESTAMP); // no timestamp necessary - - std::string name; - gAgent.buildFullname(name); - - msg->addStringFast(_PREHASH_FromAgentName, name); - msg->addStringFast(_PREHASH_Message, LLStringUtil::null); - msg->addU32Fast(_PREHASH_ParentEstateID, 0); - msg->addUUIDFast(_PREHASH_RegionID, LLUUID::null); - msg->addVector3Fast(_PREHASH_Position, gAgent.getPositionAgent()); -} - -void start_deprecated_conference_chat( - const LLUUID& temp_session_id, - const LLUUID& creator_id, - const LLUUID& other_participant_id, - const LLSD& agents_to_invite) -{ - U8* bucket; - U8* pos; - S32 count; - S32 bucket_size; - - // *FIX: this could suffer from endian issues - count = agents_to_invite.size(); - bucket_size = UUID_BYTES * count; - bucket = new U8[bucket_size]; - pos = bucket; - - for(S32 i = 0; i < count; ++i) - { - LLUUID agent_id = agents_to_invite[i].asUUID(); - - memcpy(pos, &agent_id, UUID_BYTES); - pos += UUID_BYTES; - } - - session_starter_helper( - temp_session_id, - other_participant_id, - IM_SESSION_CONFERENCE_START); - - gMessageSystem->addBinaryDataFast( - _PREHASH_BinaryBucket, - bucket, - bucket_size); - - gAgent.sendReliableMessage(); - - delete[] bucket; -} - -class LLStartConferenceChatResponder : public LLHTTPClient::Responder -{ -public: - LLStartConferenceChatResponder( - const LLUUID& temp_session_id, - const LLUUID& creator_id, - const LLUUID& other_participant_id, - const LLSD& agents_to_invite) - { - mTempSessionID = temp_session_id; - mCreatorID = creator_id; - mOtherParticipantID = other_participant_id; - mAgents = agents_to_invite; - } - - virtual void error(U32 statusNum, const std::string& reason) - { - //try an "old school" way. - if ( statusNum == 400 ) - { - start_deprecated_conference_chat( - mTempSessionID, - mCreatorID, - mOtherParticipantID, - mAgents); - } - - //else throw an error back to the client? - //in theory we should have just have these error strings - //etc. set up in this file as opposed to the IMMgr, - //but the error string were unneeded here previously - //and it is not worth the effort switching over all - //the possible different language translations - } - -private: - LLUUID mTempSessionID; - LLUUID mCreatorID; - LLUUID mOtherParticipantID; - - LLSD mAgents; -}; - -// Returns true if any messages were sent, false otherwise. -// Is sort of equivalent to "does the server need to do anything?" -bool send_start_session_messages( - const LLUUID& temp_session_id, - const LLUUID& other_participant_id, - const std::vector<LLUUID>& ids, - EInstantMessage dialog) -{ - if ( dialog == IM_SESSION_GROUP_START ) - { - session_starter_helper( - temp_session_id, - other_participant_id, - dialog); - - switch(dialog) - { - case IM_SESSION_GROUP_START: - gMessageSystem->addBinaryDataFast( - _PREHASH_BinaryBucket, - EMPTY_BINARY_BUCKET, - EMPTY_BINARY_BUCKET_SIZE); - break; - default: - break; - } - gAgent.sendReliableMessage(); - return true; - } - else if ( dialog == IM_SESSION_CONFERENCE_START ) - { - LLSD agents; - for (int i = 0; i < (S32) ids.size(); i++) - { - agents.append(ids[i]); - } - - //we have a new way of starting conference calls now - LLViewerRegion* region = gAgent.getRegion(); - if (region) - { - std::string url = region->getCapability( - "ChatSessionRequest"); - LLSD data; - data["method"] = "start conference"; - data["session-id"] = temp_session_id; - - data["params"] = agents; - - LLHTTPClient::post( - url, - data, - new LLStartConferenceChatResponder( - temp_session_id, - gAgent.getID(), - other_participant_id, - data["params"])); - } - else - { - start_deprecated_conference_chat( - temp_session_id, - gAgent.getID(), - other_participant_id, - agents); - } - } - - return false; -} class LLVoiceCallCapResponder : public LLHTTPClient::Responder { @@ -1200,7 +1016,7 @@ LLFloaterIMPanel::LLFloaterIMPanel(const std::string& session_label, if ( !mSessionInitialized ) { - if ( !send_start_session_messages( + if ( !LLIMModel::instance().sendStartSession( mSessionUUID, mOtherParticipantUUID, mSessionInitialTargetIDs, @@ -1542,19 +1358,21 @@ void LLFloaterIMPanel::addHistoryLine(const std::string &utf8msg, const LLColor4 prepend_newline = false; } + std::string separator_string(": "); + // 'name' is a sender name that we want to hotlink so that clicking on it opens a profile. if (!name.empty()) // If name exists, then add it to the front of the message. { // Don't hotlink any messages from the system (e.g. "Second Life:"), so just add those in plain text. if (name == SYSTEM_FROM) { - mHistoryEditor->appendColoredText(name,false,prepend_newline,color); + mHistoryEditor->appendColoredText(name + separator_string, false, prepend_newline, color); } else { // Convert the name to a hotlink and add to message. const LLStyleSP &source_style = LLStyleMap::instance().lookupAgent(source); - mHistoryEditor->appendStyledText(name,false,prepend_newline,source_style); + mHistoryEditor->appendStyledText(name + separator_string, false, prepend_newline, source_style); } prepend_newline = false; } @@ -1565,9 +1383,9 @@ void LLFloaterIMPanel::addHistoryLine(const std::string &utf8msg, const LLColor4 { std::string histstr; if (gSavedPerAccountSettings.getBOOL("IMLogTimestamp")) - histstr = LLLogChat::timestamp(gSavedPerAccountSettings.getBOOL("LogTimestampDate")) + name + utf8msg; + histstr = LLLogChat::timestamp(gSavedPerAccountSettings.getBOOL("LogTimestampDate")) + name + separator_string + utf8msg; else - histstr = name + utf8msg; + histstr = name + separator_string + utf8msg; LLLogChat::saveHistory(getTitle(),histstr); } @@ -1620,7 +1438,6 @@ void LLFloaterIMPanel::selectNone() mInputEditor->deselect(); } - BOOL LLFloaterIMPanel::handleKeyHere( KEY key, MASK mask ) { BOOL handled = FALSE; @@ -1847,23 +1664,8 @@ void LLFloaterIMPanel::onClose(bool app_quitting) { setTyping(FALSE); - if(mSessionUUID.notNull()) - { - std::string name; - gAgent.buildFullname(name); - pack_instant_message( - gMessageSystem, - gAgent.getID(), - FALSE, - gAgent.getSessionID(), - mOtherParticipantUUID, - name, - LLStringUtil::null, - IM_ONLINE, - IM_SESSION_LEAVE, - mSessionUUID); - gAgent.sendReliableMessage(); - } + LLIMModel::instance().sendLeaveSession(mSessionUUID, mOtherParticipantUUID); + gIMMgr->removeSession(mSessionUUID); // *HACK hide the voice floater @@ -1884,79 +1686,6 @@ void LLFloaterIMPanel::onVisibilityChange(BOOL new_visibility) mSessionUUID); } -void deliver_message(const std::string& utf8_text, - const LLUUID& im_session_id, - const LLUUID& other_participant_id, - EInstantMessage dialog) -{ - std::string name; - bool sent = false; - gAgent.buildFullname(name); - - const LLRelationship* info = NULL; - info = LLAvatarTracker::instance().getBuddyInfo(other_participant_id); - - U8 offline = (!info || info->isOnline()) ? IM_ONLINE : IM_OFFLINE; - - if((offline == IM_OFFLINE) && (LLVoiceClient::getInstance()->isOnlineSIP(other_participant_id))) - { - // User is online through the OOW connector, but not with a regular viewer. Try to send the message via SLVoice. - sent = gVoiceClient->sendTextMessage(other_participant_id, utf8_text); - } - - if(!sent) - { - // Send message normally. - - // default to IM_SESSION_SEND unless it's nothing special - in - // which case it's probably an IM to everyone. - U8 new_dialog = dialog; - - if ( dialog != IM_NOTHING_SPECIAL ) - { - new_dialog = IM_SESSION_SEND; - } - pack_instant_message( - gMessageSystem, - gAgent.getID(), - FALSE, - gAgent.getSessionID(), - other_participant_id, - name.c_str(), - utf8_text.c_str(), - offline, - (EInstantMessage)new_dialog, - im_session_id); - gAgent.sendReliableMessage(); - } - - // If there is a mute list and this is not a group chat... - if ( LLMuteList::getInstance() ) - { - // ... the target should not be in our mute list for some message types. - // Auto-remove them if present. - switch( dialog ) - { - case IM_NOTHING_SPECIAL: - case IM_GROUP_INVITATION: - case IM_INVENTORY_OFFERED: - case IM_SESSION_INVITE: - case IM_SESSION_P2P_INVITE: - case IM_SESSION_CONFERENCE_START: - case IM_SESSION_SEND: // This one is marginal - erring on the side of hearing. - case IM_LURE_USER: - case IM_GODLIKE_LURE_USER: - case IM_FRIENDSHIP_OFFERED: - LLMuteList::getInstance()->autoRemove(other_participant_id, LLMuteList::AR_IM); - break; - default: ; // do nothing - } - } - - // Add the recipient to the recent people list. - LLRecentPeople::instance().add(other_participant_id); -} - void LLFloaterIMPanel::sendMsg() { if (!gAgent.isGodlike() @@ -1978,7 +1707,7 @@ void LLFloaterIMPanel::sendMsg() if ( mSessionInitialized ) { - deliver_message(utf8_text, + LLIMModel::sendMessage(utf8_text, mSessionUUID, mOtherParticipantUUID, mDialog); @@ -2084,7 +1813,7 @@ void LLFloaterIMPanel::sessionInitReplyReceived(const LLUUID& session_id) iter != mQueuedMsgsForInit.endArray(); ++iter) { - deliver_message( + LLIMModel::sendMessage( iter->asString(), mSessionUUID, mOtherParticipantUUID, @@ -2135,23 +1864,10 @@ void LLFloaterIMPanel::sendTypingState(BOOL typing) // much network traffic. Only send in person-to-person IMs. if (mDialog != IM_NOTHING_SPECIAL) return; - std::string name; - gAgent.buildFullname(name); - - pack_instant_message( - gMessageSystem, - gAgent.getID(), - FALSE, - gAgent.getSessionID(), - mOtherParticipantUUID, - name, - std::string("typing"), - IM_ONLINE, - (typing ? IM_TYPING_START : IM_TYPING_STOP), - mSessionUUID); - gAgent.sendReliableMessage(); + LLIMModel::instance().sendTypingState(mSessionUUID, mOtherParticipantUUID, typing); } + void LLFloaterIMPanel::processIMTyping(const LLIMInfo* im_info, BOOL typing) { if (typing) @@ -2320,3 +2036,80 @@ bool LLFloaterIMPanel::onConfirmForceCloseError(const LLSD& notification, const } +std::map<LLUUID, LLIMFloater*> LLIMFloater::sIMFloaterMap; + +LLIMFloater::LLIMFloater(const LLUUID& session_id, + const std::string title, + EInstantMessage dialog) +: mSessionID(session_id), + mIndex(0) +{ + LLUICtrlFactory::getInstance()->buildFloater(this, "floater_im_session.xml"); + sIMFloaterMap[mSessionID] = this; + + setTitle(title); +} + +LLIMFloater::~LLIMFloater() +{ + sIMFloaterMap.erase(mSessionID); +} + + +void LLIMFloater::show(const LLUUID& session_id, S32 center_x) +{ + + LLIMFloater* floater = get_if_there(sIMFloaterMap, session_id, (LLIMFloater*)NULL); + + if (floater == NULL) + { + floater = new LLIMFloater(session_id, LLIMModel::instance().getName(session_id), IM_NOTHING_SPECIAL); + } + + //hide all + for (std::map<LLUUID, LLIMFloater*>::iterator iter = sIMFloaterMap.begin(); + iter != sIMFloaterMap.end(); ++iter) + { + LLIMFloater* floater = (*iter).second; + floater->setVisible(false); + } + + floater->setVisibleAndFrontmost(true); + + floater->updateMessages(session_id); + + floater->translate(center_x - floater->getRect().getCenterX(), gFloaterView->getRect().mBottom - floater->getRect().mBottom); + +} + +void LLIMFloater::updateMessages(const LLUUID& session_id) +{ + + LLTextEditor* text_editor = getChild<LLTextEditor>("im_text", true, false); + + if (!text_editor) + { + llwarns << "Text editor not found! " << llendl; + return; + } + + std::list<LLSD> messages = LLIMModel::instance().getMessages(mSessionID, mIndex); + + if (messages.size()) + { + std::ostringstream message; + std::list<LLSD>::const_reverse_iterator iter = messages.rbegin(); + std::list<LLSD>::const_reverse_iterator iter_end = messages.rend(); + for (; iter != iter_end; ++iter) + { + LLSD msg = *iter; + + message << msg["from"].asString() << " : " << msg["time"].asString() << "\n " << msg["message"].asString() << "\n"; + + mIndex = msg["index"].asInteger(); + } + + text_editor->setText(message.str()); + } + +} diff --git a/indra/newview/llimpanel.h b/indra/newview/llimpanel.h index 7cd19d4872..88f21864b5 100644 --- a/indra/newview/llimpanel.h +++ b/indra/newview/llimpanel.h @@ -356,10 +356,28 @@ private: LLFrameTimer mLastKeystrokeTimer; void disableWhileSessionStarting(); +}; + + +class LLIMFloater : public LLFloater +{ +public: + LLIMFloater(const LLUUID& session_id, + const std::string title, + EInstantMessage dialog); - typedef std::map<LLUUID, LLStyleSP> styleMap; - static styleMap mStyleMap; + virtual ~LLIMFloater(); + + static void show(const LLUUID& session_id, S32 center_x); + void updateMessages(const LLUUID& session_id); + + static std::map<LLUUID, LLIMFloater*> sIMFloaterMap; + + LLUUID mSessionID; + U32 mIndex; }; + + #endif // LL_IMPANEL_H diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index bc98b609ec..a31d7daff7 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -91,16 +91,494 @@ std::map<std::string,std::string> LLFloaterIM::sEventStringsMap; std::map<std::string,std::string> LLFloaterIM::sErrorStringsMap; std::map<std::string,std::string> LLFloaterIM::sForceCloseSessionMap; +std::map<LLUUID, LLIMModel::LLIMSession*> LLIMModel::sSessionsMap; + + + +void toast_callback(const LLSD& msg){ + + //we send notifications to reset counter also + if (msg["num_unread"].asInteger()) + { + LLSD args; + args["MESSAGE"] = msg["message"]; + args["TIME"] = msg["time"]; + args["FROM"] = msg["from"]; + + LLNotifications::instance().add("IMToast", args, LLSD(), boost::bind(&LLFloaterChatterBox::onOpen, LLFloaterChatterBox::getInstance(), msg["session_id"].asUUID())); + } +} + +LLIMModel::LLIMModel() +{ + addChangedCallback(toast_callback); +} + + +void LLIMModel::testMessages() +{ + static LLUUID bot1_id, bot1_session_id; + if (bot1_id.isNull()) bot1_id.generate(); + std::string from = "Bot1 TestLinden"; + bot1_session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, bot1_id); + newSession(bot1_session_id, from, IM_NOTHING_SPECIAL, bot1_id); + addMessage(bot1_session_id, from, "Test Message: Hi from testerbot land!"); + + LLUUID bot2_id; + std::string firstname[] = {"Roflcopter", "Joe"}; + std::string lastname[] = {"Linden", "Tester", "Resident", "Schmoe"}; + + S32 rand1 = ll_rand(sizeof firstname)/(sizeof firstname[0]); + S32 rand2 = ll_rand(sizeof lastname)/(sizeof lastname[0]); + + from = firstname[rand1] + " " + lastname[rand2]; + bot2_id.generate(from); + LLUUID bot2_session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, bot2_id); + newSession(bot2_session_id, from, IM_NOTHING_SPECIAL, bot2_id); + addMessage(bot2_session_id, from, "Test Message: Can I haz bear? "); + addMessage(bot2_session_id, from, "Test Message: OMGWTFBBQ."); +} + + +bool LLIMModel::newSession(LLUUID session_id, std::string name, EInstantMessage type, LLUUID other_participant_id) +{ + if (is_in_map(sSessionsMap, session_id)) + { + llwarns << "IM Session " << session_id << " already exists" << llendl; + return false; + } + + LLIMSession* session = new LLIMSession(name, type, other_participant_id); + sSessionsMap[session_id] = session; + + LLIMMgr::getInstance()->notifyObserverSessionAdded(session_id, name, other_participant_id); + + return true; + +} + +std::list<LLSD> LLIMModel::getMessages(LLUUID session_id, int index) +{ + std::list<LLSD> return_list; + + LLIMSession* session = get_if_there(sSessionsMap, session_id, (LLIMSession*)NULL); + + if (!session) + { + llwarns << "session " << session_id << "does not exist " << llendl; + return return_list; + } + + int i = session->mMsgs.size() - index; + + for (std::list<LLSD>::iterator iter = session->mMsgs.begin(); + iter != session->mMsgs.end() && i > 0; + iter++) + { + LLSD msg; + msg = *iter; + return_list.push_back(*iter); + i--; + } + + session->mNumUnread = 0; + + LLSD arg; + arg["session_id"] = session_id; + arg["num_unread"] = 0; + mChangedSignal(arg); + + // TODO: in the future is there a more efficient way to return these + return return_list; + +} + +bool LLIMModel::addToHistory(LLUUID session_id, std::string from, std::string utf8_text) { + + LLIMSession* session = get_if_there(sSessionsMap, session_id, (LLIMSession*)NULL); + + if (!session) + { + llwarns << "session " << session_id << "does not exist " << llendl; + return false; + } + + LLSD message; + message["from"] = from; + message["message"] = utf8_text; + message["time"] = LLLogChat::timestamp(false); //might want to add date separately + message["index"] = (LLSD::Integer)session->mMsgs.size(); + + session->mMsgs.push_front(message); + + return true; + +} + + +bool LLIMModel::addMessage(LLUUID session_id, std::string from, std::string utf8_text) { + + LLIMSession* session = get_if_there(sSessionsMap, session_id, (LLIMSession*)NULL); + + if (!session) + { + llwarns << "session " << session_id << "does not exist " << llendl; + return false; + } + + addToHistory(session_id, from, utf8_text); + + std::string agent_name; + gAgent.buildFullname(agent_name); + + session->mNumUnread++; + + // notify listeners + LLSD arg; + arg["session_id"] = session_id; + arg["num_unread"] = session->mNumUnread; + arg["message"] = utf8_text; + mChangedSignal(arg); + + return true; +} + + +const std::string& LLIMModel::getName(LLUUID session_id) +{ + LLIMSession* session = get_if_there(sSessionsMap, session_id, (LLIMSession*)NULL); + + if (!session) + { + llwarns << "session " << session_id << "does not exist " << llendl; + return LLStringUtil::null; + } + + return session->mName; +} + + +// TODO get rid of other participant ID +void LLIMModel::sendTypingState(LLUUID session_id, LLUUID other_participant_id, BOOL typing) +{ + std::string name; + gAgent.buildFullname(name); + + pack_instant_message( + gMessageSystem, + gAgent.getID(), + FALSE, + gAgent.getSessionID(), + other_participant_id, + name, + std::string("typing"), + IM_ONLINE, + (typing ? IM_TYPING_START : IM_TYPING_STOP), + session_id); + gAgent.sendReliableMessage(); +} + +void LLIMModel::sendLeaveSession(LLUUID session_id, LLUUID other_participant_id) +{ + if(session_id.notNull()) + { + std::string name; + gAgent.buildFullname(name); + pack_instant_message( + gMessageSystem, + gAgent.getID(), + FALSE, + gAgent.getSessionID(), + other_participant_id, + name, + LLStringUtil::null, + IM_ONLINE, + IM_SESSION_LEAVE, + session_id); + gAgent.sendReliableMessage(); + } +} + + + +void LLIMModel::sendMessage(const std::string& utf8_text, + const LLUUID& im_session_id, + const LLUUID& other_participant_id, + EInstantMessage dialog) +{ + std::string name; + bool sent = false; + gAgent.buildFullname(name); + + const LLRelationship* info = NULL; + info = LLAvatarTracker::instance().getBuddyInfo(other_participant_id); + + U8 offline = (!info || info->isOnline()) ? IM_ONLINE : IM_OFFLINE; + + if((offline == IM_OFFLINE) && (LLVoiceClient::getInstance()->isOnlineSIP(other_participant_id))) + { + // User is online through the OOW connector, but not with a regular viewer. Try to send the message via SLVoice. + sent = gVoiceClient->sendTextMessage(other_participant_id, utf8_text); + } + + if(!sent) + { + // Send message normally. + + // default to IM_SESSION_SEND unless it's nothing special - in + // which case it's probably an IM to everyone. + U8 new_dialog = dialog; + + if ( dialog != IM_NOTHING_SPECIAL ) + { + new_dialog = IM_SESSION_SEND; + } + pack_instant_message( + gMessageSystem, + gAgent.getID(), + FALSE, + gAgent.getSessionID(), + other_participant_id, + name.c_str(), + utf8_text.c_str(), + offline, + (EInstantMessage)new_dialog, + im_session_id); + gAgent.sendReliableMessage(); + } + + // If there is a mute list and this is not a group chat... + if ( LLMuteList::getInstance() ) + { + // ... the target should not be in our mute list for some message types. + // Auto-remove them if present. + switch( dialog ) + { + case IM_NOTHING_SPECIAL: + case IM_GROUP_INVITATION: + case IM_INVENTORY_OFFERED: + case IM_SESSION_INVITE: + case IM_SESSION_P2P_INVITE: + case IM_SESSION_CONFERENCE_START: + case IM_SESSION_SEND: // This one is marginal - erring on the side of hearing. + case IM_LURE_USER: + case IM_GODLIKE_LURE_USER: + case IM_FRIENDSHIP_OFFERED: + LLMuteList::getInstance()->autoRemove(other_participant_id, LLMuteList::AR_IM); + break; + default: ; // do nothing + } + } + + if((dialog == IM_NOTHING_SPECIAL) && + (other_participant_id.notNull())) + { + // Do we have to replace the /me's here? + std::string from; + gAgent.buildFullname(from); + LLIMModel::instance().addToHistory(im_session_id, from, utf8_text); + } + + // Add the recipient to the recent people list. + LLRecentPeople::instance().add(other_participant_id); +} + +boost::signals2::connection LLIMModel::addChangedCallback( boost::function<void (const LLSD& data)> cb ) +{ + return mChangedSignal.connect(cb); +} + +void session_starter_helper( + const LLUUID& temp_session_id, + const LLUUID& other_participant_id, + EInstantMessage im_type) +{ + LLMessageSystem *msg = gMessageSystem; + + msg->newMessageFast(_PREHASH_ImprovedInstantMessage); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + + msg->nextBlockFast(_PREHASH_MessageBlock); + msg->addBOOLFast(_PREHASH_FromGroup, FALSE); + msg->addUUIDFast(_PREHASH_ToAgentID, other_participant_id); + msg->addU8Fast(_PREHASH_Offline, IM_ONLINE); + msg->addU8Fast(_PREHASH_Dialog, im_type); + msg->addUUIDFast(_PREHASH_ID, temp_session_id); + msg->addU32Fast(_PREHASH_Timestamp, NO_TIMESTAMP); // no timestamp necessary + + std::string name; + gAgent.buildFullname(name); + + msg->addStringFast(_PREHASH_FromAgentName, name); + msg->addStringFast(_PREHASH_Message, LLStringUtil::null); + msg->addU32Fast(_PREHASH_ParentEstateID, 0); + msg->addUUIDFast(_PREHASH_RegionID, LLUUID::null); + msg->addVector3Fast(_PREHASH_Position, gAgent.getPositionAgent()); +} + +void start_deprecated_conference_chat( + const LLUUID& temp_session_id, + const LLUUID& creator_id, + const LLUUID& other_participant_id, + const LLSD& agents_to_invite) +{ + U8* bucket; + U8* pos; + S32 count; + S32 bucket_size; + + // *FIX: this could suffer from endian issues + count = agents_to_invite.size(); + bucket_size = UUID_BYTES * count; + bucket = new U8[bucket_size]; + pos = bucket; + + for(S32 i = 0; i < count; ++i) + { + LLUUID agent_id = agents_to_invite[i].asUUID(); + + memcpy(pos, &agent_id, UUID_BYTES); + pos += UUID_BYTES; + } + + session_starter_helper( + temp_session_id, + other_participant_id, + IM_SESSION_CONFERENCE_START); + + gMessageSystem->addBinaryDataFast( + _PREHASH_BinaryBucket, + bucket, + bucket_size); + + gAgent.sendReliableMessage(); + + delete[] bucket; +} + +class LLStartConferenceChatResponder : public LLHTTPClient::Responder +{ +public: + LLStartConferenceChatResponder( + const LLUUID& temp_session_id, + const LLUUID& creator_id, + const LLUUID& other_participant_id, + const LLSD& agents_to_invite) + { + mTempSessionID = temp_session_id; + mCreatorID = creator_id; + mOtherParticipantID = other_participant_id; + mAgents = agents_to_invite; + } + + virtual void error(U32 statusNum, const std::string& reason) + { + //try an "old school" way. + if ( statusNum == 400 ) + { + start_deprecated_conference_chat( + mTempSessionID, + mCreatorID, + mOtherParticipantID, + mAgents); + } + + //else throw an error back to the client? + //in theory we should have just have these error strings + //etc. set up in this file as opposed to the IMMgr, + //but the error string were unneeded here previously + //and it is not worth the effort switching over all + //the possible different language translations + } + +private: + LLUUID mTempSessionID; + LLUUID mCreatorID; + LLUUID mOtherParticipantID; + + LLSD mAgents; +}; + +// Returns true if any messages were sent, false otherwise. +// Is sort of equivalent to "does the server need to do anything?" +bool LLIMModel::sendStartSession( + const LLUUID& temp_session_id, + const LLUUID& other_participant_id, + const std::vector<LLUUID>& ids, + EInstantMessage dialog) +{ + if ( dialog == IM_SESSION_GROUP_START ) + { + session_starter_helper( + temp_session_id, + other_participant_id, + dialog); + + switch(dialog) + { + case IM_SESSION_GROUP_START: + gMessageSystem->addBinaryDataFast( + _PREHASH_BinaryBucket, + EMPTY_BINARY_BUCKET, + EMPTY_BINARY_BUCKET_SIZE); + break; + default: + break; + } + gAgent.sendReliableMessage(); + + return true; + } + else if ( dialog == IM_SESSION_CONFERENCE_START ) + { + LLSD agents; + for (int i = 0; i < (S32) ids.size(); i++) + { + agents.append(ids[i]); + } + + //we have a new way of starting conference calls now + LLViewerRegion* region = gAgent.getRegion(); + if (region) + { + std::string url = region->getCapability( + "ChatSessionRequest"); + LLSD data; + data["method"] = "start conference"; + data["session-id"] = temp_session_id; + + data["params"] = agents; + + LLHTTPClient::post( + url, + data, + new LLStartConferenceChatResponder( + temp_session_id, + gAgent.getID(), + other_participant_id, + data["params"])); + } + else + { + start_deprecated_conference_chat( + temp_session_id, + gAgent.getID(), + other_participant_id, + agents); + } + } + + return false; +} + + + // // Helper Functions // -// returns true if a should appear before b -//static BOOL group_dictionary_sort( LLGroupData* a, LLGroupData* b ) -//{ -// return (LLStringUtil::compareDict( a->mName, b->mName ) < 0); -//} - class LLViewerChatterBoxInvitationAcceptResponder : public LLHTTPClient::Responder { @@ -614,26 +1092,6 @@ bool inviteUserResponse(const LLSD& notification, const LLSD& response) } // -// Public Static Member Functions -// - -// This is a helper function to determine what kind of im session -// should be used for the given agent. -// static -EInstantMessage LLIMMgr::defaultIMTypeForAgent(const LLUUID& agent_id) -{ - EInstantMessage type = IM_NOTHING_SPECIAL; - if(is_agent_friend(agent_id)) - { - if(LLAvatarTracker::instance().isBuddyOnline(agent_id)) - { - type = IM_SESSION_CONFERENCE_START; - } - } - return type; -} - -// // Member Functions // @@ -725,7 +1183,9 @@ void LLIMMgr::addMessage( dialog, FALSE); - notifyObserverSessionAdded(floater->getSessionID(), name, other_participant_id); + + LLIMModel::instance().newSession(new_session_id, name, dialog, other_participant_id); + // When we get a new IM, and if you are a god, display a bit // of information about the source. This is to help liaisons @@ -746,6 +1206,7 @@ void LLIMMgr::addMessage( //<< "*** position: " << position << std::endl; floater->addHistoryLine(bonus_info.str(), LLUIColorTable::instance().getColor("SystemChatColor")); + LLIMModel::instance().addMessage(new_session_id, from, bonus_info.str()); } make_ui_sound("UISndNewIncomingIMSession"); @@ -765,6 +1226,8 @@ void LLIMMgr::addMessage( floater->addHistoryLine(msg, color, true, other_participant_id, from); // Insert linked name to front of message } + LLIMModel::instance().addMessage(new_session_id, from, msg); + if( !LLFloaterReg::instanceVisible("communicate") && !floater->getVisible()) { LLFloaterChatterBox* chat_floater = LLFloaterChatterBox::getInstance(); @@ -1652,7 +2115,7 @@ public: { saved = llformat("(Saved %s) ", formatted_time(timestamp).c_str()); } - std::string buffer = separator_string + saved + message.substr(message_offset); + std::string buffer = saved + message.substr(message_offset); BOOL is_this_agent = FALSE; if(from_id == gAgentID) diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h index 37dcd1593f..6a354dfe92 100644 --- a/indra/newview/llimview.h +++ b/indra/newview/llimview.h @@ -38,6 +38,7 @@ #include "llinstantmessage.h" #include "lluuid.h" #include "llmultifloater.h" +#include "llrecentpeople.h" class LLFloaterChatterBox; class LLUUID; @@ -45,6 +46,47 @@ class LLFloaterIMPanel; class LLFriendObserver; class LLFloaterIM; +class LLIMModel : public LLSingleton<LLIMModel> +{ +public: + + struct LLIMSession + { + LLIMSession(std::string name, EInstantMessage type, LLUUID other_participant_id) + :mName(name), mType(type), mNumUnread(0), mOtherPraticipantID(other_participant_id) {} + + std::string mName; + EInstantMessage mType; + LLUUID mOtherPraticipantID; + S32 mNumUnread; + std::list<LLSD> mMsgs; + }; + + + LLIMModel(); + + static std::map<LLUUID, LLIMSession*> sSessionsMap; //mapping session_id to session + boost::signals2::signal<void(const LLSD&)> mChangedSignal; + boost::signals2::connection addChangedCallback( boost::function<void (const LLSD& data)> cb ); + + bool newSession(LLUUID session_id, std::string name, EInstantMessage type, LLUUID other_participant_id); + std::list<LLSD> getMessages(LLUUID session_id, int index = 0); + bool addMessage(LLUUID session_id, std::string from, std::string utf8_text); + bool addToHistory(LLUUID session_id, std::string from, std::string utf8_text); + //used to get the name of the session, for use as the title + //currently just the other avatar name + const std::string& getName(LLUUID session_id); + + static void sendLeaveSession(LLUUID session_id, LLUUID other_participant_id); + static bool sendStartSession(const LLUUID& temp_session_id, const LLUUID& other_participant_id, + const std::vector<LLUUID>& ids, EInstantMessage dialog); + static void sendTypingState(LLUUID session_id, LLUUID other_participant_id, BOOL typing); + static void sendMessage(const std::string& utf8_text, const LLUUID& im_session_id, + const LLUUID& other_participant_id, EInstantMessage dialog); + + void testMessages(); +}; + class LLIMSessionObserver { public: @@ -53,8 +95,11 @@ public: virtual void sessionRemoved(const LLUUID& session_id) = 0; }; + class LLIMMgr : public LLSingleton<LLIMMgr> { + friend class LLIMModel; + public: enum EInvitationType { diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index af653238d3..9d1b24ae11 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -34,7 +34,7 @@ #include <utility> // for std::pair<> -#include "llinventoryview.h" +#include "llfloaterinventory.h" #include "llinventorybridge.h" #include "message.h" @@ -184,6 +184,13 @@ PermissionMask LLInvFVBridge::getPermissionMask() const return PERM_ALL; } +// virtual +LLAssetType::EType LLInvFVBridge::getPreferredType() const +{ + return LLAssetType::AT_NONE; +} + + // Folders don't have creation dates. time_t LLInvFVBridge::getCreationDate() const { @@ -195,7 +202,7 @@ BOOL LLInvFVBridge::isItemRemovable() { LLInventoryModel* model = getInventoryModel(); if(!model) return FALSE; - if(model->isObjectDescendentOf(mUUID, gAgent.getInventoryRootID())) + if(model->isObjectDescendentOf(mUUID, gInventory.getRootFolderID())) { return TRUE; } @@ -660,8 +667,8 @@ BOOL LLInvFVBridge::isAgentInventory() const { LLInventoryModel* model = getInventoryModel(); if(!model) return FALSE; - if(gAgent.getInventoryRootID() == mUUID) return TRUE; - return model->isObjectDescendentOf(mUUID, gAgent.getInventoryRootID()); + if(gInventory.getRootFolderID() == mUUID) return TRUE; + return model->isObjectDescendentOf(mUUID, gInventory.getRootFolderID()); } BOOL LLInvFVBridge::isItemPermissive() const @@ -1020,7 +1027,7 @@ PermissionMask LLItemBridge::getPermissionMask() const } return perm_mask; } - + const std::string& LLItemBridge::getDisplayName() const { if(mDisplayName.empty()) @@ -1062,10 +1069,11 @@ LLFontGL::StyleFlags LLItemBridge::getLabelStyle() const std::string LLItemBridge::getLabelSuffix() const { - // assume that this won't be called before string table is loaded - static const char* NO_COPY =LLTrans::getString("NO_COPY").c_str(); - static const char* NO_MOD = LLTrans::getString("NO_MOD").c_str(); - static const char* NO_XFER = LLTrans::getString("NO_XFER").c_str(); + // String table is loaded before login screen and inventory items are + // loaded after login, so LLTrans should be ready. + static std::string NO_COPY =LLTrans::getString("no_copy"); + static std::string NO_MOD = LLTrans::getString("no_modify"); + static std::string NO_XFER = LLTrans::getString("no_transfer"); std::string suffix; LLInventoryItem* item = getItem(); @@ -1075,26 +1083,26 @@ std::string LLItemBridge::getLabelSuffix() const if(LLAssetType::AT_CALLINGCARD != item->getType() && item->getPermissions().getOwner() == gAgent.getID()) { - BOOL copy = item->getPermissions().allowCopyBy(gAgent.getID()); - BOOL mod = item->getPermissions().allowModifyBy(gAgent.getID()); - BOOL xfer = item->getPermissions().allowOperationBy(PERM_TRANSFER, - gAgent.getID()); BOOL link = (item->getActualType() == LLAssetType::AT_LINK); - - const char* EMPTY = ""; const char* LINK = " (link)"; // *TODO: Seraph translate if (link) return LINK; - const char* scopy; - if(copy) scopy = EMPTY; - else scopy = NO_COPY; - const char* smod; - if(mod) smod = EMPTY; - else smod = NO_MOD; - const char* sxfer; - if(xfer) sxfer = EMPTY; - else sxfer = NO_XFER; - suffix = llformat("%s%s%s",scopy,smod,sxfer); + BOOL copy = item->getPermissions().allowCopyBy(gAgent.getID()); + if (!copy) + { + suffix += NO_COPY; + } + BOOL mod = item->getPermissions().allowModifyBy(gAgent.getID()); + if (!mod) + { + suffix += NO_MOD; + } + BOOL xfer = item->getPermissions().allowOperationBy(PERM_TRANSFER, + gAgent.getID()); + if (!xfer) + { + suffix += NO_XFER; + } } } return suffix; @@ -1269,7 +1277,7 @@ BOOL LLFolderBridge::isItemRemovable() return FALSE; } - if(!model->isObjectDescendentOf(mUUID, gAgent.getInventoryRootID())) + if(!model->isObjectDescendentOf(mUUID, gInventory.getRootFolderID())) { return FALSE; } @@ -2525,9 +2533,9 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, // everything in the active window so that we don't follow // the selection to its new location (which is very // annoying). - if (LLInventoryView::getActiveInventory()) + if (LLFloaterInventory::getActiveInventory()) { - LLInventoryPanel* active_panel = LLInventoryView::getActiveInventory()->getPanel(); + LLInventoryPanel* active_panel = LLFloaterInventory::getActiveInventory()->getPanel(); LLInventoryPanel* panel = dynamic_cast<LLInventoryPanel*>(mInventoryPanel.get()); if (active_panel && (panel != active_panel)) { @@ -3348,7 +3356,7 @@ void LLObjectBridge::performAction(LLFolderView* folder, LLInventoryModel* model LLUUID object_id = mUUID; LLViewerInventoryItem* item; item = (LLViewerInventoryItem*)gInventory.getItem(object_id); - if(item && gInventory.isObjectDescendentOf(object_id, gAgent.getInventoryRootID())) + if(item && gInventory.isObjectDescendentOf(object_id, gInventory.getRootFolderID())) { rez_attachment(item, NULL); } @@ -3815,7 +3823,7 @@ void LLOutfitObserver::done() } if(pid.isNull()) { - pid = gAgent.getInventoryRootID(); + pid = gInventory.getRootFolderID(); } LLUUID cat_id = gInventory.createNewCategory( @@ -3922,7 +3930,7 @@ void wear_outfit_by_name(const std::string& name) LLInventoryModel::cat_array_t cat_array; LLInventoryModel::item_array_t item_array; LLNameCategoryCollector has_name(name); - gInventory.collectDescendentsIf(gAgent.getInventoryRootID(), + gInventory.collectDescendentsIf(gInventory.getRootFolderID(), cat_array, item_array, LLInventoryModel::EXCLUDE_TRASH, @@ -4960,8 +4968,8 @@ BOOL LLWearableBridgeAction::isInTrash() const BOOL LLWearableBridgeAction::isAgentInventory() const { if(!mModel) return FALSE; - if(gAgent.getInventoryRootID() == mUUID) return TRUE; - return mModel->isObjectDescendentOf(mUUID, gAgent.getInventoryRootID()); + if(gInventory.getRootFolderID() == mUUID) return TRUE; + return mModel->isObjectDescendentOf(mUUID, gInventory.getRootFolderID()); } void LLWearableBridgeAction::wearOnAvatar() diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index 016eb701d6..a37b7969ed 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -38,7 +38,8 @@ #include "llviewercontrol.h" #include "llcallingcard.h" #include "llinventorymodel.h" -#include "llinventoryview.h" +#include "llfloaterinventory.h" +#include "llfoldervieweventlistener.h" enum EInventoryIcon { @@ -147,6 +148,7 @@ public: virtual const std::string& getName() const; virtual const std::string& getDisplayName() const; virtual PermissionMask getPermissionMask() const; + virtual LLAssetType::EType getPreferredType() const; virtual time_t getCreationDate() const; virtual LLFontGL::StyleFlags getLabelStyle() const { diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp new file mode 100644 index 0000000000..9cbe11f5c9 --- /dev/null +++ b/indra/newview/llinventoryfilter.cpp @@ -0,0 +1,631 @@ +/** +* @file llinventoryfilter.cpp +* @brief Support for filtering your inventory to only display a subset of the +* available items. +* +* $LicenseInfo:firstyear=2005&license=viewergpl$ +* +* Copyright (c) 2005-2009, Linden Research, Inc. +* +* Second Life Viewer Source Code +* The source code in this file ("Source Code") is provided by Linden Lab +* to you under the terms of the GNU General Public License, version 2.0 +* ("GPL"), unless you have obtained a separate licensing agreement +* ("Other License"), formally executed by you and Linden Lab. Terms of +* the GPL can be found in doc/GPL-license.txt in this distribution, or +* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 +* +* There are special exceptions to the terms and conditions of the GPL as +* it is applied to this Source Code. View the full text of the exception +* in the file doc/FLOSS-exception.txt in this software distribution, or +* online at +* http://secondlifegrid.net/programs/open_source/licensing/flossexception +* +* By copying, modifying or distributing this software, you acknowledge +* that you have read and understood your obligations described above, +* and agree to abide by those obligations. +* +* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO +* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +* COMPLETENESS OR PERFORMANCE. +* $/LicenseInfo$ +*/ +#include "llviewerprecompiledheaders.h" + +#include "llinventoryfilter.h" + +// viewer includes +#include "llfoldervieweventlistener.h" +#include "llfolderviewitem.h" +#include "llinventorymodel.h" // gInventory.backgroundFetchActive() +#include "llviewercontrol.h" + +// linden library includes +#include "lltrans.h" + +///---------------------------------------------------------------------------- +/// Class LLInventoryFilter +///---------------------------------------------------------------------------- +LLInventoryFilter::LLInventoryFilter(const std::string& name) +: mName(name), + mModified(FALSE), + mNeedTextRebuild(TRUE) +{ + mFilterOps.mFilterTypes = 0xffffffff; + mFilterOps.mMinDate = time_min(); + mFilterOps.mMaxDate = time_max(); + mFilterOps.mHoursAgo = 0; + mFilterOps.mShowFolderState = SHOW_NON_EMPTY_FOLDERS; + mFilterOps.mPermissions = PERM_NONE; + + mOrder = SO_FOLDERS_BY_NAME; // This gets overridden by a pref immediately + + mSubStringMatchOffset = 0; + mFilterSubString.clear(); + mFilterGeneration = 0; + mMustPassGeneration = S32_MAX; + mMinRequiredGeneration = 0; + mFilterCount = 0; + mNextFilterGeneration = mFilterGeneration + 1; + + mLastLogoff = gSavedPerAccountSettings.getU32("LastLogoff"); + mFilterBehavior = FILTER_NONE; + + // copy mFilterOps into mDefaultFilterOps + markDefault(); +} + +LLInventoryFilter::~LLInventoryFilter() +{ +} + +BOOL LLInventoryFilter::check(LLFolderViewItem* item) +{ + time_t earliest; + + earliest = time_corrected() - mFilterOps.mHoursAgo * 3600; + if (mFilterOps.mMinDate > time_min() && mFilterOps.mMinDate < earliest) + { + earliest = mFilterOps.mMinDate; + } + else if (!mFilterOps.mHoursAgo) + { + earliest = 0; + } + LLFolderViewEventListener* listener = item->getListener(); + mSubStringMatchOffset = mFilterSubString.size() ? item->getSearchableLabel().find(mFilterSubString) : std::string::npos; + BOOL passed = (0x1 << listener->getInventoryType() & mFilterOps.mFilterTypes || listener->getInventoryType() == LLInventoryType::IT_NONE) + && (mFilterSubString.size() == 0 || mSubStringMatchOffset != std::string::npos) + && ((listener->getPermissionMask() & mFilterOps.mPermissions) == mFilterOps.mPermissions) + && (listener->getCreationDate() >= earliest && listener->getCreationDate() <= mFilterOps.mMaxDate); + return passed; +} + +const std::string LLInventoryFilter::getFilterSubString(BOOL trim) +{ + return mFilterSubString; +} + +std::string::size_type LLInventoryFilter::getStringMatchOffset() const +{ + return mSubStringMatchOffset; +} + +// has user modified default filter params? +BOOL LLInventoryFilter::isNotDefault() +{ + return mFilterOps.mFilterTypes != mDefaultFilterOps.mFilterTypes + || mFilterSubString.size() + || mFilterOps.mPermissions != mDefaultFilterOps.mPermissions + || mFilterOps.mMinDate != mDefaultFilterOps.mMinDate + || mFilterOps.mMaxDate != mDefaultFilterOps.mMaxDate + || mFilterOps.mHoursAgo != mDefaultFilterOps.mHoursAgo; +} + +BOOL LLInventoryFilter::isActive() +{ + return mFilterOps.mFilterTypes != 0xffffffff + || mFilterSubString.size() + || mFilterOps.mPermissions != PERM_NONE + || mFilterOps.mMinDate != time_min() + || mFilterOps.mMaxDate != time_max() + || mFilterOps.mHoursAgo != 0; +} + +BOOL LLInventoryFilter::isModified() +{ + return mModified; +} + +BOOL LLInventoryFilter::isModifiedAndClear() +{ + BOOL ret = mModified; + mModified = FALSE; + return ret; +} + +void LLInventoryFilter::setFilterTypes(U32 types) +{ + if (mFilterOps.mFilterTypes != types) + { + // keep current items only if no type bits getting turned off + BOOL fewer_bits_set = (mFilterOps.mFilterTypes & ~types); + BOOL more_bits_set = (~mFilterOps.mFilterTypes & types); + + mFilterOps.mFilterTypes = types; + if (more_bits_set && fewer_bits_set) + { + // neither less or more restrive, both simultaneously + // so we need to filter from scratch + setModified(FILTER_RESTART); + } + else if (more_bits_set) + { + // target is only one of all requested types so more type bits == less restrictive + setModified(FILTER_LESS_RESTRICTIVE); + } + else if (fewer_bits_set) + { + setModified(FILTER_MORE_RESTRICTIVE); + } + + } +} + +void LLInventoryFilter::setFilterSubString(const std::string& string) +{ + if (mFilterSubString != string) + { + // hitting BACKSPACE, for example + BOOL less_restrictive = mFilterSubString.size() >= string.size() && !mFilterSubString.substr(0, string.size()).compare(string); + // appending new characters + BOOL more_restrictive = mFilterSubString.size() < string.size() && !string.substr(0, mFilterSubString.size()).compare(mFilterSubString); + mFilterSubString = string; + LLStringUtil::toUpper(mFilterSubString); + LLStringUtil::trimHead(mFilterSubString); + + if (less_restrictive) + { + setModified(FILTER_LESS_RESTRICTIVE); + } + else if (more_restrictive) + { + setModified(FILTER_MORE_RESTRICTIVE); + } + else + { + setModified(FILTER_RESTART); + } + } +} + +void LLInventoryFilter::setFilterPermissions(PermissionMask perms) +{ + if (mFilterOps.mPermissions != perms) + { + // keep current items only if no perm bits getting turned off + BOOL fewer_bits_set = (mFilterOps.mPermissions & ~perms); + BOOL more_bits_set = (~mFilterOps.mPermissions & perms); + mFilterOps.mPermissions = perms; + + if (more_bits_set && fewer_bits_set) + { + setModified(FILTER_RESTART); + } + else if (more_bits_set) + { + // target must have all requested permission bits, so more bits == more restrictive + setModified(FILTER_MORE_RESTRICTIVE); + } + else if (fewer_bits_set) + { + setModified(FILTER_LESS_RESTRICTIVE); + } + } +} + +void LLInventoryFilter::setDateRange(time_t min_date, time_t max_date) +{ + mFilterOps.mHoursAgo = 0; + if (mFilterOps.mMinDate != min_date) + { + mFilterOps.mMinDate = min_date; + setModified(); + } + if (mFilterOps.mMaxDate != llmax(mFilterOps.mMinDate, max_date)) + { + mFilterOps.mMaxDate = llmax(mFilterOps.mMinDate, max_date); + setModified(); + } +} + +void LLInventoryFilter::setDateRangeLastLogoff(BOOL sl) +{ + if (sl && !isSinceLogoff()) + { + setDateRange(mLastLogoff, time_max()); + setModified(); + } + if (!sl && isSinceLogoff()) + { + setDateRange(0, time_max()); + setModified(); + } +} + +BOOL LLInventoryFilter::isSinceLogoff() +{ + return (mFilterOps.mMinDate == (time_t)mLastLogoff) && + (mFilterOps.mMaxDate == time_max()); +} + +void LLInventoryFilter::setHoursAgo(U32 hours) +{ + if (mFilterOps.mHoursAgo != hours) + { + // *NOTE: need to cache last filter time, in case filter goes stale + BOOL less_restrictive = (mFilterOps.mMinDate == time_min() && mFilterOps.mMaxDate == time_max() && hours > mFilterOps.mHoursAgo); + BOOL more_restrictive = (mFilterOps.mMinDate == time_min() && mFilterOps.mMaxDate == time_max() && hours <= mFilterOps.mHoursAgo); + mFilterOps.mHoursAgo = hours; + mFilterOps.mMinDate = time_min(); + mFilterOps.mMaxDate = time_max(); + if (less_restrictive) + { + setModified(FILTER_LESS_RESTRICTIVE); + } + else if (more_restrictive) + { + setModified(FILTER_MORE_RESTRICTIVE); + } + else + { + setModified(FILTER_RESTART); + } + } +} +void LLInventoryFilter::setShowFolderState(EFolderShow state) +{ + if (mFilterOps.mShowFolderState != state) + { + mFilterOps.mShowFolderState = state; + if (state == SHOW_NON_EMPTY_FOLDERS) + { + // showing fewer folders than before + setModified(FILTER_MORE_RESTRICTIVE); + } + else if (state == SHOW_ALL_FOLDERS) + { + // showing same folders as before and then some + setModified(FILTER_LESS_RESTRICTIVE); + } + else + { + setModified(); + } + } +} + +void LLInventoryFilter::setSortOrder(U32 order) +{ + if (mOrder != order) + { + mOrder = order; + setModified(); + } +} + +void LLInventoryFilter::markDefault() +{ + mDefaultFilterOps = mFilterOps; +} + +void LLInventoryFilter::resetDefault() +{ + mFilterOps = mDefaultFilterOps; + setModified(); +} + +void LLInventoryFilter::setModified(EFilterBehavior behavior) +{ + mModified = TRUE; + mNeedTextRebuild = TRUE; + mFilterGeneration = mNextFilterGeneration++; + + if (mFilterBehavior == FILTER_NONE) + { + mFilterBehavior = behavior; + } + else if (mFilterBehavior != behavior) + { + // trying to do both less restrictive and more restrictive filter + // basically means restart from scratch + mFilterBehavior = FILTER_RESTART; + } + + if (isNotDefault()) + { + // if not keeping current filter results, update last valid as well + switch(mFilterBehavior) + { + case FILTER_RESTART: + mMustPassGeneration = mFilterGeneration; + mMinRequiredGeneration = mFilterGeneration; + break; + case FILTER_LESS_RESTRICTIVE: + mMustPassGeneration = mFilterGeneration; + break; + case FILTER_MORE_RESTRICTIVE: + mMinRequiredGeneration = mFilterGeneration; + // must have passed either current filter generation (meaningless, as it hasn't been run yet) + // or some older generation, so keep the value + mMustPassGeneration = llmin(mMustPassGeneration, mFilterGeneration); + break; + default: + llerrs << "Bad filter behavior specified" << llendl; + } + } + else + { + // shortcut disabled filters to show everything immediately + mMinRequiredGeneration = 0; + mMustPassGeneration = S32_MAX; + } +} + +BOOL LLInventoryFilter::isFilterWith(LLInventoryType::EType t) +{ + return mFilterOps.mFilterTypes & (0x01 << t); +} + +std::string LLInventoryFilter::getFilterText() +{ + if (!mNeedTextRebuild) + { + return mFilterText; + } + + mNeedTextRebuild = FALSE; + std::string filtered_types; + std::string not_filtered_types; + BOOL filtered_by_type = FALSE; + BOOL filtered_by_all_types = TRUE; + S32 num_filter_types = 0; + mFilterText.clear(); + + if (isFilterWith(LLInventoryType::IT_ANIMATION)) + { + //filtered_types += " Animations,"; + filtered_types += LLTrans::getString("Animations"); + filtered_by_type = TRUE; + num_filter_types++; + } + else + { + //not_filtered_types += " Animations,"; + not_filtered_types += LLTrans::getString("Animations"); + + filtered_by_all_types = FALSE; + } + + if (isFilterWith(LLInventoryType::IT_CALLINGCARD)) + { + //filtered_types += " Calling Cards,"; + filtered_types += LLTrans::getString("Calling Cards"); + filtered_by_type = TRUE; + num_filter_types++; + } + else + { + //not_filtered_types += " Calling Cards,"; + not_filtered_types += LLTrans::getString("Calling Cards"); + filtered_by_all_types = FALSE; + } + + if (isFilterWith(LLInventoryType::IT_WEARABLE)) + { + //filtered_types += " Clothing,"; + filtered_types += LLTrans::getString("Clothing"); + filtered_by_type = TRUE; + num_filter_types++; + } + else + { + //not_filtered_types += " Clothing,"; + not_filtered_types += LLTrans::getString("Clothing"); + filtered_by_all_types = FALSE; + } + + if (isFilterWith(LLInventoryType::IT_GESTURE)) + { + //filtered_types += " Gestures,"; + filtered_types += LLTrans::getString("Gestures"); + filtered_by_type = TRUE; + num_filter_types++; + } + else + { + //not_filtered_types += " Gestures,"; + not_filtered_types += LLTrans::getString("Gestures"); + filtered_by_all_types = FALSE; + } + + if (isFilterWith(LLInventoryType::IT_LANDMARK)) + { + //filtered_types += " Landmarks,"; + filtered_types += LLTrans::getString("Landmarks"); + filtered_by_type = TRUE; + num_filter_types++; + } + else + { + //not_filtered_types += " Landmarks,"; + not_filtered_types += LLTrans::getString("Landmarks"); + filtered_by_all_types = FALSE; + } + + if (isFilterWith(LLInventoryType::IT_NOTECARD)) + { + //filtered_types += " Notecards,"; + filtered_types += LLTrans::getString("Notecards"); + filtered_by_type = TRUE; + num_filter_types++; + } + else + { + //not_filtered_types += " Notecards,"; + not_filtered_types += LLTrans::getString("Notecards"); + filtered_by_all_types = FALSE; + } + + if (isFilterWith(LLInventoryType::IT_OBJECT) && isFilterWith(LLInventoryType::IT_ATTACHMENT)) + { + //filtered_types += " Objects,"; + filtered_types += LLTrans::getString("Objects"); + filtered_by_type = TRUE; + num_filter_types++; + } + else + { + //not_filtered_types += " Objects,"; + not_filtered_types += LLTrans::getString("Objects"); + filtered_by_all_types = FALSE; + } + + if (isFilterWith(LLInventoryType::IT_LSL)) + { + //filtered_types += " Scripts,"; + filtered_types += LLTrans::getString("Scripts"); + filtered_by_type = TRUE; + num_filter_types++; + } + else + { + //not_filtered_types += " Scripts,"; + not_filtered_types += LLTrans::getString("Scripts"); + filtered_by_all_types = FALSE; + } + + if (isFilterWith(LLInventoryType::IT_SOUND)) + { + //filtered_types += " Sounds,"; + filtered_types += LLTrans::getString("Sounds"); + filtered_by_type = TRUE; + num_filter_types++; + } + else + { + //not_filtered_types += " Sounds,"; + not_filtered_types += LLTrans::getString("Sounds"); + filtered_by_all_types = FALSE; + } + + if (isFilterWith(LLInventoryType::IT_TEXTURE)) + { + //filtered_types += " Textures,"; + filtered_types += LLTrans::getString("Textures"); + filtered_by_type = TRUE; + num_filter_types++; + } + else + { + //not_filtered_types += " Textures,"; + not_filtered_types += LLTrans::getString("Textures"); + filtered_by_all_types = FALSE; + } + + if (isFilterWith(LLInventoryType::IT_SNAPSHOT)) + { + //filtered_types += " Snapshots,"; + filtered_types += LLTrans::getString("Snapshots"); + filtered_by_type = TRUE; + num_filter_types++; + } + else + { + //not_filtered_types += " Snapshots,"; + not_filtered_types += LLTrans::getString("Snapshots"); + filtered_by_all_types = FALSE; + } + + if (!gInventory.backgroundFetchActive() + && filtered_by_type + && !filtered_by_all_types) + { + mFilterText += " - "; + if (num_filter_types < 5) + { + mFilterText += filtered_types; + } + else + { + //mFilterText += "No "; + mFilterText += LLTrans::getString("No Filters"); + mFilterText += not_filtered_types; + } + // remove the ',' at the end + mFilterText.erase(mFilterText.size() - 1, 1); + } + + if (isSinceLogoff()) + { + //mFilterText += " - Since Logoff"; + mFilterText += LLTrans::getString("Since Logoff"); + } + return mFilterText; +} + +void LLInventoryFilter::toLLSD(LLSD& data) +{ + data["filter_types"] = (LLSD::Integer)getFilterTypes(); + data["min_date"] = (LLSD::Integer)getMinDate(); + data["max_date"] = (LLSD::Integer)getMaxDate(); + data["hours_ago"] = (LLSD::Integer)getHoursAgo(); + data["show_folder_state"] = (LLSD::Integer)getShowFolderState(); + data["permissions"] = (LLSD::Integer)getFilterPermissions(); + data["substring"] = (LLSD::String)getFilterSubString(); + data["sort_order"] = (LLSD::Integer)getSortOrder(); + data["since_logoff"] = (LLSD::Boolean)isSinceLogoff(); +} + +void LLInventoryFilter::fromLLSD(LLSD& data) +{ + if(data.has("filter_types")) + { + setFilterTypes((U32)data["filter_types"].asInteger()); + } + + if(data.has("min_date") && data.has("max_date")) + { + setDateRange(data["min_date"].asInteger(), data["max_date"].asInteger()); + } + + if(data.has("hours_ago")) + { + setHoursAgo((U32)data["hours_ago"].asInteger()); + } + + if(data.has("show_folder_state")) + { + setShowFolderState((EFolderShow)data["show_folder_state"].asInteger()); + } + + if(data.has("permissions")) + { + setFilterPermissions((PermissionMask)data["permissions"].asInteger()); + } + + if(data.has("substring")) + { + setFilterSubString(std::string(data["substring"].asString())); + } + + if(data.has("sort_order")) + { + setSortOrder((U32)data["sort_order"].asInteger()); + } + + if(data.has("since_logoff")) + { + setDateRangeLastLogoff((bool)data["since_logoff"].asBoolean()); + } +} diff --git a/indra/newview/llinventoryfilter.h b/indra/newview/llinventoryfilter.h new file mode 100644 index 0000000000..7c5f6681cf --- /dev/null +++ b/indra/newview/llinventoryfilter.h @@ -0,0 +1,150 @@ +/** +* @file llinventoryfilter.h +* @brief Support for filtering your inventory to only display a subset of the +* available items. +* +* $LicenseInfo:firstyear=2005&license=viewergpl$ +* +* Copyright (c) 2005-2009, Linden Research, Inc. +* +* Second Life Viewer Source Code +* The source code in this file ("Source Code") is provided by Linden Lab +* to you under the terms of the GNU General Public License, version 2.0 +* ("GPL"), unless you have obtained a separate licensing agreement +* ("Other License"), formally executed by you and Linden Lab. Terms of +* the GPL can be found in doc/GPL-license.txt in this distribution, or +* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 +* +* There are special exceptions to the terms and conditions of the GPL as +* it is applied to this Source Code. View the full text of the exception +* in the file doc/FLOSS-exception.txt in this software distribution, or +* online at +* http://secondlifegrid.net/programs/open_source/licensing/flossexception +* +* By copying, modifying or distributing this software, you acknowledge +* that you have read and understood your obligations described above, +* and agree to abide by those obligations. +* +* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO +* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +* COMPLETENESS OR PERFORMANCE. +* $/LicenseInfo$ +*/ +#ifndef LLINVENTORYFILTER_H +#define LLINVENTORYFILTER_H + +// lots of includes here +#include "llinventorytype.h" +#include "llpermissionsflags.h" // PermissionsMask + +class LLFolderViewItem; + +class LLInventoryFilter +{ +public: + typedef enum e_folder_show + { + SHOW_ALL_FOLDERS, + SHOW_NON_EMPTY_FOLDERS, + SHOW_NO_FOLDERS + } EFolderShow; + + typedef enum e_filter_behavior + { + FILTER_NONE, // nothing to do, already filtered + FILTER_RESTART, // restart filtering from scratch + FILTER_LESS_RESTRICTIVE, // existing filtered items will certainly pass this filter + FILTER_MORE_RESTRICTIVE // if you didn't pass the previous filter, you definitely won't pass this one + } EFilterBehavior; + + static const U32 SO_DATE = 1; + static const U32 SO_FOLDERS_BY_NAME = 2; + static const U32 SO_SYSTEM_FOLDERS_TO_TOP = 4; + + LLInventoryFilter(const std::string& name); + virtual ~LLInventoryFilter(); + + void setFilterTypes(U32 types); + U32 getFilterTypes() const { return mFilterOps.mFilterTypes; } + + void setFilterSubString(const std::string& string); + const std::string getFilterSubString(BOOL trim = FALSE); + + void setFilterPermissions(PermissionMask perms); + PermissionMask getFilterPermissions() const { return mFilterOps.mPermissions; } + + void setDateRange(time_t min_date, time_t max_date); + void setDateRangeLastLogoff(BOOL sl); + time_t getMinDate() const { return mFilterOps.mMinDate; } + time_t getMaxDate() const { return mFilterOps.mMaxDate; } + + void setHoursAgo(U32 hours); + U32 getHoursAgo() const { return mFilterOps.mHoursAgo; } + + void setShowFolderState( EFolderShow state); + EFolderShow getShowFolderState() { return mFilterOps.mShowFolderState; } + + void setSortOrder(U32 order); + U32 getSortOrder() { return mOrder; } + + BOOL check(LLFolderViewItem* item); + std::string::size_type getStringMatchOffset() const; + BOOL isActive(); + BOOL isNotDefault(); + BOOL isModified(); + BOOL isModifiedAndClear(); + BOOL isSinceLogoff(); + void clearModified() { mModified = FALSE; mFilterBehavior = FILTER_NONE; } + const std::string getName() const { return mName; } + std::string getFilterText(); + + void setFilterCount(S32 count) { mFilterCount = count; } + S32 getFilterCount() { return mFilterCount; } + void decrementFilterCount() { mFilterCount--; } + + void markDefault(); + void resetDefault(); + + BOOL isFilterWith(LLInventoryType::EType t); + + S32 getCurrentGeneration() const { return mFilterGeneration; } + S32 getMinRequiredGeneration() const { return mMinRequiredGeneration; } + S32 getMustPassGeneration() const { return mMustPassGeneration; } + + //RN: this is public to allow system to externally force a global refilter + void setModified(EFilterBehavior behavior = FILTER_RESTART); + + void toLLSD(LLSD& data); + void fromLLSD(LLSD& data); + +protected: + struct filter_ops + { + U32 mFilterTypes; + time_t mMinDate; + time_t mMaxDate; + U32 mHoursAgo; + EFolderShow mShowFolderState; + PermissionMask mPermissions; + }; + filter_ops mFilterOps; + filter_ops mDefaultFilterOps; + std::string::size_type mSubStringMatchOffset; + std::string mFilterSubString; + U32 mOrder; + const std::string mName; + S32 mFilterGeneration; + S32 mMustPassGeneration; + S32 mMinRequiredGeneration; + S32 mFilterCount; + S32 mNextFilterGeneration; + EFilterBehavior mFilterBehavior; + +private: + U32 mLastLogoff; + BOOL mModified; + BOOL mNeedTextRebuild; + std::string mFilterText; +}; + +#endif diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 5a14bdd55e..2c281a4615 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -46,7 +46,7 @@ #include "llfloater.h" #include "llfocusmgr.h" #include "llinventorybridge.h" -#include "llinventoryview.h" +#include "llfloaterinventory.h" #include "llviewerinventory.h" #include "llviewermessage.h" #include "llviewerwindow.h" @@ -155,9 +155,20 @@ bool LLCanCache::operator()(LLInventoryCategory* cat, LLInventoryItem* item) LLInventoryModel gInventory; // Default constructor -LLInventoryModel::LLInventoryModel() : - mModifyMask(LLInventoryObserver::ALL), +LLInventoryModel::LLInventoryModel() +: mModifyMask(LLInventoryObserver::ALL), + mChangedItemIDs(), + mCategoryMap(), + mItemMap(), + mCategoryLock(), + mItemLock(), mLastItem(NULL), + mParentChildCategoryTree(), + mParentChildItemTree(), + mObservers(), + mRootFolderID(), + mLibraryRootFolderID(), + mLibraryOwnerID(), mIsAgentInvUsable(false) { } @@ -299,7 +310,7 @@ LLUUID LLInventoryModel::findCategoryUUIDForType(LLAssetType::EType t, bool crea LLUUID rv = findCatUUID(t); if(rv.isNull() && isInventoryUsable() && create_folder) { - LLUUID root_id = gAgent.getInventoryRootID(); + LLUUID root_id = gInventory.getRootFolderID(); if(root_id.notNull()) { rv = createNewCategory(root_id, t, LLStringUtil::null); @@ -312,7 +323,7 @@ LLUUID LLInventoryModel::findCategoryUUIDForType(LLAssetType::EType t, bool crea // preferred type. Returns LLUUID::null if not found. LLUUID LLInventoryModel::findCatUUID(LLAssetType::EType preferred_type) { - LLUUID root_id = gAgent.getInventoryRootID(); + LLUUID root_id = gInventory.getRootFolderID(); if(LLAssetType::AT_CATEGORY == preferred_type) { return root_id; @@ -469,7 +480,7 @@ void LLInventoryModel::collectLinkedItems(const LLUUID& id, { LLInventoryModel::cat_array_t cat_array; LLLinkedItemIDMatches is_linked_item_match(id); - collectDescendentsIf(gAgent.getInventoryRootID(), + collectDescendentsIf(gInventory.getRootFolderID(), cat_array, items, LLInventoryModel::INCLUDE_TRASH, @@ -500,7 +511,7 @@ void LLInventoryModel::appendPath(const LLUUID& id, std::string& path) bool LLInventoryModel::isInventoryUsable() { bool result = false; - if(gAgent.getInventoryRootID().notNull() && mIsAgentInvUsable) + if(gInventory.getRootFolderID().notNull() && mIsAgentInvUsable) { result = true; } @@ -1478,8 +1489,8 @@ void LLInventoryModel::startBackgroundFetch(const LLUUID& cat_id) if (!sFullFetchStarted) { sFullFetchStarted = TRUE; - sFetchQueue.push_back(gInventoryLibraryRoot); - sFetchQueue.push_back(gAgent.getInventoryRootID()); + sFetchQueue.push_back(gInventory.getLibraryRootFolderID()); + sFetchQueue.push_back(gInventory.getRootFolderID()); gIdleCallbacks.addFunction(&LLInventoryModel::backgroundFetch, NULL); } } @@ -2271,7 +2282,7 @@ void LLInventoryModel::buildParentChildMap() else { // it's a protected folder. - cat->setParent(gAgent.getInventoryRootID()); + cat->setParent(gInventory.getRootFolderID()); } cat->updateServer(TRUE); catsp = getUnlockedCatArray(cat->getParentUUID()); @@ -2371,7 +2382,7 @@ void LLInventoryModel::buildParentChildMap() } } - const LLUUID& agent_inv_root_id = gAgent.getInventoryRootID(); + LLUUID agent_inv_root_id = gInventory.getRootFolderID(); if (agent_inv_root_id.notNull()) { cat_array_t* catsp = get_ptr_in_map(mParentChildCategoryTree, agent_inv_root_id); @@ -2821,7 +2832,7 @@ void LLInventoryModel::processUpdateInventoryFolder(LLMessageSystem* msg, gInventory.notifyObservers(); // *HACK: Do the 'show' logic for a new item in the inventory. - LLInventoryView* view = LLInventoryView::getActiveInventory(); + LLFloaterInventory* view = LLFloaterInventory::getActiveInventory(); if(view) { view->getPanel()->setSelection(lastfolder->getUUID(), TAKE_FOCUS_NO); @@ -3030,13 +3041,13 @@ void LLInventoryModel::processBulkUpdateInventory(LLMessageSystem* msg, void**) // The incoming inventory could span more than one BulkInventoryUpdate packet, // so record the transaction ID for this purchase, then wear all clothing // that comes in as part of that transaction ID. JC - if (LLInventoryView::sWearNewClothing) + if (LLFloaterInventory::sWearNewClothing) { - LLInventoryView::sWearNewClothingTransactionID = tid; - LLInventoryView::sWearNewClothing = FALSE; + LLFloaterInventory::sWearNewClothingTransactionID = tid; + LLFloaterInventory::sWearNewClothing = FALSE; } - if (tid == LLInventoryView::sWearNewClothingTransactionID) + if (tid == LLFloaterInventory::sWearNewClothingTransactionID) { count = wearable_ids.size(); for (i = 0; i < count; ++i) @@ -3054,7 +3065,7 @@ void LLInventoryModel::processBulkUpdateInventory(LLMessageSystem* msg, void**) gInventoryCallbacks.fire(cbinfo.mCallback, cbinfo.mInvID); } // Don't show the inventory. We used to call showAgentInventory here. - //LLInventoryView* view = LLInventoryView::getActiveInventory(); + //LLFloaterInventory* view = LLFloaterInventory::getActiveInventory(); //if(view) //{ // const BOOL take_keyboard_focus = FALSE; @@ -3064,10 +3075,10 @@ void LLInventoryModel::processBulkUpdateInventory(LLMessageSystem* msg, void**) // // HACK to open inventory offers that are accepted. This information // // really needs to flow through the instant messages and inventory // // transfer/update messages. - // if (LLInventoryView::sOpenNextNewItem) + // if (LLFloaterInventory::sOpenNextNewItem) // { // view->openSelected(); - // LLInventoryView::sOpenNextNewItem = FALSE; + // LLFloaterInventory::sOpenNextNewItem = FALSE; // } // // // restore keyboard focus @@ -3232,6 +3243,36 @@ void LLInventoryModel::removeItem(const LLUUID& item_id) } } +LLUUID LLInventoryModel::getRootFolderID() const +{ + return mRootFolderID; +} + +void LLInventoryModel::setRootFolderID(const LLUUID& val) +{ + mRootFolderID = val; +} + +LLUUID LLInventoryModel::getLibraryRootFolderID() const +{ + return mLibraryRootFolderID; +} + +void LLInventoryModel::setLibraryRootFolderID(const LLUUID& val) +{ + mLibraryRootFolderID = val; +} + +LLUUID LLInventoryModel::getLibraryOwnerID() const +{ + return mLibraryOwnerID; +} + +void LLInventoryModel::setLibraryOwnerID(const LLUUID& val) +{ + mLibraryOwnerID = val; +} + //---------------------------------------------------------------------------- // *NOTE: DEBUG functionality diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h index 46288700d2..950e8866bb 100644 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -204,7 +204,7 @@ public: // Calling this method with an inventory item will either change // an existing item with a matching item_id, or will add the item // to the current inventory. Returns the change mask generated by - // the update. No notifcation will be sent to observers. This + // the update. No notification will be sent to observers. This // method will only generate network traffic if the item had to be // reparented. // *NOTE: In usage, you will want to perform cache accounting @@ -231,7 +231,7 @@ public: // delete a particular inventory object by ID. This will purge one // object from the internal data structures maintaining a - // cosistent internal state. No cache accounting, observer + // consistent internal state. No cache accounting, observer // notification, or server update is performed. Purges linked items. void deleteObject(const LLUUID& id); @@ -240,12 +240,12 @@ public: void purgeObject(const LLUUID& id); void purgeLinkedObjects(const LLUUID& id); - // This is a method which collects the descendents of the id + // This is a method which collects the descendants of the id // provided. If the category is not found, no action is // taken. This method goes through the long winded process of // removing server representation of folders and items while doing // cache accounting in a fairly efficient manner. This method does - // not notify observers (though maybe it shouldd...) + // not notify observers (though maybe it should...) void purgeDescendentsOf(const LLUUID& id); // This method optimally removes the referenced categories and @@ -394,6 +394,22 @@ public: static bool isEverythingFetched(); static void backgroundFetch(void*); // background fetch idle function static void incrBulkFetch(S16 fetching) { sBulkFetchCount+=fetching; if (sBulkFetchCount<0) sBulkFetchCount=0; } + + + // Data about the agent's root folder and root library folder + // are stored here, rather than in LLAgent where it used to be, because + // gInventory is a singleton and represents the agent's inventory. + // The "library" is actually the inventory of a special agent, + // usually Alexandria Linden. + LLUUID getRootFolderID() const; + LLUUID getLibraryOwnerID() const; + LLUUID getLibraryRootFolderID() const; + + // These are set during login with data from the server + void setRootFolderID(const LLUUID& id); + void setLibraryOwnerID(const LLUUID& id); + void setLibraryRootFolderID(const LLUUID& id); + protected: // Internal methods which add inventory and make sure that all of @@ -446,7 +462,7 @@ protected: item_array_t* getUnlockedItemArray(const LLUUID& id); protected: - // Varaibles used to track what has changed since the last notify. + // Variables used to track what has changed since the last notify. U32 mModifyMask; typedef std::set<LLUUID> changed_items_t; changed_items_t mChangedItemIDs; @@ -477,6 +493,11 @@ protected: typedef std::set<LLInventoryObserver*> observer_list_t; observer_list_t mObservers; + // Agent inventory folder information. + LLUUID mRootFolderID; + LLUUID mLibraryRootFolderID; + LLUUID mLibraryOwnerID; + // completing the fetch once per session should be sufficient static BOOL sBackgroundFetchActive; static BOOL sTimelyFetchPending; diff --git a/indra/newview/lljoystickbutton.cpp b/indra/newview/lljoystickbutton.cpp index 8e6889a379..d63eebfcac 100644 --- a/indra/newview/lljoystickbutton.cpp +++ b/indra/newview/lljoystickbutton.cpp @@ -49,11 +49,11 @@ #include "llglheaders.h" -static LLDefaultWidgetRegistry::Register<LLJoystickAgentSlide> r1("joystick_slide"); -static LLDefaultWidgetRegistry::Register<LLJoystickAgentTurn> r2("joystick_turn"); -static LLDefaultWidgetRegistry::Register<LLJoystickCameraRotate> r3("joystick_rotate"); -static LLDefaultWidgetRegistry::Register<LLJoystickCameraZoom> r4("joystick_zoom"); -static LLDefaultWidgetRegistry::Register<LLJoystickCameraTrack> r5("joystick_track"); +static LLDefaultChildRegistry::Register<LLJoystickAgentSlide> r1("joystick_slide"); +static LLDefaultChildRegistry::Register<LLJoystickAgentTurn> r2("joystick_turn"); +static LLDefaultChildRegistry::Register<LLJoystickCameraRotate> r3("joystick_rotate"); +static LLDefaultChildRegistry::Register<LLJoystickCameraZoom> r4("joystick_zoom"); +static LLDefaultChildRegistry::Register<LLJoystickCameraTrack> r5("joystick_track"); diff --git a/indra/newview/lljoystickbutton.h b/indra/newview/lljoystickbutton.h index 954a8c481d..d0f63803ea 100644 --- a/indra/newview/lljoystickbutton.h +++ b/indra/newview/lljoystickbutton.h @@ -63,7 +63,7 @@ public: Params() : quadrant("quadrant", JQ_ORIGIN) { - label(""); + label = ""; } }; LLJoystick(const Params&); diff --git a/indra/newview/lllistbrowser.cpp b/indra/newview/lllistbrowser.cpp new file mode 100644 index 0000000000..edd8e9818f --- /dev/null +++ b/indra/newview/lllistbrowser.cpp @@ -0,0 +1,37 @@ +/** + * @file lllistbrowser.cpp + * @brief UI widget showing a search filter, list view, icon action buttons, + * and verb action buttons, as usually embedded in the side tray. + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ +#include "llviewerprecompiledheaders.h" + +#include "lllistbrowser.h" + +// TODO diff --git a/indra/newview/lllistbrowser.h b/indra/newview/lllistbrowser.h new file mode 100644 index 0000000000..bc9498c514 --- /dev/null +++ b/indra/newview/lllistbrowser.h @@ -0,0 +1,36 @@ +/** + * @file lllistbrowser.h + * @brief UI widget showing a search filter, list view, icon action buttons, + * and verb action buttons, as usually embedded in the side tray. + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ +#ifndef LLLISTBROWSER_H +#define LLLISTBROWSER_H + +#endif // LLLISTBROWSER_H diff --git a/indra/newview/lllistview.cpp b/indra/newview/lllistview.cpp new file mode 100644 index 0000000000..568655b500 --- /dev/null +++ b/indra/newview/lllistview.cpp @@ -0,0 +1,73 @@ +/** + * @file lllistview.cpp + * @brief UI widget containing a scrollable, possibly hierarchical list of + * folders (LLListViewFolder) and items (LLListViewItem). + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ +#include "llviewerprecompiledheaders.h" + +#include "lllistview.h" + +#include "lltextbox.h" +#include "lluictrlfactory.h" // LLDefaultWidgetRegistry + +// linker optimizes this out on Windows until there is a real reference +// to this file +static LLDefaultChildRegistry::Register<LLListView> r("list_view"); + +LLListView::Params::Params() +: bg_color("bg_color"), + fg_selected_color("fg_selected_color"), + bg_selected_color("bg_selected_color") +{} + +LLListView::LLListView(const Params& p) +: LLUICtrl(p), + mLabel(NULL), + mBgColor(p.bg_color()), + mFgSelectedColor(p.fg_selected_color()), + mBgSelectedColor(p.bg_selected_color()) +{ + LLRect label_rect(0, 20, 300, 0); + LLTextBox::Params text_box_params; + text_box_params.rect(label_rect); + text_box_params.text("This is a list-view"); + mLabel = LLUICtrlFactory::create<LLTextBox>(text_box_params); + addChild(mLabel); +} + +LLListView::~LLListView() +{} + + +// placeholder for setting a property +void LLListView::setString(const std::string& s) +{ + mLabel->setValue( LLSD(s) ); +} diff --git a/indra/newview/lllistview.h b/indra/newview/lllistview.h new file mode 100644 index 0000000000..501c0c9e1f --- /dev/null +++ b/indra/newview/lllistview.h @@ -0,0 +1,66 @@ +/** + * @file lllistview.h + * @brief UI widget containing a scrollable, possibly hierarchical list of + * folders (LLListViewFolder) and items (LLListViewItem). + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ +#ifndef LLLISTVIEW_H +#define LLLISTVIEW_H + +#include "llui.h" // for LLUIColor, *TODO: use more specific header +#include "lluictrl.h" + +class LLTextBox; + +class LLListView +: public LLUICtrl +{ +public: + struct Params : public LLInitParam::Block<Params, LLUICtrl::Params> + { + Optional<LLUIColor> bg_color, + fg_selected_color, + bg_selected_color; + Params(); + }; + LLListView(const Params& p); + virtual ~LLListView(); + + // placeholder for setting a property + void setString(const std::string& s); + +private: + // TODO: scroll container? + LLTextBox* mLabel; // just for testing + LLUIColor mBgColor; + LLUIColor mFgSelectedColor; + LLUIColor mBgSelectedColor; +}; + +#endif // LLLISTVIEW_H diff --git a/indra/newview/lllocationinputctrl.cpp b/indra/newview/lllocationinputctrl.cpp index 2cee9de1eb..c7ef6e16f7 100644 --- a/indra/newview/lllocationinputctrl.cpp +++ b/indra/newview/lllocationinputctrl.cpp @@ -167,7 +167,7 @@ private: //============================================================================ -static LLDefaultWidgetRegistry::Register<LLLocationInputCtrl> r("location_input"); +static LLDefaultChildRegistry::Register<LLLocationInputCtrl> r("location_input"); LLLocationInputCtrl::Params::Params() : add_landmark_image_enabled("add_landmark_image_enabled"), @@ -459,7 +459,7 @@ void LLLocationInputCtrl::updateAddLandmarkButton() LLInventoryModel::cat_array_t cats; LLInventoryModel::item_array_t items; LLIsAgentParcelLandmark is_current_parcel_landmark; - gInventory.collectDescendentsIf(gAgent.getInventoryRootID(), + gInventory.collectDescendentsIf(gInventory.getRootFolderID(), cats, items, LLInventoryModel::EXCLUDE_TRASH, diff --git a/indra/newview/llmenucommands.cpp b/indra/newview/llmenucommands.cpp index f0bfbef565..c0225ebfca 100644 --- a/indra/newview/llmenucommands.cpp +++ b/indra/newview/llmenucommands.cpp @@ -51,7 +51,7 @@ #include "llfloaterdirectory.h" #include "llfloaterworldmap.h" #include "llgivemoney.h" -#include "llinventoryview.h" +#include "llfloaterinventory.h" #include "llnotify.h" #include "llstatusbar.h" #include "llimview.h" diff --git a/indra/newview/llmoveview.cpp b/indra/newview/llmoveview.cpp index 36ec2c779a..1ba8bdc37f 100644 --- a/indra/newview/llmoveview.cpp +++ b/indra/newview/llmoveview.cpp @@ -38,12 +38,14 @@ #include "indra_constants.h" // Viewer includes + #include "llagent.h" -#include "llviewercontrol.h" #include "llbutton.h" -#include "llviewerwindow.h" +#include "llfloaterreg.h" #include "lljoystickbutton.h" #include "lluictrlfactory.h" +#include "llviewerwindow.h" +#include "llviewercontrol.h" // // Constants @@ -59,12 +61,10 @@ const F32 NUDGE_TIME = 0.25f; // in seconds // protected LLFloaterMove::LLFloaterMove(const LLSD& key) -: LLFloater() +: LLFloater(key) { - setIsChrome(TRUE); - const BOOL DONT_OPEN = FALSE; - LLUICtrlFactory::getInstance()->buildFloater(this,"floater_moveview.xml", DONT_OPEN); +// LLUICtrlFactory::getInstance()->buildFloater(this,"floater_moveview.xml", DONT_OPEN); } @@ -81,6 +81,9 @@ void LLFloaterMove::onClose(bool app_quitting) // virtual BOOL LLFloaterMove::postBuild() { + setIsChrome(TRUE); + + mForwardButton = getChild<LLJoystickAgentTurn>("forward btn"); mForwardButton->setHeldDownDelay(MOVE_BUTTON_DELAY); @@ -138,14 +141,20 @@ F32 LLFloaterMove::getYawRate( F32 time ) // protected static void LLFloaterMove::turnLeft(void *) { - F32 time = getInstance()->mTurnLeftButton->getHeldDownTime(); + LLFloaterMove* instance = LLFloaterReg::getTypedInstance<LLFloaterMove>("moveview"); + if(!instance) return; + + F32 time = instance->mTurnLeftButton->getHeldDownTime(); gAgent.moveYaw( getYawRate( time ) ); } // protected static void LLFloaterMove::turnRight(void *) { - F32 time = getInstance()->mTurnRightButton->getHeldDownTime(); + LLFloaterMove* instance = LLFloaterReg::getTypedInstance<LLFloaterMove>("moveview"); + if(!instance) return; + + F32 time = instance->mTurnRightButton->getHeldDownTime(); gAgent.moveYaw( -getYawRate( time ) ); } diff --git a/indra/newview/llmoveview.h b/indra/newview/llmoveview.h index 8d7cdc881d..de5d1ac432 100644 --- a/indra/newview/llmoveview.h +++ b/indra/newview/llmoveview.h @@ -44,16 +44,15 @@ class LLJoystickAgentSlide; // Classes // class LLFloaterMove -: public LLFloater, - public LLFloaterSingleton<LLFloaterMove> +: public LLFloater { - friend class LLUISingleton<LLFloaterMove, VisibilityPolicy<LLFloater> >; - -protected: + friend class LLFloaterReg; + +private: LLFloaterMove(const LLSD& key); ~LLFloaterMove() {} - public: + /*virtual*/ void onOpen(const LLSD& key); /*virtual*/ void onClose(bool app_quitting); /*virtual*/ BOOL postBuild(); diff --git a/indra/newview/llnamebox.cpp b/indra/newview/llnamebox.cpp index b85c1c759d..56648d3218 100644 --- a/indra/newview/llnamebox.cpp +++ b/indra/newview/llnamebox.cpp @@ -46,7 +46,7 @@ // statics std::set<LLNameBox*> LLNameBox::sInstances; -static LLDefaultWidgetRegistry::Register<LLNameBox> r("name_box"); +static LLDefaultChildRegistry::Register<LLNameBox> r("name_box"); LLNameBox::LLNameBox(const Params& p) diff --git a/indra/newview/llnameeditor.cpp b/indra/newview/llnameeditor.cpp index 7f9ba8ba5a..ccb33c770a 100644 --- a/indra/newview/llnameeditor.cpp +++ b/indra/newview/llnameeditor.cpp @@ -43,7 +43,7 @@ #include "llstring.h" #include "llui.h" -static LLDefaultWidgetRegistry::Register<LLNameEditor> r("name_editor"); +static LLDefaultChildRegistry::Register<LLNameEditor> r("name_editor"); // statics std::set<LLNameEditor*> LLNameEditor::sInstances; diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp index 722113928b..d7066cb140 100644 --- a/indra/newview/llnamelistctrl.cpp +++ b/indra/newview/llnamelistctrl.cpp @@ -44,7 +44,7 @@ #include "llscrolllistcolumn.h" #include "llsdparam.h" -static LLDefaultWidgetRegistry::Register<LLNameListCtrl> r("name_list"); +static LLDefaultChildRegistry::Register<LLNameListCtrl> r("name_list"); void LLNameListCtrl::NameTypeNames::declareValues() { diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp index cf1d9a5d86..b4a6e63de8 100644 --- a/indra/newview/llnavigationbar.cpp +++ b/indra/newview/llnavigationbar.cpp @@ -231,7 +231,7 @@ BOOL LLNavigationBar::postBuild() search_btn->setClickedCallback(boost::bind(&LLNavigationBar::onSearchCommit, this)); // Load the location field context menu - mLocationContextMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_navbar.xml", gMenuHolder); + mLocationContextMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_navbar.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); if (!mLocationContextMenu) { llwarns << "Error loading navigation bar context menu" << llendl; diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp index 1f623af434..510933a331 100644 --- a/indra/newview/llnetmap.cpp +++ b/indra/newview/llnetmap.cpp @@ -56,7 +56,7 @@ #include "llworld.h" #include "llworldmapview.h" // shared draw code -static LLDefaultWidgetRegistry::Register<LLNetMap> r1("net_map"); +static LLDefaultChildRegistry::Register<LLNetMap> r1("net_map"); const F32 MAP_SCALE_MIN = 64; const F32 MAP_SCALE_MID = 172; diff --git a/indra/newview/lloutputmonitorctrl.cpp b/indra/newview/lloutputmonitorctrl.cpp index 196a86b29c..60a86ed253 100644 --- a/indra/newview/lloutputmonitorctrl.cpp +++ b/indra/newview/lloutputmonitorctrl.cpp @@ -39,7 +39,7 @@ // viewer includes #include "llvoiceclient.h" -static LLDefaultWidgetRegistry::Register<LLOutputMonitorCtrl> r("output_monitor"); +static LLDefaultChildRegistry::Register<LLOutputMonitorCtrl> r("output_monitor"); // The defaults will be initialized in the constructor. LLColor4 LLOutputMonitorCtrl::sColorMuted; diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp index ee592ac22c..5c572b8fcd 100644 --- a/indra/newview/llpanelavatar.cpp +++ b/indra/newview/llpanelavatar.cpp @@ -115,7 +115,7 @@ BOOL LLDropTarget::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, return FALSE; } -static LLDefaultWidgetRegistry::Register<LLDropTarget> r("drop_target"); +static LLDefaultChildRegistry::Register<LLDropTarget> r("drop_target"); ////////////////////////////////////////////////////////////////////////// //----------------------------------------------------------------------------- diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp index c328bcb7f9..bd4625ab11 100644 --- a/indra/newview/llpanelclassified.cpp +++ b/indra/newview/llpanelclassified.cpp @@ -931,12 +931,12 @@ bool LLPanelClassified::confirmPublish(const LLSD& notification, const LLSD& res void LLPanelClassified::onClickTeleport(void* data) { LLPanelClassified* self = (LLPanelClassified*)data; - - if (!self->mPosGlobal.isExactlyZero()) + LLFloaterWorldMap* worldmap_instance = LLFloaterWorldMap::getInstance(); + + if (!self->mPosGlobal.isExactlyZero()&&worldmap_instance) { - gAgent.teleportViaLocation(self->mPosGlobal); - LLFloaterWorldMap::getInstance()->trackLocation(self->mPosGlobal); - + gAgent.teleportViaLocation(self->mPosGlobal); + worldmap_instance->trackLocation(self->mPosGlobal); self->sendClassifiedClickMessage("teleport"); } } @@ -946,9 +946,12 @@ void LLPanelClassified::onClickTeleport(void* data) void LLPanelClassified::onClickMap(void* data) { LLPanelClassified* self = (LLPanelClassified*)data; - LLFloaterWorldMap::getInstance()->trackLocation(self->mPosGlobal); - LLFloaterReg::showInstance("world_map", "center"); - + LLFloaterWorldMap* worldmap_instance = LLFloaterWorldMap::getInstance(); + if(worldmap_instance) + { + worldmap_instance->trackLocation(self->mPosGlobal); + LLFloaterReg::showInstance("world_map", "center"); + } self->sendClassifiedClickMessage("map"); } diff --git a/indra/newview/llpanelcontents.cpp b/indra/newview/llpanelcontents.cpp index b7ec485872..5da646497b 100644 --- a/indra/newview/llpanelcontents.cpp +++ b/indra/newview/llpanelcontents.cpp @@ -193,5 +193,5 @@ void LLPanelContents::onClickNewScript(void *userdata) void LLPanelContents::onClickPermissions(void *userdata) { LLPanelContents* self = (LLPanelContents*)userdata; - gFloaterView->getParentFloater(self)->addDependentFloater(LLFloaterBulkPermission::showInstance()); + gFloaterView->getParentFloater(self)->addDependentFloater(LLFloaterReg::showInstance("bulk_perms")); } diff --git a/indra/newview/llpanelgrouplandmoney.cpp b/indra/newview/llpanelgrouplandmoney.cpp index ea092645e7..39a9f231b2 100644 --- a/indra/newview/llpanelgrouplandmoney.cpp +++ b/indra/newview/llpanelgrouplandmoney.cpp @@ -247,9 +247,12 @@ void LLPanelGroupLandMoney::impl::onMapButton() F64 global_z = gAgent.getPositionGlobal().mdV[VZ]; LLVector3d pos_global(global_x, global_y, global_z); - LLFloaterWorldMap::getInstance()->trackLocation(pos_global); - - LLFloaterReg::showInstance("world_map", "center"); + LLFloaterWorldMap* worldmap_instance = LLFloaterWorldMap::getInstance(); + if(worldmap_instance) + { + worldmap_instance->trackLocation(pos_global); + LLFloaterReg::showInstance("world_map", "center"); + } } bool LLPanelGroupLandMoney::impl::applyContribution() diff --git a/indra/newview/llpanelgroupnotices.cpp b/indra/newview/llpanelgroupnotices.cpp index 201cf5a023..0e75681afa 100644 --- a/indra/newview/llpanelgroupnotices.cpp +++ b/indra/newview/llpanelgroupnotices.cpp @@ -39,7 +39,7 @@ #include "llinventory.h" #include "llviewerinventory.h" #include "llinventorymodel.h" -#include "llinventoryview.h" +#include "llfloaterinventory.h" #include "llagent.h" #include "lltooldraganddrop.h" @@ -105,7 +105,7 @@ protected: LLUUID mGroupID; }; -static LLDefaultWidgetRegistry::Register<LLGroupDropTarget> r("group_drop_target"); +static LLDefaultChildRegistry::Register<LLGroupDropTarget> r("group_drop_target"); LLGroupDropTarget::LLGroupDropTarget(const LLGroupDropTarget::Params& p) : LLView(p), diff --git a/indra/newview/llpanelland.cpp b/indra/newview/llpanelland.cpp index 92fe082ef2..bce5525a40 100644 --- a/indra/newview/llpanelland.cpp +++ b/indra/newview/llpanelland.cpp @@ -40,6 +40,7 @@ #include "llbutton.h" #include "llcheckboxctrl.h" #include "llfloaterland.h" +#include "llfloaterreg.h" #include "lltextbox.h" #include "llviewercontrol.h" #include "llviewerparcelmgr.h" @@ -262,7 +263,7 @@ void LLPanelLandInfo::onClickAbout(void*) LLViewerParcelMgr::getInstance()->selectParcelInRectangle(); } - LLFloaterLand::showInstance(); + LLFloaterReg::showInstance("about_land"); } void LLPanelLandInfo::onShowOwnersHelp(void* user_data) diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp index 8c7e3e960a..d1164dafb8 100644 --- a/indra/newview/llpanellandmarks.cpp +++ b/indra/newview/llpanellandmarks.cpp @@ -31,12 +31,14 @@ #include "llviewerprecompiledheaders.h" +#include "llpanellandmarks.h" + #include "llfloaterreg.h" #include "lllandmark.h" #include "llfloaterworldmap.h" +#include "llfoldervieweventlistener.h" #include "lllandmarklist.h" -#include "llpanellandmarks.h" #include "llsidetray.h" #include "lltabcontainer.h" #include "llworldmap.h" @@ -138,9 +140,10 @@ void LLLandmarksPanel::onShowOnMap() if (!landmark->getGlobalPos(landmark_global_pos)) return; - if (!landmark_global_pos.isExactlyZero()) + LLFloaterWorldMap* worldmap_instance = LLFloaterWorldMap::getInstance(); + if (!landmark_global_pos.isExactlyZero() && worldmap_instance) { - LLFloaterWorldMap::getInstance()->trackLocation(landmark_global_pos); + worldmap_instance->trackLocation(landmark_global_pos); LLFloaterReg::showInstance("world_map", "center"); } } diff --git a/indra/newview/llpanellandmarks.h b/indra/newview/llpanellandmarks.h index 76333e4d85..8889a99925 100644 --- a/indra/newview/llpanellandmarks.h +++ b/indra/newview/llpanellandmarks.h @@ -33,7 +33,7 @@ #ifndef LL_LLPANELLANDMARKS_H #define LL_LLPANELLANDMARKS_H -#include "llinventoryview.h" +#include "llfloaterinventory.h" #include "llinventorymodel.h" #include "llpanelplacestab.h" diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp index 3f9f44bbf5..b6141384f7 100644 --- a/indra/newview/llpanelpeople.cpp +++ b/indra/newview/llpanelpeople.cpp @@ -375,10 +375,10 @@ BOOL LLPanelPeople::postBuild() // Create menus. LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; registrar.add("People.Group.Plus.Action", boost::bind(&LLPanelPeople::onGroupPlusMenuItemClicked, this, _2)); - LLMenuGL* plus_menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_group_plus.xml", gMenuHolder); + LLMenuGL* plus_menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_group_plus.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); mGroupPlusMenuHandle = plus_menu->getHandle(); registrar.add("People.Group.Minus.Action", boost::bind(&LLPanelPeople::onGroupMinusMenuItemClicked, this, _2)); - LLMenuGL* minus_menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_group_minus.xml", gMenuHolder); + LLMenuGL* minus_menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_group_minus.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); mGroupMinusMenuHandle = minus_menu->getHandle(); // Perform initial update. diff --git a/indra/newview/llpanelpicks.cpp b/indra/newview/llpanelpicks.cpp index c32af24423..f3adaded34 100644 --- a/indra/newview/llpanelpicks.cpp +++ b/indra/newview/llpanelpicks.cpp @@ -239,7 +239,7 @@ BOOL LLPanelPicks::postBuild(void) mCommitCallbackRegistrar.add("Pick.Map", boost::bind(onClickMap, this)); mCommitCallbackRegistrar.add("Pick.Delete", boost::bind(onClickDelete, this)); - mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>("menu_picks.xml", gMenuHolder); + mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>("menu_picks.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); return TRUE; } diff --git a/indra/newview/llpanelplace.cpp b/indra/newview/llpanelplace.cpp index d4c2f4b6b2..2cb7fd8c14 100644 --- a/indra/newview/llpanelplace.cpp +++ b/indra/newview/llpanelplace.cpp @@ -355,16 +355,17 @@ void LLPanelPlace::onClickTeleport(void* data) } // LLFloater* parent_floaterp = (LLFloater*)self->getParent(); parent_viewp->setVisible(false); - if(self->mLandmarkAssetID.notNull()) + LLFloaterWorldMap* worldmap_instance = LLFloaterWorldMap::getInstance(); + if(self->mLandmarkAssetID.notNull() && worldmap_instance) { gAgent.teleportViaLandmark(self->mLandmarkAssetID); - LLFloaterWorldMap::getInstance()->trackLandmark(self->mLandmarkAssetID); + worldmap_instance->trackLandmark(self->mLandmarkAssetID); } - else if (!self->mPosGlobal.isExactlyZero()) + else if (!self->mPosGlobal.isExactlyZero() && worldmap_instance) { gAgent.teleportViaLocation(self->mPosGlobal); - LLFloaterWorldMap::getInstance()->trackLocation(self->mPosGlobal); + worldmap_instance->trackLocation(self->mPosGlobal); } } @@ -372,9 +373,11 @@ void LLPanelPlace::onClickTeleport(void* data) void LLPanelPlace::onClickMap(void* data) { LLPanelPlace* self = (LLPanelPlace*)data; - if (!self->mPosGlobal.isExactlyZero()) + LLFloaterWorldMap* worldmap_instance = LLFloaterWorldMap::getInstance(); + + if (!self->mPosGlobal.isExactlyZero() && worldmap_instance) { - LLFloaterWorldMap::getInstance()->trackLocation(self->mPosGlobal); + worldmap_instance->trackLocation(self->mPosGlobal); LLFloaterReg::showInstance("world_map", "center"); } } diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp index 42b09a45c3..f23d839708 100644 --- a/indra/newview/llpanelplaces.cpp +++ b/indra/newview/llpanelplaces.cpp @@ -216,8 +216,13 @@ void LLPanelPlaces::onShowOnMapButtonClicked() LLVector3d global_pos = gAgent.getPositionGlobal(); if (!global_pos.isExactlyZero()) { - LLFloaterWorldMap::getInstance()->trackLocation(global_pos); - LLFloaterReg::showInstance("world_map", "center"); + LLFloaterWorldMap* instance = LLFloaterWorldMap::getInstance(); + if(instance) + { + instance->trackLocation(global_pos); + LLFloaterReg::showInstance("world_map", "center"); + + } } } else diff --git a/indra/newview/llpreview.cpp b/indra/newview/llpreview.cpp index 676943ff87..9a987c8d7c 100644 --- a/indra/newview/llpreview.cpp +++ b/indra/newview/llpreview.cpp @@ -51,7 +51,7 @@ #include "llagent.h" #include "llvoavatarself.h" #include "llselectmgr.h" -#include "llinventoryview.h" +#include "llfloaterinventory.h" #include "llviewerinventory.h" #include "llviewerwindow.h" #include "lltrans.h" diff --git a/indra/newview/llpreviewanim.cpp b/indra/newview/llpreviewanim.cpp index 6857d14fff..c4037c94fe 100644 --- a/indra/newview/llpreviewanim.cpp +++ b/indra/newview/llpreviewanim.cpp @@ -36,7 +36,7 @@ #include "llbutton.h" #include "llresmgr.h" #include "llinventory.h" -#include "llinventoryview.h" +#include "llfloaterinventory.h" #include "llvoavatarself.h" #include "llagent.h" // gAgent #include "llkeyframemotion.h" diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp index dc6ee44936..ac08fd23a4 100644 --- a/indra/newview/llpreviewgesture.cpp +++ b/indra/newview/llpreviewgesture.cpp @@ -559,7 +559,7 @@ void LLPreviewGesture::addAnimations() PERM_ITEM_UNRESTRICTED, gAgent.getID(), gAgent.getGroupID()); - gInventory.collectDescendentsIf(gAgent.getInventoryRootID(), + gInventory.collectDescendentsIf(gInventory.getRootFolderID(), cats, items, LLInventoryModel::EXCLUDE_TRASH, @@ -604,7 +604,7 @@ void LLPreviewGesture::addSounds() PERM_ITEM_UNRESTRICTED, gAgent.getID(), gAgent.getGroupID()); - gInventory.collectDescendentsIf(gAgent.getInventoryRootID(), + gInventory.collectDescendentsIf(gInventory.getRootFolderID(), cats, items, LLInventoryModel::EXCLUDE_TRASH, diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index 7c50bc5977..7883b1ab06 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -973,7 +973,7 @@ void LLPreviewLSL::loadAsset() const LLInventoryItem* item = gInventory.getItem(mItemUUID); BOOL is_library = item && !gInventory.isObjectDescendentOf(mItemUUID, - gAgent.getInventoryRootID()); + gInventory.getRootFolderID()); if(!item) { // do the more generic search. diff --git a/indra/newview/llpreviewsound.cpp b/indra/newview/llpreviewsound.cpp index 7e7be5b2c6..84f7562297 100644 --- a/indra/newview/llpreviewsound.cpp +++ b/indra/newview/llpreviewsound.cpp @@ -36,7 +36,7 @@ #include "llagent.h" // gAgent #include "llbutton.h" #include "llinventory.h" -#include "llinventoryview.h" +#include "llfloaterinventory.h" #include "lllineeditor.h" #include "llpreviewsound.h" #include "llresmgr.h" diff --git a/indra/newview/llpreviewtexture.cpp b/indra/newview/llpreviewtexture.cpp index 3204006e43..d6ecb42255 100644 --- a/indra/newview/llpreviewtexture.cpp +++ b/indra/newview/llpreviewtexture.cpp @@ -39,7 +39,7 @@ #include "llfilepicker.h" #include "llfloaterreg.h" #include "llimagetga.h" -#include "llinventoryview.h" +#include "llfloaterinventory.h" #include "llinventory.h" #include "llresmgr.h" #include "lltrans.h" diff --git a/indra/newview/llrootview.h b/indra/newview/llrootview.h index af9517f922..f704fecddd 100644 --- a/indra/newview/llrootview.h +++ b/indra/newview/llrootview.h @@ -36,20 +36,16 @@ #include "llview.h" #include "lluictrlfactory.h" -class LLRootViewRegistry : public LLWidgetRegistry<LLRootViewRegistry> +class LLRootViewRegistry : public LLChildRegistry<LLRootViewRegistry> {}; class LLRootView : public LLView { public: + typedef LLRootViewRegistry child_registry_t; + LLRootView(const Params& p) : LLView(p) {} - - const widget_registry_t& getChildRegistry() const - { - // use default widget registry - return LLRootViewRegistry::instance(); - } }; #endif //LL_LLROOTVIEW_H diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index baa5f34849..b3b850441c 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -57,6 +57,7 @@ #include "llfloaterinspect.h" #include "llfloaterproperties.h" #include "llfloaterreporter.h" +#include "llfloaterreg.h" #include "llfloatertools.h" #include "llframetimer.h" #include "llhudeffecttrail.h" @@ -4842,8 +4843,12 @@ void LLSelectMgr::renderSilhouettes(BOOL for_hud) } if (mSelectedObjects->getNumNodes()) { - LLUUID inspect_item_id = LLFloaterInspect::getSelectedUUID(); - + LLFloaterInspect* inspect_instance = LLFloaterReg::getTypedInstance<LLFloaterInspect>("inspect"); + LLUUID inspect_item_id= LLUUID::null; + if(inspect_instance) + { + inspect_item_id = inspect_instance->getSelectedUUID(); + } for (S32 pass = 0; pass < 2; pass++) { for (LLObjectSelection::iterator iter = mSelectedObjects->begin(); @@ -5400,7 +5405,11 @@ void dialog_refresh_all() } LLFloaterProperties::dirtyAll(); - LLFloaterInspect::dirty(); + LLFloaterInspect* inspect_instance = LLFloaterReg::getTypedInstance<LLFloaterInspect>("inspect"); + if(inspect_instance) + { + inspect_instance->dirty(); + } } S32 get_family_count(LLViewerObject *parent) diff --git a/indra/newview/llsidetray.cpp b/indra/newview/llsidetray.cpp index 2871b16f5c..b7c4c74891 100644 --- a/indra/newview/llsidetray.cpp +++ b/indra/newview/llsidetray.cpp @@ -52,7 +52,7 @@ using namespace std; static LLRootViewRegistry::Register<LLSideTray> t1("side_tray"); -static LLDefaultWidgetRegistry::Register<LLSideTrayTab> t2("sidetray_tab"); +static LLDefaultChildRegistry::Register<LLSideTrayTab> t2("sidetray_tab"); static const std::string COLLAPSED_NAME = "<<"; static const std::string EXPANDED_NAME = ">>"; @@ -103,7 +103,7 @@ LLSideTray* LLSideTray::getInstance() { if (!sInstance) { - sInstance = LLUICtrlFactory::createFromFile<LLSideTray>("panel_side_tray.xml",gViewerWindow->getRootView()); + sInstance = LLUICtrlFactory::createFromFile<LLSideTray>("panel_side_tray.xml",gViewerWindow->getRootView(), LLRootView::child_registry_t::instance()); } return sInstance; @@ -156,7 +156,7 @@ bool LLSideTrayTab::addChild(LLView* view, S32 tab_group) //virtual BOOL LLSideTrayTab::postBuild() { - LLPanel* title_panel = LLUICtrlFactory::getInstance()->createFromFile<LLPanel>("panel_side_tray_tab_caption.xml",this); + LLPanel* title_panel = LLUICtrlFactory::getInstance()->createFromFile<LLPanel>("panel_side_tray_tab_caption.xml",this, child_registry_t::instance()); string name = title_panel->getName(); LLPanel::addChild(title_panel); @@ -374,7 +374,7 @@ bool LLSideTray::selectTabByName (const std::string& name) LLButton* LLSideTray::createButton (const std::string& name,const std::string& image,LLUICtrl::commit_callback_t callback) { - static LLSideTray::Params sidetray_params(LLUICtrlFactory::getDefaultParams<LLSideTray::Params>()); + static LLSideTray::Params sidetray_params(LLUICtrlFactory::getDefaultParams<LLSideTray>()); LLButton::Params bparams; @@ -475,7 +475,7 @@ void LLSideTray::reflectCollapseChange() void LLSideTray::arrange () { - static LLSideTray::Params sidetray_params(LLUICtrlFactory::getDefaultParams<LLSideTray::Params>()); + static LLSideTray::Params sidetray_params(LLUICtrlFactory::getDefaultParams<LLSideTray>()); calcMaxSideBarWidth(); @@ -600,7 +600,7 @@ void LLSideTray::reshape (S32 width, S32 height, BOOL called_from_parent) if(!mActiveTab) return; - static LLSideTray::Params sidetray_params(LLUICtrlFactory::getDefaultParams<LLSideTray::Params>()); + static LLSideTray::Params sidetray_params(LLUICtrlFactory::getDefaultParams<LLSideTray>()); setPanelRect(); @@ -724,7 +724,7 @@ static const S32 fake_top_offset = 78; void LLSideTray::setPanelRect () { - static LLSideTray::Params sidetray_params(LLUICtrlFactory::getDefaultParams<LLSideTray::Params>()); + static LLSideTray::Params sidetray_params(LLUICtrlFactory::getDefaultParams<LLSideTray>()); const LLRect& parent_rect = gViewerWindow->getRootView()->getRect(); @@ -743,6 +743,6 @@ void LLSideTray::setPanelRect () S32 LLSideTray::getTrayWidth() { - static LLSideTray::Params sidetray_params(LLUICtrlFactory::getDefaultParams<LLSideTray::Params>()); + static LLSideTray::Params sidetray_params(LLUICtrlFactory::getDefaultParams<LLSideTray>()); return getRect().getWidth() - (sidetray_params.default_button_width + sidetray_params.default_button_margin); } diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 790669c07f..8b6124870d 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -94,9 +94,6 @@ #include "llface.h" #include "llfeaturemanager.h" #include "llfirstuse.h" -#include "llfloateractivespeakers.h" -#include "llfloaterbeacons.h" -#include "llfloatercamera.h" #include "llfloaterchat.h" #include "llfloatergesture.h" #include "llfloaterhud.h" @@ -113,7 +110,7 @@ #include "llimagebmp.h" #include "llinventorybridge.h" #include "llinventorymodel.h" -#include "llinventoryview.h" +#include "llfloaterinventory.h" #include "llkeyboard.h" #include "llloginhandler.h" // gLoginHandler, SLURL support #include "llpanellogin.h" @@ -750,8 +747,10 @@ bool idle_startup() std::string msg = LLTrans::getString("LoginInitializingBrowser"); set_startup_status(0.03f, msg.c_str(), gAgent.mMOTD.c_str()); display_startup(); +#if !defined(LL_WINDOWS) || !defined(LL_DEBUG) + // This generates an error in debug mode on Windows LLViewerMedia::initBrowser(); - +#endif LLStartUp::setStartupState( STATE_LOGIN_SHOW ); return FALSE; } @@ -1466,8 +1465,7 @@ bool idle_startup() it = options[0].find("folder_id"); if(it != options[0].end()) { - gAgent.getInventoryRootID().set((*it).second); - //gInventory.mock(gAgent.getInventoryRootID()); + gInventory.setRootFolderID( LLUUID( (*it).second ) ); } } @@ -1555,7 +1553,7 @@ bool idle_startup() && gAgentSessionID.notNull() && gMessageSystem->mOurCircuitCode && first_sim.isOk() - && gAgent.getInventoryRootID().notNull()) + && gInventory.getRootFolderID().notNull()) { LLStartUp::setStartupState( STATE_WORLD_INIT ); } @@ -1724,21 +1722,21 @@ bool idle_startup() if (gSavedSettings.getBOOL("ShowCameraControls")) { - LLFloaterCamera::showInstance(); + LLFloaterReg::showInstance("camera"); } if (gSavedSettings.getBOOL("ShowMovementControls")) { - LLFloaterMove::showInstance(); + LLFloaterReg::showInstance("moveview"); } if (gSavedSettings.getBOOL("ShowActiveSpeakers")) { - LLFloaterActiveSpeakers::showInstance(); + LLFloaterReg::showInstance("active_speakers"); } if (gSavedSettings.getBOOL("BeaconAlwaysOn")) { - LLFloaterBeacons::showInstance(); + LLFloaterReg::showInstance("beacons"); } if (!gNoRender) @@ -1994,7 +1992,7 @@ bool idle_startup() it = options[0].find("folder_id"); if(it != options[0].end()) { - gInventoryLibraryRoot.set((*it).second); + gInventory.setLibraryRootFolderID( LLUUID( (*it).second ) ); } } options.clear(); @@ -2006,14 +2004,14 @@ bool idle_startup() it = options[0].find("agent_id"); if(it != options[0].end()) { - gInventoryLibraryOwner.set((*it).second); + gInventory.setLibraryOwnerID( LLUUID( (*it).second ) ); } } options.clear(); if(LLUserAuth::getInstance()->getOptions("inventory-skel-lib", options) - && gInventoryLibraryOwner.notNull()) + && gInventory.getLibraryOwnerID().notNull()) { - if(!gInventory.loadSkeleton(options, gInventoryLibraryOwner)) + if(!gInventory.loadSkeleton(options, gInventory.getLibraryOwnerID())) { LL_WARNS("AppInit") << "Problem loading inventory-skel-lib" << LL_ENDL; } @@ -2087,10 +2085,9 @@ bool idle_startup() // Either we want to show tutorial because this is the first login // to a Linden Help Island or the user quit with the tutorial // visible. JC - if (show_hud - || gSavedSettings.getBOOL("ShowTutorial")) + if (show_hud || gSavedSettings.getBOOL("ShowTutorial")) { - LLFloaterHUD::showHUD(); + LLFloaterReg::showInstance("hud", LLSD(), FALSE); } options.clear(); @@ -2465,9 +2462,11 @@ bool idle_startup() // Let the map know about the inventory. LLFloaterWorldMap* floater_world_map = LLFloaterWorldMap::getInstance(); - floater_world_map->observeInventory(&gInventory); - floater_world_map->observeFriends(); - + if(floater_world_map) + { + floater_world_map->observeInventory(&gInventory); + floater_world_map->observeFriends(); + } gViewerWindow->showCursor(); gViewerWindow->getWindow()->resetBusyCount(); gViewerWindow->getWindow()->setCursor(UI_CURSOR_ARROW); diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp index 58af603569..bc90fe7adc 100644 --- a/indra/newview/llstatusbar.cpp +++ b/indra/newview/llstatusbar.cpp @@ -47,7 +47,7 @@ #include "llfloaterregioninfo.h" #include "llfloaterscriptdebug.h" #include "llhudicon.h" -#include "llinventoryview.h" +#include "llfloaterinventory.h" #include "llkeyboard.h" #include "lllineeditor.h" #include "llmenugl.h" diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index 3c9290acea..243ac7803e 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -45,9 +45,10 @@ #include "llfocusmgr.h" #include "llviewerimage.h" #include "llfolderview.h" +#include "llfoldervieweventlistener.h" #include "llinventory.h" #include "llinventorymodel.h" -#include "llinventoryview.h" +#include "llfloaterinventory.h" #include "lllineeditor.h" #include "llui.h" #include "llviewerinventory.h" @@ -342,7 +343,7 @@ BOOL LLFloaterTexturePicker::handleKeyHere(KEY key, MASK mask) { if (!root_folder->getCurSelectedItem()) { - LLFolderViewItem* itemp = root_folder->getItemByID(gAgent.getInventoryRootID()); + LLFolderViewItem* itemp = root_folder->getItemByID(gInventory.getRootFolderID()); if (itemp) { root_folder->setSelection(itemp, FALSE, FALSE); @@ -858,7 +859,7 @@ void LLFloaterTexturePicker::onTextureSelect( const LLTextureEntry& te ) /////////////////////////////////////////////////////////////////////// // LLTextureCtrl -static LLDefaultWidgetRegistry::Register<LLTextureCtrl> r("texture_picker"); +static LLDefaultChildRegistry::Register<LLTextureCtrl> r("texture_picker"); LLTextureCtrl::LLTextureCtrl(const LLTextureCtrl::Params& p) : LLUICtrl(p), diff --git a/indra/newview/lltoolbar.cpp b/indra/newview/lltoolbar.cpp index d27958c2ac..477e452907 100644 --- a/indra/newview/lltoolbar.cpp +++ b/indra/newview/lltoolbar.cpp @@ -52,7 +52,7 @@ #include "lluiconstants.h" #include "llvoavatarself.h" #include "lltooldraganddrop.h" -#include "llinventoryview.h" +#include "llfloaterinventory.h" #include "llfloaterchatterbox.h" #include "llfloaterfriends.h" #include "llfloatersnapshot.h" @@ -157,7 +157,7 @@ BOOL LLToolBar::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, LLButton* inventory_btn = getChild<LLButton>("inventory_btn"); if (!inventory_btn) return FALSE; - LLInventoryView* active_inventory = LLInventoryView::getActiveInventory(); + LLFloaterInventory* active_inventory = LLFloaterInventory::getActiveInventory(); LLRect button_screen_rect; inventory_btn->localRectToScreen(inventory_btn->getRect(),&button_screen_rect); @@ -173,7 +173,7 @@ BOOL LLToolBar::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, if (!(active_inventory && active_inventory->getVisible()) && mInventoryAutoOpenTimer.getElapsedTimeF32() > sInventoryAutoOpenTime) { - LLInventoryView::showAgentInventory(); + LLFloaterInventory::showAgentInventory(); } } else @@ -332,8 +332,11 @@ void LLToolBar::updateCommunicateList() communicate_button->addSeparator(ADD_TOP); communicate_button->add(getString("Redock Windows"), LLSD("redock"), ADD_TOP); communicate_button->addSeparator(ADD_TOP); - communicate_button->add(LLFloaterReg::getTypedInstance<LLFloaterMute>("mute")->getShortTitle(), LLSD("mute list"), ADD_TOP); - + LLFloaterMute* mute_instance = LLFloaterReg::getTypedInstance<LLFloaterMute>("mute"); + if(mute_instance) + { + communicate_button->add(mute_instance->getShortTitle(), LLSD("mute list"), ADD_TOP); + } std::set<LLHandle<LLFloater> >::const_iterator floater_handle_it; if (gIMMgr->getIMFloaterHandles().size() > 0) @@ -385,25 +388,29 @@ void LLToolBar::onClickCommunicate(LLUICtrl* ctrl, const LLSD& user_data) } else if (selected_option.asString() == "redock") { - LLFloaterChatterBox::getInstance()->addFloater(LLFloaterMyFriends::getInstance(), FALSE); - LLFloaterChatterBox::getInstance()->addFloater(LLFloaterChat::getInstance(), FALSE); - LLUUID session_to_show; - - std::set<LLHandle<LLFloater> >::const_iterator floater_handle_it; - for(floater_handle_it = gIMMgr->getIMFloaterHandles().begin(); floater_handle_it != gIMMgr->getIMFloaterHandles().end(); ++floater_handle_it) + LLFloaterChatterBox* chatterbox_instance = LLFloaterChatterBox::getInstance(); + if(chatterbox_instance) { - LLFloater* im_floaterp = floater_handle_it->get(); - if (im_floaterp) + chatterbox_instance->addFloater(LLFloaterMyFriends::getInstance(), FALSE); + chatterbox_instance->addFloater(LLFloaterChat::getInstance(), FALSE); + + LLUUID session_to_show; + + std::set<LLHandle<LLFloater> >::const_iterator floater_handle_it; + for(floater_handle_it = gIMMgr->getIMFloaterHandles().begin(); floater_handle_it != gIMMgr->getIMFloaterHandles().end(); ++floater_handle_it) { - if (im_floaterp->isFrontmost()) + LLFloater* im_floaterp = floater_handle_it->get(); + if (im_floaterp) { - session_to_show = ((LLFloaterIMPanel*)im_floaterp)->getSessionID(); + if (im_floaterp->isFrontmost()) + { + session_to_show = ((LLFloaterIMPanel*)im_floaterp)->getSessionID(); + } + chatterbox_instance->addFloater(im_floaterp, FALSE); } - LLFloaterChatterBox::getInstance()->addFloater(im_floaterp, FALSE); } + LLFloaterReg::showInstance("communicate", session_to_show); } - - LLFloaterReg::showInstance("communicate", session_to_show); } else if (selected_option.asString() == "mute list") { diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index 0c0253a76a..72ed8f8108 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -51,7 +51,7 @@ #include "llhudmanager.h" #include "llinventorybridge.h" #include "llinventorymodel.h" -#include "llinventoryview.h" +#include "llfloaterinventory.h" #include "llmutelist.h" #include "llnotify.h" #include "llpreviewnotecard.h" diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index a89e79c8b8..c71ed5ae47 100644 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -44,6 +44,7 @@ #include "llfirstuse.h" #include "llfloateravatarinfo.h" #include "llfloaterland.h" +#include "llfloaterreg.h" #include "llfloaterscriptdebug.h" #include "llhoverview.h" #include "llhudeffecttrail.h" @@ -142,7 +143,7 @@ BOOL LLToolPie::pickLeftMouseDownCallback() else { // not selling passes, get info - LLFloaterLand::showInstance(); + LLFloaterReg::showInstance("about_land"); } } @@ -425,7 +426,7 @@ void LLToolPie::selectionPropertiesReceived() handle_give_money_dialog(); break; case CLICK_ACTION_OPEN: - handle_object_open(); + LLFloaterReg::showInstance("openobject"); break; default: break; diff --git a/indra/newview/llurldispatcher.cpp b/indra/newview/llurldispatcher.cpp index 6c8e7e1f69..acb7f927b6 100644 --- a/indra/newview/llurldispatcher.cpp +++ b/indra/newview/llurldispatcher.cpp @@ -36,11 +36,12 @@ // viewer includes #include "llagent.h" // teleportViaLocation() #include "llcommandhandler.h" -#include "llfloaterurldisplay.h" #include "llfloaterdirectory.h" #include "llfloaterhtml.h" -#include "llfloaterworldmap.h" #include "llfloaterhtmlhelp.h" +#include "llfloaterreg.h" +#include "llfloaterurldisplay.h" +#include "llfloaterworldmap.h" #include "llpanellogin.h" #include "llslurl.h" #include "llstartup.h" // gStartupState @@ -201,8 +202,8 @@ bool LLURLDispatcherImpl::dispatchRegion(const std::string& url, bool right_mous S32 z = 0; LLURLSimString::parse(sim_string, ®ion_name, &x, &y, &z); - LLFloaterURLDisplay* url_displayp = LLFloaterURLDisplay::getInstance(LLSD()); - url_displayp->setName(region_name); + LLFloaterURLDisplay* url_displayp = LLFloaterReg::getTypedInstance<LLFloaterURLDisplay>("preview_url",LLSD()); + if(url_displayp) url_displayp->setName(region_name); // Request a region handle by name LLWorldMap::getInstance()->sendNamedRegionRequest(region_name, @@ -280,21 +281,26 @@ void LLURLDispatcherImpl::regionHandleCallback(U64 region_handle, const std::str LLVector3d global_pos = from_region_handle(region_handle); global_pos += LLVector3d(local_pos); gAgent.teleportViaLocation(global_pos); - LLFloaterWorldMap::getInstance()->trackLocation(global_pos); + LLFloaterWorldMap* instance = LLFloaterWorldMap::getInstance(); + if(instance) + { + instance->trackLocation(global_pos); + } } else { // display informational floater, allow user to click teleport btn - LLFloaterURLDisplay* url_displayp = LLFloaterURLDisplay::getInstance(LLSD()); - - - url_displayp->displayParcelInfo(region_handle, local_pos); - if(snapshot_id.notNull()) + LLFloaterURLDisplay* url_displayp = LLFloaterReg::getTypedInstance<LLFloaterURLDisplay>("preview_url",LLSD()); + if(url_displayp) { - url_displayp->setSnapshotDisplay(snapshot_id); + url_displayp->displayParcelInfo(region_handle, local_pos); + if(snapshot_id.notNull()) + { + url_displayp->setSnapshotDisplay(snapshot_id); + } + std::string locationString = llformat("%s %d, %d, %d", region_name.c_str(), x, y, z); + url_displayp->setLocationString(locationString); } - std::string locationString = llformat("%s %d, %d, %d", region_name.c_str(), x, y, z); - url_displayp->setLocationString(locationString); } } diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 03c4915e66..914f74ca78 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -39,28 +39,48 @@ #include "llcompilequeue.h" #include "llfloaterabout.h" +#include "llfloateractivespeakers.h" #include "llfloaterauction.h" #include "llfloateraddlandmark.h" #include "llfloateravatarinfo.h" +#include "llfloaterbeacons.h" +#include "llfloaterbulkpermission.h" #include "llfloaterbuildoptions.h" #include "llfloaterbump.h" +#include "llfloatercamera.h" #include "llfloaterchat.h" #include "llfloaterchatterbox.h" #include "llfloaterdirectory.h" +#include "llfloaterfonttest.h" +#include "llfloatergodtools.h" +#include "llfloaterhtmlcurrency.h" +#include "llfloaterhtmlhelp.h" +#include "llfloaterhud.h" +#include "llfloaterinspect.h" #include "llfloaterjoystick.h" #include "llfloaternotificationsconsole.h" #include "llfloaterlagmeter.h" +#include "llfloaterland.h" #include "llfloatermap.h" #include "llfloatermemleak.h" #include "llfloatermute.h" +#include "llfloaterobjectiminfo.h" +#include "llfloateropenobject.h" +#include "llfloaterperms.h" #include "llfloaterpreference.h" +#include "llfloaterregioninfo.h" #include "llfloatersnapshot.h" #include "llfloatersettingsdebug.h" +#include "llfloatertestlistview.h" +#include "llfloatertopobjects.h" #include "llfloatertools.h" #include "llfloateruipreview.h" +#include "llfloaterurldisplay.h" #include "llfloatervoicedevicesettings.h" #include "llfloaterworldmap.h" -#include "llinventoryview.h" +#include "llfloaterinventory.h" +#include "llmediaremotectrl.h" +#include "llmoveview.h" #include "llnearbychathistory.h" #include "llpreviewanim.h" @@ -72,6 +92,8 @@ #include "llpreviewtexture.h" #include "llfloaterminiinspector.h" +//class LLLLFloaterObjectIMInfo; + void LLViewerFloaterReg::registerFloaters() { LLFloaterReg::add("mini_inspector", "panel_mini_inspector.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMiniInspector>); @@ -82,9 +104,15 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("build", "floater_tools.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTools>); LLFloaterReg::add("world_map", "floater_world_map.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterWorldMap>); LLFloaterReg::add("mini_map", "floater_map.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMap>); - LLFloaterReg::add("inventory", "floater_inventory.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLInventoryView>); + LLFloaterReg::add("inventory", "floater_inventory.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterInventory>); LLFloaterReg::add("add_landmark", "floater_add_landmark.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAddLandmark>); LLFloaterReg::add("mute", "floater_mute.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMute>); + LLFloaterReg::add("about_land", "floater_about_land.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLand>); + LLFloaterReg::add("perm_prefs", "floater_perm_prefs.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPerms>); + LLFloaterReg::add("region_info", "floater_region_info.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterRegionInfo>); + LLFloaterReg::add("preview_url", "floater_preview_url.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterURLDisplay>); + LLFloaterReg::add("font_test", "floater_font_test.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterFontTest>); + LLFloaterReg::add("mem_leaking", "floater_mem_leaking.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMemLeak>); LLFloaterReg::add("auction", "floater_auction.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAuction>); LLFloaterReg::add("build_options", "floater_build_options.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterBuildOptions>); @@ -92,9 +120,25 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("notifications_console", "floater_notifications_console.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterNotificationConsole>); LLFloaterReg::add("settings_debug", "floater_settings_debug.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSettingsDebug>); LLFloaterReg::add("lagmeter", "floater_lagmeter.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLagMeter>); + LLFloaterReg::add("moveview", "floater_moveview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMove>); + LLFloaterReg::add("active_speakers", "floater_active_speakers.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterActiveSpeakers>); + LLFloaterReg::add("beacons", "floater_beacons.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterBeacons>); + LLFloaterReg::add("bulk_perms", "floater_bulk_perms.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterBulkPermission>); + LLFloaterReg::add("camera", "floater_camera.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCamera>); + LLFloaterReg::add("god_tools", "floater_god_tools.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterGodTools>); + LLFloaterReg::add("media_browser", "floater_media_browser.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMediaBrowser>); + LLFloaterReg::add("html_currency", "floater_html_simple.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHtmlCurrency>); + LLFloaterReg::add("top_objects", "floater_top_objects.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTopObjects>); + LLFloaterReg::add("inspect", "floater_inspect.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterInspect>); + LLFloaterReg::add("hud", "floater_hud.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHUD>); + LLFloaterReg::add("openobject", "floater_openobject.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterOpenObject>); - LLFloaterReg::add("ui_preview", "floater_ui_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterUIPreview>); - LLFloaterReg::add("test_widgets", "floater_test_widgets.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloater>); + LLFloaterReg::add("ui_preview", "floater_ui_preview.xml", + &LLFloaterReg::build<LLFloaterUIPreview>); + LLFloaterReg::add("test_list_view", "floater_test_list_view.xml", + &LLFloaterReg::build<LLFloaterTestListView>); + LLFloaterReg::add("test_widgets", "floater_test_widgets.xml", + &LLFloaterReg::build<LLFloater>); LLFloaterReg::add("pref_joystick", "floater_joystick.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterJoystick>); LLFloaterReg::add("pref_voicedevicesettings", "floater_device_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterVoiceDeviceSettings>); @@ -122,4 +166,10 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("preview_texture", "floater_preview_texture.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPreviewTexture>, "preview"); LLFloaterReg::add("stats", "floater_stats.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloater>); + + LLObjectIMInfo::register_floater(); + // debug use only + LLFloaterReg::add("media_remote_ctrl", "floater_media_remote.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMediaRemoteCtrl>); + + // *NOTE: Please keep these alphabetized for easier merges } diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index 2c79e67ebc..54b0a4f568 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -45,7 +45,7 @@ #include "llgesturemgr.h" #include "llinventorybridge.h" -#include "llinventoryview.h" +#include "llfloaterinventory.h" #include "llviewerregion.h" #include "llviewerobjectlist.h" @@ -870,7 +870,7 @@ void menu_create_inventory_item(LLFolderView* folder, LLFolderBridge *bridge, co } else { - category = gInventory.createNewCategory(gAgent.getInventoryRootID(), LLAssetType::AT_NONE, LLStringUtil::null); + category = gInventory.createNewCategory(gInventory.getRootFolderID(), LLAssetType::AT_NONE, LLStringUtil::null); } gInventory.notifyObservers(); folder->setSelectionByID(category, TRUE); diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index ae7099d382..70a6e24c8f 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -87,14 +87,12 @@ #include "llfloateractivespeakers.h" #include "llfloateranimpreview.h" #include "llfloateravatartextures.h" -#include "llfloaterbeacons.h" #include "llfloaterbuildoptions.h" #include "llfloaterbump.h" #include "llfloaterbuy.h" #include "llfloaterbuycontents.h" #include "llfloaterbuycurrency.h" #include "llfloaterbuyland.h" -#include "llfloatercamera.h" #include "llfloaterchat.h" #include "llfloatercustomize.h" #include "llfloaterdaycycle.h" @@ -146,7 +144,7 @@ #include "llimagetga.h" #include "llinventorybridge.h" #include "llinventorymodel.h" -#include "llinventoryview.h" +#include "llfloaterinventory.h" #include "llkeyboard.h" #include "llpanellogin.h" #include "llmenucommands.h" @@ -500,23 +498,23 @@ void init_menus() /// /// Pie menus /// - gPieSelf = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>("menu_pie_self.xml", gMenuHolder); + gPieSelf = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>("menu_pie_self.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); // TomY TODO: what shall we do about these? gDetachScreenPieMenu = gMenuHolder->getChild<LLContextMenu>("Object Detach HUD", true); gDetachPieMenu = gMenuHolder->getChild<LLContextMenu>("Object Detach", true); - gPieAvatar = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>("menu_pie_avatar.xml", gMenuHolder); + gPieAvatar = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>("menu_pie_avatar.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); - gPieObject = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>("menu_pie_object.xml", gMenuHolder); + gPieObject = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>("menu_pie_object.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); gAttachScreenPieMenu = gMenuHolder->getChild<LLContextMenu>("Object Attach HUD"); gAttachPieMenu = gMenuHolder->getChild<LLContextMenu>("Object Attach"); gPieRate = gMenuHolder->getChild<LLContextMenu>("Rate Menu"); - gPieAttachment = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>("menu_pie_attachment.xml", gMenuHolder); + gPieAttachment = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>("menu_pie_attachment.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); - gPieLand = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>("menu_pie_land.xml", gMenuHolder); + gPieLand = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>("menu_pie_land.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); /// /// set up the colors @@ -544,7 +542,7 @@ void init_menus() { color = LLUIColorTable::instance().getColor( "MenuNonProductionBgColor" ); } - gMenuBarView = LLUICtrlFactory::getInstance()->createFromFile<LLMenuBarGL>("menu_viewer.xml", gMenuHolder); + gMenuBarView = LLUICtrlFactory::getInstance()->createFromFile<LLMenuBarGL>("menu_viewer.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); gMenuBarView->setRect(LLRect(0, top, 0, top - MENU_BAR_HEIGHT)); gMenuBarView->setBackgroundColor( color ); @@ -575,7 +573,7 @@ void init_menus() // Let land based option enable when parcel changes gMenuParcelObserver = new LLMenuParcelObserver(); - gLoginMenuBarView = LLUICtrlFactory::getInstance()->createFromFile<LLMenuBarGL>("menu_login.xml", gMenuHolder); + gLoginMenuBarView = LLUICtrlFactory::getInstance()->createFromFile<LLMenuBarGL>("menu_login.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); gLoginMenuBarView->arrangeAndClear(); LLRect menuBarRect = gLoginMenuBarView->getRect(); gLoginMenuBarView->setRect(LLRect(menuBarRect.mLeft, menuBarRect.mTop, gViewerWindow->getRootView()->getRect().getWidth() - menuBarRect.mLeft, menuBarRect.mBottom)); @@ -612,11 +610,6 @@ class LLAdvancedToggleConsole : public view_listener_t toggle_visibility( (void*)gDebugView->mMemoryView ); } #endif - else if ("notifications" == console_type) - { - //LLFloaterNotificationConsole::showInstance(); - LLFloaterReg::showInstance("notifications_console"); - } return true; } }; @@ -1117,30 +1110,6 @@ class LLAdvancedCheckFrameTest : public view_listener_t }; - // -///////////////////////////// -//// HIDE SELECTED OBJECTS // -///////////////////////////// -// -// -//class LLAdvancedToggleHideSelectedObjects : public view_listener_t -//{ -// bool handleEvent(const LLSD& userdata) -// { -// LLSelectMgr::sHideSelectedObjects = !(LLSelectMgr::sHideSelectedObjects); -// return true; -// } -//}; - // -//class LLAdvancedCheckHideSelectedObjects : public view_listener_t -//{ -// bool handleEvent(const LLSD& userdata) -// { -// bool new_value = gHideSelectedObjects; -// return new_value; -// } -//}; - /////////////////////////// // SELECTED TEXTURE INFO // /////////////////////////// @@ -1506,16 +1475,6 @@ class LLAdvancedCheckDebugWindowProc : public view_listener_t // ------------------------------XUI MENU --------------------------- - -class LLAdvancedShowFontTest : public view_listener_t -{ - bool handleEvent(const LLSD& userdata) - { - LLFloaterFontTest::show(NULL); - return true; - } -}; - ////////////////////// // LOAD UI FROM XML // ////////////////////// @@ -1547,6 +1506,15 @@ class LLAdvancedSaveUIToXML : public view_listener_t }; +class LLAdvancedSendTestIms : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + LLIMModel::instance().testMessages(); + return true; +} +}; + /////////////// // XUI NAMES // @@ -1987,18 +1955,6 @@ class LLAdvancedDumpAvatarLocalTextures : public view_listener_t } }; -//////////////////////////////// -// Memory Leaking Simulation // -//////////////////////////////// -class LLAdvancedMemoryLeakingSimulation : public view_listener_t -{ - bool handleEvent(const LLSD& userdata) - { - LLFloaterMemLeak::show(NULL); - return true; - } -}; - #endif ///////////////// @@ -2147,7 +2103,6 @@ class LLAdvancedShowDebugSettings : public view_listener_t { bool handleEvent(const LLSD& userdata) { - // LLFloaterSettingsDebug::showInstance(userdata); LLFloaterReg::showInstance("settings_debug",userdata); return true; } @@ -2414,14 +2369,6 @@ class LLAdminHandleRegionDumpTempAssetData: public view_listener_t } }; //Admin (Top Level) -class LLAdminShowGodTools: public view_listener_t -{ - bool handleEvent(const LLSD& userdata) - { - LLFloaterGodTools::showInstance(LLSD()); - return true; - } -}; class LLAdminOnSaveState: public view_listener_t { @@ -2581,7 +2528,7 @@ class LLObjectEnableTouch : public view_listener_t // label.assign("Touch"); // } //} - +/* bool handle_object_open() { LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); @@ -2598,7 +2545,7 @@ class LLObjectOpen : public view_listener_t return handle_object_open(); } }; - +*/ class LLObjectEnableOpen : public view_listener_t { bool handleEvent(const LLSD& userdata) @@ -2715,16 +2662,6 @@ class LLObjectEdit : public view_listener_t } }; -class LLObjectInspect : public view_listener_t -{ - bool handleEvent(const LLSD& userdata) - { - LLFloaterInspect::show(); - return true; - } -}; - - //--------------------------------------------------------------------------- // Land pie menu //--------------------------------------------------------------------------- @@ -4382,7 +4319,7 @@ void handle_take() } // check library - if(gInventory.isObjectDescendentOf(category_id, gInventoryLibraryRoot)) + if(gInventory.isObjectDescendentOf(category_id, gInventory.getLibraryRootFolderID())) { category_id.setNull(); } @@ -5612,35 +5549,10 @@ class LLShowFloater : public view_listener_t { LLToolBar::toggle(NULL); } - else if (floater_name == "mute list") - { - LLFloaterReg::toggleInstance("mute"); - } - else if (floater_name == "camera controls") - { - LLFloaterCamera::toggleInstance(); - } - else if (floater_name == "movement controls") - { - LLFloaterMove::toggleInstance(); - } else if (floater_name == "my land") { LLFloaterLandHoldings::show(NULL); } - else if (floater_name == "about land") - { - if (LLViewerParcelMgr::getInstance()->selectionEmpty()) - { - LLViewerParcelMgr::getInstance()->selectParcelAt(gAgent.getPositionGlobal()); - } - - LLFloaterLand::showInstance(); - } - else if (floater_name == "about region") - { - LLFloaterRegionInfo::showInstance(); - } else if (floater_name == "buy land") { if (LLViewerParcelMgr::getInstance()->selectionEmpty()) @@ -5650,10 +5562,6 @@ class LLShowFloater : public view_listener_t LLViewerParcelMgr::getInstance()->startBuyLand(); } - else if (floater_name == "grid options") - { - LLFloaterReg::showInstance("build_options"); - } else if (floater_name == "script errors") { LLFloaterScriptDebug::show(LLUUID::null); @@ -5662,48 +5570,16 @@ class LLShowFloater : public view_listener_t { gViewerHtmlHelp.show(); } - else if (floater_name == "help tutorial") - { - LLFloaterHUD::showHUD(); - } else if (floater_name == "complaint reporter") { // Prevent menu from appearing in screen shot. gMenuHolder->hideMenus(); LLFloaterReporter::showFromMenu(COMPLAINT_REPORT); } - else if (floater_name == "mean events") - { - if (!gNoRender) - { - //LLFloaterBump::showInstance(); - LLFloaterReg::showInstance("bumps"); - } - } - else if (floater_name == "lag meter") - { - LLFloaterReg::showInstance("lagmeter"); - } else if (floater_name == "buy currency") { LLFloaterBuyCurrency::buyCurrency(); } - else if (floater_name == "about") - { - LLFloaterReg::showInstance("sl_about"); - } - else if (floater_name == "active speakers") - { - LLFloaterActiveSpeakers::toggleInstance(LLSD()); - } - else if (floater_name == "beacons") - { - LLFloaterBeacons::toggleInstance(LLSD()); - } - else if (floater_name == "perm prefs") - { - LLFloaterPerms::toggleInstance(LLSD()); - } else { LLFloaterReg::toggleInstance(floater_name); @@ -5722,30 +5598,6 @@ class LLFloaterVisible : public view_listener_t { new_value = LLToolBar::visible(NULL); } - else if (floater_name == "mute list") - { - new_value = LLFloaterReg::instanceVisible("mute"); - } - else if (floater_name == "camera controls") - { - new_value = LLFloaterCamera::instanceVisible(); - } - else if (floater_name == "movement controls") - { - new_value = LLFloaterMove::instanceVisible(); - } - else if (floater_name == "stat bar") - { - new_value = gSavedSettings.getBOOL("ShowDebugStats"); - } - else if (floater_name == "active speakers") - { - new_value = LLFloaterActiveSpeakers::instanceVisible(LLSD()); - } - else if (floater_name == "beacons") - { - new_value = LLFloaterBeacons::instanceVisible(LLSD()); - } else { new_value = LLFloaterReg::instanceVisible(floater_name); @@ -6440,8 +6292,8 @@ class LLToolsSelectedScriptAction : public view_listener_t msg = "RunningNot"; } LLUUID id; id.generate(); - LLFloater* floater = LLFloaterReg::getInstance(name, LLSD(id)); - LLFloaterScriptQueue* queue = dynamic_cast<LLFloaterScriptQueue*>(floater); + + LLFloaterScriptQueue* queue =LLFloaterReg::getTypedInstance<LLFloaterScriptQueue>(name, LLSD(id)); if (queue) { queue->setMono(mono); @@ -6450,7 +6302,7 @@ class LLToolsSelectedScriptAction : public view_listener_t else { llwarns << "Failed to generate LLFloaterScriptQueue with action: " << action << llendl; - delete floater; + delete queue; } return true; } @@ -7016,7 +6868,7 @@ void handle_grab_texture(void* data) gInventory.updateItem(item); gInventory.notifyObservers(); - LLInventoryView* view = LLInventoryView::getActiveInventory(); + LLFloaterInventory* view = LLFloaterInventory::getActiveInventory(); // Show the preview panel for textures to let // user know that the image is now in inventory. @@ -7026,7 +6878,7 @@ void handle_grab_texture(void* data) view->getPanel()->setSelection(item_id, TAKE_FOCUS_NO); view->getPanel()->openSelected(); - //LLInventoryView::dumpSelectionInformation((void*)view); + //LLFloaterInventory::dumpSelectionInformation((void*)view); // restore keyboard focus gFocusMgr.setKeyboardFocus(focus_ctrl); } @@ -7261,10 +7113,14 @@ void handle_buy_currency_test(void*) llinfos << "buy currency url " << url << llendl; - LLFloaterHtmlCurrency* floater = LLFloaterHtmlCurrency::showInstance(url); - // Needed so we can use secondlife:///app/floater/self/close SLURLs - floater->setTrusted(true); - floater->center(); + LLFloaterHtmlCurrency* floater =LLFloaterReg::getTypedInstance<LLFloaterHtmlCurrency>("html_currency", LLSD(url)); + if(floater) + { + LLFloaterReg::showInstance("html_currency", LLSD(url)); + // Needed so we can use secondlife:///app/floater/self/close SLURLs + floater->setTrusted(true); + floater->center(); + } } void handle_rebake_textures(void*) @@ -7984,11 +7840,11 @@ void initialize_menus() // Advanced > XUI commit.add("Advanced.ReloadColorSettings", boost::bind(&LLUIColorTable::loadFromSettings, LLUIColorTable::getInstance())); - view_listener_t::addMenu(new LLAdvancedShowFontTest(), "Advanced.ShowFontTest"); view_listener_t::addMenu(new LLAdvancedLoadUIFromXML(), "Advanced.LoadUIFromXML"); view_listener_t::addMenu(new LLAdvancedSaveUIToXML(), "Advanced.SaveUIToXML"); view_listener_t::addMenu(new LLAdvancedToggleXUINames(), "Advanced.ToggleXUINames"); view_listener_t::addMenu(new LLAdvancedCheckXUINames(), "Advanced.CheckXUINames"); + view_listener_t::addMenu(new LLAdvancedSendTestIms(), "Advanced.SendTestIMs"); // Advanced > Character > Grab Baked Texture view_listener_t::addMenu(new LLAdvancedGrabBakedTexture(), "Advanced.GrabBakedTexture"); @@ -8024,7 +7880,6 @@ void initialize_menus() #ifndef LL_RELEASE_FOR_DOWNLOAD view_listener_t::addMenu(new LLAdvancedDebugAvatarTextures(), "Advanced.DebugAvatarTextures"); view_listener_t::addMenu(new LLAdvancedDumpAvatarLocalTextures(), "Advanced.DumpAvatarLocalTextures"); - view_listener_t::addMenu(new LLAdvancedMemoryLeakingSimulation(), "Advanced.MemoryLeakingSimulation"); #endif // Advanced > Network view_listener_t::addMenu(new LLAdvancedEnableMessageLog(), "Advanced.EnableMessageLog"); @@ -8072,7 +7927,6 @@ void initialize_menus() // Admin >Region view_listener_t::addMenu(new LLAdminHandleRegionDumpTempAssetData(), "Admin.HandleRegionDumpTempAssetData"); // Admin top level - view_listener_t::addMenu(new LLAdminShowGodTools(), "Admin.ShowGodTools"); view_listener_t::addMenu(new LLAdminOnSaveState(), "Admin.OnSaveState"); // Self pie menu @@ -8100,7 +7954,6 @@ void initialize_menus() view_listener_t::addMenu(new LLAvatarEnableFreezeEject(), "Avatar.EnableFreezeEject"); // Object pie menu - view_listener_t::addMenu(new LLObjectOpen(), "Object.Open"); view_listener_t::addMenu(new LLObjectBuild(), "Object.Build"); view_listener_t::addMenu(new LLObjectTouch(), "Object.Touch"); view_listener_t::addMenu(new LLObjectSitOrStand(), "Object.SitOrStand"); @@ -8111,7 +7964,6 @@ void initialize_menus() view_listener_t::addMenu(new LLObjectMute(), "Object.Mute"); view_listener_t::addMenu(new LLObjectBuy(), "Object.Buy"); view_listener_t::addMenu(new LLObjectEdit(), "Object.Edit"); - view_listener_t::addMenu(new LLObjectInspect(), "Object.Inspect"); view_listener_t::addMenu(new LLObjectEnableOpen(), "Object.EnableOpen"); view_listener_t::addMenu(new LLObjectEnableTouch(), "Object.EnableTouch"); diff --git a/indra/newview/llviewermenu.h b/indra/newview/llviewermenu.h index 99994bdf5b..13a1639917 100644 --- a/indra/newview/llviewermenu.h +++ b/indra/newview/llviewermenu.h @@ -101,7 +101,6 @@ void handle_toggle_flycam(); bool handle_sit_or_stand(); bool handle_give_money_dialog(); -bool handle_object_open(); bool handle_go_to(); // Export to XML or Collada diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index a05bd30600..e46748edf0 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -94,7 +94,7 @@ #include "llhudmanager.h" #include "llimpanel.h" #include "llinventorymodel.h" -#include "llinventoryview.h" +#include "llfloaterinventory.h" #include "llmenugl.h" #include "llmutelist.h" #include "llnotifications.h" @@ -912,17 +912,17 @@ void open_offer(const std::vector<LLUUID>& items, const std::string& from_name) //highlight item, if it's not in the trash or lost+found // Don't auto-open the inventory floater - LLInventoryView* view = NULL; + LLFloaterInventory* view = NULL; if(gSavedSettings.getBOOL("ShowInInventory") && asset_type != LLAssetType::AT_CALLINGCARD && item->getInventoryType() != LLInventoryType::IT_ATTACHMENT && !from_name.empty()) { - view = LLInventoryView::showAgentInventory(); + view = LLFloaterInventory::showAgentInventory(); } else { - view = LLInventoryView::getActiveInventory(); + view = LLFloaterInventory::getActiveInventory(); } if(!view) { @@ -986,7 +986,8 @@ void inventory_offer_mute_callback(const LLUUID& blocked_id, if (LLMuteList::getInstance()->add(mute)) { LLFloaterReg::showInstance("mute"); - LLFloaterReg::getTypedInstance<LLFloaterMute>("mute")->selectMute(blocked_id); + LLFloaterMute* mute_instance = LLFloaterReg::getTypedInstance<LLFloaterMute>("mute"); + if(mute_instance) mute_instance->selectMute(blocked_id); } // purge the message queue of any previously queued inventory offers from the same source. @@ -1527,7 +1528,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) // now store incoming IM in chat history - buffer = separator_string + message.substr(message_offset); + buffer = message.substr(message_offset); LL_INFOS("Messaging") << "process_improved_im: session_id( " << session_id << " ), from_id( " << from_id << " )" << LL_ENDL; @@ -1577,7 +1578,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) { saved = llformat("(Saved %s) ", formatted_time(timestamp).c_str()); } - buffer = separator_string + saved + message.substr(message_offset); + buffer = saved + message.substr(message_offset); LL_INFOS("Messaging") << "process_improved_im: session_id( " << session_id << " ), from_id( " << from_id << " )" << LL_ENDL; @@ -1876,7 +1877,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) { saved = llformat("(Saved %s) ", formatted_time(timestamp).c_str()); } - buffer = separator_string + saved + message.substr(message_offset); + buffer = saved + message.substr(message_offset); BOOL is_this_agent = FALSE; if(from_id == gAgentID) { @@ -4793,13 +4794,13 @@ void container_inventory_arrived(LLViewerObject* object, gAgent.changeCameraToDefault(); } - LLInventoryView* view = LLInventoryView::getActiveInventory(); + LLFloaterInventory* view = LLFloaterInventory::getActiveInventory(); if (inventory->size() > 2) { // create a new inventory category to put this in LLUUID cat_id; - cat_id = gInventory.createNewCategory(gAgent.getInventoryRootID(), + cat_id = gInventory.createNewCategory(gInventory.getRootFolderID(), LLAssetType::AT_NONE, LLTrans::getString("AcquiredItems")); @@ -5494,10 +5495,14 @@ void process_script_teleport_request(LLMessageSystem* msg, void**) msg->getVector3("Data", "SimPosition", pos); msg->getVector3("Data", "LookAt", look_at); - LLFloaterWorldMap::getInstance()->trackURL( - sim_name, (S32)pos.mV[VX], (S32)pos.mV[VY], (S32)pos.mV[VZ]); - LLFloaterReg::showInstance("world_map", "center"); - + LLFloaterWorldMap* instance = LLFloaterWorldMap::getInstance(); + if(instance) + { + instance->trackURL( + sim_name, (S32)pos.mV[VX], (S32)pos.mV[VY], (S32)pos.mV[VZ]); + LLFloaterReg::showInstance("world_map", "center"); + } + // remove above two lines and replace with below line // to re-enable parcel browser for llMapDestination() // LLURLDispatcher::dispatch(LLSLURL::buildSLURL(sim_name, (S32)pos.mV[VX], (S32)pos.mV[VY], (S32)pos.mV[VZ]), FALSE); diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp index f4989ec4fe..399b7c6bc1 100644 --- a/indra/newview/llviewertexteditor.cpp +++ b/indra/newview/llviewertexteditor.cpp @@ -39,7 +39,7 @@ #include "llinventory.h" #include "llinventorybridge.h" #include "llinventorymodel.h" -#include "llinventoryview.h" +#include "llfloaterinventory.h" #include "llviewertexteditor.h" @@ -64,7 +64,7 @@ #include "llappviewer.h" // for gPacificDaylightTime -static LLDefaultWidgetRegistry::Register<LLViewerTextEditor> r("text_editor"); +static LLDefaultChildRegistry::Register<LLViewerTextEditor> r("text_editor"); ///---------------------------------------------------------------------------- /// Class LLEmbeddedNotecardOpener diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 569eba2f20..e4aaf2bf29 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -93,7 +93,6 @@ #include "llfeaturemanager.h" #include "llfilepicker.h" #include "llfloater.h" -#include "llfloateractivespeakers.h" #include "llfloaterbuildoptions.h" #include "llfloaterbuyland.h" #include "llfloatercamera.h" @@ -116,7 +115,7 @@ #include "llhudview.h" #include "llimagebmp.h" #include "llimagej2c.h" -#include "llinventoryview.h" +#include "llfloaterinventory.h" #include "llkeyboard.h" #include "lllineeditor.h" #include "llmenugl.h" diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index b38e71236d..e351c904e6 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -52,7 +52,7 @@ #include "llheadrotmotion.h" #include "llhudeffecttrail.h" #include "llhudmanager.h" -#include "llinventoryview.h" +#include "llfloaterinventory.h" #include "llkeyframefallmotion.h" #include "llkeyframestandmotion.h" #include "llkeyframewalkmotion.h" diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index e7d7d74f62..ef02b509ba 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -54,7 +54,7 @@ #include "llheadrotmotion.h" #include "llhudeffecttrail.h" #include "llhudmanager.h" -#include "llinventoryview.h" +#include "llfloaterinventory.h" #include "llkeyframefallmotion.h" #include "llkeyframestandmotion.h" #include "llkeyframewalkmotion.h" diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index 082dcb50a2..fc639fbb21 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -4551,7 +4551,7 @@ void LLVoiceClient::messageEvent( if(messageHeader.find("text/html") != std::string::npos) { - std::string rawMessage; + std::string message; { const std::string startMarker = "<body"; @@ -4563,7 +4563,7 @@ void LLVoiceClient::messageEvent( std::string::size_type end; // Default to displaying the raw string, so the message gets through. - rawMessage = messageBody; + message = messageBody; // Find the actual message text within the XML fragment start = messageBody.find(startMarker); @@ -4577,7 +4577,7 @@ void LLVoiceClient::messageEvent( if(end != std::string::npos) end -= start; - rawMessage.assign(messageBody, start, end); + message.assign(messageBody, start, end); } else { @@ -4593,24 +4593,24 @@ void LLVoiceClient::messageEvent( if(end != std::string::npos) end -= start; - rawMessage.assign(messageBody, start, end); + message.assign(messageBody, start, end); } } } -// LL_DEBUGS("Voice") << " raw message = \n" << rawMessage << LL_ENDL; +// LL_DEBUGS("Voice") << " raw message = \n" << message << LL_ENDL; // strip formatting tags { std::string::size_type start; std::string::size_type end; - while((start = rawMessage.find('<')) != std::string::npos) + while((start = message.find('<')) != std::string::npos) { - if((end = rawMessage.find('>', start + 1)) != std::string::npos) + if((end = message.find('>', start + 1)) != std::string::npos) { // Strip out the tag - rawMessage.erase(start, (end + 1) - start); + message.erase(start, (end + 1) - start); } else { @@ -4626,31 +4626,31 @@ void LLVoiceClient::messageEvent( // The text may contain text encoded with <, >, and & mark = 0; - while((mark = rawMessage.find("<", mark)) != std::string::npos) + while((mark = message.find("<", mark)) != std::string::npos) { - rawMessage.replace(mark, 4, "<"); + message.replace(mark, 4, "<"); mark += 1; } mark = 0; - while((mark = rawMessage.find(">", mark)) != std::string::npos) + while((mark = message.find(">", mark)) != std::string::npos) { - rawMessage.replace(mark, 4, ">"); + message.replace(mark, 4, ">"); mark += 1; } mark = 0; - while((mark = rawMessage.find("&", mark)) != std::string::npos) + while((mark = message.find("&", mark)) != std::string::npos) { - rawMessage.replace(mark, 5, "&"); + message.replace(mark, 5, "&"); mark += 1; } } // strip leading/trailing whitespace (since we always seem to get a couple newlines) - LLStringUtil::trim(rawMessage); + LLStringUtil::trim(message); -// LL_DEBUGS("Voice") << " stripped message = \n" << rawMessage << LL_ENDL; +// LL_DEBUGS("Voice") << " stripped message = \n" << message << LL_ENDL; sessionState *session = findSession(sessionHandle); if(session) @@ -4674,14 +4674,12 @@ void LLVoiceClient::messageEvent( quiet_chat = true; // TODO: Question: Return busy mode response here? Or maybe when session is started instead? } - - std::string fullMessage = std::string(": ") + rawMessage; - + LL_DEBUGS("Voice") << "adding message, name " << session->mName << " session " << session->mIMSessionID << ", target " << session->mCallerID << LL_ENDL; gIMMgr->addMessage(session->mIMSessionID, session->mCallerID, session->mName.c_str(), - fullMessage.c_str(), + message.c_str(), LLStringUtil::null, // default arg IM_NOTHING_SPECIAL, // default arg 0, // default arg @@ -4689,7 +4687,7 @@ void LLVoiceClient::messageEvent( LLVector3::zero, // default arg true); // prepend name and make it a link to the user's profile - chat.mText = std::string("IM: ") + session->mName + std::string(": ") + rawMessage; + chat.mText = std::string("IM: ") + session->mName + std::string(": ") + message; // If the chat should come in quietly (i.e. we're in busy mode), pretend it's from a local agent. LLFloaterChat::addChat( chat, TRUE, quiet_chat ); } diff --git a/indra/newview/llweb.cpp b/indra/newview/llweb.cpp index 781f8298f7..57f57f75d7 100644 --- a/indra/newview/llweb.cpp +++ b/indra/newview/llweb.cpp @@ -41,6 +41,7 @@ #include "llviewerwindow.h" #include "llviewercontrol.h" #include "llfloaterhtmlhelp.h" +#include "llfloaterreg.h" #include "llalertdialog.h" class URLLoader : public LLAlertDialog::URLLoader @@ -75,7 +76,7 @@ void LLWeb::loadURL(const std::string& url) } else { - LLFloaterMediaBrowser::showInstance(url); + LLFloaterReg::showInstance("media_browser",url); } } diff --git a/indra/newview/skins/default/xui/en/floater_auction.xml b/indra/newview/skins/default/xui/en/floater_auction.xml index 076332e062..32d3f4fd7e 100644 --- a/indra/newview/skins/default/xui/en/floater_auction.xml +++ b/indra/newview/skins/default/xui/en/floater_auction.xml @@ -48,7 +48,7 @@ left_delta="0" name="snapshot_btn" top_pad="4" - width="96" > + width="96"> <button.commit_callback function="ClickSnapshot" /> </button> diff --git a/indra/newview/skins/default/xui/en/floater_beacons.xml b/indra/newview/skins/default/xui/en/floater_beacons.xml index 41ddec6395..049ea9ab14 100644 --- a/indra/newview/skins/default/xui/en/floater_beacons.xml +++ b/indra/newview/skins/default/xui/en/floater_beacons.xml @@ -20,43 +20,64 @@ control_name="scripttouchbeacon" label="Scripted Objects with Touch Only" layout="topleft" - name="touch_only" /> + name="touch_only" > + <check_box.commit_callback + function="Beacons.UICheck" /> + </check_box> <check_box bottom_delta="20" control_name="scriptsbeacon" label="Scripted Objects" layout="topleft" - name="scripted" /> + name="scripted"> + <check_box.commit_callback + function="Beacons.UICheck" /> + </check_box> <check_box bottom_delta="20" control_name="physicalbeacon" label="Physical Objects" layout="topleft" - name="physical" /> + name="physical" > + <check_box.commit_callback + function="Beacons.UICheck" /> + </check_box> <check_box bottom_delta="20" control_name="soundsbeacon" label="Sound Sources" layout="topleft" - name="sounds" /> + name="sounds" > + <check_box.commit_callback + function="Beacons.UICheck" /> + </check_box> <check_box bottom_delta="20" control_name="particlesbeacon" label="Particle Sources" layout="topleft" - name="particles" /> + name="particles" > + <check_box.commit_callback + function="Beacons.UICheck" /> + </check_box> <check_box bottom_delta="20" control_name="renderhighlights" label="Render Highlights" layout="topleft" - name="highlights" /> + name="highlights" > + <check_box.commit_callback + function="Beacons.UICheck" /> + </check_box> <check_box bottom_delta="20" control_name="renderbeacons" label="Render Beacons" layout="topleft" - name="beacons" /> + name="beacons" > + <check_box.commit_callback + function="Beacons.UICheck" /> + </check_box> <text type="string" length="1" diff --git a/indra/newview/skins/default/xui/en/floater_bulk_perms.xml b/indra/newview/skins/default/xui/en/floater_bulk_perms.xml index 6d7e3a9c45..843a8848bf 100644 --- a/indra/newview/skins/default/xui/en/floater_bulk_perms.xml +++ b/indra/newview/skins/default/xui/en/floater_bulk_perms.xml @@ -224,7 +224,10 @@ left="8" name="check_all" top="257" - width="100" /> + width="100"> + <button.commit_callback + function="BulkPermission.CheckAll" /> + </button> <button follows="left|top" height="20" @@ -234,7 +237,10 @@ left_delta="0" name="check_none" top_pad="4" - width="100" /> + width="100" > + <button.commit_callback + function="BulkPermission.UncheckAll"/> + </button> <text type="string" length="1" @@ -295,10 +301,13 @@ left_delta="78" name="next_owner_copy" top_delta="0" - width="88" /> - <check_box + width="88"> + <check_box.commit_callback + function="BulkPermission.CommitCopy"/> + </check_box> + <check_box control_name="BulkChangeNextOwnerTransfer" - enabled="false" + enabled_control="BulkChangeNextOwnerCopy" height="16" initial_value="true" label="Resell/Give away" @@ -324,7 +333,10 @@ left="65" name="apply" top_pad="10" - width="100" /> + width="100"> + <button.commit_callback + function="BulkPermission.Apply"/> + </button> <button follows="left|top" height="20" @@ -333,5 +345,8 @@ left_pad="5" name="close" top_delta="0" - width="100" /> + width="100" > + <button.commit_callback + function="BulkPermission.Close"/> + </button> </floater> diff --git a/indra/newview/skins/default/xui/en/floater_god_tools.xml b/indra/newview/skins/default/xui/en/floater_god_tools.xml index e35ab3ea49..f3abad8cb2 100644 --- a/indra/newview/skins/default/xui/en/floater_god_tools.xml +++ b/indra/newview/skins/default/xui/en/floater_god_tools.xml @@ -34,7 +34,10 @@ left="10" name="Kick all users" top="8" - width="100" /> + width="100"> + <button.commit_callback + function="GridTools.KickAll" /> + </button> <button follows="left|top" height="20" @@ -44,7 +47,10 @@ left_delta="0" name="Flush This Region's Map Visibility Caches" top_pad="8" - width="250" /> + width="250"> + <button.commit_callback + function="GridTools.FlushMapVisibilityCaches" /> + </button> </panel> <panel border="true" @@ -79,7 +85,10 @@ max_length="63" name="region name" top_delta="0" - width="208" /> + width="208"> + <line_editor.commit_callback + function="RegionTools.ChangeAnything" /> + </line_editor> <check_box height="16" label="Prelude" @@ -88,7 +97,10 @@ name="check prelude" tool_tip="Set this to make the region a prelude." top="30" - width="180" /> + width="180"> + <check_box.commit_callback + function="RegionTools.ChangePrelude" /> + </check_box> <check_box height="16" label="Fixed Sun" @@ -97,7 +109,10 @@ name="check fixed sun" tool_tip="Fix the sun position (like in Region/Estate > Terrain." top_pad="4" - width="180" /> + width="180"> + <check_box.commit_callback + function="RegionTools.ChangeAnything" /> + </check_box> <check_box height="16" label="Reset Home On Teleport" @@ -106,7 +121,10 @@ name="check reset home" tool_tip="When resident teleports out, reset their home to the destination position." top_pad="4" - width="180" /> + width="180"> + <check_box.commit_callback + function="RegionTools.ChangeAnything" /> + </check_box> <check_box height="16" label="Visible" @@ -115,7 +133,10 @@ name="check visible" tool_tip="Set this to make the region visible to non-gods." top_pad="4" - width="180" /> + width="180"> + <check_box.commit_callback + function="RegionTools.ChangeAnything" /> + </check_box> <check_box height="16" label="Damage" @@ -124,7 +145,10 @@ name="check damage" tool_tip="Set this to enable damage in this region." top_pad="4" - width="180" /> + width="180"> + <check_box.commit_callback + function="RegionTools.ChangeAnything" /> + </check_box> <check_box height="16" label="Block Traffic Tracking" @@ -133,7 +157,10 @@ name="block dwell" tool_tip="Set this to make the region not compute traffic." top_pad="4" - width="180" /> + width="180"> + <check_box.commit_callback + function="RegionTools.ChangeAnything" /> + </check_box> <check_box height="16" label="Block Terraform" @@ -142,7 +169,10 @@ name="block terraform" tool_tip="Set this to disallow people terraforming their land" top_pad="4" - width="180" /> + width="180"> + <check_box.commit_callback + function="RegionTools.ChangeAnything" /> + </check_box> <check_box height="16" label="Sandbox" @@ -151,7 +181,10 @@ name="is sandbox" tool_tip="Toggle whether this is a sandbox region." top_pad="4" - width="180" /> + width="180"> + <check_box.commit_callback + function="RegionTools.ChangeAnything" /> + </check_box> <button follows="top|right" font="SansSerifSmall" @@ -163,7 +196,10 @@ name="Bake Terrain" tool_tip="Save the current terrain as default." top_pad="32" - width="110" /> + width="110"> + <button.commit_callback + function="RegionTools.BakeTerrain" /> + </button> <button follows="top|right" font="SansSerifSmall" @@ -175,7 +211,10 @@ name="Revert Terrain" tool_tip="Replace the current terrain with default." top_pad="4" - width="110" /> + width="110"> + <button.commit_callback + function="RegionTools.RevertTerrain" /> + </button> <button follows="top|right" font="SansSerifSmall" @@ -187,7 +226,10 @@ name="Swap Terrain" tool_tip="Swap current terrain with default." top_pad="4" - width="110" /> + width="110"> + <button.commit_callback + function="RegionTools.SwapTerrain" /> + </button> <text type="string" length="1" @@ -236,7 +278,10 @@ name="parentestate" tool_tip="This is the parent estate for this region" top_delta="0" - width="50" /> + width="50"> + <line_editor.commit_callback + function="RegionTools.ChangeAnything" /> + </line_editor> <text type="string" length="1" @@ -260,7 +305,10 @@ name="gridposx" tool_tip="This is the grid x position for this region" top_delta="0" - width="50" /> + width="50"> + <line_editor.commit_callback + function="RegionTools.ChangeAnything" /> + </line_editor> <line_editor border_style="line" border_thickness="1" @@ -272,7 +320,10 @@ name="gridposy" tool_tip="This is the grid y position for this region" top_delta="0" - width="40" /> + width="40"> + <line_editor.commit_callback + function="RegionTools.ChangeAnything" /> + </line_editor> <text type="string" length="1" @@ -295,7 +346,10 @@ max_length="10" name="redirectx" top_delta="0" - width="50" /> + width="50"> + <line_editor.commit_callback + function="RegionTools.ChangeAnything" /> + </line_editor> <line_editor border_style="line" border_thickness="1" @@ -306,7 +360,10 @@ max_length="10" name="redirecty" top_delta="0" - width="40" /> + width="40"> + <line_editor.commit_callback + function="RegionTools.ChangeAnything" /> + </line_editor> <spinner follows="top|right" height="16" @@ -316,7 +373,10 @@ max_val="4" name="billable factor" top="110" - width="80" /> + width="80"> + <spinner.commit_callback + function="RegionTools.ChangeAnything" /> + </spinner> <text type="string" length="1" @@ -340,7 +400,10 @@ max_val="100" name="land cost" top="130" - width="80" /> + width="80"> + <spinner.commit_callback + function="RegionTools.ChangeAnything" /> + </spinner> <text type="string" length="1" @@ -365,7 +428,10 @@ name="Refresh" tool_tip="Click here to refresh the above information." top="150" - width="110" /> + width="110"> + <button.commit_callback + function="RegionTools.Refresh" /> + </button> <button follows="top|right" font="SansSerifSmall" @@ -377,7 +443,10 @@ name="Apply" tool_tip="Click here to apply any changes from above." top_pad="36" - width="110" /> + width="110"> + <button.commit_callback + function="RegionTools.ApplyChanges" /> + </button> <button follows="top|right" font="SansSerifSmall" @@ -389,7 +458,10 @@ name="Select Region" tool_tip="Select the whole region with the land tool." top="238" - width="110" /> + width="110"> + <button.commit_callback + function="RegionTools.SelectRegion" /> + </button> <button follows="top|right" font="SansSerifSmall" @@ -401,7 +473,10 @@ name="Autosave now" tool_tip="Save gzipped state to autosave directory." top_pad="4" - width="110" /> + width="110"> + <button.commit_callback + function="RegionTools.SaveState" /> + </button> </panel> <panel border="true" @@ -450,7 +525,10 @@ name="disable scripts" tool_tip="Set this to disable all scripts in this region" top="30" - width="110" /> + width="110"> + <check_box.commit_callback + function="ObjectTools.ChangeAnything" /> + </check_box> <check_box height="16" label="Disable Collisions" @@ -459,7 +537,10 @@ name="disable collisions" tool_tip="Set this to disable non-agent collisions in this region" top_delta="0" - width="121" /> + width="121"> + <check_box.commit_callback + function="ObjectTools.ChangeAnything" /> + </check_box> <check_box height="16" label="Disable Physics" @@ -468,7 +549,10 @@ name="disable physics" tool_tip="Set this to disable all physics in this region" top_delta="0" - width="130" /> + width="130"> + <check_box.commit_callback + function="ObjectTools.ChangeAnything" /> + </check_box> <button follows="top|right" font="SansSerifSmall" @@ -480,8 +564,11 @@ name="Apply" tool_tip="Click here to apply any changes from above." top="54" - width="110" /> - <button + width="110"> + <button.commit_callback + function="ObjectTools.ApplyChanges" /> + </button> + <button follows="top|right" font="SansSerifSmall" height="20" @@ -492,7 +579,10 @@ name="Set Target" tool_tip="Set the target avatar for object deletion." top="78" - width="110" /> + width="110"> + <button.commit_callback + function="ObjectTools.Set" /> + </button> <text type="string" length="1" @@ -516,7 +606,10 @@ name="Delete Target's Scripted Objects On Others Land" tool_tip="Delete all scripted objects owned by the target on land not owned by the target. (no copy) objects will be returned." top="126" - width="380" /> + width="380"> + <button.commit_callback + function="ObjectTools.DeletePublicOwnedBy" /> + </button> <button follows="top|right" font="SansSerifSmall" @@ -528,7 +621,10 @@ name="Delete Target's Scripted Objects On *Any* Land" tool_tip="Delete all scripted objects owned by the target in this region. (no copy) objects will be returned." top_pad="28" - width="380" /> + width="380"> + <button.commit_callback + function="ObjectTools.DeleteAllScriptedOwnedBy" /> + </button> <button follows="top|right" font="SansSerifSmall" @@ -540,8 +636,11 @@ name="Delete *ALL* Of Target's Objects" tool_tip="Delete all objects owned by the target in this region. (no copy) objects will be returned." top_pad="28" - width="380" /> - <button + width="380"> + <button.commit_callback + function="ObjectTools.DeleteAllOwnedBy" /> + </button> + <button follows="top|right" font="SansSerifSmall" height="20" @@ -552,7 +651,10 @@ name="Get Top Colliders" tool_tip="Gets list of objects experiencing the most narrowphase callbacks." top_pad="28" - width="110" /> + width="110"> + <button.commit_callback + function="ObjectTools.GetTopColliders" /> + </button> <button follows="top|right" font="SansSerifSmall" @@ -564,7 +666,10 @@ name="Get Top Scripts" tool_tip="Gets list of objects spending the most time running scripts." top_pad="4" - width="110" /> + width="110"> + <button.commit_callback + function="ObjectTools.GetTopScripts" /> + </button> <button follows="top|right" font="SansSerifSmall" @@ -576,7 +681,10 @@ name="Scripts digest" tool_tip="Gets a list of all scripts and number of occurences of each." top_pad="4" - width="110" /> + width="110" > + <button.commit_callback + function="ObjectTools.GetScriptDigest" /> + </button> </panel> <panel border="true" @@ -679,7 +787,10 @@ left="10" name="Make Request" top="96" - width="100" /> + width="100"> + <button.commit_callback + function="GodTools.Request" /> + </button> </panel> </tab_container> </floater> diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml new file mode 100644 index 0000000000..7c95fcd96a --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_im_session.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ background_visible="true"
+ follows="left|top|right|bottom"
+ height="200"
+ layout="topleft"
+ left="0"
+ name="panel_im"
+ top="0"
+ width="300">
+ <text_editor
+ enabled="false"
+ type="string"
+ length="1"
+ top="20"
+ follows="left|top|right"
+ font="SansSerif"
+ height="175"
+ layout="topleft"
+ left="5"
+ name="im_text"
+ width="290"
+ word_wrap="true">
+ </text_editor>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_inspect.xml b/indra/newview/skins/default/xui/en/floater_inspect.xml index ed3b4f00f2..b11b3e4df5 100644 --- a/indra/newview/skins/default/xui/en/floater_inspect.xml +++ b/indra/newview/skins/default/xui/en/floater_inspect.xml @@ -40,6 +40,8 @@ label="Creation Date" name="creation_date" width="150" /> + <scroll_list.commit_callback + function="Inspect.SelectObject" /> </scroll_list> <button follows="left|bottom" @@ -50,7 +52,10 @@ name="button owner" tool_tip="See profile of the highlighted object's owner" top_pad="5" - width="150" /> + width="150"> + <button.commit_callback + function="Inspect.OwnerProfilet" /> + </button> <button follows="left|bottom" height="20" @@ -60,5 +65,8 @@ name="button creator" tool_tip="See profile of the highlighted object's original creator" top_delta="0" - width="150" /> + width="150"> + <button.commit_callback + function="Inspect.CreatorProfile" /> + </button> </floater> diff --git a/indra/newview/skins/default/xui/en/floater_lagmeter.xml b/indra/newview/skins/default/xui/en/floater_lagmeter.xml index 8af4f74aa3..a326cd006f 100644 --- a/indra/newview/skins/default/xui/en/floater_lagmeter.xml +++ b/indra/newview/skins/default/xui/en/floater_lagmeter.xml @@ -201,7 +201,7 @@ Client: </text> <text - make_visible_control="LagMeterShrunk" + visiblity_control="LagMeterShrunk" type="string" length="1" bottom="40" @@ -215,7 +215,7 @@ Normal </text> <text - make_visible_control="LagMeterShrunk" + visiblity_control="LagMeterShrunk" bottom="56" follows="left|top" height="16" @@ -250,7 +250,7 @@ Network: </text> <text - make_visible_control="LagMeterShrunk" + visiblity_control="LagMeterShrunk" type="string" length="1" bottom="80" @@ -264,7 +264,7 @@ Normal </text> <text - make_visible_control="LagMeterShrunk" + visiblity_control="LagMeterShrunk" bottom="96" follows="left|top" height="16" diff --git a/indra/newview/skins/default/xui/en/floater_media_browser.xml b/indra/newview/skins/default/xui/en/floater_media_browser.xml index a073c3443a..15ec2e220f 100644 --- a/indra/newview/skins/default/xui/en/floater_media_browser.xml +++ b/indra/newview/skins/default/xui/en/floater_media_browser.xml @@ -34,7 +34,10 @@ left="0" name="back" top="0" - width="55" /> + width="55"> + <button.commit_callback + function="MediaBrowser.Back" /> + </button> <button follows="left|top" height="20" @@ -43,7 +46,10 @@ left_pad="3" name="forward" top_delta="0" - width="68" /> + width="68"> + <button.commit_callback + function="MediaBrowser.Forward" /> + </button> <button enabled="false" follows="left|top" @@ -53,7 +59,10 @@ left_pad="2" name="reload" top_delta="0" - width="70" /> + width="70"> + <button.commit_callback + function="MediaBrowser.Refresh" /> + </button> <combo_box allow_text_entry="true" follows="left|top|right" @@ -63,7 +72,10 @@ max_chars="255" name="address" top_delta="0" - width="540" /> + width="540"> + <combo_box.commit_callback + function="MediaBrowser.EnterAddress" /> + </combo_box> <button enabled="false" follows="right|top" @@ -73,7 +85,10 @@ left_pad="5" name="go" top_delta="0" - width="55" /> + width="55"> + <button.commit_callback + function="MediaBrowser.Go" /> + </button> </layout_panel> <layout_panel auto_resize="false" @@ -93,7 +108,10 @@ left="0" name="assign" top="0" - width="200" /> + width="200"> + <button.commit_callback + function="MediaBrowser.Assign" /> + </button> </layout_panel> <layout_panel height="20" @@ -119,7 +137,10 @@ left_delta="0" name="open_browser" top_pad="5" - width="185" /> + width="185"> + <button.commit_callback + function="MediaBrowser.OpenWebBrowser" /> + </button> <check_box control_name="UseExternalBrowser" follows="bottom|left" @@ -138,7 +159,10 @@ left_pad="80" name="close" top_delta="0" - width="70" /> + width="70"> + <button.commit_callback + function="MediaBrowser.Close" /> + </button> </layout_panel> </layout_stack> </floater> diff --git a/indra/newview/skins/default/xui/en/floater_mem_leaking.xml b/indra/newview/skins/default/xui/en/floater_mem_leaking.xml index e2a99e6614..da698f276b 100644 --- a/indra/newview/skins/default/xui/en/floater_mem_leaking.xml +++ b/indra/newview/skins/default/xui/en/floater_mem_leaking.xml @@ -20,7 +20,10 @@ max_val="4.29497e+009" name="leak_speed" top="30" - width="330" /> + width="330"> + <spinner.commit_callback + function="MemLeak.ChangeLeakingSpeed" /> + </spinner> <spinner decimal_digits="0" follows="left|top" @@ -34,7 +37,10 @@ max_val="4096" name="max_leak" top_pad="5" - width="330" /> + width="330"> + <spinner.commit_callback + function="MemLeak.ChangeMaxMemLeaking" /> + </spinner> <text type="string" length="1" @@ -79,7 +85,10 @@ left_delta="0" name="start_btn" top_delta="20" - width="70" /> + width="70"> + <button.commit_callback + function="MemLeak.Start" /> + </button> <button follows="left|top" height="20" @@ -88,7 +97,10 @@ left_pad="7" name="stop_btn" top_delta="0" - width="70" /> + width="70"> + <button.commit_callback + function="MemLeak.Stop" /> + </button> <button follows="left|top" height="20" @@ -97,7 +109,10 @@ left_pad="7" name="release_btn" top_delta="0" - width="70" /> + width="70"> + <button.commit_callback + function="MemLeak.Release" /> + </button> <button follows="left|top" height="20" @@ -106,5 +121,8 @@ left_pad="36" name="close_btn" top_delta="0" - width="70" /> + width="70"> + <button.commit_callback + function="MemLeak.Close" /> + </button> </floater> diff --git a/indra/newview/skins/default/xui/en/floater_openobject.xml b/indra/newview/skins/default/xui/en/floater_openobject.xml index 742934b57b..e0ac2c1d51 100644 --- a/indra/newview/skins/default/xui/en/floater_openobject.xml +++ b/indra/newview/skins/default/xui/en/floater_openobject.xml @@ -42,7 +42,10 @@ name="copy_to_inventory_button" tab_group="1" top_pad="285" - width="120" /> + width="120"> + <button.commit_callback + function="OpenObject.MoveToInventory" /> + </button> <button follows="bottom|left" font="SansSerifSmall" @@ -53,5 +56,8 @@ left_pad="10" name="copy_and_wear_button" top_delta="0" - width="120" /> + width="120"> + <button.commit_callback + function="OpenObject.MoveAndWear" /> + </button> </floater> diff --git a/indra/newview/skins/default/xui/en/floater_perm_prefs.xml b/indra/newview/skins/default/xui/en/floater_perm_prefs.xml index 430cb940e5..e4cb97035c 100644 --- a/indra/newview/skins/default/xui/en/floater_perm_prefs.xml +++ b/indra/newview/skins/default/xui/en/floater_perm_prefs.xml @@ -24,7 +24,11 @@ left="260" name="help" top="7" - width="22" /> + width="22"> + <button.commit_callback + function="Notification.Show" + parameter="ClickUploadHelpPermissions" /> + </button> <check_box control_name="ShareWithGroup" height="16" @@ -72,8 +76,12 @@ left_delta="78" name="next_owner_copy" top_delta="0" - width="88" /> + width="88" > + <check_box.commit_callback + function="Perms.Copy" /> + </check_box> <check_box + enabled_control="NextOwnerCopy" control_name="NextOwnerTransfer" enabled="false" height="16" @@ -93,7 +101,10 @@ left="90" name="ok" top="150" - width="100" /> + width="100"> + <button.commit_callback + function="Perms.OK" /> + </button> <button height="20" label="Cancel" @@ -102,5 +113,8 @@ left_pad="5" name="cancel" top_delta="0" - width="100" /> + width="100"> + <button.commit_callback + function="Perms.Cancel" /> + </button> </floater> diff --git a/indra/newview/skins/default/xui/en/floater_test_list_view.xml b/indra/newview/skins/default/xui/en/floater_test_list_view.xml new file mode 100644 index 0000000000..3991a4a82b --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_test_list_view.xml @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_resize="true"
+ height="400"
+ layout="topleft"
+ name="floater_test_list_view"
+ width="400">
+ <list_view
+ height="300"
+ left="10"
+ name="test_list_view"
+ top="28"
+ width="300" />
+ <button
+ name="test_1_btn"
+ label="Test 1"
+ top="350"
+ left="10"
+ height="20"
+ width="80"
+ commit_callback.function="TestListView.Test1" />
+ <button
+ name="test_2_btn"
+ label="Test 2"
+ top_delta="0"
+ left_pad="10"
+ height="20"
+ width="80"
+ commit_callback.function="TestListView.Test2" />
+
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_top_objects.xml b/indra/newview/skins/default/xui/en/floater_top_objects.xml index 20e39beb6f..ecd64d08e6 100644 --- a/indra/newview/skins/default/xui/en/floater_top_objects.xml +++ b/indra/newview/skins/default/xui/en/floater_top_objects.xml @@ -87,6 +87,8 @@ label="Mono Time" name="mono_time" width="55" /> + <scroll_list.commit_callback + function="TopObjects.CommitObjectsList" /> </scroll_list> <text type="string" @@ -117,7 +119,10 @@ left_pad="10" name="show_beacon_btn" top_delta="0" - width="100" /> + width="100"> + <button.commit_callback + function="TopObjects.ShowBeacon" /> + </button> <text type="string" length="1" @@ -146,7 +151,10 @@ left_pad="10" name="filter_object_btn" top_delta="0" - width="100" /> + width="100"> + <button.commit_callback + function="TopObjects.GetByObjectName" /> + </button> <text type="string" length="1" @@ -175,7 +183,10 @@ left_pad="10" name="filter_owner_btn" top_delta="0" - width="100" /> + width="100"> + <button.commit_callback + function="TopObjects.GetByOwnerName" /> + </button> <button follows="bottom|left" height="20" @@ -184,7 +195,10 @@ left="10" name="return_selected_btn" top="295" - width="130" /> + width="130"> + <button.commit_callback + function="TopObjects.ReturnSelected" /> + </button> <button follows="bottom|left" height="20" @@ -193,7 +207,10 @@ left_pad="10" name="return_all_btn" top_delta="0" - width="130" /> + width="130"> + <button.commit_callback + function="TopObjects.ReturnAll" /> + </button> <button follows="bottom|left" height="20" @@ -202,7 +219,10 @@ left="10" name="disable_selected_btn" top="320" - width="130" /> + width="130"> + <button.commit_callback + function="TopObjects.DisableSelected" /> + </button> <button follows="bottom|left" height="20" @@ -211,7 +231,10 @@ left_pad="10" name="disable_all_btn" top_delta="0" - width="130" /> + width="130"> + <button.commit_callback + function="TopObjects.DisableAll" /> + </button> <button bottom="315" follows="bottom|right" @@ -220,5 +243,8 @@ layout="topleft" name="refresh_btn" right="-10" - width="100" /> + width="100"> + <button.commit_callback + function="TopObjects.Refresh" /> + </button> </floater> diff --git a/indra/newview/skins/default/xui/en/floater_world_map.xml b/indra/newview/skins/default/xui/en/floater_world_map.xml index 43f209546a..b179190819 100644 --- a/indra/newview/skins/default/xui/en/floater_world_map.xml +++ b/indra/newview/skins/default/xui/en/floater_world_map.xml @@ -144,7 +144,10 @@ name="Go Home" tool_tip="Teleport to your home" top="34" - width="88" /> + width="88" > + <button.commit_callback + function="WMap.GoHome" /> + </button> <icon color="0 1 0 1" follows="top|right" @@ -325,6 +328,8 @@ <combo_box.item label="Online Friends" value="None" /> + <combo_box.commit_callback + function="WMap.AvatarCombo"/> </combo_box> <icon color="0.5 0 0 1" @@ -352,6 +357,8 @@ <combo_box.item label="Landmarks" value="None" /> + <combo_box.commit_callback + function="WMap.Landmark" /> </combo_box> <icon color="0.5 0 0 1" @@ -384,7 +391,10 @@ name="DoSearch" tool_tip="Search for region" top_delta="0" - width="60" /> + width="60"> + <button.commit_callback + function="WMap.Location" /> + </button> <text type="string" length="1" @@ -415,6 +425,8 @@ label="" name="sim_name" width="206" /> + <scroll_list.commit_callback + function="WMap.SearchResult" /> </scroll_list> <text type="string" @@ -441,7 +453,10 @@ name="spin x" tool_tip="X coordinate of location to show on map" top_delta="0" - width="48" /> + width="48"> + <spinner.commit_callback + function="WMap.CommitLocation" /> + </spinner> <spinner decimal_digits="0" follows="bottom|right" @@ -454,7 +469,10 @@ name="spin y" tool_tip="Y coordinate of location to show on map" top_delta="0" - width="48" /> + width="48" > + <spinner.commit_callback + function="WMap.CommitLocation" /> + </spinner> <spinner decimal_digits="0" follows="bottom|right" @@ -467,7 +485,10 @@ name="spin z" tool_tip="Z coordinate of location to show on map" top_delta="0" - width="48" /> + width="48"> + <spinner.commit_callback + function="WMap.CommitLocation" /> + </spinner> <button follows="right|bottom" height="20" @@ -478,7 +499,10 @@ name="Teleport" tool_tip="Teleport to selected location" top="494" - width="90" /> + width="90"> + <button.commit_callback + function="WMap.Teleport" /> + </button> <button follows="right|bottom" height="20" @@ -489,7 +513,10 @@ name="Show Destination" tool_tip="Center map on selected location" top_delta="0" - width="125" /> + width="125"> + <button.commit_callback + function="WMap.ShowTarget" /> + </button> <button follows="right|bottom" height="20" @@ -500,7 +527,10 @@ name="Clear" tool_tip="Stop tracking" top="518" - width="90" /> + width="90"> + <button.commit_callback + function="WMap.Clear" /> + </button> <button follows="right|bottom" height="20" @@ -511,7 +541,10 @@ name="Show My Location" tool_tip="Center map on your avatar's location" top_delta="0" - width="125" /> + width="125" > + <button.commit_callback + function="WMap.ShowAgent" /> + </button> <button enabled="false" follows="bottom|right" @@ -522,7 +555,10 @@ name="copy_slurl" tool_tip="Copies current location as SLURL to be used on the web." top="542" - width="222" /> + width="222"> + <button.commit_callback + function="WMap.CopySLURL" /> + </button> <slider follows="right|bottom" height="16" diff --git a/indra/newview/skins/default/xui/en/menu_login.xml b/indra/newview/skins/default/xui/en/menu_login.xml index eb3dcc225e..14c38f6f26 100644 --- a/indra/newview/skins/default/xui/en/menu_login.xml +++ b/indra/newview/skins/default/xui/en/menu_login.xml @@ -101,5 +101,13 @@ function="ShowFloater" parameter="test_widgets" /> </menu_item_call> + <menu_item_call + label="List View Test" + name="List View Test" + shortcut="control|shift|L"> + <menu_item_call.on_click + function="ShowFloater" + parameter="test_list_view" /> + </menu_item_call> </menu> </menu_bar> diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 1d1a1c063e..4ce3c18dcc 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -15,9 +15,18 @@ name="Preferences" shortcut="control|P"> <menu_item_call.on_click - function="ShowFloater" + function="Floater.Show" parameter="preferences" /> </menu_item_call> + <menu_item_call + label="Media Remote Ctrl" + layout="topleft" + name="Preferences" + shortcut="control|A"> + <menu_item_call.on_click + function="Floater.Toggle" + parameter="media_remote_ctrl" /> + </menu_item_call> <menu_item_separator layout="topleft" /> <menu @@ -221,22 +230,22 @@ layout="topleft" name="Active Speakers"> <menu_item_check.on_check - function="FloaterVisible" - parameter="active speakers" /> + function="Floater.Visible" + parameter="active_speakers" /> <menu_item_check.on_click - function="ShowFloater" - parameter="active speakers" /> + function="Floater.Toggle" + parameter="active_speakers" /> </menu_item_check> <menu_item_check label="Block List" layout="topleft" name="Mute List"> <menu_item_check.on_check - function="FloaterVisible" - parameter="mute list" /> + function="Floater.Visible" + parameter="mute" /> <menu_item_check.on_click - function="ShowFloater" - parameter="mute list" /> + function="Floater.Toggle" + parameter="mute" /> </menu_item_check> </menu> <menu @@ -249,22 +258,22 @@ layout="topleft" name="Camera Controls"> <menu_item_check.on_check - function="FloaterVisible" - parameter="camera controls" /> + function="Floater.Visible" + parameter="camera" /> <menu_item_check.on_click - function="ShowFloater" - parameter="camera controls" /> + function="Floater.Toggle" + parameter="camera" /> </menu_item_check> <menu_item_check label="Movement Controls" layout="topleft" name="Movement Controls"> <menu_item_check.on_check - function="FloaterVisible" - parameter="movement controls" /> + function="Floater.Visible" + parameter="moveview" /> <menu_item_check.on_click - function="ShowFloater" - parameter="movement controls" /> + function="Floater.Toggle" + parameter="moveview" /> </menu_item_check> <menu_item_separator layout="topleft" /> @@ -273,16 +282,16 @@ layout="topleft" name="About Land"> <menu_item_call.on_click - function="ShowFloater" - parameter="about land" /> + function="Floater.Show" + parameter="about_land" /> </menu_item_call> <menu_item_call label="Region/Estate" layout="topleft" name="Region/Estate"> <menu_item_call.on_click - function="ShowFloater" - parameter="about region" /> + function="Floater.Show" + parameter="region_info" /> </menu_item_call> <menu_item_separator layout="topleft" /> @@ -350,9 +359,10 @@ name="Mini-Map" shortcut="control|shift|M"> <menu_item_check.on_check - function="FloaterVisible" /> + function="Floater.Visible" + parameter="mini_map" /> <menu_item_check.on_click - function="ShowFloater" + function="Floater.Show" parameter="mini_map" /> </menu_item_check> <menu_item_separator @@ -400,8 +410,8 @@ layout="topleft" name="Tutorial"> <menu_item_call.on_click - function="ShowFloater" - parameter="help tutorial" /> + function="Floater.Show" + parameter="hud" /> </menu_item_call> <menu label="Report" @@ -429,16 +439,16 @@ layout="topleft" name="Bumps, Pushes &amp; Hits"> <menu_item_call.on_click - function="ShowFloater" - parameter="mean events" /> + function="Floater.Show" + parameter="bumps" /> </menu_item_call> <menu_item_call label="About Second Life" layout="topleft" name="About Second Life"> <menu_item_call.on_click - function="ShowFloater" - parameter="about" /> + function="Floater.Show" + parameter="sl_about" /> </menu_item_call> </menu> </menu> @@ -573,8 +583,8 @@ layout="topleft" name="perm prefs"> <menu_item_call.on_click - function="ShowFloater" - parameter="perm prefs" /> + function="Floater.Toggle" + parameter="perm_prefs" /> </menu_item_call> <menu_item_call label="Show Script Warning/Error Window" @@ -702,8 +712,8 @@ name="Grid Options" shortcut="control|shift|B"> <menu_item_call.on_click - function="ShowFloater" - parameter="grid options" /> + function="Floater.Show" + parameter="build_options" /> <menu_item_call.on_enable function="Tools.EnableToolNotPie" /> </menu_item_call> @@ -720,10 +730,10 @@ name="beacons" shortcut="control|alt|shift|N"> <menu_item_check.on_check - function="FloaterVisible" + function="Floater.Visible" parameter="beacons" /> <menu_item_check.on_click - function="ShowFloater" + function="Floater.Toggle" parameter="beacons" /> </menu_item_check> <menu_item_check @@ -1312,8 +1322,8 @@ layout="topleft" name="Lag Meter"> <menu_item_call.on_click - function="ShowFloater" - parameter="lag meter" /> + function="Floater.Show" + parameter="lagmeter" /> </menu_item_call> <menu_item_check label="Statistics Bar" @@ -1894,8 +1904,8 @@ function="Advanced.CheckConsole" parameter="notifications" /> <menu_item_check.on_click - function="Advanced.ToggleConsole" - parameter="notifications" /> + function="Floater.Show" + parameter="notifications_console" /> </menu_item_check> <menu_item_separator layout="topleft" /> @@ -1999,8 +2009,8 @@ layout="topleft" name="Memory Leaking Simulation"> <menu_item_call.on_click - function="Advanced.MemoryLeakingSimulation" - parameter="" /> + function="Floater.Show" + parameter="mem_leaking" /> </menu_item_call> <menu_item_separator layout="topleft" /> @@ -2843,7 +2853,8 @@ layout="topleft" name="Show Font Test"> <menu_item_call.on_click - function="Advanced.ShowFontTest" /> + function="Floater.Show" + parameter="font_test" /> </menu_item_call> <menu_item_call label="Load from XML..." @@ -2869,6 +2880,13 @@ <menu_item_check.on_click function="Advanced.ToggleXUINames" /> </menu_item_check> + <menu_item_call + label="Send Test IMs" + layout="topleft" + name="Send Test IMs"> + <menu_item_call.on_click + function="Advanced.SendTestIMs" /> + </menu_item_call> </menu> <menu create_jump_keys="true" @@ -3304,7 +3322,8 @@ layout="topleft" name="God Tools"> <menu_item_call.on_click - function="Admin.ShowGodTools" /> + function="Floater.Show" + parameter="god_tools" /> <menu_item_call.on_enable function="EnableGodCustomerService" /> </menu_item_call> diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 0a63da1463..d2c0ffd13d 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -13,7 +13,7 @@ <global name="implicitclosebutton"> Close </global> - + <template name="okbutton"> <form> <button @@ -4980,347 +4980,347 @@ The string [STRING_NAME] is missing from strings.xml icon="notifytip.tga" name="SystemMessageTip" type="notifytip"> -[MESSAGE] + [MESSAGE] </notification> <notification icon="notifytip.tga" name="Cancelled" type="notifytip"> -Cancelled + Cancelled </notification> <notification icon="notifytip.tga" name="CancelledSit" type="notifytip"> -Cancelled Sit + Cancelled Sit </notification> <notification icon="notifytip.tga" name="CancelledAttach" type="notifytip"> -Cancelled Attach + Cancelled Attach </notification> <notification icon="notifytip.tga" name="ReplacedMissingWearable" type="notifytip"> -Replaced missing clothing/body part with default. + Replaced missing clothing/body part with default. </notification> <notification icon="groupnotify" name="GroupNotice" type="groupnotify"> -Topic: [SUBJECT], Message: [MESSAGE] + Topic: [SUBJECT], Message: [MESSAGE] </notification> <notification icon="notifytip.tga" name="FriendOnline" type="notifytip"> -[FIRST] [LAST] is Online + [FIRST] [LAST] is Online </notification> <notification icon="notifytip.tga" name="FriendOffline" type="notifytip"> -[FIRST] [LAST] is Offline + [FIRST] [LAST] is Offline </notification> <notification icon="notifytip.tga" name="AddSelfFriend" type="notifytip"> -You cannot add yourself as a friend. + You cannot add yourself as a friend. </notification> <notification icon="notifytip.tga" name="UploadingAuctionSnapshot" type="notifytip"> -Uploading in-world and web site snapshots... -(Takes about 5 minutes.) + Uploading in-world and web site snapshots... + (Takes about 5 minutes.) </notification> <notification icon="notify.tga" name="UploadPayment" type="notify"> -You paid L$[AMOUNT] to upload. + You paid L$[AMOUNT] to upload. </notification> <notification icon="notifytip.tga" name="UploadWebSnapshotDone" type="notifytip"> -Web site snapshot upload done. + Web site snapshot upload done. </notification> <notification icon="notifytip.tga" name="UploadSnapshotDone" type="notifytip"> -In-world snapshot upload done + In-world snapshot upload done </notification> <notification icon="notifytip.tga" name="TerrainDownloaded" type="notifytip"> -Terrain.raw downloaded + Terrain.raw downloaded </notification> <notification icon="notifytip.tga" name="GestureMissing" type="notifytip"> -Gesture [NAME] is missing from database. + Gesture [NAME] is missing from database. </notification> <notification icon="notifytip.tga" name="UnableToLoadGesture" type="notifytip"> -Unable to load gesture [NAME]. -Please try again. + Unable to load gesture [NAME]. + Please try again. </notification> <notification icon="notifytip.tga" name="LandmarkMissing" type="notifytip"> -Landmark is missing from database. + Landmark is missing from database. </notification> <notification icon="notifytip.tga" name="UnableToLoadLandmark" type="notifytip"> -Unable to load landmark. Please try again. + Unable to load landmark. Please try again. </notification> <notification icon="notifytip.tga" name="CapsKeyOn" type="notifytip"> -Your Caps Lock key is on. -As this will affect the password you type in, you will probably want to turn it off. + Your Caps Lock key is on. + As this will affect the password you type in, you will probably want to turn it off. </notification> <notification icon="notifytip.tga" name="NotecardMissing" type="notifytip"> -Notecard is missing from database. + Notecard is missing from database. </notification> <notification icon="notifytip.tga" name="NotecardNoPermissions" type="notifytip"> -Insufficient permissions to view notecard. + Insufficient permissions to view notecard. </notification> <notification icon="notifytip.tga" name="RezItemNoPermissions" type="notifytip"> -Insufficient permissions to rez object. + Insufficient permissions to rez object. </notification> <notification icon="notifytip.tga" name="UnableToLoadNotecard" type="notifytip"> -Unable to load notecard. -Please try again. + Unable to load notecard. + Please try again. </notification> <notification icon="notifytip.tga" name="ScriptMissing" type="notifytip"> -Script is missing from database. + Script is missing from database. </notification> <notification icon="notifytip.tga" name="ScriptNoPermissions" type="notifytip"> -Insufficient permissions to view script. + Insufficient permissions to view script. </notification> <notification icon="notifytip.tga" name="UnableToLoadScript" type="notifytip"> -Unable to load script. Please try again. + Unable to load script. Please try again. </notification> <notification icon="notifytip.tga" name="IncompleteInventory" type="notifytip"> -The complete contents you are offering are not yet locally available. Please try offering those items again in a minute. + The complete contents you are offering are not yet locally available. Please try offering those items again in a minute. </notification> <notification icon="notifytip.tga" name="CannotModifyProtectedCategories" type="notifytip"> -You cannot modify protected categories. + You cannot modify protected categories. </notification> <notification icon="notifytip.tga" name="CannotRemoveProtectedCategories" type="notifytip"> -You cannot remove protected categories. + You cannot remove protected categories. </notification> <notification icon="notifytip.tga" name="OfferedCard" type="notifytip"> -You have offered a calling card to [FIRST] [LAST] + You have offered a calling card to [FIRST] [LAST] </notification> <notification icon="notifytip.tga" name="UnableToBuyWhileDownloading" type="notifytip"> -Unable to buy while downloading object data. -Please try again. + Unable to buy while downloading object data. + Please try again. </notification> <notification icon="notifytip.tga" name="UnableToLinkWhileDownloading" type="notifytip"> -Unable to link while downloading object data. -Please try again. + Unable to link while downloading object data. + Please try again. </notification> <notification icon="notifytip.tga" name="CannotBuyObjectsFromDifferentOwners" type="notifytip"> -Cannot buy objects from different owners at the same time. -Please select a single object. + Cannot buy objects from different owners at the same time. + Please select a single object. </notification> <notification icon="notifytip.tga" name="ObjectNotForSale" type="notifytip"> -Object does not appear to be for sale. + Object does not appear to be for sale. </notification> <notification icon="notifytip.tga" name="EnteringGodMode" type="notifytip"> -Entering god mode, level [LEVEL] + Entering god mode, level [LEVEL] </notification> <notification icon="notifytip.tga" name="LeavingGodMode" type="notifytip"> -Leaving god mode, level [LEVEL] + Leaving god mode, level [LEVEL] </notification> <notification icon="notifytip.tga" name="CopyFailed" type="notifytip"> -Copy failed because you lack copy permission + Copy failed because you lack copy permission </notification> <notification icon="notifytip.tga" name="InventoryAccepted" type="notifytip"> -[NAME] accepted your inventory offer. + [NAME] accepted your inventory offer. </notification> <notification icon="notifytip.tga" name="InventoryDeclined" type="notifytip"> -[NAME] declined your inventory offer. + [NAME] declined your inventory offer. </notification> <notification icon="notifytip.tga" name="ObjectMessage" type="notifytip"> -[NAME]: [MESSAGE] + [NAME]: [MESSAGE] </notification> <notification icon="notifytip.tga" name="CallingCardAccepted" type="notifytip"> -Your calling card was accepted. + Your calling card was accepted. </notification> <notification icon="notifytip.tga" name="CallingCardDeclined" type="notifytip"> -Your calling card was declined. + Your calling card was declined. </notification> <notification icon="notifytip.tga" name="TeleportToLandmark" type="notifytip"> -Now that you have reached the mainland, you can teleport to locations like '[NAME]' by clicking on the Inventory button on the bottom right of your screen, and then select the Landmarks folder. -Double click on the landmark and click on Teleport to travel there. + Now that you have reached the mainland, you can teleport to locations like '[NAME]' by clicking on the Inventory button on the bottom right of your screen, and then select the Landmarks folder. + Double click on the landmark and click on Teleport to travel there. </notification> <notification icon="notifytip.tga" name="TeleportToPerson" type="notifytip"> -Now that you have reached the mainland, you can contact residents like '[NAME]' by clicking on the Inventory button on the bottom right of your screen, and then select the Calling Cards folder. -Double click on the card, click on Instant Message, and type a message. + Now that you have reached the mainland, you can contact residents like '[NAME]' by clicking on the Inventory button on the bottom right of your screen, and then select the Calling Cards folder. + Double click on the card, click on Instant Message, and type a message. </notification> <notification icon="notifytip.tga" name="CantSelectLandFromMultipleRegions" type="notifytip"> -Can't select land across server boundaries. -Try selecting a smaller piece of land. + Can't select land across server boundaries. + Try selecting a smaller piece of land. </notification> <notification icon="notifytip.tga" name="SearchWordBanned" type="notifytip"> -Some terms in your search query were excluded due to content restrictions as clarified in the Community Standards. + Some terms in your search query were excluded due to content restrictions as clarified in the Community Standards. </notification> <notification icon="notifytip.tga" name="NoContentToSearch" type="notifytip"> -Please select at least one type of content to search (PG, Mature, or Adult). + Please select at least one type of content to search (PG, Mature, or Adult). </notification> <notification icon="notify.tga" name="GroupVote" type="notify"> -[NAME] has proposed to vote on: -[MESSAGE] + [NAME] has proposed to vote on: + [MESSAGE] <form name="form"> <button index="0" @@ -5337,17 +5337,17 @@ Please select at least one type of content to search (PG, Mature, or Adult). icon="notify.tga" name="SystemMessage" type="notify"> -[MESSAGE] + [MESSAGE] </notification> <notification icon="notify.tga" name="EventNotification" type="notify"> -Event Notification: + Event Notification: -[NAME] -[DATE] + [NAME] + [DATE] <form name="form"> <button index="0" @@ -5368,9 +5368,9 @@ Event Notification: icon="notify.tga" name="TransferObjectsHighlighted" type="notify"> -All objects on this parcel that will transfer to the purchaser of this parcel are now highlighted. + All objects on this parcel that will transfer to the purchaser of this parcel are now highlighted. -* Trees and grasses that will transfer are not highlighted. + * Trees and grasses that will transfer are not highlighted. <form name="form"> <button index="0" @@ -5383,61 +5383,61 @@ All objects on this parcel that will transfer to the purchaser of this parcel ar icon="notify.tga" name="DeactivatedGesturesTrigger" type="notify"> -Deactivated gestures with same trigger: -[NAMES] + Deactivated gestures with same trigger: + [NAMES] </notification> <notification icon="notify.tga" name="NoQuickTime" type="notify"> -Apple's QuickTime software does not appear to be installed on your system. -If you want to view streaming media on parcels that support it you should go to the QuickTime site (http://www.apple.com/quicktime) and install the QuickTime Player. + Apple's QuickTime software does not appear to be installed on your system. + If you want to view streaming media on parcels that support it you should go to the QuickTime site (http://www.apple.com/quicktime) and install the QuickTime Player. </notification> <notification icon="notify.tga" name="OwnedObjectsReturned" type="notify"> -The objects you own on the selected parcel of land have been returned back to your inventory. + The objects you own on the selected parcel of land have been returned back to your inventory. </notification> <notification icon="notify.tga" name="OtherObjectsReturned" type="notify"> -The objects on the selected parcel of land that is owned by [FIRST] [LAST] have been returned to his or her inventory. + The objects on the selected parcel of land that is owned by [FIRST] [LAST] have been returned to his or her inventory. </notification> <notification icon="notify.tga" name="OtherObjectsReturned2" type="notify"> -The objects on the selected parcel of land owned by the resident '[NAME]' have been returned to their owner. + The objects on the selected parcel of land owned by the resident '[NAME]' have been returned to their owner. </notification> <notification icon="notify.tga" name="GroupObjectsReturned" type="notify"> -The objects on the selected parcel of land shared with the group [GROUPNAME] have been returned back to their owner's inventory. -Transferable deeded objects have been returned to their previous owners. -Non-transferable objects that are deeded to the group have been deleted. + The objects on the selected parcel of land shared with the group [GROUPNAME] have been returned back to their owner's inventory. + Transferable deeded objects have been returned to their previous owners. + Non-transferable objects that are deeded to the group have been deleted. </notification> <notification icon="notify.tga" name="UnOwnedObjectsReturned" type="notify"> -The objects on the selected parcel that are NOT owned by you have been returned to their owners. + The objects on the selected parcel that are NOT owned by you have been returned to their owners. </notification> <notification icon="notify.tga" name="NotSafe" type="notify"> -This land has damage enabled ('not safe'). -You can be hurt here. If you die, you will be teleported to your home location. + This land has damage enabled ('not safe'). + You can be hurt here. If you die, you will be teleported to your home location. <unique/> </notification> @@ -5445,8 +5445,8 @@ You can be hurt here. If you die, you will be teleported to your home location. icon="notify.tga" name="NoFly" type="notify"> -This land has flying disabled ('no fly'). -You cannot fly here. + This land has flying disabled ('no fly'). + You cannot fly here. <unique/> </notification> @@ -5454,8 +5454,8 @@ You cannot fly here. icon="notify.tga" name="PushRestricted" type="notify"> -This land is 'No Pushing'. -You cannot push others here unless you own the land. + This land is 'No Pushing'. + You cannot push others here unless you own the land. <unique/> </notification> @@ -5463,7 +5463,7 @@ You cannot push others here unless you own the land. icon="notify.tga" name="NoVoice" type="notify"> -This land has voice disabled. + This land has voice disabled. <unique/> </notification> @@ -5471,8 +5471,8 @@ This land has voice disabled. icon="notify.tga" name="NoBuild" type="notify"> -This land has building disabled ('no build'). -You cannot create objects here. + This land has building disabled ('no build'). + You cannot create objects here. <unique/> </notification> @@ -5480,222 +5480,222 @@ You cannot create objects here. icon="notify.tga" name="ScriptsStopped" type="notify"> -An administrator has temporarily stopped scripts in this region. + An administrator has temporarily stopped scripts in this region. </notification> <notification icon="notify.tga" name="ScriptsNotRunning" type="notify"> -This region is not running any scripts. + This region is not running any scripts. </notification> <notification icon="notify.tga" name="NoOutsideScripts" type="notify"> -This land has outside scripts disabled ('no outside scripts'). -No scripts will run except those belonging to the land owner. + This land has outside scripts disabled ('no outside scripts'). + No scripts will run except those belonging to the land owner. </notification> <notification icon="notify.tga" name="ClaimPublicLand" type="notify"> -Can only claim public land in region you're in. + Can only claim public land in region you're in. </notification> <notification icon="notify.tga" name="RegionTPAccessBlocked" type="notify"> -You aren't allowed in that Region due to your maturity Rating. You may need to validate your age and/or install the latest Viewer. + You aren't allowed in that Region due to your maturity Rating. You may need to validate your age and/or install the latest Viewer. -Please go to the Knowledge Base for details on accessing areas with this maturity Rating. + Please go to the Knowledge Base for details on accessing areas with this maturity Rating. </notification> <notification icon="notify.tga" name="URBannedFromRegion" type="notify"> -You are banned from the region. + You are banned from the region. </notification> <notification icon="notify.tga" name="NoTeenGridAccess" type="notify"> -Your account cannot connect to this teen grid region. + Your account cannot connect to this teen grid region. </notification> <notification icon="notify.tga" name="NoHelpIslandTP" type="notify"> -You cannot teleport back to Help Island. -Go to 'Help Island Public' to repeat the tutorial. + You cannot teleport back to Help Island. + Go to 'Help Island Public' to repeat the tutorial. </notification> <notification icon="notify.tga" name="ImproperPaymentStatus" type="notify"> -You do not have proper payment status to enter this region. + You do not have proper payment status to enter this region. </notification> <notification icon="notify.tga" name="MustGetAgeRgion" type="notify"> -You must be age-verified to enter this region. + You must be age-verified to enter this region. </notification> <notification icon="notify.tga" name="MustGetAgeParcel" type="notify"> -You must be age-verified to enter this parcel. + You must be age-verified to enter this parcel. </notification> <notification icon="notify.tga" name="NoDestRegion" type="notify"> -No destination region found. + No destination region found. </notification> <notification icon="notify.tga" name="NotAllowedInDest" type="notify"> -You are not allowed into the destination. + You are not allowed into the destination. </notification> <notification icon="notify.tga" name="RegionParcelBan" type="notify"> -Cannot region cross into banned parcel. Try another way. + Cannot region cross into banned parcel. Try another way. </notification> <notification icon="notify.tga" name="TelehubRedirect" type="notify"> -You have been redirected to a telehub. + You have been redirected to a telehub. </notification> <notification icon="notify.tga" name="CouldntTPCloser" type="notify"> -Could not teleport closer to destination. + Could not teleport closer to destination. </notification> <notification icon="notify.tga" name="TPCancelled" type="notify"> - Teleport cancelled. + Teleport cancelled. </notification> <notification icon="notify.tga" name="FullRegionTryAgain" type="notify"> -The region you are attempting to enter is currently full. -Please try again in a few moments. + The region you are attempting to enter is currently full. + Please try again in a few moments. </notification> <notification icon="notify.tga" name="GeneralFailure" type="notify"> -General failure. + General failure. </notification> <notification icon="notify.tga" name="RoutedWrongRegion" type="notify"> -Routed to wrong region. Please try again. + Routed to wrong region. Please try again. </notification> <notification icon="notify.tga" name="NoValidAgentID" type="notify"> -No valid agent id. + No valid agent id. </notification> <notification icon="notify.tga" name="NoValidSession" type="notify"> -No valid session id. + No valid session id. </notification> <notification icon="notify.tga" name="NoValidCircuit" type="notify"> -No valid circuit code. + No valid circuit code. </notification> <notification icon="notify.tga" name="NoValidTimestamp" type="notify"> -No valid timestamp. + No valid timestamp. </notification> <notification icon="notify.tga" name="NoPendingConnection" type="notify"> -Unable to create pending connection. + Unable to create pending connection. </notification> <notification icon="notify.tga" name="InternalUsherError" type="notify"> -Internal error attempting to connect agent usher. + Internal error attempting to connect agent usher. </notification> <notification icon="notify.tga" name="NoGoodTPDestination" type="notify"> -Unable to find a good teleport destination in this region. + Unable to find a good teleport destination in this region. </notification> <notification icon="notify.tga" name="InternalErrorRegionResolver" type="notify"> -Internal error attempting to activate region resolver. + Internal error attempting to activate region resolver. </notification> <notification icon="notify.tga" name="NoValidLanding" type="notify"> -A valid landing point could not be found. + A valid landing point could not be found. </notification> <notification icon="notify.tga" name="NoValidParcel" type="notify"> -No valid parcel could be found. + No valid parcel could be found. </notification> <notification icon="notify.tga" name="ObjectGiveItem" type="notify"> -An object named [OBJECTFROMNAME] owned by [FIRST] [LAST] has given you a [OBJECTTYPE] named [OBJECTNAME]. + An object named [OBJECTFROMNAME] owned by [FIRST] [LAST] has given you a [OBJECTTYPE] named [OBJECTNAME]. <form name="form"> <button index="0" @@ -5716,7 +5716,7 @@ An object named [OBJECTFROMNAME] owned by [FIRST] [LAST] has given you a [OBJECT icon="notify.tga" name="ObjectGiveItemUnknownUser" type="notify"> -An object named [OBJECTFROMNAME] owned by (an unknown user) has given you a [OBJECTTYPE] named [OBJECTNAME]. + An object named [OBJECTFROMNAME] owned by (an unknown user) has given you a [OBJECTTYPE] named [OBJECTNAME]. <form name="form"> <button index="0" @@ -5737,7 +5737,7 @@ An object named [OBJECTFROMNAME] owned by (an unknown user) has given you a [OBJ icon="notify.tga" name="UserGiveItem" type="notify"> -[NAME] has given you a [OBJECTTYPE] named '[OBJECTNAME]'. + [NAME] has given you a [OBJECTTYPE] named '[OBJECTNAME]'. <form name="form"> <button index="0" @@ -5758,15 +5758,15 @@ An object named [OBJECTFROMNAME] owned by (an unknown user) has given you a [OBJ icon="notify.tga" name="GodMessage" type="notify"> -[NAME] -[MESSAGE] + [NAME] + [MESSAGE] </notification> <notification icon="notify.tga" name="JoinGroup" type="notify"> -[MESSAGE] + [MESSAGE] <form name="form"> <button index="0" @@ -5787,9 +5787,9 @@ An object named [OBJECTFROMNAME] owned by (an unknown user) has given you a [OBJ icon="notify.tga" name="TeleportOffered" type="notify"> -[NAME] has offered to teleport you to his or her location: + [NAME] has offered to teleport you to his or her location: -[MESSAGE] + [MESSAGE] <form name="form"> <button index="0" @@ -5806,8 +5806,8 @@ An object named [OBJECTFROMNAME] owned by (an unknown user) has given you a [OBJ icon="notify.tga" name="GotoURL" type="notify"> -[MESSAGE] -[URL] + [MESSAGE] + [URL] <form name="form"> <button index="0" @@ -5824,11 +5824,11 @@ An object named [OBJECTFROMNAME] owned by (an unknown user) has given you a [OBJ icon="notify.tga" name="OfferFriendship" type="notify"> -[NAME] is offering friendship. + [NAME] is offering friendship. -[MESSAGE] + [MESSAGE] -(By default, you will be able to see each other's online status.) + (By default, you will be able to see each other's online status.) <form name="form"> <button index="0" @@ -5845,9 +5845,9 @@ An object named [OBJECTFROMNAME] owned by (an unknown user) has given you a [OBJ icon="notify.tga" name="OfferFriendshipNoMessage" type="notify"> -[NAME] is offering friendship. + [NAME] is offering friendship. -(By default, you will be able to see each other's online status.) + (By default, you will be able to see each other's online status.) <form name="form"> <button index="0" @@ -5864,22 +5864,22 @@ An object named [OBJECTFROMNAME] owned by (an unknown user) has given you a [OBJ icon="notify.tga" name="FriendshipAccepted" type="notify"> -[NAME] accepted your friendship offer. + [NAME] accepted your friendship offer. </notification> <notification icon="notify.tga" name="FriendshipDeclined" type="notify"> -[NAME] declined your friendship offer. + [NAME] declined your friendship offer. </notification> <notification icon="notify.tga" name="OfferCallingCard" type="notify"> -[FIRST] [LAST] is offering their calling card. -This will add a bookmark in your inventory so you can quickly IM this resident. + [FIRST] [LAST] is offering their calling card. + This will add a bookmark in your inventory so you can quickly IM this resident. <form name="form"> <button index="0" @@ -5898,8 +5898,8 @@ This will add a bookmark in your inventory so you can quickly IM this resident. priority="high" sound="UISndAlert" type="notify"> -Region is restarting in [MINUTES] minutes. -If you remain in this region you will be logged out. + Region is restarting in [MINUTES] minutes. + If you remain in this region you will be logged out. </notification> <notification @@ -5908,19 +5908,19 @@ If you remain in this region you will be logged out. priority="high" sound="UISndAlert" type="notify"> -Region is restarting in [SECONDS] seconds. -If you remain in this region you will be logged out. + Region is restarting in [SECONDS] seconds. + If you remain in this region you will be logged out. </notification> <notification icon="notify.tga" name="LoadWebPage" type="notify"> -Load web page [URL]? + Load web page [URL]? -[MESSAGE] + [MESSAGE] -From object: [OBJECTNAME], owner: [NAME]? + From object: [OBJECTNAME], owner: [NAME]? <form name="form"> <button index="0" @@ -5937,14 +5937,14 @@ From object: [OBJECTNAME], owner: [NAME]? icon="notify.tga" name="FailedToFindWearableUnnamed" type="notify"> -Failed to find [TYPE] in database. + Failed to find [TYPE] in database. </notification> <notification icon="notify.tga" name="FailedToFindWearable" type="notify"> -Failed to find [TYPE] named [DESC] in database. + Failed to find [TYPE] named [DESC] in database. </notification> <notification @@ -5958,10 +5958,10 @@ Failed to find [TYPE] named [DESC] in database. icon="notify.tga" name="ScriptQuestion" type="notify"> -'[OBJECTNAME]', an object owned by '[NAME]', would like to: + '[OBJECTNAME]', an object owned by '[NAME]', would like to: -[QUESTIONS] -Is this OK? + [QUESTIONS] + Is this OK? <form name="form"> <button index="0" @@ -5983,12 +5983,12 @@ Is this OK? name="ScriptQuestionCaution" priority="high" type="notify"> -'[OBJECTNAME]', an object owned by '[NAME]', would like to: + '[OBJECTNAME]', an object owned by '[NAME]', would like to: -[QUESTIONS] -If you do not trust this object and its creator, you should deny the request. For additional information, click the Details button. + [QUESTIONS] + If you do not trust this object and its creator, you should deny the request. For additional information, click the Details button. -Grant this request? + Grant this request? <form name="form"> <button index="0" @@ -6010,8 +6010,8 @@ Grant this request? icon="notify.tga" name="ScriptDialog" type="notify"> -[FIRST] [LAST]'s '[TITLE]' -[MESSAGE] + [FIRST] [LAST]'s '[TITLE]' + [MESSAGE] <form name="form"> <button index="-1" @@ -6024,8 +6024,8 @@ Grant this request? icon="notify.tga" name="ScriptDialogGroup" type="notify"> -[GROUPNAME]'s '[TITLE]' -[MESSAGE] + [GROUPNAME]'s '[TITLE]' + [MESSAGE] <form name="form"> <button index="-1" @@ -6038,142 +6038,142 @@ Grant this request? icon="notify.tga" name="FirstBalanceIncrease" type="notify"> -You just received L$[AMOUNT]. -Objects and other users may give you L$. -Your balance is shown in the upper-right corner of the screen. + You just received L$[AMOUNT]. + Objects and other users may give you L$. + Your balance is shown in the upper-right corner of the screen. </notification> <notification icon="notify.tga" name="FirstBalanceDecrease" type="notify"> -You just paid L$[AMOUNT]. -Your balance is shown in the upper-right corner of the screen. + You just paid L$[AMOUNT]. + Your balance is shown in the upper-right corner of the screen. </notification> <notification icon="notify.tga" name="FirstSit" type="notify"> -You are sitting. -Use the arrow keys (or AWSD) to change the view. -Click the 'Stand Up' button to get up. + You are sitting. + Use the arrow keys (or AWSD) to change the view. + Click the 'Stand Up' button to get up. </notification> <notification icon="notify.tga" name="FirstMap" type="notify"> -Click and drag to scroll the map. -Double-click to teleport. -Use the controls on the right to find things and display different backgrounds. + Click and drag to scroll the map. + Double-click to teleport. + Use the controls on the right to find things and display different backgrounds. </notification> <notification icon="notify.tga" name="FirstBuild" type="notify"> -You can build new objects in some areas of [SECOND_LIFE]. -Use the tools in the upper left to build, and try holding down Ctrl or Alt to rapidly switch tools. -Press Esc to stop building. + You can build new objects in some areas of [SECOND_LIFE]. + Use the tools in the upper left to build, and try holding down Ctrl or Alt to rapidly switch tools. + Press Esc to stop building. </notification> <notification icon="notify.tga" name="FirstLeftClickNoHit" type="notify"> -Left-clicking interacts with special objects. -If the mouse pointer changes to a hand, you can interact with the object. -Right-click always shows a menu of things you can do. + Left-clicking interacts with special objects. + If the mouse pointer changes to a hand, you can interact with the object. + Right-click always shows a menu of things you can do. </notification> <notification icon="notify.tga" name="FirstTeleport" type="notify"> -This region doesn't allow point-to-point teleports, so you've been transported to the nearest telehub. -Your destination is marked with a tall beacon. -Follow the red arrow to the beacon, or click the arrow to dismiss the beacon. + This region doesn't allow point-to-point teleports, so you've been transported to the nearest telehub. + Your destination is marked with a tall beacon. + Follow the red arrow to the beacon, or click the arrow to dismiss the beacon. </notification> <notification icon="notify.tga" name="FirstOverrideKeys" type="notify"> -Your movement keys are now being handled by an object. -Try the arrow keys or AWSD to see what they do. -Some objects (like guns) require you to go into mouselook to use them. -Press 'M' to do this. + Your movement keys are now being handled by an object. + Try the arrow keys or AWSD to see what they do. + Some objects (like guns) require you to go into mouselook to use them. + Press 'M' to do this. </notification> <notification icon="notify.tga" name="FirstAppearance" type="notify"> -You are editing your appearance. -To rotate and zoom view, use the arrow keys. -When you are finished, press 'Save All' to save your look and exit. -You can edit your appearance as often as you like. + You are editing your appearance. + To rotate and zoom view, use the arrow keys. + When you are finished, press 'Save All' to save your look and exit. + You can edit your appearance as often as you like. </notification> <notification icon="notify.tga" name="FirstInventory" type="notify"> -This is your inventory, which contains objects, notecards, clothing, and other things you own. -* To wear an object or outfit folder, drag it onto yourself. -* To bring an object into the world, drag it onto the ground. -* To read a notecard, double-click it. + This is your inventory, which contains objects, notecards, clothing, and other things you own. + * To wear an object or outfit folder, drag it onto yourself. + * To bring an object into the world, drag it onto the ground. + * To read a notecard, double-click it. </notification> <notification icon="notify.tga" name="FirstSandbox" type="notify"> -This is a sandbox region. -Objects you build here may be deleted after you leave the area, Sandboxes clean on a regular basis, please refer to the information at the top of the screen next to the region name. + This is a sandbox region. + Objects you build here may be deleted after you leave the area, Sandboxes clean on a regular basis, please refer to the information at the top of the screen next to the region name. -Sandbox regions are uncommon, and are marked with signs. + Sandbox regions are uncommon, and are marked with signs. </notification> <notification icon="notify.tga" name="FirstFlexible" type="notify"> -This object is flexible. -Flexible objects may not be physical and must be phantom until the flexible checkbox is unchecked. + This object is flexible. + Flexible objects may not be physical and must be phantom until the flexible checkbox is unchecked. </notification> <notification icon="notify.tga" name="FirstDebugMenus" type="notify"> -You have enabled the Advanced menu. -This menu contains features useful for developers debugging Second Life. -To toggle this menu on Windows press Ctrl-Alt-D. On Mac press Cmd-Opt-Shift-D. + You have enabled the Advanced menu. + This menu contains features useful for developers debugging Second Life. + To toggle this menu on Windows press Ctrl-Alt-D. On Mac press Cmd-Opt-Shift-D. </notification> <notification icon="notify.tga" name="FirstSculptedPrim" type="notify"> -You are editing a sculpted prim. -Sculpted prims require a special texture to specify their shape. -You can find example sculpted textures in the inventory library. + You are editing a sculpted prim. + Sculpted prims require a special texture to specify their shape. + You can find example sculpted textures in the inventory library. </notification> <notification icon="notify.tga" name="FirstMedia" type="notify"> -You have begun playing media. Media can set to play automatically in the preferences window under Audio / Video. Note that this can be a security risk for media sites you do not trust. + You have begun playing media. Media can set to play automatically in the preferences window under Audio / Video. Note that this can be a security risk for media sites you do not trust. </notification> <notification icon="notifytip.tga" name="MaxListSelectMessage" type="notifytip"> -You may only select up to [MAX_SELECT] items from this list. + You may only select up to [MAX_SELECT] items from this list. </notification> <notification @@ -6302,7 +6302,7 @@ Click Accept to join the chat or Decline to decline the invitation. Click Block icon="notifytip.tga" name="VoiceChannelFull" type="notifytip"> -The voice call you are trying to join, [VOICE_CHANNEL_NAME], has reached maximum capacity. Please try again later. + The voice call you are trying to join, [VOICE_CHANNEL_NAME], has reached maximum capacity. Please try again later. <unique> <context key="VOICE_CHANNEL_NAME"/> </unique> @@ -6312,7 +6312,7 @@ The voice call you are trying to join, [VOICE_CHANNEL_NAME], has reached maximum icon="notifytip.tga" name="ProximalVoiceChannelFull" type="notifytip"> -We're sorry. This area has reached maximum capacity for voice conversations. Please try to use voice in another area. + We're sorry. This area has reached maximum capacity for voice conversations. Please try to use voice in another area. <unique/> </notification> @@ -6320,7 +6320,7 @@ We're sorry. This area has reached maximum capacity for voice conversation icon="notifytip.tga" name="VoiceChannelDisconnected" type="notifytip"> -You have been disconnected from [VOICE_CHANNEL_NAME]. You will now be reconnected to spatial voice chat. + You have been disconnected from [VOICE_CHANNEL_NAME]. You will now be reconnected to spatial voice chat. <unique> <context key="VOICE_CHANNEL_NAME"/> </unique> @@ -6330,7 +6330,7 @@ You have been disconnected from [VOICE_CHANNEL_NAME]. You will now be reconnect icon="notifytip.tga" name="VoiceChannelDisconnectedP2P" type="notifytip"> -[VOICE_CHANNEL_NAME] has ended the call. You will now be reconnected to spatial voice chat. + [VOICE_CHANNEL_NAME] has ended the call. You will now be reconnected to spatial voice chat. <unique> <context key="VOICE_CHANNEL_NAME"/> </unique> @@ -6340,7 +6340,7 @@ You have been disconnected from [VOICE_CHANNEL_NAME]. You will now be reconnect icon="notifytip.tga" name="P2PCallDeclined" type="notifytip"> -[VOICE_CHANNEL_NAME] has declined your call. You will now be reconnected to spatial voice chat. + [VOICE_CHANNEL_NAME] has declined your call. You will now be reconnected to spatial voice chat. <unique> <context key="VOICE_CHANNEL_NAME"/> </unique> @@ -6350,7 +6350,7 @@ You have been disconnected from [VOICE_CHANNEL_NAME]. You will now be reconnect icon="notifytip.tga" name="P2PCallNoAnswer" type="notifytip"> -[VOICE_CHANNEL_NAME] is not available to take your call. You will now be reconnected to spatial voice chat. + [VOICE_CHANNEL_NAME] is not available to take your call. You will now be reconnected to spatial voice chat. <unique> <context key="VOICE_CHANNEL_NAME"/> </unique> @@ -6360,7 +6360,7 @@ You have been disconnected from [VOICE_CHANNEL_NAME]. You will now be reconnect icon="notifytip.tga" name="VoiceChannelJoinFailed" type="notifytip"> -Failed to connect to [VOICE_CHANNEL_NAME], please try again later. You will now be reconnected to spatial voice chat. + Failed to connect to [VOICE_CHANNEL_NAME], please try again later. You will now be reconnected to spatial voice chat. <unique> <context key="VOICE_CHANNEL_NAME"/> </unique> @@ -6371,7 +6371,7 @@ Failed to connect to [VOICE_CHANNEL_NAME], please try again later. You will now icon="notifytip.tga" name="VoiceLoginRetry" type="notifytip"> -We are creating a voice channel for you. This may take up to one minute. + We are creating a voice channel for you. This may take up to one minute. <unique/> </notification> @@ -6379,28 +6379,28 @@ We are creating a voice channel for you. This may take up to one minute. icon="notifytip.tga" name="Cannot enter parcel: not a group member" type="notifytip"> -Cannot enter parcel, you are not a member of the appropriate group. + Cannot enter parcel, you are not a member of the appropriate group. </notification> <notification icon="notifytip.tga" name="Cannot enter parcel: banned" type="notifytip"> -Cannot enter parcel, you have been banned. + Cannot enter parcel, you have been banned. </notification> <notification icon="notifytip.tga" name="Cannot enter parcel: not on access list" type="notifytip"> -Cannot enter parcel, you are not on the access list. + Cannot enter parcel, you are not on the access list. </notification> <notification icon="notifytip.tga" name="VoiceNotAllowed" type="notifytip"> -You do not have permission to connect to voice chat for [VOICE_CHANNEL_NAME]. + You do not have permission to connect to voice chat for [VOICE_CHANNEL_NAME]. <unique> <context key="VOICE_CHANNEL_NAME"/> </unique> @@ -6410,7 +6410,7 @@ You do not have permission to connect to voice chat for [VOICE_CHANNEL_NAME]. icon="notifytip.tga" name="VoiceCallGenericError" type="notifytip"> -An error has occurred while trying to connect to voice chat for [VOICE_CHANNEL_NAME]. Please try again later. + An error has occurred while trying to connect to voice chat for [VOICE_CHANNEL_NAME]. Please try again later. <unique> <context key="VOICE_CHANNEL_NAME"/> </unique> @@ -6422,7 +6422,7 @@ An error has occurred while trying to connect to voice chat for [VOICE_CHANNEL_N name="ServerVersionChanged" priority="high" type="notifytip"> -The region you have entered is running a different simulator version. Click this message for details. + The region you have entered is running a different simulator version. Click this message for details. </notification> <notification @@ -6430,7 +6430,14 @@ The region you have entered is running a different simulator version. Click this name="UnableToOpenCommandURL" priority="high" type="notifytip"> -The URL you clicked cannot be opened from this web browser. + The URL you clicked cannot be opened from this web browser. + </notification> + + <notification name="IMToast" type="notify"> + [MESSAGE] + <form name="form"> + <button index="0" name="respondbutton" text="Respond"/> + </form> </notification> <global name="UnsupportedCPU"> diff --git a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml index 7b802fb5b3..61ba76aa28 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml @@ -40,7 +40,7 @@ width="100"> </check_box> <combo_box - make_visible_control="WindowFullScreen" + visiblity_control="WindowFullScreen" allow_text_entry="true" height="16" layout="topleft" @@ -208,7 +208,7 @@ Ultra </text> <panel - make_visible_control="ShowAdvancedGraphicsSettings" + visiblity_control="ShowAdvancedGraphicsSettings" border="false" follows="top|left" height="260" diff --git a/indra/newview/skins/default/xui/en/panel_region_general.xml b/indra/newview/skins/default/xui/en/panel_region_general.xml index 90cc209a68..8ea1a05e97 100644 --- a/indra/newview/skins/default/xui/en/panel_region_general.xml +++ b/indra/newview/skins/default/xui/en/panel_region_general.xml @@ -310,7 +310,10 @@ left="108" name="apply_btn" top="320" - width="100" /> + width="100"> + <button.commit_callback + function="RegionInfo.Cancel" /> + </button> <button follows="left|top" height="20" diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index c21c691680..e8027b1b4b 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -341,36 +341,39 @@ You do not have a copy of this texture in your inventory </string> - <string name="no_transfer"> (no transfer)</string> - <string name="no_modify"> (no modify)</string> - <string name="no_copy"> (no copy)</string> - <string name="worn"> (worn)</string> + <!-- use value="" because they have preceding spaces --> + <string name="no_transfer" value=" (no transfer)" /> + <string name="no_modify" value=" (no modify)" /> + <string name="no_copy" value=" (no copy)" /> + <string name="worn" value=" (worn)" /> <string name="LoadingContents">Loading contents...</string> <string name="NoContents">No contents</string> <!-- Gestures labels --> - <string name="Chat"> Chat : </string> - <string name="Sound"> Sound : </string> - <string name="Wait"> --- Wait : </string> - <string name="AnimFlagStop"> Stop Animation : </string> - <string name="AnimFlagStart"> Start Animation : </string> - <string name="Wave"> Wave </string> - <string name="HelloAvatar"> Hello, avatar! </string> + <!-- use value="" because they have preceding spaces --> + <string name="Chat" value=" Chat : " /> + <string name="Sound" value=" Sound : " /> + <string name="Wait" value=" --- Wait : " /> + <string name="AnimFlagStop" value=" Stop Animation : " /> + <string name="AnimFlagStart" value=" Start Animation : " /> + <string name="Wave" value=" Wave " /> + <string name="HelloAvatar" value=" Hello, avatar! " /> <!-- inventory filter --> - <string name="Animations"> Animations,</string> - <string name="Calling Cards"> Calling Cards,</string> - <string name="Clothing"> Clothing,</string> - <string name="Gestures"> Gestures,</string> - <string name="Landmarks"> Landmarks,</string> - <string name="Notecards"> Notecards,</string> - <string name="Objects"> Objects,</string> - <string name="Scripts"> Scripts,</string> - <string name="Sounds"> Sounds,</string> - <string name="Textures"> Textures,</string> - <string name="Snapshots"> Snapshots,</string> - <string name="No Filters"> No </string> - <string name="Since Logoff"> - Since Logoff</string> + <!-- use value="" because they have preceding spaces --> + <string name="Animations" value=" Animations," /> + <string name="Calling Cards" value=" Calling Cards," /> + <string name="Clothing" value=" Clothing," /> + <string name="Gestures" value=" Gestures," /> + <string name="Landmarks" value=" Landmarks," /> + <string name="Notecards" value=" Notecards," /> + <string name="Objects" value=" Objects," /> + <string name="Scripts" value=" Scripts," /> + <string name="Sounds" value=" Sounds," /> + <string name="Textures" value=" Textures," /> + <string name="Snapshots" value=" Snapshots," /> + <string name="No Filters" value="No " /> + <string name="Since Logoff" value=" - Since Logoff" /> <!-- inventory folder --> <string name="InvFolder My Inventory">My Inventory</string> @@ -397,10 +400,6 @@ this texture in your inventory <string name="InvFolder favorite">Favorites</string> <!-- inventory FVBridge --> - <string name="NO_COPY"> (no copy)</string> - <string name="NO_MOD"> (no modify)</string> - <string name="NO_XFER"> (no transfer)</string> - <string name="Buy">Buy</string> <string name="BuyforL$">Buy for L$</string> @@ -486,13 +485,11 @@ this texture in your inventory <!-- groups --> <string name="GroupsNone">none</string> - <string name="Group"> (group)</string> + <string name="Group" value=" (group)" /> <string name="Unknown">(Unknown)</string> - <string name="SummaryForTheWeek">Summary for this week, beginning on </string> - <string name="NextStipendDay">The next stipend day is </string> - <string name="GroupIndividualShare"> Group Individual Share - - </string> + <string name="SummaryForTheWeek" value="Summary for this week, beginning on " /> + <string name="NextStipendDay" value="The next stipend day is " /> + <string name="GroupIndividualShare" value=" Group Individual Share" /> <string name="Balance">Balance</string> <string name="Credits">Credits</string> <string name="Debits">Debits</string> @@ -544,8 +541,8 @@ you managed for [OWNER] <string name="RegionNoCovenant">There is no Covenant provided for this Estate.</string> <string name="RegionNoCovenantOtherOwner">There is no Covenant provided for this Estate. The land on this estate is being sold by the Estate owner, not Linden Lab. Please contact the Estate Owner for sales details.</string> <string name="covenant_last_modified">Last Modified:</string> - <string name="none_text"> (none) </string> - <string name="never_text"> (never) </string> + <string name="none_text" value=" (none) " /> + <string name="never_text" value=" (never) " /> <!--Region Details--> <string name="GroupOwned">Group Owned</string> diff --git a/indra/newview/skins/default/xui/en/widgets/list_view.xml b/indra/newview/skins/default/xui/en/widgets/list_view.xml new file mode 100644 index 0000000000..c66aeb57a0 --- /dev/null +++ b/indra/newview/skins/default/xui/en/widgets/list_view.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<list_view
+ fg_selected_color="ListViewSelectedFgColor"
+ bg_selected_color="ListViewSelectedBgColor"
+ bg_color="ListViewBgColor"
+ />
|