diff options
Diffstat (limited to 'indra/newview')
144 files changed, 4731 insertions, 2129 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index da7466f6b5..10192113f3 100755 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -229,6 +229,7 @@ set(viewer_SOURCE_FILES llfloaterfonttest.cpp llfloatergesture.cpp llfloatergodtools.cpp + llfloatergotoline.cpp llfloatergroupinvite.cpp llfloatergroups.cpp llfloaterhandler.cpp @@ -815,6 +816,7 @@ set(viewer_HEADER_FILES llfloaterfonttest.h llfloatergesture.h llfloatergodtools.h + llfloatergotoline.h llfloatergroupinvite.h llfloatergroups.h llfloaterhandler.h @@ -1275,6 +1277,11 @@ set_source_files_properties( if (DARWIN) LIST(APPEND viewer_SOURCE_FILES llappviewermacosx.cpp) + LIST(APPEND viewer_SOURCE_FILES llfilepicker_mac.mm) + LIST(APPEND viewer_HEADER_FILES llfilepicker_mac.h) + + # This should be compiled with the viewer. + LIST(APPEND viewer_SOURCE_FILES llappdelegate-objc.mm) find_library(AGL_LIBRARY AGL) find_library(APPKIT_LIBRARY AppKit) @@ -1295,7 +1302,7 @@ if (DARWIN) macview.r gpu_table.txt Info-SecondLife.plist - SecondLife.nib/ + SecondLife.xib/ # CMake doesn't seem to support Xcode language variants well just yet English.lproj/InfoPlist.strings English.lproj/language.txt @@ -1975,20 +1982,25 @@ if (LINUX) endif (LINUX) if (DARWIN) + # These all get set with PROPERTIES set(product "Second Life") - + set(MACOSX_BUNDLE_INFO_STRING "Second Life Viewer") + set(MACOSX_BUNDLE_ICON_FILE "secondlife.icns") + set(MACOSX_BUNDLE_GUI_IDENTIFIER "com.secondlife.indra.viewer") + set(MACOSX_BUNDLE_LONG_VERSION_STRING "${VIEWER_CHANNEL} ${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}") + set(MACOSX_BUNDLE_BUNDLE_NAME "SecondLife") + set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${VIEWER_SHORT_VERSION}") + set(MACOSX_BUNDLE_BUNDLE_VERSION "${VIEWER_SHORT_VERSION}${VIEWER_MACOSX_PHASE}${VIEWER_REVISION}") + set(MACOSX_BUNDLE_COPYRIGHT "Copyright © Linden Research, Inc. 2007") + set(MACOSX_BUNDLE_NSMAIN_NIB_FILE "SecondLife.nib") + set(MACOSX_BUNDLE_NSPRINCIPAL_CLASS "NSApplication") + set_target_properties( ${VIEWER_BINARY_NAME} PROPERTIES OUTPUT_NAME "${product}" - MACOSX_BUNDLE_INFO_STRING "Second Life Viewer" - MACOSX_BUNDLE_ICON_FILE "secondlife.icns" - MACOSX_BUNDLE_GUI_IDENTIFIER "com.secondlife.indra.viewer" - MACOSX_BUNDLE_LONG_VERSION_STRING "${VIEWER_CHANNEL} ${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}" - MACOSX_BUNDLE_BUNDLE_NAME "Second Life" - MACOSX_BUNDLE_SHORT_VERSION_STRING "${VIEWER_SHORT_VERSION}" - MACOSX_BUNDLE_BUNDLE_VERSION "${VIEWER_SHORT_VERSION}${VIEWER_MACOSX_PHASE}${VIEWER_REVISION}" - MACOSX_BUNDLE_COPYRIGHT "Copyright © Linden Research, Inc. 2007" + MACOSX_BUNDLE_INFO_PLIST + "${CMAKE_CURRENT_SOURCE_DIR}/Info-SecondLife.plist" ) configure_file( diff --git a/indra/newview/Info-SecondLife.plist b/indra/newview/Info-SecondLife.plist index a19844f11c..9b8136a827 100755 --- a/indra/newview/Info-SecondLife.plist +++ b/indra/newview/Info-SecondLife.plist @@ -5,19 +5,33 @@ <key>CFBundleDevelopmentRegion</key> <string>English</string> <key>CFBundleExecutable</key> - <string>Second Life</string> + <string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string> + <key>CFBundleGetInfoString</key> + <string>${MACOSX_BUNDLE_INFO_STRING}</string> <key>CFBundleIconFile</key> - <string>secondlife.icns</string> + <string>${MACOSX_BUNDLE_ICON_FILE}</string> <key>CFBundleIdentifier</key> - <string>com.secondlife.indra.viewer</string> + <string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string> <key>CFBundleInfoDictionaryVersion</key> <string>6.0</string> + <key>CFBundleLongVersionString</key> + <string>${MACOSX_BUNDLE_LONG_VERSION_STRING}</string> <key>CFBundleName</key> - <string>Second Life</string> + <string>${MACOSX_BUNDLE_BUNDLE_NAME}</string> <key>CFBundlePackageType</key> <string>APPL</string> + <key>CFBundleShortVersionString</key> + <string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string> <key>CFBundleSignature</key> <string>????</string> + <key>CFBundleVersion</key> + <string>${VIEWER_VERSION_MAJOR}.${VIEWER_VERSION_MINOR}.${VIEWER_VERSION_PATCH}.${VIEWER_VERSION_REVISION}</string> + <key>CSResourcesFileMapped</key> + <true/> + <key>LSRequiresCarbon</key> + <true/> + <key>NSHumanReadableCopyright</key> + <string>${MACOSX_BUNDLE_COPYRIGHT}</string> <key>CFBundleDocumentTypes</key> <array> <dict> @@ -59,9 +73,9 @@ <true/> </dict> </array> - <key>CFBundleVersion</key> - <string>${VIEWER_VERSION_MAJOR}.${VIEWER_VERSION_MINOR}.${VIEWER_VERSION_PATCH}.${VIEWER_VERSION_REVISION}</string> - <key>CSResourcesFileMapped</key> - <true/> + <key>NSPrincipalClass</key> + <string>${MACOSX_BUNDLE_NSPRINCIPAL_CLASS}</string> + <key>NSMainNibFile</key> + <string>${MACOSX_BUNDLE_NSMAIN_NIB_FILE}</string> </dict> </plist> diff --git a/indra/newview/SecondLife.nib b/indra/newview/SecondLife.nib Binary files differnew file mode 100644 index 0000000000..8b99b5a770 --- /dev/null +++ b/indra/newview/SecondLife.nib diff --git a/indra/newview/SecondLife.nib/classes.nib b/indra/newview/SecondLife.nib/classes.nib deleted file mode 100755 index ea58db1189..0000000000 --- a/indra/newview/SecondLife.nib/classes.nib +++ /dev/null @@ -1,4 +0,0 @@ -{ -IBClasses = (); -IBVersion = 1; -} diff --git a/indra/newview/SecondLife.nib/info.nib b/indra/newview/SecondLife.nib/info.nib deleted file mode 100755 index 1b531de104..0000000000 --- a/indra/newview/SecondLife.nib/info.nib +++ /dev/null @@ -1,23 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> - <key>IBDocumentLocation</key> - <string>85 13 356 240 0 0 1280 1002 </string> - <key>IBEditorPositions</key> - <dict> - <key>29</key> - <string>27 314 247 44 0 0 1280 1002 </string> - </dict> - <key>IBFramework Version</key> - <string>362.0</string> - <key>IBOpenObjects</key> - <array> - <integer>191</integer> - </array> - <key>IBSystem Version</key> - <string>7D24</string> - <key>targetFramework</key> - <string>IBCarbonFramework</string> -</dict> -</plist> diff --git a/indra/newview/SecondLife.nib/objects.xib b/indra/newview/SecondLife.nib/objects.xib deleted file mode 100755 index b7ff30f2b2..0000000000 --- a/indra/newview/SecondLife.nib/objects.xib +++ /dev/null @@ -1,259 +0,0 @@ -<?xml version="1.0" standalone="yes"?> -<object class="NSIBObjectData"> - <string name="targetFramework">IBCarbonFramework</string> - <object name="rootObject" class="NSCustomObject" id="1"> - <string name="customClass">NSApplication</string> - </object> - <array count="31" name="allObjects"> - <object class="IBCarbonMenu" id="29"> - <string name="title">SecondLife</string> - <array count="4" name="items"> - <object class="IBCarbonMenuItem" id="182"> - <string name="title">Second Life</string> - <object name="submenu" class="IBCarbonMenu" id="181"> - <string name="title">Second Life</string> - <array count="1" name="items"> - <object class="IBCarbonMenuItem" id="183"> - <boolean name="disabled">TRUE</boolean> - <boolean name="updateSingleItem">TRUE</boolean> - <string name="title">About Second Life</string> - <int name="keyEquivalentModifier">0</int> - <ostype name="command">abou</ostype> - </object> - </array> - <string name="name">_NSAppleMenu</string> - </object> - </object> - <object class="IBCarbonMenuItem" id="127"> - <string name="title">File</string> - <object name="submenu" class="IBCarbonMenu" id="131"> - <string name="title">File</string> - </object> - </object> - <object class="IBCarbonMenuItem" id="152"> - <string name="title">Edit</string> - <object name="submenu" class="IBCarbonMenu" id="147"> - <string name="title">Edit</string> - <array count="10" name="items"> - <object class="IBCarbonMenuItem" id="141"> - <boolean name="updateSingleItem">TRUE</boolean> - <string name="title">Undo</string> - <string name="keyEquivalent">z</string> - <ostype name="command">undo</ostype> - </object> - <object class="IBCarbonMenuItem" id="146"> - <boolean name="updateSingleItem">TRUE</boolean> - <string name="title">Redo</string> - <string name="keyEquivalent">Z</string> - <ostype name="command">redo</ostype> - </object> - <object class="IBCarbonMenuItem" id="142"> - <boolean name="separator">TRUE</boolean> - </object> - <object class="IBCarbonMenuItem" id="143"> - <boolean name="updateSingleItem">TRUE</boolean> - <string name="title">Cut</string> - <string name="keyEquivalent">x</string> - <ostype name="command">cut </ostype> - </object> - <object class="IBCarbonMenuItem" id="149"> - <boolean name="updateSingleItem">TRUE</boolean> - <string name="title">Copy</string> - <string name="keyEquivalent">c</string> - <ostype name="command">copy</ostype> - </object> - <object class="IBCarbonMenuItem" id="144"> - <boolean name="updateSingleItem">TRUE</boolean> - <string name="title">Paste</string> - <string name="keyEquivalent">v</string> - <ostype name="command">past</ostype> - </object> - <object class="IBCarbonMenuItem" id="151"> - <boolean name="updateSingleItem">TRUE</boolean> - <string name="title">Delete</string> - <ostype name="command">clea</ostype> - </object> - <object class="IBCarbonMenuItem" id="148"> - <boolean name="updateSingleItem">TRUE</boolean> - <string name="title">Select All</string> - <string name="keyEquivalent">a</string> - <ostype name="command">sall</ostype> - </object> - <object class="IBCarbonMenuItem" id="188"> - <boolean name="separator">TRUE</boolean> - </object> - <object class="IBCarbonMenuItem" id="187"> - <boolean name="updateSingleItem">TRUE</boolean> - <string name="title">Special Characters…</string> - <ostype name="command">chrp</ostype> - </object> - </array> - </object> - </object> - <object class="IBCarbonMenuItem" id="153"> - <string name="title">Window</string> - <object name="submenu" class="IBCarbonMenu" id="154"> - <string name="title">Window</string> - <array count="6" name="items"> - <object class="IBCarbonMenuItem" id="155"> - <boolean name="dynamic">TRUE</boolean> - <boolean name="updateSingleItem">TRUE</boolean> - <string name="title">Minimize Window</string> - <string name="keyEquivalent">m</string> - <ostype name="command">mini</ostype> - </object> - <object class="IBCarbonMenuItem" id="184"> - <boolean name="dynamic">TRUE</boolean> - <boolean name="updateSingleItem">TRUE</boolean> - <string name="title">Minimize All Windows</string> - <string name="keyEquivalent">m</string> - <int name="keyEquivalentModifier">1572864</int> - <ostype name="command">mina</ostype> - </object> - <object class="IBCarbonMenuItem" id="186"> - <boolean name="updateSingleItem">TRUE</boolean> - <string name="title">Zoom</string> - <ostype name="command">zoom</ostype> - </object> - <object class="IBCarbonMenuItem" id="156"> - <boolean name="separator">TRUE</boolean> - </object> - <object class="IBCarbonMenuItem" id="157"> - <boolean name="dynamic">TRUE</boolean> - <boolean name="updateSingleItem">TRUE</boolean> - <string name="title">Bring All to Front</string> - <ostype name="command">bfrt</ostype> - </object> - <object class="IBCarbonMenuItem" id="185"> - <boolean name="dynamic">TRUE</boolean> - <boolean name="updateSingleItem">TRUE</boolean> - <string name="title">Arrange in Front</string> - <int name="keyEquivalentModifier">1572864</int> - <ostype name="command">frnt</ostype> - </object> - </array> - <string name="name">_NSWindowsMenu</string> - </object> - </object> - </array> - <string name="name">_NSMainMenu</string> - </object> - <reference idRef="127"/> - <reference idRef="131"/> - <reference idRef="141"/> - <reference idRef="142"/> - <reference idRef="143"/> - <reference idRef="144"/> - <reference idRef="146"/> - <reference idRef="147"/> - <reference idRef="148"/> - <reference idRef="149"/> - <reference idRef="151"/> - <reference idRef="152"/> - <reference idRef="153"/> - <reference idRef="154"/> - <reference idRef="155"/> - <reference idRef="156"/> - <reference idRef="157"/> - <reference idRef="181"/> - <reference idRef="182"/> - <reference idRef="183"/> - <reference idRef="184"/> - <reference idRef="185"/> - <reference idRef="186"/> - <reference idRef="187"/> - <reference idRef="188"/> - <object class="IBCarbonRootControl" id="190"> - <string name="bounds">0 0 482 694 </string> - <string name="viewFrame">0 0 694 482 </string> - <array count="2" name="subviews"> - <object class="IBCarbonButton" id="192"> - <string name="bounds">442 604 462 674 </string> - <string name="viewFrame">604 442 70 20 </string> - <string name="title">OK</string> - <ostype name="command">ok </ostype> - <object name="layoutInfo" class="IBCarbonHILayoutInfo"> - <int name="bindingBottomKind">2</int> - <int name="bindingRightKind">2</int> - </object> - <int name="buttonType">1</int> - </object> - <object class="IBCarbonScrollView" id="201"> - <string name="bounds">20 20 422 674 </string> - <string name="viewFrame">20 20 654 402 </string> - <array count="1" name="subviews"> - <object class="IBCarbonTextView" id="200"> - <string name="bounds">20 20 422 659 </string> - <string name="viewFrame">0 0 639 402 </string> - <ostype name="controlSignature">text</ostype> - <int name="fontStyle">5</int> - <boolean name="readOnly">TRUE</boolean> - </object> - </array> - <boolean name="scrollHorizontally">FALSE</boolean> - </object> - </array> - </object> - <object class="IBCarbonWindow" id="191"> - <string name="windowRect">84 72 566 766 </string> - <string name="title">Release Notes</string> - <reference name="rootControl" idRef="190"/> - <boolean name="receiveUpdates">FALSE</boolean> - <boolean name="hasCloseBox">FALSE</boolean> - <boolean name="hasCollapseBox">FALSE</boolean> - <boolean name="hasHorizontalZoom">FALSE</boolean> - <boolean name="isResizable">FALSE</boolean> - <boolean name="hasVerticalZoom">FALSE</boolean> - <boolean name="liveResize">TRUE</boolean> - <boolean name="compositing">TRUE</boolean> - <int name="carbonWindowClass">4</int> - <int name="windowPosition">1</int> - <boolean name="isConstrained">FALSE</boolean> - </object> - <reference idRef="192"/> - <reference idRef="200"/> - <reference idRef="201"/> - </array> - <array count="31" name="allParents"> - <reference idRef="1"/> - <reference idRef="29"/> - <reference idRef="127"/> - <reference idRef="147"/> - <reference idRef="147"/> - <reference idRef="147"/> - <reference idRef="147"/> - <reference idRef="147"/> - <reference idRef="152"/> - <reference idRef="147"/> - <reference idRef="147"/> - <reference idRef="147"/> - <reference idRef="29"/> - <reference idRef="29"/> - <reference idRef="153"/> - <reference idRef="154"/> - <reference idRef="154"/> - <reference idRef="154"/> - <reference idRef="182"/> - <reference idRef="29"/> - <reference idRef="181"/> - <reference idRef="154"/> - <reference idRef="154"/> - <reference idRef="154"/> - <reference idRef="147"/> - <reference idRef="147"/> - <reference idRef="191"/> - <reference idRef="1"/> - <reference idRef="190"/> - <reference idRef="201"/> - <reference idRef="190"/> - </array> - <dictionary count="3" name="nameTable"> - <string>Files Owner</string> - <reference idRef="1"/> - <string>MenuBar</string> - <reference idRef="29"/> - <string>Release Notes</string> - <reference idRef="191"/> - </dictionary> - <unsigned_int name="nextObjectID">202</unsigned_int> -</object> diff --git a/indra/newview/SecondLife.xib b/indra/newview/SecondLife.xib new file mode 100644 index 0000000000..370df6bf5f --- /dev/null +++ b/indra/newview/SecondLife.xib @@ -0,0 +1,1136 @@ +<?xml version="1.0" encoding="UTF-8"?> +<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="8.00"> + <data> + <int key="IBDocument.SystemTarget">1060</int> + <string key="IBDocument.SystemVersion">12E55</string> + <string key="IBDocument.InterfaceBuilderVersion">4457.6</string> + <string key="IBDocument.AppKitVersion">1187.39</string> + <string key="IBDocument.HIToolboxVersion">626.00</string> + <object class="NSMutableDictionary" key="IBDocument.PluginVersions"> + <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="NS.object.0">4457.6</string> + </object> + <array key="IBDocument.IntegratedClassDependencies"> + <string>NSCustomObject</string> + <string>NSMenu</string> + <string>NSMenuItem</string> + <string>NSScrollView</string> + <string>NSScroller</string> + <string>NSTextView</string> + <string>NSView</string> + <string>NSWindowTemplate</string> + </array> + <array key="IBDocument.PluginDependencies"> + <string>com.apple.InterfaceBuilder.CocoaPlugin</string> + </array> + <object class="NSMutableDictionary" key="IBDocument.Metadata"> + <string key="NS.key.0">PluginDependencyRecalculationVersion</string> + <integer value="1" key="NS.object.0"/> + </object> + <array class="NSMutableArray" key="IBDocument.RootObjects" id="1048"> + <object class="NSCustomObject" id="1021"> + <string key="NSClassName">NSApplication</string> + </object> + <object class="NSCustomObject" id="1014"> + <string key="NSClassName">FirstResponder</string> + </object> + <object class="NSCustomObject" id="1050"> + <string key="NSClassName">NSApplication</string> + </object> + <object class="NSMenu" id="649796088"> + <string key="NSTitle">Main Menu</string> + <array class="NSMutableArray" key="NSMenuItems"> + <object class="NSMenuItem" id="694149608"> + <reference key="NSMenu" ref="649796088"/> + <string key="NSTitle">Second Life</string> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <object class="NSCustomResource" key="NSOnImage" id="353210768"> + <string key="NSClassName">NSImage</string> + <string key="NSResourceName">NSMenuCheckmark</string> + </object> + <object class="NSCustomResource" key="NSMixedImage" id="549394948"> + <string key="NSClassName">NSImage</string> + <string key="NSResourceName">NSMenuMixedState</string> + </object> + <string key="NSAction">submenuAction:</string> + <object class="NSMenu" key="NSSubmenu" id="110575045"> + <string key="NSTitle">Second Life</string> + <array class="NSMutableArray" key="NSMenuItems"> + <object class="NSMenuItem" id="238522557"> + <reference key="NSMenu" ref="110575045"/> + <string key="NSTitle">About Second Life</string> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="353210768"/> + <reference key="NSMixedImage" ref="549394948"/> + </object> + <object class="NSMenuItem" id="304266470"> + <reference key="NSMenu" ref="110575045"/> + <bool key="NSIsDisabled">YES</bool> + <bool key="NSIsSeparator">YES</bool> + <string key="NSTitle"/> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="353210768"/> + <reference key="NSMixedImage" ref="549394948"/> + </object> + <object class="NSMenuItem" id="609285721"> + <reference key="NSMenu" ref="110575045"/> + <string key="NSTitle">Preferences…</string> + <string key="NSKeyEquiv">,</string> + <int key="NSKeyEquivModMask">1048576</int> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="353210768"/> + <reference key="NSMixedImage" ref="549394948"/> + </object> + <object class="NSMenuItem" id="481834944"> + <reference key="NSMenu" ref="110575045"/> + <bool key="NSIsDisabled">YES</bool> + <bool key="NSIsSeparator">YES</bool> + <string key="NSTitle"/> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="353210768"/> + <reference key="NSMixedImage" ref="549394948"/> + </object> + <object class="NSMenuItem" id="1046388886"> + <reference key="NSMenu" ref="110575045"/> + <string key="NSTitle">Services</string> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="353210768"/> + <reference key="NSMixedImage" ref="549394948"/> + <string key="NSAction">submenuAction:</string> + <object class="NSMenu" key="NSSubmenu" id="752062318"> + <string key="NSTitle">Services</string> + <array class="NSMutableArray" key="NSMenuItems"/> + <string key="NSName">_NSServicesMenu</string> + </object> + </object> + <object class="NSMenuItem" id="646227648"> + <reference key="NSMenu" ref="110575045"/> + <bool key="NSIsDisabled">YES</bool> + <bool key="NSIsSeparator">YES</bool> + <string key="NSTitle"/> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="353210768"/> + <reference key="NSMixedImage" ref="549394948"/> + </object> + <object class="NSMenuItem" id="755159360"> + <reference key="NSMenu" ref="110575045"/> + <string key="NSTitle">Hide NewApplication</string> + <string key="NSKeyEquiv">h</string> + <int key="NSKeyEquivModMask">1048576</int> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="353210768"/> + <reference key="NSMixedImage" ref="549394948"/> + </object> + <object class="NSMenuItem" id="342932134"> + <reference key="NSMenu" ref="110575045"/> + <string key="NSTitle">Hide Others</string> + <string key="NSKeyEquiv">h</string> + <int key="NSKeyEquivModMask">1572864</int> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="353210768"/> + <reference key="NSMixedImage" ref="549394948"/> + </object> + <object class="NSMenuItem" id="908899353"> + <reference key="NSMenu" ref="110575045"/> + <string key="NSTitle">Show All</string> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="353210768"/> + <reference key="NSMixedImage" ref="549394948"/> + </object> + <object class="NSMenuItem" id="1056857174"> + <reference key="NSMenu" ref="110575045"/> + <bool key="NSIsDisabled">YES</bool> + <bool key="NSIsSeparator">YES</bool> + <string key="NSTitle"/> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="353210768"/> + <reference key="NSMixedImage" ref="549394948"/> + </object> + <object class="NSMenuItem" id="632727374"> + <reference key="NSMenu" ref="110575045"/> + <string key="NSTitle">Quit Second Life</string> + <string key="NSKeyEquiv">q</string> + <int key="NSKeyEquivModMask">1048576</int> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="353210768"/> + <reference key="NSMixedImage" ref="549394948"/> + </object> + </array> + <string key="NSName">_NSAppleMenu</string> + </object> + </object> + <object class="NSMenuItem" id="725688984"> + <reference key="NSMenu" ref="649796088"/> + <string key="NSTitle">Edit</string> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="353210768"/> + <reference key="NSMixedImage" ref="549394948"/> + <string key="NSAction">submenuAction:</string> + <object class="NSMenu" key="NSSubmenu" id="701759256"> + <string key="NSTitle">Edit</string> + <array class="NSMutableArray" key="NSMenuItems"> + <object class="NSMenuItem" id="521487141"> + <reference key="NSMenu" ref="701759256"/> + <string key="NSTitle">Undo</string> + <string key="NSKeyEquiv">z</string> + <int key="NSKeyEquivModMask">1048576</int> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="353210768"/> + <reference key="NSMixedImage" ref="549394948"/> + </object> + <object class="NSMenuItem" id="668936019"> + <reference key="NSMenu" ref="701759256"/> + <string key="NSTitle">Redo</string> + <string key="NSKeyEquiv">Z</string> + <int key="NSKeyEquivModMask">1048576</int> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="353210768"/> + <reference key="NSMixedImage" ref="549394948"/> + </object> + <object class="NSMenuItem" id="383018193"> + <reference key="NSMenu" ref="701759256"/> + <bool key="NSIsDisabled">YES</bool> + <bool key="NSIsSeparator">YES</bool> + <string key="NSTitle"/> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="353210768"/> + <reference key="NSMixedImage" ref="549394948"/> + </object> + <object class="NSMenuItem" id="984623395"> + <reference key="NSMenu" ref="701759256"/> + <string key="NSTitle">Cut</string> + <string key="NSKeyEquiv">x</string> + <int key="NSKeyEquivModMask">1048576</int> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="353210768"/> + <reference key="NSMixedImage" ref="549394948"/> + </object> + <object class="NSMenuItem" id="656529582"> + <reference key="NSMenu" ref="701759256"/> + <string key="NSTitle">Copy</string> + <string key="NSKeyEquiv">c</string> + <int key="NSKeyEquivModMask">1048576</int> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="353210768"/> + <reference key="NSMixedImage" ref="549394948"/> + </object> + <object class="NSMenuItem" id="1032676691"> + <reference key="NSMenu" ref="701759256"/> + <string key="NSTitle">Paste</string> + <string key="NSKeyEquiv">v</string> + <int key="NSKeyEquivModMask">1048576</int> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="353210768"/> + <reference key="NSMixedImage" ref="549394948"/> + </object> + <object class="NSMenuItem" id="538907583"> + <reference key="NSMenu" ref="701759256"/> + <string key="NSTitle">Select All</string> + <string key="NSKeyEquiv">a</string> + <int key="NSKeyEquivModMask">1048576</int> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="353210768"/> + <reference key="NSMixedImage" ref="549394948"/> + </object> + </array> + </object> + </object> + <object class="NSMenuItem" id="713487014"> + <reference key="NSMenu" ref="649796088"/> + <string key="NSTitle">Window</string> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="353210768"/> + <reference key="NSMixedImage" ref="549394948"/> + <string key="NSAction">submenuAction:</string> + <object class="NSMenu" key="NSSubmenu" id="835318025"> + <string key="NSTitle">Window</string> + <array class="NSMutableArray" key="NSMenuItems"> + <object class="NSMenuItem" id="1011231497"> + <reference key="NSMenu" ref="835318025"/> + <string key="NSTitle">Minimize</string> + <string key="NSKeyEquiv">m</string> + <int key="NSKeyEquivModMask">1048576</int> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="353210768"/> + <reference key="NSMixedImage" ref="549394948"/> + </object> + <object class="NSMenuItem" id="575023229"> + <reference key="NSMenu" ref="835318025"/> + <string key="NSTitle">Zoom</string> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="353210768"/> + <reference key="NSMixedImage" ref="549394948"/> + </object> + <object class="NSMenuItem" id="86356408"> + <reference key="NSMenu" ref="835318025"/> + <string key="NSTitle">Enter Full Screen</string> + <string key="NSKeyEquiv">f</string> + <int key="NSKeyEquivModMask">1310720</int> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="353210768"/> + <reference key="NSMixedImage" ref="549394948"/> + </object> + <object class="NSMenuItem" id="299356726"> + <reference key="NSMenu" ref="835318025"/> + <bool key="NSIsDisabled">YES</bool> + <bool key="NSIsSeparator">YES</bool> + <string key="NSTitle"/> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="353210768"/> + <reference key="NSMixedImage" ref="549394948"/> + </object> + <object class="NSMenuItem" id="625202149"> + <reference key="NSMenu" ref="835318025"/> + <string key="NSTitle">Bring All to Front</string> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="353210768"/> + <reference key="NSMixedImage" ref="549394948"/> + </object> + </array> + <string key="NSName">_NSWindowsMenu</string> + </object> + </object> + <object class="NSMenuItem" id="391199113"> + <reference key="NSMenu" ref="649796088"/> + <string key="NSTitle">Help</string> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="353210768"/> + <reference key="NSMixedImage" ref="549394948"/> + </object> + </array> + <string key="NSName">_NSMainMenu</string> + </object> + <object class="NSCustomObject" id="756173070"> + <string key="NSClassName">LLAppDelegate</string> + </object> + <object class="NSWindowTemplate" id="110292814"> + <int key="NSWindowStyleMask">15</int> + <int key="NSWindowBacking">2</int> + <string key="NSWindowRect">{{196, 240}, {1024, 600}}</string> + <int key="NSWTFlags">74974208</int> + <string key="NSWindowTitle">Second Life</string> + <string key="NSWindowClass">LLNSWindow</string> + <nil key="NSViewClass"/> + <nil key="NSUserInterfaceItemIdentifier"/> + <object class="NSView" key="NSWindowView" id="305280978"> + <reference key="NSNextResponder"/> + <int key="NSvFlags">256</int> + <array class="NSMutableArray" key="NSSubviews"/> + <string key="NSFrameSize">{1024, 600}</string> + <reference key="NSSuperview"/> + <reference key="NSWindow"/> + <string key="NSReuseIdentifierKey">_NS:20</string> + </object> + <string key="NSScreenRect">{{0, 0}, {2560, 1418}}</string> + <string key="NSMaxSize">{10000000000000, 10000000000000}</string> + <string key="NSFrameAutosaveName">Second Life</string> + <int key="NSWindowCollectionBehavior">128</int> + <bool key="NSWindowIsRestorable">YES</bool> + </object> + <object class="NSWindowTemplate" id="979091056"> + <int key="NSWindowStyleMask">31</int> + <int key="NSWindowBacking">2</int> + <string key="NSWindowRect">{{272, 176}, {938, 42}}</string> + <int key="NSWTFlags">-1535638528</int> + <string key="NSWindowTitle">Input Window</string> + <string key="NSWindowClass">LLUserInputWindow</string> + <nil key="NSViewClass"/> + <nil key="NSUserInterfaceItemIdentifier"/> + <object class="NSView" key="NSWindowView" id="1044753903"> + <reference key="NSNextResponder"/> + <int key="NSvFlags">256</int> + <array class="NSMutableArray" key="NSSubviews"> + <object class="NSScrollView" id="238626476"> + <reference key="NSNextResponder" ref="1044753903"/> + <int key="NSvFlags">256</int> + <array class="NSMutableArray" key="NSSubviews"> + <object class="NSClipView" id="871543330"> + <reference key="NSNextResponder" ref="238626476"/> + <int key="NSvFlags">2322</int> + <array class="NSMutableArray" key="NSSubviews"> + <object class="NSTextView" id="395788163"> + <reference key="NSNextResponder" ref="871543330"/> + <int key="NSvFlags">2322</int> + <set class="NSMutableSet" key="NSDragTypes"> + <string>Apple HTML pasteboard type</string> + <string>Apple PDF pasteboard type</string> + <string>Apple PICT pasteboard type</string> + <string>Apple PNG pasteboard type</string> + <string>Apple URL pasteboard type</string> + <string>CorePasteboardFlavorType 0x6D6F6F76</string> + <string>NSColor pasteboard type</string> + <string>NSFilenamesPboardType</string> + <string>NSStringPboardType</string> + <string>NeXT Encapsulated PostScript v1.2 pasteboard type</string> + <string>NeXT RTFD pasteboard type</string> + <string>NeXT Rich Text Format v1.0 pasteboard type</string> + <string>NeXT TIFF v4.0 pasteboard type</string> + <string>NeXT font pasteboard type</string> + <string>NeXT ruler pasteboard type</string> + <string>WebURLsWithTitlesPboardType</string> + <string>public.url</string> + </set> + <string key="NSFrameSize">{938, 42}</string> + <reference key="NSSuperview" ref="871543330"/> + <reference key="NSWindow"/> + <reference key="NSNextKeyView" ref="339833963"/> + <string key="NSReuseIdentifierKey">_NS:13</string> + <object class="NSTextContainer" key="NSTextContainer" id="648552009"> + <object class="NSLayoutManager" key="NSLayoutManager"> + <object class="NSTextStorage" key="NSTextStorage"> + <object class="NSMutableString" key="NSString"> + <characters key="NS.bytes"/> + </object> + <nil key="NSDelegate"/> + </object> + <array class="NSMutableArray" key="NSTextContainers"> + <reference ref="648552009"/> + </array> + <int key="NSLMFlags">166</int> + <nil key="NSDelegate"/> + </object> + <reference key="NSTextView" ref="395788163"/> + <double key="NSWidth">938</double> + <int key="NSTCFlags">1</int> + </object> + <object class="NSTextViewSharedData" key="NSSharedData"> + <int key="NSFlags">67121127</int> + <int key="NSTextCheckingTypes">0</int> + <nil key="NSMarkedAttributes"/> + <object class="NSColor" key="NSBackgroundColor" id="535647664"> + <int key="NSColorSpace">3</int> + <bytes key="NSWhite">MQA</bytes> + </object> + <dictionary key="NSSelectedAttributes"> + <object class="NSColor" key="NSBackgroundColor"> + <int key="NSColorSpace">6</int> + <string key="NSCatalogName">System</string> + <string key="NSColorName">selectedTextBackgroundColor</string> + <object class="NSColor" key="NSColor"> + <int key="NSColorSpace">3</int> + <bytes key="NSWhite">MC42NjY2NjY2NjY3AA</bytes> + </object> + </object> + <object class="NSColor" key="NSColor"> + <int key="NSColorSpace">6</int> + <string key="NSCatalogName">System</string> + <string key="NSColorName">selectedTextColor</string> + <object class="NSColor" key="NSColor" id="835883401"> + <int key="NSColorSpace">3</int> + <bytes key="NSWhite">MAA</bytes> + </object> + </object> + </dictionary> + <reference key="NSInsertionColor" ref="835883401"/> + <dictionary key="NSLinkAttributes"> + <object class="NSColor" key="NSColor"> + <int key="NSColorSpace">1</int> + <bytes key="NSRGB">MCAwIDEAA</bytes> + </object> + <object class="NSCursor" key="NSCursor"> + <string key="NSHotSpot">{8, -8}</string> + <int key="NSCursorType">13</int> + </object> + <integer value="1" key="NSUnderline"/> + </dictionary> + <nil key="NSDefaultParagraphStyle"/> + <nil key="NSTextFinder"/> + <int key="NSPreferredTextFinderStyle">1</int> + </object> + <int key="NSTVFlags">6</int> + <string key="NSMaxSize">{939, 10000000}</string> + <nil key="NSDelegate"/> + </object> + </array> + <string key="NSFrame">{{1, 1}, {938, 42}}</string> + <reference key="NSSuperview" ref="238626476"/> + <reference key="NSWindow"/> + <reference key="NSNextKeyView" ref="395788163"/> + <string key="NSReuseIdentifierKey">_NS:11</string> + <reference key="NSDocView" ref="395788163"/> + <reference key="NSBGColor" ref="535647664"/> + <object class="NSCursor" key="NSCursor"> + <string key="NSHotSpot">{4, 5}</string> + <object class="NSImage" key="NSImage"> + <int key="NSImageFlags">79691776</int> + <array key="NSReps"> + <array> + <integer value="5"/> + <object class="NSURL"> + <nil key="NS.base"/> + <string key="NS.relative">file://localhost/Applications/Xcode.app/Contents/SharedFrameworks/DVTKit.framework/Resources/DVTIbeamCursor.tiff</string> + </object> + </array> + </array> + <object class="NSColor" key="NSColor"> + <int key="NSColorSpace">3</int> + <bytes key="NSWhite">MCAwAA</bytes> + </object> + </object> + </object> + <int key="NScvFlags">4</int> + </object> + <object class="NSScroller" id="339833963"> + <reference key="NSNextResponder" ref="238626476"/> + <int key="NSvFlags">256</int> + <string key="NSFrame">{{923, 1}, {16, 42}}</string> + <reference key="NSSuperview" ref="238626476"/> + <reference key="NSWindow"/> + <reference key="NSNextKeyView"/> + <string key="NSReuseIdentifierKey">_NS:83</string> + <bool key="NSAllowsLogicalLayoutDirection">NO</bool> + <reference key="NSTarget" ref="238626476"/> + <string key="NSAction">_doScroller:</string> + <double key="NSPercent">0.96666666666666667</double> + </object> + <object class="NSScroller" id="1067057765"> + <reference key="NSNextResponder" ref="238626476"/> + <int key="NSvFlags">-2147483392</int> + <string key="NSFrame">{{-100, -100}, {87, 18}}</string> + <reference key="NSSuperview" ref="238626476"/> + <reference key="NSWindow"/> + <reference key="NSNextKeyView" ref="871543330"/> + <string key="NSReuseIdentifierKey">_NS:33</string> + <bool key="NSAllowsLogicalLayoutDirection">NO</bool> + <int key="NSsFlags">1</int> + <reference key="NSTarget" ref="238626476"/> + <string key="NSAction">_doScroller:</string> + <double key="NSCurValue">1</double> + <double key="NSPercent">0.94565218687057495</double> + </object> + </array> + <string key="NSFrame">{{-1, -1}, {940, 44}}</string> + <reference key="NSSuperview" ref="1044753903"/> + <reference key="NSWindow"/> + <reference key="NSNextKeyView" ref="1067057765"/> + <string key="NSReuseIdentifierKey">_NS:9</string> + <int key="NSsFlags">133138</int> + <reference key="NSVScroller" ref="339833963"/> + <reference key="NSHScroller" ref="1067057765"/> + <reference key="NSContentView" ref="871543330"/> + <double key="NSMinMagnification">0.25</double> + <double key="NSMaxMagnification">4</double> + <double key="NSMagnification">1</double> + </object> + </array> + <string key="NSFrameSize">{938, 42}</string> + <reference key="NSSuperview"/> + <reference key="NSWindow"/> + <reference key="NSNextKeyView" ref="238626476"/> + <string key="NSReuseIdentifierKey">_NS:21</string> + </object> + <string key="NSScreenRect">{{0, 0}, {2560, 1418}}</string> + <string key="NSMaxSize">{10000000000000, 10000000000000}</string> + <bool key="NSWindowIsRestorable">YES</bool> + </object> + </array> + <object class="IBObjectContainer" key="IBDocument.Objects"> + <array class="NSMutableArray" key="connectionRecords"> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">terminate:</string> + <reference key="source" ref="1050"/> + <reference key="destination" ref="632727374"/> + </object> + <int key="connectionID">823</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">orderFrontStandardAboutPanel:</string> + <reference key="source" ref="1021"/> + <reference key="destination" ref="238522557"/> + </object> + <int key="connectionID">142</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBOutletConnection" key="connection"> + <string key="label">delegate</string> + <reference key="source" ref="1021"/> + <reference key="destination" ref="756173070"/> + </object> + <int key="connectionID">845</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">performMiniaturize:</string> + <reference key="source" ref="1014"/> + <reference key="destination" ref="1011231497"/> + </object> + <int key="connectionID">37</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">arrangeInFront:</string> + <reference key="source" ref="1014"/> + <reference key="destination" ref="625202149"/> + </object> + <int key="connectionID">39</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">performZoom:</string> + <reference key="source" ref="1014"/> + <reference key="destination" ref="575023229"/> + </object> + <int key="connectionID">240</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">hide:</string> + <reference key="source" ref="1014"/> + <reference key="destination" ref="755159360"/> + </object> + <int key="connectionID">369</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">hideOtherApplications:</string> + <reference key="source" ref="1014"/> + <reference key="destination" ref="342932134"/> + </object> + <int key="connectionID">370</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">unhideAllApplications:</string> + <reference key="source" ref="1014"/> + <reference key="destination" ref="908899353"/> + </object> + <int key="connectionID">372</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">cut:</string> + <reference key="source" ref="1014"/> + <reference key="destination" ref="984623395"/> + </object> + <int key="connectionID">768</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">paste:</string> + <reference key="source" ref="1014"/> + <reference key="destination" ref="1032676691"/> + </object> + <int key="connectionID">769</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">undo:</string> + <reference key="source" ref="1014"/> + <reference key="destination" ref="521487141"/> + </object> + <int key="connectionID">776</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">copy:</string> + <reference key="source" ref="1014"/> + <reference key="destination" ref="656529582"/> + </object> + <int key="connectionID">782</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">selectAll:</string> + <reference key="source" ref="1014"/> + <reference key="destination" ref="538907583"/> + </object> + <int key="connectionID">785</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">toggleFullScreen:</string> + <reference key="source" ref="1014"/> + <reference key="destination" ref="86356408"/> + </object> + <int key="connectionID">842</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBOutletConnection" key="connection"> + <string key="label">window</string> + <reference key="source" ref="756173070"/> + <reference key="destination" ref="110292814"/> + </object> + <int key="connectionID">850</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBOutletConnection" key="connection"> + <string key="label">inputWindow</string> + <reference key="source" ref="756173070"/> + <reference key="destination" ref="979091056"/> + </object> + <int key="connectionID">953</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBOutletConnection" key="connection"> + <string key="label">inputView</string> + <reference key="source" ref="756173070"/> + <reference key="destination" ref="395788163"/> + </object> + <int key="connectionID">954</int> + </object> + </array> + <object class="IBMutableOrderedSet" key="objectRecords"> + <array key="orderedObjects"> + <object class="IBObjectRecord"> + <int key="objectID">0</int> + <array key="object" id="0"/> + <reference key="children" ref="1048"/> + <nil key="parent"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">-2</int> + <reference key="object" ref="1021"/> + <reference key="parent" ref="0"/> + <string key="objectName">File's Owner</string> + </object> + <object class="IBObjectRecord"> + <int key="objectID">-1</int> + <reference key="object" ref="1014"/> + <reference key="parent" ref="0"/> + <string key="objectName">First Responder</string> + </object> + <object class="IBObjectRecord"> + <int key="objectID">-3</int> + <reference key="object" ref="1050"/> + <reference key="parent" ref="0"/> + <string key="objectName">Application</string> + </object> + <object class="IBObjectRecord"> + <int key="objectID">29</int> + <reference key="object" ref="649796088"/> + <array class="NSMutableArray" key="children"> + <reference ref="713487014"/> + <reference ref="694149608"/> + <reference ref="391199113"/> + <reference ref="725688984"/> + </array> + <reference key="parent" ref="0"/> + <string key="objectName">Main Menu</string> + </object> + <object class="IBObjectRecord"> + <int key="objectID">19</int> + <reference key="object" ref="713487014"/> + <array class="NSMutableArray" key="children"> + <reference ref="835318025"/> + </array> + <reference key="parent" ref="649796088"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">56</int> + <reference key="object" ref="694149608"/> + <array class="NSMutableArray" key="children"> + <reference ref="110575045"/> + </array> + <reference key="parent" ref="649796088"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">103</int> + <reference key="object" ref="391199113"/> + <array class="NSMutableArray" key="children"/> + <reference key="parent" ref="649796088"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">57</int> + <reference key="object" ref="110575045"/> + <array class="NSMutableArray" key="children"> + <reference ref="238522557"/> + <reference ref="755159360"/> + <reference ref="908899353"/> + <reference ref="632727374"/> + <reference ref="646227648"/> + <reference ref="609285721"/> + <reference ref="481834944"/> + <reference ref="304266470"/> + <reference ref="1046388886"/> + <reference ref="1056857174"/> + <reference ref="342932134"/> + </array> + <reference key="parent" ref="694149608"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">58</int> + <reference key="object" ref="238522557"/> + <reference key="parent" ref="110575045"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">134</int> + <reference key="object" ref="755159360"/> + <reference key="parent" ref="110575045"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">150</int> + <reference key="object" ref="908899353"/> + <reference key="parent" ref="110575045"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">136</int> + <reference key="object" ref="632727374"/> + <reference key="parent" ref="110575045"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">144</int> + <reference key="object" ref="646227648"/> + <reference key="parent" ref="110575045"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">129</int> + <reference key="object" ref="609285721"/> + <reference key="parent" ref="110575045"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">143</int> + <reference key="object" ref="481834944"/> + <reference key="parent" ref="110575045"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">236</int> + <reference key="object" ref="304266470"/> + <reference key="parent" ref="110575045"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">131</int> + <reference key="object" ref="1046388886"/> + <array class="NSMutableArray" key="children"> + <reference ref="752062318"/> + </array> + <reference key="parent" ref="110575045"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">149</int> + <reference key="object" ref="1056857174"/> + <reference key="parent" ref="110575045"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">145</int> + <reference key="object" ref="342932134"/> + <reference key="parent" ref="110575045"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">130</int> + <reference key="object" ref="752062318"/> + <reference key="parent" ref="1046388886"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">24</int> + <reference key="object" ref="835318025"/> + <array class="NSMutableArray" key="children"> + <reference ref="299356726"/> + <reference ref="625202149"/> + <reference ref="575023229"/> + <reference ref="1011231497"/> + <reference ref="86356408"/> + </array> + <reference key="parent" ref="713487014"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">92</int> + <reference key="object" ref="299356726"/> + <reference key="parent" ref="835318025"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">5</int> + <reference key="object" ref="625202149"/> + <reference key="parent" ref="835318025"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">239</int> + <reference key="object" ref="575023229"/> + <reference key="parent" ref="835318025"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">23</int> + <reference key="object" ref="1011231497"/> + <reference key="parent" ref="835318025"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">711</int> + <reference key="object" ref="725688984"/> + <array class="NSMutableArray" key="children"> + <reference ref="701759256"/> + </array> + <reference key="parent" ref="649796088"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">712</int> + <reference key="object" ref="701759256"/> + <array class="NSMutableArray" key="children"> + <reference ref="521487141"/> + <reference ref="668936019"/> + <reference ref="383018193"/> + <reference ref="984623395"/> + <reference ref="656529582"/> + <reference ref="1032676691"/> + <reference ref="538907583"/> + </array> + <reference key="parent" ref="725688984"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">716</int> + <reference key="object" ref="984623395"/> + <reference key="parent" ref="701759256"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">717</int> + <reference key="object" ref="656529582"/> + <reference key="parent" ref="701759256"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">718</int> + <reference key="object" ref="1032676691"/> + <reference key="parent" ref="701759256"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">721</int> + <reference key="object" ref="538907583"/> + <reference key="parent" ref="701759256"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">824</int> + <reference key="object" ref="756173070"/> + <reference key="parent" ref="0"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">841</int> + <reference key="object" ref="86356408"/> + <reference key="parent" ref="835318025"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">828</int> + <reference key="object" ref="110292814"/> + <array class="NSMutableArray" key="children"> + <reference ref="305280978"/> + </array> + <reference key="parent" ref="0"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">829</int> + <reference key="object" ref="305280978"/> + <array class="NSMutableArray" key="children"/> + <reference key="parent" ref="110292814"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">713</int> + <reference key="object" ref="521487141"/> + <reference key="parent" ref="701759256"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">714</int> + <reference key="object" ref="668936019"/> + <reference key="parent" ref="701759256"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">715</int> + <reference key="object" ref="383018193"/> + <reference key="parent" ref="701759256"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">941</int> + <reference key="object" ref="979091056"/> + <array class="NSMutableArray" key="children"> + <reference ref="1044753903"/> + </array> + <reference key="parent" ref="0"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">942</int> + <reference key="object" ref="1044753903"/> + <array class="NSMutableArray" key="children"> + <reference ref="238626476"/> + </array> + <reference key="parent" ref="979091056"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">943</int> + <reference key="object" ref="238626476"/> + <array class="NSMutableArray" key="children"> + <reference ref="395788163"/> + <reference ref="1067057765"/> + <reference ref="339833963"/> + </array> + <reference key="parent" ref="1044753903"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">944</int> + <reference key="object" ref="395788163"/> + <reference key="parent" ref="238626476"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">945</int> + <reference key="object" ref="1067057765"/> + <reference key="parent" ref="238626476"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">946</int> + <reference key="object" ref="339833963"/> + <reference key="parent" ref="238626476"/> + </object> + </array> + </object> + <dictionary class="NSMutableDictionary" key="flattenedProperties"> + <string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="-3.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="103.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="129.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="130.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="131.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="134.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="136.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="143.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="144.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="145.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="149.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="150.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="19.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="23.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="236.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="239.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="24.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="29.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="5.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="56.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="57.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="58.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="711.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="712.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="713.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="714.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="715.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="716.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="717.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="718.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="721.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="824.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <boolean value="YES" key="828.IBNSWindowAutoPositionCentersHorizontal"/> + <boolean value="YES" key="828.IBNSWindowAutoPositionCentersVertical"/> + <string key="828.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <boolean value="YES" key="828.NSWindowTemplate.visibleAtLaunch"/> + <string key="829.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="841.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="92.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="941.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <boolean value="NO" key="941.NSWindowTemplate.visibleAtLaunch"/> + <string key="942.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="943.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="944.CustomClassName">LLNonInlineTextView</string> + <string key="944.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="945.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="946.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + </dictionary> + <dictionary class="NSMutableDictionary" key="unlocalizedProperties"/> + <nil key="activeLocalization"/> + <dictionary class="NSMutableDictionary" key="localizations"/> + <nil key="sourceID"/> + <int key="maxID">954</int> + </object> + <object class="IBClassDescriber" key="IBDocument.Classes"> + <array class="NSMutableArray" key="referencedPartialClassDescriptions"> + <object class="IBPartialClassDescription"> + <string key="className">LLAppDelegate</string> + <string key="superclassName">NSObject</string> + <dictionary class="NSMutableDictionary" key="outlets"> + <string key="inputView">LLNonInlineTextView</string> + <string key="inputWindow">NSWindow</string> + <string key="window">LLNSWindow</string> + </dictionary> + <dictionary class="NSMutableDictionary" key="toOneOutletInfosByName"> + <object class="IBToOneOutletInfo" key="inputView"> + <string key="name">inputView</string> + <string key="candidateClassName">LLNonInlineTextView</string> + </object> + <object class="IBToOneOutletInfo" key="inputWindow"> + <string key="name">inputWindow</string> + <string key="candidateClassName">NSWindow</string> + </object> + <object class="IBToOneOutletInfo" key="window"> + <string key="name">window</string> + <string key="candidateClassName">LLNSWindow</string> + </object> + </dictionary> + <object class="IBClassDescriptionSource" key="sourceIdentifier"> + <string key="majorKey">IBProjectSource</string> + <string key="minorKey">./Classes/LLAppDelegate.h</string> + </object> + </object> + <object class="IBPartialClassDescription"> + <string key="className">LLNSWindow</string> + <string key="superclassName">NSWindow</string> + <object class="IBClassDescriptionSource" key="sourceIdentifier"> + <string key="majorKey">IBProjectSource</string> + <string key="minorKey">./Classes/LLNSWindow.h</string> + </object> + </object> + <object class="IBPartialClassDescription"> + <string key="className">LLNonInlineTextView</string> + <string key="superclassName">NSTextView</string> + <object class="IBClassDescriptionSource" key="sourceIdentifier"> + <string key="majorKey">IBProjectSource</string> + <string key="minorKey">./Classes/LLNonInlineTextView.h</string> + </object> + </object> + <object class="IBPartialClassDescription"> + <string key="className">LLUserInputWindow</string> + <string key="superclassName">NSPanel</string> + <object class="IBClassDescriptionSource" key="sourceIdentifier"> + <string key="majorKey">IBProjectSource</string> + <string key="minorKey">./Classes/LLUserInputWindow.h</string> + </object> + </object> + <object class="IBPartialClassDescription"> + <string key="className">NSTextView</string> + <dictionary class="NSMutableDictionary" key="actions"> + <string key="orderFrontSharingServicePicker:">id</string> + <string key="toggleQuickLookPreviewPanel:">id</string> + </dictionary> + <dictionary class="NSMutableDictionary" key="actionInfosByName"> + <object class="IBActionInfo" key="orderFrontSharingServicePicker:"> + <string key="name">orderFrontSharingServicePicker:</string> + <string key="candidateClassName">id</string> + </object> + <object class="IBActionInfo" key="toggleQuickLookPreviewPanel:"> + <string key="name">toggleQuickLookPreviewPanel:</string> + <string key="candidateClassName">id</string> + </object> + </dictionary> + <object class="IBClassDescriptionSource" key="sourceIdentifier"> + <string key="majorKey">IBProjectSource</string> + <string key="minorKey">./Classes/NSTextView.h</string> + </object> + </object> + </array> + </object> + <int key="IBDocument.localizationMode">0</int> + <string key="IBDocument.TargetRuntimeIdentifier">IBCocoaFramework</string> + <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencies"> + <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin.macosx</string> + <real value="1060" key="NS.object.0"/> + </object> + <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies"> + <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3</string> + <integer value="4600" key="NS.object.0"/> + </object> + <bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool> + <int key="IBDocument.defaultPropertyAccessControl">3</int> + <dictionary class="NSMutableDictionary" key="IBDocument.LastKnownImageSizes"> + <string key="NSMenuCheckmark">{11, 11}</string> + <string key="NSMenuMixedState">{10, 3}</string> + </dictionary> + </data> +</archive> diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index 0f44168a4d..4f2c1d15f6 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -3.6.4 +3.6.6 diff --git a/indra/newview/app_settings/cmd_line.xml b/indra/newview/app_settings/cmd_line.xml index 7ab7787d77..a9f6079630 100755 --- a/indra/newview/app_settings/cmd_line.xml +++ b/indra/newview/app_settings/cmd_line.xml @@ -22,7 +22,8 @@ <map> <key>count</key> <integer>1</integer> - <!-- Special case. Not mapped to a setting. --> + <key>map-to</key> + <string>CmdLineChannel</string> </map> <key>console</key> @@ -96,6 +97,8 @@ 0 - low, 1 - medium, 2 - high, 3 - ultra</string> <key>count</key> <integer>1</integer> + <key>map-to</key> + <string>RenderQualityPerformance</string> </map> <key>grid</key> @@ -108,6 +111,16 @@ <string>CmdLineGridChoice</string> </map> + <key>update-service</key> + <map> + <key>desc</key> + <string>Override the url base for the update query.</string> + <key>count</key> + <integer>1</integer> + <key>map-to</key> + <string>CmdLineUpdateService</string> + </map> + <key>help</key> <map> <key>desc</key> @@ -370,7 +383,8 @@ <boolean>true</boolean> <key>last_option</key> <boolean>true</boolean> - <!-- Special case. Not mapped to a setting. --> + <key>map-to</key> + <string>CmdLineLoginLocation</string> </map> <key>url</key> @@ -381,7 +395,8 @@ <integer>1</integer> <key>last_option</key> <boolean>true</boolean> - <!-- Special case. Not mapped to a setting. --> + <key>map-to</key> + <string>CmdLineLoginLocation</string> </map> <key>usersessionsettings</key> diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 93cc605be0..ae49fce380 100755 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -126,6 +126,17 @@ <key>Value</key> <integer>1</integer> </map> + <key>AnalyzePerformance</key> + <map> + <key>Comment</key> + <string>Request performance analysis for a particular viewer run</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>AnimateTextures</key> <map> <key>Comment</key> @@ -1760,6 +1771,17 @@ <key>Value</key> <integer>0</integer> </map> + <key>CmdLineChannel</key> + <map> + <key>Comment</key> + <string>Command line specified channel name</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>String</string> + <key>Value</key> + <string /> + </map> <key>CmdLineDisableVoice</key> <map> <key>Comment</key> @@ -1782,6 +1804,17 @@ <key>Value</key> <string /> </map> + <key>CmdLineUpdateService</key> + <map> + <key>Comment</key> + <string>Override the url base for the update query.</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>String</string> + <key>Value</key> + <string /> + </map> <key>CmdLineHelperURI</key> <map> <key>Comment</key> @@ -1806,6 +1839,17 @@ <string /> </array> </map> + <key>CmdLineLoginLocation</key> + <map> + <key>Comment</key> + <string>Startup destination requested on command line</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>String</string> + <key>Value</key> + <string/> + </map> <key>ConnectAsGod</key> <map> <key>Comment</key> @@ -1938,6 +1982,17 @@ <key>Value</key> <integer>262144</integer> </map> + <key>CrashOnStartup</key> + <map> + <key>Comment</key> + <string>User-requested crash on viewer startup</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>CreateToolCopyCenters</key> <map> <key>Comment</key> @@ -2180,6 +2235,17 @@ <key>Value</key> <integer>0</integer> </map> + <key>DebugSession</key> + <map> + <key>Comment</key> + <string>Request debugging for a particular viewer session</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>DebugShowColor</key> <map> <key>Comment</key> @@ -2994,6 +3060,17 @@ <key>Value</key> <integer>0</integer> </map> + <key>DisableCrashLogger</key> + <map> + <key>Comment</key> + <string>Do not send crash report to Linden server</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>DisableMouseWarp</key> <map> <key>Comment</key> @@ -3511,16 +3588,27 @@ <key>Value</key> <real>10.0</real> </map> - <key>FilterItemsPerFrame</key> + <key>FilterItemsMaxTimePerFrameVisible</key> <map> - <key>Comment</key> - <string>Maximum number of inventory items to match against search filter every frame (lower to increase framerate while searching, higher to improve search speed)</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>500</integer> + <key>Comment</key> + <string>Max time devoted to items filtering per frame for visible inventory listings (in milliseconds)</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>S32</string> + <key>Value</key> + <integer>10</integer> + </map> + <key>FilterItemsMaxTimePerFrameUnvisible</key> + <map> + <key>Comment</key> + <string>Max time devoted to items filtering per frame for non visible inventory listings (in milliseconds)</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>S32</string> + <key>Value</key> + <integer>1</integer> </map> <key>FindLandArea</key> <map> @@ -5250,6 +5338,28 @@ <key>Value</key> <integer>0</integer> </map> + <key>LogMetrics</key> + <map> + <key>Comment</key> + <string>Log viewer metrics</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>String</string> + <key>Value</key> + <string/> + </map> + <key>LogPerformance</key> + <map> + <key>Comment</key> + <string>Log performance analysis for a particular viewer run</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>LogTextureNetworkTraffic</key> <map> <key>Comment</key> @@ -6449,6 +6559,17 @@ <key>Value</key> <integer>0</integer> </map> + <key>NoQuickTime</key> + <map> + <key>Comment</key> + <string>Disable QuickTime for a particular viewer run</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>NoVerifySSLCert</key> <map> <key>Comment</key> @@ -6485,7 +6606,10 @@ <key>NotificationConferenceIMOptions</key> <map> <key>Comment</key> - <string>Specifies how the UI responds to Conference IM Notifications.</string> + <string> + Specifies how the UI responds to Conference IM Notifications. + Allowed values: [openconversations,toast,flash,noaction] + </string> <key>Persist</key> <integer>1</integer> <key>Type</key> @@ -6496,7 +6620,10 @@ <key>NotificationFriendIMOptions</key> <map> <key>Comment</key> - <string>Specifies how the UI responds to Friend IM Notifications.</string> + <string> + Specifies how the UI responds to Friend IM Notifications. + Allowed values: [openconversations,toast,flash,noaction] + </string> <key>Persist</key> <integer>1</integer> <key>Type</key> @@ -6507,7 +6634,10 @@ <key>NotificationGroupChatOptions</key> <map> <key>Comment</key> - <string>Specifies how the UI responds to Group Chat Notifications.</string> + <string> + Specifies how the UI responds to Group Chat Notifications. + Allowed values: [openconversations,toast,flash,noaction] + </string> <key>Persist</key> <integer>1</integer> <key>Type</key> @@ -6518,7 +6648,10 @@ <key>NotificationNearbyChatOptions</key> <map> <key>Comment</key> - <string>Specifies how the UI responds to Nearby Chat Notifications.</string> + <string> + Specifies how the UI responds to Nearby Chat Notifications. + Allowed values: [openconversations,toast,flash,noaction] + </string> <key>Persist</key> <integer>1</integer> <key>Type</key> @@ -6529,7 +6662,24 @@ <key>NotificationNonFriendIMOptions</key> <map> <key>Comment</key> - <string>Specifies how the UI responds to Non Friend IM Notifications.</string> + <string> + Specifies how the UI responds to Non Friend IM Notifications. + Allowed values: [openconversations,toast,flash,noaction] + </string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>String</string> + <key>Value</key> + <string>toast</string> + </map> + <key>NotificationObjectIMOptions</key> + <map> + <key>Comment</key> + <string> + Specifies how the UI responds to Object IM Notifications. + Allowed values: [openconversations,toast,flash,noaction] + </string> <key>Persist</key> <integer>1</integer> <key>Type</key> @@ -7053,6 +7203,17 @@ <key>Value</key> <real>90.0</real> </map> + <key>PlayChatAnim</key> + <map> + <key>Comment</key> + <string>Your avatar plays the chat animation whenever you say, shout or whisper something in nearby chat</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> <key>PlayTypingAnim</key> <map> <key>Comment</key> @@ -7086,6 +7247,72 @@ <key>Value</key> <integer>0</integer> </map> + <key>PlaySoundFriendIM</key> + <map> + <key>Comment</key> + <string>Plays a sound when friend's IM received.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>PlaySoundNonFriendIM</key> + <map> + <key>Comment</key> + <string>Plays a sound when non-friend's IM received.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>PlaySoundConferenceIM</key> + <map> + <key>Comment</key> + <string>Plays a sound when conference IM received.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>PlaySoundGroupChatIM</key> + <map> + <key>Comment</key> + <string>Plays a sound when group chat IM received.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>PlaySoundNearbyChatIM</key> + <map> + <key>Comment</key> + <string>Plays a sound when nearby chat IM received.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>PlaySoundObjectIM</key> + <map> + <key>Comment</key> + <string>Plays a sound when IM fom an object received.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>PlaySoundNewConversation</key> <map> <key>Comment</key> @@ -9730,6 +9957,17 @@ <key>Value</key> <integer>1</integer> </map> + <key>ReplaySession</key> + <map> + <key>Comment</key> + <string>Request replay of previously-recorded pilot file</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>RotateRight</key> <map> <key>Comment</key> @@ -12990,12 +13228,13 @@ <key>UserLoginInfo</key> <map> <key>Comment</key> - <string>Users loging data.</string> + <string>User login data.</string> <key>Persist</key> <integer>1</integer> <key>Type</key> <string>LLSD</string> <key>Value</key> + <string/> </map> <key>VFSOldSize</key> <map> diff --git a/indra/newview/app_settings/settings_files.xml b/indra/newview/app_settings/settings_files.xml index bfc09286e3..4a9e522a96 100755 --- a/indra/newview/app_settings/settings_files.xml +++ b/indra/newview/app_settings/settings_files.xml @@ -4,6 +4,9 @@ <file name="Global" file_name="settings.xml" required="true"/> + <file name="Global" + file_name="settings_install.xml" + required="false"/> <file name="PerAccount" file_name="settings_per_account.xml" required="true"/> diff --git a/indra/newview/app_settings/settings_minimal.xml b/indra/newview/app_settings/settings_minimal.xml index 01a70f2671..e660c1a33b 100755 --- a/indra/newview/app_settings/settings_minimal.xml +++ b/indra/newview/app_settings/settings_minimal.xml @@ -1 +1,4 @@ -<llsd/>
\ No newline at end of file +<?xml version="1.0"?> +<llsd> + <undef/> +</llsd> diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml index 590f41283b..636caf5ef3 100755 --- a/indra/newview/app_settings/settings_per_account.xml +++ b/indra/newview/app_settings/settings_per_account.xml @@ -109,18 +109,7 @@ <string>Boolean</string> <key>Value</key> <integer>0</integer> - </map> - <key>DisplayDestinationsOnInitialRun</key> - <map> - <key>Comment</key> - <string>Display the destinations guide when a user first launches Second Life.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> + </map> <key>LastInventoryInboxActivity</key> <map> <key>Comment</key> diff --git a/indra/newview/app_settings/shaders/class1/deferred/fxaaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fxaaF.glsl index 2cef8f2a5d..a2b4b3b8c8 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/fxaaF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/fxaaF.glsl @@ -24,6 +24,7 @@ */ #extension GL_ARB_texture_rectangle : enable +#extension GL_ARB_shader_texture_lod : enable #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl index 97bf49a605..0443b592e2 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl @@ -32,6 +32,7 @@ out vec4 frag_color; //class 1 -- no shadows #extension GL_ARB_texture_rectangle : enable +#extension GL_ARB_shader_texture_lod : enable uniform sampler2DRect diffuseRect; uniform sampler2DRect specularRect; diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl index 08583ad0f2..58875ff4ea 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl @@ -24,6 +24,7 @@ */ #extension GL_ARB_texture_rectangle : enable +#extension GL_ARB_shader_texture_lod : enable #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; diff --git a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl index 1975b18652..28432dac9a 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl @@ -22,8 +22,9 @@ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ - + #extension GL_ARB_texture_rectangle : enable +#extension GL_ARB_shader_texture_lod : enable #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; @@ -31,6 +32,8 @@ out vec4 frag_color; #define frag_color gl_FragColor #endif +//class 1 -- no shadows + uniform sampler2DRect diffuseRect; uniform sampler2DRect specularRect; uniform sampler2DRect depthMap; diff --git a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl index 780df9ed1a..37179c7e14 100755 --- a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl @@ -24,6 +24,7 @@ */ #extension GL_ARB_texture_rectangle : enable +#extension GL_ARB_shader_texture_lod : enable #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; diff --git a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl index fc0e6b2388..9bdee15541 100755 --- a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl @@ -24,6 +24,7 @@ */ #extension GL_ARB_texture_rectangle : enable +#extension GL_ARB_shader_texture_lod : enable #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; diff --git a/indra/newview/linux_tools/wrapper.sh b/indra/newview/linux_tools/wrapper.sh index d8440eebf1..c23401d5a6 100755 --- a/indra/newview/linux_tools/wrapper.sh +++ b/indra/newview/linux_tools/wrapper.sh @@ -121,37 +121,21 @@ export SAVED_LD_LIBRARY_PATH="${LD_LIBRARY_PATH}" export LD_LIBRARY_PATH="$PWD/lib:${LD_LIBRARY_PATH}" -# Have to deal specially with gridargs.dat; typical contents look like: -# --channel "Second Life Test" --settings settings_test.xml -# Simply embedding $(<etc/gridargs.dat) into a command line treats each of -# Second, Life and Developer as separate args -- no good. We need bash to -# process quotes using eval. -# First, check if we have been instructed to skip reading in gridargs.dat: -skip_gridargs=false -argnum=0 +# Copy "$@" to ARGS array specifically to delete the --skip-gridargs switch. +# The gridargs.dat file is no more, but we still want to avoid breaking +# scripts that invoke this one with --skip-gridargs. +ARGS=() for ARG in "$@"; do - if [ "--skip-gridargs" == "$ARG" ]; then - skip_gridargs=true - else - ARGS[$argnum]="$ARG" - argnum=$(($argnum+1)) + if [ "--skip-gridargs" != "$ARG" ]; then + ARGS[${#ARGS[*]}]="$ARG" fi done -# Second, read it without scanning, then scan that string. Break quoted words -# into a bash array. Note that if gridargs.dat is empty, or contains only -# whitespace, the resulting gridargs array will be empty -- zero entries -- -# therefore "${gridargs[@]}" entirely vanishes from the command line below, -# just as we want. -if ! $skip_gridargs ; then - eval gridargs=("$(<etc/gridargs.dat)") -fi - # Run the program. # Don't quote $LL_WRAPPER because, if empty, it should simply vanish from the -# command line. But DO quote "$@": preserve separate args as individually -# quoted. Similar remarks about the contents of gridargs. -$LL_WRAPPER bin/do-not-directly-run-secondlife-bin "${gridargs[@]}" "${ARGS[@]}" +# command line. But DO quote "${ARGS[@]}": preserve separate args as +# individually quoted. +$LL_WRAPPER bin/do-not-directly-run-secondlife-bin "${ARGS[@]}" LL_RUN_ERR=$? # Handle any resulting errors diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index d7965c1e8f..054fcb181b 100755 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -46,6 +46,7 @@ #include "llenvmanager.h" #include "llfirstuse.h" #include "llfloatercamera.h" +#include "llfloaterimcontainer.h" #include "llfloaterreg.h" #include "llfloatertools.h" #include "llgroupactions.h" @@ -91,6 +92,7 @@ #include "llworld.h" #include "llworldmap.h" #include "stringize.h" +#include "boost/foreach.hpp" using namespace LLAvatarAppearanceDefines; @@ -433,7 +435,7 @@ void LLAgent::init() { mMoveTimer.start(); - gSavedSettings.declareBOOL("SlowMotionAnimation", FALSE, "Declared in code", FALSE); + gSavedSettings.declareBOOL("SlowMotionAnimation", FALSE, "Declared in code", LLControlVariable::PERSIST_NO); gSavedSettings.getControl("SlowMotionAnimation")->getSignal()->connect(boost::bind(&handleSlowMotionAnimation, _2)); // *Note: this is where LLViewerCamera::getInstance() used to be constructed. @@ -2037,7 +2039,16 @@ void LLAgent::endAnimationUpdateUI() { skip_list.insert(LLFloaterReg::findInstance("mini_map")); } - + + LLFloaterIMContainer* im_box = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container"); + LLFloaterIMContainer::floater_list_t conversations; + im_box->getDetachedConversationFloaters(conversations); + BOOST_FOREACH(LLFloater* conversation, conversations) + { + LL_INFOS() << "skip_list.insert(session_floater): " << conversation->getTitle() << LL_ENDL; + skip_list.insert(conversation); + } + gFloaterView->popVisibleAll(skip_list); #endif mViewsPushed = FALSE; diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm new file mode 100644 index 0000000000..30476b3d22 --- /dev/null +++ b/indra/newview/llappdelegate-objc.mm @@ -0,0 +1,144 @@ +/** + * @file llappdelegate-objc.mm + * @brief Class implementation for the Mac version's application delegate. + * + * $LicenseInfo:firstyear=2000&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#import "llappdelegate-objc.h" +#include "llwindowmacosx-objc.h" +#include <Carbon/Carbon.h> // Used for Text Input Services ("Safe" API - it's supported) + +@implementation LLAppDelegate + +@synthesize window; +@synthesize inputWindow; +@synthesize inputView; +@synthesize currentInputLanguage; + +- (void)dealloc +{ + [super dealloc]; +} + +- (void) applicationDidFinishLaunching:(NSNotification *)notification +{ + frameTimer = nil; + + [self languageUpdated]; + + if (initViewer()) + { + frameTimer = [NSTimer scheduledTimerWithTimeInterval:0.0 target:self selector:@selector(mainLoop) userInfo:nil repeats:YES]; + } else { + handleQuit(); + } + + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(languageUpdated) name:@"NSTextInputContextKeyboardSelectionDidChangeNotification" object:nil]; +} + +- (void) applicationDidBecomeActive:(NSNotification *)notification +{ + callWindowFocus(); +} + +- (void) applicationDidResignActive:(NSNotification *)notification +{ + callWindowUnfocus(); +} + +- (NSApplicationDelegateReply) applicationShouldTerminate:(NSApplication *)sender +{ + if (!runMainLoop()) + { + handleQuit(); + return NSTerminateCancel; + } else { + [frameTimer release]; + cleanupViewer(); + return NSTerminateNow; + } +} + +- (void) mainLoop +{ + bool appExiting = runMainLoop(); + if (appExiting) + { + [frameTimer release]; + [[NSApplication sharedApplication] terminate:self]; + } +} + +- (void) showInputWindow:(bool)show withEvent:(NSEvent*)textEvent +{ + if (![self romanScript]) + { + if (show) + { + NSLog(@"Showing input window."); + [inputWindow makeKeyAndOrderFront:inputWindow]; + if (textEvent != nil) + { + [[inputView inputContext] discardMarkedText]; + [[inputView inputContext] handleEvent:textEvent]; + } + } else { + NSLog(@"Hiding input window."); + [inputWindow orderOut:inputWindow]; + [window makeKeyAndOrderFront:window]; + } + } +} + +// This will get called multiple times by NSNotificationCenter. +// It will be called every time that the window focus changes, and every time that the input language gets changed. +// The primary use case for this selector is to update our current input language when the user, for whatever reason, changes the input language. +// This is the more elegant way of handling input language changes instead of checking every time we want to use the input window. + +- (void) languageUpdated +{ + TISInputSourceRef currentInput = TISCopyCurrentKeyboardInputSource(); + CFArrayRef languages = (CFArrayRef)TISGetInputSourceProperty(currentInput, kTISPropertyInputSourceLanguages); + +#if 0 // In the event of ever needing to add new language sources, change this to 1 and watch the terminal for "languages:" + NSLog(@"languages: %@", TISGetInputSourceProperty(currentInput, kTISPropertyInputSourceLanguages)); +#endif + + // Typically the language we want is going to be the very first result in the array. + currentInputLanguage = (NSString*)CFArrayGetValueAtIndex(languages, 0); +} + +- (bool) romanScript +{ + // How to add support for new languages with the input window: + // Simply append this array with the language code (ja for japanese, ko for korean, zh for chinese, etc.) + NSArray *nonRomanScript = [[NSArray alloc] initWithObjects:@"ja", @"ko", @"zh-Hant", @"zh-Hans", nil]; + if ([nonRomanScript containsObject:currentInputLanguage]) + { + return false; + } + + return true; +} + +@end diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 4f776aa15a..4eea1c873e 100755 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -674,7 +674,6 @@ LLAppViewer::LLAppViewer() mSecondInstance(false), mSavedFinalSnapshot(false), mSavePerAccountSettings(false), // don't save settings on logout unless login succeeded. - mForceGraphicsDetail(false), mQuitRequested(false), mLogoutRequestSent(false), mYieldTime(-1), @@ -729,6 +728,9 @@ bool LLAppViewer::init() // into the log files during normal startup until AFTER // we run the "program crashed last time" error handler below. // +#ifdef LL_DARWIN + mMainLoopInitialized = false; +#endif // initialize LLWearableType translation bridge. // Memory will be cleaned up in ::cleanupClass() @@ -1258,42 +1260,58 @@ LLTrace::TimeBlock FTM_FRAME("Frame"); bool LLAppViewer::mainLoop() { - LL_INFOS() << "***********************Entering main_loop***********************" << LL_ENDL; - - mMainloopTimeout = new LLWatchdogTimeout(); + LL_INFOS() << "Entering main_loop" << LL_ENDL; +#ifdef LL_DARWIN + if (!mMainLoopInitialized) +#endif + { + mMainloopTimeout = new LLWatchdogTimeout(); + + //------------------------------------------- + // Run main loop until time to quit + //------------------------------------------- + + // Create IO Pump to use for HTTP Requests. + gServicePump = new LLPumpIO(gAPRPoolp); + LLHTTPClient::setPump(*gServicePump); + LLCurl::setCAFile(gDirUtilp->getCAFile()); + + // Note: this is where gLocalSpeakerMgr and gActiveSpeakerMgr used to be instantiated. + + LLVoiceChannel::initClass(); + LLVoiceClient::getInstance()->init(gServicePump); + LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&LLFloaterIMContainer::onCurrentChannelChanged, _1), true); + + joystick = LLViewerJoystick::getInstance(); + joystick->setNeedsReset(true); + +#ifdef LL_DARWIN + // Ensure that this section of code never gets called again on OS X. + mMainLoopInitialized = true; +#endif + } + // As we do not (yet) send data on the mainloop LLEventPump that varies + // with each frame, no need to instantiate a new LLSD event object each + // time. Obviously, if that changes, just instantiate the LLSD at the + // point of posting. + + LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop")); + + LLSD newFrame; - //------------------------------------------- - // Run main loop until time to quit - //------------------------------------------- - - // Create IO Pump to use for HTTP Requests. - gServicePump = new LLPumpIO(gAPRPoolp); - LLHTTPClient::setPump(*gServicePump); - LLCurl::setCAFile(gDirUtilp->getCAFile()); - - // Note: this is where gLocalSpeakerMgr and gActiveSpeakerMgr used to be instantiated. - - LLVoiceChannel::initClass(); - LLVoiceClient::getInstance()->init(gServicePump); - LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&LLFloaterIMContainer::onCurrentChannelChanged, _1), true); LLTimer frameTimer,idleTimer; LLTimer debugTime; - LLViewerJoystick* joystick(LLViewerJoystick::getInstance()); - joystick->setNeedsReset(true); - - LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop")); - // As we do not (yet) send data on the mainloop LLEventPump that varies - // with each frame, no need to instantiate a new LLSD event object each - // time. Obviously, if that changes, just instantiate the LLSD at the - // point of posting. - LLSD newFrame; - + //LLPrivateMemoryPoolTester::getInstance()->run(false) ; //LLPrivateMemoryPoolTester::getInstance()->run(true) ; //LLPrivateMemoryPoolTester::destroy() ; // Handle messages +#ifdef LL_DARWIN + if (!LLApp::isExiting()) +#else while (!LLApp::isExiting()) +#endif { LL_RECORD_BLOCK_TIME(FTM_FRAME); LLTrace::TimeBlock::processTimes(); @@ -1561,34 +1579,37 @@ bool LLAppViewer::mainLoop() } } - // Save snapshot for next time, if we made it through initialization - if (STATE_STARTED == LLStartUp::getStartupState()) + if (LLApp::isExiting()) { - try - { - saveFinalSnapshot(); - } - catch(std::bad_alloc) + // Save snapshot for next time, if we made it through initialization + if (STATE_STARTED == LLStartUp::getStartupState()) { - LL_WARNS() << "Bad memory allocation when saveFinalSnapshot() is called!" << LL_ENDL ; - - //stop memory leaking simulation - LLFloaterMemLeak* mem_leak_instance = - LLFloaterReg::findTypedInstance<LLFloaterMemLeak>("mem_leaking"); - if(mem_leak_instance) + try { - mem_leak_instance->stop() ; - } + saveFinalSnapshot(); + } + catch(std::bad_alloc) + { + LL_WARNS() << "Bad memory allocation when saveFinalSnapshot() is called!" << LL_ENDL ; + + //stop memory leaking simulation + LLFloaterMemLeak* mem_leak_instance = + LLFloaterReg::findTypedInstance<LLFloaterMemLeak>("mem_leaking"); + if(mem_leak_instance) + { + mem_leak_instance->stop() ; + } + } } + + delete gServicePump; + + destroyMainloopTimeout(); + + LL_INFOS() << "Exiting main_loop" << LL_ENDL; } - - delete gServicePump; - - destroyMainloopTimeout(); - - LL_INFOS() << "***********************Exiting main_loop***********************" << LL_ENDL; - return true; + return LLApp::isExiting(); } S32 LLAppViewer::updateTextureThreads(F32 max_time) @@ -2321,17 +2342,24 @@ void LLAppViewer::loadColorSettings() LLUIColorTable::instance().loadFromSettings(); } +namespace +{ + void handleCommandLineError(LLControlGroupCLP& clp) + { + LL_WARNS() << "Error parsing command line options. Command Line options ignored." << LL_ENDL; + + LL_INFOS() << "Command line usage:\n" << clp << LL_ENDL; + + OSMessageBox(STRINGIZE(LLTrans::getString("MBCmdLineError") << clp.getErrorMessage()), + LLStringUtil::null, + OSMB_OK); + } +} // anonymous namespace + bool LLAppViewer::initConfiguration() { //Load settings files list std::string settings_file_list = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "settings_files.xml"); - //LLControlGroup settings_control("SettingsFiles"); - //LL_INFOS() << "Loading settings file list " << settings_file_list << LL_ENDL; - //if (0 == settings_control.loadFromFile(settings_file_list)) - //{ - // LL_ERRS() << "Cannot load default configuration file " << settings_file_list << LL_ENDL; - //} - LLXMLNodePtr root; BOOL success = LLXMLNode::parseFile(settings_file_list, root, NULL); if (!success) @@ -2390,9 +2418,7 @@ bool LLAppViewer::initConfiguration() { c->setValue(true, false); } -#endif -#ifndef LL_RELEASE_FOR_DOWNLOAD gSavedSettings.setBOOL("QAMode", TRUE ); gSavedSettings.setS32("WatchdogEnabled", 0); #endif @@ -2428,13 +2454,7 @@ bool LLAppViewer::initConfiguration() if(!initParseCommandLine(clp)) { - LL_WARNS() << "Error parsing command line options. Command Line options ignored." << LL_ENDL; - - LL_INFOS() << "Command line usage:\n" << clp << LL_ENDL; - - std::ostringstream msg; - msg << LLTrans::getString("MBCmdLineError") << clp.getErrorMessage(); - OSMessageBox(msg.str(),LLStringUtil::null,OSMB_OK); + handleCommandLineError(clp); return false; } @@ -2481,12 +2501,16 @@ bool LLAppViewer::initConfiguration() loadSettingsFromDirectory("UserSession"); // - apply command line settings - clp.notify(); + if (! clp.notify()) + { + handleCommandLineError(clp); + return false; + } // Register the core crash option as soon as we can // if we want gdb post-mortem on cores we need to be up and running // ASAP or we might miss init issue etc. - if(clp.hasOption("disablecrashlogger")) + if(gSavedSettings.getBOOL("DisableCrashLogger")) { LL_WARNS() << "Crashes will be handled by system, stack trace logs and crash logger are both disabled" << LL_ENDL; LLAppViewer::instance()->disableCrashlogger(); @@ -2559,91 +2583,52 @@ bool LLAppViewer::initConfiguration() } } - if(clp.hasOption("channel")) - { - LLVersionInfo::resetChannel(clp.getOption("channel")[0]); + std::string CmdLineChannel(gSavedSettings.getString("CmdLineChannel")); + if(! CmdLineChannel.empty()) + { + LLVersionInfo::resetChannel(CmdLineChannel); } // If we have specified crash on startup, set the global so we'll trigger the crash at the right time - if(clp.hasOption("crashonstartup")) - { - gCrashOnStartup = TRUE; - } + gCrashOnStartup = gSavedSettings.getBOOL("CrashOnStartup"); - if (clp.hasOption("logperformance")) + if (gSavedSettings.getBOOL("LogPerformance")) { LLTrace::TimeBlock::sLog = true; LLTrace::TimeBlock::sLogName = std::string("performance"); } - - if (clp.hasOption("logmetrics")) - { - LLTrace::TimeBlock::sMetricLog = true ; - // '--logmetrics' can be specified with a named test metric argument so the data gathering is done only on that test - // In the absence of argument, every metric is gathered (makes for a rather slow run and hard to decipher report...) - std::string test_name = clp.getOption("logmetrics")[0]; + + std::string test_name(gSavedSettings.getString("LogMetrics")); + if (! test_name.empty()) + { + LLTrace::TimeBlock::sMetricLog = TRUE ; + // '--logmetrics' is specified with a named test metric argument so the data gathering is done only on that test + // In the absence of argument, every metric would be gathered (makes for a rather slow run and hard to decipher report...) LL_INFOS() << "'--logmetrics' argument : " << test_name << LL_ENDL; - if (test_name == "") - { - LL_WARNS() << "No '--logmetrics' argument given, will output all metrics to " << DEFAULT_METRIC_NAME << LL_ENDL; - LLTrace::TimeBlock::sLogName = DEFAULT_METRIC_NAME; - } - else - { - LLTrace::TimeBlock::sLogName = test_name; - } + LLTrace::TimeBlock::sLogName = test_name; } if (clp.hasOption("graphicslevel")) { - const LLCommandLineParser::token_vector_t& value = clp.getOption("graphicslevel"); - if(value.size() != 1) - { - LL_WARNS() << "Usage: -graphicslevel <0-3>" << LL_ENDL; - } - else - { - std::string detail = value.front(); - mForceGraphicsDetail = TRUE; - - switch (detail.c_str()[0]) - { - case '0': - gSavedSettings.setU32("RenderQualityPerformance", 0); - break; - case '1': - gSavedSettings.setU32("RenderQualityPerformance", 1); - break; - case '2': - gSavedSettings.setU32("RenderQualityPerformance", 2); - break; - case '3': - gSavedSettings.setU32("RenderQualityPerformance", 3); - break; - default: - mForceGraphicsDetail = FALSE; - LL_WARNS() << "Usage: -graphicslevel <0-3>" << LL_ENDL; - break; - } - } - } - - if (clp.hasOption("analyzeperformance")) - { - LLFastTimerView::sAnalyzePerformance = TRUE; + // User explicitly requested --graphicslevel on the command line. We + // expect this switch has already set RenderQualityPerformance. Check + // that value for validity. + U32 graphicslevel = gSavedSettings.getU32("RenderQualityPerformance"); + if (LLFeatureManager::instance().isValidGraphicsLevel(graphicslevel)) + { + // graphicslevel is valid: save it and engage it later. Capture + // the requested value separately from the settings variable + // because, if this is the first run, LLViewerWindow's constructor + // will call LLFeatureManager::applyRecommendedSettings(), which + // overwrites this settings variable! + mForceGraphicsLevel = graphicslevel; + } } - if (clp.hasOption("replaysession")) - { - gAgentPilot.setReplaySession(TRUE); - } + LLFastTimerView::sAnalyzePerformance = gSavedSettings.getBOOL("AnalyzePerformance"); + gAgentPilot.setReplaySession(gSavedSettings.getBOOL("ReplaySession")); - if (clp.hasOption("nonotifications")) - { - gSavedSettings.getControl("IgnoreAllNotifications")->setValue(true, false); - } - - if (clp.hasOption("debugsession")) + if (gSavedSettings.getBOOL("DebugSession")) { gDebugSession = TRUE; gDebugGL = TRUE; @@ -2668,20 +2653,16 @@ bool LLAppViewer::initConfiguration() // What can happen is that someone can use IE (or potentially // other browsers) and do the rough equivalent of command // injection and steal passwords. Phoenix. SL-55321 - if(clp.hasOption("url")) - { - LLStartUp::setStartSLURL(LLSLURL(clp.getOption("url")[0])); - if(LLStartUp::getStartSLURL().getType() == LLSLURL::LOCATION) - { - LLGridManager::getInstance()->setGridChoice(LLStartUp::getStartSLURL().getGrid()); - - } - } - else if(clp.hasOption("slurl")) - { - LLSLURL start_slurl(clp.getOption("slurl")[0]); + std::string CmdLineLoginLocation(gSavedSettings.getString("CmdLineLoginLocation")); + if(! CmdLineLoginLocation.empty()) + { + LLSLURL start_slurl(CmdLineLoginLocation); LLStartUp::setStartSLURL(start_slurl); - } + if(start_slurl.getType() == LLSLURL::LOCATION) + { + LLGridManager::getInstance()->setGridChoice(start_slurl.getGrid()); + } + } const LLControlVariable* skinfolder = gSavedSettings.getControl("SkinCurrent"); if(skinfolder && LLStringUtil::null != skinfolder->getValue().asString()) @@ -2722,8 +2703,6 @@ bool LLAppViewer::initConfiguration() //} #if LL_DARWIN - // Initialize apple menubar and various callbacks - init_apple_menu(LLTrans::getString("APP_NAME").c_str()); #if __ppc__ // If the CPU doesn't have Altivec (i.e. it's not at least a G4), don't go any further. @@ -2824,9 +2803,8 @@ bool LLAppViewer::initConfiguration() LL_DEBUGS("AppInit")<<"set start from NextLoginLocation: "<<nextLoginLocation<<LL_ENDL; LLStartUp::setStartSLURL(LLSLURL(nextLoginLocation)); } - else if ( ( clp.hasOption("login") || clp.hasOption("autologin")) - && !clp.hasOption("url") - && !clp.hasOption("slurl")) + else if ((clp.hasOption("login") || clp.hasOption("autologin")) + && gSavedSettings.getString("CmdLineLoginLocation").empty()) { // If automatic login from command line with --login switch // init StartSLURL location. @@ -3062,13 +3040,19 @@ namespace { void LLAppViewer::initUpdater() { // Initialize the updater service. - // Generate URL to the udpater service // Get Channel // Get Version - std::string url = gSavedSettings.getString("UpdaterServiceURL"); + + /***************************************************************** + * Previously, the url was derived from the settings + * UpdaterServiceURL + * UpdaterServicePath + * it is now obtained from the grid manager. The settings above + * are no longer used. + *****************************************************************/ std::string channel = LLVersionInfo::getChannel(); std::string version = LLVersionInfo::getVersion(); - std::string service_path = gSavedSettings.getString("UpdaterServicePath"); + U32 check_period = gSavedSettings.getU32("UpdaterServiceCheckPeriod"); bool willing_to_test; LL_DEBUGS("UpdaterService") << "channel " << channel << LL_ENDL; @@ -3093,9 +3077,7 @@ void LLAppViewer::initUpdater() } mUpdater->setAppExitCallback(boost::bind(&LLAppViewer::forceQuit, this)); - mUpdater->initialize(url, - service_path, - channel, + mUpdater->initialize(channel, version, gPlatform, getOSInfo().getOSVersionString(), @@ -3199,11 +3181,12 @@ bool LLAppViewer::initWindow() // Initialize GL stuff // - if (mForceGraphicsDetail) + if (mForceGraphicsLevel) { - LLFeatureManager::getInstance()->setGraphicsLevel(gSavedSettings.getU32("RenderQualityPerformance"), false); + LLFeatureManager::getInstance()->setGraphicsLevel(*mForceGraphicsLevel, false); + gSavedSettings.setU32("RenderQualityPerformance", *mForceGraphicsLevel); } - + // Set this flag in case we crash while initializing GL gSavedSettings.setBOOL("RenderInitError", TRUE); gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE ); diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index a258e24536..e4dab8eb17 100755 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -32,7 +32,6 @@ #include "llsys.h" // for LLOSInfo #include "lltimer.h" #include "llappcorehttp.h" -#include "llunits.h" class LLCommandLineParser; class LLFrameTimer; @@ -42,6 +41,7 @@ class LLImageDecodeThread; class LLTextureFetch; class LLWatchdogTimeout; class LLUpdaterService; +class LLViewerJoystick; extern LLTrace::TimeBlock FTM_FRAME; @@ -257,11 +257,13 @@ private: std::string mSerialNumber; bool mPurgeCache; bool mPurgeOnExit; + bool mMainLoopInitialized; + LLViewerJoystick* joystick; bool mSavedFinalSnapshot; bool mSavePerAccountSettings; // only save per account settings if login succeeded - bool mForceGraphicsDetail; + boost::optional<U32> mForceGraphicsLevel; bool mQuitRequested; // User wants to quit, may have modified documents open. bool mLogoutRequestSent; // Disconnect message sent to simulator, no longer safe to send messages to the sim. diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp index 8d6d52185a..c5fd6041b5 100755 --- a/indra/newview/llappviewermacosx.cpp +++ b/indra/newview/llappviewermacosx.cpp @@ -30,7 +30,10 @@ #error "Use only with Mac OS X" #endif +#define LL_CARBON_CRASH_HANDLER 1 + #include "llappviewermacosx.h" +#include "llwindowmacosx-objc.h" #include "llcommandlineparser.h" #include "llviewernetwork.h" @@ -38,7 +41,10 @@ #include "llmd5.h" #include "llfloaterworldmap.h" #include "llurldispatcher.h" +#include <ApplicationServices/ApplicationServices.h> +#ifdef LL_CARBON_CRASH_HANDLER #include <Carbon/Carbon.h> +#endif #include "lldir.h" #include <signal.h> #include <CoreAudio/CoreAudio.h> // for systemwide mute @@ -50,9 +56,9 @@ namespace // They are not used immediately by the app. int gArgC; char** gArgV; - bool sCrashReporterIsRunning = false; - + LLAppViewerMacOSX* gViewerAppPtr; +#ifdef LL_CARBON_CRASH_HANDLER OSErr AEQuitHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn) { OSErr result = noErr; @@ -61,9 +67,10 @@ namespace return(result); } +#endif } -int main( int argc, char **argv ) +bool initViewer() { #if LL_SOLARIS && defined(__sparc) asm ("ta\t6"); // NOTE: Make sure memory alignment is enforced on SPARC @@ -76,40 +83,57 @@ int main( int argc, char **argv ) << gDirUtilp->getAppRODataDir() << ": " << strerror(errno) << LL_ENDL; } - - LLAppViewerMacOSX* viewer_app_ptr = new LLAppViewerMacOSX(); - - viewer_app_ptr->setErrorHandler(LLAppViewer::handleViewerCrash); - - // Store off the command line args for use later. - gArgC = argc; - gArgV = argv; - bool ok = viewer_app_ptr->init(); + gViewerAppPtr = new LLAppViewerMacOSX(); + + gViewerAppPtr->setErrorHandler(LLAppViewer::handleViewerCrash); + + + + bool ok = gViewerAppPtr->init(); if(!ok) { LL_WARNS() << "Application init failed." << LL_ENDL; - return -1; } + + return ok; +} - // Run the application main loop - if(!LLApp::isQuitting()) +void handleQuit() +{ + LLAppViewer::instance()->userQuit(); +} + +bool runMainLoop() +{ + bool ret = LLApp::isQuitting(); + if (!ret && gViewerAppPtr != NULL) { - viewer_app_ptr->mainLoop(); + ret = gViewerAppPtr->mainLoop(); + } else { + ret = true; } + + return ret; +} - if (!LLApp::isError()) +void cleanupViewer() +{ + if(!LLApp::isError()) { - // - // We don't want to do cleanup here if the error handler got called - - // the assumption is that the error handler is responsible for doing - // app cleanup if there was a problem. - // - viewer_app_ptr->cleanup(); + gViewerAppPtr->cleanup(); } - delete viewer_app_ptr; - viewer_app_ptr = NULL; - return 0; + + delete gViewerAppPtr; + gViewerAppPtr = NULL; +} + +int main( int argc, char **argv ) +{ + // Store off the command line args for use later. + gArgC = argc; + gArgV = argv; + return createNSApp(argc, (const char**)argv); } LLAppViewerMacOSX::LLAppViewerMacOSX() @@ -148,28 +172,13 @@ bool LLAppViewerMacOSX::initParseCommandLine(LLCommandLineParser& clp) // The next two lines add the support for parsing the mac -psn_XXX arg. clp.addOptionDesc("psn", NULL, 1, "MacOSX process serial number"); clp.setCustomParser(parse_psn); - - // First read in the args from arguments txt. - const char* filename = "arguments.txt"; - llifstream ifs(filename, llifstream::binary); - if (!ifs.is_open()) - { - LL_WARNS() << "Unable to open file" << filename << LL_ENDL; - return false; - } - - if(clp.parseCommandLineFile(ifs) == false) - { - return false; - } - // Then parse the user's command line, so that any --url arg can appear last - // Succesive calls to clp.parse... will NOT override earlier options. + // parse the user's command line if(clp.parseCommandLine(gArgC, gArgV) == false) { return false; } - + // Get the user's preferred language string based on the Mac OS localization mechanism. // To add a new localization: // go to the "Resources" section of the project @@ -254,23 +263,24 @@ bool LLAppViewerMacOSX::restoreErrorTrap() return reset_count == 0; } -static OSStatus CarbonEventHandler(EventHandlerCallRef inHandlerCallRef, - EventRef inEvent, +#ifdef LL_CARBON_CRASH_HANDLER +static OSStatus CarbonEventHandler(EventHandlerCallRef inHandlerCallRef, + EventRef inEvent, void* inUserData) { ProcessSerialNumber psn; - GetEventParameter(inEvent, - kEventParamProcessID, - typeProcessSerialNumber, - NULL, - sizeof(psn), - NULL, + GetEventParameter(inEvent, + kEventParamProcessID, + typeProcessSerialNumber, + NULL, + sizeof(psn), + NULL, &psn); - if( GetEventKind(inEvent) == kEventAppTerminated ) + if( GetEventKind(inEvent) == kEventAppTerminated ) { - Boolean matching_psn = FALSE; + Boolean matching_psn = FALSE; OSErr os_result = SameProcess(&psn, (ProcessSerialNumber*)inUserData, &matching_psn); if(os_result >= 0 && matching_psn) { @@ -280,48 +290,58 @@ static OSStatus CarbonEventHandler(EventHandlerCallRef inHandlerCallRef, } return noErr; } +#endif void LLAppViewerMacOSX::handleCrashReporting(bool reportFreeze) { - // This used to use fork&exec, but is switched to LSOpenApplication to +#ifdef LL_CARBON_CRASH_HANDLER + // This used to use fork&exec, but is switched to LSOpenApplication to // Make sure the crash reporter launches in front of the SL window. std::string command_str; //command_str = "open Second Life.app/Contents/Resources/mac-crash-logger.app"; command_str = "mac-crash-logger.app/Contents/MacOS/mac-crash-logger"; + CFURLRef urlRef = CFURLCreateFromFileSystemRepresentation(NULL, (UInt8*)command_str.c_str(), strlen(command_str.c_str()), FALSE); + + // FSRef apparently isn't deprecated. + // There's other funcitonality that depends on it existing as well that isn't deprecated. + // There doesn't seem to be much to directly verify what the status of FSRef is, outside of some documentation pointing at FSRef being valid, and other documentation pointing to everything in Files.h being deprecated. + // We'll assume it isn't for now, since all non-deprecated functions that use it seem to assume similar. + FSRef appRef; - Boolean isDir = 0; - OSStatus os_result = FSPathMakeRef((UInt8*)command_str.c_str(), - &appRef, - &isDir); - if(os_result >= 0) + Boolean pathstatus = CFURLGetFSRef(urlRef, &appRef); + + OSStatus os_result = noErr; + + if(pathstatus == true) { LSApplicationParameters appParams; memset(&appParams, 0, sizeof(appParams)); appParams.version = 0; appParams.flags = kLSLaunchNoParams | kLSLaunchStartClassic; + appParams.application = &appRef; if(reportFreeze) { - // Make sure freeze reporting launches the crash logger synchronously, lest + // Make sure freeze reporting launches the crash logger synchronously, lest // Log files get changed by SL while the logger is running. - + // *NOTE:Mani A better way - make a copy of the data that the crash reporter will send // and let SL go about its business. This way makes the mac work like windows and linux - // and is the smallest patch for the issue. + // and is the smallest patch for the issue. sCrashReporterIsRunning = false; ProcessSerialNumber o_psn; - + static EventHandlerRef sCarbonEventsRef = NULL; - static const EventTypeSpec kEvents[] = + static const EventTypeSpec kEvents[] = { { kEventClassApplication, kEventAppTerminated } }; // Install the handler to detect crash logger termination - InstallEventHandler(GetApplicationEventTarget(), + InstallEventHandler(GetApplicationEventTarget(), (EventHandlerUPP) CarbonEventHandler, GetEventTypeCount(kEvents), kEvents, @@ -329,31 +349,31 @@ void LLAppViewerMacOSX::handleCrashReporting(bool reportFreeze) &sCarbonEventsRef ); - // Remove, temporarily the quit handler - which has *crash* behavior before + // Remove, temporarily the quit handler - which has *crash* behavior before // the mainloop gets running! - AERemoveEventHandler(kCoreEventClass, - kAEQuitApplication, + AERemoveEventHandler(kCoreEventClass, + kAEQuitApplication, NewAEEventHandlerUPP(AEQuitHandler), false); - + // Launch the crash reporter. os_result = LSOpenApplication(&appParams, &o_psn); if(os_result >= 0) - { + { sCrashReporterIsRunning = true; } - + while(sCrashReporterIsRunning) { RunApplicationEventLoop(); } - + // Re-install the apps quit handler. - AEInstallEventHandler(kCoreEventClass, - kAEQuitApplication, + AEInstallEventHandler(kCoreEventClass, + kAEQuitApplication, NewAEEventHandlerUPP(AEQuitHandler), - 0, + 0, false); // Remove the crash reporter quit handler. @@ -363,12 +383,12 @@ void LLAppViewerMacOSX::handleCrashReporting(bool reportFreeze) { appParams.flags |= kLSLaunchAsync; clear_signals(); - + ProcessSerialNumber o_psn; os_result = LSOpenApplication(&appParams, &o_psn); } - } +#endif } std::string LLAppViewerMacOSX::generateSerialNumber() @@ -501,73 +521,3 @@ OSErr AEGURLHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn) return(result); } - -OSStatus simpleDialogHandler(EventHandlerCallRef handler, EventRef event, void *userdata) -{ - OSStatus result = eventNotHandledErr; - OSStatus err; - UInt32 evtClass = GetEventClass(event); - UInt32 evtKind = GetEventKind(event); - WindowRef window = (WindowRef)userdata; - - if((evtClass == kEventClassCommand) && (evtKind == kEventCommandProcess)) - { - HICommand cmd; - err = GetEventParameter(event, kEventParamDirectObject, typeHICommand, NULL, sizeof(cmd), NULL, &cmd); - - if(err == noErr) - { - switch(cmd.commandID) - { - case kHICommandOK: - QuitAppModalLoopForWindow(window); - result = noErr; - break; - - case kHICommandCancel: - QuitAppModalLoopForWindow(window); - result = userCanceledErr; - break; - } - } - } - - return(result); -} - -void init_apple_menu(const char* product) -{ - // Load up a proper menu bar. - { - OSStatus err; - IBNibRef nib = NULL; - // NOTE: DO NOT translate or brand this string. It's an internal name in the .nib file, and MUST match exactly. - err = CreateNibReference(CFSTR("SecondLife"), &nib); - - if(err == noErr) - { - // NOTE: DO NOT translate or brand this string. It's an internal name in the .nib file, and MUST match exactly. - SetMenuBarFromNib(nib, CFSTR("MenuBar")); - } - - if(nib != NULL) - { - DisposeNibReference(nib); - } - } - - // Install a handler for 'gurl' AppleEvents. This is how secondlife:// URLs get passed to the viewer. - - if(AEInstallEventHandler('GURL', 'GURL', NewAEEventHandlerUPP(AEGURLHandler),0, false) != noErr) - { - // Couldn't install AppleEvent handler. This error shouldn't be fatal. - LL_INFOS() << "Couldn't install 'GURL' AppleEvent handler. Continuing..." << LL_ENDL; - } - - // Install a handler for 'quit' AppleEvents. This makes quitting the application from the dock work. - if(AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, NewAEEventHandlerUPP(AEQuitHandler),0, false) != noErr) - { - // Couldn't install AppleEvent handler. This error shouldn't be fatal. - LL_INFOS() << "Couldn't install Quit AppleEvent handler. Continuing..." << LL_ENDL; - } -} diff --git a/indra/newview/llchannelmanager.cpp b/indra/newview/llchannelmanager.cpp index 6c8d19d742..b0537a83f1 100755 --- a/indra/newview/llchannelmanager.cpp +++ b/indra/newview/llchannelmanager.cpp @@ -139,8 +139,6 @@ void LLChannelManager::onLoginCompleted() } LLPersistentNotificationStorage::getInstance()->loadNotifications(); - - LLDoNotDisturbNotificationStorage::getInstance()->initialize(); LLDoNotDisturbNotificationStorage::getInstance()->loadNotifications(); } diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp index 0adf469858..00fa6dd979 100755 --- a/indra/newview/llchatbar.cpp +++ b/indra/newview/llchatbar.cpp @@ -380,7 +380,7 @@ void LLChatBar::sendChat( EChatType type ) if (!utf8_revised_text.empty()) { // Chat with animation - sendChatFromViewer(utf8_revised_text, type, TRUE); + sendChatFromViewer(utf8_revised_text, type, gSavedSettings.getBOOL("PlayChatAnim")); } } } diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index 5c3dd4ebe0..1e49e0a116 100755 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -628,6 +628,7 @@ LLChatHistory::LLChatHistory(const LLChatHistory::Params& p) editor_params.enabled = false; // read only editor_params.show_context_menu = "true"; mEditor = LLUICtrlFactory::create<LLTextEditor>(editor_params, this); + mEditor->setIsFriendCallback(LLAvatarActions::isFriend); } LLSD LLChatHistory::getValue() const diff --git a/indra/newview/llchatitemscontainerctrl.cpp b/indra/newview/llchatitemscontainerctrl.cpp index a1a9463d43..fd4f17b694 100755 --- a/indra/newview/llchatitemscontainerctrl.cpp +++ b/indra/newview/llchatitemscontainerctrl.cpp @@ -323,12 +323,11 @@ BOOL LLFloaterIMNearbyChatToastPanel::handleMouseUp (S32 x, S32 y, MASK mask) return TRUE; else { - (LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"))->showHistory(); + LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat")->showHistory(); return FALSE; } } - - (LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"))->showHistory(); + LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat")->showHistory(); return LLPanel::handleMouseUp(x,y,mask); } diff --git a/indra/newview/llcommandlineparser.cpp b/indra/newview/llcommandlineparser.cpp index 559a02bbd9..06164e9597 100755 --- a/indra/newview/llcommandlineparser.cpp +++ b/indra/newview/llcommandlineparser.cpp @@ -38,16 +38,23 @@ #endif #include <boost/program_options.hpp> +#include <boost/lexical_cast.hpp> #include <boost/bind.hpp> -#include<boost/tokenizer.hpp> +#include <boost/tokenizer.hpp> +#include <boost/assign/list_of.hpp> #if _MSC_VER # pragma warning(pop) #endif #include "llsdserialize.h" +#include "llerror.h" +#include "stringize.h" +#include <string> +#include <set> #include <iostream> #include <sstream> +#include <typeinfo> #include "llcontrol.h" @@ -63,10 +70,22 @@ namespace po = boost::program_options; // This could be good or bad, and probably won't matter for most use cases. namespace { + // List of command-line switches that can't map-to settings variables. + // Going forward, we want every new command-line switch to map-to some + // settings variable. This list is used to validate that. + const std::set<std::string> unmapped_options = boost::assign::list_of + ("help") + ("set") + ("setdefault") + ("settings") + ("sessionsettings") + ("usersessionsettings") + ; + po::options_description gOptionsDesc; po::positional_options_description gPositionalOptions; po::variables_map gVariableMap; - + const LLCommandLineParser::token_vector_t gEmptyValue; void read_file_into_string(std::string& str, const std::basic_istream < char >& file) @@ -384,9 +403,19 @@ bool LLCommandLineParser::parseCommandLineFile(const std::basic_istream < char > return parseCommandLineString(args); } -void LLCommandLineParser::notify() +bool LLCommandLineParser::notify() { - po::notify(gVariableMap); + try + { + po::notify(gVariableMap); + return true; + } + catch (const LLCLPError& e) + { + LL_WARNS() << "Caught Error: " << e.what() << LL_ENDL; + mErrorMsg = e.what(); + return false; + } } void LLCommandLineParser::printOptions() const @@ -428,43 +457,129 @@ const LLCommandLineParser::token_vector_t& LLCommandLineParser::getOption(const //---------------------------------------------------------------------------- // LLControlGroupCLP defintions //---------------------------------------------------------------------------- +namespace { +LLCommandLineParser::token_vector_t::value_type +onevalue(const std::string& option, + const LLCommandLineParser::token_vector_t& value) +{ + if (value.empty()) + { + // What does it mean when the user specifies a command-line switch + // that requires a value, but omits the value? Complain. + throw LLCLPError(STRINGIZE("No value specified for --" << option << "!")); + } + else if (value.size() > 1) + { + LL_WARNS() << "Ignoring extra tokens specified for --" + << option << "." << LL_ENDL; + } + return value[0]; +} + +void badvalue(const std::string& option, + const std::string& varname, + const std::string& type, + const std::string& value) +{ + // If the user passes an unusable value for a command-line switch, it + // seems like a really bad idea to just ignore it, even with a log + // warning. + throw LLCLPError(STRINGIZE("Invalid value specified by command-line switch '" << option + << "' for variable '" << varname << "' of type " << type + << ": '" << value << "'")); +} + +template <typename T> +T convertTo(const std::string& option, + const std::string& varname, + const LLCommandLineParser::token_vector_t::value_type& value) +{ + try + { + return boost::lexical_cast<T>(value); + } + catch (const boost::bad_lexical_cast&) + { + badvalue(option, varname, typeid(T).name(), value); + // bogus return; compiler unaware that badvalue() won't return + return T(); + } +} + void setControlValueCB(const LLCommandLineParser::token_vector_t& value, - const std::string& opt_name, - LLControlGroup* ctrlGroup) + const std::string& option, + LLControlVariable* ctrl) { - // *FIX: Do sematic conversion here. + // *FIX: Do semantic conversion here. // LLSD (ImplString) Is no good for doing string to type conversion for... // booleans // compound types // ?... - LLControlVariable* ctrl = ctrlGroup->getControl(opt_name); if(NULL != ctrl) { switch(ctrl->type()) { case TYPE_BOOLEAN: - if(value.size() > 1) + if (value.empty()) { - LL_WARNS() << "Ignoring extra tokens." << LL_ENDL; + // Boolean-valued command-line switches are unusual. If you + // simply specify the switch without an explicit value, we can + // infer you mean 'true'. + ctrl->setValue(LLSD(true), false); } - - if(value.size() > 0) + else { + // Only call onevalue() AFTER handling value.empty() case! + std::string token(onevalue(option, value)); + // There's a token. check the string for true/false/1/0 etc. BOOL result = false; - BOOL gotSet = LLStringUtil::convertToBOOL(value[0], result); - if(gotSet) + BOOL gotSet = LLStringUtil::convertToBOOL(token, result); + if (gotSet) { ctrl->setValue(LLSD(result), false); } + else + { + badvalue(option, ctrl->getName(), "bool", token); + } + } + break; + + case TYPE_U32: + { + std::string token(onevalue(option, value)); + // To my surprise, for an unsigned target, lexical_cast() doesn't + // complain about an input string such as "-17". In that case, you + // get a very large positive result. So for U32, make sure there's + // no minus sign! + if (token.find('-') == std::string::npos) + { + ctrl->setValue(LLSD::Integer(convertTo<U32>(option, ctrl->getName(), token)), + false); } else { - ctrl->setValue(LLSD(true), false); + badvalue(option, ctrl->getName(), "unsigned", token); } break; + } + + case TYPE_S32: + ctrl->setValue(convertTo<S32>(option, ctrl->getName(), + onevalue(option, value)), false); + break; + + case TYPE_F32: + ctrl->setValue(convertTo<F32>(option, ctrl->getName(), + onevalue(option, value)), false); + break; + // It appears that no one has yet tried to define a command-line + // switch mapped to a settings variable of TYPE_VEC3, TYPE_VEC3D, + // TYPE_RECT, TYPE_COL4, TYPE_COL3. Such types would certainly seem to + // call for a bit of special handling here... default: { // For the default types, let llsd do the conversion. @@ -481,16 +596,9 @@ void setControlValueCB(const LLCommandLineParser::token_vector_t& value, ctrl->setValue(llsdArray, false); } - else if(value.size() > 0) + else { - if(value.size() > 1) - { - LL_WARNS() << "Ignoring extra tokens mapped to the setting: " << opt_name << "." << LL_ENDL; - } - - LLSD llsdValue; - llsdValue.assign(LLSD::String(value[0])); - ctrl->setValue(llsdValue, false); + ctrl->setValue(onevalue(option, value), false); } } break; @@ -498,12 +606,14 @@ void setControlValueCB(const LLCommandLineParser::token_vector_t& value, } else { - LL_WARNS() << "Command Line option mapping '" - << opt_name - << "' not found! Ignoring." - << LL_ENDL; + // This isn't anything a user can affect -- it's a misconfiguration on + // the part of the coder. Rub the coder's nose in the problem right + // away so even preliminary testing will surface it. + LL_ERRS() << "Command Line option --" << option + << " maps to unknown setting!" << LL_ENDL; } } +} // anonymous namespace void LLControlGroupCLP::configure(const std::string& config_filename, LLControlGroup* controlGroup) { @@ -561,11 +671,37 @@ void LLControlGroupCLP::configure(const std::string& config_filename, LLControlG } boost::function1<void, const token_vector_t&> callback; - if(option_params.has("map-to") && (NULL != controlGroup)) + if (! option_params.has("map-to")) + { + // If this option isn't mapped to a settings variable, is it + // one of the ones for which that's unreasonable, or did + // someone carelessly add a new option? (Make all these + // configuration errors fatal so a maintainer will catch them + // right away.) + std::set<std::string>::const_iterator found = unmapped_options.find(long_name); + if (found == unmapped_options.end()) + { + LL_ERRS() << "New command-line option " << long_name + << " should map-to a variable in settings.xml" << LL_ENDL; + } + } + else // option specifies map-to { std::string controlName = option_params["map-to"].asString(); - callback = boost::bind(setControlValueCB, _1, - controlName, controlGroup); + if (! controlGroup) + { + LL_ERRS() << "Must pass gSavedSettings to LLControlGroupCLP::configure() for " + << long_name << " (map-to " << controlName << ")" << LL_ENDL; + } + + LLControlVariable* ctrl = controlGroup->getControl(controlName); + if (! ctrl) + { + LL_ERRS() << "Option " << long_name << " specifies map-to " << controlName + << " which does not exist" << LL_ENDL; + } + + callback = boost::bind(setControlValueCB, _1, long_name, ctrl); } this->addOptionDesc( diff --git a/indra/newview/llcommandlineparser.h b/indra/newview/llcommandlineparser.h index 44f2a26843..71388b8217 100755 --- a/indra/newview/llcommandlineparser.h +++ b/indra/newview/llcommandlineparser.h @@ -86,7 +86,7 @@ public: * * Use this to handle the results of parsing. */ - void notify(); + bool notify(); /** @brief Print a description of the configured options. * diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp index fffc1c7ced..5b015da2ed 100755 --- a/indra/newview/llconversationmodel.cpp +++ b/indra/newview/llconversationmodel.cpp @@ -363,7 +363,10 @@ void LLConversationItemSession::buildContextMenu(LLMenuGL& menu, U32 flags) LL_DEBUGS() << "LLConversationItemParticipant::buildContextMenu()" << LL_ENDL; menuentry_vec_t items; menuentry_vec_t disabled_items; - + if((flags & ITEM_IN_MULTI_SELECTION) && (this->getType() != CONV_SESSION_NEARBY)) + { + items.push_back(std::string("close_selected_conversations")); + } if(this->getType() == CONV_SESSION_1_ON_1) { items.push_back(std::string("close_conversation")); @@ -386,6 +389,10 @@ void LLConversationItemSession::buildContextMenu(LLMenuGL& menu, U32 flags) addVoiceOptions(items); items.push_back(std::string("chat_history")); } + else if(this->getType() == CONV_SESSION_NEARBY) + { + items.push_back(std::string("chat_history")); + } hide_context_entries(menu, items, disabled_items); } diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h index 8766585049..d8cdcdfc97 100755 --- a/indra/newview/llconversationmodel.h +++ b/indra/newview/llconversationmodel.h @@ -252,11 +252,10 @@ public: const std::string& getName() const { return mEmpty; } const std::string& getFilterText() { return mEmpty; } void setModified(EFilterModified behavior = FILTER_RESTART) { } - - void setFilterCount(S32 count) { } - S32 getFilterCount() const { return 0; } - void decrementFilterCount() { } - + + void resetTime(S32 timeout) { } + bool isTimedOut() { return false; } + bool isDefault() const { return true; } bool isNotDefault() const { return false; } void markDefault() { } diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp index b6c53e5e30..9faa12b2ee 100755 --- a/indra/newview/llconversationview.cpp +++ b/indra/newview/llconversationview.cpp @@ -118,9 +118,19 @@ void LLConversationViewSession::setFlashState(bool flash_state) mFlashTimer->stopFlashing(); } +void LLConversationViewSession::setHighlightState(bool hihglight_state) +{ + mFlashStateOn = hihglight_state; + mFlashStarted = true; + mFlashTimer->stopFlashing(); +} + void LLConversationViewSession::startFlashing() { - if (isInVisibleChain() && mFlashStateOn && !mFlashStarted) + LLFloaterIMContainer* im_box = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container"); + + // Need to start flashing only when "Conversations" is opened or brought on top + if (isInVisibleChain() && !im_box->isMinimized() && mFlashStateOn && !mFlashStarted) { mFlashStarted = true; mFlashTimer->startFlashing(); @@ -263,6 +273,29 @@ BOOL LLConversationViewSession::handleMouseDown( S32 x, S32 y, MASK mask ) return result; } +BOOL LLConversationViewSession::handleMouseUp( S32 x, S32 y, MASK mask ) +{ + BOOL result = LLFolderViewFolder::handleMouseUp(x, y, mask); + + LLFloater* volume_floater = LLFloaterReg::findInstance("floater_voice_volume"); + LLFloater* chat_volume_floater = LLFloaterReg::findInstance("chat_voice"); + if (result + && getRoot() + && !(volume_floater && volume_floater->isShown() && volume_floater->hasFocus()) + && !(chat_volume_floater && chat_volume_floater->isShown() && chat_volume_floater->hasFocus())) + { + LLConversationItem* item = dynamic_cast<LLConversationItem *>(getViewModelItem()); + LLUUID session_id = item? item->getUUID() : LLUUID(); + LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::findConversation(session_id); + if(!session_floater->hasFocus()) + { + session_floater->setFocus(true); + } + } + + return result; +} + BOOL LLConversationViewSession::handleRightMouseDown( S32 x, S32 y, MASK mask ) { BOOL result = LLFolderViewFolder::handleRightMouseDown(x, y, mask); @@ -340,16 +373,20 @@ void LLConversationViewSession::setVisibleIfDetached(BOOL visible) { // Do this only if the conversation floater has been torn off (i.e. no multi floater host) and is not minimized // Note: minimized dockable floaters are brought to front hence unminimized when made visible and we don't want that here - LLFolderViewModelItem* item = mViewModelItem; - LLUUID session_uuid = dynamic_cast<LLConversationItem*>(item)->getUUID(); - LLFloater* session_floater = LLFloaterIMSessionTab::getConversation(session_uuid); - - if (session_floater && !session_floater->getHost() && !session_floater->isMinimized()) + LLFloater* session_floater = getSessionFloater(); + if (session_floater && session_floater->isDetachedAndNotMinimized()) { session_floater->setVisible(visible); } } +LLFloater* LLConversationViewSession::getSessionFloater() +{ + LLFolderViewModelItem* item = mViewModelItem; + LLUUID session_uuid = dynamic_cast<LLConversationItem*>(item)->getUUID(); + return LLFloaterIMSessionTab::getConversation(session_uuid); +} + LLConversationViewParticipant* LLConversationViewSession::findParticipant(const LLUUID& participant_id) { // This is *not* a general tree parsing algorithm. We search only in the mItems list diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h index 3eb2e63792..5a74974302 100755 --- a/indra/newview/llconversationview.h +++ b/indra/newview/llconversationview.h @@ -69,6 +69,7 @@ public: /*virtual*/ void draw(); /*virtual*/ BOOL handleMouseDown( S32 x, S32 y, MASK mask ); /*virtual*/ BOOL handleRightMouseDown( S32 x, S32 y, MASK mask ); + /*virtual*/ BOOL handleMouseUp( S32 x, S32 y, MASK mask ); /*virtual*/ S32 arrange(S32* width, S32* height); @@ -86,6 +87,9 @@ public: virtual void refresh(); /*virtual*/ void setFlashState(bool flash_state); + void setHighlightState(bool hihglight_state); + + LLFloater* getSessionFloater(); private: diff --git a/indra/newview/lldirpicker.cpp b/indra/newview/lldirpicker.cpp index 6fd0897919..5c4f0f4d5d 100755 --- a/indra/newview/lldirpicker.cpp +++ b/indra/newview/lldirpicker.cpp @@ -37,7 +37,7 @@ #include "llviewercontrol.h" #include "llwin32headerslean.h" -#if LL_LINUX || LL_SOLARIS +#if LL_LINUX || LL_SOLARIS || LL_DARWIN # include "llfilepicker.h" #endif @@ -147,152 +147,36 @@ std::string LLDirPicker::getDirName() #elif LL_DARWIN LLDirPicker::LLDirPicker() : - mFileName(NULL), - mLocked(false) +mFileName(NULL), +mLocked(false) { + mFilePicker = new LLFilePicker(); reset(); - - memset(&mNavOptions, 0, sizeof(mNavOptions)); - OSStatus error = NavGetDefaultDialogCreationOptions(&mNavOptions); - if (error == noErr) - { - mNavOptions.modality = kWindowModalityAppModal; - } } LLDirPicker::~LLDirPicker() { - // nothing + delete mFilePicker; } -//static -pascal void LLDirPicker::doNavCallbackEvent(NavEventCallbackMessage callBackSelector, - NavCBRecPtr callBackParms, void* callBackUD) +void LLDirPicker::reset() { - switch(callBackSelector) - { - case kNavCBStart: - { - if (!sInstance.mFileName) break; - - OSStatus error = noErr; - AEDesc theLocation = {typeNull, NULL}; - FSSpec outFSSpec; - - //Convert string to a FSSpec - FSRef myFSRef; - - const char* filename=sInstance.mFileName->c_str(); - - error = FSPathMakeRef ((UInt8*)filename, &myFSRef, NULL); - - if (error != noErr) break; - - error = FSGetCatalogInfo (&myFSRef, kFSCatInfoNone, NULL, NULL, &outFSSpec, NULL); - - if (error != noErr) break; - - error = AECreateDesc(typeFSS, &outFSSpec, sizeof(FSSpec), &theLocation); - - if (error != noErr) break; - - error = NavCustomControl(callBackParms->context, - kNavCtlSetLocation, (void*)&theLocation); - - } - } + if (mFilePicker) + mFilePicker->reset(); } -OSStatus LLDirPicker::doNavChooseDialog() -{ - OSStatus error = noErr; - NavDialogRef navRef = NULL; - NavReplyRecord navReply; - - memset(&navReply, 0, sizeof(navReply)); - - // NOTE: we are passing the address of a local variable here. - // This is fine, because the object this call creates will exist for less than the lifetime of this function. - // (It is destroyed by NavDialogDispose() below.) - - error = NavCreateChooseFolderDialog(&mNavOptions, &doNavCallbackEvent, NULL, NULL, &navRef); - - gViewerWindow->getWindow()->beforeDialog(); - - if (error == noErr) - error = NavDialogRun(navRef); - - gViewerWindow->getWindow()->afterDialog(); - - if (error == noErr) - error = NavDialogGetReply(navRef, &navReply); - - if (navRef) - NavDialogDispose(navRef); - - if (error == noErr && navReply.validRecord) - { - FSRef fsRef; - AEKeyword theAEKeyword; - DescType typeCode; - Size actualSize = 0; - char path[LL_MAX_PATH]; /*Flawfinder: ignore*/ - - memset(&fsRef, 0, sizeof(fsRef)); - error = AEGetNthPtr(&navReply.selection, 1, typeFSRef, &theAEKeyword, &typeCode, &fsRef, sizeof(fsRef), &actualSize); - - if (error == noErr) - error = FSRefMakePath(&fsRef, (UInt8*) path, sizeof(path)); - - if (error == noErr) - mDir = path; - } - - return error; -} +//static BOOL LLDirPicker::getDir(std::string* filename) { - if( mLocked ) return FALSE; - BOOL success = FALSE; - OSStatus error = noErr; - - // if local file browsing is turned off, return without opening dialog - if ( check_local_file_access_enabled() == false ) - { - return FALSE; - } - - mFileName = filename; - -// mNavOptions.saveFileName - - // Modal, so pause agent - send_agent_pause(); - { - error = doNavChooseDialog(); - } - send_agent_resume(); - if (error == noErr) - { - if (mDir.length() > 0) - success = true; - } - - // Account for the fact that the app has been stalled. - LLFrameTimer::updateFrameTime(); - return success; + LLFilePicker::ELoadFilter filter=LLFilePicker::FFLOAD_DIRECTORY; + + return mFilePicker->getOpenFile(filter, true); } std::string LLDirPicker::getDirName() { - return mDir; -} - -void LLDirPicker::reset() -{ - mLocked = false; - mDir.clear(); + return mFilePicker->getFirstFile(); } #elif LL_LINUX || LL_SOLARIS diff --git a/indra/newview/lldirpicker.h b/indra/newview/lldirpicker.h index 2299341aba..8656b23afd 100755 --- a/indra/newview/lldirpicker.h +++ b/indra/newview/lldirpicker.h @@ -34,11 +34,10 @@ #include "stdtypes.h" #if LL_DARWIN -#include <Carbon/Carbon.h> // AssertMacros.h does bad things. -#include "fix_macros.h" #undef verify +#undef check #undef require #include <vector> @@ -72,15 +71,7 @@ private: void buildDirname( void ); bool check_local_file_access_enabled(); -#if LL_DARWIN - NavDialogCreationOptions mNavOptions; - static pascal void doNavCallbackEvent(NavEventCallbackMessage callBackSelector, - NavCBRecPtr callBackParms, void* callBackUD); - OSStatus doNavChooseDialog(); - -#endif - -#if LL_LINUX || LL_SOLARIS +#if LL_LINUX || LL_SOLARIS || LL_DARWIN // On Linux we just implement LLDirPicker on top of LLFilePicker LLFilePicker *mFilePicker; #endif diff --git a/indra/newview/lldonotdisturbnotificationstorage.cpp b/indra/newview/lldonotdisturbnotificationstorage.cpp index 5bdf9c612a..93a98084d9 100755 --- a/indra/newview/lldonotdisturbnotificationstorage.cpp +++ b/indra/newview/lldonotdisturbnotificationstorage.cpp @@ -70,7 +70,7 @@ BOOL LLDoNotDisturbNotificationStorageTimer::tick() LLDoNotDisturbNotificationStorage::LLDoNotDisturbNotificationStorage() : LLSingleton<LLDoNotDisturbNotificationStorage>() - , LLNotificationStorage(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "dnd_notifications.xml")) + , LLNotificationStorage("") , mDirty(false) { nameToPayloadParameterMap[toastName] = "SESSION_ID"; @@ -83,6 +83,7 @@ LLDoNotDisturbNotificationStorage::~LLDoNotDisturbNotificationStorage() void LLDoNotDisturbNotificationStorage::initialize() { + setFileName(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "dnd_notifications.xml")); getCommunicationChannel()->connectFailedFilter(boost::bind(&LLDoNotDisturbNotificationStorage::onChannelChanged, this, _1)); } @@ -115,7 +116,8 @@ void LLDoNotDisturbNotificationStorage::saveNotifications() { LLNotificationPtr notificationPtr = historyIter->second; - if (!notificationPtr->isRespondedTo() && !notificationPtr->isCancelled() && !notificationPtr->isExpired()) + if (!notificationPtr->isRespondedTo() && !notificationPtr->isCancelled() && + !notificationPtr->isExpired() && !notificationPtr->isPersistent()) { data.append(notificationPtr->asLLSD(true)); } @@ -210,12 +212,8 @@ void LLDoNotDisturbNotificationStorage::loadNotifications() } - if(imToastExists) - { - LLFloaterReg::showInstance("im_container"); - } - - if(group_ad_hoc_toast_exists) + bool isConversationLoggingAllowed = gSavedPerAccountSettings.getS32("KeepConversationLogTranscripts") > 0; + if(group_ad_hoc_toast_exists && isConversationLoggingAllowed) { LLFloaterReg::showInstance("conversation"); } @@ -266,11 +264,6 @@ void LLDoNotDisturbNotificationStorage::updateNotifications() } } - if(imToastExists) - { - LLFloaterReg::showInstance("im_container"); - } - if(imToastExists || offerExists) { make_ui_sound("UISndNewIncomingIMSession"); diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp index 3c47545121..d66424ffc3 100755 --- a/indra/newview/llfavoritesbar.cpp +++ b/indra/newview/llfavoritesbar.cpp @@ -400,6 +400,8 @@ LLFavoritesBarCtrl::LLFavoritesBarCtrl(const LLFavoritesBarCtrl::Params& p) mMoreTextBox->setClickedCallback(boost::bind(&LLFavoritesBarCtrl::showDropDownMenu, this)); addChild(mMoreTextBox); + mDropDownItemsCount = 0; + LLTextBox::Params label_param(p.label); mBarLabel = LLUICtrlFactory::create<LLTextBox> (label_param); addChild(mBarLabel); @@ -820,11 +822,13 @@ void LLFavoritesBarCtrl::updateButtons() } // Update overflow menu LLToggleableMenu* overflow_menu = static_cast <LLToggleableMenu*> (mOverflowMenuHandle.get()); - if (overflow_menu && overflow_menu->getVisible()) + if (overflow_menu && overflow_menu->getVisible() && (overflow_menu->getItemCount() != mDropDownItemsCount)) { overflow_menu->setVisible(FALSE); if (mUpdateDropDownItems) + { showDropDownMenu(); + } } } else @@ -940,6 +944,7 @@ void LLFavoritesBarCtrl::showDropDownMenu() menu->updateParent(LLMenuGL::sMenuContainer); menu->setButtonRect(mMoreTextBox->getRect(), this); positionAndShowMenu(menu); + mDropDownItemsCount = menu->getItemCount(); } } diff --git a/indra/newview/llfavoritesbar.h b/indra/newview/llfavoritesbar.h index f06e9b9b64..211d3c4ce3 100755 --- a/indra/newview/llfavoritesbar.h +++ b/indra/newview/llfavoritesbar.h @@ -101,6 +101,7 @@ protected: LLUUID mFavoriteFolderId; const LLFontGL *mFont; S32 mFirstDropDownItem; + S32 mDropDownItemsCount; bool mUpdateDropDownItems; bool mRestoreOverflowMenu; diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp index 333e8ee67e..5746f8b454 100755 --- a/indra/newview/llfeaturemanager.cpp +++ b/indra/newview/llfeaturemanager.cpp @@ -30,6 +30,7 @@ #include <fstream> #include <boost/regex.hpp> +#include <boost/assign/list_of.hpp> #include "llfeaturemanager.h" #include "lldir.h" @@ -51,6 +52,8 @@ #include "llboost.h" #include "llweb.h" #include "llviewershadermgr.h" +#include "llstring.h" +#include "stringize.h" #if LL_WINDOWS #include "lldxhardware.h" @@ -186,6 +189,55 @@ void LLFeatureList::dump() LL_DEBUGS("RenderInit") << LL_ENDL; } +static const std::vector<std::string> sGraphicsLevelNames = boost::assign::list_of + ("Low") + ("LowMid") + ("Mid") + ("MidHigh") + ("High") + ("HighUltra") + ("Ultra") +; + +U32 LLFeatureManager::getMaxGraphicsLevel() const +{ + return sGraphicsLevelNames.size() - 1; +} + +bool LLFeatureManager::isValidGraphicsLevel(U32 level) const +{ + return (level <= getMaxGraphicsLevel()); +} + +std::string LLFeatureManager::getNameForGraphicsLevel(U32 level) const +{ + if (isValidGraphicsLevel(level)) + { + return sGraphicsLevelNames[level]; + } + return STRINGIZE("Invalid graphics level " << level << ", valid are 0 .. " + << getMaxGraphicsLevel()); +} + +S32 LLFeatureManager::getGraphicsLevelForName(const std::string& name) const +{ + const std::string FixedFunction("FixedFunction"); + std::string rname(name); + if (LLStringUtil::endsWith(rname, FixedFunction)) + { + // chop off any "FixedFunction" suffix + rname = rname.substr(0, rname.length() - FixedFunction.length()); + } + for (S32 i(0), iend(getMaxGraphicsLevel()); i <= iend; ++i) + { + if (sGraphicsLevelNames[i] == rname) + { + return i; + } + } + return -1; +} + LLFeatureList *LLFeatureManager::findMask(const std::string& name) { if (mMaskList.count(name)) @@ -619,7 +671,7 @@ void LLFeatureManager::applyRecommendedSettings() { // apply saved settings // cap the level at 2 (high) - S32 level = llmax(GPU_CLASS_0, llmin(mGPUClass, GPU_CLASS_5)); + U32 level = llmax(GPU_CLASS_0, llmin(mGPUClass, GPU_CLASS_5)); LL_INFOS() << "Applying Recommended Features" << LL_ENDL; @@ -695,62 +747,33 @@ void LLFeatureManager::applyFeatures(bool skipFeatures) } } -void LLFeatureManager::setGraphicsLevel(S32 level, bool skipFeatures) +void LLFeatureManager::setGraphicsLevel(U32 level, bool skipFeatures) { LLViewerShaderMgr::sSkipReload = true; applyBaseMasks(); - - switch (level) + + // if we're passed an invalid level, default to "Low" + std::string features(isValidGraphicsLevel(level)? getNameForGraphicsLevel(level) : "Low"); + if (features == "Low") { - case 0: #if LL_DARWIN - // This Mac-specific change is to insure that we force 'Basic Shaders' for all Mac - // systems which support them instead of falling back to fixed-function unnecessarily - // MAINT-2157 - // - if (gGLManager.mGLVersion < 2.1f) - { - maskFeatures("LowFixedFunction"); - } - else - { //same as low, but with "Basic Shaders" enabled - maskFeatures("Low"); - } + // This Mac-specific change is to insure that we force 'Basic Shaders' for all Mac + // systems which support them instead of falling back to fixed-function unnecessarily + // MAINT-2157 + if (gGLManager.mGLVersion < 2.1f) #else - if (gGLManager.mGLVersion < 3.f || gGLManager.mIsIntel) - { //only use fixed function by default if GL version < 3.0 or this is an intel graphics chip - maskFeatures("LowFixedFunction"); - } - else - { //same as low, but with "Basic Shaders" enabled - maskFeatures("Low"); - } + // only use fixed function by default if GL version < 3.0 or this is an intel graphics chip + if (gGLManager.mGLVersion < 3.f || gGLManager.mIsIntel) #endif - break; - case 1: - maskFeatures("LowMid"); - break; - case 2: - maskFeatures("Mid"); - break; - case 3: - maskFeatures("MidHigh"); - break; - case 4: - maskFeatures("High"); - break; - case 5: - maskFeatures("HighUltra"); - break; - case 6: - maskFeatures("Ultra"); - break; - default: - maskFeatures("Low"); - break; + { + // same as Low, but with "Basic Shaders" disabled + features = "LowFixedFunction"; + } } + maskFeatures(features); + applyFeatures(skipFeatures); LLViewerShaderMgr::sSkipReload = false; diff --git a/indra/newview/llfeaturemanager.h b/indra/newview/llfeaturemanager.h index ad72c16743..3b8d251236 100755 --- a/indra/newview/llfeaturemanager.h +++ b/indra/newview/llfeaturemanager.h @@ -134,8 +134,18 @@ public: // skipFeatures forces skipping of mostly hardware settings // that we don't want to change when we change graphics // settings - void setGraphicsLevel(S32 level, bool skipFeatures); - + void setGraphicsLevel(U32 level, bool skipFeatures); + + // What 'level' values are valid to pass to setGraphicsLevel()? + // 0 is the low end... + U32 getMaxGraphicsLevel() const; + bool isValidGraphicsLevel(U32 level) const; + + // setGraphicsLevel() levels have names. + std::string getNameForGraphicsLevel(U32 level) const; + // returns -1 for unrecognized name (hence S32 rather than U32) + S32 getGraphicsLevelForName(const std::string& name) const; + void applyBaseMasks(); void applyRecommendedSettings(); diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp index a288d8e4de..82a99c0561 100755 --- a/indra/newview/llfilepicker.cpp +++ b/indra/newview/llfilepicker.cpp @@ -62,6 +62,11 @@ LLFilePicker LLFilePicker::sInstance; #define DICTIONARY_FILTER L"Dictionary files (*.dic; *.xcu)\0*.dic;*.xcu\0" #endif +#ifdef LL_DARWIN +#include "llfilepicker_mac.h" +//#include <boost/algorithm/string/predicate.hpp> +#endif + // // Implementation // @@ -94,14 +99,6 @@ LLFilePicker::LLFilePicker() mFilesW[0] = '\0'; #endif -#if LL_DARWIN - memset(&mNavOptions, 0, sizeof(mNavOptions)); - OSStatus error = NavGetDefaultDialogCreationOptions(&mNavOptions); - if (error == noErr) - { - mNavOptions.modality = kWindowModalityAppModal; - } -#endif } LLFilePicker::~LLFilePicker() @@ -546,369 +543,197 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename) #elif LL_DARWIN -Boolean LLFilePicker::navOpenFilterProc(AEDesc *theItem, void *info, void *callBackUD, NavFilterModes filterMode) +std::vector<std::string>* LLFilePicker::navOpenFilterProc(ELoadFilter filter) //(AEDesc *theItem, void *info, void *callBackUD, NavFilterModes filterMode) { - Boolean result = true; - ELoadFilter filter = *((ELoadFilter*) callBackUD); - OSStatus error = noErr; - - if (filterMode == kNavFilteringBrowserList && filter != FFLOAD_ALL && (theItem->descriptorType == typeFSRef || theItem->descriptorType == typeFSS)) - { - // navInfo is only valid for typeFSRef and typeFSS - NavFileOrFolderInfo *navInfo = (NavFileOrFolderInfo*) info; - if (!navInfo->isFolder) - { - AEDesc desc; - error = AECoerceDesc(theItem, typeFSRef, &desc); - if (error == noErr) - { - FSRef fileRef; - error = AEGetDescData(&desc, &fileRef, sizeof(fileRef)); - if (error == noErr) - { - LSItemInfoRecord fileInfo; - error = LSCopyItemInfoForRef(&fileRef, kLSRequestExtension | kLSRequestTypeCreator, &fileInfo); - if (error == noErr) - { - if (filter == FFLOAD_IMAGE) - { - if (fileInfo.filetype != 'JPEG' && fileInfo.filetype != 'JPG ' && - fileInfo.filetype != 'BMP ' && fileInfo.filetype != 'TGA ' && - fileInfo.filetype != 'BMPf' && fileInfo.filetype != 'TPIC' && - fileInfo.filetype != 'PNG ' && - (fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("jpeg"), kCFCompareCaseInsensitive) != kCFCompareEqualTo && - CFStringCompare(fileInfo.extension, CFSTR("jpg"), kCFCompareCaseInsensitive) != kCFCompareEqualTo && - CFStringCompare(fileInfo.extension, CFSTR("bmp"), kCFCompareCaseInsensitive) != kCFCompareEqualTo && - CFStringCompare(fileInfo.extension, CFSTR("tga"), kCFCompareCaseInsensitive) != kCFCompareEqualTo && - CFStringCompare(fileInfo.extension, CFSTR("png"), kCFCompareCaseInsensitive) != kCFCompareEqualTo)) - ) - { - result = false; - } - } - else if (filter == FFLOAD_WAV) - { - if (fileInfo.filetype != 'WAVE' && fileInfo.filetype != 'WAV ' && - (fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("wave"), kCFCompareCaseInsensitive) != kCFCompareEqualTo && - CFStringCompare(fileInfo.extension, CFSTR("wav"), kCFCompareCaseInsensitive) != kCFCompareEqualTo)) - ) - { - result = false; - } - } - else if (filter == FFLOAD_ANIM) - { - if (fileInfo.filetype != 'BVH ' && - fileInfo.filetype != 'ANIM' && - (fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("bvh"), kCFCompareCaseInsensitive) != kCFCompareEqualTo) && - fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("anim"), kCFCompareCaseInsensitive) != kCFCompareEqualTo)) - ) - { - result = false; - } - } - else if (filter == FFLOAD_COLLADA) - { - if (fileInfo.filetype != 'DAE ' && - (fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("dae"), kCFCompareCaseInsensitive) != kCFCompareEqualTo)) - ) - { - result = false; - } - } + std::vector<std::string> *allowedv = new std::vector< std::string >; + switch(filter) + { + case FFLOAD_ALL: + allowedv->push_back("wav"); + allowedv->push_back("bvh"); + allowedv->push_back("anim"); + allowedv->push_back("dae"); + allowedv->push_back("raw"); + allowedv->push_back("lsl"); + allowedv->push_back("dic"); + allowedv->push_back("xcu"); + case FFLOAD_IMAGE: + allowedv->push_back("jpg"); + allowedv->push_back("jpeg"); + allowedv->push_back("bmp"); + allowedv->push_back("tga"); + allowedv->push_back("bmpf"); + allowedv->push_back("tpic"); + allowedv->push_back("png"); + break; + case FFLOAD_WAV: + allowedv->push_back("wav"); + break; + case FFLOAD_ANIM: + allowedv->push_back("bvh"); + allowedv->push_back("anim"); + break; + case FFLOAD_COLLADA: + allowedv->push_back("dae"); + break; #ifdef _CORY_TESTING - else if (filter == FFLOAD_GEOMETRY) - { - if (fileInfo.filetype != 'SLG ' && - (fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("slg"), kCFCompareCaseInsensitive) != kCFCompareEqualTo)) - ) - { - result = false; - } - } + case FFLOAD_GEOMETRY: + allowedv->push_back("slg"); + break; #endif - else if (filter == FFLOAD_SLOBJECT) - { - LL_WARNS() << "*** navOpenFilterProc: FFLOAD_SLOBJECT NOT IMPLEMENTED ***" << LL_ENDL; - } - else if (filter == FFLOAD_RAW) - { - if (fileInfo.filetype != '\?\?\?\?' && - (fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("raw"), kCFCompareCaseInsensitive) != kCFCompareEqualTo)) - ) - { - result = false; - } - } - else if (filter == FFLOAD_SCRIPT) - { - if (fileInfo.filetype != 'LSL ' && - (fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("lsl"), kCFCompareCaseInsensitive) != kCFCompareEqualTo)) ) - { - result = false; - } - } - else if (filter == FFLOAD_DICTIONARY) - { - if (fileInfo.filetype != 'DIC ' && - fileInfo.filetype != 'XCU ' && - (fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("dic"), kCFCompareCaseInsensitive) != kCFCompareEqualTo) && - fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("xcu"), kCFCompareCaseInsensitive) != kCFCompareEqualTo))) - { - result = false; - } - } - - if (fileInfo.extension) - { - CFRelease(fileInfo.extension); - } - } - } - AEDisposeDesc(&desc); - } - } - } - return result; + case FFLOAD_RAW: + allowedv->push_back("raw"); + break; + case FFLOAD_SCRIPT: + allowedv->push_back("lsl"); + break; + case FFLOAD_DICTIONARY: + allowedv->push_back("dic"); + allowedv->push_back("xcu"); + break; + case FFLOAD_DIRECTORY: + break; + default: + llwarns << "Unsupported format." << llendl; + } + + return allowedv; } -OSStatus LLFilePicker::doNavChooseDialog(ELoadFilter filter) +bool LLFilePicker::doNavChooseDialog(ELoadFilter filter) { - OSStatus error = noErr; - NavDialogRef navRef = NULL; - NavReplyRecord navReply; - // if local file browsing is turned off, return without opening dialog if ( check_local_file_access_enabled() == false ) { - return FALSE; + return false; } - - memset(&navReply, 0, sizeof(navReply)); - - // NOTE: we are passing the address of a local variable here. - // This is fine, because the object this call creates will exist for less than the lifetime of this function. - // (It is destroyed by NavDialogDispose() below.) - error = NavCreateChooseFileDialog(&mNavOptions, NULL, NULL, NULL, navOpenFilterProc, (void*)(&filter), &navRef); - + gViewerWindow->getWindow()->beforeDialog(); - - if (error == noErr) - error = NavDialogRun(navRef); + + std::vector<std::string> *allowed_types=navOpenFilterProc(filter); + + std::vector<std::string> *filev = doLoadDialog(allowed_types, + mPickOptions); gViewerWindow->getWindow()->afterDialog(); - if (error == noErr) - error = NavDialogGetReply(navRef, &navReply); - if (navRef) - NavDialogDispose(navRef); - - if (error == noErr && navReply.validRecord) - { - SInt32 count = 0; - SInt32 index; - - // AE indexes are 1 based... - error = AECountItems(&navReply.selection, &count); - for (index = 1; index <= count; index++) - { - FSRef fsRef; - AEKeyword theAEKeyword; - DescType typeCode; - Size actualSize = 0; - char path[MAX_PATH]; /*Flawfinder: ignore*/ - - memset(&fsRef, 0, sizeof(fsRef)); - error = AEGetNthPtr(&navReply.selection, index, typeFSRef, &theAEKeyword, &typeCode, &fsRef, sizeof(fsRef), &actualSize); - - if (error == noErr) - error = FSRefMakePath(&fsRef, (UInt8*) path, sizeof(path)); - - if (error == noErr) - mFiles.push_back(std::string(path)); - } - } + if (filev && filev->size() > 0) + { + mFiles.insert(mFiles.end(), filev->begin(), filev->end()); + return true; + } - return error; + return false; } -OSStatus LLFilePicker::doNavSaveDialog(ESaveFilter filter, const std::string& filename) +bool LLFilePicker::doNavSaveDialog(ESaveFilter filter, const std::string& filename) { - OSStatus error = noErr; - NavDialogRef navRef = NULL; - NavReplyRecord navReply; - - memset(&navReply, 0, sizeof(navReply)); // Setup the type, creator, and extension - OSType type, creator; - CFStringRef extension = NULL; + std::string extension, type, creator; + switch (filter) { case FFSAVE_WAV: - type = 'WAVE'; - creator = 'TVOD'; - extension = CFSTR(".wav"); + type = "WAVE"; + creator = "TVOD"; + extension = "wav"; break; case FFSAVE_TGA: - type = 'TPIC'; - creator = 'prvw'; - extension = CFSTR(".tga"); + type = "TPIC"; + creator = "prvw"; + extension = "tga"; break; case FFSAVE_BMP: - type = 'BMPf'; - creator = 'prvw'; - extension = CFSTR(".bmp"); + type = "BMPf"; + creator = "prvw"; + extension = "bmp"; break; case FFSAVE_JPEG: - type = 'JPEG'; - creator = 'prvw'; - extension = CFSTR(".jpeg"); + type = "JPEG"; + creator = "prvw"; + extension = "jpeg"; break; case FFSAVE_PNG: - type = 'PNG '; - creator = 'prvw'; - extension = CFSTR(".png"); + type = "PNG "; + creator = "prvw"; + extension = "png"; break; case FFSAVE_AVI: - type = '\?\?\?\?'; - creator = '\?\?\?\?'; - extension = CFSTR(".mov"); + type = "\?\?\?\?"; + creator = "\?\?\?\?"; + extension = "mov"; break; case FFSAVE_ANIM: - type = '\?\?\?\?'; - creator = '\?\?\?\?'; - extension = CFSTR(".xaf"); + type = "\?\?\?\?"; + creator = "\?\?\?\?"; + extension = "xaf"; break; #ifdef _CORY_TESTING case FFSAVE_GEOMETRY: - type = '\?\?\?\?'; - creator = '\?\?\?\?'; - extension = CFSTR(".slg"); + type = "\?\?\?\?"; + creator = "\?\?\?\?"; + extension = "slg"; break; #endif case FFSAVE_RAW: - type = '\?\?\?\?'; - creator = '\?\?\?\?'; - extension = CFSTR(".raw"); + type = "\?\?\?\?"; + creator = "\?\?\?\?"; + extension = "raw"; break; case FFSAVE_J2C: - type = '\?\?\?\?'; - creator = 'prvw'; - extension = CFSTR(".j2c"); + type = "\?\?\?\?"; + creator = "prvw"; + extension = "j2c"; break; case FFSAVE_SCRIPT: - type = 'LSL '; - creator = '\?\?\?\?'; - extension = CFSTR(".lsl"); + type = "LSL "; + creator = "\?\?\?\?"; + extension = "lsl"; break; case FFSAVE_ALL: default: - type = '\?\?\?\?'; - creator = '\?\?\?\?'; - extension = CFSTR(""); + type = "\?\?\?\?"; + creator = "\?\?\?\?"; + extension = ""; break; } - // Create the dialog - error = NavCreatePutFileDialog(&mNavOptions, type, creator, NULL, NULL, &navRef); - if (error == noErr) - { - CFStringRef nameString = NULL; - bool hasExtension = true; - - // Create a CFString of the initial file name - if (!filename.empty()) - nameString = CFStringCreateWithCString(NULL, filename.c_str(), kCFStringEncodingUTF8); - else - nameString = CFSTR("Untitled"); - - // Add the extension if one was not provided - if (nameString && !CFStringHasSuffix(nameString, extension)) - { - CFStringRef tempString = nameString; - hasExtension = false; - nameString = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@%@"), tempString, extension); - CFRelease(tempString); - } - - // Set the name in the dialog - if (nameString) - { - error = NavDialogSetSaveFileName(navRef, nameString); - CFRelease(nameString); - } - else - { - error = paramErr; - } - } - + std::string namestring = filename; + if (namestring.empty()) namestring="Untitled"; + +// if (! boost::algorithm::ends_with(namestring, extension) ) +// { +// namestring = namestring + "." + extension; +// +// } + gViewerWindow->getWindow()->beforeDialog(); // Run the dialog - if (error == noErr) - error = NavDialogRun(navRef); + std::string* filev = doSaveDialog(&namestring, + &type, + &creator, + &extension, + mPickOptions); gViewerWindow->getWindow()->afterDialog(); - if (error == noErr) - error = NavDialogGetReply(navRef, &navReply); - - if (navRef) - NavDialogDispose(navRef); - - if (error == noErr && navReply.validRecord) + if ( filev && !filev->empty() ) { - SInt32 count = 0; - - // AE indexes are 1 based... - error = AECountItems(&navReply.selection, &count); - if (count > 0) - { - // Get the FSRef to the containing folder - FSRef fsRef; - AEKeyword theAEKeyword; - DescType typeCode; - Size actualSize = 0; - - memset(&fsRef, 0, sizeof(fsRef)); - error = AEGetNthPtr(&navReply.selection, 1, typeFSRef, &theAEKeyword, &typeCode, &fsRef, sizeof(fsRef), &actualSize); - - if (error == noErr) - { - char path[PATH_MAX]; /*Flawfinder: ignore*/ - char newFileName[SINGLE_FILENAME_BUFFER_SIZE]; /*Flawfinder: ignore*/ - - error = FSRefMakePath(&fsRef, (UInt8*)path, PATH_MAX); - if (error == noErr) - { - if (CFStringGetCString(navReply.saveFileName, newFileName, sizeof(newFileName), kCFStringEncodingUTF8)) - { - mFiles.push_back(std::string(path) + "/" + std::string(newFileName)); - } - else - { - error = paramErr; - } - } - else - { - error = paramErr; - } - } - } - } + mFiles.push_back(*filev); + return true; + } - return error; + return false; } BOOL LLFilePicker::getOpenFile(ELoadFilter filter, bool blocking) @@ -924,16 +749,21 @@ BOOL LLFilePicker::getOpenFile(ELoadFilter filter, bool blocking) return FALSE; } - OSStatus error = noErr; - reset(); - mNavOptions.optionFlags &= ~kNavAllowMultipleFiles; + mPickOptions &= ~F_MULTIPLE; + mPickOptions |= F_FILE; + + if (filter == FFLOAD_DIRECTORY) //This should only be called from lldirpicker. + { + + mPickOptions |= ( F_NAV_SUPPORT | F_DIRECTORY ); + mPickOptions &= ~F_FILE; + } if(filter == FFLOAD_ALL) // allow application bundles etc. to be traversed; important for DEV-16869, but generally useful { - // mNavOptions.optionFlags |= kNavAllowOpenPackages; - mNavOptions.optionFlags |= kNavSupportPackages; + mPickOptions &= F_NAV_SUPPORT; } if (blocking) @@ -942,14 +772,13 @@ BOOL LLFilePicker::getOpenFile(ELoadFilter filter, bool blocking) send_agent_pause(); } + + success = doNavChooseDialog(filter); + + if (success) { - error = doNavChooseDialog(filter); - } - - if (error == noErr) - { - if (getFileCount()) - success = true; + if (!getFileCount()) + success = false; } if (blocking) @@ -975,21 +804,22 @@ BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter) return FALSE; } - OSStatus error = noErr; - reset(); - - mNavOptions.optionFlags |= kNavAllowMultipleFiles; + + mPickOptions |= F_FILE; + + mPickOptions |= F_MULTIPLE; // Modal, so pause agent send_agent_pause(); + + success = doNavChooseDialog(filter); + + send_agent_resume(); + + if (success) { - error = doNavChooseDialog(filter); - } - send_agent_resume(); - if (error == noErr) - { - if (getFileCount()) - success = true; + if (!getFileCount()) + success = false; if (getFileCount() > 1) mLocked = true; } @@ -1001,37 +831,37 @@ BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter) BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename) { + if( mLocked ) - return FALSE; - BOOL success = FALSE; - OSStatus error = noErr; + return false; + BOOL success = false; // if local file browsing is turned off, return without opening dialog if ( check_local_file_access_enabled() == false ) { - return FALSE; + return false; } reset(); - mNavOptions.optionFlags &= ~kNavAllowMultipleFiles; + mPickOptions &= ~F_MULTIPLE; // Modal, so pause agent send_agent_pause(); + + success = doNavSaveDialog(filter, filename); + + if (success) { - error = doNavSaveDialog(filter, filename); - } - send_agent_resume(); - if (error == noErr) - { - if (getFileCount()) - success = true; + if (!getFileCount()) + success = false; } // Account for the fact that the app has been stalled. LLFrameTimer::updateFrameTime(); return success; } +//END LL_DARWIN #elif LL_LINUX || LL_SOLARIS @@ -1537,4 +1367,4 @@ BOOL LLFilePicker::getMultipleOpenFiles( ELoadFilter filter ) return FALSE; } -#endif +#endif // LL_LINUX || LL_SOLARIS diff --git a/indra/newview/llfilepicker.h b/indra/newview/llfilepicker.h index 4d7b81304a..fac4c71c19 100755 --- a/indra/newview/llfilepicker.h +++ b/indra/newview/llfilepicker.h @@ -39,8 +39,8 @@ #include <Carbon/Carbon.h> // AssertMacros.h does bad things. -#include "fix_macros.h" #undef verify +#undef check #undef require #include <vector> @@ -86,7 +86,8 @@ public: FFLOAD_MODEL = 9, FFLOAD_COLLADA = 10, FFLOAD_SCRIPT = 11, - FFLOAD_DICTIONARY = 12 + FFLOAD_DICTIONARY = 12, + FFLOAD_DIRECTORY = 13 //To call from lldirpicker. }; enum ESaveFilter @@ -159,15 +160,14 @@ private: #endif #if LL_DARWIN - NavDialogCreationOptions mNavOptions; + S32 mPickOptions; std::vector<std::string> mFileVector; UInt32 mFileIndex; - OSStatus doNavChooseDialog(ELoadFilter filter); - OSStatus doNavSaveDialog(ESaveFilter filter, const std::string& filename); - void getFilePath(SInt32 index); - void getFileName(SInt32 index); - static Boolean navOpenFilterProc(AEDesc *theItem, void *info, void *callBackUD, NavFilterModes filterMode); + bool doNavChooseDialog(ELoadFilter filter); + bool doNavSaveDialog(ESaveFilter filter, const std::string& filename); + //static Boolean navOpenFilterProc(AEDesc *theItem, void *info, void *callBackUD, NavFilterModes filterMode); + std::vector<std::string>* navOpenFilterProc(ELoadFilter filter); #endif #if LL_GTK diff --git a/indra/newview/llfilepicker_mac.h b/indra/newview/llfilepicker_mac.h new file mode 100644 index 0000000000..e0b7e2e8ce --- /dev/null +++ b/indra/newview/llfilepicker_mac.h @@ -0,0 +1,58 @@ +/** + * @file llfilepicker_mac.h + * @brief OS-specific file picker + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +// OS specific file selection dialog. This is implemented as a +// singleton class, so call the instance() method to get the working +// instance. When you call getMultipleOpenFile(), it locks the picker +// until you iterate to the end of the list of selected files with +// getNextFile() or call reset(). + +#ifndef LL_LLFILEPICKER_MAC_H +#define LL_LLFILEPICKER_MAC_H + +#if LL_DARWIN + +#include <string> +#include <vector> + +//void modelessPicker(); +std::vector<std::string>* doLoadDialog(const std::vector<std::string>* allowed_types, + unsigned int flags); +std::string* doSaveDialog(const std::string* file, + const std::string* type, + const std::string* creator, + const std::string* extension, + unsigned int flags); +enum { + F_FILE = 0x00000001, + F_DIRECTORY = 0x00000002, + F_MULTIPLE = 0x00000004, + F_NAV_SUPPORT=0x00000008 +}; + +#endif + +#endif diff --git a/indra/newview/llfilepicker_mac.mm b/indra/newview/llfilepicker_mac.mm new file mode 100644 index 0000000000..2a84226e0a --- /dev/null +++ b/indra/newview/llfilepicker_mac.mm @@ -0,0 +1,132 @@ +/** + * @file llfilepicker_mac.cpp + * @brief OS-specific file picker + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifdef LL_DARWIN +#import <Cocoa/Cocoa.h> +#include <iostream> +#include "llfilepicker_mac.h" + +std::vector<std::string>* doLoadDialog(const std::vector<std::string>* allowed_types, + unsigned int flags) +{ + int i, result; + + //Aura TODO: We could init a small window and release it at the end of this routine + //for a modeless interface. + + NSOpenPanel *panel = [NSOpenPanel openPanel]; + //NSString *fileName = nil; + NSMutableArray *fileTypes = nil; + + + if ( allowed_types && !allowed_types->empty()) + { + fileTypes = [[NSMutableArray alloc] init]; + + for (i=0;i<allowed_types->size();++i) + { + [fileTypes addObject: + [NSString stringWithCString:(*allowed_types)[i].c_str() + encoding:[NSString defaultCStringEncoding]]]; + } + } + + //[panel setMessage:@"Import one or more files or directories."]; + [panel setAllowsMultipleSelection: ( (flags & F_MULTIPLE)?true:false ) ]; + [panel setCanChooseDirectories: ( (flags & F_DIRECTORY)?true:false ) ]; + [panel setCanCreateDirectories: true]; + [panel setResolvesAliases: true]; + [panel setCanChooseFiles: ( (flags & F_FILE)?true:false )]; + [panel setTreatsFilePackagesAsDirectories: ( flags & F_NAV_SUPPORT ) ]; + + std::vector<std::string>* outfiles = NULL; + + if (fileTypes) + { + [panel setAllowedFileTypes:fileTypes]; + result = [panel runModal]; + } + else + { + // I suggest it's better to open the last path and let this default to home dir as necessary + // for consistency with other OS X apps + // + //[panel setDirectoryURL: fileURLWithPath(NSHomeDirectory()) ]; + result = [panel runModal]; + } + + if (result == NSOKButton) + { + NSArray *filesToOpen = [panel URLs]; + int i, count = [filesToOpen count]; + + if (count > 0) + { + outfiles = new std::vector<std::string>; + } + + for (i=0; i<count; i++) { + NSString *aFile = [[filesToOpen objectAtIndex:i] path]; + std::string *afilestr = new std::string([aFile UTF8String]); + outfiles->push_back(*afilestr); + } + } + return outfiles; +} + + +std::string* doSaveDialog(const std::string* file, + const std::string* type, + const std::string* creator, + const std::string* extension, + unsigned int flags) +{ + NSSavePanel *panel = [NSSavePanel savePanel]; + + NSString *extensionns = [NSString stringWithCString:extension->c_str() encoding:[NSString defaultCStringEncoding]]; + NSArray *fileType = [[NSArray alloc] initWithObjects:extensionns,nil]; + + //[panel setMessage:@"Save Image File"]; + [panel setTreatsFilePackagesAsDirectories: ( flags & F_NAV_SUPPORT ) ]; + [panel setCanSelectHiddenExtension:true]; + [panel setAllowedFileTypes:fileType]; + NSString *fileName = [NSString stringWithCString:file->c_str() encoding:[NSString defaultCStringEncoding]]; + + std::string *outfile = NULL; + NSURL* url = [NSURL fileURLWithPath:fileName]; + [panel setDirectoryURL: url]; + if([panel runModal] == + NSFileHandlingPanelOKButton) + { + NSURL* url = [panel URL]; + NSString* p = [url path]; + outfile = new std::string( [p UTF8String] ); + // write the file + } + return outfile; +} + +#endif diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp index 7f81d40ebb..3288f90b88 100755 --- a/indra/newview/llfloaterabout.cpp +++ b/indra/newview/llfloaterabout.cpp @@ -33,7 +33,9 @@ // Viewer includes #include "llagent.h" +#include "llagentui.h" #include "llappviewer.h" +#include "llslurl.h" #include "llvoiceclient.h" #include "lluictrlfactory.h" #include "llviewertexteditor.h" @@ -249,12 +251,16 @@ LLSD LLFloaterAbout::getInfo() LLViewerRegion* region = gAgent.getRegion(); if (region) { - const LLVector3d &pos = gAgent.getPositionGlobal(); + LLVector3d pos = gAgent.getPositionGlobal(); info["POSITION"] = ll_sd_from_vector3d(pos); + info["POSITION_LOCAL"] = ll_sd_from_vector3(gAgent.getPosAgentFromGlobal(pos)); info["REGION"] = gAgent.getRegion()->getName(); info["HOSTNAME"] = gAgent.getRegion()->getHost().getHostName(); info["HOSTIP"] = gAgent.getRegion()->getHost().getString(); info["SERVER_VERSION"] = gLastVersionChannel; + LLSLURL slurl; + LLAgentUI::buildSLURL(slurl); + info["SLURL"] = slurl.getSLURLString(); } // CPU @@ -307,12 +313,12 @@ LLSD LLFloaterAbout::getInfo() static std::string get_viewer_release_notes_url() { // return a URL to the release notes for this viewer, such as: - // http://wiki.secondlife.com/wiki/Release_Notes/Second Life Beta Viewer/2.1.0 + // http://wiki.secondlife.com/wiki/Release_Notes/Second Life Beta Viewer/2.1.0.123456 std::string url = LLTrans::getString("RELEASE_NOTES_BASE_URL"); if (! LLStringUtil::endsWith(url, "/")) url += "/"; url += LLVersionInfo::getChannel() + "/"; - url += LLVersionInfo::getShortVersion(); + url += LLVersionInfo::getVersion(); return LLWeb::escapeURL(url); } diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp index 8d5352e2a6..7d091a79c5 100755 --- a/indra/newview/llfloateravatarpicker.cpp +++ b/indra/newview/llfloateravatarpicker.cpp @@ -513,6 +513,7 @@ void LLFloaterAvatarPicker::find() url += "/"; } url += "?page_size=100&names="; + std::replace(text.begin(), text.end(), '.', ' '); url += LLURI::escape(text); LL_INFOS() << "avatar picker " << url << LL_ENDL; LLHTTPClient::get(url, new LLAvatarPickerResponder(mQueryID, getKey().asString())); @@ -748,7 +749,12 @@ void LLFloaterAvatarPicker::processResponse(const LLUUID& query_id, const LLSD& { getChildView("ok_btn")->setEnabled(true); search_results->setEnabled(true); - search_results->selectFirstItem(); + search_results->sortByColumnIndex(1, TRUE); + std::string text = getChild<LLUICtrl>("Edit")->getValue().asString(); + if (!search_results->selectItemByLabel(text, TRUE, 1)) + { + search_results->selectFirstItem(); + } onList(); search_results->setFocus(TRUE); } diff --git a/indra/newview/llfloaterbulkpermission.cpp b/indra/newview/llfloaterbulkpermission.cpp index c202ca1b05..c57afbaf6e 100755 --- a/indra/newview/llfloaterbulkpermission.cpp +++ b/indra/newview/llfloaterbulkpermission.cpp @@ -56,6 +56,7 @@ LLFloaterBulkPermission::LLFloaterBulkPermission(const LLSD& seed) mDone(FALSE) { mID.generate(); + mCommitCallbackRegistrar.add("BulkPermission.Ok", boost::bind(&LLFloaterBulkPermission::onOkBtn, this)); 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)); @@ -65,6 +66,21 @@ LLFloaterBulkPermission::LLFloaterBulkPermission(const LLSD& seed) BOOL LLFloaterBulkPermission::postBuild() { + mBulkChangeIncludeAnimations = gSavedSettings.getBOOL("BulkChangeIncludeAnimations"); + mBulkChangeIncludeBodyParts = gSavedSettings.getBOOL("BulkChangeIncludeBodyParts"); + mBulkChangeIncludeClothing = gSavedSettings.getBOOL("BulkChangeIncludeClothing"); + mBulkChangeIncludeGestures = gSavedSettings.getBOOL("BulkChangeIncludeGestures"); + mBulkChangeIncludeNotecards = gSavedSettings.getBOOL("BulkChangeIncludeNotecards"); + mBulkChangeIncludeObjects = gSavedSettings.getBOOL("BulkChangeIncludeObjects"); + mBulkChangeIncludeScripts = gSavedSettings.getBOOL("BulkChangeIncludeScripts"); + mBulkChangeIncludeSounds = gSavedSettings.getBOOL("BulkChangeIncludeSounds"); + mBulkChangeIncludeTextures = gSavedSettings.getBOOL("BulkChangeIncludeTextures"); + mBulkChangeShareWithGroup = gSavedSettings.getBOOL("BulkChangeShareWithGroup"); + mBulkChangeEveryoneCopy = gSavedSettings.getBOOL("BulkChangeEveryoneCopy"); + mBulkChangeNextOwnerModify = gSavedSettings.getBOOL("BulkChangeNextOwnerModify"); + mBulkChangeNextOwnerCopy = gSavedSettings.getBOOL("BulkChangeNextOwnerCopy"); + mBulkChangeNextOwnerTransfer = gSavedSettings.getBOOL("BulkChangeNextOwnerTransfer"); + return TRUE; } @@ -143,6 +159,12 @@ void LLFloaterBulkPermission::inventoryChanged(LLViewerObject* viewer_object, } } +void LLFloaterBulkPermission::onOkBtn() +{ + doApply(); + closeFloater(); +} + void LLFloaterBulkPermission::onApplyBtn() { doApply(); @@ -150,6 +172,20 @@ void LLFloaterBulkPermission::onApplyBtn() void LLFloaterBulkPermission::onCloseBtn() { + gSavedSettings.setBOOL("BulkChangeIncludeAnimations", mBulkChangeIncludeAnimations); + gSavedSettings.setBOOL("BulkChangeIncludeBodyParts", mBulkChangeIncludeBodyParts); + gSavedSettings.setBOOL("BulkChangeIncludeClothing", mBulkChangeIncludeClothing); + gSavedSettings.setBOOL("BulkChangeIncludeGestures", mBulkChangeIncludeGestures); + gSavedSettings.setBOOL("BulkChangeIncludeNotecards", mBulkChangeIncludeNotecards); + gSavedSettings.setBOOL("BulkChangeIncludeObjects", mBulkChangeIncludeObjects); + gSavedSettings.setBOOL("BulkChangeIncludeScripts", mBulkChangeIncludeScripts); + gSavedSettings.setBOOL("BulkChangeIncludeSounds", mBulkChangeIncludeSounds); + gSavedSettings.setBOOL("BulkChangeIncludeTextures", mBulkChangeIncludeTextures); + gSavedSettings.setBOOL("BulkChangeShareWithGroup", mBulkChangeShareWithGroup); + gSavedSettings.setBOOL("BulkChangeEveryoneCopy", mBulkChangeEveryoneCopy); + gSavedSettings.setBOOL("BulkChangeNextOwnerModify", mBulkChangeNextOwnerModify); + gSavedSettings.setBOOL("BulkChangeNextOwnerCopy", mBulkChangeNextOwnerCopy); + gSavedSettings.setBOOL("BulkChangeNextOwnerTransfer", mBulkChangeNextOwnerTransfer); closeFloater(); } diff --git a/indra/newview/llfloaterbulkpermission.h b/indra/newview/llfloaterbulkpermission.h index 88532ed124..0c042c3ee3 100755 --- a/indra/newview/llfloaterbulkpermission.h +++ b/indra/newview/llfloaterbulkpermission.h @@ -70,6 +70,7 @@ private: bool is_new); void onCloseBtn(); + void onOkBtn(); void onApplyBtn(); void onCommitCopy(); void onCheckAll() { doCheckUncheckAll(TRUE); } @@ -92,6 +93,21 @@ private: LLUUID mCurrentObjectID; BOOL mDone; + bool mBulkChangeIncludeAnimations; + bool mBulkChangeIncludeBodyParts; + bool mBulkChangeIncludeClothing; + bool mBulkChangeIncludeGestures; + bool mBulkChangeIncludeNotecards; + bool mBulkChangeIncludeObjects; + bool mBulkChangeIncludeScripts; + bool mBulkChangeIncludeSounds; + bool mBulkChangeIncludeTextures; + bool mBulkChangeShareWithGroup; + bool mBulkChangeEveryoneCopy; + bool mBulkChangeNextOwnerModify; + bool mBulkChangeNextOwnerCopy; + bool mBulkChangeNextOwnerTransfer; + LLUUID mID; const char* mStartString; diff --git a/indra/newview/llfloaterconversationpreview.cpp b/indra/newview/llfloaterconversationpreview.cpp index a3d715530d..b570de14aa 100755 --- a/indra/newview/llfloaterconversationpreview.cpp +++ b/indra/newview/llfloaterconversationpreview.cpp @@ -50,6 +50,7 @@ LLFloaterConversationPreview::LLFloaterConversationPreview(const LLSD& session_i BOOL LLFloaterConversationPreview::postBuild() { mChatHistory = getChild<LLChatHistory>("chat_history"); + LLLoadHistoryThread::setLoadEndSignal(boost::bind(&LLFloaterConversationPreview::SetPages, this, _1, _2)); const LLConversation* conv = LLConversationLog::instance().getConversation(mSessionID); std::string name; @@ -70,7 +71,7 @@ BOOL LLFloaterConversationPreview::postBuild() name = LLTrans::getString("NearbyChatTitle"); file = "chat"; } - + mChatHistoryFileName = file; LLStringUtil::format_map_t args; args["[NAME]"] = name; std::string title = getString("Title", args); @@ -80,23 +81,46 @@ BOOL LLFloaterConversationPreview::postBuild() load_params["load_all_history"] = true; load_params["cut_off_todays_date"] = false; - LLLogChat::loadChatHistory(file, mMessages, load_params); - mCurrentPage = mMessages.size() / mPageSize; + LLSD loading; + loading[LL_IM_TEXT] = LLTrans::getString("loading_chat_logs"); + mMessages.push_back(loading); mPageSpinner = getChild<LLSpinCtrl>("history_page_spin"); mPageSpinner->setCommitCallback(boost::bind(&LLFloaterConversationPreview::onMoreHistoryBtnClick, this)); mPageSpinner->setMinValue(1); - mPageSpinner->setMaxValue(mCurrentPage + 1); - mPageSpinner->set(mCurrentPage + 1); - - std::string total_page_num = llformat("/ %d", mCurrentPage + 1); - getChild<LLTextBox>("page_num_label")->setValue(total_page_num); - + mPageSpinner->set(1); + mPageSpinner->setEnabled(false); + mChatHistoryLoaded = false; + LLLogChat::startChatHistoryThread(file, load_params); return LLFloater::postBuild(); } +void LLFloaterConversationPreview::SetPages(std::list<LLSD>& messages, const std::string& file_name) +{ + if(file_name == mChatHistoryFileName) + { + mMessages = messages; + + + mCurrentPage = mMessages.size() / mPageSize; + mPageSpinner->setEnabled(true); + mPageSpinner->setMaxValue(mCurrentPage+1); + mPageSpinner->set(mCurrentPage+1); + + std::string total_page_num = llformat("/ %d", mCurrentPage+1); + getChild<LLTextBox>("page_num_label")->setValue(total_page_num); + mChatHistoryLoaded = true; + + } + +} void LLFloaterConversationPreview::draw() { + if(mChatHistoryLoaded) + { + showHistory(); + mChatHistoryLoaded = false; + } LLFloater::draw(); } @@ -128,6 +152,11 @@ void LLFloaterConversationPreview::showHistory() for (int msg_num = 0; (iter != mMessages.end() && msg_num < mPageSize); ++iter, ++msg_num) { + if (iter->size() == 0) + { + continue; + } + LLSD msg = *iter; LLUUID from_id = LLUUID::null; diff --git a/indra/newview/llfloaterconversationpreview.h b/indra/newview/llfloaterconversationpreview.h index b17ae84b63..389f3dfd09 100755 --- a/indra/newview/llfloaterconversationpreview.h +++ b/indra/newview/llfloaterconversationpreview.h @@ -42,6 +42,7 @@ public: virtual ~LLFloaterConversationPreview(){}; virtual BOOL postBuild(); + void SetPages(std::list<LLSD>& messages,const std::string& file_name); virtual void draw(); virtual void onOpen(const LLSD& key); @@ -59,6 +60,8 @@ private: std::list<LLSD> mMessages; std::string mAccountName; std::string mCompleteName; + std::string mChatHistoryFileName; + bool mChatHistoryLoaded; }; #endif /* LLFLOATERCONVERSATIONPREVIEW_H_ */ diff --git a/indra/newview/llfloatergotoline.cpp b/indra/newview/llfloatergotoline.cpp new file mode 100644 index 0000000000..d66e418926 --- /dev/null +++ b/indra/newview/llfloatergotoline.cpp @@ -0,0 +1,160 @@ +/** + * @file llfloatergotoline.h + * @author MartinRJ + * @brief LLFloaterGotoLine class implementation + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" +#include "llfloatergotoline.h" +#include "llpreviewscript.h" +#include "llfloaterreg.h" +#include "lllineeditor.h" +#include "llviewertexteditor.h" +#include "llviewerwindow.h" + +LLFloaterGotoLine* LLFloaterGotoLine::sInstance = NULL; + +LLFloaterGotoLine::LLFloaterGotoLine(LLScriptEdCore* editor_core) +: LLFloater(LLSD()), + mGotoBox(NULL), + mEditorCore(editor_core) +{ + buildFromFile("floater_goto_line.xml"); + + sInstance = this; + + // find floater in which script panel is embedded + LLView* viewp = (LLView*)editor_core; + while(viewp) + { + LLFloater* floaterp = dynamic_cast<LLFloater*>(viewp); + if (floaterp) + { + floaterp->addDependentFloater(this); + break; + } + viewp = viewp->getParent(); + } +} + +BOOL LLFloaterGotoLine::postBuild() +{ + mGotoBox = getChild<LLLineEditor>("goto_line"); + mGotoBox->setCommitCallback(boost::bind(&LLFloaterGotoLine::onGotoBoxCommit, this)); + mGotoBox->setCommitOnFocusLost(FALSE); + getChild<LLLineEditor>("goto_line")->setPrevalidate(LLTextValidate::validateNonNegativeS32); + childSetAction("goto_btn", onBtnGoto,this); + setDefaultBtn("goto_btn"); + + return TRUE; +} + +//static +void LLFloaterGotoLine::show(LLScriptEdCore* editor_core) +{ + if (sInstance && sInstance->mEditorCore && sInstance->mEditorCore != editor_core) + { + sInstance->closeFloater(); + delete sInstance; + } + + if (!sInstance) + { + // sInstance will be assigned in the constructor. + new LLFloaterGotoLine(editor_core); + } + + sInstance->openFloater(); +} + +LLFloaterGotoLine::~LLFloaterGotoLine() +{ + sInstance = NULL; +} + +// static +void LLFloaterGotoLine::onBtnGoto(void *userdata) +{ + LLFloaterGotoLine* self = (LLFloaterGotoLine*)userdata; + self->handleBtnGoto(); +} + +void LLFloaterGotoLine::handleBtnGoto() +{ + S32 row = 0; + S32 column = 0; + row = getChild<LLUICtrl>("goto_line")->getValue().asInteger(); + if (row >= 0) + { + if (mEditorCore && mEditorCore->mEditor) + { + mEditorCore->mEditor->deselect(); + mEditorCore->mEditor->setCursor(row, column); + mEditorCore->mEditor->setFocus(TRUE); + } + } +} + +bool LLFloaterGotoLine::hasAccelerators() const +{ + if (mEditorCore) + { + return mEditorCore->hasAccelerators(); + } + return FALSE; +} + +BOOL LLFloaterGotoLine::handleKeyHere(KEY key, MASK mask) +{ + if (mEditorCore) + { + return mEditorCore->handleKeyHere(key, mask); + } + + return FALSE; +} + +void LLFloaterGotoLine::onGotoBoxCommit() +{ + S32 row = 0; + S32 column = 0; + row = getChild<LLUICtrl>("goto_line")->getValue().asInteger(); + if (row >= 0) + { + if (mEditorCore && mEditorCore->mEditor) + { + mEditorCore->mEditor->setCursor(row, column); + + S32 rownew = 0; + S32 columnnew = 0; + mEditorCore->mEditor->getCurrentLineAndColumn( &rownew, &columnnew, FALSE ); // don't include wordwrap + if (rownew == row && columnnew == column) + { + mEditorCore->mEditor->deselect(); + mEditorCore->mEditor->setFocus(TRUE); + sInstance->closeFloater(); + } //else do nothing (if the cursor-position didn't change) + } + } +} diff --git a/indra/newview/llfloatergotoline.h b/indra/newview/llfloatergotoline.h new file mode 100644 index 0000000000..058d601752 --- /dev/null +++ b/indra/newview/llfloatergotoline.h @@ -0,0 +1,66 @@ +/** + * @file llfloatergotoline.h + * @author MartinRJ + * @brief LLFloaterGotoLine class definition + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLFLOATERGOTOLINE_H +#define LL_LLFLOATERGOTOLINE_H + +#include "llfloater.h" +#include "lllineeditor.h" +#include "llpreviewscript.h" + +class LLScriptEdCore; + +class LLFloaterGotoLine : public LLFloater +{ +public: + LLFloaterGotoLine(LLScriptEdCore* editor_core); + ~LLFloaterGotoLine(); + + /*virtual*/ BOOL postBuild(); + static void show(LLScriptEdCore* editor_core); + + static void onBtnGoto(void* userdata); + void handleBtnGoto(); + + LLScriptEdCore* getEditorCore() { return mEditorCore; } + static LLFloaterGotoLine* getInstance() { return sInstance; } + + virtual bool hasAccelerators() const; + virtual BOOL handleKeyHere(KEY key, MASK mask); + +private: + + LLScriptEdCore* mEditorCore; + + static LLFloaterGotoLine* sInstance; + +protected: + LLLineEditor* mGotoBox; + void onGotoBoxCommit(); +}; + +#endif // LL_LLFLOATERGOTOLINE_H diff --git a/indra/newview/llfloaterhardwaresettings.cpp b/indra/newview/llfloaterhardwaresettings.cpp index 9efdf9d10e..035eb307c2 100755 --- a/indra/newview/llfloaterhardwaresettings.cpp +++ b/indra/newview/llfloaterhardwaresettings.cpp @@ -89,8 +89,9 @@ void LLFloaterHardwareSettings::refresh() void LLFloaterHardwareSettings::refreshEnabledState() { + F32 mem_multiplier = gSavedSettings.getF32("RenderTextureMemoryMultiple"); S32Megabytes min_tex_mem = LLViewerTextureList::getMinVideoRamSetting(); - S32Megabytes max_tex_mem = LLViewerTextureList::getMaxVideoRamSetting(); + S32Megabytes max_tex_mem = LLViewerTextureList::getMaxVideoRamSetting(false, mem_multiplier); getChild<LLSliderCtrl>("GraphicsCardTextureMemory")->setMinValue(min_tex_mem.value()); getChild<LLSliderCtrl>("GraphicsCardTextureMemory")->setMaxValue(max_tex_mem.value()); @@ -149,12 +150,17 @@ BOOL LLFloaterHardwareSettings::postBuild() { childSetAction("OK", onBtnOK, this); +// Don't do this on Mac as their braindead GL versioning +// sets this when 8x and 16x are indeed available +// +#if !LL_DARWIN if (gGLManager.mIsIntel || gGLManager.mGLVersion < 3.f) { //remove FSAA settings above "4x" LLComboBox* combo = getChild<LLComboBox>("fsaa"); combo->remove("8x"); combo->remove("16x"); } +#endif refresh(); center(); diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp index c1cd3d1d93..010e671205 100755 --- a/indra/newview/llfloaterimcontainer.cpp +++ b/indra/newview/llfloaterimcontainer.cpp @@ -47,6 +47,7 @@ #include "llfloaterpreference.h" #include "llimview.h" #include "llnotificationsutil.h" +#include "lltoolbarview.h" #include "lltransientfloatermgr.h" #include "llviewercontrol.h" #include "llconversationview.h" @@ -54,6 +55,7 @@ #include "llworld.h" #include "llsdserialize.h" #include "llviewerobjectlist.h" +#include "boost/foreach.hpp" // // LLFloaterIMContainer @@ -63,7 +65,8 @@ LLFloaterIMContainer::LLFloaterIMContainer(const LLSD& seed, const Params& param mExpandCollapseBtn(NULL), mConversationsRoot(NULL), mConversationsEventStream("ConversationsEvents"), - mInitialized(false) + mInitialized(false), + mIsFirstLaunch(true) { mEnableCallbackRegistrar.add("IMFloaterContainer.Check", boost::bind(&LLFloaterIMContainer::isActionChecked, this, _2)); mCommitCallbackRegistrar.add("IMFloaterContainer.Action", boost::bind(&LLFloaterIMContainer::onCustomAction, this, _2)); @@ -113,6 +116,10 @@ void LLFloaterIMContainer::sessionAdded(const LLUUID& session_id, const std::str void LLFloaterIMContainer::sessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) { + if(!isInVisibleChain()) + { + setVisibleAndFrontmost(false); + } selectConversationPair(session_id, true); collapseMessagesPane(false); } @@ -204,6 +211,7 @@ BOOL LLFloaterIMContainer::postBuild() // a scroller for folder view LLRect scroller_view_rect = mConversationsListPanel->getRect(); scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom); + scroller_view_rect.mBottom += getChild<LLLayoutStack>("conversations_pane_buttons_stack")->getRect().getHeight(); LLScrollContainer::Params scroller_params(LLUICtrlFactory::getDefaultParams<LLFolderViewScrollContainer>()); scroller_params.rect(scroller_view_rect); @@ -221,7 +229,8 @@ BOOL LLFloaterIMContainer::postBuild() mExpandCollapseBtn->setClickedCallback(boost::bind(&LLFloaterIMContainer::onExpandCollapseButtonClicked, this)); mStubCollapseBtn = getChild<LLButton>("stub_collapse_btn"); mStubCollapseBtn->setClickedCallback(boost::bind(&LLFloaterIMContainer::onStubCollapseButtonClicked, this)); - getChild<LLButton>("speak_btn")->setClickedCallback(boost::bind(&LLFloaterIMContainer::onSpeakButtonClicked, this)); + mSpeakBtn = getChild<LLButton>("speak_btn"); + mSpeakBtn->setClickedCallback(boost::bind(&LLFloaterIMContainer::onSpeakButtonClicked, this)); childSetAction("add_btn", boost::bind(&LLFloaterIMContainer::onAddButtonClicked, this)); @@ -258,7 +267,6 @@ BOOL LLFloaterIMContainer::postBuild() void LLFloaterIMContainer::onOpen(const LLSD& key) { LLMultiFloater::onOpen(key); - openNearbyChat(); reSelectConversation(); assignResizeLimits(); } @@ -593,6 +601,7 @@ void LLFloaterIMContainer::setMinimized(BOOL b) //Switching from minimized to un-minimized if(was_minimized && !b) { + gToolBarView->flashCommand(LLCommandId("chat"), false); LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::findConversation(mSelectedSession); if(session_floater && !session_floater->isTornOff()) @@ -621,7 +630,6 @@ void LLFloaterIMContainer::setVisible(BOOL visible) LLFloaterReg::toggleInstanceOrBringToFront(name); selectConversationPair(LLUUID(NULL), false, false); } - openNearbyChat(); flashConversationItemWidget(mSelectedSession,false); LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::findConversation(mSelectedSession); @@ -651,7 +659,11 @@ void LLFloaterIMContainer::setVisible(BOOL visible) LLConversationViewSession* widget = dynamic_cast<LLConversationViewSession*>(widget_it->second); if (widget) { - widget->setVisibleIfDetached(visible); + LLFloater* session_floater = widget->getSessionFloater(); + if (session_floater != nearby_chat) + { + widget->setVisibleIfDetached(visible); + } } } @@ -659,10 +671,37 @@ void LLFloaterIMContainer::setVisible(BOOL visible) LLMultiFloater::setVisible(visible); } +void LLFloaterIMContainer::getDetachedConversationFloaters(floater_list_t& floaters) +{ + typedef conversations_widgets_map::value_type conv_pair; + BOOST_FOREACH(conv_pair item, mConversationsWidgets) + { + LLConversationViewSession* widget = dynamic_cast<LLConversationViewSession*>(item.second); + if (widget) + { + LLFloater* session_floater = widget->getSessionFloater(); + if (session_floater && session_floater->isDetachedAndNotMinimized()) + { + floaters.push_back(session_floater); + } + } + } +} + void LLFloaterIMContainer::setVisibleAndFrontmost(BOOL take_focus, const LLSD& key) { LLMultiFloater::setVisibleAndFrontmost(take_focus, key); - selectConversationPair(getSelectedSession(), false, take_focus); + // Do not select "Nearby Chat" conversation, since it will bring its window to front + // Only select other sessions + if (!getSelectedSession().isNull()) + { + selectConversationPair(getSelectedSession(), false, take_focus); + } + if (mInitialized && mIsFirstLaunch) + { + collapseMessagesPane(gSavedPerAccountSettings.getBOOL("ConversationsMessagePaneCollapsed")); + mIsFirstLaunch = false; + } } void LLFloaterIMContainer::updateResizeLimits() @@ -779,13 +818,6 @@ void LLFloaterIMContainer::reshapeFloaterAndSetResizeLimits(bool collapse, S32 d setCanMinimize(at_least_one_panel_is_expanded); assignResizeLimits(); - - // force set correct size for the title after show/hide minimize button - LLRect cur_rect = getRect(); - LLRect force_rect = cur_rect; - force_rect.mRight = cur_rect.mRight + 1; - setRect(force_rect); - setRect(cur_rect); } void LLFloaterIMContainer::assignResizeLimits() @@ -793,15 +825,12 @@ void LLFloaterIMContainer::assignResizeLimits() bool is_conv_pane_expanded = !mConversationsPane->isCollapsed(); bool is_msg_pane_expanded = !mMessagesPane->isCollapsed(); - // With two panels visible number of borders is three, because the borders - // between the panels are merged into one - S32 number_of_visible_borders = llmin((is_conv_pane_expanded? 2 : 0) + (is_msg_pane_expanded? 2 : 0), 3); - S32 summary_width_of_visible_borders = number_of_visible_borders * LLPANEL_BORDER_WIDTH; - S32 conv_pane_target_width = is_conv_pane_expanded? - (is_msg_pane_expanded? - mConversationsPane->getRect().getWidth() - : mConversationsPane->getExpandedMinDim()) - : mConversationsPane->getMinDim(); + S32 summary_width_of_visible_borders = (is_msg_pane_expanded ? mConversationsStack->getPanelSpacing() : 0) + 1; + + S32 conv_pane_target_width = is_conv_pane_expanded + ? ( is_msg_pane_expanded?mConversationsPane->getRect().getWidth():mConversationsPane->getExpandedMinDim() ) + : mConversationsPane->getMinDim(); + S32 msg_pane_min_width = is_msg_pane_expanded ? mMessagesPane->getExpandedMinDim() : 0; S32 new_min_width = conv_pane_target_width + msg_pane_min_width + summary_width_of_visible_borders; @@ -961,11 +990,11 @@ void LLFloaterIMContainer::setSortOrder(const LLConversationSort& order) conversation_floater->setSortOrder(order); } } - + gSavedSettings.setU32("ConversationSortOrder", (U32)order); } -void LLFloaterIMContainer::getSelectedUUIDs(uuid_vec_t& selected_uuids) +void LLFloaterIMContainer::getSelectedUUIDs(uuid_vec_t& selected_uuids, bool participant_uuids/* = true*/) { const std::set<LLFolderViewItem*> selectedItems = mConversationsRoot->getSelectionList(); @@ -978,7 +1007,7 @@ void LLFloaterIMContainer::getSelectedUUIDs(uuid_vec_t& selected_uuids) conversationItem = static_cast<LLConversationItem *>((*it)->getViewModelItem()); //When a one-on-one conversation exists, retrieve the participant id from the conversation floater - if(conversationItem->getType() == LLConversationItem::CONV_SESSION_1_ON_1) + if(conversationItem->getType() == LLConversationItem::CONV_SESSION_1_ON_1 && participant_uuids) { LLFloaterIMSession * conversation_floaterp = LLFloaterIMSession::findInstance(conversationItem->getUUID()); LLUUID participant_id = conversation_floaterp->getOtherParticipantUUID(); @@ -1133,6 +1162,11 @@ void LLFloaterIMContainer::doToSelectedConversation(const std::string& command, { LLFloater::onClickClose(conversationFloater); } + else if("close_selected_conversations" == command) + { + getSelectedUUIDs(selectedIDS,false); + closeSelectedConversations(selectedIDS); + } else if("open_voice_conversation" == command) { gIMMgr->startCall(conversationItem->getUUID()); @@ -1143,7 +1177,7 @@ void LLFloaterIMContainer::doToSelectedConversation(const std::string& command, } else if("chat_history" == command) { - if (selectedIDS.size() > 0) + if (selectedIDS.size() > 0) { LLAvatarActions::viewChatHistory(selectedIDS.front()); } @@ -1156,6 +1190,17 @@ void LLFloaterIMContainer::doToSelectedConversation(const std::string& command, } } } + //if there is no LLFloaterIMSession* instance for selected conversation it might be Nearby chat + else + { + if(conversationItem->getType() == LLConversationItem::CONV_SESSION_NEARBY) + { + if("chat_history" == command) + { + LLFloaterReg::showInstance("preview_conversation", LLSD(LLUUID::null), true); + } + } + } } void LLFloaterIMContainer::doToSelected(const LLSD& userdata) @@ -1185,7 +1230,7 @@ void LLFloaterIMContainer::doToSelectedGroup(const LLSD& userdata) if (action == "group_profile") { - LLGroupActions::show(mSelectedSession); + LLGroupActions::show(mSelectedSession); } else if (action == "activate_group") { @@ -1211,7 +1256,19 @@ bool LLFloaterIMContainer::enableContextMenuItem(const LLSD& userdata) //Enable Chat history item for ad-hoc and group conversations if ("can_chat_history" == item && uuids.size() > 0) { - return LLLogChat::isTranscriptExist(uuids.front()); + //Disable menu item if selected participant is user agent + if(uuids.front() != gAgentID) + { + if (getCurSelectedViewModelItem()->getType() == LLConversationItem::CONV_SESSION_NEARBY) + { + return LLLogChat::isNearbyTranscriptExist(); + } + else + { + bool is_group = (getCurSelectedViewModelItem()->getType() == LLConversationItem::CONV_SESSION_GROUP); + return LLLogChat::isTranscriptExist(uuids.front(),is_group); + } + } } // If nothing is selected(and selected item is not group chat), everything needs to be disabled @@ -1886,13 +1943,6 @@ void LLFloaterIMContainer::openNearbyChat() } } -void LLFloaterIMContainer::onNearbyChatClosed() -{ - // If nearby chat is the only remaining conversation and it is closed, close whole conversation floater as well - if (mConversationsItems.size() == 1) - closeFloater(); -} - void LLFloaterIMContainer::reSelectConversation() { LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::getConversation(mSelectedSession); @@ -1904,7 +1954,6 @@ void LLFloaterIMContainer::reSelectConversation() void LLFloaterIMContainer::updateSpeakBtnState() { - LLButton* mSpeakBtn = getChild<LLButton>("speak_btn"); mSpeakBtn->setToggleState(LLVoiceClient::getInstance()->getUserPTTState()); mSpeakBtn->setEnabled(LLAgent::isActionAllowed("speak")); } @@ -1925,6 +1974,17 @@ void LLFloaterIMContainer::flashConversationItemWidget(const LLUUID& session_id, } } +void LLFloaterIMContainer::highlightConversationItemWidget(const LLUUID& session_id, bool is_highlighted) +{ + //Finds the conversation line item to highlight using the session_id + LLConversationViewSession * widget = dynamic_cast<LLConversationViewSession *>(get_ptr_in_map(mConversationsWidgets,session_id)); + + if (widget) + { + widget->setHighlightState(is_highlighted); + } +} + bool LLFloaterIMContainer::isScrolledOutOfSight(LLConversationViewSession* conversation_item_widget) { llassert(conversation_item_widget != NULL); @@ -1940,23 +2000,28 @@ bool LLFloaterIMContainer::isScrolledOutOfSight(LLConversationViewSession* conve BOOL LLFloaterIMContainer::handleKeyHere(KEY key, MASK mask ) { + BOOL handled = FALSE; + if(mask == MASK_ALT) { if (KEY_RETURN == key ) { expandConversation(); + handled = TRUE; } if ((KEY_DOWN == key ) || (KEY_RIGHT == key)) { selectNextorPreviousConversation(true); + handled = TRUE; } if ((KEY_UP == key) || (KEY_LEFT == key)) { selectNextorPreviousConversation(false); + handled = TRUE; } } - return TRUE; + return handled; } bool LLFloaterIMContainer::selectAdjacentConversation(bool focus_selected) @@ -2013,7 +2078,22 @@ void LLFloaterIMContainer::expandConversation() } } -void LLFloaterIMContainer::closeFloater(bool app_quitting/* = false*/) +// By default, if torn off session is currently frontmost, LLFloater::isFrontmost() will return FALSE, which can lead to some bugs +// So LLFloater::isFrontmost() is overriden here to check both selected session and the IM floater itself +// Exclude "Nearby Chat" session from the check, as "Nearby Chat" window and "Conversations" floater can be brought +// to front independently +/*virtual*/ +BOOL LLFloaterIMContainer::isFrontmost() +{ + LLFloaterIMSessionTab* selected_session = LLFloaterIMSessionTab::getConversation(mSelectedSession); + LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"); + return (selected_session && selected_session->isFrontmost() && (selected_session != nearby_chat)) + || LLFloater::isFrontmost(); +} + +// For conversations, closeFloater() (linked to Ctrl-W) does not actually close the floater but the active conversation. +// This is intentional so it doesn't confuse the user. onClickCloseBtn() closes the whole floater. +void LLFloaterIMContainer::onClickCloseBtn() { // Always unminimize before trying to close. // Most of the time the user will never see this state. @@ -2022,7 +2102,80 @@ void LLFloaterIMContainer::closeFloater(bool app_quitting/* = false*/) LLMultiFloater::setMinimized(FALSE); } - LLFloater::closeFloater(app_quitting); + LLFloater::closeFloater(); +} + +void LLFloaterIMContainer::closeHostedFloater() +{ + onClickCloseBtn(); +} + +void LLFloaterIMContainer::closeAllConversations() +{ + std::vector<LLUUID> ids; + for (conversations_items_map::iterator it_session = mConversationsItems.begin(); it_session != mConversationsItems.end(); it_session++) + { + LLUUID session_id = it_session->first; + if (session_id != LLUUID()) + { + ids.push_back(session_id); + } + } + + for (std::vector<LLUUID>::const_iterator it = ids.begin(); it != ids.end(); ++it) + { + LLFloaterIMSession *conversationFloater = LLFloaterIMSession::findInstance(*it); + LLFloater::onClickClose(conversationFloater); + } +} + +void LLFloaterIMContainer::closeSelectedConversations(const uuid_vec_t& ids) +{ + for (uuid_vec_t::const_iterator it = ids.begin(); it != ids.end(); ++it) + { + //We don't need to close Nearby chat, so skip it + if (*it != LLUUID()) + { + LLFloaterIMSession *conversationFloater = LLFloaterIMSession::findInstance(*it); + if(conversationFloater) + { + LLFloater::onClickClose(conversationFloater); + } + } + } +} +void LLFloaterIMContainer::closeFloater(bool app_quitting/* = false*/) +{ + if(app_quitting) + { + closeAllConversations(); + onClickCloseBtn(); + } + else + { + // Check for currently active session + LLUUID session_id = getSelectedSession(); + // If current session is Nearby Chat or there is only one session remaining, close the floater + if (mConversationsItems.size() == 1 || session_id == LLUUID() || app_quitting) + { + onClickCloseBtn(); + } + else + { + // Otherwise, close current conversation + LLFloaterIMSessionTab* active_conversation = LLFloaterIMSessionTab::getConversation(session_id); + if (active_conversation) + { + active_conversation->closeFloater(); + } + } + } +} + +void LLFloaterIMContainer::handleReshape(const LLRect& rect, bool by_user) +{ + LLMultiFloater::handleReshape(rect, by_user); + storeRectControl(); } // EOF diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h index e39d20ec35..36da457cac 100755 --- a/indra/newview/llfloaterimcontainer.h +++ b/indra/newview/llfloaterimcontainer.h @@ -63,6 +63,8 @@ public: /*virtual*/ void setVisible(BOOL visible); /*virtual*/ void setVisibleAndFrontmost(BOOL take_focus=TRUE, const LLSD& key = LLSD()); /*virtual*/ void updateResizeLimits(); + /*virtual*/ void handleReshape(const LLRect& rect, bool by_user); + void onCloseFloater(LLUUID& id); /*virtual*/ void addFloater(LLFloater* floaterp, @@ -105,8 +107,6 @@ public: LLConversationItem* getSessionModel(const LLUUID& session_id) { return get_ptr_in_map(mConversationsItems,session_id); } LLConversationSort& getSortOrder() { return mConversationViewModel.getSorter(); } - void onNearbyChatClosed(); - // Handling of lists of participants is public so to be common with llfloatersessiontab // *TODO : Find a better place for this. bool checkContextMenuItem(const std::string& item, uuid_vec_t& selectedIDS); @@ -116,6 +116,10 @@ public: void assignResizeLimits(); virtual BOOL handleKeyHere(KEY key, MASK mask ); /*virtual*/ void closeFloater(bool app_quitting = false); + void closeAllConversations(); + void closeSelectedConversations(const uuid_vec_t& ids); + /*virtual*/ BOOL isFrontmost(); + private: typedef std::map<LLUUID,LLFloater*> avatarID_panel_map_t; @@ -130,6 +134,8 @@ private: void onStubCollapseButtonClicked(); void processParticipantsStyleUpdate(); void onSpeakButtonClicked(); + /*virtual*/ void onClickCloseBtn(); + /*virtual*/ void closeHostedFloater(); void collapseConversationsPane(bool collapse, bool save_is_allowed=true); @@ -144,7 +150,7 @@ private: void setSortOrderParticipants(const LLConversationFilter::ESortOrderType order); void setSortOrder(const LLConversationSort& order); - void getSelectedUUIDs(uuid_vec_t& selected_uuids); + void getSelectedUUIDs(uuid_vec_t& selected_uuids, bool participant_uuids = true); const LLConversationItem * getCurSelectedViewModelItem(); void getParticipantUUIDs(uuid_vec_t& selected_uuids); void doToSelected(const LLSD& userdata); @@ -169,6 +175,7 @@ private: LLButton* mExpandCollapseBtn; LLButton* mStubCollapseBtn; + LLButton* mSpeakBtn; LLPanel* mStubPanel; LLTextBox* mStubTextBox; LLLayoutPanel* mMessagesPane; @@ -176,6 +183,7 @@ private: LLLayoutStack* mConversationsStack; bool mInitialized; + bool mIsFirstLaunch; LLUUID mSelectedSession; std::string mGeneralTitle; @@ -190,9 +198,12 @@ public: void updateSpeakBtnState(); static bool isConversationLoggingAllowed(); void flashConversationItemWidget(const LLUUID& session_id, bool is_flashes); + void highlightConversationItemWidget(const LLUUID& session_id, bool is_highlighted); bool isScrolledOutOfSight(LLConversationViewSession* conversation_item_widget); boost::signals2::connection mMicroChangedSignal; S32 getConversationListItemSize() { return mConversationsWidgets.size(); } + typedef std::list<LLFloater*> floater_list_t; + void getDetachedConversationFloaters(floater_list_t& floaters); private: LLConversationViewSession* createConversationItemWidget(LLConversationItem* item); diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp index 886af6ed15..4e0a4b523f 100755 --- a/indra/newview/llfloaterimnearbychat.cpp +++ b/indra/newview/llfloaterimnearbychat.cpp @@ -125,7 +125,7 @@ BOOL LLFloaterIMNearbyChat::postBuild() setTitle(LLTrans::getString("NearbyChatTitle")); // obsolete, but may be needed for backward compatibility? - gSavedSettings.declareS32("nearbychat_showicons_and_names", 2, "NearByChat header settings", true); + gSavedSettings.declareS32("nearbychat_showicons_and_names", 2, "NearByChat header settings", LLControlVariable::PERSIST_NONDFT); if (gSavedPerAccountSettings.getBOOL("LogShowHistory")) { @@ -138,19 +138,28 @@ BOOL LLFloaterIMNearbyChat::postBuild() // virtual void LLFloaterIMNearbyChat::closeHostedFloater() { - // Should check how many conversations are ongoing. Close all if 1 only (the Nearby Chat), select next one otherwise + // If detached from conversations window close anyway + if (!getHost()) + { + setVisible(FALSE); + } + + // Should check how many conversations are ongoing. Select next to "Nearby Chat" in case there are some other besides. + // Close conversations window in case "Nearby Chat" is attached and the only conversation LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance(); if (floater_container->getConversationListItemSize() == 1) { - floater_container->closeFloater(); + if (getHost()) + { + floater_container->closeFloater(); + } } else { if (!getHost()) { - setVisible(FALSE); + floater_container->selectNextConversationByID(LLUUID()); } - floater_container->selectNextConversationByID(LLUUID()); } } @@ -262,7 +271,7 @@ void LLFloaterIMNearbyChat::setVisibleAndFrontmost(BOOL take_focus, const LLSD& { LLFloaterIMSessionTab::setVisibleAndFrontmost(take_focus, key); - if(!isTornOff() && matchesKey(key)) + if(matchesKey(key)) { LLFloaterIMContainer::getInstance()->selectConversationPair(mSessionID, true, take_focus); } @@ -296,7 +305,6 @@ void LLFloaterIMNearbyChat::onClose(bool app_quitting) { // Override LLFloaterIMSessionTab::onClose() so that Nearby Chat is not removed from the conversation floater LLFloaterIMSessionTab::restoreFloater(); - onClickCloseBtn(); } // virtual @@ -306,13 +314,7 @@ void LLFloaterIMNearbyChat::onClickCloseBtn() { return; } - LLFloaterIMSessionTab::onTearOffClicked(); - - LLFloaterIMContainer *im_box = LLFloaterIMContainer::findInstance(); - if (im_box) - { - im_box->onNearbyChatClosed(); - } + closeHostedFloater(); } void LLFloaterIMNearbyChat::onChatFontChange(LLFontGL* fontp) @@ -350,11 +352,17 @@ bool LLFloaterIMNearbyChat::isChatVisible() const void LLFloaterIMNearbyChat::showHistory() { openFloater(); + LLFloaterIMContainer::getInstance()->selectConversation(LLUUID(NULL)); + if(!isMessagePaneExpanded()) { restoreFloater(); setFocus(true); } + else + { + LLFloaterIMContainer::getInstance()->setFocus(TRUE); + } setResizeLimits(getMinWidth(), EXPANDED_MIN_HEIGHT); } @@ -568,7 +576,10 @@ void LLFloaterIMNearbyChat::sendChat( EChatType type ) if (0 == channel) { // discard returned "found" boolean - LLGestureMgr::instance().triggerAndReviseString(utf8text, &utf8_revised_text); + if(!LLGestureMgr::instance().triggerAndReviseString(utf8text, &utf8_revised_text)) + { + utf8_revised_text = utf8text; + } } else { @@ -582,7 +593,7 @@ void LLFloaterIMNearbyChat::sendChat( EChatType type ) if (!utf8_revised_text.empty()) { // Chat with animation - sendChatFromViewer(utf8_revised_text, type, TRUE); + sendChatFromViewer(utf8_revised_text, type, gSavedSettings.getBOOL("PlayChatAnim")); } } @@ -636,10 +647,7 @@ void LLFloaterIMNearbyChat::addMessage(const LLChat& chat,bool archive,const LLS void LLFloaterIMNearbyChat::onChatBoxCommit() { - if (mInputEditor->getText().length() > 0) - { - sendChat(CHAT_TYPE_NORMAL); - } + sendChat(CHAT_TYPE_NORMAL); gAgent.stopTyping(); } diff --git a/indra/newview/llfloaterimnearbychathandler.cpp b/indra/newview/llfloaterimnearbychathandler.cpp index e0fcbb58f6..bb11c299cb 100755 --- a/indra/newview/llfloaterimnearbychathandler.cpp +++ b/indra/newview/llfloaterimnearbychathandler.cpp @@ -606,6 +606,7 @@ void LLFloaterIMNearbyChatHandler::processChat(const LLChat& chat_msg, //Don't show nearby toast, if conversation is visible and selected if ((nearby_chat->hasFocus()) || + (LLFloater::isVisible(nearby_chat) && nearby_chat->isTornOff() && !nearby_chat->isMinimized()) || ((im_box->getSelectedSession().isNull() && ((LLFloater::isVisible(im_box) && !im_box->isMinimized() && im_box->isFrontmost()) || (LLFloater::isVisible(nearby_chat) && !nearby_chat->isMinimized() && nearby_chat->isFrontmost()))))) diff --git a/indra/newview/llfloaterimnearbychatlistener.cpp b/indra/newview/llfloaterimnearbychatlistener.cpp index 14a22bcd84..5a5f6c72c8 100755 --- a/indra/newview/llfloaterimnearbychatlistener.cpp +++ b/indra/newview/llfloaterimnearbychatlistener.cpp @@ -33,7 +33,7 @@ #include "llagent.h" #include "llchat.h" - +#include "llviewercontrol.h" LLFloaterIMNearbyChatListener::LLFloaterIMNearbyChatListener(LLFloaterIMNearbyChat & chatbar) @@ -95,6 +95,6 @@ void LLFloaterIMNearbyChatListener::sendChat(LLSD const & chat_data) const } // Send it as if it was typed in - mChatbar.sendChatFromViewer(chat_to_send, type_o_chat, (BOOL)(channel == 0)); + mChatbar.sendChatFromViewer(chat_to_send, type_o_chat, ((BOOL)(channel == 0)) && gSavedSettings.getBOOL("PlayChatAnim")); } diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp index af76551bd4..01f905370c 100644 --- a/indra/newview/llfloaterimsession.cpp +++ b/indra/newview/llfloaterimsession.cpp @@ -111,18 +111,6 @@ void LLFloaterIMSession::refresh() void LLFloaterIMSession::onTearOffClicked() { LLFloaterIMSessionTab::onTearOffClicked(); - - if(mIsP2PChat) - { - if(isTornOff()) - { - mSpeakingIndicator->setSpeakerId(mOtherParticipantUUID, mSessionID); - } - else - { - mSpeakingIndicator->setSpeakerId(LLUUID::null); - } - } } // virtual @@ -444,8 +432,11 @@ void LLFloaterIMSession::addSessionParticipants(const uuid_vec_t& uuids) } else { - // remember whom we have invited, to notify others later, when the invited ones actually join - mInvitedParticipants.insert(mInvitedParticipants.end(), uuids.begin(), uuids.end()); + if(findInstance(mSessionID)) + { + // remember whom we have invited, to notify others later, when the invited ones actually join + mInvitedParticipants.insert(mInvitedParticipants.end(), uuids.begin(), uuids.end()); + } inviteToSession(uuids); } @@ -471,13 +462,18 @@ void LLFloaterIMSession::addP2PSessionParticipants(const LLSD& notification, con temp_ids.insert(temp_ids.end(), uuids.begin(), uuids.end()); // then we can close the current session - onClose(false); + if(findInstance(mSessionID)) + { + onClose(false); + + // remember whom we have invited, to notify others later, when the invited ones actually join + mInvitedParticipants.insert(mInvitedParticipants.end(), uuids.begin(), uuids.end()); + } // we start a new session so reset the initialization flag mSessionInitialized = false; - // remember whom we have invited, to notify others later, when the invited ones actually join - mInvitedParticipants.insert(mInvitedParticipants.end(), uuids.begin(), uuids.end()); + // Start a new ad hoc voice call if we invite new participants to a P2P call, // or start a text chat otherwise. diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index ce6e639305..0ccfdb9a7b 100755 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -55,7 +55,6 @@ LLFloaterIMSessionTab::LLFloaterIMSessionTab(const LLSD& session_id) , mSessionID(session_id.asUUID()) , mConversationsRoot(NULL) , mScroller(NULL) - , mSpeakingIndicator(NULL) , mChatHistory(NULL) , mInputEditor(NULL) , mInputEditorPad(0) @@ -212,7 +211,7 @@ void LLFloaterIMSessionTab::assignResizeLimits() mRightPartPanel->setIgnoreReshape(is_participants_pane_collapsed); S32 participants_pane_target_width = is_participants_pane_collapsed? - 0 : (mParticipantListPanel->getRect().getWidth() + LLPANEL_BORDER_WIDTH); + 0 : (mParticipantListPanel->getRect().getWidth() + mParticipantListAndHistoryStack->getPanelSpacing()); S32 new_min_width = participants_pane_target_width + mRightPartPanel->getExpandedMinDim() + mFloaterExtraWidth; @@ -241,7 +240,10 @@ BOOL LLFloaterIMSessionTab::postBuild() mTearOffBtn->setCommitCallback(boost::bind(&LLFloaterIMSessionTab::onTearOffClicked, this)); mGearBtn = getChild<LLButton>("gear_btn"); - + mAddBtn = getChild<LLButton>("add_btn"); + mVoiceButton = getChild<LLButton>("voice_call_btn"); + mTranslationCheckBox = getChild<LLUICtrl>("translate_chat_checkbox_lp"); + mParticipantListPanel = getChild<LLLayoutPanel>("speakers_list_panel"); mRightPartPanel = getChild<LLLayoutPanel>("right_part_holder"); @@ -256,8 +258,6 @@ BOOL LLFloaterIMSessionTab::postBuild() scroller_params.rect(scroller_view_rect); mScroller = LLUICtrlFactory::create<LLFolderViewScrollContainer>(scroller_params); mScroller->setFollowsAll(); - - mSpeakingIndicator = getChild<LLOutputMonitorCtrl>("speaking_indicator"); // Insert that scroller into the panel widgets hierarchy mParticipantListPanel->addChild(mScroller); @@ -270,6 +270,7 @@ BOOL LLFloaterIMSessionTab::postBuild() mInputPanels = getChild<LLLayoutStack>("input_panels"); mInputEditor->setTextExpandedCallback(boost::bind(&LLFloaterIMSessionTab::reshapeChatLayoutPanel, this)); + mInputEditor->setMouseUpCallback(boost::bind(&LLFloaterIMSessionTab::onInputEditorClicked, this)); mInputEditor->setCommitOnFocusLost( FALSE ); mInputEditor->setPassDelete(TRUE); mInputEditor->setFont(LLViewerChat::getChatFont()); @@ -372,7 +373,7 @@ void LLFloaterIMSessionTab::draw() void LLFloaterIMSessionTab::enableDisableCallBtn() { - getChildView("voice_call_btn")->setEnabled( + mVoiceButton->setEnabled( mSessionID.notNull() && mSession && mSession->mSessionInitialized @@ -399,6 +400,16 @@ void LLFloaterIMSessionTab::onFocusLost() LLTransientDockableFloater::onFocusLost(); } +void LLFloaterIMSessionTab::onInputEditorClicked() +{ + LLFloaterIMContainer* im_box = LLFloaterIMContainer::findInstance(); + if (im_box) + { + im_box->flashConversationItemWidget(mSessionID,false); + } + gToolBarView->flashCommand(LLCommandId("chat"), false); +} + std::string LLFloaterIMSessionTab::appendTime() { time_t utc_time; @@ -758,7 +769,7 @@ void LLFloaterIMSessionTab::reshapeChatLayoutPanel() void LLFloaterIMSessionTab::showTranslationCheckbox(BOOL show) { - getChild<LLUICtrl>("translate_chat_checkbox_lp")->setVisible(mIsNearbyChat? show : FALSE); + mTranslationCheckBox->setVisible(mIsNearbyChat && show); } // static @@ -805,15 +816,10 @@ void LLFloaterIMSessionTab::reloadEmptyFloaters() void LLFloaterIMSessionTab::updateCallBtnState(bool callIsActive) { - LLButton* voiceButton = getChild<LLButton>("voice_call_btn"); - voiceButton->setImageOverlay( - callIsActive? getString("call_btn_stop") : getString("call_btn_start")); - - voiceButton->setToolTip( - callIsActive? getString("end_call_button_tooltip") : getString("start_call_button_tooltip")); + mVoiceButton->setImageOverlay(callIsActive? getString("call_btn_stop") : getString("call_btn_start")); + mVoiceButton->setToolTip(callIsActive? getString("end_call_button_tooltip") : getString("start_call_button_tooltip")); enableDisableCallBtn(); - } void LLFloaterIMSessionTab::onSlide(LLFloaterIMSessionTab* self) @@ -898,6 +904,7 @@ void LLFloaterIMSessionTab::restoreFloater() mExpandCollapseLineBtn->setImageOverlay(getString("expandline_icon")); setMessagePaneExpanded(true); saveCollapsedState(); + mInputEditor->enableSingleLineMode(false); enableResizeCtrls(true, true, true); } } @@ -953,8 +960,8 @@ void LLFloaterIMSessionTab::updateGearBtn() if(prevVisibility != mGearBtn->getVisible()) { LLRect gear_btn_rect = mGearBtn->getRect(); - LLRect add_btn_rect = getChild<LLButton>("add_btn")->getRect(); - LLRect call_btn_rect = getChild<LLButton>("voice_call_btn")->getRect(); + LLRect add_btn_rect = mAddBtn->getRect(); + LLRect call_btn_rect = mVoiceButton->getRect(); S32 gap_width = call_btn_rect.mLeft - add_btn_rect.mRight; S32 right_shift = gear_btn_rect.getWidth() + gap_width; if(mGearBtn->getVisible()) @@ -968,24 +975,24 @@ void LLFloaterIMSessionTab::updateGearBtn() add_btn_rect.translate(-right_shift,0); call_btn_rect.translate(-right_shift,0); } - getChild<LLButton>("add_btn")->setRect(add_btn_rect); - getChild<LLButton>("voice_call_btn")->setRect(call_btn_rect); + mAddBtn->setRect(add_btn_rect); + mVoiceButton->setRect(call_btn_rect); } } void LLFloaterIMSessionTab::initBtns() { LLRect gear_btn_rect = mGearBtn->getRect(); - LLRect add_btn_rect = getChild<LLButton>("add_btn")->getRect(); - LLRect call_btn_rect = getChild<LLButton>("voice_call_btn")->getRect(); + LLRect add_btn_rect = mAddBtn->getRect(); + LLRect call_btn_rect = mVoiceButton->getRect(); S32 gap_width = call_btn_rect.mLeft - add_btn_rect.mRight; S32 right_shift = gear_btn_rect.getWidth() + gap_width; add_btn_rect.translate(-right_shift,0); call_btn_rect.translate(-right_shift,0); - getChild<LLButton>("add_btn")->setRect(add_btn_rect); - getChild<LLButton>("voice_call_btn")->setRect(call_btn_rect); + mAddBtn->setRect(add_btn_rect); + mVoiceButton->setRect(call_btn_rect); } // static @@ -1083,21 +1090,26 @@ void LLFloaterIMSessionTab::saveCollapsedState() } BOOL LLFloaterIMSessionTab::handleKeyHere(KEY key, MASK mask ) { + BOOL handled = FALSE; + if(mask == MASK_ALT) { LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance(); if (KEY_RETURN == key && !isTornOff()) { floater_container->expandConversation(); + handled = TRUE; } if ((KEY_UP == key) || (KEY_LEFT == key)) { floater_container->selectNextorPreviousConversation(false); + handled = TRUE; } if ((KEY_DOWN == key ) || (KEY_RIGHT == key)) { floater_container->selectNextorPreviousConversation(true); + handled = TRUE; } } - return TRUE; + return handled; } diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h index 302d5a8066..e7b05a584b 100755 --- a/indra/newview/llfloaterimsessiontab.h +++ b/indra/newview/llfloaterimsessiontab.h @@ -171,8 +171,7 @@ protected: LLFolderView* mConversationsRoot; LLScrollContainer* mScroller; - LLOutputMonitorCtrl* mSpeakingIndicator; - LLChatHistory* mChatHistory; + LLChatHistory* mChatHistory; LLChatEntry* mInputEditor; LLLayoutPanel * mChatLayoutPanel; LLLayoutStack * mInputPanels; @@ -182,6 +181,9 @@ protected: LLButton* mTearOffBtn; LLButton* mCloseBtn; LLButton* mGearBtn; + LLButton* mAddBtn; + LLButton* mVoiceButton; + LLUICtrl* mTranslationCheckBox; private: // Handling selection and contextual menu @@ -201,6 +203,8 @@ private: */ void reshapeChatLayoutPanel(); + void onInputEditorClicked(); + bool checkIfTornOff(); bool mIsHostAttached; bool mHasVisibleBeenInitialized; diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index eaee2f0dc1..85e86311a4 100755 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -455,6 +455,7 @@ BOOL LLFloaterPreference::postBuild() getChild<LLComboBox>("ConferenceIMOptions")->setCommitCallback(boost::bind(&LLFloaterPreference::onNotificationsChange, this,"ConferenceIMOptions")); getChild<LLComboBox>("GroupChatOptions")->setCommitCallback(boost::bind(&LLFloaterPreference::onNotificationsChange, this,"GroupChatOptions")); getChild<LLComboBox>("NearbyChatOptions")->setCommitCallback(boost::bind(&LLFloaterPreference::onNotificationsChange, this,"NearbyChatOptions")); + getChild<LLComboBox>("ObjectIMOptions")->setCommitCallback(boost::bind(&LLFloaterPreference::onNotificationsChange, this,"ObjectIMOptions")); // if floater is opened before login set default localized do not disturb message if (LLStartUp::getStartupState() < STATE_STARTED) @@ -724,6 +725,7 @@ void LLFloaterPreference::onOpen(const LLSD& key) onNotificationsChange("ConferenceIMOptions"); onNotificationsChange("GroupChatOptions"); onNotificationsChange("NearbyChatOptions"); + onNotificationsChange("ObjectIMOptions"); LLPanelLogin::setAlwaysRefresh(true); refresh(); @@ -931,7 +933,7 @@ void LLFloaterPreference::onNotificationsChange(const std::string& OptionName) bool show_notifications_alert = true; for (notifications_map::iterator it_notification = mNotificationOptions.begin(); it_notification != mNotificationOptions.end(); it_notification++) { - if(it_notification->second != "None") + if(it_notification->second != "No action") { show_notifications_alert = false; break; diff --git a/indra/newview/llfolderviewmodelinventory.cpp b/indra/newview/llfolderviewmodelinventory.cpp index 52f4dd57e5..d76d6d422f 100755 --- a/indra/newview/llfolderviewmodelinventory.cpp +++ b/indra/newview/llfolderviewmodelinventory.cpp @@ -74,6 +74,7 @@ void LLFolderViewModelInventory::sort( LLFolderViewFolder* folder ) it != end_it; ++it) { + // Recursive call to sort() on child (CHUI-849) LLFolderViewFolder* child_folderp = *it; sort(child_folderp); @@ -129,12 +130,12 @@ void LLFolderViewModelItemInventory::requestSort() void LLFolderViewModelItemInventory::setPassedFilter(bool passed, S32 filter_generation, std::string::size_type string_offset, std::string::size_type string_size) { LLFolderViewModelItemCommon::setPassedFilter(passed, filter_generation, string_offset, string_size); - - bool passed_filter_before = mPrevPassedAllFilters; + bool before = mPrevPassedAllFilters; mPrevPassedAllFilters = passedFilter(filter_generation); - if (passed_filter_before != mPrevPassedAllFilters) + if (before != mPrevPassedAllFilters) { + // Need to rearrange the folder if the filtered state of the item changed LLFolderViewFolder* parent_folder = mFolderViewItem->getParentFolder(); if (parent_folder) { @@ -150,11 +151,11 @@ bool LLFolderViewModelItemInventory::filterChildItem( LLFolderViewModelItem* ite bool continue_filtering = true; if (item->getLastFilterGeneration() < filter_generation) { - // recursive application of the filter for child items + // Recursive application of the filter for child items (CHUI-849) continue_filtering = item->filter( filter ); } - // track latest generation to pass any child items, for each folder up to root + // Update latest generation to pass filter in parent and propagate up to root if (item->passedFilter()) { LLFolderViewModelItemInventory* view_model = this; @@ -174,53 +175,61 @@ bool LLFolderViewModelItemInventory::filter( LLFolderViewFilter& filter) const S32 filter_generation = filter.getCurrentGeneration(); const S32 must_pass_generation = filter.getFirstRequiredGeneration(); - if (getLastFilterGeneration() >= must_pass_generation + if (getLastFilterGeneration() >= must_pass_generation && getLastFolderFilterGeneration() >= must_pass_generation && !passedFilter(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 + // go ahead and flag this item as not pass setPassedFilter(false, filter_generation); setPassedFolderFilter(false, filter_generation); return true; } - const bool passed_filter_folder = (getInventoryType() == LLInventoryType::IT_CATEGORY) - ? filter.checkFolder(this) - : true; + // *TODO : Revise the logic for fast pass on less restrictive filter case + /* + const S32 sufficient_pass_generation = filter.getFirstSuccessGeneration(); + if (getLastFilterGeneration() >= sufficient_pass_generation + && getLastFolderFilterGeneration() >= sufficient_pass_generation + && passedFilter(sufficient_pass_generation)) + { + // passed an earlier filter that was a superset of the current one + // go ahead and flag this item as pass + setPassedFilter(true, filter_generation); + setPassedFolderFilter(true, filter_generation); + return true; + } + */ + + const bool passed_filter_folder = (getInventoryType() == LLInventoryType::IT_CATEGORY) ? filter.checkFolder(this) : true; setPassedFolderFilter(passed_filter_folder, filter_generation); - if(!mChildren.empty() + bool continue_filtering = true; + + if (!mChildren.empty() && (getLastFilterGeneration() < must_pass_generation // haven't checked descendants against minimum required generation to pass - || descendantsPassedFilter(must_pass_generation))) // or at least one descendant has passed the minimum requirement + || descendantsPassedFilter(must_pass_generation))) // or at least one descendant has passed the minimum requirement { // now query children - for (child_list_t::iterator iter = mChildren.begin(), end_iter = mChildren.end(); - iter != end_iter && filter.getFilterCount() > 0; - ++iter) + for (child_list_t::iterator iter = mChildren.begin(), end_iter = mChildren.end(); iter != end_iter; ++iter) { - if (!filterChildItem((*iter), filter)) + continue_filtering = filterChildItem((*iter), filter); + if (!continue_filtering) { break; } } } - // if we didn't use all filter iterations - // that means we filtered all of our descendants - // so filter ourselves now - if (filter.getFilterCount() > 0) + // If we didn't use all the filter time that means we filtered all of our descendants so we can filter ourselves now + if (continue_filtering) { - filter.decrementFilterCount(); - + // This is where filter check on the item done (CHUI-849) const bool passed_filter = filter.check(this); setPassedFilter(passed_filter, filter_generation, filter.getStringMatchOffset(this), filter.getFilterStringSize()); - return true; - } - else - { - return false; + continue_filtering = !filter.isTimedOut(); } + return continue_filtering; } LLFolderViewModelInventory* LLInventoryPanel::getFolderViewModel() @@ -307,8 +316,8 @@ bool LLInventorySort::operator()(const LLFolderViewModelItemInventory* const& a, } } -LLFolderViewModelItemInventory::LLFolderViewModelItemInventory( class LLFolderViewModelInventory& root_view_model ) - : LLFolderViewModelItemCommon(root_view_model), - mPrevPassedAllFilters(false) +LLFolderViewModelItemInventory::LLFolderViewModelItemInventory( class LLFolderViewModelInventory& root_view_model ) : + LLFolderViewModelItemCommon(root_view_model), + mPrevPassedAllFilters(false) { } diff --git a/indra/newview/llfolderviewmodelinventory.h b/indra/newview/llfolderviewmodelinventory.h index 890d03d1c9..9dcfdfa185 100755 --- a/indra/newview/llfolderviewmodelinventory.h +++ b/indra/newview/llfolderviewmodelinventory.h @@ -59,9 +59,8 @@ public: virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const = 0; virtual LLToolDragAndDrop::ESource getDragSource() const = 0; - protected: - bool mPrevPassedAllFilters; + bool mPrevPassedAllFilters; }; class LLInventorySort diff --git a/indra/newview/llgroupactions.cpp b/indra/newview/llgroupactions.cpp index 5c015c58c4..f514729aa1 100755 --- a/indra/newview/llgroupactions.cpp +++ b/indra/newview/llgroupactions.cpp @@ -116,6 +116,80 @@ public: }; LLGroupHandler gGroupHandler; +// This object represents a pending request for specified group member information +// which is needed to check whether avatar can leave group +class LLFetchGroupMemberData : public LLGroupMgrObserver +{ +public: + LLFetchGroupMemberData(const LLUUID& group_id) : + mGroupId(group_id), + mRequestProcessed(false), + LLGroupMgrObserver(group_id) + { + LL_INFOS() << "Sending new group member request for group_id: "<< group_id << LL_ENDL; + LLGroupMgr* mgr = LLGroupMgr::getInstance(); + // register ourselves as an observer + mgr->addObserver(this); + // send a request + mgr->sendGroupPropertiesRequest(group_id); + mgr->sendCapGroupMembersRequest(group_id); + } + + ~LLFetchGroupMemberData() + { + if (!mRequestProcessed) + { + // Request is pending + LL_WARNS() << "Destroying pending group member request for group_id: " + << mGroupId << LL_ENDL; + } + // Remove ourselves as an observer + LLGroupMgr::getInstance()->removeObserver(this); + } + + void changed(LLGroupChange gc) + { + if (gc == GC_MEMBER_DATA && !mRequestProcessed) + { + LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupId); + if (!gdatap) + { + LL_WARNS() << "LLGroupMgr::getInstance()->getGroupData() was NULL" << LL_ENDL; + } + else if (!gdatap->isMemberDataComplete()) + { + LL_WARNS() << "LLGroupMgr::getInstance()->getGroupData()->isMemberDataComplete() was FALSE" << LL_ENDL; + } + else + { + processGroupData(); + mRequestProcessed = true; + } + } + } + + LLUUID getGroupId() { return mGroupId; } + virtual void processGroupData() = 0; +protected: + LLUUID mGroupId; +private: + bool mRequestProcessed; +}; + +class LLFetchLeaveGroupData: public LLFetchGroupMemberData +{ +public: + LLFetchLeaveGroupData(const LLUUID& group_id) + : LLFetchGroupMemberData(group_id) + {} + void processGroupData() + { + LLGroupActions::processLeaveGroupDataResponse(mGroupId); + } +}; + +LLFetchLeaveGroupData* gFetchLeaveGroupData = NULL; + // static void LLGroupActions::search() { @@ -208,23 +282,52 @@ bool LLGroupActions::onJoinGroup(const LLSD& notification, const LLSD& response) void LLGroupActions::leave(const LLUUID& group_id) { if (group_id.isNull()) + { return; + } - S32 count = gAgent.mGroups.size(); - S32 i; - for (i = 0; i < count; ++i) + LLGroupData group_data; + if (gAgent.getGroupData(group_id, group_data)) { - if(gAgent.mGroups.at(i).mID == group_id) - break; + LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(group_id); + if (!gdatap || !gdatap->isMemberDataComplete()) + { + if (gFetchLeaveGroupData != NULL) + { + delete gFetchLeaveGroupData; + gFetchLeaveGroupData = NULL; + } + gFetchLeaveGroupData = new LLFetchLeaveGroupData(group_id); + } + else + { + processLeaveGroupDataResponse(group_id); + } } - if (i < count) +} + +//static +void LLGroupActions::processLeaveGroupDataResponse(const LLUUID group_id) +{ + LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(group_id); + LLUUID agent_id = gAgent.getID(); + LLGroupMgrGroupData::member_list_t::iterator mit = gdatap->mMembers.find(agent_id); + //get the member data for the group + if ( mit != gdatap->mMembers.end() ) { - LLSD args; - args["GROUP"] = gAgent.mGroups.at(i).mName; - LLSD payload; - payload["group_id"] = group_id; - LLNotificationsUtil::add("GroupLeaveConfirmMember", args, payload, onLeaveGroup); + LLGroupMemberData* member_data = (*mit).second; + + if ( member_data && member_data->isOwner() && gdatap->mMemberCount == 1) + { + LLNotificationsUtil::add("OwnerCannotLeaveGroup"); + return; + } } + LLSD args; + args["GROUP"] = gdatap->mName; + LLSD payload; + payload["group_id"] = group_id; + LLNotificationsUtil::add("GroupLeaveConfirmMember", args, payload, onLeaveGroup); } // static diff --git a/indra/newview/llgroupactions.h b/indra/newview/llgroupactions.h index 3f9852f194..afc4686dd7 100755 --- a/indra/newview/llgroupactions.h +++ b/indra/newview/llgroupactions.h @@ -114,6 +114,14 @@ public: private: static bool onJoinGroup(const LLSD& notification, const LLSD& response); static bool onLeaveGroup(const LLSD& notification, const LLSD& response); + + /** + * This function is called by LLFetchLeaveGroupData upon receiving a response to a group + * members data request. + */ + static void processLeaveGroupDataResponse(const LLUUID group_id); + + friend class LLFetchLeaveGroupData; }; #endif // LL_LLGROUPACTIONS_H diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 236dc47169..7e52f708e3 100755 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -104,6 +104,7 @@ BOOL LLSessionTimeoutTimer::tick() } +void notify_of_message(const LLSD& msg, bool is_dnd_msg); void process_dnd_im(const LLSD& notification) { @@ -130,15 +131,9 @@ void process_dnd_im(const LLSD& notification) fromID, false, false); //will need slight refactor to retrieve whether offline message or not (assume online for now) + } - LLFloaterIMContainer* im_box = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container"); - - if (im_box) - { - im_box->flashConversationItemWidget(sessionID, true); - } - - } + notify_of_message(data, true); } @@ -159,75 +154,106 @@ static void on_avatar_name_cache_toast(const LLUUID& agent_id, LLNotificationsUtil::add("IMToast", args, args, boost::bind(&LLFloaterIMContainer::showConversation, LLFloaterIMContainer::getInstance(), msg["session_id"].asUUID())); } -void on_new_message(const LLSD& msg) +void notify_of_message(const LLSD& msg, bool is_dnd_msg) { - std::string user_preferences; - LLUUID participant_id = msg["from_id"].asUUID(); - LLUUID session_id = msg["session_id"].asUUID(); - LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(session_id); - - // do not show notification which goes from agent - if (gAgent.getID() == participant_id) - { - return; - } + std::string user_preferences; + LLUUID participant_id = msg[is_dnd_msg ? "FROM_ID" : "from_id"].asUUID(); + LLUUID session_id = msg[is_dnd_msg ? "SESSION_ID" : "session_id"].asUUID(); + LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(session_id); - // determine state of conversations floater - enum {CLOSED, NOT_ON_TOP, ON_TOP, ON_TOP_AND_ITEM_IS_SELECTED} conversations_floater_status; + // do not show notification which goes from agent + if (gAgent.getID() == participant_id) + { + return; + } + // determine state of conversations floater + enum {CLOSED, NOT_ON_TOP, ON_TOP, ON_TOP_AND_ITEM_IS_SELECTED} conversations_floater_status; - LLFloaterIMContainer* im_box = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container"); + LLFloaterIMContainer* im_box = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container"); LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::getConversation(session_id); - + bool store_dnd_message = false; // flag storage of a dnd message + bool is_session_focused = session_floater->isTornOff() && session_floater->hasFocus(); if (!LLFloater::isVisible(im_box) || im_box->isMinimized()) { conversations_floater_status = CLOSED; } else if (!im_box->hasFocus() && - !(session_floater && LLFloater::isVisible(session_floater) - && !session_floater->isMinimized() && session_floater->hasFocus())) + !(session_floater && LLFloater::isVisible(session_floater) + && !session_floater->isMinimized() && session_floater->hasFocus())) { conversations_floater_status = NOT_ON_TOP; } else if (im_box->getSelectedSession() != session_id) { conversations_floater_status = ON_TOP; - } + } else { conversations_floater_status = ON_TOP_AND_ITEM_IS_SELECTED; } - // determine user prefs for this session - if (session_id.isNull()) - { - user_preferences = gSavedSettings.getString("NotificationNearbyChatOptions"); - } - else if(session->isP2PSessionType()) - { - if (LLAvatarTracker::instance().isBuddy(participant_id)) - { - user_preferences = gSavedSettings.getString("NotificationFriendIMOptions"); - } - else - { - user_preferences = gSavedSettings.getString("NotificationNonFriendIMOptions"); - } - } - else if(session->isAdHocSessionType()) - { - user_preferences = gSavedSettings.getString("NotificationConferenceIMOptions"); - } - else if(session->isGroupSessionType()) - { - user_preferences = gSavedSettings.getString("NotificationGroupChatOptions"); - } + // determine user prefs for this session + if (session_id.isNull()) + { + if (msg["source_type"].asInteger() == CHAT_SOURCE_OBJECT) + { + user_preferences = gSavedSettings.getString("NotificationObjectIMOptions"); + if (!gAgent.isDoNotDisturb() && (gSavedSettings.getBOOL("PlaySoundObjectIM") == TRUE)) + { + make_ui_sound("UISndNewIncomingIMSession"); + } + } + else + { + user_preferences = gSavedSettings.getString("NotificationNearbyChatOptions"); + if (!gAgent.isDoNotDisturb() && (gSavedSettings.getBOOL("PlaySoundNearbyChatIM") == TRUE)) + { + make_ui_sound("UISndNewIncomingIMSession"); + } + } + } + else if(session->isP2PSessionType()) + { + if (LLAvatarTracker::instance().isBuddy(participant_id)) + { + user_preferences = gSavedSettings.getString("NotificationFriendIMOptions"); + if (!gAgent.isDoNotDisturb() && (gSavedSettings.getBOOL("PlaySoundFriendIM") == TRUE)) + { + make_ui_sound("UISndNewIncomingIMSession"); + } + } + else + { + user_preferences = gSavedSettings.getString("NotificationNonFriendIMOptions"); + if (!gAgent.isDoNotDisturb() && (gSavedSettings.getBOOL("PlaySoundNonFriendIM") == TRUE)) + { + make_ui_sound("UISndNewIncomingIMSession"); + } + } + } + else if(session->isAdHocSessionType()) + { + user_preferences = gSavedSettings.getString("NotificationConferenceIMOptions"); + if (!gAgent.isDoNotDisturb() && (gSavedSettings.getBOOL("PlaySoundConferenceIM") == TRUE)) + { + make_ui_sound("UISndNewIncomingIMSession"); + } + } + else if(session->isGroupSessionType()) + { + user_preferences = gSavedSettings.getString("NotificationGroupChatOptions"); + if (!gAgent.isDoNotDisturb() && (gSavedSettings.getBOOL("PlaySoundGroupChatIM") == TRUE)) + { + make_ui_sound("UISndNewIncomingIMSession"); + } + } - // actions: + // actions: // 0. nothing - exit - if (("none" == user_preferences || + if (("noaction" == user_preferences || ON_TOP_AND_ITEM_IS_SELECTED == conversations_floater_status) && session_floater->isMessagePaneExpanded()) { @@ -262,57 +288,103 @@ void on_new_message(const LLSD& msg) } } } - else - { - //If in DND mode, allow notification to be stored so upon DND exit - //useMostItrusiveIMNotification will be called to notify user a message exists - if(session_id.notNull() - && participant_id.notNull() - && !session_floater->isShown()) - { - LLAvatarNameCache::get(participant_id, boost::bind(&on_avatar_name_cache_toast, _1, _2, msg)); - } - } - } + else + { + store_dnd_message = true; + } - // 2. Flash line item - if ("openconversations" == user_preferences - || ON_TOP == conversations_floater_status - || ("toast" == user_preferences && ON_TOP != conversations_floater_status) - || ("flash" == user_preferences && CLOSED == conversations_floater_status)) - { - if(!LLMuteList::getInstance()->isMuted(participant_id)) - { - im_box->flashConversationItemWidget(session_id, true); - } - } + } - // 3. Flash FUI button - if (("toast" == user_preferences || "flash" == user_preferences) && - (CLOSED == conversations_floater_status - || NOT_ON_TOP == conversations_floater_status)) - { - if(!LLMuteList::getInstance()->isMuted(participant_id) - && !gAgent.isDoNotDisturb()) - { - gToolBarView->flashCommand(LLCommandId("chat"), true); - } - } + // 2. Flash line item + if ("openconversations" == user_preferences + || ON_TOP == conversations_floater_status + || ("toast" == user_preferences && ON_TOP != conversations_floater_status) + || ("flash" == user_preferences && (CLOSED == conversations_floater_status + || NOT_ON_TOP == conversations_floater_status)) + || is_dnd_msg) + { + if(!LLMuteList::getInstance()->isMuted(participant_id)) + { + if(gAgent.isDoNotDisturb()) + { + store_dnd_message = true; + } + else + { + if (is_dnd_msg && (ON_TOP == conversations_floater_status || + NOT_ON_TOP == conversations_floater_status || + CLOSED == conversations_floater_status)) + { + im_box->highlightConversationItemWidget(session_id, true); + } + else + { + im_box->flashConversationItemWidget(session_id, true); + } + } + } + } - // 4. Toast - if ((("toast" == user_preferences) && - (CLOSED == conversations_floater_status - || NOT_ON_TOP == conversations_floater_status)) - || !session_floater->isMessagePaneExpanded()) + // 3. Flash FUI button + if (("toast" == user_preferences || "flash" == user_preferences) && + (CLOSED == conversations_floater_status + || NOT_ON_TOP == conversations_floater_status) + && !is_session_focused + && !is_dnd_msg) //prevent flashing FUI button because the conversation floater will have already opened + { + if(!LLMuteList::getInstance()->isMuted(participant_id)) + { + if(!gAgent.isDoNotDisturb()) + { + gToolBarView->flashCommand(LLCommandId("chat"), true, im_box->isMinimized()); + } + else + { + store_dnd_message = true; + } + } + } - { - //Show IM toasts (upper right toasts) - // Skip toasting for system messages and for nearby chat - if(session_id.notNull() && participant_id.notNull()) - { - LLAvatarNameCache::get(participant_id, boost::bind(&on_avatar_name_cache_toast, _1, _2, msg)); - } - } + // 4. Toast + if ((("toast" == user_preferences) && + (ON_TOP_AND_ITEM_IS_SELECTED != conversations_floater_status) && + (!session_floater->isTornOff() || !LLFloater::isVisible(session_floater))) + || !session_floater->isMessagePaneExpanded()) + + { + //Show IM toasts (upper right toasts) + // Skip toasting for system messages and for nearby chat + if(session_id.notNull() && participant_id.notNull()) + { + if(!is_dnd_msg) + { + if(gAgent.isDoNotDisturb()) + { + store_dnd_message = true; + } + else + { + LLAvatarNameCache::get(participant_id, boost::bind(&on_avatar_name_cache_toast, _1, _2, msg)); + } + } + } + } + if (store_dnd_message) + { + // If in DND mode, allow notification to be stored so upon DND exit + // the user will be notified with some limitations (see 'is_dnd_msg' flag checks) + if(session_id.notNull() + && participant_id.notNull() + && !session_floater->isShown()) + { + LLAvatarNameCache::get(participant_id, boost::bind(&on_avatar_name_cache_toast, _1, _2, msg)); + } + } +} + +void on_new_message(const LLSD& msg) +{ + notify_of_message(msg, false); } LLIMModel::LLIMModel() @@ -2598,6 +2670,13 @@ void LLIMMgr::addMessage( fixed_session_name = session_name; name_is_setted = true; } + bool skip_message = false; + if (gSavedSettings.getBOOL("VoiceCallsFriendsOnly")) + { + // Evaluate if we need to skip this message when that setting is true (default is false) + skip_message = (LLAvatarTracker::instance().getBuddyInfo(other_participant_id) == NULL); // Skip non friends... + skip_message &= !(other_participant_id == gAgentID); // You are your best friend... Don't skip yourself + } bool new_session = !hasSession(new_session_id); if (new_session) @@ -2609,6 +2688,12 @@ void LLIMMgr::addMessage( } LLIMModel::getInstance()->newSession(new_session_id, fixed_session_name, dialog, other_participant_id, false, is_offline_msg); + LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(new_session_id); + skip_message &= !session->isGroupSessionType(); // Do not skip group chats... + if(skip_message) + { + gIMMgr->leaveSession(new_session_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 // when answering questions. @@ -2649,23 +2734,13 @@ void LLIMMgr::addMessage( } } - bool skip_message = false; - if (gSavedSettings.getBOOL("VoiceCallsFriendsOnly")) - { - // Evaluate if we need to skip this message when that setting is true (default is false) - LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(new_session_id); - skip_message = (LLAvatarTracker::instance().getBuddyInfo(other_participant_id) == NULL); // Skip non friends... - skip_message &= !session->isGroupSessionType(); // Do not skip group chats... - skip_message &= !(other_participant_id == gAgentID); // You are your best friend... Don't skip yourself - } - if (!LLMuteList::getInstance()->isMuted(other_participant_id, LLMute::flagTextChat) && !skip_message) { LLIMModel::instance().addMessage(new_session_id, from, other_participant_id, msg); } // Open conversation floater if offline messages are present - if (is_offline_msg) + if (is_offline_msg && !skip_message) { LLFloaterReg::showInstance("im_container"); LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container")-> @@ -2972,10 +3047,9 @@ void LLIMMgr::inviteToSession( { bool isRejectGroupCall = (gSavedSettings.getBOOL("VoiceCallsRejectGroup") && (notify_box_type == "VoiceInviteGroup")); bool isRejectNonFriendCall = (gSavedSettings.getBOOL("VoiceCallsFriendsOnly") && (LLAvatarTracker::instance().getBuddyInfo(caller_id) == NULL)); - bool isRejectDoNotDisturb = (gAgent.isDoNotDisturb() && !hasSession(session_id)); - if (isRejectGroupCall || isRejectNonFriendCall || isRejectDoNotDisturb) + if (isRejectGroupCall || isRejectNonFriendCall || gAgent.isDoNotDisturb()) { - if (isRejectDoNotDisturb && !isRejectGroupCall && !isRejectNonFriendCall) + if (gAgent.isDoNotDisturb() && !isRejectGroupCall && !isRejectNonFriendCall) { LLSD args; addSystemMessage(session_id, "you_auto_rejected_call", args); diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp index 3265676f9b..c71e610941 100755 --- a/indra/newview/llinventoryfilter.cpp +++ b/indra/newview/llinventoryfilter.cpp @@ -70,11 +70,8 @@ LLInventoryFilter::LLInventoryFilter(const Params& p) mFilterSubString(p.substring), mCurrentGeneration(0), mFirstRequiredGeneration(0), - mFirstSuccessGeneration(0), - mFilterCount(0) + mFirstSuccessGeneration(0) { - mNextFilterGeneration = mCurrentGeneration + 1; - // copy mFilterOps into mDefaultFilterOps markDefault(); } @@ -92,9 +89,7 @@ bool LLInventoryFilter::check(const LLFolderViewModelItem* item) return passed_clipboard; } - std::string::size_type string_offset = mFilterSubString.size() ? listener->getSearchableName().find(mFilterSubString) : std::string::npos; - - BOOL passed = (mFilterSubString.size() == 0 || string_offset != std::string::npos); + bool passed = (mFilterSubString.size() ? listener->getSearchableName().find(mFilterSubString) != std::string::npos : true); passed = passed && checkAgainstFilterType(listener); passed = passed && checkAgainstPermissions(listener); passed = passed && checkAgainstFilterLinks(listener); @@ -105,17 +100,12 @@ bool LLInventoryFilter::check(const LLFolderViewModelItem* item) bool LLInventoryFilter::check(const LLInventoryItem* item) { - std::string::size_type string_offset = mFilterSubString.size() ? item->getName().find(mFilterSubString) : std::string::npos; - + const bool passed_string = (mFilterSubString.size() ? item->getName().find(mFilterSubString) != std::string::npos : true); const bool passed_filtertype = checkAgainstFilterType(item); const bool passed_permissions = checkAgainstPermissions(item); - const BOOL passed_clipboard = checkAgainstClipboard(item->getUUID()); - const bool passed = (passed_filtertype - && passed_permissions - && passed_clipboard - && (mFilterSubString.size() == 0 || string_offset != std::string::npos)); + const bool passed_clipboard = checkAgainstClipboard(item->getUUID()); - return passed; + return passed_filtertype && passed_permissions && passed_clipboard && passed_string; } bool LLInventoryFilter::checkFolder(const LLFolderViewModelItem* item) const @@ -439,7 +429,7 @@ void LLInventoryFilter::updateFilterTypes(U64 types, U64& current_types) current_types = types; if (more_bits_set && fewer_bits_set) { - // neither less or more restrive, both simultaneously + // neither less or more restrictive, both simultaneously // so we need to filter from scratch setModified(FILTER_RESTART); } @@ -714,7 +704,7 @@ void LLInventoryFilter::resetDefault() void LLInventoryFilter::setModified(EFilterModified behavior) { mFilterText.clear(); - mCurrentGeneration = mNextFilterGeneration++; + mCurrentGeneration++; if (mFilterModified == FILTER_NONE) { @@ -1021,21 +1011,19 @@ LLInventoryFilter::EFolderShow LLInventoryFilter::getShowFolderState() const return mFilterOps.mShowFolderState; } -void LLInventoryFilter::setFilterCount(S32 count) -{ - mFilterCount = count; -} -S32 LLInventoryFilter::getFilterCount() const +bool LLInventoryFilter::isTimedOut() { - return mFilterCount; + return mFilterTime.hasExpired(); } -void LLInventoryFilter::decrementFilterCount() -{ - mFilterCount--; +void LLInventoryFilter::resetTime(S32 timeout) +{ + mFilterTime.reset(); + F32 time_in_sec = (F32)(timeout)/1000.0; + mFilterTime.setTimerExpirySec(time_in_sec); } -S32 LLInventoryFilter::getCurrentGeneration() const +S32 LLInventoryFilter::getCurrentGeneration() const { return mCurrentGeneration; } diff --git a/indra/newview/llinventoryfilter.h b/indra/newview/llinventoryfilter.h index 4912b5ca91..ce516af0b9 100755 --- a/indra/newview/llinventoryfilter.h +++ b/indra/newview/llinventoryfilter.h @@ -215,12 +215,11 @@ public: void setModified(EFilterModified behavior = FILTER_RESTART); // +-------------------------------------------------------------------+ - // + Count + // + Time // +-------------------------------------------------------------------+ - void setFilterCount(S32 count); - S32 getFilterCount() const; - void decrementFilterCount(); - + void resetTime(S32 timeout); + bool isTimedOut(); + // +-------------------------------------------------------------------+ // + Default // +-------------------------------------------------------------------+ @@ -262,13 +261,15 @@ private: const std::string mName; S32 mCurrentGeneration; + // The following makes checking for pass/no pass possible even if the item is not checked against the current generation + // Any item that *did not pass* the "required generation" will *not pass* the current one + // Any item that *passes* the "success generation" will *pass* the current one S32 mFirstRequiredGeneration; S32 mFirstSuccessGeneration; - S32 mNextFilterGeneration; - S32 mFilterCount; EFilterModified mFilterModified; - + LLTimer mFilterTime; + std::string mFilterText; std::string mEmptyLookupMessage; }; diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index 2a7ae017fb..3276985114 100755 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -192,7 +192,7 @@ LLFolderView * LLInventoryPanel::createFolderRoot(LLUUID root_id ) p.show_item_link_overlays = mShowItemLinkOverlays; p.root = NULL; p.options_menu = "menu_inventory.xml"; - + return LLUICtrlFactory::create<LLFolderView>(p); } @@ -396,8 +396,8 @@ LLInventoryFilter::EFolderShow LLInventoryPanel::getShowFolderState() return getFilter().getShowFolderState(); } +// Called when something changed in the global model (new item, item coming through the wire, rename, move, etc...) (CHUI-849) static LLTrace::TimeBlock FTM_REFRESH("Inventory Refresh"); - void LLInventoryPanel::modelChanged(U32 mask) { LL_RECORD_BLOCK_TIME(FTM_REFRESH); diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp index e8424d840a..a3cdf29ef2 100755 --- a/indra/newview/lllogchat.cpp +++ b/indra/newview/lllogchat.cpp @@ -25,7 +25,7 @@ */ #include "llviewerprecompiledheaders.h" - +#include "llfloaterconversationpreview.h" #include "llagent.h" #include "llagentui.h" #include "llavatarnamecache.h" @@ -206,6 +206,7 @@ private: }; LLLogChat::save_history_signal_t * LLLogChat::sSaveHistorySignal = NULL; +LLLoadHistoryThread::load_end_signal_t * LLLoadHistoryThread::mLoadEndSignal = NULL; //static std::string LLLogChat::makeLogFileName(std::string filename) @@ -336,75 +337,83 @@ void LLLogChat::saveHistory(const std::string& filename, void LLLogChat::loadChatHistory(const std::string& file_name, std::list<LLSD>& messages, const LLSD& load_params) { if (file_name.empty()) - { - LL_WARNS() << "Session name is Empty!" << LL_ENDL; - return ; - } - - bool load_all_history = load_params.has("load_all_history") ? load_params["load_all_history"].asBoolean() : false; + { + LL_WARNS("LLLogChat::loadChatHistory") << "Session name is Empty!" << LL_ENDL; + return ; + } - LLFILE* fptr = LLFile::fopen(makeLogFileName(file_name), "r");/*Flawfinder: ignore*/ - if (!fptr) - { - fptr = LLFile::fopen(oldLogFileName(file_name), "r");/*Flawfinder: ignore*/ - if (!fptr) - { - return; //No previous conversation with this name. - } - } - - char buffer[LOG_RECALL_SIZE]; /*Flawfinder: ignore*/ - char *bptr; - S32 len; - bool firstline = TRUE; + bool load_all_history = load_params.has("load_all_history") ? load_params["load_all_history"].asBoolean() : false; - if (load_all_history || fseek(fptr, (LOG_RECALL_SIZE - 1) * -1 , SEEK_END)) - { //We need to load the whole historyFile or it's smaller than recall size, so get it all. - firstline = FALSE; - if (fseek(fptr, 0, SEEK_SET)) - { - fclose(fptr); - return; - } - } + LLFILE* fptr = LLFile::fopen(LLLogChat::makeLogFileName(file_name), "r");/*Flawfinder: ignore*/ + if (!fptr) + { + fptr = LLFile::fopen(LLLogChat::oldLogFileName(file_name), "r");/*Flawfinder: ignore*/ + if (!fptr) + { + return; //No previous conversation with this name. + } + } - while (fgets(buffer, LOG_RECALL_SIZE, fptr) && !feof(fptr)) - { - len = strlen(buffer) - 1; /*Flawfinder: ignore*/ - for (bptr = (buffer + len); (*bptr == '\n' || *bptr == '\r') && bptr>buffer; bptr--) *bptr='\0'; - - if (firstline) - { - firstline = FALSE; - continue; - } + char buffer[LOG_RECALL_SIZE]; /*Flawfinder: ignore*/ + char *bptr; + S32 len; + bool firstline = TRUE; + + if (load_all_history || fseek(fptr, (LOG_RECALL_SIZE - 1) * -1 , SEEK_END)) + { //We need to load the whole historyFile or it's smaller than recall size, so get it all. + firstline = FALSE; + if (fseek(fptr, 0, SEEK_SET)) + { + fclose(fptr); + return; + } + } + while (fgets(buffer, LOG_RECALL_SIZE, fptr) && !feof(fptr)) + { + len = strlen(buffer) - 1; /*Flawfinder: ignore*/ + for (bptr = (buffer + len); (*bptr == '\n' || *bptr == '\r') && bptr>buffer; bptr--) *bptr='\0'; + + if (firstline) + { + firstline = FALSE; + continue; + } + + std::string line(buffer); + + //updated 1.23 plain text log format requires a space added before subsequent lines in a multilined message + if (' ' == line[0]) + { + line.erase(0, MULTI_LINE_PREFIX.length()); + append_to_last_message(messages, '\n' + line); + } + else if (0 == len && ('\n' == line[0] || '\r' == line[0])) + { + //to support old format's multilined messages with new lines used to divide paragraphs + append_to_last_message(messages, line); + } + else + { + LLSD item; + if (!LLChatLogParser::parse(line, item, load_params)) + { + item[LL_IM_TEXT] = line; + } + messages.push_back(item); + } + } + fclose(fptr); - std::string line(buffer); - //updated 1.23 plaint text log format requires a space added before subsequent lines in a multilined message - if (' ' == line[0]) - { - line.erase(0, MULTI_LINE_PREFIX.length()); - append_to_last_message(messages, '\n' + line); - } - else if (0 == len && ('\n' == line[0] || '\r' == line[0])) - { - //to support old format's multilined messages with new lines used to divide paragraphs - append_to_last_message(messages, line); - } - else - { - LLSD item; - if (!LLChatLogParser::parse(line, item, load_params)) - { - item[LL_IM_TEXT] = line; - } - messages.push_back(item); - } - } - fclose(fptr); } +void LLLogChat::startChatHistoryThread(const std::string& file_name, const LLSD& load_params) +{ + + LLLoadHistoryThread* mThread = new LLLoadHistoryThread(); + mThread->start(); + mThread->setHistoryParams(file_name, load_params); +} // static std::string LLLogChat::oldLogFileName(std::string filename) { @@ -461,6 +470,13 @@ void LLLogChat::findTranscriptFiles(std::string pattern, std::vector<std::string LLFILE * filep = LLFile::fopen(fullname, "rb"); if (NULL != filep) { + if(makeLogFileName("chat")== fullname) + { + //Add Nearby chat history to the list of transcriptions + list_of_transcriptions.push_back(gDirUtilp->add(dirname, filename)); + LLFile::close(filep); + return; + } char buffer[LOG_RECALL_SIZE]; fseek(filep, 0, SEEK_END); // seek to end of file @@ -631,7 +647,7 @@ void LLLogChat::deleteTranscripts() } // static -bool LLLogChat::isTranscriptExist(const LLUUID& avatar_id) +bool LLLogChat::isTranscriptExist(const LLUUID& avatar_id, bool is_group) { std::vector<std::string> list_of_transcriptions; LLLogChat::getListOfTranscriptFiles(list_of_transcriptions); @@ -641,20 +657,53 @@ bool LLLogChat::isTranscriptExist(const LLUUID& avatar_id) LLAvatarName avatar_name; LLAvatarNameCache::get(avatar_id, &avatar_name); std::string avatar_user_name = avatar_name.getAccountName(); - std::replace(avatar_user_name.begin(), avatar_user_name.end(), '.', '_'); - - BOOST_FOREACH(std::string& transcript_file_name, list_of_transcriptions) + if(!is_group) { - if (std::string::npos != transcript_file_name.find(avatar_user_name)) + std::replace(avatar_user_name.begin(), avatar_user_name.end(), '.', '_'); + BOOST_FOREACH(std::string& transcript_file_name, list_of_transcriptions) { - return true; + if (std::string::npos != transcript_file_name.find(avatar_user_name)) + { + return true; + } } } + else + { + std::string file_name; + gCacheName->getGroupName(avatar_id, file_name); + file_name = makeLogFileName(file_name); + BOOST_FOREACH(std::string& transcript_file_name, list_of_transcriptions) + { + if (transcript_file_name == file_name) + { + return true; + } + } + } + } return false; } +bool LLLogChat::isNearbyTranscriptExist() +{ + std::vector<std::string> list_of_transcriptions; + LLLogChat::getListOfTranscriptFiles(list_of_transcriptions); + + std::string file_name; + file_name = makeLogFileName("chat"); + BOOST_FOREACH(std::string& transcript_file_name, list_of_transcriptions) + { + if (transcript_file_name == file_name) + { + return true; + } + } + return false; +} + //*TODO mark object's names in a special way so that they will be distinguishable form avatar name //which are more strict by its nature (only firstname and secondname) //Example, an object's name can be written like "Object <actual_object's_name>" @@ -795,3 +844,116 @@ bool LLChatLogParser::parse(std::string& raw, LLSD& im, const LLSD& parse_params im[LL_IM_TEXT] = name_and_text[IDX_TEXT]; return true; //parsed name and message text, maybe have a timestamp too } + + + + LLLoadHistoryThread::LLLoadHistoryThread() : LLThread("load chat history") + { + mNewLoad = false; + } + + void LLLoadHistoryThread::run() + { + while (!LLApp::isQuitting()) + { + if(mNewLoad) + { + loadHistory(mFileName,mMessages,mLoadParams); + shutdown(); + } + } + } + void LLLoadHistoryThread::setHistoryParams(const std::string& file_name, const LLSD& load_params) + { + mFileName = file_name; + mLoadParams = load_params; + mNewLoad = true; + } + void LLLoadHistoryThread::loadHistory(const std::string& file_name, std::list<LLSD>& messages, const LLSD& load_params) + { + + if (file_name.empty()) + { + LL_WARNS("LLLogChat::loadHistory") << "Session name is Empty!" << LL_ENDL; + return ; + } + + bool load_all_history = load_params.has("load_all_history") ? load_params["load_all_history"].asBoolean() : false; + + LLFILE* fptr = LLFile::fopen(LLLogChat::makeLogFileName(file_name), "r");/*Flawfinder: ignore*/ + if (!fptr) + { + fptr = LLFile::fopen(LLLogChat::oldLogFileName(file_name), "r");/*Flawfinder: ignore*/ + if (!fptr) + { + mNewLoad = false; + (*mLoadEndSignal)(messages, file_name); + return; //No previous conversation with this name. + } + } + + char buffer[LOG_RECALL_SIZE]; /*Flawfinder: ignore*/ + char *bptr; + S32 len; + bool firstline = TRUE; + + if (load_all_history || fseek(fptr, (LOG_RECALL_SIZE - 1) * -1 , SEEK_END)) + { //We need to load the whole historyFile or it's smaller than recall size, so get it all. + firstline = FALSE; + if (fseek(fptr, 0, SEEK_SET)) + { + fclose(fptr); + mNewLoad = false; + (*mLoadEndSignal)(messages, file_name); + return; + } + } + while (fgets(buffer, LOG_RECALL_SIZE, fptr) && !feof(fptr)) + { + len = strlen(buffer) - 1; /*Flawfinder: ignore*/ + for (bptr = (buffer + len); (*bptr == '\n' || *bptr == '\r') && bptr>buffer; bptr--) *bptr='\0'; + + if (firstline) + { + firstline = FALSE; + continue; + } + + std::string line(buffer); + + //updated 1.23 plaint text log format requires a space added before subsequent lines in a multilined message + if (' ' == line[0]) + { + line.erase(0, MULTI_LINE_PREFIX.length()); + append_to_last_message(messages, '\n' + line); + } + else if (0 == len && ('\n' == line[0] || '\r' == line[0])) + { + //to support old format's multilined messages with new lines used to divide paragraphs + append_to_last_message(messages, line); + } + else + { + LLSD item; + if (!LLChatLogParser::parse(line, item, load_params)) + { + item[LL_IM_TEXT] = line; + } + messages.push_back(item); + } + } + fclose(fptr); + mNewLoad = false; + (*mLoadEndSignal)(messages, file_name); + } + + //static + boost::signals2::connection LLLoadHistoryThread::setLoadEndSignal(const load_end_signal_t::slot_type& cb) + { + if (NULL == mLoadEndSignal) + { + mLoadEndSignal = new load_end_signal_t(); + } + + return mLoadEndSignal->connect(cb); + } diff --git a/indra/newview/lllogchat.h b/indra/newview/lllogchat.h index e819f00dd9..86610f99b3 100755 --- a/indra/newview/lllogchat.h +++ b/indra/newview/lllogchat.h @@ -26,8 +26,27 @@ #ifndef LL_LLLOGCHAT_H #define LL_LLLOGCHAT_H +#include "llthread.h" class LLChat; +class LLLoadHistoryThread : public LLThread +{ +private: + std::string mFileName; + std::list<LLSD> mMessages; + LLSD mLoadParams; + bool mNewLoad; +public: + LLLoadHistoryThread(); + + void setHistoryParams(const std::string& file_name, const LLSD& load_params); + virtual void loadHistory(const std::string& file_name, std::list<LLSD>& messages, const LLSD& load_params); + virtual void run(); + + typedef boost::signals2::signal<void (std::list<LLSD>& messages,const std::string& file_name)> load_end_signal_t; + static load_end_signal_t * mLoadEndSignal; + static boost::signals2::connection setLoadEndSignal(const load_end_signal_t::slot_type& cb); +}; class LLLogChat { @@ -39,6 +58,7 @@ public: LOG_LLSD, LOG_END }; + static std::string timestamp(bool withdate = false); static std::string makeLogFileName(std::string(filename)); /** @@ -54,6 +74,7 @@ public: static void getListOfTranscriptBackupFiles(std::vector<std::string>& list_of_transcriptions); static void loadChatHistory(const std::string& file_name, std::list<LLSD>& messages, const LLSD& load_params = LLSD()); + static void startChatHistoryThread(const std::string& file_name, const LLSD& load_params); typedef boost::signals2::signal<void ()> save_history_signal_t; static boost::signals2::connection setSaveHistorySignal(const save_history_signal_t::slot_type& cb); @@ -67,7 +88,8 @@ public: std::vector<std::string>& listOfFilesToMove); static void deleteTranscripts(); - static bool isTranscriptExist(const LLUUID& avatar_id); + static bool isTranscriptExist(const LLUUID& avatar_id, bool is_group=false); + static bool isNearbyTranscriptExist(); private: static std::string cleanFileName(std::string filename); @@ -126,6 +148,7 @@ protected: virtual ~LLChatLogParser() {}; }; + // LLSD map lookup constants extern const std::string LL_IM_TIME; //("time"); extern const std::string LL_IM_TEXT; //("message"); diff --git a/indra/newview/llmaniprotate.cpp b/indra/newview/llmaniprotate.cpp index 224bfe3a17..8185cbb1a3 100755 --- a/indra/newview/llmaniprotate.cpp +++ b/indra/newview/llmaniprotate.cpp @@ -1376,74 +1376,28 @@ LLQuaternion LLManipRotate::dragConstrained( S32 x, S32 y ) BOOL hit = getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, constraint_axis); projected_mouse -= snap_plane_center; - S32 snap_plane = 0; - - F32 dot = cam_to_snap_plane * constraint_axis; - if (llabs(dot) < 0.01f) - { - // looking at ring edge on, project onto view plane and check if mouse is past ring - getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, cam_to_snap_plane); - projected_mouse -= snap_plane_center; - dot = projected_mouse * constraint_axis; - if (projected_mouse * constraint_axis > 0) - { - snap_plane = 1; - } - projected_mouse -= dot * constraint_axis; - } - else if (dot > 0.f) - { - // look for mouse position outside and in front of snap circle - if (hit && projected_mouse.magVec() > SNAP_GUIDE_INNER_RADIUS * mRadiusMeters && projected_mouse * cam_to_snap_plane < 0.f) - { - snap_plane = 1; - } - } - else - { - // look for mouse position inside or in back of snap circle - if (projected_mouse.magVec() < SNAP_GUIDE_INNER_RADIUS * mRadiusMeters || projected_mouse * cam_to_snap_plane > 0.f || !hit) - { - snap_plane = 1; - } - } - - if (snap_plane == 0) - { - // try other plane - snap_plane_center = (center - (constraint_axis * mRadiusMeters * 0.5f)); - if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) - { - cam_to_snap_plane.setVec(1.f, 0.f, 0.f); - } - else - { - cam_to_snap_plane = snap_plane_center - gAgentCamera.getCameraPositionAgent(); - cam_to_snap_plane.normVec(); - } - - hit = getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, constraint_axis); - projected_mouse -= snap_plane_center; - - dot = cam_to_snap_plane * constraint_axis; + if (gSavedSettings.getBOOL("SnapEnabled")) { + S32 snap_plane = 0; + + F32 dot = cam_to_snap_plane * constraint_axis; if (llabs(dot) < 0.01f) { // looking at ring edge on, project onto view plane and check if mouse is past ring getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, cam_to_snap_plane); projected_mouse -= snap_plane_center; dot = projected_mouse * constraint_axis; - if (projected_mouse * constraint_axis < 0) + if (projected_mouse * constraint_axis > 0) { - snap_plane = 2; + snap_plane = 1; } projected_mouse -= dot * constraint_axis; } - else if (dot < 0.f) + else if (dot > 0.f) { // look for mouse position outside and in front of snap circle if (hit && projected_mouse.magVec() > SNAP_GUIDE_INNER_RADIUS * mRadiusMeters && projected_mouse * cam_to_snap_plane < 0.f) { - snap_plane = 2; + snap_plane = 1; } } else @@ -1451,78 +1405,136 @@ LLQuaternion LLManipRotate::dragConstrained( S32 x, S32 y ) // look for mouse position inside or in back of snap circle if (projected_mouse.magVec() < SNAP_GUIDE_INNER_RADIUS * mRadiusMeters || projected_mouse * cam_to_snap_plane > 0.f || !hit) { - snap_plane = 2; + snap_plane = 1; } } - } - - if (snap_plane > 0) - { - LLVector3 cam_at_axis; - if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) - { - cam_at_axis.setVec(1.f, 0.f, 0.f); - } - else - { - cam_at_axis = snap_plane_center - gAgentCamera.getCameraPositionAgent(); - cam_at_axis.normVec(); - } - - // first, project mouse onto screen plane at point tangent to rotation radius. - getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, cam_at_axis); - // project that point onto rotation plane - projected_mouse -= snap_plane_center; - projected_mouse -= projected_vec(projected_mouse, constraint_axis); - - F32 mouse_lateral_dist = llmin(SNAP_GUIDE_INNER_RADIUS * mRadiusMeters, projected_mouse.magVec()); - F32 mouse_depth = SNAP_GUIDE_INNER_RADIUS * mRadiusMeters; - if (llabs(mouse_lateral_dist) > 0.01f) - { - mouse_depth = sqrtf((SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) * (SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) - - (mouse_lateral_dist * mouse_lateral_dist)); - } - LLVector3 projected_camera_at = cam_at_axis - projected_vec(cam_at_axis, constraint_axis); - projected_mouse -= mouse_depth * projected_camera_at; - - if (!mInSnapRegime) + + if (snap_plane == 0) { - mSmoothRotate = TRUE; + // try other plane + snap_plane_center = (center - (constraint_axis * mRadiusMeters * 0.5f)); + if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) + { + cam_to_snap_plane.setVec(1.f, 0.f, 0.f); + } + else + { + cam_to_snap_plane = snap_plane_center - gAgentCamera.getCameraPositionAgent(); + cam_to_snap_plane.normVec(); + } + + hit = getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, constraint_axis); + projected_mouse -= snap_plane_center; + + dot = cam_to_snap_plane * constraint_axis; + if (llabs(dot) < 0.01f) + { + // looking at ring edge on, project onto view plane and check if mouse is past ring + getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, cam_to_snap_plane); + projected_mouse -= snap_plane_center; + dot = projected_mouse * constraint_axis; + if (projected_mouse * constraint_axis < 0) + { + snap_plane = 2; + } + projected_mouse -= dot * constraint_axis; + } + else if (dot < 0.f) + { + // look for mouse position outside and in front of snap circle + if (hit && projected_mouse.magVec() > SNAP_GUIDE_INNER_RADIUS * mRadiusMeters && projected_mouse * cam_to_snap_plane < 0.f) + { + snap_plane = 2; + } + } + else + { + // look for mouse position inside or in back of snap circle + if (projected_mouse.magVec() < SNAP_GUIDE_INNER_RADIUS * mRadiusMeters || projected_mouse * cam_to_snap_plane > 0.f || !hit) + { + snap_plane = 2; + } + } } - mInSnapRegime = TRUE; - // 0 to 360 deg - F32 mouse_angle = fmodf(atan2(projected_mouse * axis1, projected_mouse * axis2) * RAD_TO_DEG + 360.f, 360.f); - F32 relative_mouse_angle = fmodf(mouse_angle + (SNAP_ANGLE_DETENTE / 2), SNAP_ANGLE_INCREMENT); - //fmodf(llround(mouse_angle * RAD_TO_DEG, 7.5f) + 360.f, 360.f); - - LLVector3 object_axis; - getObjectAxisClosestToMouse(object_axis); - object_axis = object_axis * first_object_node->mSavedRotation; - - // project onto constraint plane - object_axis = object_axis - (object_axis * getConstraintAxis()) * getConstraintAxis(); - object_axis.normVec(); - - if (relative_mouse_angle < SNAP_ANGLE_DETENTE) + if (snap_plane > 0) { - F32 quantized_mouse_angle = mouse_angle - (relative_mouse_angle - (SNAP_ANGLE_DETENTE * 0.5f)); - angle = (quantized_mouse_angle * DEG_TO_RAD) - atan2(object_axis * axis1, object_axis * axis2); + LLVector3 cam_at_axis; + if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) + { + cam_at_axis.setVec(1.f, 0.f, 0.f); + } + else + { + cam_at_axis = snap_plane_center - gAgentCamera.getCameraPositionAgent(); + cam_at_axis.normVec(); + } + + // first, project mouse onto screen plane at point tangent to rotation radius. + getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, cam_at_axis); + // project that point onto rotation plane + projected_mouse -= snap_plane_center; + projected_mouse -= projected_vec(projected_mouse, constraint_axis); + + F32 mouse_lateral_dist = llmin(SNAP_GUIDE_INNER_RADIUS * mRadiusMeters, projected_mouse.magVec()); + F32 mouse_depth = SNAP_GUIDE_INNER_RADIUS * mRadiusMeters; + if (llabs(mouse_lateral_dist) > 0.01f) + { + mouse_depth = sqrtf((SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) * (SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) - + (mouse_lateral_dist * mouse_lateral_dist)); + } + LLVector3 projected_camera_at = cam_at_axis - projected_vec(cam_at_axis, constraint_axis); + projected_mouse -= mouse_depth * projected_camera_at; + + if (!mInSnapRegime) + { + mSmoothRotate = TRUE; + } + mInSnapRegime = TRUE; + // 0 to 360 deg + F32 mouse_angle = fmodf(atan2(projected_mouse * axis1, projected_mouse * axis2) * RAD_TO_DEG + 360.f, 360.f); + + F32 relative_mouse_angle = fmodf(mouse_angle + (SNAP_ANGLE_DETENTE / 2), SNAP_ANGLE_INCREMENT); + //fmodf(llround(mouse_angle * RAD_TO_DEG, 7.5f) + 360.f, 360.f); + + LLVector3 object_axis; + getObjectAxisClosestToMouse(object_axis); + object_axis = object_axis * first_object_node->mSavedRotation; + + // project onto constraint plane + object_axis = object_axis - (object_axis * getConstraintAxis()) * getConstraintAxis(); + object_axis.normVec(); + + if (relative_mouse_angle < SNAP_ANGLE_DETENTE) + { + F32 quantized_mouse_angle = mouse_angle - (relative_mouse_angle - (SNAP_ANGLE_DETENTE * 0.5f)); + angle = (quantized_mouse_angle * DEG_TO_RAD) - atan2(object_axis * axis1, object_axis * axis2); + } + else + { + angle = (mouse_angle * DEG_TO_RAD) - atan2(object_axis * axis1, object_axis * axis2); + } + return LLQuaternion( -angle, constraint_axis ); } else { - angle = (mouse_angle * DEG_TO_RAD) - atan2(object_axis * axis1, object_axis * axis2); + if (mInSnapRegime) + { + mSmoothRotate = TRUE; + } + mInSnapRegime = FALSE; } - return LLQuaternion( -angle, constraint_axis ); } - else - { + else { if (mInSnapRegime) { mSmoothRotate = TRUE; } mInSnapRegime = FALSE; - + } + + if (!mInSnapRegime) + { LLVector3 up_from_axis = mCenterToCamNorm % constraint_axis; up_from_axis.normVec(); LLVector3 cur_intersection; diff --git a/indra/newview/llnotificationstorage.h b/indra/newview/llnotificationstorage.h index 7aabf7d09e..53fd898ea4 100755 --- a/indra/newview/llnotificationstorage.h +++ b/indra/newview/llnotificationstorage.h @@ -44,6 +44,7 @@ public: protected: bool writeNotifications(const LLSD& pNotificationData) const; bool readNotifications(LLSD& pNotificationData) const; + void setFileName(std::string pFileName) {mFileName = pFileName;} LLNotificationResponderInterface* createResponder(const std::string& pNotificationName, const LLSD& pParams) const; diff --git a/indra/newview/llnotificationtiphandler.cpp b/indra/newview/llnotificationtiphandler.cpp index a85335f1ba..4ca961c1f9 100755 --- a/indra/newview/llnotificationtiphandler.cpp +++ b/indra/newview/llnotificationtiphandler.cpp @@ -83,13 +83,6 @@ bool LLTipHandler::processNotification(const LLNotificationPtr& notification) if (notification->canLogToChat()) { LLHandlerUtil::logToNearbyChat(notification, CHAT_SOURCE_SYSTEM); - - // don't show toast if Nearby Chat is opened - LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"); - if (nearby_chat->isChatVisible()) - { - return false; - } } std::string session_name = notification->getPayload()["SESSION_NAME"]; diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp index 2d9b3118e1..4deb02f6fa 100755 --- a/indra/newview/llpanelgrouproles.cpp +++ b/indra/newview/llpanelgrouproles.cpp @@ -1101,27 +1101,61 @@ void LLPanelGroupMembersSubTab::onEjectMembers(void *userdata) } void LLPanelGroupMembersSubTab::handleEjectMembers() -{ - //send down an eject message - uuid_vec_t selected_members; - +{ std::vector<LLScrollListItem*> selection = mMembersList->getAllSelected(); if (selection.empty()) return; - - std::vector<LLScrollListItem*>::iterator itor; - for (itor = selection.begin() ; - itor != selection.end(); ++itor) + + S32 selection_count = selection.size(); + if (selection_count == 1) { - LLUUID member_id = (*itor)->getUUID(); - selected_members.push_back( member_id ); + LLSD args; + LLUUID selected_avatar = mMembersList->getValue().asUUID(); + std::string fullname = LLSLURL("agent", selected_avatar, "inspect").getSLURLString(); + args["AVATAR_NAME"] = fullname; + LLSD payload; + LLNotificationsUtil::add("EjectGroupMemberWarning", + args, + payload, + boost::bind(&LLPanelGroupMembersSubTab::handleEjectCallback, this, _1, _2)); } + else + { + LLSD args; + args["COUNT"] = llformat("%d", selection_count); + LLSD payload; + LLNotificationsUtil::add("EjectGroupMembersWarning", + args, + payload, + boost::bind(&LLPanelGroupMembersSubTab::handleEjectCallback, this, _1, _2)); + } +} - mMembersList->deleteSelectedItems(); - - sendEjectNotifications(mGroupID, selected_members); - - LLGroupMgr::getInstance()->sendGroupMemberEjects(mGroupID, - selected_members); +bool LLPanelGroupMembersSubTab::handleEjectCallback(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (0 == option) // Eject button + { + //send down an eject message + uuid_vec_t selected_members; + + std::vector<LLScrollListItem*> selection = mMembersList->getAllSelected(); + if (selection.empty()) return false; + + std::vector<LLScrollListItem*>::iterator itor; + for (itor = selection.begin() ; + itor != selection.end(); ++itor) + { + LLUUID member_id = (*itor)->getUUID(); + selected_members.push_back( member_id ); + } + + mMembersList->deleteSelectedItems(); + + sendEjectNotifications(mGroupID, selected_members); + + LLGroupMgr::getInstance()->sendGroupMemberEjects(mGroupID, selected_members); + } + return false; } void LLPanelGroupMembersSubTab::sendEjectNotifications(const LLUUID& group_id, const uuid_vec_t& selected_members) diff --git a/indra/newview/llpanelgrouproles.h b/indra/newview/llpanelgrouproles.h index 78bb3c57a1..0cf272f3ee 100755 --- a/indra/newview/llpanelgrouproles.h +++ b/indra/newview/llpanelgrouproles.h @@ -167,6 +167,7 @@ public: static void onEjectMembers(void*); void handleEjectMembers(); void sendEjectNotifications(const LLUUID& group_id, const uuid_vec_t& selected_members); + bool handleEjectCallback(const LLSD& notification, const LLSD& response); static void onRoleCheck(LLUICtrl* check, void* user_data); void handleRoleCheck(const LLUUID& role_id, diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp index efcfd045ba..707f43660c 100755 --- a/indra/newview/llpanellogin.cpp +++ b/indra/newview/llpanellogin.cpp @@ -81,10 +81,6 @@ const S32 MAX_PASSWORD = 16; LLPanelLogin *LLPanelLogin::sInstance = NULL; BOOL LLPanelLogin::sCapslockDidNotification = FALSE; -// Helper for converting a user name into the canonical "Firstname Lastname" form. -// For new accounts without a last name "Resident" is added as a last name. -static std::string canonicalize_username(const std::string& name); - class LLLoginRefreshHandler : public LLCommandHandler { public: @@ -265,7 +261,6 @@ void LLPanelLogin::addFavoritesToStartLocation() // Load favorites into the combo. std::string user_defined_name = getChild<LLComboBox>("username_combo")->getSimple(); - std::string canonical_user_name = canonicalize_username(user_defined_name); std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites.xml"); LLSD fav_llsd; llifstream file; @@ -278,7 +273,7 @@ void LLPanelLogin::addFavoritesToStartLocation() // The account name in stored_favorites.xml has Resident last name even if user has // a single word account name, so it can be compared case-insensitive with the // user defined "firstname lastname". - S32 res = LLStringUtil::compareInsensitive(canonical_user_name, iter->first); + S32 res = LLStringUtil::compareInsensitive(user_defined_name, iter->first); if (res != 0) { LL_DEBUGS() << "Skipping favorites for " << iter->first << LL_ENDL; @@ -1011,29 +1006,3 @@ void LLPanelLogin::onLocationSLURL() LLStartUp::setStartSLURL(location); // calls onUpdateStartSLURL, above } - - -std::string canonicalize_username(const std::string& name) -{ - std::string cname = name; - LLStringUtil::trim(cname); - - // determine if the username is a first/last form or not. - size_t separator_index = cname.find_first_of(" ._"); - std::string first = cname.substr(0, separator_index); - std::string last; - if (separator_index != cname.npos) - { - last = cname.substr(separator_index+1, cname.npos); - LLStringUtil::trim(last); - } - else - { - // ...on Linden grids, single username users as considered to have - // last name "Resident" - last = "Resident"; - } - - // Username in traditional "firstname lastname" form. - return first + ' ' + last; -} diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp index 7bf5e28822..89e9e6e2a0 100755 --- a/indra/newview/llpanelmaininventory.cpp +++ b/indra/newview/llpanelmaininventory.cpp @@ -130,6 +130,8 @@ BOOL LLPanelMainInventory::postBuild() mFilterTabs = getChild<LLTabContainer>("inventory filter tabs"); mFilterTabs->setCommitCallback(boost::bind(&LLPanelMainInventory::onFilterSelected, this)); + mCounterCtrl = getChild<LLUICtrl>("ItemcountText"); + //panel->getFilter().markDefault(); // Set up the default inv. panel/filter settings. @@ -566,7 +568,7 @@ void LLPanelMainInventory::draw() void LLPanelMainInventory::updateItemcountText() { // *TODO: Calling setlocale() on each frame may be inefficient. - LLLocale locale(LLStringUtil::getLocale()); + //LLLocale locale(LLStringUtil::getLocale()); std::string item_count_string; LLResMgr::getInstance()->getIntegerString(item_count_string, gInventory.getItemCount()); @@ -589,8 +591,7 @@ void LLPanelMainInventory::updateItemcountText() text = getString("ItemcountUnknown"); } - // *TODO: Cache the LLUICtrl* for the ItemcountText control - getChild<LLUICtrl>("ItemcountText")->setValue(text); + mCounterCtrl->setValue(text); } void LLPanelMainInventory::onFocusReceived() diff --git a/indra/newview/llpanelmaininventory.h b/indra/newview/llpanelmaininventory.h index 899931aa89..394b004e20 100755 --- a/indra/newview/llpanelmaininventory.h +++ b/indra/newview/llpanelmaininventory.h @@ -121,6 +121,7 @@ private: LLFilterEditor* mFilterEditor; LLTabContainer* mFilterTabs; + LLUICtrl* mCounterCtrl; LLHandle<LLFloater> mFinderHandle; LLInventoryPanel* mActivePanel; bool mResortActivePanel; diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp index c9688e743e..2c8cd13b70 100755 --- a/indra/newview/llpanelpeople.cpp +++ b/indra/newview/llpanelpeople.cpp @@ -76,6 +76,8 @@ static const std::string BLOCKED_TAB_NAME = "blocked_panel"; // blocked avatars static const std::string COLLAPSED_BY_USER = "collapsed_by_user"; +extern S32 gMaxAgentGroups; + /** Comparator for comparing avatar items by last interaction date */ class LLAvatarItemRecentComparator : public LLAvatarItemComparator { @@ -808,6 +810,8 @@ void LLPanelPeople::updateButtons() LLPanel* groups_panel = mTabContainer->getCurrentPanel(); groups_panel->getChildView("minus_btn")->setEnabled(item_selected && selected_id.notNull()); // a real group selected + groups_panel->getChild<LLUICtrl>("groupcount")->setTextArg("[COUNT]", llformat("%d",gAgent.mGroups.size())); + groups_panel->getChild<LLUICtrl>("groupcount")->setTextArg("[REMAINING]", llformat("%d",(gMaxAgentGroups-gAgent.mGroups.size()))); } else { diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 0e7a8b9d00..f91c4110c0 100755 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -36,6 +36,8 @@ #include "lltabcontainer.h" #include "llviewercontrol.h" #include "llviewernetwork.h" +#include "llmutelist.h" +#include "llpanelblockedlist.h" #include "llweb.h" static const std::string PANEL_PICKS = "panel_picks"; @@ -138,6 +140,12 @@ public: return true; } + if (verb == "removefriend") + { + LLAvatarActions::removeFriendDialog(avatar_id); + return true; + } + if (verb == "mute") { if (! LLAvatarActions::isBlocked(avatar_id)) @@ -156,6 +164,18 @@ public: return true; } + if (verb == "block") + { + if (params.size() > 2) + { + const std::string object_name = params[2].asString(); + LLMute mute(avatar_id, object_name, LLMute::OBJECT); + LLMuteList::getInstance()->add(mute); + LLPanelBlockedList::showPanelAndSelect(mute.mID); + } + return true; + } + return false; } }; diff --git a/indra/newview/llpersistentnotificationstorage.cpp b/indra/newview/llpersistentnotificationstorage.cpp index bd4b0a0b08..c13c305791 100755 --- a/indra/newview/llpersistentnotificationstorage.cpp +++ b/indra/newview/llpersistentnotificationstorage.cpp @@ -38,7 +38,8 @@ LLPersistentNotificationStorage::LLPersistentNotificationStorage() : LLSingleton<LLPersistentNotificationStorage>() - , LLNotificationStorage(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "open_notifications.xml")) + , LLNotificationStorage("") + , mLoaded(false) { } @@ -89,8 +90,13 @@ void LLPersistentNotificationStorage::loadNotifications() LL_INFOS("LLPersistentNotificationStorage") << "start loading notifications" << LL_ENDL; - LLNotifications::instance().getChannel("Persistent")-> - connectChanged(boost::bind(&LLPersistentNotificationStorage::onPersistentChannelChanged, this, _1)); + if (mLoaded) + { + LL_INFOS("LLPersistentNotificationStorage") << "notifications already loaded, exiting" << LL_ENDL; + return; + } + + mLoaded = true; LLSD input; if (!readNotifications(input) ||input.isUndefined()) @@ -135,8 +141,20 @@ void LLPersistentNotificationStorage::loadNotifications() LL_INFOS("LLPersistentNotificationStorage") << "finished loading notifications" << LL_ENDL; } +void LLPersistentNotificationStorage::initialize() +{ + setFileName(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "open_notifications.xml")); + LLNotifications::instance().getChannel("Persistent")-> + connectChanged(boost::bind(&LLPersistentNotificationStorage::onPersistentChannelChanged, this, _1)); +} + bool LLPersistentNotificationStorage::onPersistentChannelChanged(const LLSD& payload) { + // In case we received channel changed signal but haven't yet loaded notifications, do it + if (!mLoaded) + { + loadNotifications(); + } // we ignore "load" messages, but rewrite the persistence file on any other const std::string sigtype = payload["sigtype"].asString(); if ("load" != sigtype) diff --git a/indra/newview/llpersistentnotificationstorage.h b/indra/newview/llpersistentnotificationstorage.h index 98a825d2c1..bf0306380e 100755 --- a/indra/newview/llpersistentnotificationstorage.h +++ b/indra/newview/llpersistentnotificationstorage.h @@ -53,10 +53,13 @@ public: void saveNotifications(); void loadNotifications(); + void initialize(); + protected: private: bool onPersistentChannelChanged(const LLSD& payload); + bool mLoaded; }; #endif // LL_LLPERSISTENTNOTIFICATIONSTORAGE_H diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index 70a280ca09..870304a7b8 100755 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -86,6 +86,7 @@ #include "lltrans.h" #include "llviewercontrol.h" #include "llappviewer.h" +#include "llfloatergotoline.h" const std::string HELLO_LSL = "default\n" @@ -193,12 +194,17 @@ private: LLScriptEdCore* mEditorCore; static LLFloaterScriptSearch* sInstance; + +protected: + LLLineEditor* mSearchBox; + void onSearchBoxCommit(); }; LLFloaterScriptSearch* LLFloaterScriptSearch::sInstance = NULL; LLFloaterScriptSearch::LLFloaterScriptSearch(LLScriptEdCore* editor_core) : LLFloater(LLSD()), + mSearchBox(NULL), mEditorCore(editor_core) { buildFromFile("floater_script_search.xml"); @@ -221,6 +227,9 @@ LLFloaterScriptSearch::LLFloaterScriptSearch(LLScriptEdCore* editor_core) BOOL LLFloaterScriptSearch::postBuild() { + mSearchBox = getChild<LLLineEditor>("search_text"); + mSearchBox->setCommitCallback(boost::bind(&LLFloaterScriptSearch::onSearchBoxCommit, this)); + mSearchBox->setCommitOnFocusLost(FALSE); childSetAction("search_btn", onBtnSearch,this); childSetAction("replace_btn", onBtnReplace,this); childSetAction("replace_all_btn", onBtnReplaceAll,this); @@ -315,6 +324,15 @@ BOOL LLFloaterScriptSearch::handleKeyHere(KEY key, MASK mask) return FALSE; } +void LLFloaterScriptSearch::onSearchBoxCommit() +{ + if (mEditorCore && mEditorCore->mEditor) + { + LLCheckBoxCtrl* caseChk = getChild<LLCheckBoxCtrl>("case_text"); + mEditorCore->mEditor->selectNext(getChild<LLUICtrl>("search_text")->getValue().asString(), caseChk->get()); + } +} + /// --------------------------------------------------------------------------- /// LLScriptEdCore /// --------------------------------------------------------------------------- @@ -503,6 +521,9 @@ void LLScriptEdCore::initMenu() menuItem = getChild<LLMenuItemCallGL>("Search / Replace..."); menuItem->setClickCallback(boost::bind(&LLFloaterScriptSearch::show, this)); + menuItem = getChild<LLMenuItemCallGL>("Go to line..."); + menuItem->setClickCallback(boost::bind(&LLFloaterGotoLine::show, this)); + menuItem = getChild<LLMenuItemCallGL>("Help..."); menuItem->setClickCallback(boost::bind(&LLScriptEdCore::onBtnHelp, this)); diff --git a/indra/newview/llpreviewscript.h b/indra/newview/llpreviewscript.h index a799f3c167..cb53d1df07 100755 --- a/indra/newview/llpreviewscript.h +++ b/indra/newview/llpreviewscript.h @@ -33,6 +33,7 @@ #include "llcombobox.h" #include "lliconctrl.h" #include "llframetimer.h" +#include "llfloatergotoline.h" class LLLiveLSLFile; class LLMessageSystem; @@ -48,6 +49,7 @@ class LLKeywordToken; class LLVFS; class LLViewerInventoryItem; class LLScriptEdContainer; +class LLFloaterGotoLine; // Inner, implementation class. LLPreviewScript and LLLiveLSLEditor each own one of these. class LLScriptEdCore : public LLPanel @@ -57,6 +59,7 @@ class LLScriptEdCore : public LLPanel friend class LLLiveLSLEditor; friend class LLFloaterScriptSearch; friend class LLScriptEdContainer; + friend class LLFloaterGotoLine; protected: // Supposed to be invoked only by the container. diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index fdd289c823..39ced906ad 100755 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -51,6 +51,7 @@ #include "lllandmark.h" #include "llcachename.h" #include "lldir.h" +#include "lldonotdisturbnotificationstorage.h" #include "llerrorcontrol.h" #include "llfloaterreg.h" #include "llfocusmgr.h" @@ -68,6 +69,7 @@ #include "llfloaterimnearbychat.h" #include "llnotifications.h" #include "llnotificationsutil.h" +#include "llpersistentnotificationstorage.h" #include "llteleporthistory.h" #include "llregionhandle.h" #include "llsd.h" @@ -898,6 +900,10 @@ bool idle_startup() gDirUtilp->setLindenUserDir(userid); LLFile::mkdir(gDirUtilp->getLindenUserDir()); + // As soon as directories are ready initialize notification storages + LLPersistentNotificationStorage::getInstance()->initialize(); + LLDoNotDisturbNotificationStorage::getInstance()->initialize(); + // Set PerAccountSettingsFile to the default value. gSavedSettings.setString("PerAccountSettingsFile", gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, diff --git a/indra/newview/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp index 5612d09f7f..97b5b8fec6 100755 --- a/indra/newview/llsyswellwindow.cpp +++ b/indra/newview/llsyswellwindow.cpp @@ -423,9 +423,18 @@ void LLNotificationWellWindow::onItemClick(LLSysWellItem* item) void LLNotificationWellWindow::onItemClose(LLSysWellItem* item) { LLUUID id = item->getID(); - removeItemByID(id); + if(mChannel) + { + // removeItemByID() is invoked from killToastByNotificationID() and item will removed; mChannel->killToastByNotificationID(id); + } + else + { + // removeItemByID() should be called one time for each item to remove it from notification well + removeItemByID(id); + } + } void LLNotificationWellWindow::onAdd( LLNotificationPtr notify ) diff --git a/indra/newview/lltoastimpanel.cpp b/indra/newview/lltoastimpanel.cpp index 81dfd95f16..a4f0df869f 100755 --- a/indra/newview/lltoastimpanel.cpp +++ b/indra/newview/lltoastimpanel.cpp @@ -28,6 +28,7 @@ #include "lltoastimpanel.h" #include "llagent.h" +#include "llavatarnamecache.h" #include "llfloaterreg.h" #include "llgroupactions.h" #include "llgroupiconctrl.h" @@ -61,6 +62,15 @@ LLToastIMPanel::LLToastIMPanel(LLToastIMPanel::Params &p) : LLToastPanel(p.notif style_params.font.name(font_name); style_params.font.size(font_size); + LLIMModel::LLIMSession* im_session = LLIMModel::getInstance()->findIMSession(p.session_id); + mIsGroupMsg = (im_session && im_session->mSessionType == LLIMModel::LLIMSession::GROUP_SESSION); + if(mIsGroupMsg) + { + mAvatarName->setValue(im_session->mName); + LLAvatarName avatar_name; + LLAvatarNameCache::get(p.avatar_id, &avatar_name); + p.message = "[From " + avatar_name.getDisplayName() + "]\n" + p.message; + } //Handle IRC styled /me messages. std::string prefix = p.message.substr(0, 4); @@ -81,12 +91,17 @@ LLToastIMPanel::LLToastIMPanel(LLToastIMPanel::Params &p) : LLToastPanel(p.notif mMessage->setText(p.message, style_params); } - mAvatarName->setValue(p.from); + if(!mIsGroupMsg) + { + mAvatarName->setValue(p.from); + } mTime->setValue(p.time); mSessionID = p.session_id; mAvatarID = p.avatar_id; mNotification = p.notification; + + initIcon(); S32 maxLinesCount; @@ -147,7 +162,14 @@ void LLToastIMPanel::spawnNameToolTip() LLToolTip::Params params; params.background_visible(false); - params.click_callback(boost::bind(&LLFloaterReg::showInstance, "inspect_avatar", LLSD().with("avatar_id", mAvatarID), FALSE)); + if(!mIsGroupMsg) + { + params.click_callback(boost::bind(&LLFloaterReg::showInstance, "inspect_avatar", LLSD().with("avatar_id", mAvatarID), FALSE)); + } + else + { + params.click_callback(boost::bind(&LLFloaterReg::showInstance, "inspect_group", LLSD().with("group_id", mSessionID), FALSE)); + } params.delay_time(0.0f); // spawn instantly on hover params.image(LLUI::getUIImage("Info_Small")); params.message(""); diff --git a/indra/newview/lltoastimpanel.h b/indra/newview/lltoastimpanel.h index 3eb11fb3bc..767617dabc 100755 --- a/indra/newview/lltoastimpanel.h +++ b/indra/newview/lltoastimpanel.h @@ -73,6 +73,8 @@ private: LLTextBox* mAvatarName; LLTextBox* mTime; LLTextBox* mMessage; + + bool mIsGroupMsg; }; #endif // LLTOASTIMPANEL_H_ diff --git a/indra/newview/lltoolbarview.cpp b/indra/newview/lltoolbarview.cpp index 98eac008b3..efad4e6aef 100755 --- a/indra/newview/lltoolbarview.cpp +++ b/indra/newview/lltoolbarview.cpp @@ -51,8 +51,6 @@ LLToolBarView* gToolBarView = NULL; static LLDefaultChildRegistry::Register<LLToolBarView> r("toolbar_view"); -void handleLoginToolbarSetup(); - bool isToolDragged() { return (LLToolDragAndDrop::getInstance()->getSource() == LLToolDragAndDrop::SOURCE_VIEWER); @@ -111,8 +109,6 @@ BOOL LLToolBarView::postBuild() mToolbars[i]->setButtonAddCallback(boost::bind(LLToolBarView::onToolBarButtonAdded,_1)); mToolbars[i]->setButtonRemoveCallback(boost::bind(LLToolBarView::onToolBarButtonRemoved,_1)); } - - LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&handleLoginToolbarSetup)); return TRUE; } @@ -180,13 +176,13 @@ S32 LLToolBarView::stopCommandInProgress(const LLCommandId& commandId) return command_location; } -S32 LLToolBarView::flashCommand(const LLCommandId& commandId, bool flash) +S32 LLToolBarView::flashCommand(const LLCommandId& commandId, bool flash, bool force_flashing/* = false */) { S32 command_location = hasCommand(commandId); if (command_location != TOOLBAR_NONE) { - mToolbars[command_location]->flashCommand(commandId, flash); + mToolbars[command_location]->flashCommand(commandId, flash, force_flashing); } return command_location; @@ -696,18 +692,3 @@ bool LLToolBarView::isModified() const } -// -// HACK to bring up destinations guide at startup -// - -void handleLoginToolbarSetup() -{ - // Open the destinations guide by default on first login, per Rhett - if (gSavedPerAccountSettings.getBOOL("DisplayDestinationsOnInitialRun") || gAgent.isFirstLogin()) - { - LLFloaterReg::showInstance("destinations"); - - gSavedPerAccountSettings.setBOOL("DisplayDestinationsOnInitialRun", FALSE); - } -} - diff --git a/indra/newview/lltoolbarview.h b/indra/newview/lltoolbarview.h index 7125dd9990..dcc3862074 100755 --- a/indra/newview/lltoolbarview.h +++ b/indra/newview/lltoolbarview.h @@ -90,7 +90,7 @@ public: S32 removeCommand(const LLCommandId& commandId, int& rank); // Sets the rank the removed command was at, RANK_NONE if not found S32 enableCommand(const LLCommandId& commandId, bool enabled); S32 stopCommandInProgress(const LLCommandId& commandId); - S32 flashCommand(const LLCommandId& commandId, bool flash); + S32 flashCommand(const LLCommandId& commandId, bool flash, bool force_flashing = false); // Loads the toolbars from the existing user or default settings bool loadToolbars(bool force_default = false); // return false if load fails diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 95419c7cf3..70d3fc9462 100755 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -83,7 +83,9 @@ BOOL gHackGodmode = FALSE; #endif - +// Should you contemplate changing the name "Global", please first grep for +// that string literal. There are at least a couple other places in the C++ +// code that assume the LLControlGroup named "Global" is gSavedSettings. LLControlGroup gSavedSettings("Global"); // saved at end of session LLControlGroup gSavedPerAccountSettings("PerAccount"); // saved at end of session LLControlGroup gCrashSettings("CrashSettings"); // saved at end of session diff --git a/indra/newview/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp index dc004af923..372c247243 100755 --- a/indra/newview/llviewerkeyboard.cpp +++ b/indra/newview/llviewerkeyboard.cpp @@ -681,6 +681,7 @@ BOOL LLViewerKeyboard::handleKey(KEY translated_key, MASK translated_mask, BOOL if(mKeysSkippedByUI.find(translated_key) != mKeysSkippedByUI.end()) { mKeyHandledByUI[translated_key] = FALSE; + LL_INFOS("Keyboard Handling") << "Key wasn't handled by UI!" << LL_ENDL; } else { diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index c70efd9dfa..ce83221d2c 100755 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -264,11 +264,15 @@ bool friendship_offer_callback(const LLSD& notification, const LLSD& response) break; } - LLNotificationFormPtr modified_form(new LLNotificationForm(*notification_ptr->getForm())); - modified_form->setElementEnabled("Accept", false); - modified_form->setElementEnabled("Decline", false); - notification_ptr->updateForm(modified_form); - notification_ptr->repost(); + // TODO: this set of calls has undesirable behavior under Windows OS (CHUI-985): + // here appears three additional toasts instead one modified + // need investigation and fix + + // LLNotificationFormPtr modified_form(new LLNotificationForm(*notification_ptr->getForm())); + // modified_form->setElementEnabled("Accept", false); + // modified_form->setElementEnabled("Decline", false); + // notification_ptr->updateForm(modified_form); + // notification_ptr->repost(); } return false; @@ -2656,7 +2660,8 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) { send_do_not_disturb_message(msg, from_id); } - else + + if (!is_muted) { LL_INFOS("Messaging") << "Received IM_GROUP_INVITATION message." << LL_ENDL; // Read the binary bucket for more information. @@ -3680,6 +3685,7 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) LLSD msg_notify = LLSD(LLSD::emptyMap()); msg_notify["session_id"] = LLUUID(); msg_notify["from_id"] = chat.mFromID; + msg_notify["source_type"] = chat.mSourceType; on_new_message(msg_notify); } } @@ -5830,6 +5836,15 @@ bool attempt_standard_notification(LLMessageSystem* msgsystem) return true; } } + // HACK -- handle callbacks for specific alerts. + if( notificationID == "HomePositionSet" ) + { + // save the home location image to disk + std::string snap_filename = gDirUtilp->getLindenUserDir(); + snap_filename += gDirUtilp->getDirDelimiter(); + snap_filename += SCREEN_HOME_FILENAME; + gViewerWindow->saveSnapshot(snap_filename, gViewerWindow->getWindowWidthRaw(), gViewerWindow->getWindowHeightRaw(), FALSE, FALSE); + } LLNotificationsUtil::add(notificationID, llsdBlock); return true; @@ -5905,14 +5920,6 @@ void process_alert_core(const std::string& message, BOOL modal) { add(LLStatViewer::KILLED, 1); } - else if( message == "Home position set." ) - { - // save the home location image to disk - std::string snap_filename = gDirUtilp->getLindenUserDir(); - snap_filename += gDirUtilp->getDirDelimiter(); - snap_filename += SCREEN_HOME_FILENAME; - gViewerWindow->saveSnapshot(snap_filename, gViewerWindow->getWindowWidthRaw(), gViewerWindow->getWindowHeightRaw(), FALSE, FALSE); - } const std::string ALERT_PREFIX("ALERT: "); const std::string NOTIFY_PREFIX("NOTIFY: "); diff --git a/indra/newview/llviewernetwork.cpp b/indra/newview/llviewernetwork.cpp index 97f4c3e5fe..faa58d423f 100755 --- a/indra/newview/llviewernetwork.cpp +++ b/indra/newview/llviewernetwork.cpp @@ -43,6 +43,8 @@ const std::string GRID_LABEL_VALUE = "label"; const std::string GRID_ID_VALUE = "grid_login_id"; /// the url for the login cgi script const std::string GRID_LOGIN_URI_VALUE = "login_uri"; +/// url base for update queries +const std::string GRID_UPDATE_SERVICE_URL = "update_query_url_base"; /// const std::string GRID_HELPER_URI_VALUE = "helper_uri"; /// the splash page url @@ -63,6 +65,8 @@ const std::string DEFAULT_LOGIN_PAGE = "http://viewer-login.agni.lindenlab.com/" const std::string MAIN_GRID_LOGIN_URI = "https://login.agni.lindenlab.com/cgi-bin/login.cgi"; +const std::string SL_UPDATE_QUERY_URL = "https://update.secondlife.com/update"; + const std::string MAIN_GRID_SLURL_BASE = "http://maps.secondlife.com/secondlife/"; const std::string SYSTEM_GRID_APP_SLURL_BASE = "secondlife:///app"; @@ -120,12 +124,14 @@ void LLGridManager::initialize(const std::string& grid_file) MAIN_GRID_LOGIN_URI, "https://secondlife.com/helpers/", DEFAULT_LOGIN_PAGE, + SL_UPDATE_QUERY_URL, "Agni"); addSystemGrid("Second Life Beta Test Grid (Aditi)", "util.aditi.lindenlab.com", "https://login.aditi.lindenlab.com/cgi-bin/login.cgi", "http://aditi-secondlife.webdev.lindenlab.com/helpers/", DEFAULT_LOGIN_PAGE, + SL_UPDATE_QUERY_URL, "Aditi"); LLSD other_grids; @@ -332,6 +338,7 @@ void LLGridManager::addSystemGrid(const std::string& label, const std::string& login_uri, const std::string& helper, const std::string& login_page, + const std::string& update_url_base, const std::string& login_id) { LLSD grid = LLSD::emptyMap(); @@ -341,6 +348,7 @@ void LLGridManager::addSystemGrid(const std::string& label, grid[GRID_LOGIN_URI_VALUE] = LLSD::emptyArray(); grid[GRID_LOGIN_URI_VALUE].append(login_uri); grid[GRID_LOGIN_PAGE_VALUE] = login_page; + grid[GRID_UPDATE_SERVICE_URL] = update_url_base; grid[GRID_IS_SYSTEM_GRID_VALUE] = true; grid[GRID_LOGIN_IDENTIFIER_TYPES] = LLSD::emptyArray(); grid[GRID_LOGIN_IDENTIFIER_TYPES].append(CRED_IDENTIFIER_TYPE_AGENT); @@ -537,6 +545,30 @@ std::string LLGridManager::getGridLoginID() return mGridList[mGrid][GRID_ID_VALUE]; } +std::string LLGridManager::getUpdateServiceURL() +{ + std::string update_url_base = gSavedSettings.getString("CmdLineUpdateService");; + if ( !update_url_base.empty() ) + { + LL_INFOS("UpdaterService","GridManager") + << "Update URL base overridden from command line: " << update_url_base + << LL_ENDL; + } + else if ( mGridList[mGrid].has(GRID_UPDATE_SERVICE_URL) ) + { + update_url_base = mGridList[mGrid][GRID_UPDATE_SERVICE_URL].asString(); + } + else + { + LL_WARNS("UpdaterService","GridManager") + << "The grid property '" << GRID_UPDATE_SERVICE_URL + << "' is not defined for the grid '" << mGrid << "'" + << LL_ENDL; + } + + return update_url_base; +} + void LLGridManager::updateIsInProductionGrid() { mIsInProductionGrid = false; diff --git a/indra/newview/llviewernetwork.h b/indra/newview/llviewernetwork.h index 3f56103b2e..8526c0ba7f 100755 --- a/indra/newview/llviewernetwork.h +++ b/indra/newview/llviewernetwork.h @@ -140,6 +140,14 @@ class LLGridManager : public LLSingleton<LLGridManager> */ //@} + /* ================================================================ + * @name Update Related Properties + * @{ + */ + /// Get the update service URL base (host and path) for the selected grid + std::string getUpdateServiceURL(); + + //@} /* ================================================================ * @name URL Construction Properties @@ -207,6 +215,7 @@ class LLGridManager : public LLSingleton<LLGridManager> const std::string& login, const std::string& helper, const std::string& login_page, + const std::string& update_url_base, const std::string& login_id = ""); diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 4958c38c4e..e2bc11ea1c 100755 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -1246,7 +1246,7 @@ S32Megabytes LLViewerTextureList::getMinVideoRamSetting() //static // Returns max setting for TextureMemory (in MB) -S32Megabytes LLViewerTextureList::getMaxVideoRamSetting(bool get_recommended) +S32Megabytes LLViewerTextureList::getMaxVideoRamSetting(bool get_recommended, float mem_multiplier) { S32Megabytes max_texmem; if (gGLManager.mVRAM != 0) @@ -1290,7 +1290,10 @@ S32Megabytes LLViewerTextureList::getMaxVideoRamSetting(bool get_recommended) max_texmem = llmin(max_texmem, system_ram/2); else max_texmem = llmin(max_texmem, system_ram); - + + // limit the texture memory to a multiple of the default if we've found some cards to behave poorly otherwise + max_texmem = llmin(max_texmem, (S32Megabytes) (mem_multiplier * max_texmem)); + max_texmem = llclamp(max_texmem, getMinVideoRamSetting(), gMaxVideoRam); return max_texmem; @@ -1303,7 +1306,7 @@ void LLViewerTextureList::updateMaxResidentTexMem(S32Megabytes mem) // Initialize the image pipeline VRAM settings S32Megabytes cur_mem(gSavedSettings.getS32("TextureMemory")); F32 mem_multiplier = gSavedSettings.getF32("RenderTextureMemoryMultiple"); - S32Megabytes default_mem(getMaxVideoRamSetting(true)); // recommended default + S32Megabytes default_mem = getMaxVideoRamSetting(true, mem_multiplier); // recommended default if (mem == (S32Bytes)0) { mem = cur_mem > (S32Bytes)0 ? cur_mem : default_mem; @@ -1313,10 +1316,7 @@ void LLViewerTextureList::updateMaxResidentTexMem(S32Megabytes mem) mem = default_mem; } - // limit the texture memory to a multiple of the default if we've found some cards to behave poorly otherwise - mem = llmin(mem, S32Megabytes(mem_multiplier * (F32Megabytes)default_mem)); - - mem = llclamp(mem, getMinVideoRamSetting(), getMaxVideoRamSetting()); + mem = llclamp(mem, getMinVideoRamSetting(), getMaxVideoRamSetting(false, mem_multiplier)); if (mem != cur_mem) { gSavedSettings.setS32("TextureMemory", mem.value()); diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h index 835d750d94..9dd3a9ee8b 100755 --- a/indra/newview/llviewertexturelist.h +++ b/indra/newview/llviewertexturelist.h @@ -113,7 +113,7 @@ public: void setDebugFetching(LLViewerFetchedTexture* tex, S32 debug_level); static S32Megabytes getMinVideoRamSetting(); - static S32Megabytes getMaxVideoRamSetting(bool get_recommended = false); + static S32Megabytes getMaxVideoRamSetting(bool get_recommended, float mem_multiplier); private: void updateImagesDecodePriorities(); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index ee4972e13b..34b0f450ab 100755 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1813,7 +1813,6 @@ void LLViewerWindow::initBase() gFloaterView = main_view->getChild<LLFloaterView>("Floater View"); gFloaterView->setFloaterSnapView(main_view->getChild<LLView>("floater_snap_region")->getHandle()); gSnapshotFloaterView = main_view->getChild<LLSnapshotFloaterView>("Snapshot Floater View"); - // Console llassert( !gConsole ); diff --git a/indra/newview/macutil_Prefix.h b/indra/newview/macutil_Prefix.h index b54a764a62..b8df961cac 100755 --- a/indra/newview/macutil_Prefix.h +++ b/indra/newview/macutil_Prefix.h @@ -32,7 +32,6 @@ * */ -#include <Carbon/Carbon.h> #include "fix_macros.h" #undef verify diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml index a9176595c7..f53995732f 100755 --- a/indra/newview/skins/default/colors.xml +++ b/indra/newview/skins/default/colors.xml @@ -884,4 +884,19 @@ <color name="blue" value="0 0 1 1"/> + + <!--Resize bar colors --> + + <color + name="ResizebarBorderLight" + value="0.231 0.231 0.231 1"/> + + <color + name="ResizebarBorderDark" + value="0.133 0.133 0.133 1"/> + + <color + name="ResizebarBody" + value="0.208 0.208 0.208 1"/> + </colors> diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index b0e4b71d21..54f60f4441 100755 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -774,4 +774,7 @@ with the same filename but different name <texture name="Popup_Caution" file_name="icons/pop_up_caution.png"/> <texture name="Camera_Drag_Dot" file_name="world/CameraDragDot.png"/> <texture name="NavBar Separator" file_name="navbar/separator.png"/> + + <texture name="Horizontal Drag Handle" file_name="widgets/horizontal_drag_handle.png"/> + <texture name="Vertical Drag Handle" file_name="widgets/vertical_drag_handle.png"/> </textures> diff --git a/indra/newview/skins/default/textures/widgets/horizontal_drag_handle.png b/indra/newview/skins/default/textures/widgets/horizontal_drag_handle.png Binary files differnew file mode 100644 index 0000000000..642eac4065 --- /dev/null +++ b/indra/newview/skins/default/textures/widgets/horizontal_drag_handle.png diff --git a/indra/newview/skins/default/textures/widgets/vertical_drag_handle.png b/indra/newview/skins/default/textures/widgets/vertical_drag_handle.png Binary files differnew file mode 100644 index 0000000000..b06b70cf36 --- /dev/null +++ b/indra/newview/skins/default/textures/widgets/vertical_drag_handle.png diff --git a/indra/newview/skins/default/xui/da/floater_about.xml b/indra/newview/skins/default/xui/da/floater_about.xml index fc8bc33096..9206690c8f 100755 --- a/indra/newview/skins/default/xui/da/floater_about.xml +++ b/indra/newview/skins/default/xui/da/floater_about.xml @@ -8,7 +8,7 @@ Bygget med [COMPILER] version [COMPILER_VERSION] </floater.string> <floater.string name="AboutPosition"> - Du er ved [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] i regionen [REGION] lokaliseret ved <nolink>[HOSTNAME]</nolink> ([HOSTIP]) + Du er ved [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] i regionen [REGION] lokaliseret ved <nolink>[HOSTNAME]</nolink> ([HOSTIP]) [SERVER_VERSION] [SERVER_RELEASE_NOTES_URL] </floater.string> diff --git a/indra/newview/skins/default/xui/de/floater_about.xml b/indra/newview/skins/default/xui/de/floater_about.xml index 4387a61963..5245467183 100755 --- a/indra/newview/skins/default/xui/de/floater_about.xml +++ b/indra/newview/skins/default/xui/de/floater_about.xml @@ -8,7 +8,7 @@ Kompiliert mit [COMPILER] version [COMPILER_VERSION] </floater.string> <floater.string name="AboutPosition"> - Sie befinden sich in [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] in [REGION] auf <nolink>[HOSTNAME]</nolink> ([HOSTIP]) + Sie befinden sich in [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] in [REGION] auf <nolink>[HOSTNAME]</nolink> ([HOSTIP]) [SERVER_VERSION] [SERVER_RELEASE_NOTES_URL] </floater.string> diff --git a/indra/newview/skins/default/xui/en/floater_about.xml b/indra/newview/skins/default/xui/en/floater_about.xml index 63eb87f27a..703015af20 100755 --- a/indra/newview/skins/default/xui/en/floater_about.xml +++ b/indra/newview/skins/default/xui/en/floater_about.xml @@ -22,7 +22,9 @@ Built with [COMPILER] version [COMPILER_VERSION] </floater.string> <floater.string name="AboutPosition"> -You are at [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] in [REGION] located at <nolink>[HOSTNAME]</nolink> ([HOSTIP]) +You are at [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] in [REGION] located at <nolink>[HOSTNAME]</nolink> ([HOSTIP]) +SLURL: <nolink>[SLURL]</nolink> +(global coordinates [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1]) [SERVER_VERSION] [SERVER_RELEASE_NOTES_URL] 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 4e0cfb0cd4..e7ab3cacdc 100755 --- a/indra/newview/skins/default/xui/en/floater_bulk_perms.xml +++ b/indra/newview/skins/default/xui/en/floater_bulk_perms.xml @@ -6,7 +6,7 @@ layout="topleft" name="floaterbulkperms" help_topic="floaterbulkperms" - title="EDIT CONTENT PERMISSIONS" + title="ADJUST CONTENT PERMISSIONS" width="410"> <floater.string name="nothing_to_modify_text"> @@ -192,7 +192,7 @@ name="newperms" top="90" width="250"> - New Content Permissions + Adjust Content Permissions To </text> <text type="string" @@ -292,11 +292,22 @@ height="23" label="OK" layout="topleft" - left="205" - name="apply" + left="110" + name="ok" top_pad="10" width="90"> <button.commit_callback + function="BulkPermission.Ok"/> + </button> + <button + follows="left|top" + height="23" + label="Apply" + layout="topleft" + left_pad="5" + name="apply" + width="90"> + <button.commit_callback function="BulkPermission.Apply"/> </button> <button diff --git a/indra/newview/skins/default/xui/en/floater_goto_line.xml b/indra/newview/skins/default/xui/en/floater_goto_line.xml new file mode 100644 index 0000000000..b236888219 --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_goto_line.xml @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + legacy_header_height="18" + default_tab_group="1" + height="90" + layout="topleft" + name="script goto" + help_topic="script_goto" + title="GO TO LINE" + width="200"> + <button + height="24" + label="OK" + label_selected="OK" + layout="topleft" + left="55" + name="goto_btn" + top="53" + width="90" /> + <text + type="string" + length="1" + follows="left|top" + height="16" + layout="topleft" + left="10" + name="txt" + top="21" + width="65"> + Go to line + </text> + <line_editor + border_style="line" + border_thickness="1" + follows="left|top" + height="16" + layout="topleft" + left="75" + max_length_bytes="9" + name="goto_line" + tab_group="1" + top="21" + width="85" /> +</floater>
\ No newline at end of file diff --git a/indra/newview/skins/default/xui/en/floater_im_container.xml b/indra/newview/skins/default/xui/en/floater_im_container.xml index 65f623a47e..1215efb7f9 100755 --- a/indra/newview/skins/default/xui/en/floater_im_container.xml +++ b/indra/newview/skins/default/xui/en/floater_im_container.xml @@ -4,6 +4,7 @@ can_minimize="true" can_resize="true" height="210" + min_height="210" layout="topleft" name="floater_im_box" help_topic="floater_im_box" @@ -24,24 +25,28 @@ value="Conv_toolbar_expand"/> <layout_stack animate="true" - bottom="-1" + bottom="-5" + drag_handle_gap="6" + drag_handle_first_indent="27" + drag_handle_second_indent="10" follows="all" layout="topleft" left="0" name="conversations_stack" orientation="horizontal" right="-1" + show_drag_handle="true" top="0"> <layout_panel auto_resize="false" user_resize="true" name="conversations_layout_panel" min_dim="38" - expanded_min_dim="156"> + expanded_min_dim="136"> <layout_stack animate="false" follows="left|top|right" - height="35" + height="27" layout="topleft" left="0" name="conversations_pane_buttons_stack" @@ -50,7 +55,6 @@ top="0"> <layout_panel auto_resize="true" - height="35" name="conversations_pane_buttons_expanded"> <menu_button follows="top|left" @@ -64,7 +68,7 @@ left="5" name="sort_btn" tool_tip="View/sort options" - top="5" + top="1" width="31" /> <button follows="top|left" @@ -74,7 +78,7 @@ image_selected="Toolbar_Middle_Selected" image_unselected="Toolbar_Middle_Off" layout="topleft" - top="5" + top="1" left_pad="2" name="add_btn" tool_tip="Start a new conversation" @@ -87,7 +91,7 @@ image_selected="Toolbar_Middle_Selected" image_unselected="Toolbar_Middle_Off" layout="topleft" - top="5" + top="1" left_pad="2" name="speak_btn" tool_tip="Speak with people using your microphone" @@ -95,9 +99,8 @@ </layout_panel> <layout_panel auto_resize="false" - height="35" name="conversations_pane_buttons_collapsed" - width="41"> + width="31"> <button follows="right|top" height="25" @@ -106,8 +109,8 @@ image_selected="Toolbar_Middle_Selected" image_unselected="Toolbar_Middle_Off" layout="topleft" - top="5" - left="1" + top="1" + left="0" name="expand_collapse_btn" tool_tip="Collapse/Expand this list" width="31" /> @@ -119,7 +122,7 @@ layout="topleft" name="conversations_list_panel" opaque="true" - top="35" + top_pad="0" left="5" right="-1"/> </layout_panel> @@ -127,7 +130,7 @@ auto_resize="true" user_resize="true" name="messages_layout_panel" - expanded_min_dim="222"> + expanded_min_dim="212"> <panel_container bottom="-1" follows="all" @@ -136,44 +139,44 @@ name="im_box_tab_container" right="-1" top="0"> - <panel - bottom="-1" - follows="all" - layout="topleft" - name="stub_panel" - opaque="true" - top_pad="0" - left="0" - right="-1"> - <button - follows="right|top" - height="25" - image_hover_unselected="Toolbar_Middle_Over" - image_overlay="Conv_toolbar_collapse" - image_selected="Toolbar_Middle_Selected" - image_unselected="Toolbar_Middle_Off" + <panel + bottom="-1" + follows="all" layout="topleft" - top="5" - right="-10" - name="stub_collapse_btn" - tool_tip="Collapse this pane" - width="31" /> - <text - type="string" - clip_partial="false" - follows="left|top|right" - layout="topleft" - left="15" - right="-15" - name="stub_textbox" - top="25" - height="40" - valign="center" - parse_urls="true" - wrap="true"> - This conversation is in a separate window. [secondlife:/// Bring it back.] - </text> - </panel> + name="stub_panel" + opaque="true" + top_pad="0" + left="0" + right="-1"> + <button + follows="right|top" + height="25" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="Conv_toolbar_collapse" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + layout="topleft" + top="1" + right="-10" + name="stub_collapse_btn" + tool_tip="Collapse this pane" + width="31" /> + <text + type="string" + clip_partial="false" + follows="left|top|right" + layout="topleft" + left="15" + right="-15" + name="stub_textbox" + top="25" + height="40" + valign="center" + parse_urls="true" + wrap="true"> + This conversation is in a separate window. [secondlife:/// Bring it back.] + </text> + </panel> </panel_container> </layout_panel> </layout_stack> diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml index 2152a9f6e9..43d0f2fb18 100755 --- a/indra/newview/skins/default/xui/en/floater_im_session.xml +++ b/indra/newview/skins/default/xui/en/floater_im_session.xml @@ -70,26 +70,23 @@ top="0" left="0" right="-1" - bottom="-3"> + bottom="-1"> <layout_stack animate="false" + bottom="-1" default_tab_group="2" follows="all" - right="-5" - bottom="-1" - top="0" - left="5" - border_size="0" + left="3" layout="topleft" - orientation="vertical" name="main_stack" - tab_group="1"> + right="-3" + orientation="vertical" + tab_group="1" + top="0"> <layout_panel auto_resize="false" name="toolbar_panel" - height="35" - right="-1" - left="1"> + height="25"> <menu_button menu_filename="menu_im_session_showmodes.xml" follows="top|left" @@ -102,7 +99,7 @@ left="5" name="view_options_btn" tool_tip="View/sort options" - top="5" + top="1" width="31" /> <menu_button menu_filename="menu_im_conversation.xml" @@ -113,7 +110,7 @@ image_selected="Toolbar_Middle_Selected" image_unselected="Toolbar_Middle_Off" layout="topleft" - top="5" + top="1" left_pad="2" name="gear_btn" visible="false" @@ -128,7 +125,7 @@ image_selected="Toolbar_Middle_Selected" image_unselected="Toolbar_Middle_Off" layout="topleft" - top="5" + top="1" left_pad="2" name="add_btn" tool_tip="Add someone to this conversation" @@ -141,23 +138,11 @@ image_selected="Toolbar_Middle_Selected" image_unselected="Toolbar_Middle_Off" layout="topleft" - top="5" + top="1" left_pad="2" name="voice_call_btn" tool_tip="Open voice connection" - width="31"/> - <output_monitor - auto_update="true" - follows="top|left" - draw_border="false" - height="16" - layout="topleft" - top="10" - left_pad="10" - mouse_opaque="true" - name="speaking_indicator" - visible="false" - width="20" /> + width="31"/> <button follows="right|top" height="25" @@ -166,8 +151,8 @@ image_selected="Toolbar_Middle_Selected" image_unselected="Toolbar_Middle_Off" layout="topleft" - top="5" - right="-67" + top="1" + right="-70" name="close_btn" tool_tip="End this conversation" width="31" /> @@ -179,7 +164,7 @@ image_selected="Toolbar_Middle_Selected" image_unselected="Toolbar_Middle_Off" layout="topleft" - top="5" + top="1" left_pad="2" name="expand_collapse_btn" tool_tip="Collapse/Expand this pane" @@ -194,18 +179,21 @@ layout="topleft" left_pad="2" name="tear_off_btn" - top="5" + top="1" width="31" /> </layout_panel> <layout_panel name="body_panel" - top="1" - bottom="-1"> + height="235"> <layout_stack default_tab_group="2" + drag_handle_gap="6" + drag_handle_first_indent="0" + drag_handle_second_indent="1" follows="all" orientation="horizontal" name="im_panels" + show_drag_handle="true" tab_group="1" top="0" right="-1" @@ -217,14 +205,12 @@ min_dim="0" width="150" user_resize="true" - auto_resize="false" - bottom="-1" /> + auto_resize="false" /> <layout_panel default_tab_group="3" tab_group="2" name="right_part_holder" - min_width="221" - bottom="-1"> + min_width="172"> <layout_stack animate="true" default_tab_group="2" @@ -233,7 +219,7 @@ name="translate_and_chat_stack" tab_group="1" top="0" - left="0" + left="1" right="-1" bottom="-1"> <layout_panel @@ -259,7 +245,7 @@ parse_highlights="true" parse_urls="true" right="-1" - left="5" + left="0" top="0" bottom="-1" /> </layout_panel> @@ -268,10 +254,7 @@ </layout_stack> </layout_panel> <layout_panel - top_delta="0" - top="0" - height="26" - bottom="-1" + height="35" auto_resize="false" name="chat_layout_panel"> <layout_stack @@ -281,15 +264,11 @@ orientation="horizontal" name="input_panels" top="0" - bottom="-2" + bottom="-1" left="0" right="-1"> <layout_panel - name="input_editor_layout_panel" - auto_resize="true" - user_resize="false" - top="0" - bottom="-1"> + name="input_editor_layout_panel"> <chat_editor layout="topleft" expand_lines_count="5" @@ -302,32 +281,27 @@ max_length="1023" spellcheck="true" tab_group="3" - top="1" - bottom="-2" - left="4" - right="-4" + bottom="-8" + left="5" + right="-5" wrap="true" /> </layout_panel> <layout_panel auto_resize="false" - user_resize="false" name="input_button_layout_panel" - width="30" - top="0" - bottom="-1"> + width="32"> <button - layout="topleft" left="1" - right="-1" - top="1" - height="22" + top="4" + height="25" follows="left|right|top" image_hover_unselected="Toolbar_Middle_Over" image_overlay="Conv_expand_one_line" image_selected="Toolbar_Middle_Selected" image_unselected="Toolbar_Middle_Off" name="minz_btn" - tool_tip="Shows/hides message panel" /> + tool_tip="Shows/hides message panel" + width="28" /> </layout_panel> </layout_stack> </layout_panel> diff --git a/indra/newview/skins/default/xui/en/menu_conversation.xml b/indra/newview/skins/default/xui/en/menu_conversation.xml index 5a13ef0a59..b3d28788da 100755 --- a/indra/newview/skins/default/xui/en/menu_conversation.xml +++ b/indra/newview/skins/default/xui/en/menu_conversation.xml @@ -11,7 +11,7 @@ layout="topleft" name="close_conversation"> <on_click function="Avatar.DoToSelected" parameter="close_conversation"/> - </menu_item_call> + </menu_item_call> <menu_item_call label="Open voice conversation" layout="topleft" @@ -25,6 +25,12 @@ <on_click function="Avatar.DoToSelected" parameter="disconnect_from_voice"/> </menu_item_call> <menu_item_separator layout="topleft" name="separator_disconnect_from_voice"/> + <menu_item_call + label="Close Selected" + layout="topleft" + name="close_selected_conversations"> + <on_click function="Avatar.DoToSelected" parameter="close_selected_conversations"/> + </menu_item_call> <menu_item_call label="View Profile" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/menu_people_friends_view.xml b/indra/newview/skins/default/xui/en/menu_people_friends_view.xml index dde9432867..8790fde7c5 100755 --- a/indra/newview/skins/default/xui/en/menu_people_friends_view.xml +++ b/indra/newview/skins/default/xui/en/menu_people_friends_view.xml @@ -44,6 +44,8 @@ <menu_item_check.on_check function="Floater.Visible" parameter="conversation" /> + <menu_item_check.on_enable + function="Conversation.IsConversationLoggingAllowed" /> <menu_item_check.on_click function="Floater.Toggle" parameter="conversation" /> diff --git a/indra/newview/skins/default/xui/en/menu_url_agent.xml b/indra/newview/skins/default/xui/en/menu_url_agent.xml index 7cd56f257a..e8b6116026 100755 --- a/indra/newview/skins/default/xui/en/menu_url_agent.xml +++ b/indra/newview/skins/default/xui/en/menu_url_agent.xml @@ -21,8 +21,15 @@ layout="topleft" name="add_friend"> <menu_item_call.on_click - function="Url.AddFriend" /> + function="Url.AddFriend" /> </menu_item_call> + <menu_item_call + label="Remove Friend..." + layout="topleft" + name="remove_friend"> + <menu_item_call.on_click + function="Url.RemoveFriend" /> + </menu_item_call> <menu_item_separator layout="topleft" /> <menu_item_call diff --git a/indra/newview/skins/default/xui/en/menu_url_objectim.xml b/indra/newview/skins/default/xui/en/menu_url_objectim.xml index 87ab58e622..b9d003b841 100755 --- a/indra/newview/skins/default/xui/en/menu_url_objectim.xml +++ b/indra/newview/skins/default/xui/en/menu_url_objectim.xml @@ -9,6 +9,13 @@ <menu_item_call.on_click function="Url.Execute" /> </menu_item_call> + <menu_item_call + label="Block..." + layout="topleft" + name="block_object"> + <menu_item_call.on_click + function="Url.Block" /> + </menu_item_call> <menu_item_separator layout="topleft" /> <menu_item_call diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index f4a9e69bf9..11995161d2 100755 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -874,6 +874,15 @@ function="Tools.EnableSelectNextPart" /> </menu_item_call> </menu> + <menu_item_call + label="Linksets..." + name="pathfinding_linkset_menu_item"> + <menu_item_call.on_click + function="Floater.ToggleOrBringToFront" + parameter="pathfinding_linksets" /> + <menu_item_call.on_enable + function="Tools.EnablePathfinding" /> + </menu_item_call> <menu_item_separator/> <menu_item_call @@ -896,7 +905,7 @@ <menu_item_call.on_enable function="Tools.SomethingSelectedNoHUD" /> </menu_item_call> - + <menu_item_separator/> <menu diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index a4e01ff1c9..0e08f89640 100755 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -506,6 +506,33 @@ Add this Ability to '[ROLE_NAME]'? notext="No" yestext="Yes"/> </notification> + + <notification + icon="alertmodal.tga" + name="EjectGroupMemberWarning" + type="alertmodal"> + You are about to eject [AVATAR_NAME] from the group. + <tag>group</tag> + <tag>confirm</tag> + <usetemplate + ignoretext="Confirm ejecting a participant from group" + name="okcancelignore" + notext="Cancel" + yestext="Eject"/> + </notification> + <notification + icon="alertmodal.tga" + name="EjectGroupMembersWarning" + type="alertmodal"> + You are about to eject [COUNT] members from the group. + <tag>group</tag> + <tag>confirm</tag> + <usetemplate + ignoretext="Confirm ejecting multiple members from group" + name="okcancelignore" + notext="Cancel" + yestext="Eject"/> + </notification> <notification icon="alertmodal.tga" @@ -2682,7 +2709,7 @@ Please enter a higher price. icon="alertmodal.tga" name="ConfirmItemDeleteHasLinks" type="alertmodal"> -At least one of the items you has link items that point to it. If you delete this item, its links will permanently stop working. It is strongly advised to delete the links first. +At least one of the items has links that point to it. If you delete this item, its links will permanently stop working. It is strongly advised to delete the links first. Are you sure you want to delete these items? <tag>confirm</tag> @@ -2724,7 +2751,7 @@ Are you sure you want to delete these items? icon="alertmodal.tga" name="ConfirmObjectDeleteNoOwn" type="alertmodal"> -You do not own least one of the items you have selected. +You do not own at least one of the items you have selected. Are you sure you want to delete these items? <tag>confirm</tag> @@ -2754,7 +2781,7 @@ Are you sure you want to delete these items? name="ConfirmObjectDeleteLockNoOwn" type="alertmodal"> At least one object is locked. -You do not own least one object. +You do not own at least one object. Are you sure you want to delete these items? <tag>confirm</tag> @@ -2769,7 +2796,7 @@ Are you sure you want to delete these items? name="ConfirmObjectDeleteNoCopyNoOwn" type="alertmodal"> At least one object is not copyable. -You do not own least one object. +You do not own at least one object. Are you sure you want to delete these items? <tag>confirm</tag> @@ -2785,13 +2812,13 @@ Are you sure you want to delete these items? type="alertmodal"> At least one object is locked. At least one object is not copyable. -You do not own least one object. +You do not own at least one object. Are you sure you want to delete these items? <tag>confirm</tag> <usetemplate name="okcancelbuttons" - notext="cancel" + notext="Cancel" yestext="OK"/> </notification> @@ -3709,6 +3736,17 @@ Leave Group? </notification> <notification + icon="alertmodal.tga" + name="OwnerCannotLeaveGroup" + type="alertmodal"> + Unable to leave group. You cannot leave the group because you are the last owner of the group. Please assign another member to the owner role first. + <tag>group</tag> + <usetemplate + name="okbutton" + yestext="OK"/> + </notification> + + <notification icon="alert.tga" name="ConfirmKick" type="alert"> @@ -5943,9 +5981,7 @@ Your calling card was declined. icon="notifytip.tga" name="TeleportToPerson" type="notifytip"> - To contact Residents like '[NAME]', click on the "People" button , select a Resident from the window that opens, then click 'IM' at the - bottom of the window. - (You can also double-click on their name in the list, or right-click and choose 'IM'). + To open a private conversation with someone, right-click on their avatar and choose 'IM' from the menu. </notification> <notification @@ -6573,7 +6609,7 @@ Your object named <nolink>[OBJECTFROMNAME]</nolink> has given you th icon="notify.tga" name="JoinGroup" persist="true" - type="notify"> + type="offer"> <tag>group</tag> [MESSAGE] <form name="form"> diff --git a/indra/newview/skins/default/xui/en/panel_group_notices.xml b/indra/newview/skins/default/xui/en/panel_group_notices.xml index 6d5fb51e85..c8ce5cdebf 100755 --- a/indra/newview/skins/default/xui/en/panel_group_notices.xml +++ b/indra/newview/skins/default/xui/en/panel_group_notices.xml @@ -202,14 +202,14 @@ Maximum 200 per group daily Drag and drop item here to attach it: </text> <icon - height="72" + height="48" image_name="DropTarget" layout="topleft" left_pad="10" mouse_opaque="true" name="drop_icon" top_delta="-10" - width="72" /> + width="110" /> <button follows="left|top" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml index 7ce2627be9..ed274d0233 100755 --- a/indra/newview/skins/default/xui/en/panel_people.xml +++ b/indra/newview/skins/default/xui/en/panel_people.xml @@ -480,10 +480,22 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M function="People.Group.Minus" /> </dnd_button> </panel> + <text + type="string" + length="1" + follows="all" + height="14" + layout="topleft" + right="-10" + top_pad="4" + left="3" + name="groupcount"> + You belong to [COUNT] groups, and can join [REMAINING] more. + </text> <group_list allow_select="true" follows="all" - height="406" + height="388" layout="topleft" left="3" name="group_list" diff --git a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml index 2cc9d9c1b0..50fd57494f 100755 --- a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml @@ -138,7 +138,7 @@ initial_value="1" layout="topleft" left_pad="0" - max_val="1.4" + max_val="1.5" min_val="0.75" name="ui_scale_slider" top_pad="-14" diff --git a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml index bd096ebb88..8e867259c5 100755 --- a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml @@ -14,6 +14,7 @@ border="false" height="60" layout="topleft" + name="general_chat_settings" top="10" left="13" width="517"> @@ -97,20 +98,13 @@ border="false" height="165" layout="topleft" + name="im_notification_settings" left="13" width="517"> <text layout="topleft" height="12" - name="notifications" - left="0" - width="120"> - Notifications - </text> - <text - layout="topleft" - height="12" name="friend_ims" width="145" left="0" @@ -138,17 +132,27 @@ name="FlashToolbarButton" value="flash"/> <item - label="None" - name="None" - value="none"/> + label="No action" + name="NoAction" + value="noaction"/> </combo_box> + <check_box + control_name="PlaySoundFriendIM" + height="23" + label="Play sound" + layout="topleft" + name="play_sound_friend_im" + left_pad="7" + top_delta="-3" + width="28"> + </check_box> <text layout="topleft" height="12" name="non_friend_ims" width="145" left="0" - top_pad="9"> + top_pad="11"> Non-friend IMs: </text> <combo_box @@ -172,17 +176,27 @@ name="FlashToolbarButton" value="flash"/> <item - label="None" - name="None" - value="none"/> + label="No action" + name="NoAction" + value="noaction"/> </combo_box> + <check_box + control_name="PlaySoundNonFriendIM" + height="23" + label="Play sound" + layout="topleft" + name="play_sound_non_friend_im" + left_pad="7" + top_delta="-3" + width="28"> + </check_box> <text layout="topleft" left="0" height="13" name="conference_ims" width="145" - top_pad="9"> + top_pad="11"> Conference IMs: </text> <combo_box @@ -206,17 +220,27 @@ name="FlashToolbarButton" value="flash"/> <item - label="None" - name="None" - value="none"/> + label="No action" + name="NoAction" + value="noaction"/> </combo_box> + <check_box + control_name="PlaySoundConferenceIM" + height="23" + label="Play sound" + layout="topleft" + name="play_sound_conference_im" + left_pad="7" + top_delta="-3" + width="28"> + </check_box> <text layout="topleft" left="0" height="13" name="group_chat" width="145" - top_pad="9"> + top_pad="11"> Group chat: </text> <combo_box @@ -240,17 +264,27 @@ name="FlashToolbarButton" value="flash"/> <item - label="None" - name="None" - value="none"/> + label="No action" + name="NoAction" + value="noaction"/> </combo_box> + <check_box + control_name="PlaySoundGroupChatIM" + height="23" + label="Play sound" + layout="topleft" + name="play_sound_group_chat_im" + left_pad="7" + top_delta="-3" + width="28"> + </check_box> <text layout="topleft" left="0" height="12" name="nearby_chat" width="145" - top_pad="9"> + top_pad="11"> Nearby chat: </text> <combo_box @@ -274,10 +308,64 @@ name="FlashToolBarButton" value="flash"/> <item - label="None" - name="None" - value="none"/> + label="No action" + name="NoAction" + value="noaction"/> </combo_box> + <check_box + control_name="PlaySoundNearbyChatIM" + height="23" + label="Play sound" + layout="topleft" + name="play_sound_nearby_chat_im" + left_pad="7" + top_delta="-3" + width="28"> + </check_box> + <text + layout="topleft" + left="0" + height="12" + name="object_ims" + width="145" + top_pad="11"> + Object IMs: + </text> + <combo_box + control_name="NotificationObjectIMOptions" + height="23" + layout="topleft" + left_pad="5" + top_delta="-6" + name="ObjectIMOptions" + width="223"> + <item + label="Open Conversations window" + name="OpenConversationsWindow" + value="openconversations"/> + <item + label="Pop up the message" + name="PopUpMessage" + value="toast"/> + <item + label="Flash toolbar button" + name="FlashToolBarButton" + value="flash"/> + <item + label="No action" + name="NoAction" + value="noaction"/> + </combo_box> + <check_box + control_name="PlaySoundObjectIM" + height="23" + label="Play sound" + layout="topleft" + name="play_sound_object_im" + left_pad="7" + top_delta="-3" + width="28"> + </check_box> <text layout="topleft" left="0" @@ -296,6 +384,7 @@ border="false" height="50" layout="topleft" + name="play_sound_settings" left="13" top_pad="10" width="517"> @@ -358,6 +447,7 @@ <panel height="50" layout="topleft" + name="log_settings" left="13" top_pad="10" width="505"> diff --git a/indra/newview/skins/default/xui/en/panel_script_ed.xml b/indra/newview/skins/default/xui/en/panel_script_ed.xml index 765b07ed8b..bcdef96138 100755 --- a/indra/newview/skins/default/xui/en/panel_script_ed.xml +++ b/indra/newview/skins/default/xui/en/panel_script_ed.xml @@ -125,6 +125,10 @@ label="Search / Replace..." layout="topleft" name="Search / Replace..." /> + <menu_item_call + label="Go to line..." + layout="topleft" + name="Go to line..." /> </menu> <menu top="0" diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index dd7df368c7..6e4b46faaf 100755 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -209,7 +209,8 @@ Please try logging in again in a minute.</string> <string name="SLappAgentIM">IM</string> <string name="SLappAgentPay">Pay</string> <string name="SLappAgentOfferTeleport">Offer Teleport to </string> - <string name="SLappAgentRequestFriend">Friend Request </string> + <string name="SLappAgentRequestFriend">Friend Request</string> + <string name="SLappAgentRemoveFriend">Friend Removal</string> <!-- ButtonToolTips, llfloater.cpp --> <string name="BUTTON_CLOSE_DARWIN">Close (⌘W)</string> @@ -3930,5 +3931,8 @@ Try enclosing path to the editor with double quotes. <string name="logging_calls_enabled_log_empty"> There are no logged conversations. After you contact someone, or someone contacts you, a log entry will be shown here. </string> + <string name="loading_chat_logs"> + Loading... + </string> </strings> diff --git a/indra/newview/skins/default/xui/es/floater_about.xml b/indra/newview/skins/default/xui/es/floater_about.xml index 3696c7e12c..7ca1e3721f 100755 --- a/indra/newview/skins/default/xui/es/floater_about.xml +++ b/indra/newview/skins/default/xui/es/floater_about.xml @@ -8,7 +8,7 @@ Compilado con [COMPILER], versión [COMPILER_VERSION] </floater.string> <floater.string name="AboutPosition"> - Estás en la posición [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1], de [REGION], alojada en <nolink>[HOSTNAME]</nolink> ([HOSTIP]) + Estás en la posición [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1], de [REGION], alojada en <nolink>[HOSTNAME]</nolink> ([HOSTIP]) [SERVER_VERSION] [SERVER_RELEASE_NOTES_URL] </floater.string> diff --git a/indra/newview/skins/default/xui/fr/floater_about.xml b/indra/newview/skins/default/xui/fr/floater_about.xml index a659cb4245..d45bdccf3e 100755 --- a/indra/newview/skins/default/xui/fr/floater_about.xml +++ b/indra/newview/skins/default/xui/fr/floater_about.xml @@ -8,7 +8,7 @@ Compilé avec [COMPILER] version [COMPILER_VERSION] </floater.string> <floater.string name="AboutPosition"> - Vous êtes à [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] dans [REGION], se trouvant à <nolink>[HOSTNAME]</nolink> ([HOSTIP]) + Vous êtes à [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] dans [REGION], se trouvant à <nolink>[HOSTNAME]</nolink> ([HOSTIP]) [SERVER_VERSION] [SERVER_RELEASE_NOTES_URL] </floater.string> diff --git a/indra/newview/skins/default/xui/it/floater_about.xml b/indra/newview/skins/default/xui/it/floater_about.xml index c672511fc5..b0fb585fa2 100755 --- a/indra/newview/skins/default/xui/it/floater_about.xml +++ b/indra/newview/skins/default/xui/it/floater_about.xml @@ -8,7 +8,7 @@ Generato con [COMPILER] versione [COMPILER_VERSION] </floater.string> <floater.string name="AboutPosition"> - Tu sei [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] in [REGION] che si trova a <nolink>[HOSTNAME]</nolink> ([HOSTIP]) + Tu sei [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] in [REGION] che si trova a <nolink>[HOSTNAME]</nolink> ([HOSTIP]) [SERVER_VERSION] [SERVER_RELEASE_NOTES_URL] </floater.string> diff --git a/indra/newview/skins/default/xui/ja/floater_about.xml b/indra/newview/skins/default/xui/ja/floater_about.xml index 6d5df75645..eae52c98ec 100755 --- a/indra/newview/skins/default/xui/ja/floater_about.xml +++ b/indra/newview/skins/default/xui/ja/floater_about.xml @@ -8,7 +8,7 @@ コンパイラー [COMPILER] [COMPILER_VERSION] バージョン </floater.string> <floater.string name="AboutPosition"> - あなたの現在地は、[POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] の [REGION] です。位置は <nolink>[HOSTNAME]</nolink> です。([HOSTIP]) + あなたの現在地は、[POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] の [REGION] です。位置は <nolink>[HOSTNAME]</nolink> です。([HOSTIP]) [SERVER_VERSION] [SERVER_RELEASE_NOTES_URL] </floater.string> diff --git a/indra/newview/skins/default/xui/pl/floater_about.xml b/indra/newview/skins/default/xui/pl/floater_about.xml index 409429ffaa..61a72ff27d 100755 --- a/indra/newview/skins/default/xui/pl/floater_about.xml +++ b/indra/newview/skins/default/xui/pl/floater_about.xml @@ -8,7 +8,7 @@ Buduj z [COMPILER] wersją [COMPILER_VERSION] </floater.string> <floater.string name="AboutPosition"> - Położenie [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] w [REGION] zlokalizowanym w <nolink>[HOSTNAME]</nolink> ([HOSTIP]) + Położenie [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] w [REGION] zlokalizowanym w <nolink>[HOSTNAME]</nolink> ([HOSTIP]) [SERVER_VERSION] [SERVER_RELEASE_NOTES_URL] </floater.string> diff --git a/indra/newview/skins/default/xui/pt/floater_about.xml b/indra/newview/skins/default/xui/pt/floater_about.xml index 299f88b22a..d089266342 100755 --- a/indra/newview/skins/default/xui/pt/floater_about.xml +++ b/indra/newview/skins/default/xui/pt/floater_about.xml @@ -7,7 +7,7 @@ Construído com [COMPILER] versão [COMPILER_VERSION] </floater.string> <floater.string name="AboutPosition"> - Você está em [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] em [REGION] localizado em [HOSTNAME]</nolink>([HOSTIP]) + Você está em [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] em [REGION] localizado em [HOSTNAME]</nolink>([HOSTIP]) [SERVER_VERSION] [SERVER_RELEASE_NOTES_URL] </floater.string> diff --git a/indra/newview/skins/default/xui/ru/floater_about.xml b/indra/newview/skins/default/xui/ru/floater_about.xml index bb6266ac9a..2b2b3cf453 100755 --- a/indra/newview/skins/default/xui/ru/floater_about.xml +++ b/indra/newview/skins/default/xui/ru/floater_about.xml @@ -8,7 +8,7 @@ Использован компилятор [COMPILER], версия [COMPILER_VERSION] </floater.string> <floater.string name="AboutPosition"> - Вы в точке [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] в регионе «[REGION]», расположенном на <nolink>[HOSTNAME]</nolink> ([HOSTIP]) + Вы в точке [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] в регионе «[REGION]», расположенном на <nolink>[HOSTNAME]</nolink> ([HOSTIP]) [SERVER_VERSION] [SERVER_RELEASE_NOTES_URL] </floater.string> diff --git a/indra/newview/skins/default/xui/tr/floater_about.xml b/indra/newview/skins/default/xui/tr/floater_about.xml index 9cc9c7a220..4dcf6200c6 100755 --- a/indra/newview/skins/default/xui/tr/floater_about.xml +++ b/indra/newview/skins/default/xui/tr/floater_about.xml @@ -8,7 +8,7 @@ [COMPILER] [COMPILER_VERSION] sürümü ile oluşturuldu </floater.string> <floater.string name="AboutPosition"> - <nolink>[HOSTNAME]</nolink> ([HOSTIP]) üzerinde bulunan [REGION] içerisinde [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] konumundasınız + <nolink>[HOSTNAME]</nolink> ([HOSTIP]) üzerinde bulunan [REGION] içerisinde [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] konumundasınız [SERVER_VERSION] [SERVER_RELEASE_NOTES_URL] </floater.string> diff --git a/indra/newview/skins/default/xui/zh/floater_about.xml b/indra/newview/skins/default/xui/zh/floater_about.xml index 643881e416..1193243c7e 100755 --- a/indra/newview/skins/default/xui/zh/floater_about.xml +++ b/indra/newview/skins/default/xui/zh/floater_about.xml @@ -8,7 +8,7 @@ 以 [COMPILER_VERSION] 版本 [COMPILER] 建置 </floater.string> <floater.string name="AboutPosition"> - 你的方位是 [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1],地區名:[REGION],主機:<nolink>[HOSTNAME]</nolink> ([HOSTIP]) + 你的方位是 [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1],地區名:[REGION],主機:<nolink>[HOSTNAME]</nolink> ([HOSTIP]) [SERVER_VERSION] [SERVER_RELEASE_NOTES_URL] </floater.string> diff --git a/indra/newview/tests/llagentaccess_test.cpp b/indra/newview/tests/llagentaccess_test.cpp index 3ba25f3c10..a40b5c9a3d 100755 --- a/indra/newview/tests/llagentaccess_test.cpp +++ b/indra/newview/tests/llagentaccess_test.cpp @@ -49,10 +49,10 @@ LLControlGroup::~LLControlGroup() } // Implementation of just the LLControlGroup methods we requre -BOOL LLControlGroup::declareU32(const std::string& name, U32 initial_val, const std::string& comment, BOOL persist) +LLControlVariable* LLControlGroup::declareU32(const std::string& name, U32 initial_val, const std::string& comment, LLControlVariable::ePersist persist) { test_preferred_maturity = initial_val; - return true; + return NULL; } void LLControlGroup::setU32(const std::string& name, U32 val) @@ -80,7 +80,7 @@ namespace tut void agentaccess_object_t::test<1>() { LLControlGroup cgr("test"); - cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", FALSE); + cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", LLControlVariable::PERSIST_NO); LLAgentAccess aa(cgr); cgr.setU32("PreferredMaturity", SIM_ACCESS_PG); @@ -109,7 +109,7 @@ namespace tut void agentaccess_object_t::test<2>() { LLControlGroup cgr("test"); - cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", FALSE); + cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", LLControlVariable::PERSIST_NO); LLAgentAccess aa(cgr); // make sure default is PG @@ -157,7 +157,7 @@ namespace tut void agentaccess_object_t::test<3>() { LLControlGroup cgr("test"); - cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", FALSE); + cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", LLControlVariable::PERSIST_NO); LLAgentAccess aa(cgr); #ifndef HACKED_GODLIKE_VIEWER @@ -195,7 +195,7 @@ namespace tut void agentaccess_object_t::test<4>() { LLControlGroup cgr("test"); - cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", FALSE); + cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", LLControlVariable::PERSIST_NO); LLAgentAccess aa(cgr); #ifndef HACKED_GODLIKE_VIEWER @@ -272,7 +272,7 @@ namespace tut void agentaccess_object_t::test<5>() { LLControlGroup cgr("test"); - cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", FALSE); + cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", LLControlVariable::PERSIST_NO); LLAgentAccess aa(cgr); cgr.setU32("PreferredMaturity", SIM_ACCESS_ADULT); diff --git a/indra/newview/tests/lllogininstance_test.cpp b/indra/newview/tests/lllogininstance_test.cpp index f038112fd0..adeb848e03 100755 --- a/indra/newview/tests/lllogininstance_test.cpp +++ b/indra/newview/tests/lllogininstance_test.cpp @@ -135,6 +135,7 @@ void LLGridManager::addSystemGrid(const std::string& label, const std::string& login, const std::string& helper, const std::string& login_page, + const std::string& update_url_base, const std::string& login_id) { } @@ -175,8 +176,8 @@ F32 LLControlGroup::getF32(const std::string& name) { return 0.0f; } U32 LLControlGroup::saveToFile(const std::string& filename, BOOL nondefault_only) { return 1; } void LLControlGroup::setString(const std::string& name, const std::string& val) {} std::string LLControlGroup::getString(const std::string& name) { return "test_string"; } -BOOL LLControlGroup::declareBOOL(const std::string& name, BOOL initial_val, const std::string& comment, BOOL persist) { return TRUE; } -BOOL LLControlGroup::declareString(const std::string& name, const std::string &initial_val, const std::string& comment, BOOL persist) { return TRUE; } +LLControlVariable* LLControlGroup::declareBOOL(const std::string& name, BOOL initial_val, const std::string& comment, LLControlVariable::ePersist persist) { return NULL; } +LLControlVariable* LLControlGroup::declareString(const std::string& name, const std::string &initial_val, const std::string& comment, LLControlVariable::ePersist persist) { return NULL; } #include "lluicolortable.h" void LLUIColorTable::saveUserSettings(void)const {} @@ -208,9 +209,7 @@ std::string const & LLUpdaterService::pumpName(void) return wakka; } bool LLUpdaterService::updateReadyToInstall(void) { return false; } -void LLUpdaterService::initialize(const std::string& url, - const std::string& path, - const std::string& channel, +void LLUpdaterService::initialize(const std::string& channel, const std::string& version, const std::string& platform, const std::string& platform_version, @@ -344,13 +343,13 @@ namespace tut gTOSReplyPump = 0; // clear the callback. - gSavedSettings.declareBOOL("NoInventoryLibrary", FALSE, "", FALSE); - gSavedSettings.declareBOOL("ConnectAsGod", FALSE, "", FALSE); - gSavedSettings.declareBOOL("UseDebugMenus", FALSE, "", FALSE); - gSavedSettings.declareBOOL("ForceMandatoryUpdate", FALSE, "", FALSE); - gSavedSettings.declareString("ClientSettingsFile", "test_settings.xml", "", FALSE); - gSavedSettings.declareString("NextLoginLocation", "", "", FALSE); - gSavedSettings.declareBOOL("LoginLastLocation", FALSE, "", FALSE); + gSavedSettings.declareBOOL("NoInventoryLibrary", FALSE, "", LLControlVariable::PERSIST_NO); + gSavedSettings.declareBOOL("ConnectAsGod", FALSE, "", LLControlVariable::PERSIST_NO); + gSavedSettings.declareBOOL("UseDebugMenus", FALSE, "", LLControlVariable::PERSIST_NO); + gSavedSettings.declareBOOL("ForceMandatoryUpdate", FALSE, "", LLControlVariable::PERSIST_NO); + gSavedSettings.declareString("ClientSettingsFile", "test_settings.xml", "", LLControlVariable::PERSIST_NO); + gSavedSettings.declareString("NextLoginLocation", "", "", LLControlVariable::PERSIST_NO); + gSavedSettings.declareBOOL("LoginLastLocation", FALSE, "", LLControlVariable::PERSIST_NO); LLSD authenticator = LLSD::emptyMap(); LLSD identifier = LLSD::emptyMap(); diff --git a/indra/newview/tests/llsecapi_test.cpp b/indra/newview/tests/llsecapi_test.cpp index 703603e2db..d7e87ed52e 100755 --- a/indra/newview/tests/llsecapi_test.cpp +++ b/indra/newview/tests/llsecapi_test.cpp @@ -39,10 +39,10 @@ LLControlGroup::LLControlGroup(const std::string& name) : LLInstanceTracker<LLControlGroup, std::string>(name) {} LLControlGroup::~LLControlGroup() {} -BOOL LLControlGroup::declareString(const std::string& name, +LLControlVariable* LLControlGroup::declareString(const std::string& name, const std::string& initial_val, const std::string& comment, - BOOL persist) {return TRUE;} + LLControlVariable::ePersist persist) {return NULL;} void LLControlGroup::setString(const std::string& name, const std::string& val){} std::string LLControlGroup::getString(const std::string& name) { diff --git a/indra/newview/tests/llsechandler_basic_test.cpp b/indra/newview/tests/llsechandler_basic_test.cpp index 0235400976..2a8dc15346 100755 --- a/indra/newview/tests/llsechandler_basic_test.cpp +++ b/indra/newview/tests/llsechandler_basic_test.cpp @@ -71,10 +71,10 @@ std::string gLastName; LLControlGroup::LLControlGroup(const std::string& name) : LLInstanceTracker<LLControlGroup, std::string>(name) {} LLControlGroup::~LLControlGroup() {} -BOOL LLControlGroup::declareString(const std::string& name, +LLControlVariable* LLControlGroup::declareString(const std::string& name, const std::string& initial_val, const std::string& comment, - BOOL persist) {return TRUE;} + LLControlVariable::ePersist persist) {return NULL;} void LLControlGroup::setString(const std::string& name, const std::string& val){} std::string LLControlGroup::getString(const std::string& name) { diff --git a/indra/newview/tests/llslurl_test.cpp b/indra/newview/tests/llslurl_test.cpp index 09343ef227..86229ad636 100755 --- a/indra/newview/tests/llslurl_test.cpp +++ b/indra/newview/tests/llslurl_test.cpp @@ -37,10 +37,10 @@ LLControlGroup::LLControlGroup(const std::string& name) : LLInstanceTracker<LLControlGroup, std::string>(name) {} LLControlGroup::~LLControlGroup() {} -BOOL LLControlGroup::declareString(const std::string& name, +LLControlVariable* LLControlGroup::declareString(const std::string& name, const std::string& initial_val, const std::string& comment, - BOOL persist) {return TRUE;} + LLControlVariable::ePersist persist) {return NULL;} void LLControlGroup::setString(const std::string& name, const std::string& val){} std::string gCmdLineLoginURI; diff --git a/indra/newview/tests/llviewerhelputil_test.cpp b/indra/newview/tests/llviewerhelputil_test.cpp index 710881d811..f6456a2839 100755 --- a/indra/newview/tests/llviewerhelputil_test.cpp +++ b/indra/newview/tests/llviewerhelputil_test.cpp @@ -49,10 +49,10 @@ static std::string gOS; LLControlGroup::LLControlGroup(const std::string& name) : LLInstanceTracker<LLControlGroup, std::string>(name) {} LLControlGroup::~LLControlGroup() {} -BOOL LLControlGroup::declareString(const std::string& name, +LLControlVariable* LLControlGroup::declareString(const std::string& name, const std::string& initial_val, const std::string& comment, - BOOL persist) {return TRUE;} + LLControlVariable::ePersist persist) {return NULL;} void LLControlGroup::setString(const std::string& name, const std::string& val){} std::string LLControlGroup::getString(const std::string& name) { diff --git a/indra/newview/tests/llviewernetwork_test.cpp b/indra/newview/tests/llviewernetwork_test.cpp index a1e97ea17e..7ad7947ca4 100755 --- a/indra/newview/tests/llviewernetwork_test.cpp +++ b/indra/newview/tests/llviewernetwork_test.cpp @@ -37,10 +37,10 @@ LLControlGroup::LLControlGroup(const std::string& name) : LLInstanceTracker<LLControlGroup, std::string>(name) {} LLControlGroup::~LLControlGroup() {} -BOOL LLControlGroup::declareString(const std::string& name, +LLControlVariable* LLControlGroup::declareString(const std::string& name, const std::string& initial_val, const std::string& comment, - BOOL persist) {return TRUE;} + LLControlVariable::ePersist persist) {return NULL;} void LLControlGroup::setString(const std::string& name, const std::string& val){} std::string gCmdLineLoginURI; @@ -127,6 +127,7 @@ const char *gSampleGridFile = " <array>" " <string>myloginuri</string>" " </array>" + " <key>update_query_url_base</key><string>https://update.secondlife.com/update</string>" " <key>keyname</key><string>util.foobar.lindenlab.com</string>" " </map>" " </map>" @@ -185,6 +186,9 @@ namespace tut ensure_equals("id for agni", std::string("Agni"), LLGridManager::getInstance()->getGridId("util.agni.lindenlab.com")); + ensure_equals("update url base for Agni", // relies on agni being the default + std::string("https://update.secondlife.com/update"), + LLGridManager::getInstance()->getUpdateServiceURL()); ensure_equals("label for agni", LLGridManager::getInstance()->getGridLabel("util.agni.lindenlab.com"), std::string("Second Life Main Grid (Agni)")); @@ -256,6 +260,9 @@ namespace tut ensure_equals("id for agni", LLGridManager::getInstance()->getGridId("util.agni.lindenlab.com"), std::string("Agni")); + ensure_equals("update url base for Agni", // relies on agni being the default + std::string("https://update.secondlife.com/update"), + LLGridManager::getInstance()->getUpdateServiceURL()); ensure_equals("label for agni", LLGridManager::getInstance()->getGridLabel("util.agni.lindenlab.com"), std::string("Second Life Main Grid (Agni)")); @@ -384,6 +391,9 @@ namespace tut ensure_equals("getLoginPage", LLGridManager::getInstance()->getLoginPage(), std::string("http://viewer-login.agni.lindenlab.com/")); + ensure_equals("update url base for Agni", // relies on agni being the default + std::string("https://update.secondlife.com/update"), + LLGridManager::getInstance()->getUpdateServiceURL()); ensure("Is Agni a production grid", LLGridManager::getInstance()->isInProductionGrid()); std::vector<std::string> uris; LLGridManager::getInstance()->getLoginURIs(uris); diff --git a/indra/newview/tests/llxmlrpclistener_test.cpp b/indra/newview/tests/llxmlrpclistener_test.cpp index 711c2a3d51..20f913b670 100755 --- a/indra/newview/tests/llxmlrpclistener_test.cpp +++ b/indra/newview/tests/llxmlrpclistener_test.cpp @@ -62,8 +62,8 @@ namespace tut // These variables are required by machinery used by // LLXMLRPCTransaction. The values reflect reality for this test // executable; hopefully these values are correct. - gSavedSettings.declareBOOL("BrowserProxyEnabled", FALSE, "", FALSE); // don't persist - gSavedSettings.declareBOOL("NoVerifySSLCert", TRUE, "", FALSE); // don't persist + gSavedSettings.declareBOOL("BrowserProxyEnabled", FALSE, "", LLControlVariable::PERSIST_NO); // don't persist + gSavedSettings.declareBOOL("NoVerifySSLCert", TRUE, "", LLControlVariable::PERSIST_NO); // don't persist } // LLEventPump listener signature diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 5e08e54b7c..19863dd845 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -34,9 +34,15 @@ import tarfile import time import random viewer_dir = os.path.dirname(__file__) -# add llmanifest library to our path so we don't have to muck with PYTHONPATH -sys.path.append(os.path.join(viewer_dir, '../lib/python/indra/util')) -from llmanifest import LLManifest, main, proper_windows_path, path_ancestors +# Add indra/lib/python to our path so we don't have to muck with PYTHONPATH. +# Put it FIRST because some of our build hosts have an ancient install of +# indra.util.llmanifest under their system Python! +sys.path.insert(0, os.path.join(viewer_dir, os.pardir, "lib", "python")) +from indra.util.llmanifest import LLManifest, main, proper_windows_path, path_ancestors +try: + from llbase import llsd +except ImportError: + from indra.base import llsd class ViewerManifest(LLManifest): def is_packaging_viewer(self): @@ -65,13 +71,13 @@ class ViewerManifest(LLManifest): # include the entire shaders directory recursively self.path("shaders") # include the extracted list of contributors - contributor_names = self.extract_names("../../doc/contributions.txt") - self.put_in_file(contributor_names, "contributors.txt") - self.file_list.append(["../../doc/contributions.txt",self.dst_path_of("contributors.txt")]) + contributions_path = "../../doc/contributions.txt" + contributor_names = self.extract_names(contributions_path) + self.put_in_file(contributor_names, "contributors.txt", src=contributions_path) # include the extracted list of translators - translator_names = self.extract_names("../../doc/translations.txt") - self.put_in_file(translator_names, "translators.txt") - self.file_list.append(["../../doc/translations.txt",self.dst_path_of("translators.txt")]) + translations_path = "../../doc/translations.txt" + translator_names = self.extract_names(translations_path) + self.put_in_file(translator_names, "translators.txt", src=translations_path) # include the list of Lindens (if any) # see https://wiki.lindenlab.com/wiki/Generated_Linden_Credits linden_names_path = os.getenv("LINDEN_CREDITS") @@ -85,10 +91,9 @@ class ViewerManifest(LLManifest): else: # all names should be one line, but the join below also converts to a string linden_names = ', '.join(linden_file.readlines()) - self.put_in_file(linden_names, "lindens.txt") + self.put_in_file(linden_names, "lindens.txt", src=linden_names_path) linden_file.close() print "Linden names extracted from '%s'" % linden_names_path - self.file_list.append([linden_names_path,self.dst_path_of("lindens.txt")]) # ... and the entire windlight directory self.path("windlight") @@ -99,6 +104,27 @@ class ViewerManifest(LLManifest): self.path("dictionaries") self.end_prefix(pkgdir) + # CHOP-955: If we have "sourceid" in the build process + # environment, generate it into settings_install.xml. + try: + sourceid = os.environ["sourceid"] + except KeyError: + # no sourceid, no settings_install.xml file + pass + else: + if sourceid: + # Single-entry subset of the LLSD content of settings.xml + content = dict(sourceid=dict(Comment='Identify referring agency to Linden web servers', + Persist=1, + Type='String', + Value=sourceid)) + # put_in_file(src=) need not be an actual pathname; it + # only needs to be non-empty + settings_install = self.put_in_file(llsd.format_pretty_xml(content), + "settings_install.xml", + src="environment") + print "Put sourceid '%s' in %s" % (sourceid, settings_install) + self.end_prefix("app_settings") if self.prefix(src="character"): @@ -196,24 +222,26 @@ class ViewerManifest(LLManifest): """ Convenience function that returns the command-line flags for the grid""" - # Set command line flags relating to the target grid - grid_flags = '' - if not self.default_grid(): - grid_flags = "--grid %(grid)s "\ - "--helperuri http://preview-%(grid)s.secondlife.com/helpers/" %\ - {'grid':self.grid()} - - # Deal with settings - setting_flags = '' - if not self.default_channel() or not self.default_grid(): - if self.default_grid(): - setting_flags = '--settings settings_%s.xml'\ - % self.channel_lowerword() - else: - setting_flags = '--settings settings_%s_%s.xml'\ - % (self.grid(), self.channel_lowerword()) - - return " ".join((grid_flags, setting_flags)).strip() + # The original role of this method seems to have been to build a + # grid-specific viewer: one that would, on launch, preselect a + # particular grid. (Apparently that dates back to when the protocol + # between viewer and simulator required them to be updated in + # lockstep, so that "the beta grid" required "a beta viewer.") But + # those viewer command-line switches no longer work without tweaking + # user_settings/grids.xml. In fact, going forward, it's unclear what + # use case that would address. + + # This method also set a channel-specific (or grid-and-channel- + # specific) user_settings/settings_something.xml file. It has become + # clear that saving user settings in a channel-specific file causes + # more problems (confusion) than it solves, so we've discontinued that. + + # In fact we now avoid forcing viewer command-line switches at all, + # instead introducing a settings_install.xml file. Command-line + # switches don't aggregate well; for instance the generated --channel + # switch actually prevented the user specifying --channel on the + # command line. Settings files have well-defined override semantics. + return None def extract_names(self,src): try: @@ -530,8 +558,7 @@ class WindowsManifest(ViewerManifest): 'final_exe' : self.final_exe(), 'grid':self.args['grid'], 'grid_caps':self.args['grid'].upper(), - # escape quotes becase NSIS doesn't handle them well - 'flags':self.flags_list().replace('"', '$\\"'), + 'flags':'', 'channel':self.channel(), 'channel_oneword':self.channel_oneword(), 'channel_unique':self.channel_unique(), @@ -759,9 +786,6 @@ class DarwinManifest(ViewerManifest): self.end_prefix("llplugin") - # command line arguments for connecting to the proper grid - self.put_in_file(self.flags_list(), 'arguments.txt') - self.end_prefix("Resources") self.end_prefix("Contents") @@ -807,10 +831,6 @@ class DarwinManifest(ViewerManifest): 'bundle': self.get_dst_prefix() }) - channel_standin = 'Second Life Viewer' # hah, our default channel is not usable on its own - if not self.default_channel(): - channel_standin = self.channel() - imagename="SecondLife_" + '_'.join(self.args['version']) # MBW -- If the mounted volume name changes, it breaks the .DS_Store's background image and icon positioning. @@ -928,9 +948,6 @@ class LinuxManifest(ViewerManifest): self.path("install.sh") self.end_prefix("linux_tools") - # Create an appropriate gridargs.dat for this package, denoting required grid. - self.put_in_file(self.flags_list(), 'etc/gridargs.dat') - if self.prefix(src="", dst="bin"): self.path("secondlife-bin","do-not-directly-run-secondlife-bin") self.path("../linux_crash_logger/linux-crash-logger","linux-crash-logger.bin") |