summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCallum Linden <callum@lindenlab.com>2022-08-30 15:23:37 -0700
committerCallum Linden <callum@lindenlab.com>2022-08-30 15:23:37 -0700
commit2aace1793b2940c86b2aa0d001137d09aec82dae (patch)
treecae30bd3700fe91c23adce45aeae17531f5f70db
parentef58b9751a514e5e63cd77f9f78e6513bc6403cd (diff)
parentd31a83fb946c49a38376ea3b312b5380d0c8c065 (diff)
Merge branch 'master' into DRTVWR-568
-rwxr-xr-xdoc/contributions.txt2
-rw-r--r--indra/llui/llfloater.cpp17
-rw-r--r--indra/llui/llfloater.h1
-rw-r--r--indra/llui/lliconctrl.cpp13
-rw-r--r--indra/llui/lliconctrl.h7
-rw-r--r--indra/llui/llmenubutton.cpp8
-rw-r--r--indra/llui/llmenubutton.h3
-rw-r--r--indra/llui/lltabcontainer.cpp18
-rw-r--r--indra/llui/lltextbase.cpp50
-rw-r--r--indra/llui/lltextbase.h7
-rw-r--r--indra/newview/CMakeLists.txt22
-rw-r--r--indra/newview/VIEWER_VERSION.txt2
-rw-r--r--indra/newview/app_settings/commands.xml6
-rw-r--r--indra/newview/llagentpicksinfo.h4
-rw-r--r--indra/newview/llavataractions.cpp158
-rw-r--r--indra/newview/llavataractions.h28
-rw-r--r--indra/newview/llavatarpropertiesprocessor.cpp254
-rw-r--r--indra/newview/llavatarpropertiesprocessor.h21
-rw-r--r--indra/newview/llcallingcard.cpp1
-rw-r--r--indra/newview/llfloaterchatvoicevolume.cpp2
-rw-r--r--indra/newview/llfloaterclassified.cpp71
-rw-r--r--indra/newview/llfloaterclassified.h (renamed from indra/newview/llfloaterwebprofile.h)54
-rw-r--r--indra/newview/llfloaterdisplayname.cpp200
-rw-r--r--indra/newview/llfloaterdisplayname.h (renamed from indra/newview/llpanelme.h)28
-rw-r--r--indra/newview/llfloatergesture.cpp2
-rw-r--r--indra/newview/llfloateroutfitsnapshot.cpp1
-rw-r--r--indra/newview/llfloaterpreference.cpp97
-rw-r--r--indra/newview/llfloaterpreference.h5
-rw-r--r--indra/newview/llfloaterprofile.cpp170
-rw-r--r--indra/newview/llfloaterprofile.h66
-rw-r--r--indra/newview/llfloaterprofiletexture.cpp223
-rw-r--r--indra/newview/llfloaterprofiletexture.h81
-rw-r--r--indra/newview/llfloatervoicevolume.cpp2
-rw-r--r--indra/newview/llfloaterwebprofile.cpp81
-rw-r--r--indra/newview/llgrouplist.cpp309
-rw-r--r--indra/newview/llgrouplist.h30
-rw-r--r--indra/newview/llinspect.cpp16
-rw-r--r--indra/newview/llinspect.h2
-rw-r--r--indra/newview/llinspectavatar.cpp13
-rw-r--r--indra/newview/llinspectgroup.cpp13
-rw-r--r--indra/newview/llinspectobject.cpp14
-rw-r--r--indra/newview/llinspectremoteobject.cpp12
-rw-r--r--indra/newview/llinspecttoast.cpp2
-rw-r--r--indra/newview/lllocalbitmaps.cpp60
-rw-r--r--indra/newview/lllocalbitmaps.h1
-rw-r--r--indra/newview/lloutfitgallery.cpp1
-rw-r--r--indra/newview/llpanelavatar.cpp224
-rw-r--r--indra/newview/llpanelavatar.h183
-rw-r--r--indra/newview/llpanelclassified.cpp625
-rw-r--r--indra/newview/llpanelclassified.h134
-rw-r--r--indra/newview/llpanelexperiences.h1
-rw-r--r--indra/newview/llpanelimcontrolpanel.cpp4
-rw-r--r--indra/newview/llpanellandmarks.cpp52
-rw-r--r--indra/newview/llpanellandmarks.h2
-rw-r--r--indra/newview/llpanelme.cpp67
-rw-r--r--indra/newview/llpanelpick.cpp620
-rw-r--r--indra/newview/llpanelpick.h264
-rw-r--r--indra/newview/llpanelpicks.cpp1484
-rw-r--r--indra/newview/llpanelpicks.h315
-rw-r--r--indra/newview/llpanelplaceinfo.cpp12
-rw-r--r--indra/newview/llpanelplaceinfo.h3
-rw-r--r--indra/newview/llpanelplaces.cpp42
-rw-r--r--indra/newview/llpanelplaces.h6
-rw-r--r--indra/newview/llpanelprofile.cpp2656
-rw-r--r--indra/newview/llpanelprofile.h412
-rw-r--r--indra/newview/llpanelprofileclassifieds.cpp1513
-rw-r--r--indra/newview/llpanelprofileclassifieds.h340
-rw-r--r--indra/newview/llpanelprofilepicks.cpp883
-rw-r--r--indra/newview/llpanelprofilepicks.h248
-rw-r--r--indra/newview/llpreviewtexture.cpp15
-rw-r--r--indra/newview/llpreviewtexture.h2
-rw-r--r--indra/newview/llremoteparcelrequest.cpp7
-rw-r--r--indra/newview/llstartup.cpp5
-rw-r--r--indra/newview/lltexturectrl.cpp33
-rw-r--r--indra/newview/lltexturectrl.h4
-rw-r--r--indra/newview/llviewerdisplayname.cpp226
-rw-r--r--indra/newview/llviewerdisplayname.h55
-rw-r--r--indra/newview/llviewerfloaterreg.cpp12
-rw-r--r--indra/newview/llviewermedia.cpp2
-rw-r--r--indra/newview/llviewermenu.cpp40
-rw-r--r--indra/newview/llviewerregion.cpp54
-rw-r--r--indra/newview/llviewertexturelist.cpp11
-rw-r--r--indra/newview/llviewertexturelist.h7
-rw-r--r--indra/newview/llwebprofile.cpp2
-rw-r--r--indra/newview/skins/default/colors.xml16
-rw-r--r--indra/newview/skins/default/textures/icons/CopyBright.pngbin0 -> 519 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Profile_Friend_Offline.pngbin0 -> 208 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Profile_Friend_Online.pngbin0 -> 189 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Profile_Perm_Find_Disabled.pngbin0 -> 1608 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Profile_Perm_Find_Enabled.pngbin0 -> 1287 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Profile_Perm_Objects_Disabled.pngbin0 -> 1356 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Profile_Perm_Objects_Enabled.pngbin0 -> 1137 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Profile_Perm_Online_Disabled.pngbin0 -> 1312 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Profile_Perm_Online_Enabled.pngbin0 -> 1150 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/profile_group_visibility_eye_off.pngbin0 -> 507 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/profile_group_visibility_eye_off_pressed.pngbin0 -> 639 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/profile_group_visibility_eye_on.pngbin0 -> 485 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/profile_group_visibility_eye_on_pressed.pngbin0 -> 609 bytes
-rw-r--r--indra/newview/skins/default/textures/textures.xml14
-rw-r--r--indra/newview/skins/default/xui/da/panel_me.xml7
-rw-r--r--indra/newview/skins/default/xui/da/panel_side_tray.xml29
-rw-r--r--indra/newview/skins/default/xui/de/floater_preview_texture.xml57
-rw-r--r--indra/newview/skins/default/xui/de/floater_profile.xml16
-rw-r--r--indra/newview/skins/default/xui/de/floater_snapshot.xml9
-rw-r--r--indra/newview/skins/default/xui/de/menu_name_field.xml6
-rw-r--r--indra/newview/skins/default/xui/de/notifications.xml3
-rw-r--r--indra/newview/skins/default/xui/de/panel_edit_classified.xml2
-rw-r--r--indra/newview/skins/default/xui/de/panel_facebook_friends.xml4
-rw-r--r--indra/newview/skins/default/xui/de/panel_facebook_photo.xml8
-rw-r--r--indra/newview/skins/default/xui/de/panel_facebook_status.xml2
-rw-r--r--indra/newview/skins/default/xui/de/panel_group_general.xml2
-rw-r--r--indra/newview/skins/default/xui/de/panel_group_list_item_short.xml6
-rw-r--r--indra/newview/skins/default/xui/de/panel_me.xml4
-rw-r--r--indra/newview/skins/default/xui/de/panel_people.xml1
-rw-r--r--indra/newview/skins/default/xui/de/panel_profile_classified.xml110
-rw-r--r--indra/newview/skins/default/xui/de/panel_profile_classifieds.xml9
-rw-r--r--indra/newview/skins/default/xui/de/panel_profile_firstlife.xml (renamed from indra/newview/skins/default/xui/de/floater_picks.xml)2
-rw-r--r--indra/newview/skins/default/xui/de/panel_profile_interests.xml35
-rw-r--r--indra/newview/skins/default/xui/de/panel_profile_notes.xml8
-rw-r--r--indra/newview/skins/default/xui/de/panel_profile_pick.xml13
-rw-r--r--indra/newview/skins/default/xui/de/panel_profile_picks.xml12
-rw-r--r--indra/newview/skins/default/xui/de/panel_profile_secondlife.xml77
-rw-r--r--indra/newview/skins/default/xui/de/panel_profile_web.xml12
-rw-r--r--indra/newview/skins/default/xui/de/strings.xml33
-rw-r--r--indra/newview/skins/default/xui/en/floater_classified.xml (renamed from indra/newview/skins/default/xui/en/floater_picks.xml)13
-rw-r--r--indra/newview/skins/default/xui/en/floater_display_name.xml13
-rw-r--r--indra/newview/skins/default/xui/en/floater_preview_texture.xml208
-rw-r--r--indra/newview/skins/default/xui/en/floater_profile.xml88
-rw-r--r--indra/newview/skins/default/xui/en/floater_profile_permissions.xml76
-rw-r--r--indra/newview/skins/default/xui/en/floater_profile_texture.xml88
-rw-r--r--indra/newview/skins/default/xui/en/inspect_avatar.xml2
-rw-r--r--indra/newview/skins/default/xui/en/menu_avatar_self.xml7
-rw-r--r--indra/newview/skins/default/xui/en/menu_gesture_gear.xml2
-rw-r--r--indra/newview/skins/default/xui/en/menu_profile_other.xml171
-rw-r--r--indra/newview/skins/default/xui/en/menu_profile_self.xml85
-rw-r--r--indra/newview/skins/default/xui/en/menu_viewer.xml3
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml40
-rw-r--r--indra/newview/skins/default/xui/en/panel_classified_info.xml37
-rw-r--r--indra/newview/skins/default/xui/en/panel_edit_classified.xml354
-rw-r--r--indra/newview/skins/default/xui/en/panel_edit_pick.xml239
-rw-r--r--indra/newview/skins/default/xui/en/panel_edit_profile.xml472
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_list_item_short.xml110
-rw-r--r--indra/newview/skins/default/xui/en/panel_me.xml19
-rw-r--r--indra/newview/skins/default/xui/en/panel_pick_info.xml190
-rw-r--r--indra/newview/skins/default/xui/en/panel_picks.xml227
-rw-r--r--indra/newview/skins/default/xui/en/panel_profile_classified.xml830
-rw-r--r--indra/newview/skins/default/xui/en/panel_profile_classifieds.xml142
-rw-r--r--indra/newview/skins/default/xui/en/panel_profile_firstlife.xml103
-rw-r--r--indra/newview/skins/default/xui/en/panel_profile_notes.xml65
-rw-r--r--indra/newview/skins/default/xui/en/panel_profile_pick.xml314
-rw-r--r--indra/newview/skins/default/xui/en/panel_profile_picks.xml154
-rw-r--r--indra/newview/skins/default/xui/en/panel_profile_secondlife.xml549
-rw-r--r--indra/newview/skins/default/xui/en/panel_profile_web.xml36
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml12
-rw-r--r--indra/newview/skins/default/xui/es/floater_inventory_view_finder.xml2
-rw-r--r--indra/newview/skins/default/xui/es/floater_preview_texture.xml57
-rw-r--r--indra/newview/skins/default/xui/es/floater_profile.xml16
-rw-r--r--indra/newview/skins/default/xui/es/floater_snapshot.xml9
-rw-r--r--indra/newview/skins/default/xui/es/menu_name_field.xml6
-rw-r--r--indra/newview/skins/default/xui/es/notifications.xml3
-rw-r--r--indra/newview/skins/default/xui/es/panel_edit_classified.xml2
-rw-r--r--indra/newview/skins/default/xui/es/panel_facebook_place.xml2
-rw-r--r--indra/newview/skins/default/xui/es/panel_group_general.xml2
-rw-r--r--indra/newview/skins/default/xui/es/panel_group_list_item_short.xml6
-rw-r--r--indra/newview/skins/default/xui/es/panel_me.xml4
-rw-r--r--indra/newview/skins/default/xui/es/panel_people.xml1
-rw-r--r--indra/newview/skins/default/xui/es/panel_profile_classified.xml110
-rw-r--r--indra/newview/skins/default/xui/es/panel_profile_classifieds.xml9
-rw-r--r--indra/newview/skins/default/xui/es/panel_profile_firstlife.xml (renamed from indra/newview/skins/default/xui/fr/floater_picks.xml)2
-rw-r--r--indra/newview/skins/default/xui/es/panel_profile_interests.xml35
-rw-r--r--indra/newview/skins/default/xui/es/panel_profile_notes.xml8
-rw-r--r--indra/newview/skins/default/xui/es/panel_profile_pick.xml13
-rw-r--r--indra/newview/skins/default/xui/es/panel_profile_picks.xml12
-rw-r--r--indra/newview/skins/default/xui/es/panel_profile_secondlife.xml77
-rw-r--r--indra/newview/skins/default/xui/es/panel_profile_web.xml12
-rw-r--r--indra/newview/skins/default/xui/es/strings.xml33
-rw-r--r--indra/newview/skins/default/xui/fr/floater_facebook.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/floater_preview_texture.xml57
-rw-r--r--indra/newview/skins/default/xui/fr/floater_profile.xml16
-rw-r--r--indra/newview/skins/default/xui/fr/floater_snapshot.xml9
-rw-r--r--indra/newview/skins/default/xui/fr/menu_name_field.xml6
-rw-r--r--indra/newview/skins/default/xui/fr/notifications.xml3
-rw-r--r--indra/newview/skins/default/xui/fr/panel_edit_classified.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/panel_facebook_friends.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/panel_facebook_photo.xml8
-rw-r--r--indra/newview/skins/default/xui/fr/panel_facebook_status.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/panel_group_list_item_short.xml6
-rw-r--r--indra/newview/skins/default/xui/fr/panel_me.xml4
-rw-r--r--indra/newview/skins/default/xui/fr/panel_people.xml1
-rw-r--r--indra/newview/skins/default/xui/fr/panel_profile_classified.xml110
-rw-r--r--indra/newview/skins/default/xui/fr/panel_profile_classifieds.xml9
-rw-r--r--indra/newview/skins/default/xui/fr/panel_profile_firstlife.xml (renamed from indra/newview/skins/default/xui/es/floater_picks.xml)2
-rw-r--r--indra/newview/skins/default/xui/fr/panel_profile_interests.xml35
-rw-r--r--indra/newview/skins/default/xui/fr/panel_profile_notes.xml8
-rw-r--r--indra/newview/skins/default/xui/fr/panel_profile_pick.xml13
-rw-r--r--indra/newview/skins/default/xui/fr/panel_profile_picks.xml12
-rw-r--r--indra/newview/skins/default/xui/fr/panel_profile_secondlife.xml77
-rw-r--r--indra/newview/skins/default/xui/fr/panel_profile_web.xml12
-rw-r--r--indra/newview/skins/default/xui/fr/strings.xml33
-rw-r--r--indra/newview/skins/default/xui/it/floater_preview_texture.xml57
-rw-r--r--indra/newview/skins/default/xui/it/floater_profile.xml16
-rw-r--r--indra/newview/skins/default/xui/it/floater_snapshot.xml9
-rw-r--r--indra/newview/skins/default/xui/it/menu_name_field.xml6
-rw-r--r--indra/newview/skins/default/xui/it/notifications.xml3
-rw-r--r--indra/newview/skins/default/xui/it/panel_edit_classified.xml2
-rw-r--r--indra/newview/skins/default/xui/it/panel_facebook_friends.xml6
-rw-r--r--indra/newview/skins/default/xui/it/panel_facebook_photo.xml4
-rw-r--r--indra/newview/skins/default/xui/it/panel_facebook_status.xml10
-rw-r--r--indra/newview/skins/default/xui/it/panel_group_general.xml2
-rw-r--r--indra/newview/skins/default/xui/it/panel_group_list_item_short.xml6
-rw-r--r--indra/newview/skins/default/xui/it/panel_me.xml4
-rw-r--r--indra/newview/skins/default/xui/it/panel_people.xml1
-rw-r--r--indra/newview/skins/default/xui/it/panel_profile_classified.xml110
-rw-r--r--indra/newview/skins/default/xui/it/panel_profile_classifieds.xml9
-rw-r--r--indra/newview/skins/default/xui/it/panel_profile_firstlife.xml2
-rw-r--r--indra/newview/skins/default/xui/it/panel_profile_interests.xml35
-rw-r--r--indra/newview/skins/default/xui/it/panel_profile_notes.xml8
-rw-r--r--indra/newview/skins/default/xui/it/panel_profile_pick.xml13
-rw-r--r--indra/newview/skins/default/xui/it/panel_profile_picks.xml12
-rw-r--r--indra/newview/skins/default/xui/it/panel_profile_secondlife.xml77
-rw-r--r--indra/newview/skins/default/xui/it/panel_profile_web.xml12
-rw-r--r--indra/newview/skins/default/xui/it/strings.xml33
-rw-r--r--indra/newview/skins/default/xui/ja/floater_picks.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/floater_preview_texture.xml57
-rw-r--r--indra/newview/skins/default/xui/ja/floater_profile.xml16
-rw-r--r--indra/newview/skins/default/xui/ja/floater_snapshot.xml9
-rw-r--r--indra/newview/skins/default/xui/ja/menu_name_field.xml6
-rw-r--r--indra/newview/skins/default/xui/ja/notifications.xml3
-rw-r--r--indra/newview/skins/default/xui/ja/panel_edit_classified.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/panel_facebook_photo.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/panel_facebook_place.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/panel_facebook_status.xml4
-rw-r--r--indra/newview/skins/default/xui/ja/panel_group_list_item_short.xml6
-rw-r--r--indra/newview/skins/default/xui/ja/panel_me.xml4
-rw-r--r--indra/newview/skins/default/xui/ja/panel_people.xml1
-rw-r--r--indra/newview/skins/default/xui/ja/panel_profile_classified.xml110
-rw-r--r--indra/newview/skins/default/xui/ja/panel_profile_classifieds.xml9
-rw-r--r--indra/newview/skins/default/xui/ja/panel_profile_firstlife.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/panel_profile_interests.xml35
-rw-r--r--indra/newview/skins/default/xui/ja/panel_profile_notes.xml8
-rw-r--r--indra/newview/skins/default/xui/ja/panel_profile_pick.xml13
-rw-r--r--indra/newview/skins/default/xui/ja/panel_profile_picks.xml12
-rw-r--r--indra/newview/skins/default/xui/ja/panel_profile_secondlife.xml77
-rw-r--r--indra/newview/skins/default/xui/ja/panel_profile_web.xml12
-rw-r--r--indra/newview/skins/default/xui/ja/panel_snapshot_options.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/strings.xml33
-rw-r--r--indra/newview/skins/default/xui/pl/floater_picks.xml2
-rw-r--r--indra/newview/skins/default/xui/pl/panel_me.xml4
-rw-r--r--indra/newview/skins/default/xui/pt/floater_inventory_view_finder.xml2
-rw-r--r--indra/newview/skins/default/xui/pt/floater_picks.xml2
-rw-r--r--indra/newview/skins/default/xui/pt/floater_preview_texture.xml57
-rw-r--r--indra/newview/skins/default/xui/pt/floater_profile.xml16
-rw-r--r--indra/newview/skins/default/xui/pt/floater_snapshot.xml9
-rw-r--r--indra/newview/skins/default/xui/pt/menu_name_field.xml6
-rw-r--r--indra/newview/skins/default/xui/pt/notifications.xml3
-rw-r--r--indra/newview/skins/default/xui/pt/panel_edit_classified.xml2
-rw-r--r--indra/newview/skins/default/xui/pt/panel_group_general.xml2
-rw-r--r--indra/newview/skins/default/xui/pt/panel_group_list_item_short.xml6
-rw-r--r--indra/newview/skins/default/xui/pt/panel_me.xml4
-rw-r--r--indra/newview/skins/default/xui/pt/panel_people.xml1
-rw-r--r--indra/newview/skins/default/xui/pt/panel_profile_classified.xml110
-rw-r--r--indra/newview/skins/default/xui/pt/panel_profile_classifieds.xml9
-rw-r--r--indra/newview/skins/default/xui/pt/panel_profile_firstlife.xml (renamed from indra/newview/skins/default/xui/it/floater_picks.xml)2
-rw-r--r--indra/newview/skins/default/xui/pt/panel_profile_interests.xml35
-rw-r--r--indra/newview/skins/default/xui/pt/panel_profile_notes.xml8
-rw-r--r--indra/newview/skins/default/xui/pt/panel_profile_pick.xml13
-rw-r--r--indra/newview/skins/default/xui/pt/panel_profile_picks.xml12
-rw-r--r--indra/newview/skins/default/xui/pt/panel_profile_secondlife.xml77
-rw-r--r--indra/newview/skins/default/xui/pt/panel_profile_web.xml12
-rw-r--r--indra/newview/skins/default/xui/pt/strings.xml33
-rw-r--r--indra/newview/skins/default/xui/ru/floater_inventory_view_finder.xml2
-rw-r--r--indra/newview/skins/default/xui/ru/floater_picks.xml2
-rw-r--r--indra/newview/skins/default/xui/ru/floater_preview_texture.xml57
-rw-r--r--indra/newview/skins/default/xui/ru/floater_profile.xml16
-rw-r--r--indra/newview/skins/default/xui/ru/floater_report_abuse.xml2
-rw-r--r--indra/newview/skins/default/xui/ru/floater_snapshot.xml9
-rw-r--r--indra/newview/skins/default/xui/ru/menu_name_field.xml6
-rw-r--r--indra/newview/skins/default/xui/ru/notifications.xml3
-rw-r--r--indra/newview/skins/default/xui/ru/panel_edit_classified.xml4
-rw-r--r--indra/newview/skins/default/xui/ru/panel_facebook_friends.xml2
-rw-r--r--indra/newview/skins/default/xui/ru/panel_facebook_photo.xml14
-rw-r--r--indra/newview/skins/default/xui/ru/panel_facebook_place.xml4
-rw-r--r--indra/newview/skins/default/xui/ru/panel_facebook_status.xml12
-rw-r--r--indra/newview/skins/default/xui/ru/panel_group_list_item_short.xml6
-rw-r--r--indra/newview/skins/default/xui/ru/panel_me.xml4
-rw-r--r--indra/newview/skins/default/xui/ru/panel_people.xml1
-rw-r--r--indra/newview/skins/default/xui/ru/panel_profile_classified.xml110
-rw-r--r--indra/newview/skins/default/xui/ru/panel_profile_classifieds.xml9
-rw-r--r--indra/newview/skins/default/xui/ru/panel_profile_firstlife.xml2
-rw-r--r--indra/newview/skins/default/xui/ru/panel_profile_interests.xml35
-rw-r--r--indra/newview/skins/default/xui/ru/panel_profile_notes.xml8
-rw-r--r--indra/newview/skins/default/xui/ru/panel_profile_pick.xml13
-rw-r--r--indra/newview/skins/default/xui/ru/panel_profile_picks.xml12
-rw-r--r--indra/newview/skins/default/xui/ru/panel_profile_secondlife.xml77
-rw-r--r--indra/newview/skins/default/xui/ru/panel_profile_web.xml12
-rw-r--r--indra/newview/skins/default/xui/ru/strings.xml33
-rw-r--r--indra/newview/skins/default/xui/tr/floater_facebook.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/floater_inventory_view_finder.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/floater_picks.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/floater_preview_texture.xml57
-rw-r--r--indra/newview/skins/default/xui/tr/floater_profile.xml16
-rw-r--r--indra/newview/skins/default/xui/tr/floater_snapshot.xml9
-rw-r--r--indra/newview/skins/default/xui/tr/menu_name_field.xml6
-rw-r--r--indra/newview/skins/default/xui/tr/notifications.xml3
-rw-r--r--indra/newview/skins/default/xui/tr/panel_edit_classified.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/panel_facebook_friends.xml4
-rw-r--r--indra/newview/skins/default/xui/tr/panel_facebook_photo.xml6
-rw-r--r--indra/newview/skins/default/xui/tr/panel_facebook_place.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/panel_facebook_status.xml8
-rw-r--r--indra/newview/skins/default/xui/tr/panel_group_general.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/panel_group_list_item_short.xml6
-rw-r--r--indra/newview/skins/default/xui/tr/panel_me.xml4
-rw-r--r--indra/newview/skins/default/xui/tr/panel_people.xml1
-rw-r--r--indra/newview/skins/default/xui/tr/panel_profile_classified.xml110
-rw-r--r--indra/newview/skins/default/xui/tr/panel_profile_classifieds.xml9
-rw-r--r--indra/newview/skins/default/xui/tr/panel_profile_firstlife.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/panel_profile_interests.xml35
-rw-r--r--indra/newview/skins/default/xui/tr/panel_profile_notes.xml8
-rw-r--r--indra/newview/skins/default/xui/tr/panel_profile_pick.xml13
-rw-r--r--indra/newview/skins/default/xui/tr/panel_profile_picks.xml12
-rw-r--r--indra/newview/skins/default/xui/tr/panel_profile_secondlife.xml77
-rw-r--r--indra/newview/skins/default/xui/tr/panel_profile_web.xml12
-rw-r--r--indra/newview/skins/default/xui/tr/strings.xml33
-rw-r--r--indra/newview/skins/default/xui/zh/floater_picks.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/floater_preview_texture.xml57
-rw-r--r--indra/newview/skins/default/xui/zh/floater_profile.xml16
-rw-r--r--indra/newview/skins/default/xui/zh/floater_snapshot.xml9
-rw-r--r--indra/newview/skins/default/xui/zh/menu_name_field.xml6
-rw-r--r--indra/newview/skins/default/xui/zh/notifications.xml3
-rw-r--r--indra/newview/skins/default/xui/zh/panel_edit_classified.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/panel_group_list_item_short.xml6
-rw-r--r--indra/newview/skins/default/xui/zh/panel_me.xml4
-rw-r--r--indra/newview/skins/default/xui/zh/panel_people.xml1
-rw-r--r--indra/newview/skins/default/xui/zh/panel_profile_classified.xml110
-rw-r--r--indra/newview/skins/default/xui/zh/panel_profile_classifieds.xml9
-rw-r--r--indra/newview/skins/default/xui/zh/panel_profile_firstlife.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/panel_profile_interests.xml35
-rw-r--r--indra/newview/skins/default/xui/zh/panel_profile_notes.xml8
-rw-r--r--indra/newview/skins/default/xui/zh/panel_profile_pick.xml13
-rw-r--r--indra/newview/skins/default/xui/zh/panel_profile_picks.xml12
-rw-r--r--indra/newview/skins/default/xui/zh/panel_profile_secondlife.xml77
-rw-r--r--indra/newview/skins/default/xui/zh/panel_profile_web.xml12
-rw-r--r--indra/newview/skins/default/xui/zh/strings.xml33
343 files changed, 14615 insertions, 6730 deletions
diff --git a/doc/contributions.txt b/doc/contributions.txt
index 640ffb037e..2c1e5487ce 100755
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -223,6 +223,7 @@ Ansariel Hiller
MAINT-8723
SL-10385
SL-10891
+ SL-10675
SL-13364
SL-13858
SL-13697
@@ -820,6 +821,7 @@ Jonathan Yap
Kadah Coba
STORM-1060
STORM-1843
+ SL-10675
Jondan Lundquist
Joosten Briebers
MAINT-7074
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 03efd09689..c6a3ada777 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -259,6 +259,7 @@ LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p)
mMinHeight(p.min_height),
mHeaderHeight(p.header_height),
mLegacyHeaderHeight(p.legacy_header_height),
+ mDefaultRectForGroup(true),
mMinimized(FALSE),
mForeground(FALSE),
mFirstLook(TRUE),
@@ -906,7 +907,10 @@ bool LLFloater::applyRectControl()
if (last_in_group && last_in_group != this)
{
// other floaters in our group, position ourselves relative to them and don't save the rect
- mRectControl.clear();
+ if (mDefaultRectForGroup)
+ {
+ mRectControl.clear();
+ }
mPositioning = LLFloaterEnums::POSITIONING_CASCADE_GROUP;
}
else
@@ -3481,8 +3485,15 @@ void LLFloater::stackWith(LLFloater& other)
}
next_rect.translate(floater_offset, -floater_offset);
- next_rect.setLeftTopAndSize(next_rect.mLeft, next_rect.mTop, getRect().getWidth(), getRect().getHeight());
-
+ const LLRect& rect = getControlGroup()->getRect(mRectControl);
+ if (rect.notEmpty() && !mDefaultRectForGroup && mResizable)
+ {
+ next_rect.setLeftTopAndSize(next_rect.mLeft, next_rect.mTop, llmax(mMinWidth, rect.getWidth()), llmax(mMinHeight, rect.getHeight()));
+ }
+ else
+ {
+ next_rect.setLeftTopAndSize(next_rect.mLeft, next_rect.mTop, getRect().getWidth(), getRect().getHeight());
+ }
setShape(next_rect);
if (!other.getHost())
diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h
index 306760b7fb..668cd208a9 100644
--- a/indra/llui/llfloater.h
+++ b/indra/llui/llfloater.h
@@ -454,6 +454,7 @@ public:
protected:
bool mSaveRect;
+ bool mDefaultRectForGroup;
std::string mRectControl;
std::string mPosXControl;
std::string mPosYControl;
diff --git a/indra/llui/lliconctrl.cpp b/indra/llui/lliconctrl.cpp
index 82b01e705d..e01aba402e 100644
--- a/indra/llui/lliconctrl.cpp
+++ b/indra/llui/lliconctrl.cpp
@@ -35,6 +35,7 @@
#include "llui.h"
#include "lluictrlfactory.h"
#include "lluiimage.h"
+#include "llwindow.h"
static LLDefaultChildRegistry::Register<LLIconCtrl> r("icon");
@@ -42,6 +43,7 @@ LLIconCtrl::Params::Params()
: image("image_name"),
color("color"),
use_draw_context_alpha("use_draw_context_alpha", true),
+ interactable("interactable", false),
scale_image("scale_image"),
min_width("min_width", 0),
min_height("min_height", 0)
@@ -52,6 +54,7 @@ LLIconCtrl::LLIconCtrl(const LLIconCtrl::Params& p)
mColor(p.color()),
mImagep(p.image),
mUseDrawContextAlpha(p.use_draw_context_alpha),
+ mInteractable(p.interactable),
mPriority(0),
mMinWidth(p.min_width),
mMinHeight(p.min_height),
@@ -81,6 +84,16 @@ void LLIconCtrl::draw()
LLUICtrl::draw();
}
+BOOL LLIconCtrl::handleHover(S32 x, S32 y, MASK mask)
+{
+ if (mInteractable && getEnabled())
+ {
+ getWindow()->setCursor(UI_CURSOR_HAND);
+ return TRUE;
+ }
+ return LLUICtrl::handleHover(x, y, mask);
+}
+
// virtual
// value might be a string or a UUID
void LLIconCtrl::setValue(const LLSD& value)
diff --git a/indra/llui/lliconctrl.h b/indra/llui/lliconctrl.h
index dd83e78fd3..9c3b517bca 100644
--- a/indra/llui/lliconctrl.h
+++ b/indra/llui/lliconctrl.h
@@ -48,7 +48,8 @@ public:
{
Optional<LLUIImage*> image;
Optional<LLUIColor> color;
- Optional<bool> use_draw_context_alpha;
+ Optional<bool> use_draw_context_alpha,
+ interactable;
Optional<S32> min_width,
min_height;
Ignored scale_image;
@@ -67,6 +68,9 @@ public:
// llview overrides
virtual void draw();
+ // llview overrides
+ virtual BOOL handleHover(S32 x, S32 y, MASK mask);
+
// lluictrl overrides
virtual void setValue(const LLSD& value );
@@ -88,6 +92,7 @@ protected:
// If set to true (default), use the draw context transparency.
// If false, will use transparency returned by getCurrentTransparency(). See STORM-698.
bool mUseDrawContextAlpha;
+ bool mInteractable;
private:
LLUIColor mColor;
diff --git a/indra/llui/llmenubutton.cpp b/indra/llui/llmenubutton.cpp
index 303afcda15..583704418b 100644
--- a/indra/llui/llmenubutton.cpp
+++ b/indra/llui/llmenubutton.cpp
@@ -40,6 +40,7 @@ void LLMenuButton::MenuPositions::declareValues()
declare("topleft", MP_TOP_LEFT);
declare("topright", MP_TOP_RIGHT);
declare("bottomleft", MP_BOTTOM_LEFT);
+ declare("bottomright", MP_BOTTOM_RIGHT);
}
LLMenuButton::Params::Params()
@@ -212,6 +213,13 @@ void LLMenuButton::updateMenuOrigin()
mY = rect.mBottom;
break;
}
+ case MP_BOTTOM_RIGHT:
+ {
+ const LLRect& menu_rect = menu->getRect();
+ mX = rect.mRight - menu_rect.getWidth();
+ mY = rect.mBottom;
+ break;
+ }
}
}
diff --git a/indra/llui/llmenubutton.h b/indra/llui/llmenubutton.h
index 67ec1983b3..e42f8f53bd 100644
--- a/indra/llui/llmenubutton.h
+++ b/indra/llui/llmenubutton.h
@@ -41,7 +41,8 @@ public:
{
MP_TOP_LEFT,
MP_TOP_RIGHT,
- MP_BOTTOM_LEFT
+ MP_BOTTOM_LEFT,
+ MP_BOTTOM_RIGHT
} EMenuPosition;
struct MenuPositions
diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp
index 459fdcf2ae..0aa7a2d217 100644
--- a/indra/llui/lltabcontainer.cpp
+++ b/indra/llui/lltabcontainer.cpp
@@ -402,9 +402,13 @@ void LLTabContainer::draw()
S32 cur_scroll_pos = getScrollPos();
if (cur_scroll_pos > 0)
{
- S32 available_width_with_arrows = getRect().getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + tabcntr_arrow_btn_size + tabcntr_arrow_btn_size + 1);
- if (!mIsVertical)
+ if (mIsVertical)
{
+ target_pixel_scroll = cur_scroll_pos * (BTN_HEIGHT + tabcntrv_pad);
+ }
+ else
+ {
+ S32 available_width_with_arrows = getRect().getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + tabcntr_arrow_btn_size + tabcntr_arrow_btn_size + 1);
for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter)
{
if (cur_scroll_pos == 0)
@@ -1189,13 +1193,15 @@ void LLTabContainer::addTabPanel(const TabPanelParams& panel)
sendChildToFront(mNextArrowBtn);
sendChildToFront(mJumpPrevArrowBtn);
sendChildToFront(mJumpNextArrowBtn);
-
+
+ updateMaxScrollPos();
+
if( select )
{
selectLastTab();
+ mScrollPos = mMaxScrollPos;
}
- updateMaxScrollPos();
}
void LLTabContainer::addPlaceholder(LLPanel* child, const std::string& label)
@@ -2079,9 +2085,9 @@ void LLTabContainer::updateMaxScrollPos()
if( tab_total_height > available_height )
{
static LLUICachedControl<S32> tabcntrv_arrow_btn_size ("UITabCntrvArrowBtnSize", 0);
- S32 available_height_with_arrows = getRect().getHeight() - 2*(tabcntrv_arrow_btn_size + 3*tabcntrv_pad);
+ S32 available_height_with_arrows = getRect().getHeight() - 2*(tabcntrv_arrow_btn_size + 3*tabcntrv_pad) - mNextArrowBtn->getRect().mBottom;
S32 additional_needed = tab_total_height - available_height_with_arrows;
- setMaxScrollPos((S32) ceil(additional_needed / float(BTN_HEIGHT) ) );
+ setMaxScrollPos((S32) ceil(additional_needed / float(BTN_HEIGHT + tabcntrv_pad) ) );
no_scroll = FALSE;
}
}
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 0dc99fdde6..c4a529e4ad 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -163,6 +163,7 @@ LLTextBase::Params::Params()
font_shadow("font_shadow"),
wrap("wrap"),
trusted_content("trusted_content", true),
+ always_show_icons("always_show_icons", false),
use_ellipses("use_ellipses", false),
parse_urls("parse_urls", false),
force_urls_external("force_urls_external", false),
@@ -212,6 +213,7 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p)
mClip(p.clip),
mClipPartial(p.clip_partial && !p.allow_scroll),
mTrustedContent(p.trusted_content),
+ mAlwaysShowIcons(p.always_show_icons),
mTrackEnd( p.track_end ),
mScrollIndex(-1),
mSelectionStart( 0 ),
@@ -448,8 +450,48 @@ void LLTextBase::drawSelectionBackground()
++rect_it)
{
LLRect selection_rect = *rect_it;
- selection_rect = *rect_it;
- selection_rect.translate(mVisibleTextRect.mLeft - content_display_rect.mLeft, mVisibleTextRect.mBottom - content_display_rect.mBottom);
+ if (mScroller)
+ {
+ // If scroller is On content_display_rect has correct rect and safe to use as is
+ // Note: we might need to account for border
+ selection_rect.translate(mVisibleTextRect.mLeft - content_display_rect.mLeft, mVisibleTextRect.mBottom - content_display_rect.mBottom);
+ }
+ else
+ {
+ // If scroller is Off content_display_rect will have rect from document, adjusted to text width, heigh and position
+ // and we have to acount for offset depending on position
+ S32 v_delta = 0;
+ S32 h_delta = 0;
+ switch (mVAlign)
+ {
+ case LLFontGL::TOP:
+ v_delta = mVisibleTextRect.mTop - content_display_rect.mTop - mVPad;
+ break;
+ case LLFontGL::VCENTER:
+ v_delta = (llmax(mVisibleTextRect.getHeight() - content_display_rect.mTop, -content_display_rect.mBottom) + (mVisibleTextRect.mBottom - content_display_rect.mBottom)) / 2;
+ break;
+ case LLFontGL::BOTTOM:
+ v_delta = mVisibleTextRect.mBottom - content_display_rect.mBottom;
+ break;
+ default:
+ break;
+ }
+ switch (mHAlign)
+ {
+ case LLFontGL::LEFT:
+ h_delta = mVisibleTextRect.mLeft - content_display_rect.mLeft + mHPad;
+ break;
+ case LLFontGL::HCENTER:
+ h_delta = (llmax(mVisibleTextRect.getWidth() - content_display_rect.mLeft, -content_display_rect.mRight) + (mVisibleTextRect.mRight - content_display_rect.mRight)) / 2;
+ break;
+ case LLFontGL::RIGHT:
+ h_delta = mVisibleTextRect.mRight - content_display_rect.mRight;
+ break;
+ default:
+ break;
+ }
+ selection_rect.translate(h_delta, v_delta);
+ }
gl_rect_2d(selection_rect, selection_color);
}
}
@@ -2116,7 +2158,7 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para
LLUrlMatch match;
std::string text = new_text;
while ( LLUrlRegistry::instance().findUrl(text, match,
- boost::bind(&LLTextBase::replaceUrl, this, _1, _2, _3),isContentTrusted()))
+ boost::bind(&LLTextBase::replaceUrl, this, _1, _2, _3),isContentTrusted() || mAlwaysShowIcons))
{
start = match.getStart();
end = match.getEnd()+1;
@@ -2141,7 +2183,7 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para
}
// add icon before url if need
- LLTextUtil::processUrlMatch(&match, this, isContentTrusted() || match.isTrusted());
+ LLTextUtil::processUrlMatch(&match, this, isContentTrusted() || match.isTrusted() || mAlwaysShowIcons);
if ((isContentTrusted() || match.isTrusted()) && !match.getIcon().empty() )
{
setLastSegmentToolTip(LLTrans::getString("TooltipSLIcon"));
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index a4e83b42b4..25f8fa1c2b 100644
--- a/indra/llui/lltextbase.h
+++ b/indra/llui/lltextbase.h
@@ -321,7 +321,8 @@ public:
parse_highlights,
clip,
clip_partial,
- trusted_content;
+ trusted_content,
+ always_show_icons;
Optional<S32> v_pad,
h_pad;
@@ -369,6 +370,8 @@ public:
virtual void onFocusReceived();
virtual void onFocusLost();
+ void setParseHTML(bool parse_html) { mParseHTML = parse_html; }
+
// LLSpellCheckMenuHandler overrides
/*virtual*/ bool getSpellCheck() const;
@@ -702,6 +705,8 @@ protected:
bool mAutoIndent;
S32 mMaxTextByteLength; // Maximum length mText is allowed to be in bytes
bool mSkipTripleClick;
+ bool mAlwaysShowIcons;
+
bool mSkipLinkUnderline;
// support widgets
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index c577d062f9..7d78ec9e3c 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -234,12 +234,14 @@ set(viewer_SOURCE_FILES
llfloatercamera.cpp
llfloatercamerapresets.cpp
llfloaterchatvoicevolume.cpp
+ llfloaterclassified.cpp
llfloatercolorpicker.cpp
llfloaterconversationlog.cpp
llfloaterconversationpreview.cpp
llfloatercreatelandmark.cpp
llfloaterdeleteprefpreset.cpp
llfloaterdestinations.cpp
+ llfloaterdisplayname.cpp
llfloatereditenvironmentbase.cpp
llfloatereditextdaycycle.cpp
llfloaterenvironmentadjust.cpp
@@ -295,9 +297,11 @@ set(viewer_SOURCE_FILES
llfloaterpay.cpp
llfloaterperms.cpp
llfloaterpostprocess.cpp
+ llfloaterprofile.cpp
llfloaterpreference.cpp
llfloaterpreferenceviewadvanced.cpp
llfloaterpreviewtrash.cpp
+ llfloaterprofiletexture.cpp
llfloaterproperties.cpp
llfloaterregiondebugconsole.cpp
llfloaterregioninfo.cpp
@@ -330,7 +334,6 @@ set(viewer_SOURCE_FILES
llfloatervoiceeffect.cpp
llfloatervoicevolume.cpp
llfloaterwebcontent.cpp
- llfloaterwebprofile.cpp
llfloaterwhitelistentry.cpp
llfloaterwindowsize.cpp
llfloaterworldmap.cpp
@@ -476,7 +479,6 @@ set(viewer_SOURCE_FILES
llpanelmediasettingsgeneral.cpp
llpanelmediasettingspermissions.cpp
llpanelmediasettingssecurity.cpp
- llpanelme.cpp
llpanelnearbymedia.cpp
llpanelobject.cpp
llpanelobjectinventory.cpp
@@ -486,8 +488,6 @@ set(viewer_SOURCE_FILES
llpanelpeople.cpp
llpanelpeoplemenus.cpp
llpanelpermissions.cpp
- llpanelpick.cpp
- llpanelpicks.cpp
llpanelplaceinfo.cpp
llpanelplaceprofile.cpp
llpanelplaces.cpp
@@ -496,6 +496,8 @@ set(viewer_SOURCE_FILES
llpanelpresetspulldown.cpp
llpanelprimmediacontrols.cpp
llpanelprofile.cpp
+ llpanelprofileclassifieds.cpp
+ llpanelprofilepicks.cpp
llpanelsnapshot.cpp
llpanelsnapshotinventory.cpp
llpanelsnapshotlocal.cpp
@@ -657,6 +659,7 @@ set(viewer_SOURCE_FILES
llviewercontrol.cpp
llviewercontrollistener.cpp
llviewerdisplay.cpp
+ llviewerdisplayname.cpp
llviewerfloaterreg.cpp
llviewerfoldertype.cpp
llviewergenericmessage.cpp
@@ -870,12 +873,14 @@ set(viewer_HEADER_FILES
llfloatercamerapresets.h
llfloatercamera.h
llfloaterchatvoicevolume.h
+ llfloaterclassified.h
llfloatercolorpicker.h
llfloaterconversationlog.h
llfloaterconversationpreview.h
llfloatercreatelandmark.h
llfloaterdeleteprefpreset.h
llfloaterdestinations.h
+ llfloaterdisplayname.h
llfloatereditenvironmentbase.h
llfloatereditextdaycycle.h
llfloaterenvironmentadjust.h
@@ -934,9 +939,11 @@ set(viewer_HEADER_FILES
llfloaterpay.h
llfloaterperms.h
llfloaterpostprocess.h
+ llfloaterprofile.h
llfloaterpreference.h
llfloaterpreferenceviewadvanced.h
llfloaterpreviewtrash.h
+ llfloaterprofiletexture.h
llfloaterproperties.h
llfloaterregiondebugconsole.h
llfloaterregioninfo.h
@@ -969,7 +976,6 @@ set(viewer_HEADER_FILES
llfloatervoiceeffect.h
llfloatervoicevolume.h
llfloaterwebcontent.h
- llfloaterwebprofile.h
llfloaterwhitelistentry.h
llfloaterwindowsize.h
llfloaterworldmap.h
@@ -1105,7 +1111,6 @@ set(viewer_HEADER_FILES
llpanelmediasettingsgeneral.h
llpanelmediasettingspermissions.h
llpanelmediasettingssecurity.h
- llpanelme.h
llpanelnearbymedia.h
llpanelobject.h
llpanelobjectinventory.h
@@ -1115,8 +1120,6 @@ set(viewer_HEADER_FILES
llpanelpeople.h
llpanelpeoplemenus.h
llpanelpermissions.h
- llpanelpick.h
- llpanelpicks.h
llpanelplaceinfo.h
llpanelplaceprofile.h
llpanelplaces.h
@@ -1125,6 +1128,8 @@ set(viewer_HEADER_FILES
llpanelpresetspulldown.h
llpanelprimmediacontrols.h
llpanelprofile.h
+ llpanelprofileclassifieds.h
+ llpanelprofilepicks.h
llpanelsnapshot.h
llpanelteleporthistory.h
llpaneltiptoast.h
@@ -1287,6 +1292,7 @@ set(viewer_HEADER_FILES
llviewercontrol.h
llviewercontrollistener.h
llviewerdisplay.h
+ llviewerdisplayname.h
llviewerfloaterreg.h
llviewerfoldertype.h
llviewergenericmessage.h
diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index e411592c25..b22e754ac6 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-6.6.3
+6.6.4
diff --git a/indra/newview/app_settings/commands.xml b/indra/newview/app_settings/commands.xml
index 3dfe3f6634..2644f5f449 100644
--- a/indra/newview/app_settings/commands.xml
+++ b/indra/newview/app_settings/commands.xml
@@ -167,10 +167,8 @@
icon="Command_Picks_Icon"
label_ref="Command_Picks_Label"
tooltip_ref="Command_Picks_Tooltip"
- execute_function="Floater.ToggleOrBringToFront"
- execute_parameters="picks"
- is_running_function="Floater.IsOpen"
- is_running_parameters="picks"
+ execute_function="Avatar.TogglePicks"
+ is_running_function="Avatar.IsPicksTabOpen"
/>
<command name="places"
available_in_toybox="true"
diff --git a/indra/newview/llagentpicksinfo.h b/indra/newview/llagentpicksinfo.h
index f981e08ff7..21df036cb7 100644
--- a/indra/newview/llagentpicksinfo.h
+++ b/indra/newview/llagentpicksinfo.h
@@ -74,10 +74,10 @@ public:
void decrementNumberOfPicks() { --mNumberOfPicks; }
-private:
-
void onServerRespond(LLAvatarPicks* picks);
+private:
+
/**
* Sets number of Picks.
*/
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index 1797d2dd6e..25ba7c365f 100644
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -48,6 +48,7 @@
#include "llfloatergroups.h"
#include "llfloaterreg.h"
#include "llfloaterpay.h"
+#include "llfloaterprofile.h"
#include "llfloatersidepanelcontainer.h"
#include "llfloaterwebcontent.h"
#include "llfloaterworldmap.h"
@@ -62,11 +63,14 @@
#include "llnotificationsutil.h" // for LLNotificationsUtil
#include "llpaneloutfitedit.h"
#include "llpanelprofile.h"
+#include "llparcel.h"
#include "llrecentpeople.h"
#include "lltrans.h"
#include "llviewercontrol.h"
#include "llviewerobjectlist.h"
#include "llviewermessage.h" // for handle_lure
+#include "llviewernetwork.h" //LLGridManager
+#include "llviewerparcelmgr.h"
#include "llviewerregion.h"
#include "lltrans.h"
#include "llcallingcard.h"
@@ -81,6 +85,19 @@ const U32 KICK_FLAGS_FREEZE = 1 << 0;
const U32 KICK_FLAGS_UNFREEZE = 1 << 1;
+std::string getProfileURL(const std::string& agent_name, bool feed_only)
+{
+ std::string url = "[WEB_PROFILE_URL][AGENT_NAME][FEED_ONLY]";
+ LLSD subs;
+ subs["WEB_PROFILE_URL"] = LLGridManager::getInstance()->getWebProfileURL();
+ subs["AGENT_NAME"] = agent_name;
+ subs["FEED_ONLY"] = feed_only ? "/?feed_only=true" : "";
+ url = LLWeb::expandURLSubstitutions(url, subs);
+ LLStringUtil::toLower(url);
+ return url;
+}
+
+
// static
void LLAvatarActions::requestFriendshipDialog(const LLUUID& id, const std::string& name)
{
@@ -316,57 +333,144 @@ void LLAvatarActions::startConference(const uuid_vec_t& ids, const LLUUID& float
make_ui_sound("UISndStartIM");
}
-static const char* get_profile_floater_name(const LLUUID& avatar_id)
+// static
+void LLAvatarActions::showProfile(const LLUUID& avatar_id)
+{
+ if (avatar_id.notNull())
+ {
+ LLFloaterReg::showInstance("profile", LLSD().with("id", avatar_id));
+ }
+}
+
+// static
+void LLAvatarActions::showPicks(const LLUUID& avatar_id)
+{
+ if (avatar_id.notNull())
+ {
+ LLFloaterProfile* profilefloater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", avatar_id)));
+ if (profilefloater)
+ {
+ profilefloater->showPick();
+ }
+ }
+}
+
+// static
+void LLAvatarActions::showPick(const LLUUID& avatar_id, const LLUUID& pick_id)
+{
+ if (avatar_id.notNull())
+ {
+ LLFloaterProfile* profilefloater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", avatar_id)));
+ if (profilefloater)
+ {
+ profilefloater->showPick(pick_id);
+ }
+ }
+}
+
+// static
+void LLAvatarActions::createPick()
{
- // Use different floater XML for our profile to be able to save its rect.
- return avatar_id == gAgentID ? "my_profile" : "profile";
+ LLFloaterProfile* profilefloater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", gAgent.getID())));
+ LLViewerRegion* region = gAgent.getRegion();
+ if (profilefloater && region)
+ {
+ LLPickData data;
+ data.pos_global = gAgent.getPositionGlobal();
+ data.sim_name = region->getName();
+
+ LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+ if (parcel)
+ {
+ data.name = parcel->getName();
+ data.desc = parcel->getDesc();
+ data.snapshot_id = parcel->getSnapshotID();
+ data.parcel_id = parcel->getID();
+ }
+ else
+ {
+ data.name = region->getName();
+ }
+
+ profilefloater->createPick(data);
+ }
}
-static void on_avatar_name_show_profile(const LLUUID& agent_id, const LLAvatarName& av_name)
+// static
+bool LLAvatarActions::isPickTabSelected(const LLUUID& avatar_id)
{
- std::string url = getProfileURL(av_name.getAccountName());
+ if (avatar_id.notNull())
+ {
+ LLFloaterProfile* profilefloater = LLFloaterReg::findTypedInstance<LLFloaterProfile>("profile", LLSD().with("id", avatar_id));
+ if (profilefloater)
+ {
+ return profilefloater->isPickTabSelected();
+ }
+ }
+ return false;
+}
- // PROFILES: open in webkit window
- LLFloaterWebContent::Params p;
- p.url(url).id(agent_id.asString());
- LLFloaterReg::showInstance(get_profile_floater_name(agent_id), p);
+// static
+void LLAvatarActions::showClassifieds(const LLUUID& avatar_id)
+{
+ if (avatar_id.notNull())
+ {
+ LLFloaterProfile* profilefloater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", avatar_id)));
+ if (profilefloater)
+ {
+ profilefloater->showClassified();
+ }
+ }
}
// static
-void LLAvatarActions::showProfile(const LLUUID& id)
+void LLAvatarActions::showClassified(const LLUUID& avatar_id, const LLUUID& classified_id, bool edit)
{
- if (id.notNull())
+ if (avatar_id.notNull())
{
- LLAvatarNameCache::get(id, boost::bind(&on_avatar_name_show_profile, _1, _2));
+ LLFloaterProfile* profilefloater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", avatar_id)));
+ if (profilefloater)
+ {
+ profilefloater->showClassified(classified_id, edit);
+ }
}
}
+// static
+void LLAvatarActions::createClassified()
+{
+ LLFloaterProfile* profilefloater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", gAgent.getID())));
+ if (profilefloater)
+ {
+ profilefloater->createClassified();
+ }
+}
+
//static
-bool LLAvatarActions::profileVisible(const LLUUID& id)
+bool LLAvatarActions::profileVisible(const LLUUID& avatar_id)
{
LLSD sd;
- sd["id"] = id;
- LLFloater* browser = getProfileFloater(id);
- return browser && browser->isShown();
+ sd["id"] = avatar_id;
+ LLFloater* floater = getProfileFloater(avatar_id);
+ return floater && floater->isShown();
}
//static
-LLFloater* LLAvatarActions::getProfileFloater(const LLUUID& id)
+LLFloater* LLAvatarActions::getProfileFloater(const LLUUID& avatar_id)
{
- LLFloaterWebContent *browser = dynamic_cast<LLFloaterWebContent*>
- (LLFloaterReg::findInstance(get_profile_floater_name(id), LLSD().with("id", id)));
- return browser;
+ LLFloaterProfile* floater = LLFloaterReg::findTypedInstance<LLFloaterProfile>("profile", LLSD().with("id", avatar_id));
+ return floater;
}
//static
-void LLAvatarActions::hideProfile(const LLUUID& id)
+void LLAvatarActions::hideProfile(const LLUUID& avatar_id)
{
LLSD sd;
- sd["id"] = id;
- LLFloater* browser = getProfileFloater(id);
- if (browser)
+ sd["id"] = avatar_id;
+ LLFloater* floater = getProfileFloater(avatar_id);
+ if (floater)
{
- browser->closeFloater();
+ floater->closeFloater();
}
}
@@ -990,7 +1094,7 @@ bool LLAvatarActions::canShareSelectedItems(LLInventoryPanel* inv_panel /* = NUL
}
// static
-void LLAvatarActions::toggleBlock(const LLUUID& id)
+bool LLAvatarActions::toggleBlock(const LLUUID& id)
{
LLAvatarName av_name;
LLAvatarNameCache::get(id, &av_name);
@@ -1000,10 +1104,12 @@ void LLAvatarActions::toggleBlock(const LLUUID& id)
if (LLMuteList::getInstance()->isMuted(mute.mID, mute.mName))
{
LLMuteList::getInstance()->remove(mute);
+ return false;
}
else
{
LLMuteList::getInstance()->add(mute);
+ return true;
}
}
diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h
index 7c721076c8..86183cc119 100644
--- a/indra/newview/llavataractions.h
+++ b/indra/newview/llavataractions.h
@@ -38,6 +38,8 @@ class LLInventoryPanel;
class LLFloater;
class LLView;
+std::string getProfileURL(const std::string& agent_name, bool feed_only = false);
+
/**
* Friend-related actions (add, remove, offer teleport, etc)
*/
@@ -91,13 +93,20 @@ public:
*/
static void startConference(const uuid_vec_t& ids, const LLUUID& floater_id = LLUUID::null);
- /**
- * Show avatar profile.
- */
- static void showProfile(const LLUUID& id);
- static void hideProfile(const LLUUID& id);
- static bool profileVisible(const LLUUID& id);
- static LLFloater* getProfileFloater(const LLUUID& id);
+ /**
+ * Show avatar profile.
+ */
+ static void showProfile(const LLUUID& avatar_id);
+ static void showPicks(const LLUUID& avatar_id);
+ static void showPick(const LLUUID& avatar_id, const LLUUID& pick_id);
+ static void createPick();
+ static void showClassifieds(const LLUUID& avatar_id);
+ static void showClassified(const LLUUID& avatar_id, const LLUUID& classified_id, bool edit = false);
+ static void createClassified();
+ static void hideProfile(const LLUUID& avatar_id);
+ static bool profileVisible(const LLUUID& avatar_id);
+ static bool isPickTabSelected(const LLUUID& avatar_id);
+ static LLFloater* getProfileFloater(const LLUUID& avatar_id);
/**
* Show avatar on world map.
@@ -126,9 +135,10 @@ public:
static void shareWithAvatars(LLView * panel);
/**
- * Block/unblock the avatar.
+ * Block/unblock the avatar by id.
+ * Returns true if blocked, returns false if unblocked
*/
- static void toggleBlock(const LLUUID& id);
+ static bool toggleBlock(const LLUUID& id);
/**
* Mute/unmute avatar.
diff --git a/indra/newview/llavatarpropertiesprocessor.cpp b/indra/newview/llavatarpropertiesprocessor.cpp
index f41eb3daf4..dd0d06a8c8 100644
--- a/indra/newview/llavatarpropertiesprocessor.cpp
+++ b/indra/newview/llavatarpropertiesprocessor.cpp
@@ -36,6 +36,7 @@
#include "llstartup.h"
// Linden library includes
+#include "llavataractions.h" // for getProfileUrl
#include "lldate.h"
#include "lltrans.h"
#include "llui.h" // LLUI::getLanguage()
@@ -94,54 +95,98 @@ void LLAvatarPropertiesProcessor::removeObserver(const LLUUID& avatar_id, LLAvat
}
}
-
-void LLAvatarPropertiesProcessor::sendGenericRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string method)
+void LLAvatarPropertiesProcessor::sendRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string &method)
{
+ // this is the startup state when send_complete_agent_movement() message is sent.
+ // Before this messages won't work so don't bother trying
+ if (LLStartUp::getStartupState() <= STATE_AGENT_SEND)
+ {
+ return;
+ }
+
+ if (avatar_id.isNull())
+ {
+ return;
+ }
+
// Suppress duplicate requests while waiting for a response from the network
if (isPendingRequest(avatar_id, type))
{
// waiting for a response, don't re-request
return;
}
- // indicate we're going to make a request
- addPendingRequest(avatar_id, type);
- std::vector<std::string> strings;
- strings.push_back( avatar_id.asString() );
- send_generic_message(method, strings);
+ std::string cap;
+
+ switch (type)
+ {
+ case APT_PROPERTIES:
+ // indicate we're going to make a request
+ sendAvatarPropertiesRequestMessage(avatar_id);
+ // can use getRegionCapability("AgentProfile"), but it is heavy
+ // initAgentProfileCapRequest(avatar_id, cap);
+ break;
+ case APT_PICKS:
+ case APT_GROUPS:
+ case APT_NOTES:
+ if (cap.empty())
+ {
+ // indicate we're going to make a request
+ sendGenericRequest(avatar_id, type, method);
+ }
+ else
+ {
+ initAgentProfileCapRequest(avatar_id, cap);
+ }
+ break;
+ default:
+ sendGenericRequest(avatar_id, type, method);
+ break;
+ }
}
-void LLAvatarPropertiesProcessor::sendAvatarPropertiesRequest(const LLUUID& avatar_id)
+void LLAvatarPropertiesProcessor::sendGenericRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string &method)
{
- // this is the startup state when send_complete_agent_movement() message is sent.
- // Before this, the AvatarPropertiesRequest message
- // won't work so don't bother trying
- if (LLStartUp::getStartupState() <= STATE_AGENT_SEND)
- {
- return;
- }
+ // indicate we're going to make a request
+ addPendingRequest(avatar_id, type);
- if (isPendingRequest(avatar_id, APT_PROPERTIES))
- {
- // waiting for a response, don't re-request
- return;
- }
- // indicate we're going to make a request
- addPendingRequest(avatar_id, APT_PROPERTIES);
+ std::vector<std::string> strings;
+ strings.push_back(avatar_id.asString());
+ send_generic_message(method, strings);
+}
- LLMessageSystem *msg = gMessageSystem;
+void LLAvatarPropertiesProcessor::sendAvatarPropertiesRequestMessage(const LLUUID& avatar_id)
+{
+ addPendingRequest(avatar_id, APT_PROPERTIES);
- msg->newMessageFast(_PREHASH_AvatarPropertiesRequest);
- msg->nextBlockFast( _PREHASH_AgentData);
- msg->addUUIDFast( _PREHASH_AgentID, gAgent.getID() );
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- msg->addUUIDFast( _PREHASH_AvatarID, avatar_id);
- gAgent.sendReliableMessage();
+ LLMessageSystem *msg = gMessageSystem;
+
+ msg->newMessageFast(_PREHASH_AvatarPropertiesRequest);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->addUUIDFast(_PREHASH_AvatarID, avatar_id);
+ gAgent.sendReliableMessage();
+}
+
+void LLAvatarPropertiesProcessor::initAgentProfileCapRequest(const LLUUID& avatar_id, const std::string& cap_url)
+{
+ addPendingRequest(avatar_id, APT_PROPERTIES);
+ addPendingRequest(avatar_id, APT_PICKS);
+ addPendingRequest(avatar_id, APT_GROUPS);
+ addPendingRequest(avatar_id, APT_NOTES);
+ LLCoros::instance().launch("requestAgentUserInfoCoro",
+ boost::bind(requestAvatarPropertiesCoro, cap_url, avatar_id));
+}
+
+void LLAvatarPropertiesProcessor::sendAvatarPropertiesRequest(const LLUUID& avatar_id)
+{
+ sendRequest(avatar_id, APT_PROPERTIES, "AvatarPropertiesRequest");
}
void LLAvatarPropertiesProcessor::sendAvatarPicksRequest(const LLUUID& avatar_id)
{
- sendGenericRequest(avatar_id, APT_PICKS, "avatarpicksrequest");
+ sendGenericRequest(avatar_id, APT_PICKS, "avatarpicksrequest");
}
void LLAvatarPropertiesProcessor::sendAvatarNotesRequest(const LLUUID& avatar_id)
@@ -174,7 +219,7 @@ void LLAvatarPropertiesProcessor::sendAvatarPropertiesUpdate(const LLAvatarData*
return;
}
- LL_INFOS() << "Sending avatarinfo update" << LL_ENDL;
+ LL_WARNS() << "Sending avatarinfo update. This trims profile descriptions!!!" << LL_ENDL;
// This value is required by sendAvatarPropertiesUpdate method.
//A profile should never be mature. (From the original code)
@@ -266,6 +311,113 @@ bool LLAvatarPropertiesProcessor::hasPaymentInfoOnFile(const LLAvatarData* avata
return ((avatar_data->flags & AVATAR_TRANSACTED) || (avatar_data->flags & AVATAR_IDENTIFIED));
}
+// static
+void LLAvatarPropertiesProcessor::requestAvatarPropertiesCoro(std::string cap_url, LLUUID agent_id)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("requestAvatarPropertiesCoro", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpHeaders::ptr_t httpHeaders;
+
+ LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+ httpOpts->setFollowRedirects(true);
+
+ std::string finalUrl = cap_url + "/" + agent_id.asString();
+
+ LLSD result = httpAdapter->getAndSuspend(httpRequest, finalUrl, httpOpts, httpHeaders);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status
+ || !result.has("id")
+ || agent_id != result["id"].asUUID())
+ {
+ LL_WARNS("AvatarProperties") << "Failed to get agent information for id " << agent_id << LL_ENDL;
+ LLAvatarPropertiesProcessor* self = getInstance();
+ self->removePendingRequest(agent_id, APT_PROPERTIES);
+ self->removePendingRequest(agent_id, APT_PICKS);
+ self->removePendingRequest(agent_id, APT_GROUPS);
+ self->removePendingRequest(agent_id, APT_NOTES);
+ return;
+ }
+
+ // Avatar Data
+
+ LLAvatarData avatar_data;
+ std::string birth_date;
+
+ avatar_data.agent_id = agent_id;
+ avatar_data.avatar_id = agent_id;
+ avatar_data.image_id = result["sl_image_id"].asUUID();
+ avatar_data.fl_image_id = result["fl_image_id"].asUUID();
+ avatar_data.partner_id = result["partner_id"].asUUID();
+ avatar_data.about_text = result["sl_about_text"].asString();
+ avatar_data.fl_about_text = result["fl_about_text"].asString();
+ avatar_data.born_on = result["member_since"].asDate();
+ avatar_data.profile_url = getProfileURL(agent_id.asString());
+
+ avatar_data.flags = 0;
+ avatar_data.caption_index = 0;
+
+ LLAvatarPropertiesProcessor* self = getInstance();
+ // Request processed, no longer pending
+ self->removePendingRequest(agent_id, APT_PROPERTIES);
+ self->notifyObservers(agent_id, &avatar_data, APT_PROPERTIES);
+
+ // Picks
+
+ LLSD picks_array = result["picks"];
+ LLAvatarPicks avatar_picks;
+ avatar_picks.agent_id = agent_id; // Not in use?
+ avatar_picks.target_id = agent_id;
+
+ for (LLSD::array_const_iterator it = picks_array.beginArray(); it != picks_array.endArray(); ++it)
+ {
+ const LLSD& pick_data = *it;
+ avatar_picks.picks_list.emplace_back(pick_data["id"].asUUID(), pick_data["name"].asString());
+ }
+
+ // Request processed, no longer pending
+ self->removePendingRequest(agent_id, APT_PICKS);
+ self->notifyObservers(agent_id, &avatar_picks, APT_PICKS);
+
+ // Groups
+
+ LLSD groups_array = result["groups"];
+ LLAvatarGroups avatar_groups;
+ avatar_groups.agent_id = agent_id; // Not in use?
+ avatar_groups.avatar_id = agent_id; // target_id
+
+ for (LLSD::array_const_iterator it = groups_array.beginArray(); it != groups_array.endArray(); ++it)
+ {
+ const LLSD& group_info = *it;
+ LLAvatarGroups::LLGroupData group_data;
+ group_data.group_powers = 0; // Not in use?
+ group_data.group_title = group_info["name"].asString(); // Missing data, not in use?
+ group_data.group_id = group_info["id"].asUUID();
+ group_data.group_name = group_info["name"].asString();
+ group_data.group_insignia_id = group_info["image_id"].asUUID();
+
+ avatar_groups.group_list.push_back(group_data);
+ }
+
+ self->removePendingRequest(agent_id, APT_GROUPS);
+ self->notifyObservers(agent_id, &avatar_groups, APT_GROUPS);
+
+ // Notes
+ LLAvatarNotes avatar_notes;
+
+ avatar_notes.agent_id = agent_id;
+ avatar_notes.target_id = agent_id;
+ avatar_notes.notes = result["notes"].asString();
+
+ // Request processed, no longer pending
+ self->removePendingRequest(agent_id, APT_NOTES);
+ self->notifyObservers(agent_id, &avatar_notes, APT_NOTES);
+}
+
void LLAvatarPropertiesProcessor::processAvatarPropertiesReply(LLMessageSystem* msg, void**)
{
LLAvatarData avatar_data;
@@ -312,6 +464,21 @@ void LLAvatarPropertiesProcessor::processAvatarInterestsReply(LLMessageSystem* m
That will suppress the warnings and be compatible with old server versions.
WARNING: LLTemplateMessageReader::decodeData: Message from 216.82.37.237:13000 with no handler function received: AvatarInterestsReply
*/
+
+ LLInterestsData interests_data;
+
+ msg->getUUIDFast( _PREHASH_AgentData, _PREHASH_AgentID, interests_data.agent_id );
+ msg->getUUIDFast( _PREHASH_AgentData, _PREHASH_AvatarID, interests_data.avatar_id );
+ msg->getU32Fast( _PREHASH_PropertiesData, _PREHASH_WantToMask, interests_data.want_to_mask );
+ msg->getStringFast( _PREHASH_PropertiesData, _PREHASH_WantToText, interests_data.want_to_text );
+ msg->getU32Fast( _PREHASH_PropertiesData, _PREHASH_SkillsMask, interests_data.skills_mask );
+ msg->getStringFast( _PREHASH_PropertiesData, _PREHASH_SkillsText, interests_data.skills_text );
+ msg->getString( _PREHASH_PropertiesData, _PREHASH_LanguagesText, interests_data.languages_text );
+
+ LLAvatarPropertiesProcessor* self = getInstance();
+ // Request processed, no longer pending
+ self->removePendingRequest(interests_data.avatar_id, APT_INTERESTS_INFO);
+ self->notifyObservers(interests_data.avatar_id, &interests_data, APT_INTERESTS_INFO);
}
void LLAvatarPropertiesProcessor::processAvatarClassifiedsReply(LLMessageSystem* msg, void**)
@@ -385,7 +552,7 @@ void LLAvatarPropertiesProcessor::processAvatarNotesReply(LLMessageSystem* msg,
void LLAvatarPropertiesProcessor::processAvatarPicksReply(LLMessageSystem* msg, void**)
{
LLAvatarPicks avatar_picks;
- msg->getUUID(_PREHASH_AgentData, _PREHASH_AgentID, avatar_picks.target_id);
+ msg->getUUID(_PREHASH_AgentData, _PREHASH_AgentID, avatar_picks.agent_id);
msg->getUUID(_PREHASH_AgentData, _PREHASH_TargetID, avatar_picks.target_id);
S32 block_count = msg->getNumberOfBlocks(_PREHASH_Data);
@@ -551,6 +718,29 @@ void LLAvatarPropertiesProcessor::sendClassifiedDelete(const LLUUID& classified_
gAgent.sendReliableMessage();
}
+void LLAvatarPropertiesProcessor::sendInterestsInfoUpdate(const LLInterestsData* interests_data)
+{
+ if(!interests_data)
+ {
+ return;
+ }
+
+ LLMessageSystem* msg = gMessageSystem;
+
+ msg->newMessage(_PREHASH_AvatarInterestsUpdate);
+ msg->nextBlockFast( _PREHASH_AgentData);
+ msg->addUUIDFast( _PREHASH_AgentID, gAgent.getID() );
+ msg->addUUIDFast( _PREHASH_SessionID, gAgent.getSessionID() );
+ msg->nextBlockFast( _PREHASH_PropertiesData);
+ msg->addU32Fast( _PREHASH_WantToMask, interests_data->want_to_mask);
+ msg->addStringFast( _PREHASH_WantToText, interests_data->want_to_text);
+ msg->addU32Fast( _PREHASH_SkillsMask, interests_data->skills_mask);
+ msg->addStringFast( _PREHASH_SkillsText, interests_data->skills_text);
+ msg->addString( _PREHASH_LanguagesText, interests_data->languages_text);
+
+ gAgent.sendReliableMessage();
+}
+
void LLAvatarPropertiesProcessor::sendPickInfoUpdate(const LLPickData* new_pick)
{
if (!new_pick) return;
diff --git a/indra/newview/llavatarpropertiesprocessor.h b/indra/newview/llavatarpropertiesprocessor.h
index b063048c26..f778634d25 100644
--- a/indra/newview/llavatarpropertiesprocessor.h
+++ b/indra/newview/llavatarpropertiesprocessor.h
@@ -56,10 +56,22 @@ enum EAvatarProcessorType
APT_PICKS,
APT_PICK_INFO,
APT_TEXTURES,
+ APT_INTERESTS_INFO,
APT_CLASSIFIEDS,
APT_CLASSIFIED_INFO
};
+struct LLInterestsData
+{
+ LLUUID agent_id;
+ LLUUID avatar_id; //target id
+ U32 want_to_mask;
+ std::string want_to_text;
+ U32 skills_mask;
+ std::string skills_text;
+ std::string languages_text;
+};
+
struct LLAvatarData
{
LLUUID agent_id;
@@ -223,6 +235,8 @@ public:
void sendClassifiedDelete(const LLUUID& classified_id);
+ void sendInterestsInfoUpdate(const LLInterestsData* interests_data);
+
// Returns translated, human readable string for account type, such
// as "Resident" or "Linden Employee". Used for profiles, inspectors.
static std::string accountType(const LLAvatarData* avatar_data);
@@ -234,6 +248,8 @@ public:
static bool hasPaymentInfoOnFile(const LLAvatarData* avatar_data);
+ static void requestAvatarPropertiesCoro(std::string cap_url, LLUUID agent_id);
+
static void processAvatarPropertiesReply(LLMessageSystem* msg, void**);
static void processAvatarInterestsReply(LLMessageSystem* msg, void**);
@@ -252,7 +268,10 @@ public:
protected:
- void sendGenericRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string method);
+ void sendRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string &method);
+ void sendGenericRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string &method);
+ void sendAvatarPropertiesRequestMessage(const LLUUID& avatar_id);
+ void initAgentProfileCapRequest(const LLUUID& avatar_id, const std::string& cap_url);
void notifyObservers(const LLUUID& id,void* data, EAvatarProcessorType type);
diff --git a/indra/newview/llcallingcard.cpp b/indra/newview/llcallingcard.cpp
index 8d1e9a438e..fa7d5139ae 100644
--- a/indra/newview/llcallingcard.cpp
+++ b/indra/newview/llcallingcard.cpp
@@ -640,6 +640,7 @@ void LLAvatarTracker::processChange(LLMessageSystem* msg)
if(mBuddyInfo.find(agent_related) != mBuddyInfo.end())
{
(mBuddyInfo[agent_related])->setRightsTo(new_rights);
+ mChangedBuddyIDs.insert(agent_related);
}
}
else
diff --git a/indra/newview/llfloaterchatvoicevolume.cpp b/indra/newview/llfloaterchatvoicevolume.cpp
index 45aea00a49..67c412dfa6 100644
--- a/indra/newview/llfloaterchatvoicevolume.cpp
+++ b/indra/newview/llfloaterchatvoicevolume.cpp
@@ -35,7 +35,7 @@ LLFloaterChatVoiceVolume::LLFloaterChatVoiceVolume(const LLSD& key)
void LLFloaterChatVoiceVolume::onOpen(const LLSD& key)
{
LLInspect::onOpen(key);
- LLUI::getInstance()->positionViewNearMouse(this);
+ LLInspect::repositionInspector(key);
}
LLFloaterChatVoiceVolume::~LLFloaterChatVoiceVolume()
diff --git a/indra/newview/llfloaterclassified.cpp b/indra/newview/llfloaterclassified.cpp
new file mode 100644
index 0000000000..3520b0f67a
--- /dev/null
+++ b/indra/newview/llfloaterclassified.cpp
@@ -0,0 +1,71 @@
+/**
+ * @file llfloaterclassified.cpp
+ * @brief LLFloaterClassified for displaying classifieds.
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, 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 "llfloaterclassified.h"
+
+LLFloaterClassified::LLFloaterClassified(const LLSD& key)
+ : LLFloater(key)
+{
+}
+
+LLFloaterClassified::~LLFloaterClassified()
+{
+}
+
+void LLFloaterClassified::onOpen(const LLSD& key)
+{
+ LLPanel* panel = findChild<LLPanel>("main_panel", true);
+ if (panel)
+ {
+ panel->onOpen(key);
+ }
+ if (key.has("classified_name"))
+ {
+ setTitle(key["classified_name"].asString());
+ }
+ LLFloater::onOpen(key);
+}
+
+BOOL LLFloaterClassified::postBuild()
+{
+ return TRUE;
+}
+
+
+bool LLFloaterClassified::matchesKey(const LLSD& key)
+{
+ bool is_mkey_valid = mKey.has("classified_id");
+ bool is_key_valid = key.has("classified_id");
+ if (is_mkey_valid && is_key_valid)
+ {
+ return key["classified_id"].asUUID() == mKey["classified_id"].asUUID();
+ }
+ return is_mkey_valid == is_key_valid;
+}
+
+// eof
diff --git a/indra/newview/llfloaterwebprofile.h b/indra/newview/llfloaterclassified.h
index 4c355e401b..2c95d82b2c 100644
--- a/indra/newview/llfloaterwebprofile.h
+++ b/indra/newview/llfloaterclassified.h
@@ -1,59 +1,45 @@
-/**
- * @file llfloaterwebprofile.h
- * @brief Avatar profile floater.
+/**
+ * @file llfloaterclassified.h
+ * @brief LLFloaterClassified for displaying classifieds.
*
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
+ * Copyright (C) 2022, 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_LLFLOATERWEBPROFILE_H
-#define LL_LLFLOATERWEBPROFILE_H
-
-#include "llfloaterwebcontent.h"
-#include "llviewermediaobserver.h"
+#ifndef LL_LLFLOATERCLASSIFIED_H
+#define LL_LLFLOATERCLASSIFIED_H
-#include <string>
+#include "llfloater.h"
-class LLMediaCtrl;
-
-/**
- * Displays avatar profile web page.
- */
-class LLFloaterWebProfile
-: public LLFloaterWebContent
+class LLFloaterClassified : public LLFloater
{
- LOG_CLASS(LLFloaterWebProfile);
+ LOG_CLASS(LLFloaterClassified);
public:
- typedef LLFloaterWebContent::Params Params;
+ LLFloaterClassified(const LLSD& key);
+ virtual ~LLFloaterClassified();
- LLFloaterWebProfile(const Params& key);
+ void onOpen(const LLSD& key) override;
+ BOOL postBuild() override;
- /*virtual*/ void onOpen(const LLSD& key);
- /*virtual*/ void handleReshape(const LLRect& new_rect, bool by_user = false);
-
- static LLFloater* create(const LLSD& key);
-
-private:
- void applyPreferredRect();
+ bool matchesKey(const LLSD& key) override;
};
-#endif // LL_LLFLOATERWEBPROFILE_H
-
+#endif // LL_LLFLOATERCLASSIFIED_H
diff --git a/indra/newview/llfloaterdisplayname.cpp b/indra/newview/llfloaterdisplayname.cpp
new file mode 100644
index 0000000000..3b0c67415a
--- /dev/null
+++ b/indra/newview/llfloaterdisplayname.cpp
@@ -0,0 +1,200 @@
+/**
+ * @file llfloaterdisplayname.cpp
+ * @author Leyla Farazha
+ * @brief Implementation of the LLFloaterDisplayName class.
+ *
+ * $LicenseInfo:firstyear=2002&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$
+ */
+
+
+#include "llviewerprecompiledheaders.h"
+#include "llfloaterreg.h"
+#include "llfloater.h"
+
+#include "llnotificationsutil.h"
+#include "llviewerdisplayname.h"
+
+#include "llnotifications.h"
+#include "llfloaterdisplayname.h"
+#include "llavatarnamecache.h"
+
+#include "llagent.h"
+
+
+class LLFloaterDisplayName : public LLFloater
+{
+public:
+ LLFloaterDisplayName(const LLSD& key);
+ virtual ~LLFloaterDisplayName() { }
+ /*virtual*/ BOOL postBuild();
+ void onSave();
+ void onCancel();
+ /*virtual*/ void onOpen(const LLSD& key);
+
+private:
+
+ void onCacheSetName(bool success,
+ const std::string& reason,
+ const LLSD& content);
+};
+
+LLFloaterDisplayName::LLFloaterDisplayName(const LLSD& key) :
+ LLFloater(key)
+{
+}
+
+void LLFloaterDisplayName::onOpen(const LLSD& key)
+{
+ getChild<LLUICtrl>("display_name_editor")->clear();
+ getChild<LLUICtrl>("display_name_confirm")->clear();
+
+ LLAvatarName av_name;
+ LLAvatarNameCache::get(gAgent.getID(), &av_name);
+
+ F64 now_secs = LLDate::now().secondsSinceEpoch();
+
+ if (now_secs < av_name.mNextUpdate)
+ {
+ // ...can't update until some time in the future
+ F64 next_update_local_secs =
+ av_name.mNextUpdate - LLStringOps::getLocalTimeOffset();
+ LLDate next_update_local(next_update_local_secs);
+ // display as "July 18 12:17 PM"
+ std::string next_update_string =
+ next_update_local.toHTTPDateString("%B %d %I:%M %p");
+ getChild<LLUICtrl>("lockout_text")->setTextArg("[TIME]", next_update_string);
+ getChild<LLUICtrl>("lockout_text")->setVisible(true);
+ getChild<LLUICtrl>("save_btn")->setEnabled(false);
+ getChild<LLUICtrl>("display_name_editor")->setEnabled(false);
+ getChild<LLUICtrl>("display_name_confirm")->setEnabled(false);
+ getChild<LLUICtrl>("cancel_btn")->setFocus(TRUE);
+
+ }
+ else
+ {
+ getChild<LLUICtrl>("lockout_text")->setVisible(false);
+ getChild<LLUICtrl>("save_btn")->setEnabled(true);
+ getChild<LLUICtrl>("display_name_editor")->setEnabled(true);
+ getChild<LLUICtrl>("display_name_confirm")->setEnabled(true);
+
+ }
+}
+
+BOOL LLFloaterDisplayName::postBuild()
+{
+ getChild<LLUICtrl>("cancel_btn")->setCommitCallback(boost::bind(&LLFloaterDisplayName::onCancel, this));
+ getChild<LLUICtrl>("save_btn")->setCommitCallback(boost::bind(&LLFloaterDisplayName::onSave, this));
+
+ center();
+
+ return TRUE;
+}
+
+void LLFloaterDisplayName::onCacheSetName(bool success,
+ const std::string& reason,
+ const LLSD& content)
+{
+ if (success)
+ {
+ // Inform the user that the change took place, but will take a while
+ // to percolate.
+ LLSD args;
+ args["DISPLAY_NAME"] = content["display_name"];
+ LLNotificationsUtil::add("SetDisplayNameSuccess", args);
+ return;
+ }
+
+ // Request failed, notify the user
+ std::string error_tag = content["error_tag"].asString();
+ LL_INFOS() << "set name failure error_tag " << error_tag << LL_ENDL;
+
+ // We might have a localized string for this message
+ // error_args will usually be empty from the server.
+ if (!error_tag.empty()
+ && LLNotifications::getInstance()->templateExists(error_tag))
+ {
+ LLNotificationsUtil::add(error_tag);
+ return;
+ }
+
+ // The server error might have a localized message for us
+ std::string lang_code = LLUI::getLanguage();
+ LLSD error_desc = content["error_description"];
+ if (error_desc.has( lang_code ))
+ {
+ LLSD args;
+ args["MESSAGE"] = error_desc[lang_code].asString();
+ LLNotificationsUtil::add("GenericAlert", args);
+ return;
+ }
+
+ // No specific error, throw a generic one
+ LLNotificationsUtil::add("SetDisplayNameFailedGeneric");
+}
+
+void LLFloaterDisplayName::onCancel()
+{
+ setVisible(false);
+}
+
+void LLFloaterDisplayName::onSave()
+{
+ std::string display_name_utf8 = getChild<LLUICtrl>("display_name_editor")->getValue().asString();
+ std::string display_name_confirm = getChild<LLUICtrl>("display_name_confirm")->getValue().asString();
+
+ if (display_name_utf8.compare(display_name_confirm))
+ {
+ LLNotificationsUtil::add("SetDisplayNameMismatch");
+ return;
+ }
+
+ const U32 DISPLAY_NAME_MAX_LENGTH = 31; // characters, not bytes
+ LLWString display_name_wstr = utf8string_to_wstring(display_name_utf8);
+ if (display_name_wstr.size() > DISPLAY_NAME_MAX_LENGTH)
+ {
+ LLSD args;
+ args["LENGTH"] = llformat("%d", DISPLAY_NAME_MAX_LENGTH);
+ LLNotificationsUtil::add("SetDisplayNameFailedLength", args);
+ return;
+ }
+
+ if (LLAvatarNameCache::getInstance()->hasNameLookupURL())
+ {
+ LLViewerDisplayName::set(display_name_utf8,boost::bind(&LLFloaterDisplayName::onCacheSetName, this, _1, _2, _3));
+ }
+ else
+ {
+ LLNotificationsUtil::add("SetDisplayNameFailedGeneric");
+ }
+
+ setVisible(false);
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// LLInspectObjectUtil
+//////////////////////////////////////////////////////////////////////////////
+void LLFloaterDisplayNameUtil::registerFloater()
+{
+ LLFloaterReg::add("display_name", "floater_display_name.xml",
+ &LLFloaterReg::build<LLFloaterDisplayName>);
+}
diff --git a/indra/newview/llpanelme.h b/indra/newview/llfloaterdisplayname.h
index 60e9d4317d..a00bf56712 100644
--- a/indra/newview/llpanelme.h
+++ b/indra/newview/llfloaterdisplayname.h
@@ -1,6 +1,5 @@
/**
- * @file llpanelme.h
- * @brief Side tray "Me" (My Profile) panel
+ * @file llfloaterdisplayname.h
*
* $LicenseInfo:firstyear=2009&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -24,27 +23,16 @@
* $/LicenseInfo$
*/
-#ifndef LL_LLPANELMEPROFILE_H
-#define LL_LLPANELMEPROFILE_H
+#ifndef LLFLOATERDISPLAYNAME_H
+#define LLFLOATERDISPLAYNAME_H
-#include "llpanel.h"
-#include "llpanelprofile.h"
-/**
-* Panel for displaying Agent's Picks and Classifieds panel.
-* LLPanelMe allows user to edit his picks and classifieds.
-*/
-class LLPanelMe : public LLPanelProfile
+namespace LLFloaterDisplayNameUtil
{
- LOG_CLASS(LLPanelMe);
+ // Register with LLFloaterReg
+ void registerFloater();
+}
-public:
- LLPanelMe();
- /*virtual*/ void onOpen(const LLSD& key);
-
- /*virtual*/ BOOL postBuild();
-};
-
-#endif // LL_LLPANELMEPROFILE_H
+#endif
diff --git a/indra/newview/llfloatergesture.cpp b/indra/newview/llfloatergesture.cpp
index 6e326ff3cf..d17889bed1 100644
--- a/indra/newview/llfloatergesture.cpp
+++ b/indra/newview/llfloatergesture.cpp
@@ -122,7 +122,7 @@ LLFloaterGesture::LLFloaterGesture(const LLSD& key)
mObserver = new LLFloaterGestureObserver(this);
LLGestureMgr::instance().addObserver(mObserver);
- mCommitCallbackRegistrar.add("Gesture.Action.ToogleActiveState", boost::bind(&LLFloaterGesture::onActivateBtnClick, this));
+ mCommitCallbackRegistrar.add("Gesture.Action.ToggleActiveState", boost::bind(&LLFloaterGesture::onActivateBtnClick, this));
mCommitCallbackRegistrar.add("Gesture.Action.ShowPreview", boost::bind(&LLFloaterGesture::onClickEdit, this));
mCommitCallbackRegistrar.add("Gesture.Action.CopyPaste", boost::bind(&LLFloaterGesture::onCopyPasteAction, this, _2));
mCommitCallbackRegistrar.add("Gesture.Action.SaveToCOF", boost::bind(&LLFloaterGesture::addToCurrentOutFit, this));
diff --git a/indra/newview/llfloateroutfitsnapshot.cpp b/indra/newview/llfloateroutfitsnapshot.cpp
index dccef88e41..ad5e97e067 100644
--- a/indra/newview/llfloateroutfitsnapshot.cpp
+++ b/indra/newview/llfloateroutfitsnapshot.cpp
@@ -42,7 +42,6 @@
#include "llviewercontrol.h"
#include "lltoolfocus.h"
#include "lltoolmgr.h"
-#include "llwebprofile.h"
///----------------------------------------------------------------------------
/// Local function declarations, constants, enums, and typedefs
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 8d19aa36bb..26ea029cac 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -333,60 +333,59 @@ void LLFloaterPreference::processProperties( void* pData, EAvatarProcessorType t
const LLAvatarData* pAvatarData = static_cast<const LLAvatarData*>( pData );
if (pAvatarData && (gAgent.getID() == pAvatarData->avatar_id) && (pAvatarData->avatar_id != LLUUID::null))
{
- storeAvatarProperties( pAvatarData );
- processProfileProperties( pAvatarData );
+ mAllowPublish = (bool)(pAvatarData->flags & AVATAR_ALLOW_PUBLISH);
+ mAvatarDataInitialized = true;
+ getChild<LLUICtrl>("online_searchresults")->setValue(mAllowPublish);
}
}
}
-void LLFloaterPreference::storeAvatarProperties( const LLAvatarData* pAvatarData )
+void LLFloaterPreference::saveAvatarProperties( void )
{
- if (LLStartUp::getStartupState() == STATE_STARTED)
- {
- mAvatarProperties.avatar_id = pAvatarData->avatar_id;
- mAvatarProperties.image_id = pAvatarData->image_id;
- mAvatarProperties.fl_image_id = pAvatarData->fl_image_id;
- mAvatarProperties.about_text = pAvatarData->about_text;
- mAvatarProperties.fl_about_text = pAvatarData->fl_about_text;
- mAvatarProperties.profile_url = pAvatarData->profile_url;
- mAvatarProperties.flags = pAvatarData->flags;
- mAvatarProperties.allow_publish = pAvatarData->flags & AVATAR_ALLOW_PUBLISH;
+ const bool allowPublish = getChild<LLUICtrl>("online_searchresults")->getValue();
- mAvatarDataInitialized = true;
- }
-}
+ if ((LLStartUp::getStartupState() == STATE_STARTED)
+ && mAvatarDataInitialized
+ && (allowPublish != mAllowPublish))
+ {
+ std::string cap_url = gAgent.getRegionCapability("AgentProfile");
+ if (!cap_url.empty())
+ {
+ mAllowPublish = allowPublish;
-void LLFloaterPreference::processProfileProperties(const LLAvatarData* pAvatarData )
-{
- getChild<LLUICtrl>("online_searchresults")->setValue( (bool)(pAvatarData->flags & AVATAR_ALLOW_PUBLISH) );
+ LLCoros::instance().launch("requestAgentUserInfoCoro",
+ boost::bind(saveAvatarPropertiesCoro, cap_url, allowPublish));
+ }
+ }
}
-void LLFloaterPreference::saveAvatarProperties( void )
+void LLFloaterPreference::saveAvatarPropertiesCoro(const std::string cap_url, bool allow_publish)
{
- const BOOL allowPublish = getChild<LLUICtrl>("online_searchresults")->getValue();
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("put_avatar_properties_coro", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpHeaders::ptr_t httpHeaders;
- if (allowPublish)
- {
- mAvatarProperties.flags |= AVATAR_ALLOW_PUBLISH;
- }
+ LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+ httpOpts->setFollowRedirects(true);
- //
- // NOTE: We really don't want to send the avatar properties unless we absolutely
- // need to so we can avoid the accidental profile reset bug, so, if we're
- // logged in, the avatar data has been initialized and we have a state change
- // for the "allow publish" flag, then set the flag to its new value and send
- // the properties update.
- //
- // NOTE: The only reason we can not remove this update altogether is because of the
- // "allow publish" flag, the last remaining profile setting in the viewer
- // that doesn't exist in the web profile.
- //
- if ((LLStartUp::getStartupState() == STATE_STARTED) && mAvatarDataInitialized && (allowPublish != mAvatarProperties.allow_publish))
- {
- mAvatarProperties.allow_publish = allowPublish;
+ std::string finalUrl = cap_url + "/" + gAgentID.asString();
+ LLSD data;
+ data["allow_publish"] = allow_publish;
- LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesUpdate( &mAvatarProperties );
- }
+ LLSD result = httpAdapter->putAndSuspend(httpRequest, finalUrl, data, httpOpts, httpHeaders);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status)
+ {
+ LL_WARNS("Preferences") << "Failed to put agent information " << data << " for id " << gAgentID << LL_ENDL;
+ return;
+ }
+
+ LL_DEBUGS("Preferences") << "Agent id: " << gAgentID << " Data: " << data << " Result: " << httpResults << LL_ENDL;
}
BOOL LLFloaterPreference::postBuild()
@@ -938,7 +937,7 @@ void LLFloaterPreference::onBtnOK(const LLSD& userdata)
else
{
// Show beep, pop up dialog, etc.
- LL_INFOS() << "Can't close preferences!" << LL_ENDL;
+ LL_INFOS("Preferences") << "Can't close preferences!" << LL_ENDL;
}
LLPanelLogin::updateLocationSelectorsVisibility();
@@ -1793,13 +1792,13 @@ bool LLFloaterPreference::loadFromFilename(const std::string& filename, std::map
if (!LLXMLNode::parseFile(filename, root, NULL))
{
- LL_WARNS() << "Unable to parse file " << filename << LL_ENDL;
+ LL_WARNS("Preferences") << "Unable to parse file " << filename << LL_ENDL;
return false;
}
if (!root->hasName("labels"))
{
- LL_WARNS() << filename << " is not a valid definition file" << LL_ENDL;
+ LL_WARNS("Preferences") << filename << " is not a valid definition file" << LL_ENDL;
return false;
}
@@ -1819,7 +1818,7 @@ bool LLFloaterPreference::loadFromFilename(const std::string& filename, std::map
}
else
{
- LL_WARNS() << filename << " failed to load" << LL_ENDL;
+ LL_WARNS("Preferences") << filename << " failed to load" << LL_ENDL;
return false;
}
@@ -2725,7 +2724,7 @@ bool LLPanelPreferenceControls::addControlTableColumns(const std::string &filena
LLScrollListCtrl::Contents contents;
if (!LLUICtrlFactory::getLayeredXMLNode(filename, xmlNode))
{
- LL_WARNS() << "Failed to load " << filename << LL_ENDL;
+ LL_WARNS("Preferences") << "Failed to load " << filename << LL_ENDL;
return false;
}
LLXUIParser parser;
@@ -2752,7 +2751,7 @@ bool LLPanelPreferenceControls::addControlTableRows(const std::string &filename)
LLScrollListCtrl::Contents contents;
if (!LLUICtrlFactory::getLayeredXMLNode(filename, xmlNode))
{
- LL_WARNS() << "Failed to load " << filename << LL_ENDL;
+ LL_WARNS("Preferences") << "Failed to load " << filename << LL_ENDL;
return false;
}
LLXUIParser parser;
@@ -2858,7 +2857,7 @@ void LLPanelPreferenceControls::populateControlTable()
{
// Either unknown mode or MODE_SAVED_SETTINGS
// It doesn't have UI or actual settings yet
- LL_WARNS() << "Unimplemented mode" << LL_ENDL;
+ LL_WARNS("Preferences") << "Unimplemented mode" << LL_ENDL;
// Searchable columns were removed, mark searchables for an update
LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
@@ -2898,7 +2897,7 @@ void LLPanelPreferenceControls::populateControlTable()
}
else
{
- LL_WARNS() << "Unimplemented mode" << LL_ENDL;
+ LL_WARNS("Preferences") << "Unimplemented mode" << LL_ENDL;
}
// explicit update to make sure table is ready for llsearchableui
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index 5ef2ca68d3..542df18ddb 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -100,9 +100,8 @@ public:
static void updateShowFavoritesCheckbox(bool val);
void processProperties( void* pData, EAvatarProcessorType type );
- void processProfileProperties(const LLAvatarData* pAvatarData );
- void storeAvatarProperties( const LLAvatarData* pAvatarData );
void saveAvatarProperties( void );
+ static void saveAvatarPropertiesCoro(const std::string url, bool allow_publish);
void selectPrivacyPanel();
void selectChatPanel();
void getControlNames(std::vector<std::string>& names);
@@ -213,7 +212,7 @@ private:
bool mOriginalHideOnlineStatus;
std::string mDirectoryVisibility;
- LLAvatarData mAvatarProperties;
+ bool mAllowPublish; // Allow showing agent in search
std::string mSavedCameraPreset;
std::string mSavedGraphicsPreset;
LOG_CLASS(LLFloaterPreference);
diff --git a/indra/newview/llfloaterprofile.cpp b/indra/newview/llfloaterprofile.cpp
new file mode 100644
index 0000000000..6ccdace6c5
--- /dev/null
+++ b/indra/newview/llfloaterprofile.cpp
@@ -0,0 +1,170 @@
+/**
+ * @file llfloaterprofile.cpp
+ * @brief Avatar profile floater.
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, 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 "llfloaterprofile.h"
+
+#include "llagent.h" //gAgent
+#include "llnotificationsutil.h"
+#include "llpanelavatar.h"
+#include "llpanelprofile.h"
+
+static const std::string PANEL_PROFILE_VIEW = "panel_profile_view";
+
+LLFloaterProfile::LLFloaterProfile(const LLSD& key)
+ : LLFloater(key),
+ mAvatarId(key["id"].asUUID()),
+ mNameCallbackConnection()
+{
+ mDefaultRectForGroup = false;
+}
+
+LLFloaterProfile::~LLFloaterProfile()
+{
+ if (mNameCallbackConnection.connected())
+ {
+ mNameCallbackConnection.disconnect();
+ }
+}
+
+void LLFloaterProfile::onOpen(const LLSD& key)
+{
+ mPanelProfile->onOpen(key);
+
+ // Update the avatar name.
+ mNameCallbackConnection = LLAvatarNameCache::get(mAvatarId, boost::bind(&LLFloaterProfile::onAvatarNameCache, this, _1, _2));
+}
+
+BOOL LLFloaterProfile::postBuild()
+{
+ mPanelProfile = findChild<LLPanelProfile>(PANEL_PROFILE_VIEW);
+
+ return TRUE;
+}
+
+void LLFloaterProfile::onClickCloseBtn(bool app_quitting)
+{
+ if (!app_quitting)
+ {
+ if (mPanelProfile->hasUnpublishedClassifieds())
+ {
+ LLNotificationsUtil::add("ProfileUnpublishedClassified", LLSD(), LLSD(),
+ boost::bind(&LLFloaterProfile::onUnsavedChangesCallback, this, _1, _2, false));
+ }
+ else if (mPanelProfile->hasUnsavedChanges())
+ {
+ LLNotificationsUtil::add("ProfileUnsavedChanges", LLSD(), LLSD(),
+ boost::bind(&LLFloaterProfile::onUnsavedChangesCallback, this, _1, _2, true));
+ }
+ else
+ {
+ closeFloater();
+ }
+ }
+ else
+ {
+ closeFloater();
+ }
+}
+
+void LLFloaterProfile::onUnsavedChangesCallback(const LLSD& notification, const LLSD& response, bool can_save)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (can_save)
+ {
+ // savable content
+
+ if (option == 0) // Save
+ {
+ mPanelProfile->commitUnsavedChanges();
+ closeFloater();
+ }
+ if (option == 1) // Discard
+ {
+ closeFloater();
+ }
+ // else cancel
+ }
+ else
+ {
+ // classifieds
+
+ if (option == 0) // Ok
+ {
+ closeFloater();
+ }
+ // else cancel
+ }
+
+}
+
+void LLFloaterProfile::createPick(const LLPickData &data)
+{
+ mPanelProfile->createPick(data);
+}
+
+void LLFloaterProfile::showPick(const LLUUID& pick_id)
+{
+ mPanelProfile->showPick(pick_id);
+}
+
+bool LLFloaterProfile::isPickTabSelected()
+{
+ return mPanelProfile->isPickTabSelected();
+}
+
+void LLFloaterProfile::refreshName()
+{
+ if (!mNameCallbackConnection.connected())
+ {
+ mNameCallbackConnection = LLAvatarNameCache::get(mAvatarId, boost::bind(&LLFloaterProfile::onAvatarNameCache, this, _1, _2));
+ }
+
+ LLPanelProfileSecondLife *panel = findChild<LLPanelProfileSecondLife>("panel_profile_secondlife");
+ if (panel)
+ {
+ panel->refreshName();
+ }
+}
+
+void LLFloaterProfile::showClassified(const LLUUID& classified_id, bool edit)
+{
+ mPanelProfile->showClassified(classified_id, edit);
+}
+
+void LLFloaterProfile::createClassified()
+{
+ mPanelProfile->createClassified();
+}
+
+void LLFloaterProfile::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name)
+{
+ mNameCallbackConnection.disconnect();
+ setTitle(av_name.getCompleteName());
+}
+
+// eof
diff --git a/indra/newview/llfloaterprofile.h b/indra/newview/llfloaterprofile.h
new file mode 100644
index 0000000000..b3ed02fc2c
--- /dev/null
+++ b/indra/newview/llfloaterprofile.h
@@ -0,0 +1,66 @@
+/**
+ * @file llfloaterprofile.h
+ * @brief Avatar profile floater.
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, 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_LLFLOATERPROFILE_H
+#define LL_LLFLOATERPROFILE_H
+
+#include "llavatarnamecache.h"
+#include "llavatarpropertiesprocessor.h"
+#include "llfloater.h"
+
+class LLPanelProfile;
+
+class LLFloaterProfile : public LLFloater
+{
+ LOG_CLASS(LLFloaterProfile);
+public:
+ LLFloaterProfile(const LLSD& key);
+ virtual ~LLFloaterProfile();
+
+ BOOL postBuild() override;
+
+ void onOpen(const LLSD& key) override;
+ void onClickCloseBtn(bool app_quitting = false) override;
+ void onUnsavedChangesCallback(const LLSD& notification, const LLSD& response, bool can_save);
+
+ void createPick(const LLPickData &data);
+ void showPick(const LLUUID& pick_id = LLUUID::null);
+ bool isPickTabSelected();
+ void refreshName();
+
+ void showClassified(const LLUUID& classified_id = LLUUID::null, bool edit = false);
+ void createClassified();
+
+private:
+ LLAvatarNameCache::callback_connection_t mNameCallbackConnection;
+ void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
+
+ LLPanelProfile* mPanelProfile;
+
+ LLUUID mAvatarId;
+};
+
+#endif // LL_LLFLOATERPROFILE_H
diff --git a/indra/newview/llfloaterprofiletexture.cpp b/indra/newview/llfloaterprofiletexture.cpp
new file mode 100644
index 0000000000..bf1f56a6d1
--- /dev/null
+++ b/indra/newview/llfloaterprofiletexture.cpp
@@ -0,0 +1,223 @@
+/**
+ * @file llfloaterprofiletexture.cpp
+ * @brief LLFloaterProfileTexture class implementation
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, 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 "llfloaterprofiletexture.h"
+
+#include "llbutton.h"
+#include "llfloaterreg.h"
+#include "llpreview.h" // fors constants
+#include "lltrans.h"
+#include "llviewercontrol.h"
+#include "lltextureview.h"
+#include "llviewertexture.h"
+#include "llviewertexturelist.h"
+
+
+
+LLFloaterProfileTexture::LLFloaterProfileTexture(LLView* owner)
+ : LLFloater(LLSD())
+ , mUpdateDimensions(TRUE)
+ , mLastHeight(0)
+ , mLastWidth(0)
+ , mImage(NULL)
+ , mImageOldBoostLevel(LLGLTexture::BOOST_NONE)
+ , mOwnerHandle(owner->getHandle())
+{
+ buildFromFile("floater_profile_texture.xml");
+}
+
+LLFloaterProfileTexture::~LLFloaterProfileTexture()
+{
+ if (mImage.notNull())
+ {
+ mImage->setBoostLevel(mImageOldBoostLevel);
+ mImage = NULL;
+ }
+}
+
+// virtual
+BOOL LLFloaterProfileTexture::postBuild()
+{
+ mProfileIcon = getChild<LLIconCtrl>("profile_pic");
+
+ mCloseButton = getChild<LLButton>("close_btn");
+ mCloseButton->setCommitCallback([this](LLUICtrl*, void*) { closeFloater(); }, nullptr);
+
+ return TRUE;
+}
+
+// virtual
+void LLFloaterProfileTexture::reshape(S32 width, S32 height, BOOL called_from_parent)
+{
+ LLFloater::reshape(width, height, called_from_parent);
+}
+
+// It takes a while until we get height and width information.
+// When we receive it, reshape the window accordingly.
+void LLFloaterProfileTexture::updateDimensions()
+{
+ if (mImage.isNull())
+ {
+ return;
+ }
+ if ((mImage->getFullWidth() * mImage->getFullHeight()) == 0)
+ {
+ return;
+ }
+
+ S32 img_width = mImage->getFullWidth();
+ S32 img_height = mImage->getFullHeight();
+
+ if (mAssetStatus != LLPreview::PREVIEW_ASSET_LOADED
+ || mLastWidth != img_width
+ || mLastHeight != img_height)
+ {
+ mAssetStatus = LLPreview::PREVIEW_ASSET_LOADED;
+ // Asset has been fully loaded
+ mUpdateDimensions = TRUE;
+ }
+
+ mLastHeight = img_height;
+ mLastWidth = img_width;
+
+ // Reshape the floater only when required
+ if (mUpdateDimensions)
+ {
+ mUpdateDimensions = FALSE;
+
+ LLRect old_floater_rect = getRect();
+ LLRect old_image_rect = mProfileIcon->getRect();
+ S32 width = old_floater_rect.getWidth() - old_image_rect.getWidth() + mLastWidth;
+ S32 height = old_floater_rect.getHeight() - old_image_rect.getHeight() + mLastHeight;
+
+ const F32 MAX_DIMENTIONS = 512; // most profiles are supposed to be 256x256
+
+ S32 biggest_dim = llmax(width, height);
+ if (biggest_dim > MAX_DIMENTIONS)
+ {
+ F32 scale_down = MAX_DIMENTIONS / (F32)biggest_dim;
+ width *= scale_down;
+ height *= scale_down;
+ }
+
+ //reshape floater
+ reshape(width, height);
+
+ gFloaterView->adjustToFitScreen(this, FALSE);
+ }
+}
+
+void LLFloaterProfileTexture::draw()
+{
+ // drawFrustum
+ LLView *owner = mOwnerHandle.get();
+ static LLCachedControl<F32> max_opacity(gSavedSettings, "PickerContextOpacity", 0.4f);
+ drawConeToOwner(mContextConeOpacity, max_opacity, owner);
+
+ LLFloater::draw();
+}
+
+void LLFloaterProfileTexture::onOpen(const LLSD& key)
+{
+ mCloseButton->setFocus(true);
+}
+
+void LLFloaterProfileTexture::resetAsset()
+{
+ mProfileIcon->setValue("Generic_Person_Large");
+ mImageID = LLUUID::null;
+ if (mImage.notNull())
+ {
+ mImage->setBoostLevel(mImageOldBoostLevel);
+ mImage = NULL;
+ }
+}
+void LLFloaterProfileTexture::loadAsset(const LLUUID &image_id)
+{
+ if (mImageID != image_id)
+ {
+ if (mImage.notNull())
+ {
+ mImage->setBoostLevel(mImageOldBoostLevel);
+ mImage = NULL;
+ }
+ }
+ else
+ {
+ return;
+ }
+
+ mProfileIcon->setValue(image_id);
+ mImageID = image_id;
+ mImage = LLViewerTextureManager::getFetchedTexture(mImageID, FTT_DEFAULT, MIPMAP_TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+ mImageOldBoostLevel = mImage->getBoostLevel();
+
+ if ((mImage->getFullWidth() * mImage->getFullHeight()) == 0)
+ {
+ mImage->setLoadedCallback(LLFloaterProfileTexture::onTextureLoaded,
+ 0, TRUE, FALSE, new LLHandle<LLFloater>(getHandle()), &mCallbackTextureList);
+
+ mImage->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
+ mAssetStatus = LLPreview::PREVIEW_ASSET_LOADING;
+ }
+ else
+ {
+ mAssetStatus = LLPreview::PREVIEW_ASSET_LOADED;
+ }
+
+ mUpdateDimensions = TRUE;
+ updateDimensions();
+}
+
+// static
+void LLFloaterProfileTexture::onTextureLoaded(
+ BOOL success,
+ LLViewerFetchedTexture *src_vi,
+ LLImageRaw* src,
+ LLImageRaw* aux_src,
+ S32 discard_level,
+ BOOL final,
+ void* userdata)
+{
+ LLHandle<LLFloater>* handle = (LLHandle<LLFloater>*)userdata;
+
+ if (!handle->isDead())
+ {
+ LLFloaterProfileTexture* floater = static_cast<LLFloaterProfileTexture*>(handle->get());
+ if (floater && success)
+ {
+ floater->mUpdateDimensions = TRUE;
+ floater->updateDimensions();
+ }
+ }
+
+ if (final || !success)
+ {
+ delete handle;
+ }
+}
diff --git a/indra/newview/llfloaterprofiletexture.h b/indra/newview/llfloaterprofiletexture.h
new file mode 100644
index 0000000000..66a61213dd
--- /dev/null
+++ b/indra/newview/llfloaterprofiletexture.h
@@ -0,0 +1,81 @@
+/**
+ * @file llfloaterprofiletexture.h
+ * @brief LLFloaterProfileTexture class definition
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, 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_LLFLOATERPROFILETEXTURE_H
+#define LL_LLFLOATERPROFILETEXTURE_H
+
+#include "llfloater.h"
+#include "llviewertexture.h"
+
+class LLButton;
+class LLImageRaw;
+class LLIconCtrl;
+
+class LLFloaterProfileTexture : public LLFloater
+{
+public:
+ LLFloaterProfileTexture(LLView* owner);
+ ~LLFloaterProfileTexture();
+
+ void draw() override;
+ void onOpen(const LLSD& key) override;
+
+ void resetAsset();
+ void loadAsset(const LLUUID &image_id);
+
+
+ static void onTextureLoaded(
+ BOOL success,
+ LLViewerFetchedTexture *src_vi,
+ LLImageRaw* src,
+ LLImageRaw* aux_src,
+ S32 discard_level,
+ BOOL final,
+ void* userdata);
+
+ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE) override;
+protected:
+ BOOL postBuild() override;
+
+private:
+ void updateDimensions();
+
+ LLUUID mImageID;
+ LLPointer<LLViewerFetchedTexture> mImage;
+ S32 mImageOldBoostLevel;
+ S32 mAssetStatus;
+ F32 mContextConeOpacity;
+ S32 mLastHeight;
+ S32 mLastWidth;
+ BOOL mUpdateDimensions;
+
+ LLHandle<LLView> mOwnerHandle;
+ LLIconCtrl* mProfileIcon;
+ LLButton* mCloseButton;
+
+ LLLoadedCallbackEntry::source_callback_list_t mCallbackTextureList;
+};
+#endif // LL_LLFLOATERPROFILETEXTURE_H
diff --git a/indra/newview/llfloatervoicevolume.cpp b/indra/newview/llfloatervoicevolume.cpp
index 59e1f49f81..23f19dd5aa 100644
--- a/indra/newview/llfloatervoicevolume.cpp
+++ b/indra/newview/llfloatervoicevolume.cpp
@@ -127,7 +127,7 @@ void LLFloaterVoiceVolume::onOpen(const LLSD& data)
// Extract appropriate avatar id
mAvatarID = data["avatar_id"];
- LLUI::getInstance()->positionViewNearMouse(this);
+ LLInspect::repositionInspector(data);
getChild<LLUICtrl>("avatar_name")->setValue("");
updateVolumeControls();
diff --git a/indra/newview/llfloaterwebprofile.cpp b/indra/newview/llfloaterwebprofile.cpp
deleted file mode 100644
index 891bb90c0e..0000000000
--- a/indra/newview/llfloaterwebprofile.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-/**
- * @file llfloaterwebprofile.cpp
- * @brief Avatar profile floater.
- *
- * $LicenseInfo:firstyear=2009&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$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llfloaterwebprofile.h"
-
-#include "llviewercontrol.h"
-
-LLFloaterWebProfile::LLFloaterWebProfile(const Params& key) :
- LLFloaterWebContent(key)
-{
-}
-
-void LLFloaterWebProfile::onOpen(const LLSD& key)
-{
- Params p(key);
- p.show_chrome(true);
- p.window_class("profile");
- p.allow_address_entry(false);
- p.trusted_content(true);
- LLFloaterWebContent::onOpen(p);
- applyPreferredRect();
-}
-
-// virtual
-void LLFloaterWebProfile::handleReshape(const LLRect& new_rect, bool by_user)
-{
- LL_DEBUGS() << "handleReshape: " << new_rect << LL_ENDL;
-
- if (by_user && !isMinimized())
- {
- LL_DEBUGS() << "Storing new rect" << LL_ENDL;
- gSavedSettings.setRect("WebProfileFloaterRect", new_rect);
- }
-
- LLFloaterWebContent::handleReshape(new_rect, by_user);
-}
-
-LLFloater* LLFloaterWebProfile::create(const LLSD& key)
-{
- LLFloaterWebContent::Params p(key);
- preCreate(p);
- return new LLFloaterWebProfile(p);
-}
-
-void LLFloaterWebProfile::applyPreferredRect()
-{
- const LLRect preferred_rect = gSavedSettings.getRect("WebProfileFloaterRect");
- LL_DEBUGS() << "Applying preferred rect: " << preferred_rect << LL_ENDL;
-
- // Don't override position that may have been set by floater stacking code.
- LLRect new_rect = getRect();
- new_rect.setLeftTopAndSize(
- new_rect.mLeft, new_rect.mTop,
- preferred_rect.getWidth(), preferred_rect.getHeight());
- setShape(new_rect);
-}
diff --git a/indra/newview/llgrouplist.cpp b/indra/newview/llgrouplist.cpp
index 62414d3bbb..32af2592d3 100644
--- a/indra/newview/llgrouplist.cpp
+++ b/indra/newview/llgrouplist.cpp
@@ -45,7 +45,6 @@
#include "llvoiceclient.h"
static LLDefaultChildRegistry::Register<LLGroupList> r("group_list");
-S32 LLGroupListItem::sIconWidth = 0;
class LLGroupComparator : public LLFlatListView::ItemComparator
{
@@ -65,21 +64,81 @@ public:
}
};
-static const LLGroupComparator GROUP_COMPARATOR;
+class LLSharedGroupComparator : public LLFlatListView::ItemComparator
+{
+public:
+ LLSharedGroupComparator() {};
+
+ /*virtual*/ bool compare(const LLPanel* item1, const LLPanel* item2) const
+ {
+ const LLGroupListItem* group_item1 = static_cast<const LLGroupListItem*>(item1);
+ std::string name1 = group_item1->getGroupName();
+ bool item1_shared = gAgent.isInGroup(group_item1->getGroupID(), true);
+
+ const LLGroupListItem* group_item2 = static_cast<const LLGroupListItem*>(item2);
+ std::string name2 = group_item2->getGroupName();
+ bool item2_shared = gAgent.isInGroup(group_item2->getGroupID(), true);
+ if (item2_shared != item1_shared)
+ {
+ return item1_shared;
+ }
+
+ LLStringUtil::toUpper(name1);
+ LLStringUtil::toUpper(name2);
+
+ return name1 < name2;
+ }
+};
+
+static LLGroupComparator GROUP_COMPARATOR;
+static LLSharedGroupComparator SHARED_GROUP_COMPARATOR;
+
+LLGroupList::Params::Params()
+: for_agent("for_agent", true)
+{
+}
LLGroupList::LLGroupList(const Params& p)
: LLFlatListViewEx(p)
+ , mForAgent(p.for_agent)
, mDirty(true) // to force initial update
+ , mShowIcons(false)
+ , mShowNone(true)
{
- // Listen for agent group changes.
- gAgent.addListener(this, "new group");
-
- mShowIcons = gSavedSettings.getBOOL("GroupListShowIcons");
setCommitOnSelectionChange(true);
// Set default sort order.
- setComparator(&GROUP_COMPARATOR);
+ if (mForAgent)
+ {
+ setComparator(&GROUP_COMPARATOR);
+ }
+ else
+ {
+ // shared groups first
+ setComparator(&SHARED_GROUP_COMPARATOR);
+ }
+
+ if (mForAgent)
+ {
+ enableForAgent(true);
+ }
+}
+
+LLGroupList::~LLGroupList()
+{
+ if (mForAgent) gAgent.removeListener(this);
+ if (mContextMenuHandle.get()) mContextMenuHandle.get()->die();
+}
+
+void LLGroupList::enableForAgent(bool show_icons)
+{
+ mForAgent = true;
+
+ mShowIcons = mForAgent && gSavedSettings.getBOOL("GroupListShowIcons") && show_icons;
+
+ // Listen for agent group changes.
+ gAgent.addListener(this, "new group");
// Set up context menu.
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
@@ -94,12 +153,6 @@ LLGroupList::LLGroupList(const Params& p)
mContextMenuHandle = context_menu->getHandle();
}
-LLGroupList::~LLGroupList()
-{
- gAgent.removeListener(this);
- if (mContextMenuHandle.get()) mContextMenuHandle.get()->die();
-}
-
// virtual
void LLGroupList::draw()
{
@@ -114,12 +167,15 @@ BOOL LLGroupList::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
BOOL handled = LLUICtrl::handleRightMouseDown(x, y, mask);
- LLToggleableMenu* context_menu = mContextMenuHandle.get();
- if (context_menu && size() > 0)
- {
- context_menu->buildDrawLabels();
- context_menu->updateParent(LLMenuGL::sMenuContainer);
- LLMenuGL::showPopup(this, context_menu, x, y);
+ if (mForAgent)
+ {
+ LLToggleableMenu* context_menu = mContextMenuHandle.get();
+ if (context_menu && size() > 0)
+ {
+ context_menu->buildDrawLabels();
+ context_menu->updateParent(LLMenuGL::sMenuContainer);
+ LLMenuGL::showPopup(this, context_menu, x, y);
+ }
}
return handled;
@@ -132,7 +188,7 @@ BOOL LLGroupList::handleDoubleClick(S32 x, S32 y, MASK mask)
// Handle double click only for the selected item in the list, skip clicks on empty space.
if (handled)
{
- if (mDoubleClickSignal)
+ if (mDoubleClickSignal && getItemsRect().pointInRect(x, y))
{
(*mDoubleClickSignal)(this, x, y, mask);
}
@@ -164,34 +220,49 @@ static bool findInsensitive(std::string haystack, const std::string& needle_uppe
void LLGroupList::refresh()
{
- const LLUUID& highlight_id = gAgent.getGroupID();
- S32 count = gAgent.mGroups.size();
- LLUUID id;
- bool have_filter = !mNameFilter.empty();
-
- clear();
-
- for(S32 i = 0; i < count; ++i)
- {
- id = gAgent.mGroups.at(i).mID;
- const LLGroupData& group_data = gAgent.mGroups.at(i);
- if (have_filter && !findInsensitive(group_data.mName, mNameFilter))
- continue;
- addNewItem(id, group_data.mName, group_data.mInsigniaID, ADD_BOTTOM);
- }
-
- // Sort the list.
- sort();
-
- // Add "none" to list at top if filter not set (what's the point of filtering "none"?).
- // but only if some real groups exists. EXT-4838
- if (!have_filter && count > 0)
- {
- std::string loc_none = LLTrans::getString("GroupsNone");
- addNewItem(LLUUID::null, loc_none, LLUUID::null, ADD_TOP);
- }
-
- selectItemByUUID(highlight_id);
+ if (mForAgent)
+ {
+ const LLUUID& highlight_id = gAgent.getGroupID();
+ S32 count = gAgent.mGroups.size();
+ LLUUID id;
+ bool have_filter = !mNameFilter.empty();
+
+ clear();
+
+ for(S32 i = 0; i < count; ++i)
+ {
+ id = gAgent.mGroups.at(i).mID;
+ const LLGroupData& group_data = gAgent.mGroups.at(i);
+ if (have_filter && !findInsensitive(group_data.mName, mNameFilter))
+ continue;
+ addNewItem(id, group_data.mName, group_data.mInsigniaID, ADD_BOTTOM, group_data.mListInProfile);
+ }
+
+ // Sort the list.
+ sort();
+
+ // Add "none" to list at top if filter not set (what's the point of filtering "none"?).
+ // but only if some real groups exists. EXT-4838
+ if (!have_filter && count > 0 && mShowNone)
+ {
+ std::string loc_none = LLTrans::getString("GroupsNone");
+ addNewItem(LLUUID::null, loc_none, LLUUID::null, ADD_TOP);
+ }
+
+ selectItemByUUID(highlight_id);
+ }
+ else
+ {
+ clear();
+
+ for (group_map_t::iterator it = mGroups.begin(); it != mGroups.end(); ++it)
+ {
+ addNewItem(it->second, it->first, LLUUID::null, ADD_BOTTOM);
+ }
+
+ // Sort the list.
+ sort();
+ }
setDirty(false);
onCommit();
@@ -212,13 +283,19 @@ void LLGroupList::toggleIcons()
}
}
+void LLGroupList::setGroups(const std::map< std::string,LLUUID> group_list)
+{
+ mGroups = group_list;
+ setDirty(true);
+}
+
//////////////////////////////////////////////////////////////////////////
// PRIVATE Section
//////////////////////////////////////////////////////////////////////////
-void LLGroupList::addNewItem(const LLUUID& id, const std::string& name, const LLUUID& icon_id, EAddPosition pos)
+void LLGroupList::addNewItem(const LLUUID& id, const std::string& name, const LLUUID& icon_id, EAddPosition pos, bool visible_in_profile)
{
- LLGroupListItem* item = new LLGroupListItem();
+ LLGroupListItem* item = new LLGroupListItem(mForAgent, mShowIcons);
item->setGroupID(id);
item->setName(name, mNameFilter);
@@ -227,7 +304,10 @@ void LLGroupList::addNewItem(const LLUUID& id, const std::string& name, const LL
item->getChildView("info_btn")->setVisible( false);
item->getChildView("profile_btn")->setVisible( false);
item->setGroupIconVisible(mShowIcons);
-
+ if (!mShowIcons)
+ {
+ item->setVisibleInProfile(visible_in_profile);
+ }
addItem(item, id, pos);
// setCommentVisible(false);
@@ -243,6 +323,29 @@ bool LLGroupList::handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD&
return true;
}
+ if (event->desc() == "value_changed")
+ {
+ LLSD data = event->getValue();
+ if (data.has("group_id") && data.has("visible"))
+ {
+ LLUUID group_id = data["group_id"].asUUID();
+ bool visible = data["visible"].asBoolean();
+
+ std::vector<LLPanel*> items;
+ getItems(items);
+ for (std::vector<LLPanel*>::iterator it = items.begin(); it != items.end(); ++it)
+ {
+ LLGroupListItem* item = dynamic_cast<LLGroupListItem*>(*it);
+ if (item && item->getGroupID() == group_id)
+ {
+ item->setVisibleInProfile(visible);
+ break;
+ }
+ }
+ }
+ return true;
+ }
+
return false;
}
@@ -294,21 +397,25 @@ bool LLGroupList::onContextMenuItemEnable(const LLSD& userdata)
/* LLGroupListItem implementation */
/************************************************************************/
-LLGroupListItem::LLGroupListItem()
+LLGroupListItem::LLGroupListItem(bool for_agent, bool show_icons)
: LLPanel(),
mGroupIcon(NULL),
mGroupNameBox(NULL),
mInfoBtn(NULL),
-mGroupID(LLUUID::null)
+mProfileBtn(NULL),
+mVisibilityHideBtn(NULL),
+mVisibilityShowBtn(NULL),
+mGroupID(LLUUID::null),
+mForAgent(for_agent)
{
- buildFromFile( "panel_group_list_item.xml");
-
- // Remember group icon width including its padding from the name text box,
- // so that we can hide and show the icon again later.
- if (!sIconWidth)
- {
- sIconWidth = mGroupNameBox->getRect().mLeft - mGroupIcon->getRect().mLeft;
- }
+ if (show_icons)
+ {
+ buildFromFile( "panel_group_list_item.xml");
+ }
+ else
+ {
+ buildFromFile( "panel_group_list_item_short.xml");
+ }
}
LLGroupListItem::~LLGroupListItem()
@@ -325,7 +432,25 @@ BOOL LLGroupListItem::postBuild()
mInfoBtn = getChild<LLButton>("info_btn");
mInfoBtn->setClickedCallback(boost::bind(&LLGroupListItem::onInfoBtnClick, this));
- childSetAction("profile_btn", boost::bind(&LLGroupListItem::onProfileBtnClick, this));
+ mProfileBtn = getChild<LLButton>("profile_btn");
+ mProfileBtn->setClickedCallback([this](LLUICtrl *, const LLSD &) { onProfileBtnClick(); });
+
+ mVisibilityHideBtn = findChild<LLButton>("visibility_hide_btn");
+ if (mVisibilityHideBtn)
+ {
+ mVisibilityHideBtn->setClickedCallback([this](LLUICtrl *, const LLSD &) { onVisibilityBtnClick(false); });
+ }
+ mVisibilityShowBtn = findChild<LLButton>("visibility_show_btn");
+ if (mVisibilityShowBtn)
+ {
+ mVisibilityShowBtn->setClickedCallback([this](LLUICtrl *, const LLSD &) { onVisibilityBtnClick(true); });
+ }
+
+ // Remember group icon width including its padding from the name text box,
+ // so that we can hide and show the icon again later.
+ // Also note that panel_group_list_item and panel_group_list_item_short
+ // have icons of different sizes so we need to figure it per file.
+ mIconWidth = mGroupNameBox->getRect().mLeft - mGroupIcon->getRect().mLeft;
return TRUE;
}
@@ -344,7 +469,16 @@ void LLGroupListItem::onMouseEnter(S32 x, S32 y, MASK mask)
if (mGroupID.notNull()) // don't show the info button for the "none" group
{
mInfoBtn->setVisible(true);
- getChildView("profile_btn")->setVisible( true);
+ mProfileBtn->setVisible(true);
+ if (mForAgent && mVisibilityHideBtn)
+ {
+ LLGroupData agent_gdatap;
+ if (gAgent.getGroupData(mGroupID, agent_gdatap))
+ {
+ mVisibilityHideBtn->setVisible(agent_gdatap.mListInProfile);
+ mVisibilityShowBtn->setVisible(!agent_gdatap.mListInProfile);
+ }
+ }
}
LLPanel::onMouseEnter(x, y, mask);
@@ -354,7 +488,12 @@ void LLGroupListItem::onMouseLeave(S32 x, S32 y, MASK mask)
{
getChildView("hovered_icon")->setVisible( false);
mInfoBtn->setVisible(false);
- getChildView("profile_btn")->setVisible( false);
+ mProfileBtn->setVisible(false);
+ if (mVisibilityHideBtn)
+ {
+ mVisibilityHideBtn->setVisible(false);
+ mVisibilityShowBtn->setVisible(false);
+ }
LLPanel::onMouseLeave(x, y, mask);
}
@@ -372,7 +511,17 @@ void LLGroupListItem::setGroupID(const LLUUID& group_id)
mID = group_id;
mGroupID = group_id;
- setActive(group_id == gAgent.getGroupID());
+
+ if (mForAgent)
+ {
+ // Active group should be bold.
+ setBold(group_id == gAgent.getGroupID());
+ }
+ else
+ {
+ // Groups shared with the agent should be bold
+ setBold(gAgent.isInGroup(group_id, true));
+ }
LLGroupMgr::getInstance()->addObserver(this);
}
@@ -393,24 +542,28 @@ void LLGroupListItem::setGroupIconVisible(bool visible)
// Move the group name horizontally by icon size + its distance from the group name.
LLRect name_rect = mGroupNameBox->getRect();
- name_rect.mLeft += visible ? sIconWidth : -sIconWidth;
+ name_rect.mLeft += visible ? mIconWidth : -mIconWidth;
mGroupNameBox->setRect(name_rect);
}
+void LLGroupListItem::setVisibleInProfile(bool visible)
+{
+ mGroupNameBox->setColor(LLUIColorTable::instance().getColor((visible ? "GroupVisibleInProfile" : "GroupHiddenInProfile"), LLColor4::red).get());
+}
+
//////////////////////////////////////////////////////////////////////////
// Private Section
//////////////////////////////////////////////////////////////////////////
-void LLGroupListItem::setActive(bool active)
+void LLGroupListItem::setBold(bool bold)
{
// *BUG: setName() overrides the style params.
- // Active group should be bold.
LLFontDescriptor new_desc(mGroupNameBox->getFont()->getFontDesc());
// *NOTE dzaporozhan
// On Windows LLFontGL::NORMAL will not remove LLFontGL::BOLD if font
// is predefined as bold (SansSerifSmallBold, for example)
- new_desc.setStyle(active ? LLFontGL::BOLD : LLFontGL::NORMAL);
+ new_desc.setStyle(bold ? LLFontGL::BOLD : LLFontGL::NORMAL);
LLFontGL* new_font = LLFontGL::getFont(new_desc);
mGroupNameStyle.font = new_font;
@@ -430,11 +583,25 @@ void LLGroupListItem::onProfileBtnClick()
LLGroupActions::show(mGroupID);
}
+void LLGroupListItem::onVisibilityBtnClick(bool new_visibility)
+{
+ LLGroupData agent_gdatap;
+ if (gAgent.getGroupData(mGroupID, agent_gdatap))
+ {
+ gAgent.setUserGroupFlags(mGroupID, agent_gdatap.mAcceptNotices, new_visibility);
+ setVisibleInProfile(new_visibility);
+ mVisibilityHideBtn->setVisible(new_visibility);
+ mVisibilityShowBtn->setVisible(!new_visibility);
+ }
+}
+
void LLGroupListItem::changed(LLGroupChange gc)
{
LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->getGroupData(mID);
- if(group_data)
- setGroupIconID(group_data->mInsigniaID);
+ if ((gc == GC_ALL || gc == GC_PROPERTIES) && group_data)
+ {
+ setGroupIconID(group_data->mInsigniaID);
+ }
}
//EOF
diff --git a/indra/newview/llgrouplist.h b/indra/newview/llgrouplist.h
index 171b77fb00..5cbabb712f 100644
--- a/indra/newview/llgrouplist.h
+++ b/indra/newview/llgrouplist.h
@@ -50,12 +50,15 @@ class LLGroupList: public LLFlatListViewEx, public LLOldEvents::LLSimpleListener
public:
struct Params : public LLInitParam::Block<Params, LLFlatListViewEx::Params>
{
- Params(){};
+ Optional<bool> for_agent;
+ Params();
};
LLGroupList(const Params& p);
virtual ~LLGroupList();
+ void enableForAgent(bool show_icons);
+
virtual void draw(); // from LLView
/*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); // from LLView
/*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask); // from LLView
@@ -63,13 +66,16 @@ public:
void setNameFilter(const std::string& filter);
void toggleIcons();
bool getIconsVisible() const { return mShowIcons; }
+ void setIconsVisible(bool show_icons) { mShowIcons = show_icons; }
+ void setShowNone(bool show_none) { mShowNone = show_none; }
+ void setGroups(const std::map< std::string,LLUUID> group_list);
LLToggleableMenu* getContextMenu() const { return mContextMenuHandle.get(); }
private:
void setDirty(bool val = true) { mDirty = val; }
void refresh();
- void addNewItem(const LLUUID& id, const std::string& name, const LLUUID& icon_id, EAddPosition pos = ADD_BOTTOM);
+ void addNewItem(const LLUUID& id, const std::string& name, const LLUUID& icon_id, EAddPosition pos = ADD_BOTTOM, bool visible_in_profile = true);
bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata); // called on agent group list changes
bool onContextMenuItemClick(const LLSD& userdata);
@@ -80,6 +86,11 @@ private:
bool mShowIcons;
bool mDirty;
std::string mNameFilter;
+
+ bool mForAgent;
+ bool mShowNone;
+ typedef std::map< std::string,LLUUID> group_map_t;
+ group_map_t mGroups;
};
class LLButton;
@@ -90,7 +101,7 @@ class LLGroupListItem : public LLPanel
, public LLGroupMgrObserver
{
public:
- LLGroupListItem();
+ LLGroupListItem(bool for_agent, bool show_icons);
~LLGroupListItem();
/*virtual*/ BOOL postBuild();
/*virtual*/ void setValue(const LLSD& value);
@@ -106,19 +117,26 @@ public:
void setGroupIconVisible(bool visible);
virtual void changed(LLGroupChange gc);
+
+ void setVisibleInProfile(bool visible);
private:
- void setActive(bool active);
+ void setBold(bool bold);
void onInfoBtnClick();
void onProfileBtnClick();
+ void onVisibilityBtnClick(bool new_visibility);
LLTextBox* mGroupNameBox;
LLUUID mGroupID;
LLGroupIconCtrl* mGroupIcon;
- LLButton* mInfoBtn;
+ LLButton* mInfoBtn;
+ LLButton* mProfileBtn;
+ LLButton* mVisibilityHideBtn;
+ LLButton* mVisibilityShowBtn;
std::string mGroupName;
+ bool mForAgent;
LLStyle::Params mGroupNameStyle;
- static S32 sIconWidth; // icon width + padding
+ S32 mIconWidth;
};
#endif // LL_LLGROUPLIST_H
diff --git a/indra/newview/llinspect.cpp b/indra/newview/llinspect.cpp
index 479e8f9abf..f382b5985f 100644
--- a/indra/newview/llinspect.cpp
+++ b/indra/newview/llinspect.cpp
@@ -147,3 +147,19 @@ bool LLInspect::childHasVisiblePopupMenu()
}
return false;
}
+
+void LLInspect::repositionInspector(const LLSD& data)
+{
+ // Position the inspector relative to the mouse cursor
+ // Similar to how tooltips are positioned
+ // See LLToolTipMgr::createToolTip
+ if (data.has("pos"))
+ {
+ LLUI::getInstance()->positionViewNearMouse(this, data["pos"]["x"].asInteger(), data["pos"]["y"].asInteger());
+ }
+ else
+ {
+ LLUI::getInstance()->positionViewNearMouse(this);
+ }
+ applyRectControl();
+}
diff --git a/indra/newview/llinspect.h b/indra/newview/llinspect.h
index 1f6aafc7bd..6909aa3f16 100644
--- a/indra/newview/llinspect.h
+++ b/indra/newview/llinspect.h
@@ -49,6 +49,8 @@ public:
/// Inspectors close themselves when they lose focus
/*virtual*/ void onFocusLost();
+
+ void repositionInspector(const LLSD& data);
protected:
diff --git a/indra/newview/llinspectavatar.cpp b/indra/newview/llinspectavatar.cpp
index f357899be0..b11c440015 100644
--- a/indra/newview/llinspectavatar.cpp
+++ b/indra/newview/llinspectavatar.cpp
@@ -45,7 +45,6 @@
#include "llfloater.h"
#include "llfloaterreg.h"
#include "lltextbox.h"
-#include "lltooltip.h" // positionViewNearMouse()
#include "lltrans.h"
class LLFetchAvatarData;
@@ -202,17 +201,7 @@ void LLInspectAvatar::onOpen(const LLSD& data)
// Extract appropriate avatar id
mAvatarID = data["avatar_id"];
- // Position the inspector relative to the mouse cursor
- // Similar to how tooltips are positioned
- // See LLToolTipMgr::createToolTip
- if (data.has("pos"))
- {
- LLUI::getInstance()->positionViewNearMouse(this, data["pos"]["x"].asInteger(), data["pos"]["y"].asInteger());
- }
- else
- {
- LLUI::getInstance()->positionViewNearMouse(this);
- }
+ LLInspect::repositionInspector(data);
// Generate link to avatar profile.
LLTextBase* avatar_profile_link = getChild<LLTextBase>("avatar_profile_link");
diff --git a/indra/newview/llinspectgroup.cpp b/indra/newview/llinspectgroup.cpp
index fa8a53c546..0a30ab9217 100644
--- a/indra/newview/llinspectgroup.cpp
+++ b/indra/newview/llinspectgroup.cpp
@@ -38,7 +38,6 @@
#include "llfloater.h"
#include "llfloaterreg.h"
#include "llresmgr.h" // getMonetaryString()
-#include "lltooltip.h" // positionViewNearMouse()
#include "lltrans.h"
#include "lluictrl.h"
#include "llgroupiconctrl.h"
@@ -124,17 +123,7 @@ void LLInspectGroup::onOpen(const LLSD& data)
setGroupID(data["group_id"]);
- // Position the inspector relative to the mouse cursor
- // Similar to how tooltips are positioned
- // See LLToolTipMgr::createToolTip
- if (data.has("pos"))
- {
- LLUI::getInstance()->positionViewNearMouse(this, data["pos"]["x"].asInteger(), data["pos"]["y"].asInteger());
- }
- else
- {
- LLUI::getInstance()->positionViewNearMouse(this);
- }
+ LLInspect::repositionInspector(data);
// can't call from constructor as widgets are not built yet
requestUpdate();
diff --git a/indra/newview/llinspectobject.cpp b/indra/newview/llinspectobject.cpp
index cb7031971b..5329f10612 100644
--- a/indra/newview/llinspectobject.cpp
+++ b/indra/newview/llinspectobject.cpp
@@ -50,7 +50,6 @@
#include "lltextbox.h" // for description truncation
#include "lltoggleablemenu.h"
#include "lltrans.h"
-#include "llui.h" // positionViewNearMouse()
#include "lluictrl.h"
class LLViewerObject;
@@ -198,17 +197,8 @@ void LLInspectObject::onOpen(const LLSD& data)
{
mObjectFace = data["object_face"];
}
- // Position the inspector relative to the mouse cursor
- // Similar to how tooltips are positioned
- // See LLToolTipMgr::createToolTip
- if (data.has("pos"))
- {
- LLUI::getInstance()->positionViewNearMouse(this, data["pos"]["x"].asInteger(), data["pos"]["y"].asInteger());
- }
- else
- {
- LLUI::getInstance()->positionViewNearMouse(this);
- }
+
+ LLInspect::repositionInspector(data);
// Promote hovered object to a complete selection, which will also force
// a request for selected object data off the network
diff --git a/indra/newview/llinspectremoteobject.cpp b/indra/newview/llinspectremoteobject.cpp
index 272c8acbd5..77320510a6 100644
--- a/indra/newview/llinspectremoteobject.cpp
+++ b/indra/newview/llinspectremoteobject.cpp
@@ -111,17 +111,7 @@ void LLInspectRemoteObject::onOpen(const LLSD& data)
// update the inspector with the current object state
update();
- // Position the inspector relative to the mouse cursor
- // Similar to how tooltips are positioned
- // See LLToolTipMgr::createToolTip
- if (data.has("pos"))
- {
- LLUI::getInstance()->positionViewNearMouse(this, data["pos"]["x"].asInteger(), data["pos"]["y"].asInteger());
- }
- else
- {
- LLUI::getInstance()->positionViewNearMouse(this);
- }
+ LLInspect::repositionInspector(data);
}
void LLInspectRemoteObject::onClickMap()
diff --git a/indra/newview/llinspecttoast.cpp b/indra/newview/llinspecttoast.cpp
index d0034eff13..68801b0895 100644
--- a/indra/newview/llinspecttoast.cpp
+++ b/indra/newview/llinspecttoast.cpp
@@ -110,7 +110,7 @@ void LLInspectToast::onOpen(const LLSD& notification_id)
panel_rect = panel->getRect();
reshape(panel_rect.getWidth(), panel_rect.getHeight());
- LLUI::getInstance()->positionViewNearMouse(this);
+ LLInspect::repositionInspector(notification_id);
}
// virtual
diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp
index 5a17332fde..de8db69e19 100644
--- a/indra/newview/lllocalbitmaps.cpp
+++ b/indra/newview/lllocalbitmaps.cpp
@@ -919,6 +919,36 @@ LLLocalBitmapMgr::~LLLocalBitmapMgr()
mBitmapList.clear();
}
+LLUUID LLLocalBitmapMgr::addUnit(const std::string &filename)
+{
+ if (!checkTextureDimensions(filename))
+ {
+ return LLUUID::null;
+ }
+
+ LLLocalBitmap* unit = new LLLocalBitmap(filename);
+
+ if (unit->getValid())
+ {
+ mBitmapList.push_back(unit);
+ return unit->getTrackingID();
+ }
+ else
+ {
+ LL_WARNS() << "Attempted to add invalid or unreadable image file, attempt cancelled.\n"
+ << "Filename: " << filename << LL_ENDL;
+
+ LLSD notif_args;
+ notif_args["FNAME"] = filename;
+ LLNotificationsUtil::add("LocalBitmapsVerifyFail", notif_args);
+
+ delete unit;
+ unit = NULL;
+ }
+
+ return LLUUID::null;
+}
+
bool LLLocalBitmapMgr::addUnit()
{
bool add_successful = false;
@@ -931,32 +961,10 @@ bool LLLocalBitmapMgr::addUnit()
std::string filename = picker.getFirstFile();
while(!filename.empty())
{
- if(!checkTextureDimensions(filename))
- {
- filename = picker.getNextFile();
- continue;
- }
-
- LLLocalBitmap* unit = new LLLocalBitmap(filename);
-
- if (unit->getValid())
- {
- mBitmapList.push_back(unit);
- add_successful = true;
- }
- else
- {
- LL_WARNS() << "Attempted to add invalid or unreadable image file, attempt cancelled.\n"
- << "Filename: " << filename << LL_ENDL;
-
- LLSD notif_args;
- notif_args["FNAME"] = filename;
- LLNotificationsUtil::add("LocalBitmapsVerifyFail", notif_args);
-
- delete unit;
- unit = NULL;
- }
-
+ if (addUnit(filename).notNull())
+ {
+ add_successful = true;
+ }
filename = picker.getNextFile();
}
diff --git a/indra/newview/lllocalbitmaps.h b/indra/newview/lllocalbitmaps.h
index def5a6bd6e..02b8834c16 100644
--- a/indra/newview/lllocalbitmaps.h
+++ b/indra/newview/lllocalbitmaps.h
@@ -116,6 +116,7 @@ class LLLocalBitmapMgr : public LLSingleton<LLLocalBitmapMgr>
~LLLocalBitmapMgr();
public:
bool addUnit();
+ LLUUID addUnit(const std::string &filename);
void delUnit(LLUUID tracking_id);
bool checkTextureDimensions(std::string filename);
diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index 4febb72c6c..f419e2e06d 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -1374,6 +1374,7 @@ void LLOutfitGallery::onSelectPhoto(LLUUID selected_outfit_id)
texture_floaterp->setOnFloaterCommitCallback(boost::bind(&LLOutfitGallery::onTexturePickerCommit, this, _1, _2));
texture_floaterp->setOnUpdateImageStatsCallback(boost::bind(&LLOutfitGallery::onTexturePickerUpdateImageStats, this, _1));
texture_floaterp->setLocalTextureEnabled(FALSE);
+ texture_floaterp->setBakeTextureEnabled(FALSE);
texture_floaterp->setCanApply(false, true);
}
diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp
index 37ed4bc74c..9a030f1d7d 100644
--- a/indra/newview/llpanelavatar.cpp
+++ b/indra/newview/llpanelavatar.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llpanelavatar.cpp
* @brief LLPanelAvatar and related class implementations
*
* $LicenseInfo:firstyear=2004&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$
*/
@@ -28,173 +28,127 @@
#include "llpanelavatar.h"
#include "llagent.h"
-#include "llavataractions.h"
-#include "llcallingcard.h"
-#include "llcombobox.h"
-#include "lldateutil.h" // ageFromDate()
-#include "llimview.h"
-#include "llmenubutton.h"
-#include "llnotificationsutil.h"
-#include "llslurl.h"
-#include "lltexteditor.h"
-#include "lltexturectrl.h"
-#include "lltoggleablemenu.h"
+#include "llloadingindicator.h"
#include "lltooldraganddrop.h"
-#include "llscrollcontainer.h"
-#include "llavatariconctrl.h"
-#include "llfloaterreg.h"
-#include "llnotificationsutil.h"
-#include "llviewermenu.h" // is_agent_mappable
-#include "llvoiceclient.h"
-#include "lltextbox.h"
-#include "lltrans.h"
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Class LLDropTarget
-//
-// This handy class is a simple way to drop something on another
-// view. It handles drop events, always setting itself to the size of
-// its parent.
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-class LLDropTarget : public LLView
-{
-public:
- struct Params : public LLInitParam::Block<Params, LLView::Params>
- {
- Optional<LLUUID> agent_id;
- Params()
- : agent_id("agent_id")
- {
- changeDefault(mouse_opaque, false);
- changeDefault(follows.flags, FOLLOWS_ALL);
- }
- };
-
- LLDropTarget(const Params&);
- ~LLDropTarget();
-
- void doDrop(EDragAndDropType cargo_type, void* cargo_data);
-
- //
- // LLView functionality
- virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
- EDragAndDropType cargo_type,
- void* cargo_data,
- EAcceptance* accept,
- std::string& tooltip_msg);
- void setAgentID(const LLUUID &agent_id) { mAgentID = agent_id; }
-protected:
- LLUUID mAgentID;
-};
-
-LLDropTarget::LLDropTarget(const LLDropTarget::Params& p)
-: LLView(p),
- mAgentID(p.agent_id)
-{}
-LLDropTarget::~LLDropTarget()
+//////////////////////////////////////////////////////////////////////////
+// LLProfileDropTarget
+
+LLProfileDropTarget::LLProfileDropTarget(const LLProfileDropTarget::Params& p)
+: LLView(p),
+ mAgentID(p.agent_id)
{}
-void LLDropTarget::doDrop(EDragAndDropType cargo_type, void* cargo_data)
+void LLProfileDropTarget::doDrop(EDragAndDropType cargo_type, void* cargo_data)
{
- LL_INFOS() << "LLDropTarget::doDrop()" << LL_ENDL;
+ LL_INFOS() << "LLProfileDropTarget::doDrop()" << LL_ENDL;
}
-BOOL LLDropTarget::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
- EDragAndDropType cargo_type,
- void* cargo_data,
- EAcceptance* accept,
- std::string& tooltip_msg)
+BOOL LLProfileDropTarget::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg)
{
- if(getParent())
- {
- LLToolDragAndDrop::handleGiveDragAndDrop(mAgentID, LLUUID::null, drop,
- cargo_type, cargo_data, accept);
+ if (getParent())
+ {
+ LLToolDragAndDrop::handleGiveDragAndDrop(mAgentID, LLUUID::null, drop,
+ cargo_type, cargo_data, accept);
- return TRUE;
- }
+ return TRUE;
+ }
- return FALSE;
+ return FALSE;
}
-static LLDefaultChildRegistry::Register<LLDropTarget> r("drop_target");
+static LLDefaultChildRegistry::Register<LLProfileDropTarget> r("profile_drop_target");
//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
+// LLPanelProfileTab
LLPanelProfileTab::LLPanelProfileTab()
: LLPanel()
, mAvatarId(LLUUID::null)
+, mLoadingState(PROFILE_INIT)
+, mSelfProfile(false)
{
}
LLPanelProfileTab::~LLPanelProfileTab()
{
- if(getAvatarId().notNull())
- {
- LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(),this);
- }
}
-void LLPanelProfileTab::setAvatarId(const LLUUID& id)
+void LLPanelProfileTab::setAvatarId(const LLUUID& avatar_id)
{
- if(id.notNull())
- {
- if(getAvatarId().notNull())
- {
- LLAvatarPropertiesProcessor::getInstance()->removeObserver(mAvatarId,this);
- }
- mAvatarId = id;
- LLAvatarPropertiesProcessor::getInstance()->addObserver(getAvatarId(),this);
- }
+ if (avatar_id.notNull())
+ {
+ mAvatarId = avatar_id;
+ mSelfProfile = (getAvatarId() == gAgentID);
+ }
}
void LLPanelProfileTab::onOpen(const LLSD& key)
{
- // Don't reset panel if we are opening it for same avatar.
- if(getAvatarId() != key.asUUID())
- {
- resetControls();
- resetData();
-
- scrollToTop();
- }
-
- // Update data even if we are viewing same avatar profile as some data might been changed.
- setAvatarId(key.asUUID());
- updateData();
- updateButtons();
+ // Update data even if we are viewing same avatar profile as some data might been changed.
+ setAvatarId(key.asUUID());
+
+ setApplyProgress(true);
+}
+
+void LLPanelProfileTab::setLoaded()
+{
+ setApplyProgress(false);
+
+ mLoadingState = PROFILE_LOADED;
+}
+
+void LLPanelProfileTab::setApplyProgress(bool started)
+{
+ LLLoadingIndicator* indicator = findChild<LLLoadingIndicator>("progress_indicator");
+
+ if (indicator)
+ {
+ indicator->setVisible(started);
+
+ if (started)
+ {
+ indicator->start();
+ }
+ else
+ {
+ indicator->stop();
+ }
+ }
+
+ LLPanel* panel = findChild<LLPanel>("indicator_stack");
+ if (panel)
+ {
+ panel->setVisible(started);
+ }
}
-void LLPanelProfileTab::scrollToTop()
+LLPanelProfilePropertiesProcessorTab::LLPanelProfilePropertiesProcessorTab()
+ : LLPanelProfileTab()
{
- LLScrollContainer* scrollContainer = findChild<LLScrollContainer>("profile_scroll");
- if (scrollContainer)
- scrollContainer->goToTop();
}
-void LLPanelProfileTab::onMapButtonClick()
+LLPanelProfilePropertiesProcessorTab::~LLPanelProfilePropertiesProcessorTab()
{
- LLAvatarActions::showOnMap(getAvatarId());
+ if (getAvatarId().notNull())
+ {
+ LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
+ }
}
-void LLPanelProfileTab::updateButtons()
+void LLPanelProfilePropertiesProcessorTab::setAvatarId(const LLUUID & avatar_id)
{
- bool is_buddy_online = LLAvatarTracker::instance().isBuddyOnline(getAvatarId());
-
- if(LLAvatarActions::isFriend(getAvatarId()))
- {
- getChildView("teleport")->setEnabled(is_buddy_online);
- }
- else
- {
- getChildView("teleport")->setEnabled(true);
- }
-
- bool enable_map_btn = (is_buddy_online &&
- is_agent_mappable(getAvatarId()))
- || gAgent.isGodlike();
- getChildView("show_on_map_btn")->setEnabled(enable_map_btn);
+ if (avatar_id.notNull())
+ {
+ if (getAvatarId().notNull())
+ {
+ LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
+ }
+ LLPanelProfileTab::setAvatarId(avatar_id);
+ LLAvatarPropertiesProcessor::getInstance()->addObserver(getAvatarId(), this);
+ }
}
diff --git a/indra/newview/llpanelavatar.h b/indra/newview/llpanelavatar.h
index e33a850cfa..f182660c8e 100644
--- a/indra/newview/llpanelavatar.h
+++ b/indra/newview/llpanelavatar.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file llpanelavatar.h
- * @brief LLPanelAvatar and related class definitions
+ * @brief Legacy profile panel base class
*
- * $LicenseInfo:firstyear=2004&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2019&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
+ * Copyright (C) 2019, 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$
*/
@@ -29,80 +29,141 @@
#include "llpanel.h"
#include "llavatarpropertiesprocessor.h"
-#include "llcallingcard.h"
-#include "llvoiceclient.h"
#include "llavatarnamecache.h"
class LLComboBox;
class LLLineEditor;
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLProfileDropTarget
+//
+// This handy class is a simple way to drop something on another
+// view. It handles drop events, always setting itself to the size of
+// its parent.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+class LLProfileDropTarget : public LLView
+{
+public:
+ struct Params : public LLInitParam::Block<Params, LLView::Params>
+ {
+ Optional<LLUUID> agent_id;
+ Params()
+ : agent_id("agent_id")
+ {
+ changeDefault(mouse_opaque, false);
+ changeDefault(follows.flags, FOLLOWS_ALL);
+ }
+ };
+
+ LLProfileDropTarget(const Params&);
+ ~LLProfileDropTarget() {}
+
+ void doDrop(EDragAndDropType cargo_type, void* cargo_data);
+
+ //
+ // LLView functionality
+ virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg);
+
+ void setAgentID(const LLUUID &agent_id) { mAgentID = agent_id; }
+
+protected:
+ LLUUID mAgentID;
+};
+
+
/**
* Base class for any Profile View.
*/
class LLPanelProfileTab
- : public LLPanel
- , public LLAvatarPropertiesObserver
+ : public LLPanel
{
public:
- /**
- * Sets avatar ID, sets panel as observer of avatar related info replies from server.
- */
- virtual void setAvatarId(const LLUUID& id);
-
- /**
- * Returns avatar ID.
- */
- virtual const LLUUID& getAvatarId() { return mAvatarId; }
-
- /**
- * Sends update data request to server.
- */
- virtual void updateData() = 0;
-
- /**
- * Clears panel data if viewing avatar info for first time and sends update data request.
- */
- virtual void onOpen(const LLSD& key);
-
- /**
- * Profile tabs should close any opened panels here.
- *
- * Called from LLPanelProfile::onOpen() before opening new profile.
- * See LLPanelPicks::onClosePanel for example. LLPanelPicks closes picture info panel
- * before new profile is displayed, otherwise new profile will
- * be hidden behind picture info panel.
- */
- virtual void onClosePanel() {}
-
- /**
- * Resets controls visibility, state, etc.
- */
- virtual void resetControls(){};
-
- /**
- * Clears all data received from server.
- */
- virtual void resetData(){};
-
- /*virtual*/ ~LLPanelProfileTab();
+ /**
+ * Sets avatar ID, sets panel as observer of avatar related info replies from server.
+ */
+ virtual void setAvatarId(const LLUUID& avatar_id);
+
+ /**
+ * Returns avatar ID.
+ */
+ virtual const LLUUID& getAvatarId() { return mAvatarId; }
+
+ /**
+ * Sends update data request to server.
+ */
+ virtual void updateData() {};
+
+ /**
+ * Clears panel data if viewing avatar info for first time and sends update data request.
+ */
+ virtual void onOpen(const LLSD& key);
+
+ /**
+ * Clears all data received from server.
+ */
+ virtual void resetData(){};
+
+ /*virtual*/ ~LLPanelProfileTab();
protected:
- LLPanelProfileTab();
+ LLPanelProfileTab();
+
+ enum ELoadingState
+ {
+ PROFILE_INIT,
+ PROFILE_LOADING,
+ PROFILE_LOADED,
+ };
+
+
+ // mLoading: false: Initial state, can request
+ // true: Data requested, skip duplicate requests (happens due to LLUI's habit of repeated callbacks)
+ // mLoaded: false: Initial state, show loading indicator
+ // true: Data recieved, which comes in a single message, hide indicator
+ ELoadingState getLoadingState() { return mLoadingState; }
+ virtual void setLoaded();
+ void setApplyProgress(bool started);
+
+ const bool getSelfProfile() const { return mSelfProfile; }
- /**
- * Scrolls panel to top when viewing avatar info for first time.
- */
- void scrollToTop();
+public:
+ void setIsLoading() { mLoadingState = PROFILE_LOADING; }
+ void resetLoading() { mLoadingState = PROFILE_INIT; }
- virtual void onMapButtonClick();
+ bool getStarted() { return mLoadingState != PROFILE_INIT; }
+ bool getIsLoaded() { return mLoadingState == PROFILE_LOADED; }
- virtual void updateButtons();
+ virtual bool hasUnsavedChanges() { return false; }
+ virtual void commitUnsavedChanges() {}
private:
- LLUUID mAvatarId;
+ LLUUID mAvatarId;
+ ELoadingState mLoadingState;
+ bool mSelfProfile;
+};
+
+class LLPanelProfilePropertiesProcessorTab
+ : public LLPanelProfileTab
+ , public LLAvatarPropertiesObserver
+{
+public:
+ LLPanelProfilePropertiesProcessorTab();
+ ~LLPanelProfilePropertiesProcessorTab();
+
+ /*virtual*/ void setAvatarId(const LLUUID& avatar_id);
+
+ /**
+ * Processes data received from server via LLAvatarPropertiesObserver.
+ */
+ virtual void processProperties(void* data, EAvatarProcessorType type) = 0;
};
#endif // LL_LLPANELAVATAR_H
diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp
index c0342eef4e..183000ceac 100644
--- a/indra/newview/llpanelclassified.cpp
+++ b/indra/newview/llpanelclassified.cpp
@@ -1,10 +1,10 @@
/**
* @file llpanelclassified.cpp
- * @brief LLPanelClassified class implementation
+ * @brief LLPanelClassifiedInfo class implementation
*
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2021&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
+ * Copyright (C) 2021, 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
@@ -34,33 +34,21 @@
#include "lldispatcher.h"
#include "llfloaterreg.h"
-#include "llnotifications.h"
-#include "llnotificationsutil.h"
#include "llparcel.h"
#include "llagent.h"
#include "llclassifiedflags.h"
-#include "llcommandhandler.h" // for classified HTML detail page click tracking
#include "lliconctrl.h"
-#include "lllineeditor.h"
-#include "llcombobox.h"
#include "lltexturectrl.h"
-#include "lltexteditor.h"
-#include "llviewerparcelmgr.h"
#include "llfloaterworldmap.h"
#include "llviewergenericmessage.h" // send_generic_message
#include "llviewerregion.h"
-#include "llviewertexture.h"
-#include "lltrans.h"
#include "llscrollcontainer.h"
-#include "llstatusbar.h"
-#include "llviewertexture.h"
#include "llcorehttputil.h"
-const S32 MINIMUM_PRICE_FOR_LISTING = 50; // L$
-
//static
LLPanelClassifiedInfo::panel_list_t LLPanelClassifiedInfo::sAllPanels;
+static LLPanelInjector<LLPanelClassifiedInfo> t_panel_panel_classified_info("panel_classified_info");
// "classifiedclickthrough"
// strings[0] = classified_id
@@ -118,17 +106,8 @@ LLPanelClassifiedInfo::~LLPanelClassifiedInfo()
sAllPanels.remove(this);
}
-// static
-LLPanelClassifiedInfo* LLPanelClassifiedInfo::create()
-{
- LLPanelClassifiedInfo* panel = new LLPanelClassifiedInfo();
- panel->buildFromFile("panel_classified_info.xml");
- return panel;
-}
-
BOOL LLPanelClassifiedInfo::postBuild()
{
- childSetAction("back_btn", boost::bind(&LLPanelClassifiedInfo::onExit, this));
childSetAction("show_on_map_btn", boost::bind(&LLPanelClassifiedInfo::onMapClick, this));
childSetAction("teleport_btn", boost::bind(&LLPanelClassifiedInfo::onTeleportClick, this));
@@ -144,16 +123,6 @@ BOOL LLPanelClassifiedInfo::postBuild()
return TRUE;
}
-void LLPanelClassifiedInfo::setExitCallback(const commit_callback_t& cb)
-{
- getChild<LLButton>("back_btn")->setClickedCallback(cb);
-}
-
-void LLPanelClassifiedInfo::setEditClassifiedCallback(const commit_callback_t& cb)
-{
- getChild<LLButton>("edit_btn")->setClickedCallback(cb);
-}
-
void LLPanelClassifiedInfo::reshape(S32 width, S32 height, BOOL called_from_parent /* = TRUE */)
{
LLPanel::reshape(width, height, called_from_parent);
@@ -286,6 +255,8 @@ void LLPanelClassifiedInfo::processProperties(void* data, EAvatarProcessorType t
getChild<LLUICtrl>("creation_date")->setValue(date_str);
setInfoLoaded(true);
+
+ LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
}
}
}
@@ -590,588 +561,4 @@ void LLPanelClassifiedInfo::onTeleportClick()
}
}
-void LLPanelClassifiedInfo::onExit()
-{
- LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
- gGenericDispatcher.addHandler("classifiedclickthrough", NULL); // deregister our handler
-}
-
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-
-static const S32 CB_ITEM_MATURE = 0;
-static const S32 CB_ITEM_PG = 1;
-
-LLPanelClassifiedEdit::LLPanelClassifiedEdit()
- : LLPanelClassifiedInfo()
- , mIsNew(false)
- , mIsNewWithErrors(false)
- , mCanClose(false)
- , mPublishFloater(NULL)
-{
-}
-
-LLPanelClassifiedEdit::~LLPanelClassifiedEdit()
-{
-}
-
-//static
-LLPanelClassifiedEdit* LLPanelClassifiedEdit::create()
-{
- LLPanelClassifiedEdit* panel = new LLPanelClassifiedEdit();
- panel->buildFromFile("panel_edit_classified.xml");
- return panel;
-}
-
-BOOL LLPanelClassifiedEdit::postBuild()
-{
- LLPanelClassifiedInfo::postBuild();
-
- LLUICtrl* edit_icon = getChild<LLUICtrl>("edit_icon");
- mSnapshotCtrl->setMouseEnterCallback(boost::bind(&LLPanelClassifiedEdit::onTexturePickerMouseEnter, this, edit_icon));
- mSnapshotCtrl->setMouseLeaveCallback(boost::bind(&LLPanelClassifiedEdit::onTexturePickerMouseLeave, this, edit_icon));
- edit_icon->setVisible(false);
-
- LLLineEditor* line_edit = getChild<LLLineEditor>("classified_name");
- line_edit->setKeystrokeCallback(boost::bind(&LLPanelClassifiedEdit::onChange, this), NULL);
-
- LLTextEditor* text_edit = getChild<LLTextEditor>("classified_desc");
- text_edit->setKeystrokeCallback(boost::bind(&LLPanelClassifiedEdit::onChange, this));
-
- LLComboBox* combobox = getChild<LLComboBox>( "category");
- LLClassifiedInfo::cat_map::iterator iter;
- for (iter = LLClassifiedInfo::sCategories.begin();
- iter != LLClassifiedInfo::sCategories.end();
- iter++)
- {
- combobox->add(LLTrans::getString(iter->second));
- }
-
- combobox->setCommitCallback(boost::bind(&LLPanelClassifiedEdit::onChange, this));
-
- childSetCommitCallback("content_type", boost::bind(&LLPanelClassifiedEdit::onChange, this), NULL);
- childSetCommitCallback("price_for_listing", boost::bind(&LLPanelClassifiedEdit::onChange, this), NULL);
- childSetCommitCallback("auto_renew", boost::bind(&LLPanelClassifiedEdit::onChange, this), NULL);
-
- childSetAction("save_changes_btn", boost::bind(&LLPanelClassifiedEdit::onSaveClick, this));
- childSetAction("set_to_curr_location_btn", boost::bind(&LLPanelClassifiedEdit::onSetLocationClick, this));
-
- mSnapshotCtrl->setOnSelectCallback(boost::bind(&LLPanelClassifiedEdit::onTextureSelected, this));
-
- return TRUE;
-}
-
-void LLPanelClassifiedEdit::fillIn(const LLSD& key)
-{
- setAvatarId(gAgent.getID());
-
- if(key.isUndefined())
- {
- setPosGlobal(gAgent.getPositionGlobal());
-
- LLUUID snapshot_id = LLUUID::null;
- std::string desc;
- LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
-
- if(parcel)
- {
- desc = parcel->getDesc();
- snapshot_id = parcel->getSnapshotID();
- }
-
- std::string region_name = LLTrans::getString("ClassifiedUpdateAfterPublish");
- LLViewerRegion* region = gAgent.getRegion();
- if (region)
- {
- region_name = region->getName();
- }
-
- getChild<LLUICtrl>("classified_name")->setValue(makeClassifiedName());
- getChild<LLUICtrl>("classified_desc")->setValue(desc);
- setSnapshotId(snapshot_id);
- setClassifiedLocation(createLocationText(getLocationNotice(), region_name, getPosGlobal()));
- // server will set valid parcel id
- setParcelId(LLUUID::null);
- }
- else
- {
- setClassifiedId(key["classified_id"]);
- setClassifiedName(key["name"]);
- setDescription(key["desc"]);
- setSnapshotId(key["snapshot_id"]);
- setCategory((U32)key["category"].asInteger());
- setContentType((U32)key["content_type"].asInteger());
- setClassifiedLocation(key["location_text"]);
- getChild<LLUICtrl>("auto_renew")->setValue(key["auto_renew"]);
- getChild<LLUICtrl>("price_for_listing")->setValue(key["price_for_listing"].asInteger());
- }
-}
-
-void LLPanelClassifiedEdit::onOpen(const LLSD& key)
-{
- mIsNew = key.isUndefined();
-
- scrollToTop();
-
- // classified is not created yet
- bool is_new = isNew() || isNewWithErrors();
-
- if(is_new)
- {
- resetData();
- resetControls();
-
- fillIn(key);
-
- if(isNew())
- {
- LLAvatarPropertiesProcessor::getInstance()->addObserver(getAvatarId(), this);
- }
- }
- else
- {
- LLPanelClassifiedInfo::onOpen(key);
- }
-
- std::string save_btn_label = is_new ? getString("publish_label") : getString("save_label");
- getChild<LLUICtrl>("save_changes_btn")->setLabelArg("[LABEL]", save_btn_label);
-
- enableVerbs(is_new);
- enableEditing(is_new);
- showEditing(!is_new);
- resetDirty();
- setInfoLoaded(false);
-}
-
-void LLPanelClassifiedEdit::processProperties(void* data, EAvatarProcessorType type)
-{
- if(APT_CLASSIFIED_INFO == type)
- {
- LLAvatarClassifiedInfo* c_info = static_cast<LLAvatarClassifiedInfo*>(data);
- if(c_info && getClassifiedId() == c_info->classified_id)
- {
- // see LLPanelClassifiedEdit::sendUpdate() for notes
- mIsNewWithErrors = false;
- // for just created classified - panel will probably be closed when we get here.
- if(!getVisible())
- {
- return;
- }
-
- enableEditing(true);
-
- setClassifiedName(c_info->name);
- setDescription(c_info->description);
- setSnapshotId(c_info->snapshot_id);
- setParcelId(c_info->parcel_id);
- setPosGlobal(c_info->pos_global);
-
- setClassifiedLocation(createLocationText(c_info->parcel_name, c_info->sim_name, c_info->pos_global));
- // *HACK see LLPanelClassifiedEdit::sendUpdate()
- setCategory(c_info->category - 1);
-
- bool mature = is_cf_mature(c_info->flags);
- bool auto_renew = is_cf_auto_renew(c_info->flags);
-
- setContentType(mature ? CB_ITEM_MATURE : CB_ITEM_PG);
- getChild<LLUICtrl>("auto_renew")->setValue(auto_renew);
- getChild<LLUICtrl>("price_for_listing")->setValue(c_info->price_for_listing);
- getChildView("price_for_listing")->setEnabled(isNew());
-
- resetDirty();
- setInfoLoaded(true);
- enableVerbs(false);
-
- // for just created classified - in case user opened edit panel before processProperties() callback
- getChild<LLUICtrl>("save_changes_btn")->setLabelArg("[LABEL]", getString("save_label"));
- }
- }
-}
-
-BOOL LLPanelClassifiedEdit::isDirty() const
-{
- if(mIsNew)
- {
- return TRUE;
- }
-
- BOOL dirty = false;
-
- dirty |= LLPanelClassifiedInfo::isDirty();
- dirty |= getChild<LLUICtrl>("classified_snapshot")->isDirty();
- dirty |= getChild<LLUICtrl>("classified_name")->isDirty();
- dirty |= getChild<LLUICtrl>("classified_desc")->isDirty();
- dirty |= getChild<LLUICtrl>("category")->isDirty();
- dirty |= getChild<LLUICtrl>("content_type")->isDirty();
- dirty |= getChild<LLUICtrl>("auto_renew")->isDirty();
- dirty |= getChild<LLUICtrl>("price_for_listing")->isDirty();
-
- return dirty;
-}
-
-void LLPanelClassifiedEdit::resetDirty()
-{
- LLPanelClassifiedInfo::resetDirty();
- getChild<LLUICtrl>("classified_snapshot")->resetDirty();
- getChild<LLUICtrl>("classified_name")->resetDirty();
-
- LLTextEditor* desc = getChild<LLTextEditor>("classified_desc");
- // call blockUndo() to really reset dirty(and make isDirty work as intended)
- desc->blockUndo();
- desc->resetDirty();
-
- getChild<LLUICtrl>("category")->resetDirty();
- getChild<LLUICtrl>("content_type")->resetDirty();
- getChild<LLUICtrl>("auto_renew")->resetDirty();
- getChild<LLUICtrl>("price_for_listing")->resetDirty();
-}
-
-void LLPanelClassifiedEdit::setSaveCallback(const commit_signal_t::slot_type& cb)
-{
- mSaveButtonClickedSignal.connect(cb);
-}
-
-void LLPanelClassifiedEdit::setCancelCallback(const commit_signal_t::slot_type& cb)
-{
- getChild<LLButton>("cancel_btn")->setClickedCallback(cb);
-}
-
-void LLPanelClassifiedEdit::resetControls()
-{
- LLPanelClassifiedInfo::resetControls();
-
- getChild<LLComboBox>("category")->setCurrentByIndex(0);
- getChild<LLComboBox>("content_type")->setCurrentByIndex(0);
- getChild<LLUICtrl>("auto_renew")->setValue(false);
- getChild<LLUICtrl>("price_for_listing")->setValue(MINIMUM_PRICE_FOR_LISTING);
- getChildView("price_for_listing")->setEnabled(TRUE);
-}
-
-bool LLPanelClassifiedEdit::canClose()
-{
- return mCanClose;
-}
-
-void LLPanelClassifiedEdit::draw()
-{
- LLPanel::draw();
-
- // Need to re-stretch on every draw because LLTextureCtrl::onSelectCallback
- // does not trigger callbacks when user navigates through images.
- stretchSnapshot();
-}
-
-void LLPanelClassifiedEdit::stretchSnapshot()
-{
- LLPanelClassifiedInfo::stretchSnapshot();
-
- getChild<LLUICtrl>("edit_icon")->setShape(mSnapshotCtrl->getRect());
-}
-
-U32 LLPanelClassifiedEdit::getContentType()
-{
- LLComboBox* ct_cb = getChild<LLComboBox>("content_type");
- return ct_cb->getCurrentIndex();
-}
-
-void LLPanelClassifiedEdit::setContentType(U32 content_type)
-{
- LLComboBox* ct_cb = getChild<LLComboBox>("content_type");
- ct_cb->setCurrentByIndex(content_type);
- ct_cb->resetDirty();
-}
-
-bool LLPanelClassifiedEdit::getAutoRenew()
-{
- return getChild<LLUICtrl>("auto_renew")->getValue().asBoolean();
-}
-
-void LLPanelClassifiedEdit::sendUpdate()
-{
- LLAvatarClassifiedInfo c_data;
-
- if(getClassifiedId().isNull())
- {
- setClassifiedId(LLUUID::generateNewID());
- }
-
- c_data.agent_id = gAgent.getID();
- c_data.classified_id = getClassifiedId();
- // *HACK
- // Categories on server start with 1 while combo-box index starts with 0
- c_data.category = getCategory() + 1;
- c_data.name = getClassifiedName();
- c_data.description = getDescription();
- c_data.parcel_id = getParcelId();
- c_data.snapshot_id = getSnapshotId();
- c_data.pos_global = getPosGlobal();
- c_data.flags = getFlags();
- c_data.price_for_listing = getPriceForListing();
-
- LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoUpdate(&c_data);
-
- if(isNew())
- {
- // Lets assume there will be some error.
- // Successful sendClassifiedInfoUpdate will trigger processProperties and
- // let us know there was no error.
- mIsNewWithErrors = true;
- }
-}
-
-U32 LLPanelClassifiedEdit::getCategory()
-{
- LLComboBox* cat_cb = getChild<LLComboBox>("category");
- return cat_cb->getCurrentIndex();
-}
-
-void LLPanelClassifiedEdit::setCategory(U32 category)
-{
- LLComboBox* cat_cb = getChild<LLComboBox>("category");
- cat_cb->setCurrentByIndex(category);
- cat_cb->resetDirty();
-}
-
-U8 LLPanelClassifiedEdit::getFlags()
-{
- bool auto_renew = getChild<LLUICtrl>("auto_renew")->getValue().asBoolean();
-
- LLComboBox* content_cb = getChild<LLComboBox>("content_type");
- bool mature = content_cb->getCurrentIndex() == CB_ITEM_MATURE;
-
- return pack_classified_flags_request(auto_renew, false, mature, false);
-}
-
-void LLPanelClassifiedEdit::enableVerbs(bool enable)
-{
- getChildView("save_changes_btn")->setEnabled(enable);
-}
-
-void LLPanelClassifiedEdit::enableEditing(bool enable)
-{
- getChildView("classified_snapshot")->setEnabled(enable);
- getChildView("classified_name")->setEnabled(enable);
- getChildView("classified_desc")->setEnabled(enable);
- getChildView("set_to_curr_location_btn")->setEnabled(enable);
- getChildView("category")->setEnabled(enable);
- getChildView("content_type")->setEnabled(enable);
- getChildView("price_for_listing")->setEnabled(enable);
- getChildView("auto_renew")->setEnabled(enable);
-}
-
-void LLPanelClassifiedEdit::showEditing(bool show)
-{
- getChildView("price_for_listing_label")->setVisible( show);
- getChildView("price_for_listing")->setVisible( show);
-}
-
-std::string LLPanelClassifiedEdit::makeClassifiedName()
-{
- std::string name;
-
- LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
- if(parcel)
- {
- name = parcel->getName();
- }
-
- if(!name.empty())
- {
- return name;
- }
-
- LLViewerRegion* region = gAgent.getRegion();
- if(region)
- {
- name = region->getName();
- }
-
- return name;
-}
-
-S32 LLPanelClassifiedEdit::getPriceForListing()
-{
- return getChild<LLUICtrl>("price_for_listing")->getValue().asInteger();
-}
-
-void LLPanelClassifiedEdit::setPriceForListing(S32 price)
-{
- getChild<LLUICtrl>("price_for_listing")->setValue(price);
-}
-
-void LLPanelClassifiedEdit::onSetLocationClick()
-{
- setPosGlobal(gAgent.getPositionGlobal());
- setParcelId(LLUUID::null);
-
- std::string region_name = LLTrans::getString("ClassifiedUpdateAfterPublish");
- LLViewerRegion* region = gAgent.getRegion();
- if (region)
- {
- region_name = region->getName();
- }
-
- setClassifiedLocation(createLocationText(getLocationNotice(), region_name, getPosGlobal()));
-
- // mark classified as dirty
- setValue(LLSD());
-
- onChange();
-}
-
-void LLPanelClassifiedEdit::onChange()
-{
- enableVerbs(isDirty());
-}
-
-void LLPanelClassifiedEdit::onSaveClick()
-{
- mCanClose = false;
-
- if(!isValidName())
- {
- notifyInvalidName();
- return;
- }
- if(isNew() || isNewWithErrors())
- {
- if(gStatusBar->getBalance() < getPriceForListing())
- {
- LLNotificationsUtil::add("ClassifiedInsufficientFunds");
- return;
- }
-
- mPublishFloater = LLFloaterReg::findTypedInstance<LLPublishClassifiedFloater>(
- "publish_classified", LLSD());
-
- if(!mPublishFloater)
- {
- mPublishFloater = LLFloaterReg::getTypedInstance<LLPublishClassifiedFloater>(
- "publish_classified", LLSD());
-
- mPublishFloater->setPublishClickedCallback(boost::bind
- (&LLPanelClassifiedEdit::onPublishFloaterPublishClicked, this));
- }
-
- // set spinner value before it has focus or value wont be set
- mPublishFloater->setPrice(getPriceForListing());
- mPublishFloater->openFloater(mPublishFloater->getKey());
- mPublishFloater->center();
- }
- else
- {
- doSave();
- }
-}
-
-void LLPanelClassifiedEdit::doSave()
-{
- mCanClose = true;
- sendUpdate();
- resetDirty();
-
- mSaveButtonClickedSignal(this, LLSD());
-}
-
-void LLPanelClassifiedEdit::onPublishFloaterPublishClicked()
-{
- setPriceForListing(mPublishFloater->getPrice());
-
- doSave();
-}
-
-std::string LLPanelClassifiedEdit::getLocationNotice()
-{
- static std::string location_notice = getString("location_notice");
- return location_notice;
-}
-
-bool LLPanelClassifiedEdit::isValidName()
-{
- std::string name = getClassifiedName();
- if (name.empty())
- {
- return false;
- }
- if (!isalnum(name[0]))
- {
- return false;
- }
-
- return true;
-}
-
-void LLPanelClassifiedEdit::notifyInvalidName()
-{
- std::string name = getClassifiedName();
- if (name.empty())
- {
- LLNotificationsUtil::add("BlankClassifiedName");
- }
- else if (!isalnum(name[0]))
- {
- LLNotificationsUtil::add("ClassifiedMustBeAlphanumeric");
- }
-}
-
-void LLPanelClassifiedEdit::onTexturePickerMouseEnter(LLUICtrl* ctrl)
-{
- ctrl->setVisible(TRUE);
-}
-
-void LLPanelClassifiedEdit::onTexturePickerMouseLeave(LLUICtrl* ctrl)
-{
- ctrl->setVisible(FALSE);
-}
-
-void LLPanelClassifiedEdit::onTextureSelected()
-{
- setSnapshotId(mSnapshotCtrl->getValue().asUUID());
- onChange();
-}
-
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-
-LLPublishClassifiedFloater::LLPublishClassifiedFloater(const LLSD& key)
- : LLFloater(key)
-{
-}
-
-LLPublishClassifiedFloater::~LLPublishClassifiedFloater()
-{
-}
-
-BOOL LLPublishClassifiedFloater::postBuild()
-{
- LLFloater::postBuild();
-
- childSetAction("publish_btn", boost::bind(&LLFloater::closeFloater, this, false));
- childSetAction("cancel_btn", boost::bind(&LLFloater::closeFloater, this, false));
-
- return TRUE;
-}
-
-void LLPublishClassifiedFloater::setPrice(S32 price)
-{
- getChild<LLUICtrl>("price_for_listing")->setValue(price);
-}
-
-S32 LLPublishClassifiedFloater::getPrice()
-{
- return getChild<LLUICtrl>("price_for_listing")->getValue().asInteger();
-}
-
-void LLPublishClassifiedFloater::setPublishClickedCallback(const commit_signal_t::slot_type& cb)
-{
- getChild<LLButton>("publish_btn")->setClickedCallback(cb);
-}
-
-void LLPublishClassifiedFloater::setCancelClickedCallback(const commit_signal_t::slot_type& cb)
-{
- getChild<LLButton>("cancel_btn")->setClickedCallback(cb);
-}
-
//EOF
diff --git a/indra/newview/llpanelclassified.h b/indra/newview/llpanelclassified.h
index b292782615..471becd0f7 100644
--- a/indra/newview/llpanelclassified.h
+++ b/indra/newview/llpanelclassified.h
@@ -1,10 +1,10 @@
/**
* @file llpanelclassified.h
- * @brief LLPanelClassified class definition
+ * @brief LLPanelClassifiedInfo class definition
*
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2021&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
+ * Copyright (C) 2021, 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
@@ -35,39 +35,16 @@
#include "llfloater.h"
#include "llpanel.h"
#include "llrect.h"
-#include "lluuid.h"
-#include "v3dmath.h"
-#include "llcoros.h"
-#include "lleventcoro.h"
class LLScrollContainer;
class LLTextureCtrl;
-class LLUICtrl;
-
-class LLPublishClassifiedFloater : public LLFloater
-{
-public:
- LLPublishClassifiedFloater(const LLSD& key);
- virtual ~LLPublishClassifiedFloater();
-
- /*virtual*/ BOOL postBuild();
-
- void setPrice(S32 price);
- S32 getPrice();
-
- void setPublishClickedCallback(const commit_signal_t::slot_type& cb);
- void setCancelClickedCallback(const commit_signal_t::slot_type& cb);
-
-private:
-};
class LLPanelClassifiedInfo : public LLPanel, public LLAvatarPropertiesObserver
{
LOG_CLASS(LLPanelClassifiedInfo);
public:
- static LLPanelClassifiedInfo* create();
-
+ LLPanelClassifiedInfo();
virtual ~LLPanelClassifiedInfo();
/*virtual*/ void onOpen(const LLSD& key);
@@ -135,18 +112,12 @@ public:
const LLVector3d& global_pos,
const std::string& sim_name);
- void setExitCallback(const commit_callback_t& cb);
-
- void setEditClassifiedCallback(const commit_callback_t& cb);
-
/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
/*virtual*/ void draw();
protected:
- LLPanelClassifiedInfo();
-
virtual void resetData();
virtual void resetControls();
@@ -165,7 +136,6 @@ protected:
void onMapClick();
void onTeleportClick();
- void onExit();
bool mSnapshotStreched;
LLRect mSnapshotRect;
@@ -202,100 +172,4 @@ private:
static panel_list_t sAllPanels;
};
-class LLPanelClassifiedEdit : public LLPanelClassifiedInfo
-{
- LOG_CLASS(LLPanelClassifiedEdit);
-public:
-
- static LLPanelClassifiedEdit* create();
-
- virtual ~LLPanelClassifiedEdit();
-
- /*virtual*/ BOOL postBuild();
-
- void fillIn(const LLSD& key);
-
- /*virtual*/ void onOpen(const LLSD& key);
-
- /*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
-
- /*virtual*/ BOOL isDirty() const;
-
- /*virtual*/ void resetDirty();
-
- void setSaveCallback(const commit_signal_t::slot_type& cb);
-
- void setCancelCallback(const commit_signal_t::slot_type& cb);
-
- /*virtual*/ void resetControls();
-
- bool isNew() { return mIsNew; }
-
- bool isNewWithErrors() { return mIsNewWithErrors; }
-
- bool canClose();
-
- void draw();
-
- void stretchSnapshot();
-
- U32 getCategory();
-
- void setCategory(U32 category);
-
- U32 getContentType();
-
- void setContentType(U32 content_type);
-
- bool getAutoRenew();
-
- S32 getPriceForListing();
-
-protected:
-
- LLPanelClassifiedEdit();
-
- void sendUpdate();
-
- void enableVerbs(bool enable);
-
- void enableEditing(bool enable);
-
- void showEditing(bool show);
-
- std::string makeClassifiedName();
-
- void setPriceForListing(S32 price);
-
- U8 getFlags();
-
- std::string getLocationNotice();
-
- bool isValidName();
-
- void notifyInvalidName();
-
- void onSetLocationClick();
- void onChange();
- void onSaveClick();
-
- void doSave();
-
- void onPublishFloaterPublishClicked();
-
- void onTexturePickerMouseEnter(LLUICtrl* ctrl);
- void onTexturePickerMouseLeave(LLUICtrl* ctrl);
-
- void onTextureSelected();
-
-private:
- bool mIsNew;
- bool mIsNewWithErrors;
- bool mCanClose;
-
- LLPublishClassifiedFloater* mPublishFloater;
-
- commit_signal_t mSaveButtonClickedSignal;
-};
-
#endif // LL_LLPANELCLASSIFIED_H
diff --git a/indra/newview/llpanelexperiences.h b/indra/newview/llpanelexperiences.h
index 9d5afd1a6a..11111f2a2e 100644
--- a/indra/newview/llpanelexperiences.h
+++ b/indra/newview/llpanelexperiences.h
@@ -29,7 +29,6 @@
#include "llaccordionctrltab.h"
#include "llflatlistview.h"
-#include "llpanelavatar.h"
class LLExperienceItem;
class LLPanelProfile;
diff --git a/indra/newview/llpanelimcontrolpanel.cpp b/indra/newview/llpanelimcontrolpanel.cpp
index 389baa86cd..07a8641a92 100644
--- a/indra/newview/llpanelimcontrolpanel.cpp
+++ b/indra/newview/llpanelimcontrolpanel.cpp
@@ -1,6 +1,6 @@
/**
- * @file llpanelavatar.cpp
- * @brief LLPanelAvatar and related class implementations
+ * @file llpanelimcontrolpanel.cpp
+ * @brief LLPanelIMControlPanel and related class implementations
*
* $LicenseInfo:firstyear=2004&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp
index ce17da3076..c3334605ae 100644
--- a/indra/newview/llpanellandmarks.cpp
+++ b/indra/newview/llpanellandmarks.cpp
@@ -29,6 +29,7 @@
#include "llpanellandmarks.h"
#include "llbutton.h"
+#include "llfloaterprofile.h"
#include "llfloaterreg.h"
#include "llnotificationsutil.h"
#include "llsdutil.h"
@@ -1003,17 +1004,6 @@ bool LLLandmarksPanel::canItemBeModified(const std::string& command_name, LLFold
return can_be_modified;
}
-void LLLandmarksPanel::onPickPanelExit( LLPanelPickEdit* pick_panel, LLView* owner, const LLSD& params)
-{
- pick_panel->setVisible(FALSE);
- owner->removeChild(pick_panel);
- //we need remove observer to avoid processParcelInfo in the future.
- LLRemoteParcelInfoProcessor::getInstance()->removeObserver(params["parcel_id"].asUUID(), this);
-
- delete pick_panel;
- pick_panel = NULL;
-}
-
bool LLLandmarksPanel::handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, void* cargo_data , EAcceptance* accept)
{
*accept = ACCEPT_NO;
@@ -1080,49 +1070,21 @@ void LLLandmarksPanel::doProcessParcelInfo(LLLandmark* landmark,
LLInventoryItem* inv_item,
const LLParcelData& parcel_data)
{
- LLPanelPickEdit* panel_pick = LLPanelPickEdit::create();
LLVector3d landmark_global_pos;
landmark->getGlobalPos(landmark_global_pos);
- // let's toggle pick panel into panel places
- LLPanel* panel_places = NULL;
- LLFloaterSidePanelContainer* floaterp = LLFloaterReg::getTypedInstance<LLFloaterSidePanelContainer>("places");
- if (floaterp)
- {
- panel_places = floaterp->findChild<LLPanel>("main_panel");
- }
-
- if (!panel_places)
- {
- llassert(NULL != panel_places);
- return;
- }
- panel_places->addChild(panel_pick);
- LLRect paren_rect(panel_places->getRect());
- panel_pick->reshape(paren_rect.getWidth(),paren_rect.getHeight(), TRUE);
- panel_pick->setRect(paren_rect);
- panel_pick->onOpen(LLSD());
-
LLPickData data;
data.pos_global = landmark_global_pos;
data.name = inv_item->getName();
data.desc = inv_item->getDescription();
data.snapshot_id = parcel_data.snapshot_id;
data.parcel_id = parcel_data.parcel_id;
- panel_pick->setPickData(&data);
-
- LLSD params;
- params["parcel_id"] = parcel_data.parcel_id;
- /* set exit callback to get back onto panel places
- in callback we will make cleaning up( delete pick_panel instance,
- remove landmark panel from observer list
- */
- panel_pick->setExitCallback(boost::bind(&LLLandmarksPanel::onPickPanelExit,this,
- panel_pick, panel_places,params));
- panel_pick->setSaveCallback(boost::bind(&LLLandmarksPanel::onPickPanelExit,this,
- panel_pick, panel_places,params));
- panel_pick->setCancelCallback(boost::bind(&LLLandmarksPanel::onPickPanelExit,this,
- panel_pick, panel_places,params));
+
+ LLFloaterProfile* profile_floater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", gAgentID)));
+ if (profile_floater)
+ {
+ profile_floater->createPick(data);
+ }
}
void LLLandmarksPanel::doCreatePick(LLLandmark* landmark, const LLUUID &item_id)
diff --git a/indra/newview/llpanellandmarks.h b/indra/newview/llpanellandmarks.h
index d7408269b5..16f3a5dc24 100644
--- a/indra/newview/llpanellandmarks.h
+++ b/indra/newview/llpanellandmarks.h
@@ -34,7 +34,6 @@
#include "llinventorymodel.h"
#include "lllandmarklist.h"
#include "llpanelplacestab.h"
-#include "llpanelpick.h"
#include "llremoteparcelrequest.h"
class LLAccordionCtrlTab;
@@ -136,7 +135,6 @@ private:
* For now it checks cut/rename/delete/paste actions.
*/
bool canItemBeModified(const std::string& command_name, LLFolderViewItem* item) const;
- void onPickPanelExit( LLPanelPickEdit* pick_panel, LLView* owner, const LLSD& params);
/**
* Landmark actions callbacks. Fire when a landmark is loaded from the list.
diff --git a/indra/newview/llpanelme.cpp b/indra/newview/llpanelme.cpp
deleted file mode 100644
index 55e4ffff5e..0000000000
--- a/indra/newview/llpanelme.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-/**
- * @file llpanelme.cpp
- * @brief Side tray "Me" (My Profile) panel
- *
- * $LicenseInfo:firstyear=2009&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$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llpanelme.h"
-
-// Viewer includes
-#include "llpanelprofile.h"
-#include "llagent.h"
-#include "llagentcamera.h"
-#include "llagentwearables.h"
-#include "llfirstuse.h"
-#include "llfloaterreg.h"
-#include "llhints.h"
-#include "llviewercontrol.h"
-
-// Linden libraries
-#include "llavatarnamecache.h" // IDEVO
-#include "lliconctrl.h"
-#include "llnotifications.h"
-#include "llnotificationsutil.h" // IDEVO
-#include "lltabcontainer.h"
-#include "lltexturectrl.h"
-
-static LLPanelInjector<LLPanelMe> t_panel_me_profile("panel_me");
-
-LLPanelMe::LLPanelMe(void)
- : LLPanelProfile()
-{
- setAvatarId(gAgent.getID());
-}
-
-BOOL LLPanelMe::postBuild()
-{
- LLPanelProfile::postBuild();
-
- return TRUE;
-}
-
-void LLPanelMe::onOpen(const LLSD& key)
-{
- LLPanelProfile::onOpen(key);
-}
diff --git a/indra/newview/llpanelpick.cpp b/indra/newview/llpanelpick.cpp
deleted file mode 100644
index 40326cfb39..0000000000
--- a/indra/newview/llpanelpick.cpp
+++ /dev/null
@@ -1,620 +0,0 @@
-/**
- * @file llpanelpick.cpp
- * @brief LLPanelPick class implementation
- *
- * $LicenseInfo:firstyear=2004&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$
- */
-
-// Display of a "Top Pick" used both for the global top picks in the
-// Find directory, and also for each individual user's picks in their
-// profile.
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llpanelpick.h"
-
-#include "message.h"
-
-#include "llparcel.h"
-
-#include "llbutton.h"
-#include "llfloaterreg.h"
-#include "lliconctrl.h"
-#include "lllineeditor.h"
-#include "llpanel.h"
-#include "llscrollcontainer.h"
-#include "lltexteditor.h"
-
-#include "llagent.h"
-#include "llagentpicksinfo.h"
-#include "llavatarpropertiesprocessor.h"
-#include "llfloaterworldmap.h"
-#include "lltexturectrl.h"
-#include "lluiconstants.h"
-#include "llviewerparcelmgr.h"
-#include "llviewerregion.h"
-#include "llworldmap.h"
-
-
-#define XML_PANEL_EDIT_PICK "panel_edit_pick.xml"
-#define XML_PANEL_PICK_INFO "panel_pick_info.xml"
-
-#define XML_NAME "pick_name"
-#define XML_DESC "pick_desc"
-#define XML_SNAPSHOT "pick_snapshot"
-#define XML_LOCATION "pick_location"
-
-#define XML_BTN_ON_TXTR "edit_icon"
-#define XML_BTN_SAVE "save_changes_btn"
-
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-
-//static
-LLPanelPickInfo* LLPanelPickInfo::create()
-{
- LLPanelPickInfo* panel = new LLPanelPickInfo();
- panel->buildFromFile(XML_PANEL_PICK_INFO);
- return panel;
-}
-
-LLPanelPickInfo::LLPanelPickInfo()
- : LLPanel()
- , LLAvatarPropertiesObserver()
- , LLRemoteParcelInfoObserver()
- , mAvatarId(LLUUID::null)
- , mSnapshotCtrl(NULL)
- , mPickId(LLUUID::null)
- , mParcelId(LLUUID::null)
- , mRequestedId(LLUUID::null)
- , mScrollingPanelMinHeight(0)
- , mScrollingPanelWidth(0)
- , mScrollingPanel(NULL)
- , mScrollContainer(NULL)
-{
-}
-
-LLPanelPickInfo::~LLPanelPickInfo()
-{
- LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
-
- if (mParcelId.notNull())
- {
- LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mParcelId, this);
- }
-}
-
-void LLPanelPickInfo::onOpen(const LLSD& key)
-{
- LLUUID avatar_id = key["avatar_id"];
- if(avatar_id.isNull())
- {
- return;
- }
-
- if(getAvatarId().notNull())
- {
- LLAvatarPropertiesProcessor::getInstance()->removeObserver(
- getAvatarId(), this);
- }
-
- setAvatarId(avatar_id);
-
- resetData();
- resetControls();
-
- setPickId(key["pick_id"]);
- setPickName(key["pick_name"]);
- setPickDesc(key["pick_desc"]);
- setSnapshotId(key["snapshot_id"]);
-
- LLAvatarPropertiesProcessor::getInstance()->addObserver(
- getAvatarId(), this);
- LLAvatarPropertiesProcessor::getInstance()->sendPickInfoRequest(
- getAvatarId(), getPickId());
-}
-
-BOOL LLPanelPickInfo::postBuild()
-{
- mSnapshotCtrl = getChild<LLTextureCtrl>(XML_SNAPSHOT);
-
- childSetAction("teleport_btn", boost::bind(&LLPanelPickInfo::onClickTeleport, this));
- childSetAction("show_on_map_btn", boost::bind(&LLPanelPickInfo::onClickMap, this));
- childSetAction("back_btn", boost::bind(&LLPanelPickInfo::onClickBack, this));
-
- mScrollingPanel = getChild<LLPanel>("scroll_content_panel");
- mScrollContainer = getChild<LLScrollContainer>("profile_scroll");
-
- mScrollingPanelMinHeight = mScrollContainer->getScrolledViewRect().getHeight();
- mScrollingPanelWidth = mScrollingPanel->getRect().getWidth();
-
- LLTextEditor* text_desc = getChild<LLTextEditor>(XML_DESC);
- text_desc->setContentTrusted(false);
-
- return TRUE;
-}
-
-void LLPanelPickInfo::reshape(S32 width, S32 height, BOOL called_from_parent)
-{
- LLPanel::reshape(width, height, called_from_parent);
-
- if (!mScrollContainer || !mScrollingPanel)
- return;
-
- static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
-
- S32 scroll_height = mScrollContainer->getRect().getHeight();
- if (mScrollingPanelMinHeight >= scroll_height)
- {
- mScrollingPanel->reshape(mScrollingPanelWidth, mScrollingPanelMinHeight);
- }
- else
- {
- mScrollingPanel->reshape(mScrollingPanelWidth + scrollbar_size, scroll_height);
- }
-}
-
-void LLPanelPickInfo::processProperties(void* data, EAvatarProcessorType type)
-{
- if(APT_PICK_INFO != type)
- {
- return;
- }
- LLPickData* pick_info = static_cast<LLPickData*>(data);
- if(!pick_info
- || pick_info->creator_id != getAvatarId()
- || pick_info->pick_id != getPickId())
- {
- return;
- }
-
- mParcelId = pick_info->parcel_id;
- setSnapshotId(pick_info->snapshot_id);
- setPickName(pick_info->name);
- setPickDesc(pick_info->desc);
- setPosGlobal(pick_info->pos_global);
-
- // Send remote parcel info request to get parcel name and sim (region) name.
- sendParcelInfoRequest();
-
- // *NOTE dzaporozhan
- // We want to keep listening to APT_PICK_INFO because user may
- // edit the Pick and we have to update Pick info panel.
- // revomeObserver is called from onClickBack
-}
-
-void LLPanelPickInfo::sendParcelInfoRequest()
-{
- if (mParcelId != mRequestedId)
- {
- LLRemoteParcelInfoProcessor::getInstance()->addObserver(mParcelId, this);
- LLRemoteParcelInfoProcessor::getInstance()->sendParcelInfoRequest(mParcelId);
-
- mRequestedId = mParcelId;
- }
-}
-
-void LLPanelPickInfo::setExitCallback(const commit_callback_t& cb)
-{
- getChild<LLButton>("back_btn")->setClickedCallback(cb);
-}
-
-void LLPanelPickInfo::processParcelInfo(const LLParcelData& parcel_data)
-{
- setPickLocation(createLocationText(LLStringUtil::null, parcel_data.name,
- parcel_data.sim_name, getPosGlobal()));
-
- // We have received parcel info for the requested ID so clear it now.
- mRequestedId.setNull();
-
- if (mParcelId.notNull())
- {
- LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mParcelId, this);
- }
-}
-
-void LLPanelPickInfo::setEditPickCallback(const commit_callback_t& cb)
-{
- getChild<LLButton>("edit_btn")->setClickedCallback(cb);
-}
-
-// PROTECTED AREA
-
-void LLPanelPickInfo::resetControls()
-{
- if(getAvatarId() == gAgent.getID())
- {
- getChildView("edit_btn")->setEnabled(TRUE);
- getChildView("edit_btn")->setVisible( TRUE);
- }
- else
- {
- getChildView("edit_btn")->setEnabled(FALSE);
- getChildView("edit_btn")->setVisible( FALSE);
- }
-}
-
-void LLPanelPickInfo::resetData()
-{
- setPickName(LLStringUtil::null);
- setPickDesc(LLStringUtil::null);
- setPickLocation(LLStringUtil::null);
- setPickId(LLUUID::null);
- setSnapshotId(LLUUID::null);
- mPosGlobal.clearVec();
- mParcelId.setNull();
- mRequestedId.setNull();
-}
-
-// static
-std::string LLPanelPickInfo::createLocationText(const std::string& owner_name, const std::string& original_name, const std::string& sim_name, const LLVector3d& pos_global)
-{
- std::string location_text;
- location_text.append(owner_name);
- if (!original_name.empty())
- {
- if (!location_text.empty()) location_text.append(", ");
- location_text.append(original_name);
-
- }
- if (!sim_name.empty())
- {
- if (!location_text.empty()) location_text.append(", ");
- location_text.append(sim_name);
- }
-
- if (!location_text.empty()) location_text.append(" ");
-
- if (!pos_global.isNull())
- {
- S32 region_x = ll_round((F32)pos_global.mdV[VX]) % REGION_WIDTH_UNITS;
- S32 region_y = ll_round((F32)pos_global.mdV[VY]) % REGION_WIDTH_UNITS;
- S32 region_z = ll_round((F32)pos_global.mdV[VZ]);
- location_text.append(llformat(" (%d, %d, %d)", region_x, region_y, region_z));
- }
- return location_text;
-}
-
-void LLPanelPickInfo::setSnapshotId(const LLUUID& id)
-{
- mSnapshotCtrl->setImageAssetID(id);
- mSnapshotCtrl->setValid(TRUE);
-}
-
-void LLPanelPickInfo::setPickName(const std::string& name)
-{
- getChild<LLUICtrl>(XML_NAME)->setValue(name);
-}
-
-void LLPanelPickInfo::setPickDesc(const std::string& desc)
-{
- getChild<LLUICtrl>(XML_DESC)->setValue(desc);
-}
-
-void LLPanelPickInfo::setPickLocation(const std::string& location)
-{
- getChild<LLUICtrl>(XML_LOCATION)->setValue(location);
-}
-
-void LLPanelPickInfo::onClickMap()
-{
- LLFloaterWorldMap::getInstance()->trackLocation(getPosGlobal());
- LLFloaterReg::showInstance("world_map", "center");
-}
-
-void LLPanelPickInfo::onClickTeleport()
-{
- if (!getPosGlobal().isExactlyZero())
- {
- gAgent.teleportViaLocation(getPosGlobal());
- LLFloaterWorldMap::getInstance()->trackLocation(getPosGlobal());
- }
-}
-
-void LLPanelPickInfo::onClickBack()
-{
- LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
-}
-
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-
-//static
-LLPanelPickEdit* LLPanelPickEdit::create()
-{
- LLPanelPickEdit* panel = new LLPanelPickEdit();
- panel->buildFromFile(XML_PANEL_EDIT_PICK);
- return panel;
-}
-
-LLPanelPickEdit::LLPanelPickEdit()
- : LLPanelPickInfo()
- , mLocationChanged(false)
- , mNeedData(true)
- , mNewPick(false)
-{
-}
-
-LLPanelPickEdit::~LLPanelPickEdit()
-{
-}
-
-void LLPanelPickEdit::onOpen(const LLSD& key)
-{
- LLUUID pick_id = key["pick_id"];
- mNeedData = true;
-
- // creating new Pick
- if(pick_id.isNull())
- {
- mNewPick = true;
-
- setAvatarId(gAgent.getID());
-
- resetData();
- resetControls();
-
- setPosGlobal(gAgent.getPositionGlobal());
-
- LLUUID parcel_id = LLUUID::null, snapshot_id = LLUUID::null;
- std::string pick_name, pick_desc, region_name;
-
- LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
- if(parcel)
- {
- parcel_id = parcel->getID();
- pick_name = parcel->getName();
- pick_desc = parcel->getDesc();
- snapshot_id = parcel->getSnapshotID();
- }
-
- LLViewerRegion* region = gAgent.getRegion();
- if(region)
- {
- region_name = region->getName();
- }
-
- setParcelID(parcel_id);
- getChild<LLUICtrl>("pick_name")->setValue(pick_name.empty() ? region_name : pick_name);
- getChild<LLUICtrl>("pick_desc")->setValue(pick_desc);
- setSnapshotId(snapshot_id);
- setPickLocation(createLocationText(getLocationNotice(), pick_name, region_name, getPosGlobal()));
-
- enableSaveButton(true);
- }
- // editing existing pick
- else
- {
- mNewPick = false;
- LLPanelPickInfo::onOpen(key);
-
- enableSaveButton(false);
- }
-
- resetDirty();
-}
-
-void LLPanelPickEdit::setPickData(const LLPickData* pick_data)
-{
- if(!pick_data)
- {
- return;
- }
-
- mNeedData = false;
-
- setParcelID(pick_data->parcel_id);
- getChild<LLUICtrl>("pick_name")->setValue(pick_data->name);
- getChild<LLUICtrl>("pick_desc")->setValue(pick_data->desc);
- setSnapshotId(pick_data->snapshot_id);
- setPosGlobal(pick_data->pos_global);
- setPickLocation(createLocationText(LLStringUtil::null, pick_data->name,
- pick_data->sim_name, pick_data->pos_global));
-}
-
-BOOL LLPanelPickEdit::postBuild()
-{
- LLPanelPickInfo::postBuild();
-
- mSnapshotCtrl->setCommitCallback(boost::bind(&LLPanelPickEdit::onSnapshotChanged, this));
-
- LLLineEditor* line_edit = getChild<LLLineEditor>("pick_name");
- line_edit->setKeystrokeCallback(boost::bind(&LLPanelPickEdit::onPickChanged, this, _1), NULL);
-
- LLTextEditor* text_edit = getChild<LLTextEditor>("pick_desc");
- text_edit->setKeystrokeCallback(boost::bind(&LLPanelPickEdit::onPickChanged, this, _1));
-
- childSetAction(XML_BTN_SAVE, boost::bind(&LLPanelPickEdit::onClickSave, this));
- childSetAction("set_to_curr_location_btn", boost::bind(&LLPanelPickEdit::onClickSetLocation, this));
-
- initTexturePickerMouseEvents();
-
- return TRUE;
-}
-
-void LLPanelPickEdit::setSaveCallback(const commit_callback_t& cb)
-{
- getChild<LLButton>("save_changes_btn")->setClickedCallback(cb);
-}
-
-void LLPanelPickEdit::setCancelCallback(const commit_callback_t& cb)
-{
- getChild<LLButton>("cancel_btn")->setClickedCallback(cb);
-}
-
-void LLPanelPickEdit::resetDirty()
-{
- LLPanelPickInfo::resetDirty();
-
- getChild<LLLineEditor>("pick_name")->resetDirty();
- getChild<LLTextEditor>("pick_desc")->resetDirty();
- mSnapshotCtrl->resetDirty();
- mLocationChanged = false;
-}
-
-BOOL LLPanelPickEdit::isDirty() const
-{
- if( mNewPick
- || LLPanelPickInfo::isDirty()
- || mLocationChanged
- || mSnapshotCtrl->isDirty()
- || getChild<LLLineEditor>("pick_name")->isDirty()
- || getChild<LLTextEditor>("pick_desc")->isDirty())
- {
- return TRUE;
- }
- return FALSE;
-}
-
-// PROTECTED AREA
-
-void LLPanelPickEdit::sendUpdate()
-{
- LLPickData pick_data;
-
- // If we don't have a pick id yet, we'll need to generate one,
- // otherwise we'll keep overwriting pick_id 00000 in the database.
- if (getPickId().isNull())
- {
- getPickId().generate();
- }
-
- pick_data.agent_id = gAgent.getID();
- pick_data.session_id = gAgent.getSessionID();
- pick_data.pick_id = getPickId();
- pick_data.creator_id = gAgent.getID();;
-
- //legacy var need to be deleted
- pick_data.top_pick = FALSE;
- pick_data.parcel_id = mParcelId;
- pick_data.name = getChild<LLUICtrl>(XML_NAME)->getValue().asString();
- pick_data.desc = getChild<LLUICtrl>(XML_DESC)->getValue().asString();
- pick_data.snapshot_id = mSnapshotCtrl->getImageAssetID();
- pick_data.pos_global = getPosGlobal();
- pick_data.sort_order = 0;
- pick_data.enabled = TRUE;
-
- LLAvatarPropertiesProcessor::instance().sendPickInfoUpdate(&pick_data);
-
- if(mNewPick)
- {
- // Assume a successful create pick operation, make new number of picks
- // available immediately. Actual number of picks will be requested in
- // LLAvatarPropertiesProcessor::sendPickInfoUpdate and updated upon server respond.
- LLAgentPicksInfo::getInstance()->incrementNumberOfPicks();
- }
-}
-
-void LLPanelPickEdit::onSnapshotChanged()
-{
- enableSaveButton(true);
-}
-
-void LLPanelPickEdit::onPickChanged(LLUICtrl* ctrl)
-{
- enableSaveButton(isDirty());
-}
-
-void LLPanelPickEdit::resetData()
-{
- LLPanelPickInfo::resetData();
- mLocationChanged = false;
-}
-
-void LLPanelPickEdit::enableSaveButton(bool enable)
-{
- getChildView(XML_BTN_SAVE)->setEnabled(enable);
-}
-
-void LLPanelPickEdit::onClickSetLocation()
-{
- // Save location for later use.
- setPosGlobal(gAgent.getPositionGlobal());
-
- std::string parcel_name, region_name;
-
- LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
- if (parcel)
- {
- mParcelId = parcel->getID();
- parcel_name = parcel->getName();
- }
-
- LLViewerRegion* region = gAgent.getRegion();
- if(region)
- {
- region_name = region->getName();
- }
-
- setPickLocation(createLocationText(getLocationNotice(), parcel_name, region_name, getPosGlobal()));
-
- mLocationChanged = true;
- enableSaveButton(TRUE);
-}
-
-void LLPanelPickEdit::onClickSave()
-{
- sendUpdate();
-
- mLocationChanged = false;
-
- LLSD params;
- params["action"] = "save_new_pick";
- notifyParent(params);
-}
-
-std::string LLPanelPickEdit::getLocationNotice()
-{
- static std::string notice = getString("location_notice");
- return notice;
-}
-
-void LLPanelPickEdit::processProperties(void* data, EAvatarProcessorType type)
-{
- if(mNeedData)
- {
- LLPanelPickInfo::processProperties(data, type);
- }
-}
-
-// PRIVATE AREA
-
-void LLPanelPickEdit::initTexturePickerMouseEvents()
-{
- text_icon = getChild<LLIconCtrl>(XML_BTN_ON_TXTR);
- mSnapshotCtrl->setMouseEnterCallback(boost::bind(&LLPanelPickEdit::onTexturePickerMouseEnter, this, _1));
- mSnapshotCtrl->setMouseLeaveCallback(boost::bind(&LLPanelPickEdit::onTexturePickerMouseLeave, this, _1));
-
- text_icon->setVisible(FALSE);
-}
-
-void LLPanelPickEdit::onTexturePickerMouseEnter(LLUICtrl* ctrl)
-{
- text_icon->setVisible(TRUE);
-}
-
-void LLPanelPickEdit::onTexturePickerMouseLeave(LLUICtrl* ctrl)
-{
- text_icon->setVisible(FALSE);
-}
diff --git a/indra/newview/llpanelpick.h b/indra/newview/llpanelpick.h
deleted file mode 100644
index 7a8bd66fcf..0000000000
--- a/indra/newview/llpanelpick.h
+++ /dev/null
@@ -1,264 +0,0 @@
-/**
- * @file llpanelpick.h
- * @brief LLPanelPick class definition
- *
- * $LicenseInfo:firstyear=2004&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$
- */
-
-// Display of a "Top Pick" used both for the global top picks in the
-// Find directory, and also for each individual user's picks in their
-// profile.
-
-#ifndef LL_LLPANELPICK_H
-#define LL_LLPANELPICK_H
-
-#include "llpanel.h"
-#include "llremoteparcelrequest.h"
-#include "llavatarpropertiesprocessor.h"
-
-class LLIconCtrl;
-class LLTextureCtrl;
-class LLScrollContainer;
-class LLMessageSystem;
-class LLAvatarPropertiesObserver;
-
-/**
- * Panel for displaying Pick Information - snapshot, name, description, etc.
- */
-class LLPanelPickInfo : public LLPanel, public LLAvatarPropertiesObserver, LLRemoteParcelInfoObserver
-{
- LOG_CLASS(LLPanelPickInfo);
-public:
-
- // Creates new panel
- static LLPanelPickInfo* create();
-
- virtual ~LLPanelPickInfo();
-
- /**
- * Initializes panel properties
- *
- * By default Pick will be created for current Agent location.
- * Use setPickData to change Pick properties.
- */
- /*virtual*/ void onOpen(const LLSD& key);
-
- /*virtual*/ BOOL postBuild();
-
- /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
-
- /*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
-
- /**
- * Sends remote parcel info request to resolve parcel name from its ID.
- */
- void sendParcelInfoRequest();
-
- /**
- * Sets "Back" button click callback
- */
- virtual void setExitCallback(const commit_callback_t& cb);
-
- /**
- * Sets "Edit" button click callback
- */
- virtual void setEditPickCallback(const commit_callback_t& cb);
-
- //This stuff we got from LLRemoteParcelObserver, in the last one we intentionally do nothing
- /*virtual*/ void processParcelInfo(const LLParcelData& parcel_data);
- /*virtual*/ void setParcelID(const LLUUID& parcel_id) { mParcelId = parcel_id; }
- /*virtual*/ void setErrorStatus(S32 status, const std::string& reason) {};
-
-protected:
-
- LLPanelPickInfo();
-
- /**
- * Resets Pick information
- */
- virtual void resetData();
-
- /**
- * Resets UI controls (visibility, values)
- */
- virtual void resetControls();
-
- /**
- * "Location text" is actually the owner name, the original
- * name that owner gave the parcel, and the location.
- */
- static std::string createLocationText(
- const std::string& owner_name,
- const std::string& original_name,
- const std::string& sim_name,
- const LLVector3d& pos_global);
-
- virtual void setAvatarId(const LLUUID& avatar_id) { mAvatarId = avatar_id; }
- virtual LLUUID& getAvatarId() { return mAvatarId; }
-
- /**
- * Sets snapshot id.
- *
- * Will mark snapshot control as valid if id is not null.
- * Will mark snapshot control as invalid if id is null. If null id is a valid value,
- * you have to manually mark snapshot is valid.
- */
- virtual void setSnapshotId(const LLUUID& id);
-
- virtual void setPickId(const LLUUID& id) { mPickId = id; }
- virtual LLUUID& getPickId() { return mPickId; }
-
- virtual void setPickName(const std::string& name);
-
- virtual void setPickDesc(const std::string& desc);
-
- virtual void setPickLocation(const std::string& location);
-
- virtual void setPosGlobal(const LLVector3d& pos) { mPosGlobal = pos; }
- virtual LLVector3d& getPosGlobal() { return mPosGlobal; }
-
- /**
- * Callback for "Map" button, opens Map
- */
- void onClickMap();
-
- /**
- * Callback for "Teleport" button, teleports user to Pick location.
- */
- void onClickTeleport();
-
- void onClickBack();
-
-protected:
-
- S32 mScrollingPanelMinHeight;
- S32 mScrollingPanelWidth;
- LLScrollContainer* mScrollContainer;
- LLPanel* mScrollingPanel;
- LLTextureCtrl* mSnapshotCtrl;
-
- LLUUID mAvatarId;
- LLVector3d mPosGlobal;
- LLUUID mParcelId;
- LLUUID mPickId;
- LLUUID mRequestedId;
-};
-
-/**
- * Panel for creating/editing Pick.
- */
-class LLPanelPickEdit : public LLPanelPickInfo
-{
- LOG_CLASS(LLPanelPickEdit);
-public:
-
- /**
- * Creates new panel
- */
- static LLPanelPickEdit* create();
-
- /*virtual*/ ~LLPanelPickEdit();
-
- /*virtual*/ void onOpen(const LLSD& key);
-
- virtual void setPickData(const LLPickData* pick_data);
-
- /*virtual*/ BOOL postBuild();
-
- /**
- * Sets "Save" button click callback
- */
- virtual void setSaveCallback(const commit_callback_t& cb);
-
- /**
- * Sets "Cancel" button click callback
- */
- virtual void setCancelCallback(const commit_callback_t& cb);
-
- /**
- * Resets panel and all cantrols to unedited state
- */
- /*virtual*/ void resetDirty();
-
- /**
- * Returns true if any of Pick properties was changed by user.
- */
- /*virtual*/ BOOL isDirty() const;
-
- /*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
-
-protected:
-
- LLPanelPickEdit();
-
- /**
- * Sends Pick properties to server.
- */
- void sendUpdate();
-
- /**
- * Called when snapshot image changes.
- */
- void onSnapshotChanged();
-
- /**
- * Callback for Pick snapshot, name and description changed event.
- */
- void onPickChanged(LLUICtrl* ctrl);
-
- /*virtual*/ void resetData();
-
- /**
- * Enables/disables "Save" button
- */
- void enableSaveButton(bool enable);
-
- /**
- * Callback for "Set Location" button click
- */
- void onClickSetLocation();
-
- /**
- * Callback for "Save" button click
- */
- void onClickSave();
-
- std::string getLocationNotice();
-
-protected:
-
- bool mLocationChanged;
- bool mNeedData;
- bool mNewPick;
-
-private:
-
- void initTexturePickerMouseEvents();
- void onTexturePickerMouseEnter(LLUICtrl* ctrl);
- void onTexturePickerMouseLeave(LLUICtrl* ctrl);
-
-private:
-
- LLIconCtrl* text_icon;
-};
-
-#endif // LL_LLPANELPICK_H
diff --git a/indra/newview/llpanelpicks.cpp b/indra/newview/llpanelpicks.cpp
deleted file mode 100644
index 8294977f99..0000000000
--- a/indra/newview/llpanelpicks.cpp
+++ /dev/null
@@ -1,1484 +0,0 @@
-/**
- * @file llpanelpicks.cpp
- * @brief LLPanelPicks and related class implementations
- *
- * $LicenseInfo:firstyear=2009&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$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llpanelpicks.h"
-
-#include "llagent.h"
-#include "llagentpicksinfo.h"
-#include "llcommandhandler.h"
-#include "lldispatcher.h"
-#include "llflatlistview.h"
-#include "llfloaterreg.h"
-#include "llfloatersidepanelcontainer.h"
-#include "llfloaterworldmap.h"
-#include "llnotificationsutil.h"
-#include "llstartup.h"
-#include "lltexturectrl.h"
-#include "lltoggleablemenu.h"
-#include "lltrans.h"
-#include "llviewergenericmessage.h" // send_generic_message
-#include "llmenugl.h"
-#include "llviewermenu.h"
-#include "llregistry.h"
-
-#include "llaccordionctrl.h"
-#include "llaccordionctrltab.h"
-#include "llavatarpropertiesprocessor.h"
-#include "llfloatersidepanelcontainer.h"
-#include "llpanelavatar.h"
-#include "llpanelprofile.h"
-#include "llpanelpick.h"
-#include "llpanelclassified.h"
-
-static const std::string XML_BTN_NEW = "new_btn";
-static const std::string XML_BTN_DELETE = "trash_btn";
-static const std::string XML_BTN_INFO = "info_btn";
-static const std::string XML_BTN_TELEPORT = "teleport_btn";
-static const std::string XML_BTN_SHOW_ON_MAP = "show_on_map_btn";
-
-static const std::string PICK_ID("pick_id");
-static const std::string PICK_CREATOR_ID("pick_creator_id");
-static const std::string PICK_NAME("pick_name");
-
-static const std::string CLASSIFIED_ID("classified_id");
-static const std::string CLASSIFIED_NAME("classified_name");
-
-
-static LLPanelInjector<LLPanelPicks> t_panel_picks("panel_picks");
-
-
-class LLPickHandler : public LLCommandHandler,
- public LLAvatarPropertiesObserver
-{
-public:
-
- std::set<LLUUID> mPickIds;
-
- // requires trusted browser to trigger
- LLPickHandler() : LLCommandHandler("pick", UNTRUSTED_THROTTLE) { }
-
- bool handle(const LLSD& params, const LLSD& query_map,
- LLMediaCtrl* web)
- {
- if (LLStartUp::getStartupState() < STATE_STARTED)
- {
- return true;
- }
-
- if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnablePicks"))
- {
- LLNotificationsUtil::add("NoPicks", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit"));
- return true;
- }
-
- // handle app/classified/create urls first
- if (params.size() == 1 && params[0].asString() == "create")
- {
- createPick();
- return true;
- }
-
- // then handle the general app/pick/{UUID}/{CMD} urls
- if (params.size() < 2)
- {
- return false;
- }
-
- // get the ID for the pick_id
- LLUUID pick_id;
- if (!pick_id.set(params[0], FALSE))
- {
- return false;
- }
-
- // edit the pick in the side tray.
- // need to ask the server for more info first though...
- const std::string verb = params[1].asString();
- if (verb == "edit")
- {
- mPickIds.insert(pick_id);
- LLAvatarPropertiesProcessor::getInstance()->addObserver(LLUUID(), this);
- LLAvatarPropertiesProcessor::getInstance()->sendPickInfoRequest(gAgent.getID(),pick_id);
- return true;
- }
- else
- {
- LL_WARNS() << "unknown verb " << verb << LL_ENDL;
- return false;
- }
- }
-
- void createPick()
- {
- // open the new pick panel on the Picks floater
- LLFloater* picks_floater = LLFloaterReg::showInstance("picks");
-
- LLPanelPicks* picks = picks_floater->findChild<LLPanelPicks>("panel_picks");
- if (picks)
- {
- picks->createNewPick();
- }
- }
-
- void editPick(LLPickData* pick_info)
- {
- LLSD params;
- params["open_tab_name"] = "panel_picks";
- params["show_tab_panel"] = "edit_pick";
- params["pick_id"] = pick_info->pick_id;
- params["avatar_id"] = pick_info->creator_id;
- params["snapshot_id"] = pick_info->snapshot_id;
- params["pick_name"] = pick_info->name;
- params["pick_desc"] = pick_info->desc;
- LLFloaterSidePanelContainer::showPanel("picks", params);
- }
-
- /*virtual*/ void processProperties(void* data, EAvatarProcessorType type)
- {
- if (APT_PICK_INFO != type)
- {
- return;
- }
-
- // is this the pick that we asked for?
- LLPickData* pick_info = static_cast<LLPickData*>(data);
- if (!pick_info || mPickIds.find(pick_info->pick_id) == mPickIds.end())
- {
- return;
- }
-
- // open the edit side tray for this pick
- if (pick_info->creator_id == gAgent.getID())
- {
- editPick(pick_info);
- }
- else
- {
- LL_WARNS() << "Can't edit a pick you did not create" << LL_ENDL;
- }
-
- // remove our observer now that we're done
- mPickIds.erase(pick_info->pick_id);
- LLAvatarPropertiesProcessor::getInstance()->removeObserver(LLUUID(), this);
- }
-};
-
-LLPickHandler gPickHandler;
-
-class LLClassifiedHandler :
- public LLCommandHandler,
- public LLAvatarPropertiesObserver
-{
-public:
- // throttle calls from untrusted browsers
- LLClassifiedHandler() : LLCommandHandler("classified", UNTRUSTED_THROTTLE) {}
-
- std::set<LLUUID> mClassifiedIds;
-
- std::string mRequestVerb;
-
- bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web)
- {
- if (LLStartUp::getStartupState() < STATE_STARTED)
- {
- return true;
- }
-
- if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnableClassifieds"))
- {
- LLNotificationsUtil::add("NoClassifieds", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit"));
- return true;
- }
-
- // handle app/classified/create urls first
- if (params.size() == 1 && params[0].asString() == "create")
- {
- createClassified();
- return true;
- }
-
- // then handle the general app/classified/{UUID}/{CMD} urls
- if (params.size() < 2)
- {
- return false;
- }
-
- // get the ID for the classified
- LLUUID classified_id;
- if (!classified_id.set(params[0], FALSE))
- {
- return false;
- }
-
- // show the classified in the side tray.
- // need to ask the server for more info first though...
- const std::string verb = params[1].asString();
- if (verb == "about")
- {
- mRequestVerb = verb;
- mClassifiedIds.insert(classified_id);
- LLAvatarPropertiesProcessor::getInstance()->addObserver(LLUUID(), this);
- LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoRequest(classified_id);
- return true;
- }
- else if (verb == "edit")
- {
- mRequestVerb = verb;
- mClassifiedIds.insert(classified_id);
- LLAvatarPropertiesProcessor::getInstance()->addObserver(LLUUID(), this);
- LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoRequest(classified_id);
- return true;
- }
-
- return false;
- }
-
- void createClassified()
- {
- // open the new classified panel on the Picks floater
- LLFloater* picks_floater = LLFloaterReg::showInstance("picks");
-
- LLPanelPicks* picks = picks_floater->findChild<LLPanelPicks>("panel_picks");
- if (picks)
- {
- picks->createNewClassified();
- }
- }
-
- void openClassified(LLAvatarClassifiedInfo* c_info)
- {
- if (mRequestVerb == "about")
- {
- // open the classified info panel on the Me > Picks sidetray
- LLSD params;
- params["id"] = c_info->creator_id;
- params["open_tab_name"] = "panel_picks";
- params["show_tab_panel"] = "classified_details";
- params["classified_id"] = c_info->classified_id;
- params["classified_creator_id"] = c_info->creator_id;
- params["classified_snapshot_id"] = c_info->snapshot_id;
- params["classified_name"] = c_info->name;
- params["classified_desc"] = c_info->description;
- params["from_search"] = true;
- LLFloaterSidePanelContainer::showPanel("picks", params);
- }
- else if (mRequestVerb == "edit")
- {
- if (c_info->creator_id == gAgent.getID())
- {
- LL_WARNS() << "edit in progress" << LL_ENDL;
- // open the new classified panel on the Me > Picks sidetray
- LLSD params;
- params["id"] = gAgent.getID();
- params["open_tab_name"] = "panel_picks";
- params["show_tab_panel"] = "edit_classified";
- params["classified_id"] = c_info->classified_id;
- LLFloaterSidePanelContainer::showPanel("my_profile", params);
- }
- else
- {
- LL_WARNS() << "Can't edit a classified you did not create" << LL_ENDL;
- }
- }
- }
-
- /*virtual*/ void processProperties(void* data, EAvatarProcessorType type)
- {
- if (APT_CLASSIFIED_INFO != type)
- {
- return;
- }
-
- // is this the classified that we asked for?
- LLAvatarClassifiedInfo* c_info = static_cast<LLAvatarClassifiedInfo*>(data);
- if (!c_info || mClassifiedIds.find(c_info->classified_id) == mClassifiedIds.end())
- {
- return;
- }
-
- // open the detail side tray for this classified
- openClassified(c_info);
-
- // remove our observer now that we're done
- mClassifiedIds.erase(c_info->classified_id);
- LLAvatarPropertiesProcessor::getInstance()->removeObserver(LLUUID(), this);
- }
-
-};
-LLClassifiedHandler gClassifiedHandler;
-
-//////////////////////////////////////////////////////////////////////////
-
-
-//-----------------------------------------------------------------------------
-// LLPanelPicks
-//-----------------------------------------------------------------------------
-LLPanelPicks::LLPanelPicks()
-: LLPanelProfileTab(),
- mPopupMenu(NULL),
- mProfilePanel(NULL),
- mPickPanel(NULL),
- mPicksList(NULL),
- mClassifiedsList(NULL),
- mPanelPickInfo(NULL),
- mPanelPickEdit(NULL),
- mPlusMenu(NULL),
- mPicksAccTab(NULL),
- mClassifiedsAccTab(NULL),
- mPanelClassifiedInfo(NULL),
- mNoClassifieds(false),
- mNoPicks(false)
-{
-}
-
-LLPanelPicks::~LLPanelPicks()
-{
- if(getAvatarId().notNull())
- {
- LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(),this);
- }
-}
-
-void* LLPanelPicks::create(void* data /* = NULL */)
-{
- return new LLPanelPicks();
-}
-
-void LLPanelPicks::updateData()
-{
- // Send Picks request only when we need to, not on every onOpen(during tab switch).
- if(isDirty())
- {
- mNoPicks = false;
- mNoClassifieds = false;
-
- mNoItemsLabel->setValue(LLTrans::getString("PicksClassifiedsLoadingText"));
- mNoItemsLabel->setVisible(TRUE);
-
- mPicksList->clear();
- LLAvatarPropertiesProcessor::getInstance()->sendAvatarPicksRequest(getAvatarId());
-
- mClassifiedsList->clear();
- LLAvatarPropertiesProcessor::getInstance()->sendAvatarClassifiedsRequest(getAvatarId());
- }
-}
-
-void LLPanelPicks::processProperties(void* data, EAvatarProcessorType type)
-{
- if(APT_PICKS == type)
- {
- LLAvatarPicks* avatar_picks = static_cast<LLAvatarPicks*>(data);
- if(avatar_picks && getAvatarId() == avatar_picks->target_id)
- {
- LLAvatarName av_name;
- LLAvatarNameCache::get(getAvatarId(), &av_name);
- getChild<LLUICtrl>("pick_title")->setTextArg("[NAME]", av_name.getUserName());
-
- // Save selection, to be able to edit same item after saving changes. See EXT-3023.
- LLUUID selected_id = mPicksList->getSelectedValue()[PICK_ID];
-
- mPicksList->clear();
-
- LLAvatarPicks::picks_list_t::const_iterator it = avatar_picks->picks_list.begin();
- for(; avatar_picks->picks_list.end() != it; ++it)
- {
- LLUUID pick_id = it->first;
- std::string pick_name = it->second;
-
- LLPickItem* picture = LLPickItem::create();
- picture->childSetAction("info_chevron", boost::bind(&LLPanelPicks::onClickInfo, this));
- picture->setPickName(pick_name);
- picture->setPickId(pick_id);
- picture->setCreatorId(getAvatarId());
-
- LLAvatarPropertiesProcessor::instance().addObserver(getAvatarId(), picture);
- picture->update();
-
- LLSD pick_value = LLSD();
- pick_value.insert(PICK_ID, pick_id);
- pick_value.insert(PICK_NAME, pick_name);
- pick_value.insert(PICK_CREATOR_ID, getAvatarId());
-
- mPicksList->addItem(picture, pick_value);
-
- // Restore selection by item id.
- if ( pick_id == selected_id )
- mPicksList->selectItemByValue(pick_value);
-
- picture->setDoubleClickCallback(boost::bind(&LLPanelPicks::onDoubleClickPickItem, this, _1));
- picture->setRightMouseUpCallback(boost::bind(&LLPanelPicks::onRightMouseUpItem, this, _1, _2, _3, _4));
- picture->setMouseUpCallback(boost::bind(&LLPanelPicks::updateButtons, this));
- }
-
- showAccordion("tab_picks", mPicksList->size());
-
- resetDirty();
- updateButtons();
- }
-
- mNoPicks = !mPicksList->size();
- }
- else if((APT_CLASSIFIEDS == type) || (APT_CLASSIFIED_INFO == type))
- {
- LLAvatarClassifieds* c_info = static_cast<LLAvatarClassifieds*>(data);
- if(c_info && getAvatarId() == c_info->target_id)
- {
- // do not clear classified list in case we will receive two or more data packets.
- // list has been cleared in updateData(). (fix for EXT-6436)
-
- LLAvatarClassifieds::classifieds_list_t::const_iterator it = c_info->classifieds_list.begin();
- for(; c_info->classifieds_list.end() != it; ++it)
- {
- LLAvatarClassifieds::classified_data c_data = *it;
-
- LLClassifiedItem* c_item = new LLClassifiedItem(getAvatarId(), c_data.classified_id);
- c_item->childSetAction("info_chevron", boost::bind(&LLPanelPicks::onClickInfo, this));
- c_item->setClassifiedName(c_data.name);
-
- LLSD pick_value = LLSD();
- pick_value.insert(CLASSIFIED_ID, c_data.classified_id);
- pick_value.insert(CLASSIFIED_NAME, c_data.name);
-
- if (!findClassifiedById(c_data.classified_id))
- {
- mClassifiedsList->addItem(c_item, pick_value);
- }
-
- c_item->setDoubleClickCallback(boost::bind(&LLPanelPicks::onDoubleClickClassifiedItem, this, _1));
- c_item->setRightMouseUpCallback(boost::bind(&LLPanelPicks::onRightMouseUpItem, this, _1, _2, _3, _4));
- c_item->setMouseUpCallback(boost::bind(&LLPanelPicks::updateButtons, this));
- }
-
- showAccordion("tab_classifieds", mClassifiedsList->size());
-
- resetDirty();
- updateButtons();
- }
-
- mNoClassifieds = !mClassifiedsList->size();
- }
-
- updateNoItemsLabel();
-}
-
-LLPickItem* LLPanelPicks::getSelectedPickItem()
-{
- LLPanel* selected_item = mPicksList->getSelectedItem();
- if (!selected_item) return NULL;
-
- return dynamic_cast<LLPickItem*>(selected_item);
-}
-
-LLClassifiedItem* LLPanelPicks::getSelectedClassifiedItem()
-{
- LLPanel* selected_item = mClassifiedsList->getSelectedItem();
- if (!selected_item)
- {
- return NULL;
- }
- return dynamic_cast<LLClassifiedItem*>(selected_item);
-}
-
-BOOL LLPanelPicks::postBuild()
-{
- mPicksList = getChild<LLFlatListView>("picks_list");
- mClassifiedsList = getChild<LLFlatListView>("classifieds_list");
-
- mPicksList->setCommitOnSelectionChange(true);
- mClassifiedsList->setCommitOnSelectionChange(true);
-
- mPicksList->setCommitCallback(boost::bind(&LLPanelPicks::onListCommit, this, mPicksList));
- mClassifiedsList->setCommitCallback(boost::bind(&LLPanelPicks::onListCommit, this, mClassifiedsList));
-
- mPicksList->setNoItemsCommentText(getString("no_picks"));
- mClassifiedsList->setNoItemsCommentText(getString("no_classifieds"));
-
- mNoItemsLabel = getChild<LLUICtrl>("picks_panel_text");
-
- childSetAction(XML_BTN_NEW, boost::bind(&LLPanelPicks::onClickPlusBtn, this));
- childSetAction(XML_BTN_DELETE, boost::bind(&LLPanelPicks::onClickDelete, this));
- childSetAction(XML_BTN_TELEPORT, boost::bind(&LLPanelPicks::onClickTeleport, this));
- childSetAction(XML_BTN_SHOW_ON_MAP, boost::bind(&LLPanelPicks::onClickMap, this));
- childSetAction(XML_BTN_INFO, boost::bind(&LLPanelPicks::onClickInfo, this));
-
- mPicksAccTab = getChild<LLAccordionCtrlTab>("tab_picks");
- mPicksAccTab->setDropDownStateChangedCallback(boost::bind(&LLPanelPicks::onAccordionStateChanged, this, mPicksAccTab));
- mPicksAccTab->setDisplayChildren(true);
-
- mClassifiedsAccTab = getChild<LLAccordionCtrlTab>("tab_classifieds");
- mClassifiedsAccTab->setDropDownStateChangedCallback(boost::bind(&LLPanelPicks::onAccordionStateChanged, this, mClassifiedsAccTab));
- mClassifiedsAccTab->setDisplayChildren(false);
-
- LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registar;
- registar.add("Pick.Info", boost::bind(&LLPanelPicks::onClickInfo, this));
- registar.add("Pick.Edit", boost::bind(&LLPanelPicks::onClickMenuEdit, this));
- registar.add("Pick.Teleport", boost::bind(&LLPanelPicks::onClickTeleport, this));
- registar.add("Pick.Map", boost::bind(&LLPanelPicks::onClickMap, this));
- registar.add("Pick.Delete", boost::bind(&LLPanelPicks::onClickDelete, this));
- LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registar;
- enable_registar.add("Pick.Enable", boost::bind(&LLPanelPicks::onEnableMenuItem, this, _2));
-
- mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>("menu_picks.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
-
- LLUICtrl::CommitCallbackRegistry::ScopedRegistrar plus_registar;
- plus_registar.add("Picks.Plus.Action", boost::bind(&LLPanelPicks::onPlusMenuItemClicked, this, _2));
- mEnableCallbackRegistrar.add("Picks.Plus.Enable", boost::bind(&LLPanelPicks::isActionEnabled, this, _2));
- mPlusMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_picks_plus.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
-
- return TRUE;
-}
-
-void LLPanelPicks::onPlusMenuItemClicked(const LLSD& param)
-{
- std::string value = param.asString();
-
- if("new_pick" == value)
- {
- createNewPick();
- }
- else if("new_classified" == value)
- {
- createNewClassified();
- }
-}
-
-bool LLPanelPicks::isActionEnabled(const LLSD& userdata) const
-{
- std::string command_name = userdata.asString();
-
- if (command_name == "new_pick" && LLAgentPicksInfo::getInstance()->isPickLimitReached())
- {
- return false;
- }
-
- return true;
-}
-
-bool LLPanelPicks::isClassifiedPublished(LLClassifiedItem* c_item)
-{
- if(c_item)
- {
- LLPanelClassifiedEdit* panel = mEditClassifiedPanels[c_item->getClassifiedId()];
- if(panel)
- {
- return !panel->isNewWithErrors();
- }
-
- // we've got this classified from server - it's published
- return true;
- }
- return false;
-}
-
-void LLPanelPicks::onAccordionStateChanged(const LLAccordionCtrlTab* acc_tab)
-{
- if(!mPicksAccTab->getDisplayChildren())
- {
- mPicksList->resetSelection(true);
- }
- if(!mClassifiedsAccTab->getDisplayChildren())
- {
- mClassifiedsList->resetSelection(true);
- }
-
- updateButtons();
-}
-
-void LLPanelPicks::onOpen(const LLSD& key)
-{
- const LLUUID id(key.asUUID());
- BOOL self = (gAgent.getID() == id);
-
- // only agent can edit her picks
- getChildView("edit_panel")->setEnabled(self);
- getChildView("edit_panel")->setVisible( self);
-
- // Disable buttons when viewing profile for first time
- if(getAvatarId() != id)
- {
- getChildView(XML_BTN_INFO)->setEnabled(FALSE);
- getChildView(XML_BTN_TELEPORT)->setEnabled(FALSE);
- getChildView(XML_BTN_SHOW_ON_MAP)->setEnabled(FALSE);
- }
-
- // and see a special title - set as invisible by default in xml file
- if (self)
- {
- getChildView("pick_title")->setVisible( !self);
- getChildView("pick_title_agent")->setVisible( self);
-
- mPopupMenu->setItemVisible("pick_delete", TRUE);
- mPopupMenu->setItemVisible("pick_edit", TRUE);
- mPopupMenu->setItemVisible("pick_separator", TRUE);
- }
-
- if(getAvatarId() != id)
- {
- showAccordion("tab_picks", false);
- showAccordion("tab_classifieds", false);
-
- mPicksList->goToTop();
- // Set dummy value to make panel dirty and make it reload picks
- setValue(LLSD());
- }
-
- LLPanelProfileTab::onOpen(key);
-}
-
-void LLPanelPicks::onClosePanel()
-{
- if (mPanelClassifiedInfo)
- {
- onPanelClassifiedClose(mPanelClassifiedInfo);
- }
- if (mPanelPickInfo)
- {
- onPanelPickClose(mPanelPickInfo);
- }
-}
-
-void LLPanelPicks::onListCommit(const LLFlatListView* f_list)
-{
- // Make sure only one of the lists has selection.
- if(f_list == mPicksList)
- {
- mClassifiedsList->resetSelection(true);
- }
- else if(f_list == mClassifiedsList)
- {
- mPicksList->resetSelection(true);
- }
- else
- {
- LL_WARNS() << "Unknown list" << LL_ENDL;
- }
-
- updateButtons();
-}
-
-//static
-void LLPanelPicks::onClickDelete()
-{
- LLSD value = mPicksList->getSelectedValue();
- if (value.isDefined())
- {
- LLSD args;
- args["PICK"] = value[PICK_NAME];
- LLNotificationsUtil::add("DeleteAvatarPick", args, LLSD(), boost::bind(&LLPanelPicks::callbackDeletePick, this, _1, _2));
- return;
- }
-
- value = mClassifiedsList->getSelectedValue();
- if(value.isDefined())
- {
- LLSD args;
- args["NAME"] = value[CLASSIFIED_NAME];
- LLNotificationsUtil::add("DeleteClassified", args, LLSD(), boost::bind(&LLPanelPicks::callbackDeleteClassified, this, _1, _2));
- return;
- }
-}
-
-bool LLPanelPicks::callbackDeletePick(const LLSD& notification, const LLSD& response)
-{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- LLSD pick_value = mPicksList->getSelectedValue();
-
- if (0 == option)
- {
- LLAvatarPropertiesProcessor::instance().sendPickDelete(pick_value[PICK_ID]);
- mPicksList->removeItemByValue(pick_value);
-
- mNoPicks = !mPicksList->size();
- if (mNoPicks)
- {
- showAccordion("tab_picks", false);
- }
- updateNoItemsLabel();
- }
- updateButtons();
- return false;
-}
-
-bool LLPanelPicks::callbackDeleteClassified(const LLSD& notification, const LLSD& response)
-{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- LLSD value = mClassifiedsList->getSelectedValue();
-
- if (0 == option)
- {
- LLAvatarPropertiesProcessor::instance().sendClassifiedDelete(value[CLASSIFIED_ID]);
- mClassifiedsList->removeItemByValue(value);
-
- mNoClassifieds = !mClassifiedsList->size();
- if (mNoClassifieds)
- {
- showAccordion("tab_classifieds", false);
- }
- updateNoItemsLabel();
- }
- updateButtons();
- return false;
-}
-
-bool LLPanelPicks::callbackTeleport( const LLSD& notification, const LLSD& response )
-{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
-
- if (0 == option)
- {
- onClickTeleport();
- }
- return false;
-}
-
-//static
-void LLPanelPicks::onClickTeleport()
-{
- LLPickItem* pick_item = getSelectedPickItem();
- LLClassifiedItem* c_item = getSelectedClassifiedItem();
-
- LLVector3d pos;
- if(pick_item)
- pos = pick_item->getPosGlobal();
- else if(c_item)
- {
- pos = c_item->getPosGlobal();
- LLPanelClassifiedInfo::sendClickMessage("teleport", false,
- c_item->getClassifiedId(), LLUUID::null, pos, LLStringUtil::null);
- }
-
- if (!pos.isExactlyZero())
- {
- gAgent.teleportViaLocation(pos);
- LLFloaterWorldMap::getInstance()->trackLocation(pos);
- }
-}
-
-//static
-void LLPanelPicks::onClickMap()
-{
- LLPickItem* pick_item = getSelectedPickItem();
- LLClassifiedItem* c_item = getSelectedClassifiedItem();
-
- LLVector3d pos;
- if (pick_item)
- pos = pick_item->getPosGlobal();
- else if(c_item)
- {
- LLPanelClassifiedInfo::sendClickMessage("map", false,
- c_item->getClassifiedId(), LLUUID::null, pos, LLStringUtil::null);
- pos = c_item->getPosGlobal();
- }
-
- LLFloaterWorldMap::getInstance()->trackLocation(pos);
- LLFloaterReg::showInstance("world_map", "center");
-}
-
-
-void LLPanelPicks::onRightMouseUpItem(LLUICtrl* item, S32 x, S32 y, MASK mask)
-{
- updateButtons();
-
- if (mPopupMenu)
- {
- mPopupMenu->buildDrawLabels();
- mPopupMenu->updateParent(LLMenuGL::sMenuContainer);
- ((LLContextMenu*)mPopupMenu)->show(x, y);
- LLMenuGL::showPopup(item, mPopupMenu, x, y);
- }
-}
-
-void LLPanelPicks::onDoubleClickPickItem(LLUICtrl* item)
-{
- LLSD pick_value = mPicksList->getSelectedValue();
- if (pick_value.isUndefined()) return;
-
- LLSD args;
- args["PICK"] = pick_value[PICK_NAME];
- LLNotificationsUtil::add("TeleportToPick", args, LLSD(), boost::bind(&LLPanelPicks::callbackTeleport, this, _1, _2));
-}
-
-void LLPanelPicks::onDoubleClickClassifiedItem(LLUICtrl* item)
-{
- LLSD value = mClassifiedsList->getSelectedValue();
- if (value.isUndefined()) return;
-
- LLSD args;
- args["CLASSIFIED"] = value[CLASSIFIED_NAME];
- LLNotificationsUtil::add("TeleportToClassified", args, LLSD(), boost::bind(&LLPanelPicks::callbackTeleport, this, _1, _2));
-}
-
-void LLPanelPicks::updateButtons()
-{
- bool has_selected = mPicksList->numSelected() > 0 || mClassifiedsList->numSelected() > 0;
-
- if (getAvatarId() == gAgentID)
- {
- getChildView(XML_BTN_DELETE)->setEnabled(has_selected);
- }
-
- getChildView(XML_BTN_INFO)->setEnabled(has_selected);
- getChildView(XML_BTN_TELEPORT)->setEnabled(has_selected);
- getChildView(XML_BTN_SHOW_ON_MAP)->setEnabled(has_selected);
-
- LLClassifiedItem* c_item = dynamic_cast<LLClassifiedItem*>(mClassifiedsList->getSelectedItem());
- if(c_item)
- {
- getChildView(XML_BTN_INFO)->setEnabled(isClassifiedPublished(c_item));
- }
-}
-
-void LLPanelPicks::updateNoItemsLabel()
-{
- bool no_data = mNoPicks && mNoClassifieds;
- mNoItemsLabel->setVisible(no_data);
- if (no_data)
- {
- if (getAvatarId() == gAgentID)
- {
- mNoItemsLabel->setValue(LLTrans::getString("NoPicksClassifiedsText"));
- }
- else
- {
- mNoItemsLabel->setValue(LLTrans::getString("NoAvatarPicksClassifiedsText"));
- }
- }
-}
-
-void LLPanelPicks::setProfilePanel(LLPanelProfile* profile_panel)
-{
- mProfilePanel = profile_panel;
-}
-
-
-void LLPanelPicks::buildPickPanel()
-{
-// if (mPickPanel == NULL)
-// {
-// mPickPanel = new LLPanelPick();
-// mPickPanel->setExitCallback(boost::bind(&LLPanelPicks::onPanelPickClose, this, NULL));
-// }
-}
-
-void LLPanelPicks::onClickPlusBtn()
-{
- LLRect rect(getChildView(XML_BTN_NEW)->getRect());
-
- mPlusMenu->updateParent(LLMenuGL::sMenuContainer);
- mPlusMenu->setButtonRect(rect, this);
- LLMenuGL::showPopup(this, mPlusMenu, rect.mLeft, rect.mTop);
-}
-
-void LLPanelPicks::createNewPick()
-{
- createPickEditPanel();
-
- getProfilePanel()->openPanel(mPanelPickEdit, LLSD());
-}
-
-void LLPanelPicks::createNewClassified()
-{
- LLPanelClassifiedEdit* panel = NULL;
- createClassifiedEditPanel(&panel);
-
- getProfilePanel()->openPanel(panel, LLSD());
-}
-
-void LLPanelPicks::onClickInfo()
-{
- if(mPicksList->numSelected() > 0)
- {
- openPickInfo();
- }
- else if(mClassifiedsList->numSelected() > 0)
- {
- openClassifiedInfo();
- }
-}
-
-void LLPanelPicks::openPickInfo()
-{
- LLSD selected_value = mPicksList->getSelectedValue();
- if (selected_value.isUndefined()) return;
-
- LLPickItem* pick = (LLPickItem*)mPicksList->getSelectedItem();
-
- createPickInfoPanel();
-
- LLSD params;
- params["pick_id"] = pick->getPickId();
- params["avatar_id"] = pick->getCreatorId();
- params["snapshot_id"] = pick->getSnapshotId();
- params["pick_name"] = pick->getPickName();
- params["pick_desc"] = pick->getPickDesc();
-
- getProfilePanel()->openPanel(mPanelPickInfo, params);
-}
-
-void LLPanelPicks::openClassifiedInfo()
-{
- LLSD selected_value = mClassifiedsList->getSelectedValue();
- if (selected_value.isUndefined()) return;
-
- LLClassifiedItem* c_item = getSelectedClassifiedItem();
- LLSD params;
- params["classified_id"] = c_item->getClassifiedId();
- params["classified_creator_id"] = c_item->getAvatarId();
- params["classified_snapshot_id"] = c_item->getSnapshotId();
- params["classified_name"] = c_item->getClassifiedName();
- params["classified_desc"] = c_item->getDescription();
- params["from_search"] = false;
-
- openClassifiedInfo(params);
-}
-
-void LLPanelPicks::openClassifiedInfo(const LLSD &params)
-{
- createClassifiedInfoPanel();
- getProfilePanel()->openPanel(mPanelClassifiedInfo, params);
-}
-
-void LLPanelPicks::openClassifiedEdit(const LLSD& params)
-{
- LLUUID classified_id = params["classified_id"].asUUID();;
- LL_INFOS() << "opening classified " << classified_id << " for edit" << LL_ENDL;
- editClassified(classified_id);
-}
-
-void LLPanelPicks::showAccordion(const std::string& name, bool show)
-{
- LLAccordionCtrlTab* tab = getChild<LLAccordionCtrlTab>(name);
- tab->setVisible(show);
- LLAccordionCtrl* acc = getChild<LLAccordionCtrl>("accordion");
- acc->arrange();
-}
-
-void LLPanelPicks::onPanelPickClose(LLPanel* panel)
-{
- getProfilePanel()->closePanel(panel);
-}
-
-void LLPanelPicks::onPanelPickSave(LLPanel* panel)
-{
- onPanelPickClose(panel);
- updateButtons();
-}
-
-void LLPanelPicks::onPanelClassifiedSave(LLPanelClassifiedEdit* panel)
-{
- if(!panel->canClose())
- {
- return;
- }
-
- if(panel->isNew())
- {
- mEditClassifiedPanels[panel->getClassifiedId()] = panel;
-
- LLClassifiedItem* c_item = new LLClassifiedItem(getAvatarId(), panel->getClassifiedId());
- c_item->fillIn(panel);
-
- LLSD c_value;
- c_value.insert(CLASSIFIED_ID, c_item->getClassifiedId());
- c_value.insert(CLASSIFIED_NAME, c_item->getClassifiedName());
- mClassifiedsList->addItem(c_item, c_value, ADD_TOP);
-
- c_item->setDoubleClickCallback(boost::bind(&LLPanelPicks::onDoubleClickClassifiedItem, this, _1));
- c_item->setRightMouseUpCallback(boost::bind(&LLPanelPicks::onRightMouseUpItem, this, _1, _2, _3, _4));
- c_item->setMouseUpCallback(boost::bind(&LLPanelPicks::updateButtons, this));
- c_item->childSetAction("info_chevron", boost::bind(&LLPanelPicks::onClickInfo, this));
-
- // order does matter, showAccordion will invoke arrange for accordions.
- mClassifiedsAccTab->changeOpenClose(false);
- showAccordion("tab_classifieds", true);
- }
- else if(panel->isNewWithErrors())
- {
- LLClassifiedItem* c_item = dynamic_cast<LLClassifiedItem*>(mClassifiedsList->getSelectedItem());
- llassert(c_item);
- if (c_item)
- {
- c_item->fillIn(panel);
- }
- }
- else
- {
- onPanelClassifiedClose(panel);
- return;
- }
-
- onPanelPickClose(panel);
- updateButtons();
-}
-
-void LLPanelPicks::onPanelClassifiedClose(LLPanelClassifiedInfo* panel)
-{
- if(panel->getInfoLoaded() && !panel->isDirty())
- {
- std::vector<LLSD> values;
- mClassifiedsList->getValues(values);
- for(size_t n = 0; n < values.size(); ++n)
- {
- LLUUID c_id = values[n][CLASSIFIED_ID].asUUID();
- if(panel->getClassifiedId() == c_id)
- {
- LLClassifiedItem* c_item = dynamic_cast<LLClassifiedItem*>(
- mClassifiedsList->getItemByValue(values[n]));
- llassert(c_item);
- if (c_item)
- {
- c_item->setClassifiedName(panel->getClassifiedName());
- c_item->setDescription(panel->getDescription());
- c_item->setSnapshotId(panel->getSnapshotId());
- }
- }
- }
- }
-
- onPanelPickClose(panel);
- updateButtons();
-}
-
-void LLPanelPicks::createPickInfoPanel()
-{
- if(!mPanelPickInfo)
- {
- mPanelPickInfo = LLPanelPickInfo::create();
- mPanelPickInfo->setExitCallback(boost::bind(&LLPanelPicks::onPanelPickClose, this, mPanelPickInfo));
- mPanelPickInfo->setEditPickCallback(boost::bind(&LLPanelPicks::onPanelPickEdit, this));
- mPanelPickInfo->setVisible(FALSE);
- }
-}
-
-void LLPanelPicks::createClassifiedInfoPanel()
-{
- mPanelClassifiedInfo = LLPanelClassifiedInfo::create();
- mPanelClassifiedInfo->setExitCallback(boost::bind(&LLPanelPicks::onPanelClassifiedClose, this, mPanelClassifiedInfo));
- mPanelClassifiedInfo->setEditClassifiedCallback(boost::bind(&LLPanelPicks::onPanelClassifiedEdit, this));
- mPanelClassifiedInfo->setVisible(FALSE);
-}
-
-void LLPanelPicks::createClassifiedEditPanel(LLPanelClassifiedEdit** panel)
-{
- if(panel)
- {
- LLPanelClassifiedEdit* new_panel = LLPanelClassifiedEdit::create();
- new_panel->setExitCallback(boost::bind(&LLPanelPicks::onPanelClassifiedClose, this, new_panel));
- new_panel->setSaveCallback(boost::bind(&LLPanelPicks::onPanelClassifiedSave, this, new_panel));
- new_panel->setCancelCallback(boost::bind(&LLPanelPicks::onPanelClassifiedClose, this, new_panel));
- new_panel->setVisible(FALSE);
- *panel = new_panel;
- }
-}
-
-void LLPanelPicks::createPickEditPanel()
-{
- mPanelPickEdit = LLPanelPickEdit::create();
- mPanelPickEdit->setExitCallback(boost::bind(&LLPanelPicks::onPanelPickClose, this, mPanelPickEdit));
- mPanelPickEdit->setSaveCallback(boost::bind(&LLPanelPicks::onPanelPickSave, this, mPanelPickEdit));
- mPanelPickEdit->setCancelCallback(boost::bind(&LLPanelPicks::onPanelPickClose, this, mPanelPickEdit));
- mPanelPickEdit->setVisible(FALSE);
-}
-
-// void LLPanelPicks::openPickEditPanel(LLPickItem* pick)
-// {
-// if(!pick)
-// {
-// return;
-// }
-// }
-
-// void LLPanelPicks::openPickInfoPanel(LLPickItem* pick)
-// {
-// if(!mPanelPickInfo)
-// {
-// mPanelPickInfo = LLPanelPickInfo::create();
-// mPanelPickInfo->setExitCallback(boost::bind(&LLPanelPicks::onPanelPickClose, this, mPanelPickInfo));
-// mPanelPickInfo->setEditPickCallback(boost::bind(&LLPanelPicks::onPanelPickEdit, this));
-// mPanelPickInfo->setVisible(FALSE);
-// }
-//
-// LLSD params;
-// params["pick_id"] = pick->getPickId();
-// params["avatar_id"] = pick->getCreatorId();
-// params["snapshot_id"] = pick->getSnapshotId();
-// params["pick_name"] = pick->getPickName();
-// params["pick_desc"] = pick->getPickDesc();
-//
-// getProfilePanel()->openPanel(mPanelPickInfo, params);
-// }
-
-void LLPanelPicks::openPickEdit(const LLSD& params)
-{
- createPickEditPanel();
- getProfilePanel()->openPanel(mPanelPickEdit, params);
-}
-
-void LLPanelPicks::onPanelPickEdit()
-{
- LLSD selected_value = mPicksList->getSelectedValue();
- if (selected_value.isUndefined()) return;
-
- LLPickItem* pick = dynamic_cast<LLPickItem*>(mPicksList->getSelectedItem());
-
- createPickEditPanel();
-
- LLSD params;
- params["pick_id"] = pick->getPickId();
- params["avatar_id"] = pick->getCreatorId();
- params["snapshot_id"] = pick->getSnapshotId();
- params["pick_name"] = pick->getPickName();
- params["pick_desc"] = pick->getPickDesc();
-
- getProfilePanel()->openPanel(mPanelPickEdit, params);
-}
-
-void LLPanelPicks::onPanelClassifiedEdit()
-{
- LLSD selected_value = mClassifiedsList->getSelectedValue();
- if (selected_value.isUndefined())
- {
- return;
- }
-
- LLClassifiedItem* c_item = dynamic_cast<LLClassifiedItem*>(mClassifiedsList->getSelectedItem());
- llassert(c_item);
- if (!c_item)
- {
- return;
- }
- editClassified(c_item->getClassifiedId());
-}
-
-LLClassifiedItem *LLPanelPicks::findClassifiedById(const LLUUID& classified_id)
-{
- // HACK - find item by classified id. Should be a better way.
- std::vector<LLPanel*> items;
- mClassifiedsList->getItems(items);
- LLClassifiedItem* c_item = NULL;
- for(std::vector<LLPanel*>::iterator it = items.begin(); it != items.end(); ++it)
- {
- LLClassifiedItem *test_item = dynamic_cast<LLClassifiedItem*>(*it);
- if (test_item && test_item->getClassifiedId() == classified_id)
- {
- c_item = test_item;
- break;
- }
- }
- return c_item;
-}
-
-void LLPanelPicks::editClassified(const LLUUID& classified_id)
-{
- LLClassifiedItem* c_item = findClassifiedById(classified_id);
- if (!c_item)
- {
- LL_WARNS() << "item not found for classified_id " << classified_id << LL_ENDL;
- return;
- }
-
- LLSD params;
- params["classified_id"] = c_item->getClassifiedId();
- params["classified_creator_id"] = c_item->getAvatarId();
- params["snapshot_id"] = c_item->getSnapshotId();
- params["name"] = c_item->getClassifiedName();
- params["desc"] = c_item->getDescription();
- params["category"] = (S32)c_item->getCategory();
- params["content_type"] = (S32)c_item->getContentType();
- params["auto_renew"] = c_item->getAutoRenew();
- params["price_for_listing"] = c_item->getPriceForListing();
- params["location_text"] = c_item->getLocationText();
-
- LLPanelClassifiedEdit* panel = mEditClassifiedPanels[c_item->getClassifiedId()];
- if(!panel)
- {
- createClassifiedEditPanel(&panel);
- mEditClassifiedPanels[c_item->getClassifiedId()] = panel;
- }
- getProfilePanel()->openPanel(panel, params);
- panel->setPosGlobal(c_item->getPosGlobal());
-}
-
-void LLPanelPicks::onClickMenuEdit()
-{
- if(getSelectedPickItem())
- {
- onPanelPickEdit();
- }
- else if(getSelectedClassifiedItem())
- {
- onPanelClassifiedEdit();
- }
-}
-
-bool LLPanelPicks::onEnableMenuItem(const LLSD& user_data)
-{
- std::string param = user_data.asString();
-
- LLClassifiedItem* c_item = dynamic_cast<LLClassifiedItem*>(mClassifiedsList->getSelectedItem());
- if(c_item && "info" == param)
- {
- // dont show Info panel if classified was not created
- return isClassifiedPublished(c_item);
- }
-
- return true;
-}
-
-inline LLPanelProfile* LLPanelPicks::getProfilePanel()
-{
- llassert_always(NULL != mProfilePanel);
- return mProfilePanel;
-}
-
-//-----------------------------------------------------------------------------
-// LLPanelPicks
-//-----------------------------------------------------------------------------
-LLPickItem::LLPickItem()
-: LLPanel()
-, mPickID(LLUUID::null)
-, mCreatorID(LLUUID::null)
-, mParcelID(LLUUID::null)
-, mSnapshotID(LLUUID::null)
-, mNeedData(true)
-{
- buildFromFile("panel_pick_list_item.xml");
-}
-
-LLPickItem::~LLPickItem()
-{
- if (mCreatorID.notNull())
- {
- LLAvatarPropertiesProcessor::instance().removeObserver(mCreatorID, this);
- }
-
-}
-
-LLPickItem* LLPickItem::create()
-{
- return new LLPickItem();
-}
-
-void LLPickItem::init(LLPickData* pick_data)
-{
- setPickDesc(pick_data->desc);
- setSnapshotId(pick_data->snapshot_id);
- mPosGlobal = pick_data->pos_global;
- mSimName = pick_data->sim_name;
- mPickDescription = pick_data->desc;
- mUserName = pick_data->user_name;
- mOriginalName = pick_data->original_name;
-
- LLTextureCtrl* picture = getChild<LLTextureCtrl>("picture");
- picture->setImageAssetID(pick_data->snapshot_id);
-}
-
-void LLPickItem::setPickName(const std::string& name)
-{
- mPickName = name;
- getChild<LLUICtrl>("picture_name")->setValue(name);
-
-}
-
-const std::string& LLPickItem::getPickName()
-{
- return mPickName;
-}
-
-const LLUUID& LLPickItem::getCreatorId()
-{
- return mCreatorID;
-}
-
-const LLUUID& LLPickItem::getSnapshotId()
-{
- return mSnapshotID;
-}
-
-void LLPickItem::setPickDesc(const std::string& descr)
-{
- getChild<LLUICtrl>("picture_descr")->setValue(descr);
-}
-
-void LLPickItem::setPickId(const LLUUID& id)
-{
- mPickID = id;
-}
-
-const LLUUID& LLPickItem::getPickId()
-{
- return mPickID;
-}
-
-const LLVector3d& LLPickItem::getPosGlobal()
-{
- return mPosGlobal;
-}
-
-const std::string LLPickItem::getDescription()
-{
- return getChild<LLUICtrl>("picture_descr")->getValue().asString();
-}
-
-void LLPickItem::update()
-{
- setNeedData(true);
- LLAvatarPropertiesProcessor::instance().sendPickInfoRequest(mCreatorID, mPickID);
-}
-
-void LLPickItem::processProperties(void *data, EAvatarProcessorType type)
-{
- if (APT_PICK_INFO != type)
- {
- return;
- }
-
- LLPickData* pick_data = static_cast<LLPickData *>(data);
- if (!pick_data || mPickID != pick_data->pick_id)
- {
- return;
- }
-
- init(pick_data);
- setNeedData(false);
- LLAvatarPropertiesProcessor::instance().removeObserver(mCreatorID, this);
-}
-
-void set_child_visible(LLView* parent, const std::string& child_name, bool visible)
-{
- parent->getChildView(child_name)->setVisible(visible);
-}
-
-BOOL LLPickItem::postBuild()
-{
- setMouseEnterCallback(boost::bind(&set_child_visible, this, "hovered_icon", true));
- setMouseLeaveCallback(boost::bind(&set_child_visible, this, "hovered_icon", false));
- return TRUE;
-}
-
-void LLPickItem::setValue(const LLSD& value)
-{
- if (!value.isMap()) return;;
- if (!value.has("selected")) return;
- getChildView("selected_icon")->setVisible( value["selected"]);
-}
-
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-
-LLClassifiedItem::LLClassifiedItem(const LLUUID& avatar_id, const LLUUID& classified_id)
- : LLPanel()
- , mAvatarId(avatar_id)
- , mClassifiedId(classified_id)
-{
- buildFromFile("panel_classifieds_list_item.xml");
-
- LLAvatarPropertiesProcessor::getInstance()->addObserver(getAvatarId(), this);
- LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoRequest(getClassifiedId());
-}
-
-LLClassifiedItem::~LLClassifiedItem()
-{
- LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
-}
-
-void LLClassifiedItem::processProperties(void* data, EAvatarProcessorType type)
-{
- if(APT_CLASSIFIED_INFO != type)
- {
- return;
- }
-
- LLAvatarClassifiedInfo* c_info = static_cast<LLAvatarClassifiedInfo*>(data);
- if( !c_info || c_info->classified_id != getClassifiedId() )
- {
- return;
- }
-
- setClassifiedName(c_info->name);
- setDescription(c_info->description);
- setSnapshotId(c_info->snapshot_id);
- setPosGlobal(c_info->pos_global);
-
- LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
-}
-
-BOOL LLClassifiedItem::postBuild()
-{
- setMouseEnterCallback(boost::bind(&set_child_visible, this, "hovered_icon", true));
- setMouseLeaveCallback(boost::bind(&set_child_visible, this, "hovered_icon", false));
- return TRUE;
-}
-
-void LLClassifiedItem::setValue(const LLSD& value)
-{
- if (!value.isMap()) return;;
- if (!value.has("selected")) return;
- getChildView("selected_icon")->setVisible( value["selected"]);
-}
-
-void LLClassifiedItem::fillIn(LLPanelClassifiedEdit* panel)
-{
- if(!panel)
- {
- return;
- }
-
- setClassifiedName(panel->getClassifiedName());
- setDescription(panel->getDescription());
- setSnapshotId(panel->getSnapshotId());
- setCategory(panel->getCategory());
- setContentType(panel->getContentType());
- setAutoRenew(panel->getAutoRenew());
- setPriceForListing(panel->getPriceForListing());
- setPosGlobal(panel->getPosGlobal());
- setLocationText(panel->getClassifiedLocation());
-}
-
-void LLClassifiedItem::setClassifiedName(const std::string& name)
-{
- getChild<LLUICtrl>("name")->setValue(name);
-}
-
-void LLClassifiedItem::setDescription(const std::string& desc)
-{
- getChild<LLUICtrl>("description")->setValue(desc);
-}
-
-void LLClassifiedItem::setSnapshotId(const LLUUID& snapshot_id)
-{
- getChild<LLUICtrl>("picture")->setValue(snapshot_id);
-}
-
-LLUUID LLClassifiedItem::getSnapshotId()
-{
- return getChild<LLUICtrl>("picture")->getValue();
-}
-
-//EOF
diff --git a/indra/newview/llpanelpicks.h b/indra/newview/llpanelpicks.h
deleted file mode 100644
index fd7688b99d..0000000000
--- a/indra/newview/llpanelpicks.h
+++ /dev/null
@@ -1,315 +0,0 @@
-/**
- * @file llpanelpicks.h
- * @brief LLPanelPicks and related class definitions
- *
- * $LicenseInfo:firstyear=2009&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$
- */
-
-#ifndef LL_LLPANELPICKS_H
-#define LL_LLPANELPICKS_H
-
-#include "llpanel.h"
-#include "v3dmath.h"
-#include "lluuid.h"
-#include "llavatarpropertiesprocessor.h"
-#include "llpanelavatar.h"
-#include "llregistry.h"
-
-class LLAccordionCtrlTab;
-class LLPanelProfile;
-class LLMessageSystem;
-class LLVector3d;
-class LLPanelProfileTab;
-class LLAgent;
-class LLMenuGL;
-class LLPickItem;
-class LLClassifiedItem;
-class LLFlatListView;
-class LLPanelPickInfo;
-class LLPanelPickEdit;
-class LLToggleableMenu;
-class LLPanelClassifiedInfo;
-class LLPanelClassifiedEdit;
-
-// *TODO
-// Panel Picks has been consolidated with Classifieds (EXT-2095), give LLPanelPicks
-// and corresponding files (cpp, h, xml) a new name. (new name is TBD at the moment)
-
-class LLPanelPicks
- : public LLPanelProfileTab
-{
-public:
- LLPanelPicks();
- ~LLPanelPicks();
-
- static void* create(void* data);
-
- /*virtual*/ BOOL postBuild(void);
-
- /*virtual*/ void onOpen(const LLSD& key);
-
- /*virtual*/ void onClosePanel();
-
- void processProperties(void* data, EAvatarProcessorType type);
-
- void updateData();
-
- // returns the selected pick item
- LLPickItem* getSelectedPickItem();
- LLClassifiedItem* getSelectedClassifiedItem();
- LLClassifiedItem* findClassifiedById(const LLUUID& classified_id);
-
- //*NOTE top down approch when panel toggling is done only by
- // parent panels failed to work (picks related code was in my profile panel)
- void setProfilePanel(LLPanelProfile* profile_panel);
-
- void createNewPick();
- void createNewClassified();
-
-protected:
- /*virtual*/void updateButtons();
- void updateNoItemsLabel();
-
-private:
- void onClickDelete();
- void onClickTeleport();
- void onClickMap();
-
- void onPlusMenuItemClicked(const LLSD& param);
- bool isActionEnabled(const LLSD& userdata) const;
-
- bool isClassifiedPublished(LLClassifiedItem* c_item);
-
- void onListCommit(const LLFlatListView* f_list);
- void onAccordionStateChanged(const LLAccordionCtrlTab* acc_tab);
-
- //------------------------------------------------
- // Callbacks which require panel toggling
- //------------------------------------------------
- void onClickPlusBtn();
- void onClickInfo();
- void onPanelPickClose(LLPanel* panel);
- void onPanelPickSave(LLPanel* panel);
- void onPanelClassifiedSave(LLPanelClassifiedEdit* panel);
- void onPanelClassifiedClose(LLPanelClassifiedInfo* panel);
- void openPickEdit(const LLSD& params);
- void onPanelPickEdit();
- void onPanelClassifiedEdit();
- void editClassified(const LLUUID& classified_id);
- void onClickMenuEdit();
-
- bool onEnableMenuItem(const LLSD& user_data);
-
- void openPickInfo();
- void openClassifiedInfo();
- void openClassifiedInfo(const LLSD& params);
- void openClassifiedEdit(const LLSD& params);
- friend class LLPanelProfile;
-
- void showAccordion(const std::string& name, bool show);
-
- void buildPickPanel();
-
- bool callbackDeletePick(const LLSD& notification, const LLSD& response);
- bool callbackDeleteClassified(const LLSD& notification, const LLSD& response);
- bool callbackTeleport(const LLSD& notification, const LLSD& response);
-
-
- virtual void onDoubleClickPickItem(LLUICtrl* item);
- virtual void onDoubleClickClassifiedItem(LLUICtrl* item);
- virtual void onRightMouseUpItem(LLUICtrl* item, S32 x, S32 y, MASK mask);
-
- LLPanelProfile* getProfilePanel();
-
- void createPickInfoPanel();
- void createPickEditPanel();
- void createClassifiedInfoPanel();
- void createClassifiedEditPanel(LLPanelClassifiedEdit** panel);
-
- LLMenuGL* mPopupMenu;
- LLPanelProfile* mProfilePanel;
- LLPanelPickInfo* mPickPanel;
- LLFlatListView* mPicksList;
- LLFlatListView* mClassifiedsList;
- LLPanelPickInfo* mPanelPickInfo;
- LLPanelClassifiedInfo* mPanelClassifiedInfo;
- LLPanelPickEdit* mPanelPickEdit;
- LLToggleableMenu* mPlusMenu;
- LLUICtrl* mNoItemsLabel;
-
- // <classified_id, edit_panel>
- typedef std::map<LLUUID, LLPanelClassifiedEdit*> panel_classified_edit_map_t;
-
- // This map is needed for newly created classifieds. The purpose of panel is to
- // sit in this map and listen to LLPanelClassifiedEdit::processProperties callback.
- panel_classified_edit_map_t mEditClassifiedPanels;
-
- LLAccordionCtrlTab* mPicksAccTab;
- LLAccordionCtrlTab* mClassifiedsAccTab;
-
- //true if picks list is empty after processing picks
- bool mNoPicks;
- //true if classifieds list is empty after processing classifieds
- bool mNoClassifieds;
-};
-
-class LLPickItem : public LLPanel, public LLAvatarPropertiesObserver
-{
-public:
-
- LLPickItem();
-
- static LLPickItem* create();
-
- void init(LLPickData* pick_data);
-
- void setPickName(const std::string& name);
-
- void setPickDesc(const std::string& descr);
-
- void setPickId(const LLUUID& id);
-
- void setCreatorId(const LLUUID& id) {mCreatorID = id;};
-
- void setSnapshotId(const LLUUID& id) {mSnapshotID = id;};
-
- void setNeedData(bool need){mNeedData = need;};
-
- const LLUUID& getPickId();
-
- const std::string& getPickName();
-
- const LLUUID& getCreatorId();
-
- const LLUUID& getSnapshotId();
-
- const LLVector3d& getPosGlobal();
-
- const std::string getDescription();
-
- const std::string& getSimName() { return mSimName; }
-
- const std::string& getUserName() { return mUserName; }
-
- const std::string& getOriginalName() { return mOriginalName; }
-
- const std::string& getPickDesc() { return mPickDescription; }
-
- /*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
-
- void update();
-
- ~LLPickItem();
-
- /*virtual*/ BOOL postBuild();
-
- /** setting on/off background icon to indicate selected state */
- /*virtual*/ void setValue(const LLSD& value);
-
-protected:
-
- LLUUID mPickID;
- LLUUID mCreatorID;
- LLUUID mParcelID;
- LLUUID mSnapshotID;
- LLVector3d mPosGlobal;
- bool mNeedData;
-
- std::string mPickName;
- std::string mUserName;
- std::string mOriginalName;
- std::string mPickDescription;
- std::string mSimName;
-};
-
-class LLClassifiedItem : public LLPanel, public LLAvatarPropertiesObserver
-{
-public:
-
- LLClassifiedItem(const LLUUID& avatar_id, const LLUUID& classified_id);
-
- virtual ~LLClassifiedItem();
-
- /*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
-
- /*virtual*/ BOOL postBuild();
-
- /*virtual*/ void setValue(const LLSD& value);
-
- void fillIn(LLPanelClassifiedEdit* panel);
-
- LLUUID getAvatarId() {return mAvatarId;}
-
- void setAvatarId(const LLUUID& avatar_id) {mAvatarId = avatar_id;}
-
- LLUUID getClassifiedId() {return mClassifiedId;}
-
- void setClassifiedId(const LLUUID& classified_id) {mClassifiedId = classified_id;}
-
- void setPosGlobal(const LLVector3d& pos) { mPosGlobal = pos; }
-
- const LLVector3d getPosGlobal() { return mPosGlobal; }
-
- void setLocationText(const std::string location) { mLocationText = location; }
-
- std::string getLocationText() { return mLocationText; }
-
- void setClassifiedName (const std::string& name);
-
- std::string getClassifiedName() { return getChild<LLUICtrl>("name")->getValue().asString(); }
-
- void setDescription(const std::string& desc);
-
- std::string getDescription() { return getChild<LLUICtrl>("description")->getValue().asString(); }
-
- void setSnapshotId(const LLUUID& snapshot_id);
-
- LLUUID getSnapshotId();
-
- void setCategory(U32 cat) { mCategory = cat; }
-
- U32 getCategory() { return mCategory; }
-
- void setContentType(U32 ct) { mContentType = ct; }
-
- U32 getContentType() { return mContentType; }
-
- void setAutoRenew(U32 renew) { mAutoRenew = renew; }
-
- bool getAutoRenew() { return mAutoRenew; }
-
- void setPriceForListing(S32 price) { mPriceForListing = price; }
-
- S32 getPriceForListing() { return mPriceForListing; }
-
-private:
- LLUUID mAvatarId;
- LLUUID mClassifiedId;
- LLVector3d mPosGlobal;
- std::string mLocationText;
- U32 mCategory;
- U32 mContentType;
- bool mAutoRenew;
- S32 mPriceForListing;
-};
-
-#endif // LL_LLPANELPICKS_H
diff --git a/indra/newview/llpanelplaceinfo.cpp b/indra/newview/llpanelplaceinfo.cpp
index 9157df789f..fb5957ff8f 100644
--- a/indra/newview/llpanelplaceinfo.cpp
+++ b/indra/newview/llpanelplaceinfo.cpp
@@ -27,6 +27,8 @@
#include "llviewerprecompiledheaders.h"
#include "llpanelplaceinfo.h"
+#include "llfloaterprofile.h"
+#include "llfloaterreg.h"
#include "llavatarname.h"
#include "llsdutil.h"
@@ -42,7 +44,6 @@
#include "llagent.h"
#include "llexpandabletextbox.h"
-#include "llpanelpick.h"
#include "llslurl.h"
#include "lltexturectrl.h"
#include "llviewerregion.h"
@@ -287,7 +288,7 @@ void LLPanelPlaceInfo::reshape(S32 width, S32 height, BOOL called_from_parent)
}
}
-void LLPanelPlaceInfo::createPick(const LLVector3d& pos_global, LLPanelPickEdit* pick_panel)
+void LLPanelPlaceInfo::createPick(const LLVector3d& pos_global)
{
LLPickData data;
data.pos_global = pos_global;
@@ -296,7 +297,12 @@ void LLPanelPlaceInfo::createPick(const LLVector3d& pos_global, LLPanelPickEdit*
data.desc = mDescEditor->getText();
data.snapshot_id = mSnapshotCtrl->getImageAssetID();
data.parcel_id = mParcelID;
- pick_panel->setPickData(&data);
+
+ LLFloaterProfile* profile_floater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", gAgentID)));
+ if (profile_floater)
+ {
+ profile_floater->createPick(data);
+ }
}
// static
diff --git a/indra/newview/llpanelplaceinfo.h b/indra/newview/llpanelplaceinfo.h
index 8bf67cfe7d..533215016a 100644
--- a/indra/newview/llpanelplaceinfo.h
+++ b/indra/newview/llpanelplaceinfo.h
@@ -38,7 +38,6 @@ class LLAvatarName;
class LLExpandableTextBox;
class LLIconCtrl;
class LLInventoryItem;
-class LLPanelPickEdit;
class LLParcel;
class LLScrollContainer;
class LLTextBox;
@@ -94,7 +93,7 @@ public:
// Create a pick for the location specified
// by global_pos.
- void createPick(const LLVector3d& pos_global, LLPanelPickEdit* pick_panel);
+ void createPick(const LLVector3d& pos_global);
protected:
static void onNameCache(LLTextBox* text, const std::string& full_name);
diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp
index 69f181e1b3..74ec576554 100644
--- a/indra/newview/llpanelplaces.cpp
+++ b/indra/newview/llpanelplaces.cpp
@@ -63,7 +63,6 @@
#include "lllayoutstack.h"
#include "llpanellandmarkinfo.h"
#include "llpanellandmarks.h"
-#include "llpanelpick.h"
#include "llpanelplaceprofile.h"
#include "llpanelteleporthistory.h"
#include "llremoteparcelrequest.h"
@@ -238,7 +237,6 @@ LLPanelPlaces::LLPanelPlaces()
mFilterEditor(NULL),
mPlaceProfile(NULL),
mLandmarkInfo(NULL),
- mPickPanel(NULL),
mItem(NULL),
mPlaceMenu(NULL),
mLandmarkMenu(NULL),
@@ -952,28 +950,11 @@ void LLPanelPlaces::onOverflowMenuItemClicked(const LLSD& param)
}
else if (item == "pick")
{
- if (mPickPanel == NULL)
- {
- mPickPanel = LLPanelPickEdit::create();
- addChild(mPickPanel);
-
- mPickPanel->setExitCallback(boost::bind(&LLPanelPlaces::togglePickPanel, this, FALSE));
- mPickPanel->setCancelCallback(boost::bind(&LLPanelPlaces::togglePickPanel, this, FALSE));
- mPickPanel->setSaveCallback(boost::bind(&LLPanelPlaces::togglePickPanel, this, FALSE));
- }
-
- togglePickPanel(TRUE);
- mPickPanel->onOpen(LLSD());
-
LLPanelPlaceInfo* panel = getCurrentInfoPanel();
if (panel)
{
- panel->createPick(mPosGlobal, mPickPanel);
+ panel->createPick(mPosGlobal);
}
-
- LLRect rect = getRect();
- mPickPanel->reshape(rect.getWidth(), rect.getHeight());
- mPickPanel->setRect(rect);
}
else if (item == "add_to_favbar")
{
@@ -1050,17 +1031,6 @@ bool LLPanelPlaces::handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_t
return false;
}
-void LLPanelPlaces::togglePickPanel(BOOL visible)
-{
- if (mPickPanel)
- {
- mPickPanel->setVisible(visible);
- mPlaceProfile->setVisible(!visible);
- updateVerbs();
- }
-
-}
-
void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible)
{
if (!mPlaceProfile || !mLandmarkInfo)
@@ -1309,15 +1279,11 @@ void LLPanelPlaces::updateVerbs()
bool is_agent_place_info_visible = mPlaceInfoType == AGENT_INFO_TYPE;
bool is_create_landmark_visible = mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE;
- bool is_pick_panel_visible = false;
- if(mPickPanel)
- {
- is_pick_panel_visible = mPickPanel->isInVisibleChain();
- }
+
bool have_3d_pos = ! mPosGlobal.isExactlyZero();
- mTeleportBtn->setVisible(!is_create_landmark_visible && !isLandmarkEditModeOn && !is_pick_panel_visible);
- mShowOnMapBtn->setVisible(!is_create_landmark_visible && !isLandmarkEditModeOn && !is_pick_panel_visible);
+ mTeleportBtn->setVisible(!is_create_landmark_visible && !isLandmarkEditModeOn);
+ mShowOnMapBtn->setVisible(!is_create_landmark_visible && !isLandmarkEditModeOn);
mSaveBtn->setVisible(isLandmarkEditModeOn);
mCancelBtn->setVisible(isLandmarkEditModeOn);
mCloseBtn->setVisible(is_create_landmark_visible && !isLandmarkEditModeOn);
diff --git a/indra/newview/llpanelplaces.h b/indra/newview/llpanelplaces.h
index 3b87eb6cb9..e554099343 100644
--- a/indra/newview/llpanelplaces.h
+++ b/indra/newview/llpanelplaces.h
@@ -38,7 +38,6 @@ class LLLandmark;
class LLPanelLandmarkInfo;
class LLPanelPlaceProfile;
-class LLPanelPickEdit;
class LLPanelPlaceInfo;
class LLPanelPlacesTab;
class LLParcelSelection;
@@ -95,7 +94,6 @@ private:
void onOverflowButtonClicked();
void onOverflowMenuItemClicked(const LLSD& param);
bool onOverflowMenuItemEnable(const LLSD& param);
- void onCreateLandmarkButtonClicked(const LLUUID& folder_id);
void onBackButtonClicked();
void onGearMenuClick();
void onSortingMenuClick();
@@ -103,9 +101,6 @@ private:
void onRemoveButtonClicked();
bool handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept);
-
- void toggleMediaPanel();
- void togglePickPanel(BOOL visible);
void togglePlaceInfoPanel(BOOL visible);
/*virtual*/ void onVisibilityChange(BOOL new_visibility);
@@ -122,7 +117,6 @@ private:
LLPanelPlaceProfile* mPlaceProfile;
LLPanelLandmarkInfo* mLandmarkInfo;
- LLPanelPickEdit* mPickPanel;
LLToggleableMenu* mPlaceMenu;
LLToggleableMenu* mLandmarkMenu;
diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp
index 5f13b223fb..29c9329a26 100644
--- a/indra/newview/llpanelprofile.cpp
+++ b/indra/newview/llpanelprofile.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llpanelprofile.cpp
* @brief Profile panel implementation
*
-* $LicenseInfo:firstyear=2009&license=viewerlgpl$
+* $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
-* Copyright (C) 2010, Linden Research, Inc.
-*
+* Copyright (C) 2022, 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$
*/
@@ -27,32 +27,432 @@
#include "llviewerprecompiledheaders.h"
#include "llpanelprofile.h"
-#include "llagent.h"
+// Common
+#include "llavatarnamecache.h"
+#include "llsdutil.h"
+#include "llslurl.h"
+#include "lldateutil.h" //ageFromDate
+
+// UI
+#include "llavatariconctrl.h"
+#include "llclipboard.h"
+#include "llcheckboxctrl.h"
+#include "llcombobox.h"
+#include "lllineeditor.h"
+#include "llloadingindicator.h"
+#include "llmenubutton.h"
+#include "lltabcontainer.h"
+#include "lltextbox.h"
+#include "lltexteditor.h"
+#include "lltexturectrl.h"
+#include "lltoggleablemenu.h"
+#include "llgrouplist.h"
+#include "llurlaction.h"
+
+// Image
+#include "llimagej2c.h"
+
+// Newview
+#include "llagent.h" //gAgent
+#include "llagentpicksinfo.h"
#include "llavataractions.h"
-#include "llfloaterreg.h"
+#include "llavatarpropertiesprocessor.h"
+#include "llcallingcard.h"
#include "llcommandhandler.h"
-#include "llnotificationsutil.h"
-#include "llpanelpicks.h"
-#include "lltabcontainer.h"
-#include "llviewercontrol.h"
-#include "llviewernetwork.h"
+#include "llfloaterprofiletexture.h"
+#include "llfloaterreg.h"
+#include "llfilepicker.h"
+#include "llfirstuse.h"
+#include "llgroupactions.h"
+#include "lllogchat.h"
#include "llmutelist.h"
+#include "llnotificationsutil.h"
#include "llpanelblockedlist.h"
+#include "llpanelprofileclassifieds.h"
+#include "llpanelprofilepicks.h"
+#include "lltrans.h"
+#include "llviewercontrol.h"
+#include "llviewermenu.h" //is_agent_mappable
+#include "llviewermenufile.h"
+#include "llviewertexturelist.h"
+#include "llvoiceclient.h"
#include "llweb.h"
-static const std::string PANEL_PICKS = "panel_picks";
-std::string getProfileURL(const std::string& agent_name)
+static LLPanelInjector<LLPanelProfileSecondLife> t_panel_profile_secondlife("panel_profile_secondlife");
+static LLPanelInjector<LLPanelProfileWeb> t_panel_web("panel_profile_web");
+static LLPanelInjector<LLPanelProfilePicks> t_panel_picks("panel_profile_picks");
+static LLPanelInjector<LLPanelProfileFirstLife> t_panel_firstlife("panel_profile_firstlife");
+static LLPanelInjector<LLPanelProfileNotes> t_panel_notes("panel_profile_notes");
+static LLPanelInjector<LLPanelProfile> t_panel_profile("panel_profile");
+
+static const std::string PANEL_SECONDLIFE = "panel_profile_secondlife";
+static const std::string PANEL_WEB = "panel_profile_web";
+static const std::string PANEL_PICKS = "panel_profile_picks";
+static const std::string PANEL_CLASSIFIEDS = "panel_profile_classifieds";
+static const std::string PANEL_FIRSTLIFE = "panel_profile_firstlife";
+static const std::string PANEL_NOTES = "panel_profile_notes";
+static const std::string PANEL_PROFILE_VIEW = "panel_profile_view";
+
+static const std::string PROFILE_PROPERTIES_CAP = "AgentProfile";
+static const std::string PROFILE_IMAGE_UPLOAD_CAP = "UploadAgentProfileImage";
+
+
+//////////////////////////////////////////////////////////////////////////
+
+void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("request_avatar_properties_coro", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpHeaders::ptr_t httpHeaders;
+
+ LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+ httpOpts->setFollowRedirects(true);
+
+ std::string finalUrl = cap_url + "/" + agent_id.asString();
+
+ LLSD result = httpAdapter->getAndSuspend(httpRequest, finalUrl, httpOpts, httpHeaders);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ LL_DEBUGS("AvatarProperties") << "Agent id: " << agent_id << " Result: " << httpResults << LL_ENDL;
+
+ if (!status
+ || !result.has("id")
+ || agent_id != result["id"].asUUID())
+ {
+ LL_WARNS("AvatarProperties") << "Failed to get agent information for id " << agent_id << LL_ENDL;
+ return;
+ }
+
+ LLFloater* floater_profile = LLFloaterReg::findInstance("profile", LLSD().with("id", agent_id));
+ if (!floater_profile)
+ {
+ // floater is dead, so panels are dead as well
+ return;
+ }
+
+ LLPanel *panel = floater_profile->findChild<LLPanel>(PANEL_PROFILE_VIEW, TRUE);
+ LLPanelProfile *panel_profile = dynamic_cast<LLPanelProfile*>(panel);
+ if (!panel_profile)
+ {
+ LL_WARNS() << PANEL_PROFILE_VIEW << " not found" << LL_ENDL;
+ return;
+ }
+
+
+ // Avatar Data
+
+ LLAvatarData *avatar_data = &panel_profile->mAvatarData;
+ std::string birth_date;
+
+ avatar_data->agent_id = agent_id;
+ avatar_data->avatar_id = agent_id;
+ avatar_data->image_id = result["sl_image_id"].asUUID();
+ avatar_data->fl_image_id = result["fl_image_id"].asUUID();
+ avatar_data->partner_id = result["partner_id"].asUUID();
+ avatar_data->about_text = result["sl_about_text"].asString();
+ avatar_data->fl_about_text = result["fl_about_text"].asString();
+ avatar_data->born_on = result["member_since"].asDate();
+ avatar_data->profile_url = getProfileURL(agent_id.asString());
+
+ avatar_data->flags = 0;
+
+ if (result["online"].asBoolean())
+ {
+ avatar_data->flags |= AVATAR_ONLINE;
+ }
+ if (result["allow_publish"].asBoolean())
+ {
+ avatar_data->flags |= AVATAR_ALLOW_PUBLISH;
+ }
+ if (result["identified"].asBoolean())
+ {
+ avatar_data->flags |= AVATAR_IDENTIFIED;
+ }
+ if (result["transacted"].asBoolean())
+ {
+ avatar_data->flags |= AVATAR_TRANSACTED;
+ }
+
+ avatar_data->caption_index = 0;
+ if (result.has("charter_member")) // won't be present if "caption" is set
+ {
+ avatar_data->caption_index = result["charter_member"].asInteger();
+ }
+ else if (result.has("caption"))
+ {
+ avatar_data->caption_text = result["caption"].asString();
+ }
+
+ panel = floater_profile->findChild<LLPanel>(PANEL_SECONDLIFE, TRUE);
+ LLPanelProfileSecondLife *panel_sl = dynamic_cast<LLPanelProfileSecondLife*>(panel);
+ if (panel_sl)
+ {
+ panel_sl->processProfileProperties(avatar_data);
+ }
+
+ panel = floater_profile->findChild<LLPanel>(PANEL_WEB, TRUE);
+ LLPanelProfileWeb *panel_web = dynamic_cast<LLPanelProfileWeb*>(panel);
+ if (panel_web)
+ {
+ panel_web->setLoaded();
+ }
+
+ panel = floater_profile->findChild<LLPanel>(PANEL_FIRSTLIFE, TRUE);
+ LLPanelProfileFirstLife *panel_first = dynamic_cast<LLPanelProfileFirstLife*>(panel);
+ if (panel_first)
+ {
+ panel_first->processProperties(avatar_data);
+ }
+
+ // Picks
+
+ LLSD picks_array = result["picks"];
+ LLAvatarPicks avatar_picks;
+ avatar_picks.agent_id = agent_id; // Not in use?
+ avatar_picks.target_id = agent_id;
+
+ for (LLSD::array_const_iterator it = picks_array.beginArray(); it != picks_array.endArray(); ++it)
+ {
+ const LLSD& pick_data = *it;
+ avatar_picks.picks_list.emplace_back(pick_data["id"].asUUID(), pick_data["name"].asString());
+ }
+
+ panel = floater_profile->findChild<LLPanel>(PANEL_PICKS, TRUE);
+ LLPanelProfilePicks *panel_picks = dynamic_cast<LLPanelProfilePicks*>(panel);
+ if (panel_picks)
+ {
+ // Refresh pick limit before processing
+ LLAgentPicksInfo::getInstance()->onServerRespond(&avatar_picks);
+ panel_picks->processProperties(&avatar_picks);
+ }
+
+ // Groups
+
+ LLSD groups_array = result["groups"];
+ LLAvatarGroups avatar_groups;
+ avatar_groups.agent_id = agent_id; // Not in use?
+ avatar_groups.avatar_id = agent_id; // target_id
+
+ for (LLSD::array_const_iterator it = groups_array.beginArray(); it != groups_array.endArray(); ++it)
+ {
+ const LLSD& group_info = *it;
+ LLAvatarGroups::LLGroupData group_data;
+ group_data.group_powers = 0; // Not in use?
+ group_data.group_title = group_info["name"].asString(); // Missing data, not in use?
+ group_data.group_id = group_info["id"].asUUID();
+ group_data.group_name = group_info["name"].asString();
+ group_data.group_insignia_id = group_info["image_id"].asUUID();
+
+ avatar_groups.group_list.push_back(group_data);
+ }
+
+ if (panel_sl)
+ {
+ panel_sl->processGroupProperties(&avatar_groups);
+ }
+
+ // Notes
+ LLAvatarNotes avatar_notes;
+
+ avatar_notes.agent_id = agent_id;
+ avatar_notes.target_id = agent_id;
+ avatar_notes.notes = result["notes"].asString();
+
+ panel = floater_profile->findChild<LLPanel>(PANEL_NOTES, TRUE);
+ LLPanelProfileNotes *panel_notes = dynamic_cast<LLPanelProfileNotes*>(panel);
+ if (panel_notes)
+ {
+ panel_notes->processProperties(&avatar_notes);
+ }
+}
+
+//TODO: changes take two minutes to propagate!
+// Add some storage that holds updated data for two minutes
+// for new instances to reuse the data
+// Profile data is only relevant to won avatar, but notes
+// are for everybody
+void put_avatar_properties_coro(std::string cap_url, LLUUID agent_id, LLSD data)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("put_avatar_properties_coro", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpHeaders::ptr_t httpHeaders;
+
+ LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+ httpOpts->setFollowRedirects(true);
+
+ std::string finalUrl = cap_url + "/" + agent_id.asString();
+
+ LLSD result = httpAdapter->putAndSuspend(httpRequest, finalUrl, data, httpOpts, httpHeaders);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status)
+ {
+ LL_WARNS("AvatarProperties") << "Failed to put agent information " << data << " for id " << agent_id << LL_ENDL;
+ return;
+ }
+
+ LL_DEBUGS("AvatarProperties") << "Agent id: " << agent_id << " Data: " << data << " Result: " << httpResults << LL_ENDL;
+}
+
+LLUUID post_profile_image(std::string cap_url, const LLSD &first_data, std::string path_to_image, LLHandle<LLPanel> *handle)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("post_profile_image_coro", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpHeaders::ptr_t httpHeaders;
+
+ LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+ httpOpts->setFollowRedirects(true);
+
+ LLSD result = httpAdapter->postAndSuspend(httpRequest, cap_url, first_data, httpOpts, httpHeaders);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status)
+ {
+ // todo: notification?
+ LL_WARNS("AvatarProperties") << "Failed to get uploader cap " << status.toString() << LL_ENDL;
+ return LLUUID::null;
+ }
+ if (!result.has("uploader"))
+ {
+ // todo: notification?
+ LL_WARNS("AvatarProperties") << "Failed to get uploader cap, response contains no data." << LL_ENDL;
+ return LLUUID::null;
+ }
+ std::string uploader_cap = result["uploader"].asString();
+ if (uploader_cap.empty())
+ {
+ LL_WARNS("AvatarProperties") << "Failed to get uploader cap, cap invalid." << LL_ENDL;
+ return LLUUID::null;
+ }
+
+ // Upload the image
+
+ LLCore::HttpRequest::ptr_t uploaderhttpRequest(new LLCore::HttpRequest);
+ LLCore::HttpHeaders::ptr_t uploaderhttpHeaders(new LLCore::HttpHeaders);
+ LLCore::HttpOptions::ptr_t uploaderhttpOpts(new LLCore::HttpOptions);
+ S64 length;
+
+ {
+ llifstream instream(path_to_image.c_str(), std::iostream::binary | std::iostream::ate);
+ if (!instream.is_open())
+ {
+ LL_WARNS("AvatarProperties") << "Failed to open file " << path_to_image << LL_ENDL;
+ return LLUUID::null;
+ }
+ length = instream.tellg();
+ }
+
+ uploaderhttpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, "application/jp2"); // optional
+ uploaderhttpHeaders->append(HTTP_OUT_HEADER_CONTENT_LENGTH, llformat("%d", length)); // required!
+ uploaderhttpOpts->setFollowRedirects(true);
+
+ result = httpAdapter->postFileAndSuspend(uploaderhttpRequest, uploader_cap, path_to_image, uploaderhttpOpts, uploaderhttpHeaders);
+
+ httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ LL_WARNS("AvatarProperties") << result << LL_ENDL;
+
+ if (!status)
+ {
+ LL_WARNS("AvatarProperties") << "Failed to upload image " << status.toString() << LL_ENDL;
+ return LLUUID::null;
+ }
+
+ if (result["state"].asString() != "complete")
+ {
+ if (result.has("message"))
+ {
+ LL_WARNS("AvatarProperties") << "Failed to upload image, state " << result["state"] << " message: " << result["message"] << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS("AvatarProperties") << "Failed to upload image " << result << LL_ENDL;
+ }
+ return LLUUID::null;
+ }
+
+ return result["new_asset"].asUUID();
+}
+
+enum EProfileImageType
+{
+ PROFILE_IMAGE_SL,
+ PROFILE_IMAGE_FL,
+};
+
+void post_profile_image_coro(std::string cap_url, EProfileImageType type, std::string path_to_image, LLHandle<LLPanel> *handle)
{
- std::string url = "[WEB_PROFILE_URL][AGENT_NAME]";
- LLSD subs;
- subs["WEB_PROFILE_URL"] = LLGridManager::getInstance()->getWebProfileURL();
- subs["AGENT_NAME"] = agent_name;
- url = LLWeb::expandURLSubstitutions(url, subs);
- LLStringUtil::toLower(url);
- return url;
+ LLSD data;
+ switch (type)
+ {
+ case PROFILE_IMAGE_SL:
+ data["profile-image-asset"] = "sl_image_id";
+ break;
+ case PROFILE_IMAGE_FL:
+ data["profile-image-asset"] = "fl_image_id";
+ break;
+ }
+
+ LLUUID result = post_profile_image(cap_url, data, path_to_image, handle);
+
+ // reset loading indicator
+ if (!handle->isDead())
+ {
+ switch (type)
+ {
+ case PROFILE_IMAGE_SL:
+ {
+ LLPanelProfileSecondLife* panel = static_cast<LLPanelProfileSecondLife*>(handle->get());
+ if (result.notNull())
+ {
+ panel->setProfileImageUploaded(result);
+ }
+ else
+ {
+ // failure, just stop progress indicator
+ panel->setProfileImageUploading(false);
+ }
+ break;
+ }
+ case PROFILE_IMAGE_FL:
+ {
+ LLPanelProfileFirstLife* panel = static_cast<LLPanelProfileFirstLife*>(handle->get());
+ if (result.notNull())
+ {
+ panel->setProfileImageUploaded(result);
+ }
+ else
+ {
+ // failure, just stop progress indicator
+ panel->setProfileImageUploading(false);
+ }
+ break;
+ }
+ }
+ }
+
+ // Cleanup
+ LLFile::remove(path_to_image);
+ delete handle;
}
+//////////////////////////////////////////////////////////////////////////
+// LLProfileHandler
+
class LLProfileHandler : public LLCommandHandler
{
public:
@@ -73,6 +473,10 @@ public:
};
LLProfileHandler gProfileHandler;
+
+//////////////////////////////////////////////////////////////////////////
+// LLAgentHandler
+
class LLAgentHandler : public LLCommandHandler
{
public:
@@ -184,273 +588,2067 @@ public:
LLAgentHandler gAgentHandler;
-//-- LLPanelProfile::ChildStack begins ----------------------------------------
-LLPanelProfile::ChildStack::ChildStack()
-: mParent(NULL)
+///----------------------------------------------------------------------------
+/// LLFloaterProfilePermissions
+///----------------------------------------------------------------------------
+
+class LLFloaterProfilePermissions
+ : public LLFloater
+ , public LLFriendObserver
+{
+public:
+ LLFloaterProfilePermissions(LLView * owner, const LLUUID &avatar_id);
+ ~LLFloaterProfilePermissions();
+ BOOL postBuild() override;
+ void onOpen(const LLSD& key) override;
+ void draw() override;
+ void changed(U32 mask) override; // LLFriendObserver
+
+ void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
+ bool hasUnsavedChanges() { return mHasUnsavedPermChanges; }
+
+ void onApplyRights();
+
+private:
+ void fillRightsData();
+ void rightsConfirmationCallback(const LLSD& notification, const LLSD& response);
+ void confirmModifyRights(bool grant);
+ void onCommitSeeOnlineRights();
+ void onCommitEditRights();
+ void onCancel();
+
+ LLTextBase* mDescription;
+ LLCheckBoxCtrl* mOnlineStatus;
+ LLCheckBoxCtrl* mMapRights;
+ LLCheckBoxCtrl* mEditObjectRights;
+ LLButton* mOkBtn;
+ LLButton* mCancelBtn;
+
+ LLUUID mAvatarID;
+ F32 mContextConeOpacity;
+ bool mHasUnsavedPermChanges;
+ LLHandle<LLView> mOwnerHandle;
+
+ boost::signals2::connection mAvatarNameCacheConnection;
+};
+
+LLFloaterProfilePermissions::LLFloaterProfilePermissions(LLView * owner, const LLUUID &avatar_id)
+ : LLFloater(LLSD())
+ , mAvatarID(avatar_id)
+ , mContextConeOpacity(0.0f)
+ , mHasUnsavedPermChanges(false)
+ , mOwnerHandle(owner->getHandle())
{
+ buildFromFile("floater_profile_permissions.xml");
}
-LLPanelProfile::ChildStack::~ChildStack()
+LLFloaterProfilePermissions::~LLFloaterProfilePermissions()
{
- while (mStack.size() != 0)
- {
- view_list_t& top = mStack.back();
- for (view_list_t::const_iterator it = top.begin(); it != top.end(); ++it)
- {
- LLView* viewp = *it;
- if (viewp)
- {
- viewp->die();
- }
- }
- mStack.pop_back();
- }
+ mAvatarNameCacheConnection.disconnect();
+ if (mAvatarID.notNull())
+ {
+ LLAvatarTracker::instance().removeParticularFriendObserver(mAvatarID, this);
+ }
}
-void LLPanelProfile::ChildStack::setParent(LLPanel* parent)
+BOOL LLFloaterProfilePermissions::postBuild()
{
- llassert_always(parent != NULL);
- mParent = parent;
+ mDescription = getChild<LLTextBase>("perm_description");
+ mOnlineStatus = getChild<LLCheckBoxCtrl>("online_check");
+ mMapRights = getChild<LLCheckBoxCtrl>("map_check");
+ mEditObjectRights = getChild<LLCheckBoxCtrl>("objects_check");
+ mOkBtn = getChild<LLButton>("perms_btn_ok");
+ mCancelBtn = getChild<LLButton>("perms_btn_cancel");
+
+ mOnlineStatus->setCommitCallback([this](LLUICtrl*, void*) { onCommitSeeOnlineRights(); }, nullptr);
+ mMapRights->setCommitCallback([this](LLUICtrl*, void*) { mHasUnsavedPermChanges = true; }, nullptr);
+ mEditObjectRights->setCommitCallback([this](LLUICtrl*, void*) { onCommitEditRights(); }, nullptr);
+ mOkBtn->setCommitCallback([this](LLUICtrl*, void*) { onApplyRights(); }, nullptr);
+ mCancelBtn->setCommitCallback([this](LLUICtrl*, void*) { onCancel(); }, nullptr);
+
+ return TRUE;
}
-/// Save current parent's child views and remove them from the child list.
-bool LLPanelProfile::ChildStack::push()
+void LLFloaterProfilePermissions::onOpen(const LLSD& key)
{
- view_list_t vlist = *mParent->getChildList();
+ if (LLAvatarActions::isFriend(mAvatarID))
+ {
+ LLAvatarTracker::instance().addParticularFriendObserver(mAvatarID, this);
+ fillRightsData();
+ }
- for (view_list_t::const_iterator it = vlist.begin(); it != vlist.end(); ++it)
- {
- LLView* viewp = *it;
- mParent->removeChild(viewp);
- }
+ mCancelBtn->setFocus(true);
- mStack.push_back(vlist);
- dump();
- return true;
+ mAvatarNameCacheConnection = LLAvatarNameCache::get(mAvatarID, boost::bind(&LLFloaterProfilePermissions::onAvatarNameCache, this, _1, _2));
}
-/// Restore saved children (adding them back to the child list).
-bool LLPanelProfile::ChildStack::pop()
+void LLFloaterProfilePermissions::draw()
{
- if (mStack.size() == 0)
- {
- LL_WARNS() << "Empty stack" << LL_ENDL;
- llassert(mStack.size() == 0);
- return false;
- }
+ // drawFrustum
+ LLView *owner = mOwnerHandle.get();
+ static LLCachedControl<F32> max_opacity(gSavedSettings, "PickerContextOpacity", 0.4f);
+ drawConeToOwner(mContextConeOpacity, max_opacity, owner);
+ LLFloater::draw();
+}
- view_list_t& top = mStack.back();
- for (view_list_t::const_iterator it = top.begin(); it != top.end(); ++it)
- {
- LLView* viewp = *it;
- mParent->addChild(viewp);
- }
+void LLFloaterProfilePermissions::changed(U32 mask)
+{
+ if (mask != LLFriendObserver::ONLINE)
+ {
+ fillRightsData();
+ }
+}
+
+void LLFloaterProfilePermissions::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name)
+{
+ mAvatarNameCacheConnection.disconnect();
- mStack.pop_back();
- dump();
- return true;
+ LLStringUtil::format_map_t args;
+ args["[AGENT_NAME]"] = av_name.getDisplayName();
+ std::string descritpion = getString("description_string", args);
+ mDescription->setValue(descritpion);
}
-/// Temporarily add all saved children back.
-void LLPanelProfile::ChildStack::preParentReshape()
+void LLFloaterProfilePermissions::fillRightsData()
{
- mSavedStack = mStack;
- while(mStack.size() > 0)
- {
- pop();
- }
+ const LLRelationship* relation = LLAvatarTracker::instance().getBuddyInfo(mAvatarID);
+ // If true - we are viewing friend's profile, enable check boxes and set values.
+ if (relation)
+ {
+ S32 rights = relation->getRightsGrantedTo();
+
+ BOOL see_online = LLRelationship::GRANT_ONLINE_STATUS & rights ? TRUE : FALSE;
+ mOnlineStatus->setValue(see_online);
+ mMapRights->setEnabled(see_online);
+ mMapRights->setValue(LLRelationship::GRANT_MAP_LOCATION & rights ? TRUE : FALSE);
+ mEditObjectRights->setValue(LLRelationship::GRANT_MODIFY_OBJECTS & rights ? TRUE : FALSE);
+ }
+ else
+ {
+ closeFloater();
+ LL_INFOS("ProfilePermissions") << "Floater closing since agent is no longer a friend" << LL_ENDL;
+ }
}
-/// Add the temporarily saved children back.
-void LLPanelProfile::ChildStack::postParentReshape()
+void LLFloaterProfilePermissions::rightsConfirmationCallback(const LLSD& notification,
+ const LLSD& response)
{
- mStack = mSavedStack;
- mSavedStack = stack_t();
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (option != 0) // canceled
+ {
+ mEditObjectRights->setValue(mEditObjectRights->getValue().asBoolean() ? FALSE : TRUE);
+ }
+ else
+ {
+ mHasUnsavedPermChanges = true;
+ }
+}
- for (stack_t::const_iterator stack_it = mStack.begin(); stack_it != mStack.end(); ++stack_it)
- {
- const view_list_t& vlist = (*stack_it);
- for (view_list_t::const_iterator list_it = vlist.begin(); list_it != vlist.end(); ++list_it)
- {
- LLView* viewp = *list_it;
- LL_DEBUGS() << "removing " << viewp->getName() << LL_ENDL;
- mParent->removeChild(viewp);
- }
- }
+void LLFloaterProfilePermissions::confirmModifyRights(bool grant)
+{
+ LLSD args;
+ args["NAME"] = LLSLURL("agent", mAvatarID, "completename").getSLURLString();
+ LLNotificationsUtil::add(grant ? "GrantModifyRights" : "RevokeModifyRights", args, LLSD(),
+ boost::bind(&LLFloaterProfilePermissions::rightsConfirmationCallback, this, _1, _2));
}
-void LLPanelProfile::ChildStack::dump()
+void LLFloaterProfilePermissions::onCommitSeeOnlineRights()
{
- unsigned lvl = 0;
- LL_DEBUGS() << "child stack dump:" << LL_ENDL;
- for (stack_t::const_iterator stack_it = mStack.begin(); stack_it != mStack.end(); ++stack_it, ++lvl)
- {
- std::ostringstream dbg_line;
- dbg_line << "lvl #" << lvl << ":";
- const view_list_t& vlist = (*stack_it);
- for (view_list_t::const_iterator list_it = vlist.begin(); list_it != vlist.end(); ++list_it)
- {
- dbg_line << " " << (*list_it)->getName();
- }
- LL_DEBUGS() << dbg_line.str() << LL_ENDL;
- }
+ bool see_online = mOnlineStatus->getValue().asBoolean();
+ mMapRights->setEnabled(see_online);
+ if (see_online)
+ {
+ const LLRelationship* relation = LLAvatarTracker::instance().getBuddyInfo(mAvatarID);
+ if (relation)
+ {
+ S32 rights = relation->getRightsGrantedTo();
+ mMapRights->setValue(LLRelationship::GRANT_MAP_LOCATION & rights ? TRUE : FALSE);
+ }
+ else
+ {
+ closeFloater();
+ LL_INFOS("ProfilePermissions") << "Floater closing since agent is no longer a friend" << LL_ENDL;
+ }
+ }
+ else
+ {
+ mMapRights->setValue(FALSE);
+ }
+ mHasUnsavedPermChanges = true;
}
-//-- LLPanelProfile::ChildStack ends ------------------------------------------
+void LLFloaterProfilePermissions::onCommitEditRights()
+{
+ const LLRelationship* buddy_relationship = LLAvatarTracker::instance().getBuddyInfo(mAvatarID);
-LLPanelProfile::LLPanelProfile()
- : LLPanel()
- , mAvatarId(LLUUID::null)
+ if (!buddy_relationship)
+ {
+ LL_WARNS("ProfilePermissions") << "Trying to modify rights for non-friend avatar. Closing floater." << LL_ENDL;
+ closeFloater();
+ return;
+ }
+
+ bool allow_modify_objects = mEditObjectRights->getValue().asBoolean();
+
+ // if modify objects checkbox clicked
+ if (buddy_relationship->isRightGrantedTo(
+ LLRelationship::GRANT_MODIFY_OBJECTS) != allow_modify_objects)
+ {
+ confirmModifyRights(allow_modify_objects);
+ }
+}
+
+void LLFloaterProfilePermissions::onApplyRights()
+{
+ const LLRelationship* buddy_relationship = LLAvatarTracker::instance().getBuddyInfo(mAvatarID);
+
+ if (!buddy_relationship)
+ {
+ LL_WARNS("ProfilePermissions") << "Trying to modify rights for non-friend avatar. Skipped." << LL_ENDL;
+ return;
+ }
+
+ S32 rights = 0;
+
+ if (mOnlineStatus->getValue().asBoolean())
+ {
+ rights |= LLRelationship::GRANT_ONLINE_STATUS;
+ }
+ if (mMapRights->getValue().asBoolean())
+ {
+ rights |= LLRelationship::GRANT_MAP_LOCATION;
+ }
+ if (mEditObjectRights->getValue().asBoolean())
+ {
+ rights |= LLRelationship::GRANT_MODIFY_OBJECTS;
+ }
+
+ LLAvatarPropertiesProcessor::getInstance()->sendFriendRights(mAvatarID, rights);
+
+ closeFloater();
+}
+
+void LLFloaterProfilePermissions::onCancel()
{
- mChildStack.setParent(this);
+ closeFloater();
}
-BOOL LLPanelProfile::postBuild()
+//////////////////////////////////////////////////////////////////////////
+// LLPanelProfileSecondLife
+
+LLPanelProfileSecondLife::LLPanelProfileSecondLife()
+ : LLPanelProfileTab()
+ , mAvatarNameCacheConnection()
+ , mHasUnsavedDescriptionChanges(false)
+ , mWaitingForImageUpload(false)
+ , mAllowPublish(false)
+{
+}
+
+LLPanelProfileSecondLife::~LLPanelProfileSecondLife()
{
- LLPanelPicks* panel_picks = findChild<LLPanelPicks>(PANEL_PICKS);
- panel_picks->setProfilePanel(this);
+ if (getAvatarId().notNull())
+ {
+ LLAvatarTracker::instance().removeParticularFriendObserver(getAvatarId(), this);
+ }
- getTabContainer()[PANEL_PICKS] = panel_picks;
+ if (LLVoiceClient::instanceExists())
+ {
+ LLVoiceClient::getInstance()->removeObserver((LLVoiceClientStatusObserver*)this);
+ }
- return TRUE;
+ if (mAvatarNameCacheConnection.connected())
+ {
+ mAvatarNameCacheConnection.disconnect();
+ }
}
-// virtual
-void LLPanelProfile::reshape(S32 width, S32 height, BOOL called_from_parent)
+BOOL LLPanelProfileSecondLife::postBuild()
{
- // Temporarily add saved children back and reshape them.
- mChildStack.preParentReshape();
- LLPanel::reshape(width, height, called_from_parent);
- mChildStack.postParentReshape();
+ mGroupList = getChild<LLGroupList>("group_list");
+ mShowInSearchCombo = getChild<LLComboBox>("show_in_search");
+ mSecondLifePic = getChild<LLIconCtrl>("2nd_life_pic");
+ mSecondLifePicLayout = getChild<LLPanel>("image_panel");
+ mDescriptionEdit = getChild<LLTextEditor>("sl_description_edit");
+ mAgentActionMenuButton = getChild<LLMenuButton>("agent_actions_menu");
+ mSaveDescriptionChanges = getChild<LLButton>("save_description_changes");
+ mDiscardDescriptionChanges = getChild<LLButton>("discard_description_changes");
+ mCanSeeOnlineIcon = getChild<LLIconCtrl>("can_see_online");
+ mCantSeeOnlineIcon = getChild<LLIconCtrl>("cant_see_online");
+ mCanSeeOnMapIcon = getChild<LLIconCtrl>("can_see_on_map");
+ mCantSeeOnMapIcon = getChild<LLIconCtrl>("cant_see_on_map");
+ mCanEditObjectsIcon = getChild<LLIconCtrl>("can_edit_objects");
+ mCantEditObjectsIcon = getChild<LLIconCtrl>("cant_edit_objects");
+
+ mShowInSearchCombo->setCommitCallback([this](LLUICtrl*, void*) { onShowInSearchCallback(); }, nullptr);
+ mGroupList->setDoubleClickCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { LLPanelProfileSecondLife::openGroupProfile(); });
+ mGroupList->setReturnCallback([this](LLUICtrl*, const LLSD&) { LLPanelProfileSecondLife::openGroupProfile(); });
+ mSaveDescriptionChanges->setCommitCallback([this](LLUICtrl*, void*) { onSaveDescriptionChanges(); }, nullptr);
+ mDiscardDescriptionChanges->setCommitCallback([this](LLUICtrl*, void*) { onDiscardDescriptionChanges(); }, nullptr);
+ mDescriptionEdit->setKeystrokeCallback([this](LLTextEditor* caller) { onSetDescriptionDirty(); });
+
+ getChild<LLButton>("open_notes")->setCommitCallback([this](LLUICtrl*, void*) { onOpenNotes(); }, nullptr);
+
+ mCanSeeOnlineIcon->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentPermissionsDialog(); });
+ mCantSeeOnlineIcon->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentPermissionsDialog(); });
+ mCanSeeOnMapIcon->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentPermissionsDialog(); });
+ mCantSeeOnMapIcon->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentPermissionsDialog(); });
+ mCanEditObjectsIcon->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentPermissionsDialog(); });
+ mCantEditObjectsIcon->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentPermissionsDialog(); });
+ mSecondLifePic->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentProfileTexture(); });
+
+ return TRUE;
+}
+
+void LLPanelProfileSecondLife::onOpen(const LLSD& key)
+{
+ LLPanelProfileTab::onOpen(key);
+
+ resetData();
+
+ LLUUID avatar_id = getAvatarId();
+
+ BOOL own_profile = getSelfProfile();
+
+ mGroupList->setShowNone(!own_profile);
+
+ childSetVisible("notes_panel", !own_profile);
+ childSetVisible("settings_panel", own_profile);
+ childSetVisible("about_buttons_panel", own_profile);
+
+ if (own_profile)
+ {
+ // Group list control cannot toggle ForAgent loading
+ // Less than ideal, but viewing own profile via search is edge case
+ mGroupList->enableForAgent(false);
+ }
+
+ // Init menu, menu needs to be created in scope of a registar to work correctly.
+ LLUICtrl::CommitCallbackRegistry::ScopedRegistrar commit;
+ commit.add("Profile.Commit", [this](LLUICtrl*, const LLSD& userdata) { onCommitMenu(userdata); });
+
+ LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable;
+ enable.add("Profile.EnableItem", [this](LLUICtrl*, const LLSD& userdata) { return onEnableMenu(userdata); });
+ enable.add("Profile.CheckItem", [this](LLUICtrl*, const LLSD& userdata) { return onCheckMenu(userdata); });
+
+ if (own_profile)
+ {
+ mAgentActionMenuButton->setMenu("menu_profile_self.xml", LLMenuButton::MP_BOTTOM_RIGHT);
+ }
+ else
+ {
+ // Todo: use PeopleContextMenu instead?
+ mAgentActionMenuButton->setMenu("menu_profile_other.xml", LLMenuButton::MP_BOTTOM_RIGHT);
+ }
+
+ mDescriptionEdit->setParseHTML(!own_profile);
+
+ if (!own_profile)
+ {
+ mVoiceStatus = LLAvatarActions::canCall() && (LLAvatarActions::isFriend(avatar_id) ? LLAvatarTracker::instance().isBuddyOnline(avatar_id) : TRUE);
+ updateOnlineStatus();
+ fillRightsData();
+ }
+
+ mAvatarNameCacheConnection = LLAvatarNameCache::get(getAvatarId(), boost::bind(&LLPanelProfileSecondLife::onAvatarNameCache, this, _1, _2));
+}
+
+void LLPanelProfileSecondLife::updateData()
+{
+ LLUUID avatar_id = getAvatarId();
+ if (!getStarted() && avatar_id.notNull())
+ {
+ setIsLoading();
+
+ std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP);
+ if (!cap_url.empty())
+ {
+ LLCoros::instance().launch("requestAgentUserInfoCoro",
+ boost::bind(request_avatar_properties_coro, cap_url, avatar_id));
+ }
+ else
+ {
+ LL_WARNS() << "Failed to update profile data, no cap found" << LL_ENDL;
+ }
+ }
+}
+
+void LLPanelProfileSecondLife::refreshName()
+{
+ if (!mAvatarNameCacheConnection.connected())
+ {
+ mAvatarNameCacheConnection = LLAvatarNameCache::get(getAvatarId(), boost::bind(&LLPanelProfileSecondLife::onAvatarNameCache, this, _1, _2));
+ }
+}
+
+void LLPanelProfileSecondLife::resetData()
+{
+ resetLoading();
+
+ // Set default image and 1:1 dimensions for it
+ mSecondLifePic->setValue("Generic_Person_Large");
+ mImageId = LLUUID::null;
+
+ LLRect imageRect = mSecondLifePicLayout->getRect();
+ mSecondLifePicLayout->reshape(imageRect.getHeight(), imageRect.getHeight());
+
+ setDescriptionText(LLStringUtil::null);
+ mGroups.clear();
+ mGroupList->setGroups(mGroups);
+
+ bool own_profile = getSelfProfile();
+ mCanSeeOnlineIcon->setVisible(false);
+ mCantSeeOnlineIcon->setVisible(!own_profile);
+ mCanSeeOnMapIcon->setVisible(false);
+ mCantSeeOnMapIcon->setVisible(!own_profile);
+ mCanEditObjectsIcon->setVisible(false);
+ mCantEditObjectsIcon->setVisible(!own_profile);
+
+ mCanSeeOnlineIcon->setEnabled(false);
+ mCantSeeOnlineIcon->setEnabled(false);
+ mCanSeeOnMapIcon->setEnabled(false);
+ mCantSeeOnMapIcon->setEnabled(false);
+ mCanEditObjectsIcon->setEnabled(false);
+ mCantEditObjectsIcon->setEnabled(false);
+
+ childSetVisible("partner_layout", FALSE);
+}
+
+void LLPanelProfileSecondLife::processProfileProperties(const LLAvatarData* avatar_data)
+{
+ LLUUID avatar_id = getAvatarId();
+ const LLRelationship* relationship = LLAvatarTracker::instance().getBuddyInfo(getAvatarId());
+ if ((relationship != NULL || gAgent.isGodlike()) && !getSelfProfile())
+ {
+ // Relies onto friend observer to get information about online status updates.
+ // Once SL-17506 gets implemented, condition might need to become:
+ // (gAgent.isGodlike() || isRightGrantedFrom || flags & AVATAR_ONLINE)
+ processOnlineStatus(relationship != NULL,
+ gAgent.isGodlike() || relationship->isRightGrantedFrom(LLRelationship::GRANT_ONLINE_STATUS),
+ (avatar_data->flags & AVATAR_ONLINE));
+ }
+
+ fillCommonData(avatar_data);
+
+ fillPartnerData(avatar_data);
+
+ fillAccountStatus(avatar_data);
+
+ setLoaded();
+}
+
+void LLPanelProfileSecondLife::processGroupProperties(const LLAvatarGroups* avatar_groups)
+{
+
+ LLAvatarGroups::group_list_t::const_iterator it = avatar_groups->group_list.begin();
+ const LLAvatarGroups::group_list_t::const_iterator it_end = avatar_groups->group_list.end();
+
+ for (; it_end != it; ++it)
+ {
+ LLAvatarGroups::LLGroupData group_data = *it;
+ mGroups[group_data.group_name] = group_data.group_id;
+ }
+
+ mGroupList->setGroups(mGroups);
+}
+
+void LLPanelProfileSecondLife::openGroupProfile()
+{
+ LLUUID group_id = mGroupList->getSelectedUUID();
+ LLGroupActions::show(group_id);
+}
+
+void LLPanelProfileSecondLife::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name)
+{
+ mAvatarNameCacheConnection.disconnect();
+ getChild<LLUICtrl>("display_name")->setValue(av_name.getDisplayName());
+ getChild<LLUICtrl>("user_name")->setValue(av_name.getAccountName());
+}
+
+void LLPanelProfileSecondLife::setProfileImageUploading(bool loading)
+{
+ LLLoadingIndicator* indicator = getChild<LLLoadingIndicator>("image_upload_indicator");
+ indicator->setVisible(loading);
+ if (loading)
+ {
+ indicator->start();
+ }
+ else
+ {
+ indicator->stop();
+ }
+ mWaitingForImageUpload = loading;
+}
+
+void LLPanelProfileSecondLife::setProfileImageUploaded(const LLUUID &image_asset_id)
+{
+ mSecondLifePic->setValue(image_asset_id);
+ mImageId = image_asset_id;
+
+ LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTexture(image_asset_id);
+ if (imagep->getFullHeight())
+ {
+ onImageLoaded(true, imagep);
+ }
+ else
+ {
+ imagep->setLoadedCallback(onImageLoaded,
+ MAX_DISCARD_LEVEL,
+ FALSE,
+ FALSE,
+ new LLHandle<LLPanel>(getHandle()),
+ NULL,
+ FALSE);
+ }
+
+ LLFloater *floater = mFloaterProfileTextureHandle.get();
+ if (floater)
+ {
+ LLFloaterProfileTexture * texture_view = dynamic_cast<LLFloaterProfileTexture*>(floater);
+ if (mImageId.notNull())
+ {
+ texture_view->loadAsset(mImageId);
+ }
+ else
+ {
+ texture_view->resetAsset();
+ }
+ }
+
+ setProfileImageUploading(false);
+}
+
+bool LLPanelProfileSecondLife::hasUnsavedChanges()
+{
+ LLFloater *floater = mFloaterPermissionsHandle.get();
+ if (floater)
+ {
+ LLFloaterProfilePermissions* perm = dynamic_cast<LLFloaterProfilePermissions*>(floater);
+ if (perm && perm->hasUnsavedChanges())
+ {
+ return true;
+ }
+ }
+ // if floater
+ return mHasUnsavedDescriptionChanges;
+}
+
+void LLPanelProfileSecondLife::commitUnsavedChanges()
+{
+ LLFloater *floater = mFloaterPermissionsHandle.get();
+ if (floater)
+ {
+ LLFloaterProfilePermissions* perm = dynamic_cast<LLFloaterProfilePermissions*>(floater);
+ if (perm && perm->hasUnsavedChanges())
+ {
+ perm->onApplyRights();
+ }
+ }
+ if (mHasUnsavedDescriptionChanges)
+ {
+ onSaveDescriptionChanges();
+ }
+}
+
+void LLPanelProfileSecondLife::fillCommonData(const LLAvatarData* avatar_data)
+{
+ // Refresh avatar id in cache with new info to prevent re-requests
+ // and to make sure icons in text will be up to date
+ LLAvatarIconIDCache::getInstance()->add(avatar_data->avatar_id, avatar_data->image_id);
+
+ fillAgeData(avatar_data->born_on);
+
+ setDescriptionText(avatar_data->about_text);
+
+ if (avatar_data->image_id.notNull())
+ {
+ mSecondLifePic->setValue(avatar_data->image_id);
+ mImageId = avatar_data->image_id;
+ }
+ else
+ {
+ mSecondLifePic->setValue("Generic_Person_Large");
+ mImageId = LLUUID::null;
+ }
+
+ // Will be loaded as a LLViewerFetchedTexture::BOOST_UI due to mSecondLifePic
+ LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTexture(avatar_data->image_id);
+ if (imagep->getFullHeight())
+ {
+ onImageLoaded(true, imagep);
+ }
+ else
+ {
+ imagep->setLoadedCallback(onImageLoaded,
+ MAX_DISCARD_LEVEL,
+ FALSE,
+ FALSE,
+ new LLHandle<LLPanel>(getHandle()),
+ NULL,
+ FALSE);
+ }
+
+ if (getSelfProfile())
+ {
+ mAllowPublish = avatar_data->flags & AVATAR_ALLOW_PUBLISH;
+ mShowInSearchCombo->setValue((BOOL)mAllowPublish);
+ }
+}
+
+void LLPanelProfileSecondLife::fillPartnerData(const LLAvatarData* avatar_data)
+{
+ LLTextBox* partner_text_ctrl = getChild<LLTextBox>("partner_link");
+ if (avatar_data->partner_id.notNull())
+ {
+ childSetVisible("partner_layout", TRUE);
+ LLStringUtil::format_map_t args;
+ args["[LINK]"] = LLSLURL("agent", avatar_data->partner_id, "inspect").getSLURLString();
+ std::string partner_text = getString("partner_text", args);
+ partner_text_ctrl->setText(partner_text);
+ }
+ else
+ {
+ childSetVisible("partner_layout", FALSE);
+ }
+}
+
+void LLPanelProfileSecondLife::fillAccountStatus(const LLAvatarData* avatar_data)
+{
+ LLStringUtil::format_map_t args;
+ args["[ACCTTYPE]"] = LLAvatarPropertiesProcessor::accountType(avatar_data);
+ args["[PAYMENTINFO]"] = LLAvatarPropertiesProcessor::paymentInfo(avatar_data);
+
+ std::string caption_text = getString("CaptionTextAcctInfo", args);
+ getChild<LLUICtrl>("account_info")->setValue(caption_text);
+}
+
+void LLPanelProfileSecondLife::fillRightsData()
+{
+ if (getSelfProfile())
+ {
+ return;
+ }
+
+ const LLRelationship* relation = LLAvatarTracker::instance().getBuddyInfo(getAvatarId());
+ // If true - we are viewing friend's profile, enable check boxes and set values.
+ if (relation)
+ {
+ S32 rights = relation->getRightsGrantedTo();
+ bool can_see_online = LLRelationship::GRANT_ONLINE_STATUS & rights;
+ bool can_see_on_map = LLRelationship::GRANT_MAP_LOCATION & rights;
+ bool can_edit_objects = LLRelationship::GRANT_MODIFY_OBJECTS & rights;
+
+ mCanSeeOnlineIcon->setVisible(can_see_online);
+ mCantSeeOnlineIcon->setVisible(!can_see_online);
+ mCanSeeOnMapIcon->setVisible(can_see_on_map);
+ mCantSeeOnMapIcon->setVisible(!can_see_on_map);
+ mCanEditObjectsIcon->setVisible(can_edit_objects);
+ mCantEditObjectsIcon->setVisible(!can_edit_objects);
+
+ mCanSeeOnlineIcon->setEnabled(true);
+ mCantSeeOnlineIcon->setEnabled(true);
+ mCanSeeOnMapIcon->setEnabled(true);
+ mCantSeeOnMapIcon->setEnabled(true);
+ mCanEditObjectsIcon->setEnabled(true);
+ mCantEditObjectsIcon->setEnabled(true);
+ }
+ else
+ {
+ mCanSeeOnlineIcon->setVisible(false);
+ mCantSeeOnlineIcon->setVisible(false);
+ mCanSeeOnMapIcon->setVisible(false);
+ mCantSeeOnMapIcon->setVisible(false);
+ mCanEditObjectsIcon->setVisible(false);
+ mCantEditObjectsIcon->setVisible(false);
+ }
+}
+
+void LLPanelProfileSecondLife::fillAgeData(const LLDate &born_on)
+{
+ std::string name_and_date = getString("date_format");
+ LLSD args_name;
+ args_name["datetime"] = (S32)born_on.secondsSinceEpoch();
+ LLStringUtil::format(name_and_date, args_name);
+ getChild<LLUICtrl>("sl_birth_date")->setValue(name_and_date);
+
+ std::string register_date = getString("age_format");
+ LLSD args_age;
+ args_age["[AGE]"] = LLDateUtil::ageFromDate(born_on, LLDate::now());
+ LLStringUtil::format(register_date, args_age);
+ getChild<LLUICtrl>("user_age")->setValue(register_date);
+}
+
+void LLPanelProfileSecondLife::onImageLoaded(BOOL success, LLViewerFetchedTexture *imagep)
+{
+ LLRect imageRect = mSecondLifePicLayout->getRect();
+ if (!success || imagep->getFullWidth() == imagep->getFullHeight())
+ {
+ mSecondLifePicLayout->reshape(imageRect.getWidth(), imageRect.getWidth());
+ }
+ else
+ {
+ // assume 3:4, for sake of firestorm
+ mSecondLifePicLayout->reshape(imageRect.getWidth(), imageRect.getWidth() * 3 / 4);
+ }
+}
+
+//static
+void LLPanelProfileSecondLife::onImageLoaded(BOOL success,
+ LLViewerFetchedTexture *src_vi,
+ LLImageRaw* src,
+ LLImageRaw* aux_src,
+ S32 discard_level,
+ BOOL final,
+ void* userdata)
+{
+ if (!userdata) return;
+
+ LLHandle<LLPanel>* handle = (LLHandle<LLPanel>*)userdata;
+
+ if (!handle->isDead())
+ {
+ LLPanelProfileSecondLife* panel = static_cast<LLPanelProfileSecondLife*>(handle->get());
+ if (panel)
+ {
+ panel->onImageLoaded(success, src_vi);
+ }
+ }
+
+ if (final || !success)
+ {
+ delete handle;
+ }
+}
+
+// virtual, called by LLAvatarTracker
+void LLPanelProfileSecondLife::changed(U32 mask)
+{
+ updateOnlineStatus();
+ if (mask != LLFriendObserver::ONLINE)
+ {
+ fillRightsData();
+ }
+}
+
+// virtual, called by LLVoiceClient
+void LLPanelProfileSecondLife::onChange(EStatusType status, const std::string &channelURI, bool proximal)
+{
+ if(status == STATUS_JOINING || status == STATUS_LEFT_CHANNEL)
+ {
+ return;
+ }
+
+ mVoiceStatus = LLAvatarActions::canCall() && (LLAvatarActions::isFriend(getAvatarId()) ? LLAvatarTracker::instance().isBuddyOnline(getAvatarId()) : TRUE);
+}
+
+void LLPanelProfileSecondLife::setAvatarId(const LLUUID& avatar_id)
+{
+ if (avatar_id.notNull())
+ {
+ if (getAvatarId().notNull())
+ {
+ LLAvatarTracker::instance().removeParticularFriendObserver(getAvatarId(), this);
+ }
+
+ LLPanelProfileTab::setAvatarId(avatar_id);
+
+ if (LLAvatarActions::isFriend(getAvatarId()))
+ {
+ LLAvatarTracker::instance().addParticularFriendObserver(getAvatarId(), this);
+ }
+ }
+}
+
+// method was disabled according to EXT-2022. Re-enabled & improved according to EXT-3880
+void LLPanelProfileSecondLife::updateOnlineStatus()
+{
+ const LLRelationship* relationship = LLAvatarTracker::instance().getBuddyInfo(getAvatarId());
+ if (relationship != NULL)
+ {
+ // For friend let check if he allowed me to see his status
+ bool online = relationship->isOnline();
+ bool perm_granted = relationship->isRightGrantedFrom(LLRelationship::GRANT_ONLINE_STATUS);
+ processOnlineStatus(true, perm_granted, online);
+ }
+ else
+ {
+ childSetVisible("frind_layout", false);
+ childSetVisible("online_layout", false);
+ childSetVisible("offline_layout", false);
+ }
+}
+
+void LLPanelProfileSecondLife::processOnlineStatus(bool is_friend, bool show_online, bool online)
+{
+ childSetVisible("frind_layout", is_friend);
+ childSetVisible("online_layout", online && show_online);
+ childSetVisible("offline_layout", !online && show_online);
+}
+
+void LLPanelProfileSecondLife::setLoaded()
+{
+ LLPanelProfileTab::setLoaded();
+
+ if (getSelfProfile())
+ {
+ mShowInSearchCombo->setEnabled(TRUE);
+ mDescriptionEdit->setEnabled(TRUE);
+ }
+}
+
+
+
+class LLProfileImagePicker : public LLFilePickerThread
+{
+public:
+ LLProfileImagePicker(EProfileImageType type, LLHandle<LLPanel> *handle);
+ ~LLProfileImagePicker();
+ void notify(const std::vector<std::string>& filenames) override;
+
+private:
+ LLHandle<LLPanel> *mHandle;
+ EProfileImageType mType;
+};
+
+LLProfileImagePicker::LLProfileImagePicker(EProfileImageType type, LLHandle<LLPanel> *handle)
+ : LLFilePickerThread(LLFilePicker::FFLOAD_IMAGE),
+ mHandle(handle),
+ mType(type)
+{
+}
+
+LLProfileImagePicker::~LLProfileImagePicker()
+{
+ delete mHandle;
+}
+
+void LLProfileImagePicker::notify(const std::vector<std::string>& filenames)
+{
+ if (mHandle->isDead())
+ {
+ return;
+ }
+ if (filenames.empty())
+ {
+ return;
+ }
+ std::string file_path = filenames[0];
+ if (file_path.empty())
+ {
+ return;
+ }
+
+ // generate a temp texture file for coroutine
+ std::string temp_file = gDirUtilp->getTempFilename();
+ U32 codec = LLImageBase::getCodecFromExtension(gDirUtilp->getExtension(file_path));
+ const S32 MAX_DIM = 256;
+ if (!LLViewerTextureList::createUploadFile(file_path, temp_file, codec, MAX_DIM))
+ {
+ //todo: image not supported notification
+ LL_WARNS("AvatarProperties") << "Failed to upload profile image of type " << (S32)PROFILE_IMAGE_SL << ", failed to open image" << LL_ENDL;
+ return;
+ }
+
+ std::string cap_url = gAgent.getRegionCapability(PROFILE_IMAGE_UPLOAD_CAP);
+ if (cap_url.empty())
+ {
+ LL_WARNS("AvatarProperties") << "Failed to upload profile image of type " << (S32)PROFILE_IMAGE_SL << ", no cap found" << LL_ENDL;
+ return;
+ }
+
+ switch (mType)
+ {
+ case PROFILE_IMAGE_SL:
+ {
+ LLPanelProfileSecondLife* panel = static_cast<LLPanelProfileSecondLife*>(mHandle->get());
+ panel->setProfileImageUploading(true);
+ }
+ break;
+ case PROFILE_IMAGE_FL:
+ {
+ LLPanelProfileFirstLife* panel = static_cast<LLPanelProfileFirstLife*>(mHandle->get());
+ panel->setProfileImageUploading(true);
+ }
+ break;
+ }
+
+ LLCoros::instance().launch("postAgentUserImageCoro",
+ boost::bind(post_profile_image_coro, cap_url, mType, temp_file, mHandle));
+
+ mHandle = nullptr; // transferred to post_profile_image_coro
+}
+
+void LLPanelProfileSecondLife::onCommitMenu(const LLSD& userdata)
+{
+ const std::string item_name = userdata.asString();
+ const LLUUID agent_id = getAvatarId();
+ // todo: consider moving this into LLAvatarActions::onCommit(name, id)
+ // and making all other flaoters, like people menu do the same
+ if (item_name == "im")
+ {
+ LLAvatarActions::startIM(agent_id);
+ }
+ else if (item_name == "offer_teleport")
+ {
+ LLAvatarActions::offerTeleport(agent_id);
+ }
+ else if (item_name == "request_teleport")
+ {
+ LLAvatarActions::teleportRequest(agent_id);
+ }
+ else if (item_name == "voice_call")
+ {
+ LLAvatarActions::startCall(agent_id);
+ }
+ else if (item_name == "chat_history")
+ {
+ LLAvatarActions::viewChatHistory(agent_id);
+ }
+ else if (item_name == "add_friend")
+ {
+ LLAvatarActions::requestFriendshipDialog(agent_id);
+ }
+ else if (item_name == "remove_friend")
+ {
+ LLAvatarActions::removeFriendDialog(agent_id);
+ }
+ else if (item_name == "invite_to_group")
+ {
+ LLAvatarActions::inviteToGroup(agent_id);
+ }
+ else if (item_name == "can_show_on_map")
+ {
+ LLAvatarActions::showOnMap(agent_id);
+ }
+ else if (item_name == "share")
+ {
+ LLAvatarActions::share(agent_id);
+ }
+ else if (item_name == "pay")
+ {
+ LLAvatarActions::pay(agent_id);
+ }
+ else if (item_name == "toggle_block_agent")
+ {
+ LLAvatarActions::toggleBlock(agent_id);
+ }
+ else if (item_name == "copy_user_id")
+ {
+ LLWString wstr = utf8str_to_wstring(getAvatarId().asString());
+ LLClipboard::instance().copyToClipboard(wstr, 0, wstr.size());
+ }
+ else if (item_name == "agent_permissions")
+ {
+ onShowAgentPermissionsDialog();
+ }
+ else if (item_name == "copy_display_name"
+ || item_name == "copy_username")
+ {
+ LLAvatarName av_name;
+ if (!LLAvatarNameCache::get(getAvatarId(), &av_name))
+ {
+ // shouldn't happen, option is supposed to be invisible while name is fetching
+ LL_WARNS() << "Failed to get agent data" << LL_ENDL;
+ return;
+ }
+ LLWString wstr;
+ if (item_name == "copy_display_name")
+ {
+ wstr = utf8str_to_wstring(av_name.getDisplayName(true));
+ }
+ else if (item_name == "copy_username")
+ {
+ wstr = utf8str_to_wstring(av_name.getUserName());
+ }
+ LLClipboard::instance().copyToClipboard(wstr, 0, wstr.size());
+ }
+ else if (item_name == "edit_display_name")
+ {
+ LLAvatarNameCache::get(getAvatarId(), boost::bind(&LLPanelProfileSecondLife::onAvatarNameCacheSetName, this, _1, _2));
+ LLFirstUse::setDisplayName(false);
+ }
+ else if (item_name == "edit_partner")
+ {
+ std::string url = "https://[GRID]/my/account/partners.php";
+ LLSD subs;
+ url = LLWeb::expandURLSubstitutions(url, subs);
+ LLUrlAction::openURL(url);
+ }
+ else if (item_name == "upload_photo")
+ {
+ (new LLProfileImagePicker(PROFILE_IMAGE_SL, new LLHandle<LLPanel>(getHandle())))->getFile();
+
+ LLFloater* floaterp = mFloaterTexturePickerHandle.get();
+ if (floaterp)
+ {
+ floaterp->closeFloater();
+ }
+ }
+ else if (item_name == "change_photo")
+ {
+ onShowTexturePicker();
+ }
+ else if (item_name == "remove_photo")
+ {
+ onCommitProfileImage(LLUUID::null);
+
+ LLFloater* floaterp = mFloaterTexturePickerHandle.get();
+ if (floaterp)
+ {
+ floaterp->closeFloater();
+ }
+ }
+}
+
+bool LLPanelProfileSecondLife::onEnableMenu(const LLSD& userdata)
+{
+ const std::string item_name = userdata.asString();
+ const LLUUID agent_id = getAvatarId();
+ if (item_name == "offer_teleport" || item_name == "request_teleport")
+ {
+ return LLAvatarActions::canOfferTeleport(agent_id);
+ }
+ else if (item_name == "voice_call")
+ {
+ return mVoiceStatus;
+ }
+ else if (item_name == "chat_history")
+ {
+ return LLLogChat::isTranscriptExist(agent_id);
+ }
+ else if (item_name == "add_friend")
+ {
+ return !LLAvatarActions::isFriend(agent_id);
+ }
+ else if (item_name == "remove_friend")
+ {
+ return LLAvatarActions::isFriend(agent_id);
+ }
+ else if (item_name == "can_show_on_map")
+ {
+ return (LLAvatarTracker::instance().isBuddyOnline(agent_id) && is_agent_mappable(agent_id))
+ || gAgent.isGodlike();
+ }
+ else if (item_name == "toggle_block_agent")
+ {
+ return LLAvatarActions::canBlock(agent_id);
+ }
+ else if (item_name == "agent_permissions")
+ {
+ return LLAvatarActions::isFriend(agent_id);
+ }
+ else if (item_name == "copy_display_name"
+ || item_name == "copy_username")
+ {
+ return !mAvatarNameCacheConnection.connected();
+ }
+ else if (item_name == "upload_photo"
+ || item_name == "change_photo")
+ {
+ std::string cap_url = gAgent.getRegionCapability(PROFILE_IMAGE_UPLOAD_CAP);
+ return !cap_url.empty() && !mWaitingForImageUpload && getIsLoaded();
+ }
+ else if (item_name == "remove_photo")
+ {
+ std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP);
+ return mImageId.notNull() && !cap_url.empty() && !mWaitingForImageUpload && getIsLoaded();
+ }
+
+ return false;
+}
+
+bool LLPanelProfileSecondLife::onCheckMenu(const LLSD& userdata)
+{
+ const std::string item_name = userdata.asString();
+ const LLUUID agent_id = getAvatarId();
+ if (item_name == "toggle_block_agent")
+ {
+ return LLAvatarActions::isBlocked(agent_id);
+ }
+ return false;
+}
+
+void LLPanelProfileSecondLife::onAvatarNameCacheSetName(const LLUUID& agent_id, const LLAvatarName& av_name)
+{
+ if (av_name.getDisplayName().empty())
+ {
+ // something is wrong, tell user to try again later
+ LLNotificationsUtil::add("SetDisplayNameFailedGeneric");
+ return;
+ }
+
+ LL_INFOS("LegacyProfile") << "name-change now " << LLDate::now() << " next_update "
+ << LLDate(av_name.mNextUpdate) << LL_ENDL;
+ F64 now_secs = LLDate::now().secondsSinceEpoch();
+
+ if (now_secs < av_name.mNextUpdate)
+ {
+ // if the update time is more than a year in the future, it means updates have been blocked
+ // show a more general message
+ static const S32 YEAR = 60*60*24*365;
+ if (now_secs + YEAR < av_name.mNextUpdate)
+ {
+ LLNotificationsUtil::add("SetDisplayNameBlocked");
+ return;
+ }
+ }
+
+ LLFloaterReg::showInstance("display_name");
+}
+
+void LLPanelProfileSecondLife::setDescriptionText(const std::string &text)
+{
+ mSaveDescriptionChanges->setEnabled(FALSE);
+ mDiscardDescriptionChanges->setEnabled(FALSE);
+ mHasUnsavedDescriptionChanges = false;
+
+ mDescriptionText = text;
+ mDescriptionEdit->setValue(mDescriptionText);
+}
+
+void LLPanelProfileSecondLife::onSetDescriptionDirty()
+{
+ mSaveDescriptionChanges->setEnabled(TRUE);
+ mDiscardDescriptionChanges->setEnabled(TRUE);
+ mHasUnsavedDescriptionChanges = true;
+}
+
+void LLPanelProfileSecondLife::onShowInSearchCallback()
+{
+ S32 value = mShowInSearchCombo->getValue().asInteger();
+ if (mAllowPublish == (bool)value)
+ {
+ return;
+ }
+ std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP);
+ if (!cap_url.empty())
+ {
+ mAllowPublish = value;
+ LLSD data;
+ data["allow_publish"] = mAllowPublish;
+ LLCoros::instance().launch("putAgentUserInfoCoro",
+ boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), data));
+ }
+ else
+ {
+ LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL;
+ }
+}
+
+void LLPanelProfileSecondLife::onSaveDescriptionChanges()
+{
+ mDescriptionText = mDescriptionEdit->getValue().asString();
+ std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP);
+ if (!cap_url.empty())
+ {
+ LLCoros::instance().launch("putAgentUserInfoCoro",
+ boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), LLSD().with("sl_about_text", mDescriptionText)));
+ }
+ else
+ {
+ LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL;
+ }
+
+ mSaveDescriptionChanges->setEnabled(FALSE);
+ mDiscardDescriptionChanges->setEnabled(FALSE);
+ mHasUnsavedDescriptionChanges = false;
+}
+
+void LLPanelProfileSecondLife::onDiscardDescriptionChanges()
+{
+ setDescriptionText(mDescriptionText);
+}
+
+void LLPanelProfileSecondLife::onShowAgentPermissionsDialog()
+{
+ LLFloater *floater = mFloaterPermissionsHandle.get();
+ if (!floater)
+ {
+ LLFloater* parent_floater = gFloaterView->getParentFloater(this);
+ if (parent_floater)
+ {
+ LLFloaterProfilePermissions * perms = new LLFloaterProfilePermissions(parent_floater, getAvatarId());
+ mFloaterPermissionsHandle = perms->getHandle();
+ perms->openFloater();
+ perms->setVisibleAndFrontmost(TRUE);
+
+ parent_floater->addDependentFloater(mFloaterPermissionsHandle);
+ }
+ }
+ else // already open
+ {
+ floater->setMinimized(FALSE);
+ floater->setVisibleAndFrontmost(TRUE);
+ }
+}
+
+void LLPanelProfileSecondLife::onShowAgentProfileTexture()
+{
+ if (!getIsLoaded())
+ {
+ return;
+ }
+
+ LLFloater *floater = mFloaterProfileTextureHandle.get();
+ if (!floater)
+ {
+ LLFloater* parent_floater = gFloaterView->getParentFloater(this);
+ if (parent_floater)
+ {
+ LLFloaterProfileTexture * texture_view = new LLFloaterProfileTexture(parent_floater);
+ mFloaterProfileTextureHandle = texture_view->getHandle();
+ if (mImageId.notNull())
+ {
+ texture_view->loadAsset(mImageId);
+ }
+ else
+ {
+ texture_view->resetAsset();
+ }
+ texture_view->openFloater();
+ texture_view->setVisibleAndFrontmost(TRUE);
+
+ parent_floater->addDependentFloater(mFloaterProfileTextureHandle);
+ }
+ }
+ else // already open
+ {
+ LLFloaterProfileTexture * texture_view = dynamic_cast<LLFloaterProfileTexture*>(floater);
+ texture_view->setMinimized(FALSE);
+ texture_view->setVisibleAndFrontmost(TRUE);
+ if (mImageId.notNull())
+ {
+ texture_view->loadAsset(mImageId);
+ }
+ else
+ {
+ texture_view->resetAsset();
+ }
+ }
+}
+
+void LLPanelProfileSecondLife::onShowTexturePicker()
+{
+ LLFloater* floaterp = mFloaterTexturePickerHandle.get();
+
+ // Show the dialog
+ if (!floaterp)
+ {
+ LLFloater* parent_floater = gFloaterView->getParentFloater(this);
+ if (parent_floater)
+ {
+ // because inventory construction is somewhat slow
+ getWindow()->setCursor(UI_CURSOR_WAIT);
+ LLFloaterTexturePicker* texture_floaterp = new LLFloaterTexturePicker(
+ this,
+ mImageId,
+ LLUUID::null,
+ mImageId,
+ FALSE,
+ FALSE,
+ "SELECT PHOTO",
+ PERM_NONE,
+ PERM_NONE,
+ PERM_NONE,
+ FALSE,
+ NULL);
+
+ mFloaterTexturePickerHandle = texture_floaterp->getHandle();
+
+ texture_floaterp->setOnFloaterCommitCallback([this](LLTextureCtrl::ETexturePickOp op, LLUUID id)
+ {
+ if (op == LLTextureCtrl::TEXTURE_SELECT)
+ {
+ LLUUID image_asset_id;
+ LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterTexturePickerHandle.get();
+ if (floaterp)
+ {
+ if (id.notNull())
+ {
+ image_asset_id = id;
+ }
+ else
+ {
+ image_asset_id = floaterp->getAssetID();
+ }
+ }
+
+ onCommitProfileImage(image_asset_id);
+ }
+ });
+ texture_floaterp->setLocalTextureEnabled(FALSE);
+ texture_floaterp->setBakeTextureEnabled(FALSE);
+ texture_floaterp->setCanApply(false, true);
+
+ parent_floater->addDependentFloater(mFloaterTexturePickerHandle);
+
+ texture_floaterp->openFloater();
+ texture_floaterp->setFocus(TRUE);
+ }
+ }
+ else
+ {
+ floaterp->setMinimized(FALSE);
+ floaterp->setVisibleAndFrontmost(TRUE);
+ }
+}
+
+void LLPanelProfileSecondLife::onCommitProfileImage(const LLUUID& id)
+{
+ if (mImageId == id)
+ {
+ return;
+ }
+
+ std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP);
+ if (!cap_url.empty())
+ {
+ LLSD params;
+ params["sl_image_id"] = id;
+ LLCoros::instance().launch("putAgentUserInfoCoro",
+ boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), params));
+
+ mImageId = id;
+ if (mImageId == LLUUID::null)
+ {
+ mSecondLifePic->setValue("Generic_Person_Large");
+ }
+ else
+ {
+ mSecondLifePic->setValue(mImageId);
+ }
+
+ LLFloater *floater = mFloaterProfileTextureHandle.get();
+ if (floater)
+ {
+ LLFloaterProfileTexture * texture_view = dynamic_cast<LLFloaterProfileTexture*>(floater);
+ if (mImageId == LLUUID::null)
+ {
+ texture_view->resetAsset();
+ }
+ else
+ {
+ texture_view->loadAsset(mImageId);
+ }
+ }
+ }
+ else
+ {
+ LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL;
+ }
+}
+
+void LLPanelProfileSecondLife::onOpenNotes()
+{
+ LLFloater* parent_floater = gFloaterView->getParentFloater(this);
+ if (!parent_floater)
+ {
+ return;
+ }
+
+ LLTabContainer* tab_container = parent_floater->findChild<LLTabContainer>("panel_profile_tabs", TRUE);
+ if (!tab_container)
+ {
+ return;
+ }
+
+ tab_container->selectTabByName(PANEL_NOTES);
+}
+
+//////////////////////////////////////////////////////////////////////////
+// LLPanelProfileWeb
+
+LLPanelProfileWeb::LLPanelProfileWeb()
+ : LLPanelProfileTab()
+ , mWebBrowser(NULL)
+ , mAvatarNameCacheConnection()
+{
+}
+
+LLPanelProfileWeb::~LLPanelProfileWeb()
+{
+ if (mAvatarNameCacheConnection.connected())
+ {
+ mAvatarNameCacheConnection.disconnect();
+ }
+}
+
+void LLPanelProfileWeb::onOpen(const LLSD& key)
+{
+ LLPanelProfileTab::onOpen(key);
+
+ resetData();
+
+ mAvatarNameCacheConnection = LLAvatarNameCache::get(getAvatarId(), boost::bind(&LLPanelProfileWeb::onAvatarNameCache, this, _1, _2));
+}
+
+BOOL LLPanelProfileWeb::postBuild()
+{
+ mWebBrowser = getChild<LLMediaCtrl>("profile_html");
+ mWebBrowser->addObserver(this);
+ mWebBrowser->setHomePageUrl("about:blank");
+
+ return TRUE;
+}
+
+void LLPanelProfileWeb::resetData()
+{
+ mWebBrowser->navigateHome();
+}
+
+void LLPanelProfileWeb::updateData()
+{
+ LLUUID avatar_id = getAvatarId();
+ if (!getStarted() && avatar_id.notNull() && !mURLWebProfile.empty())
+ {
+ setIsLoading();
+
+ mWebBrowser->setVisible(TRUE);
+ mPerformanceTimer.start();
+ mWebBrowser->navigateTo(mURLWebProfile, HTTP_CONTENT_TEXT_HTML);
+ }
+}
+
+void LLPanelProfileWeb::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name)
+{
+ mAvatarNameCacheConnection.disconnect();
+
+ std::string username = av_name.getAccountName();
+ if (username.empty())
+ {
+ username = LLCacheName::buildUsername(av_name.getDisplayName());
+ }
+ else
+ {
+ LLStringUtil::replaceChar(username, ' ', '.');
+ }
+
+ mURLWebProfile = getProfileURL(username, true);
+ if (mURLWebProfile.empty())
+ {
+ return;
+ }
+
+ //if the tab was opened before name was resolved, load the panel now
+ updateData();
+}
+
+void LLPanelProfileWeb::onCommitLoad(LLUICtrl* ctrl)
+{
+ if (!mURLHome.empty())
+ {
+ LLSD::String valstr = ctrl->getValue().asString();
+ if (valstr.empty())
+ {
+ mWebBrowser->setVisible(TRUE);
+ mPerformanceTimer.start();
+ mWebBrowser->navigateTo( mURLHome, HTTP_CONTENT_TEXT_HTML );
+ }
+ else if (valstr == "popout")
+ {
+ // open in viewer's browser, new window
+ LLWeb::loadURLInternal(mURLHome);
+ }
+ else if (valstr == "external")
+ {
+ // open in external browser
+ LLWeb::loadURLExternal(mURLHome);
+ }
+ }
+}
+
+void LLPanelProfileWeb::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
+{
+ switch(event)
+ {
+ case MEDIA_EVENT_STATUS_TEXT_CHANGED:
+ childSetValue("status_text", LLSD( self->getStatusText() ) );
+ break;
+
+ case MEDIA_EVENT_NAVIGATE_BEGIN:
+ {
+ if (mFirstNavigate)
+ {
+ mFirstNavigate = false;
+ }
+ else
+ {
+ mPerformanceTimer.start();
+ }
+ }
+ break;
+
+ case MEDIA_EVENT_NAVIGATE_COMPLETE:
+ {
+ LLStringUtil::format_map_t args;
+ args["[TIME]"] = llformat("%.2f", mPerformanceTimer.getElapsedTimeF32());
+ childSetValue("status_text", LLSD( getString("LoadTime", args)) );
+ }
+ break;
+
+ default:
+ // Having a default case makes the compiler happy.
+ break;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+LLPanelProfileFirstLife::LLPanelProfileFirstLife()
+ : LLPanelProfileTab()
+ , mHasUnsavedChanges(false)
+{
+}
+
+LLPanelProfileFirstLife::~LLPanelProfileFirstLife()
+{
+}
+
+BOOL LLPanelProfileFirstLife::postBuild()
+{
+ mDescriptionEdit = getChild<LLTextEditor>("fl_description_edit");
+ mPicture = getChild<LLIconCtrl>("real_world_pic");
+
+ mUploadPhoto = getChild<LLButton>("fl_upload_image");
+ mChangePhoto = getChild<LLButton>("fl_change_image");
+ mRemovePhoto = getChild<LLButton>("fl_remove_image");
+ mSaveChanges = getChild<LLButton>("fl_save_changes");
+ mDiscardChanges = getChild<LLButton>("fl_discard_changes");
+
+ mUploadPhoto->setCommitCallback([this](LLUICtrl*, void*) { onUploadPhoto(); }, nullptr);
+ mChangePhoto->setCommitCallback([this](LLUICtrl*, void*) { onChangePhoto(); }, nullptr);
+ mRemovePhoto->setCommitCallback([this](LLUICtrl*, void*) { onRemovePhoto(); }, nullptr);
+ mSaveChanges->setCommitCallback([this](LLUICtrl*, void*) { onSaveDescriptionChanges(); }, nullptr);
+ mDiscardChanges->setCommitCallback([this](LLUICtrl*, void*) { onDiscardDescriptionChanges(); }, nullptr);
+ mDescriptionEdit->setKeystrokeCallback([this](LLTextEditor* caller) { onSetDescriptionDirty(); });
+
+ return TRUE;
+}
+
+void LLPanelProfileFirstLife::onOpen(const LLSD& key)
+{
+ LLPanelProfileTab::onOpen(key);
+
+ if (!getSelfProfile())
+ {
+ // Otherwise as the only focusable element it will be selected
+ mDescriptionEdit->setTabStop(FALSE);
+ }
+
+ resetData();
+}
+
+void LLPanelProfileFirstLife::setProfileImageUploading(bool loading)
+{
+ mUploadPhoto->setEnabled(!loading);
+ mChangePhoto->setEnabled(!loading);
+ mRemovePhoto->setEnabled(!loading && mImageId.notNull());
+
+ LLLoadingIndicator* indicator = getChild<LLLoadingIndicator>("image_upload_indicator");
+ indicator->setVisible(loading);
+ if (loading)
+ {
+ indicator->start();
+ }
+ else
+ {
+ indicator->stop();
+ }
+}
+
+void LLPanelProfileFirstLife::setProfileImageUploaded(const LLUUID &image_asset_id)
+{
+ mPicture->setValue(image_asset_id);
+ mImageId = image_asset_id;
+ setProfileImageUploading(false);
+}
+
+void LLPanelProfileFirstLife::commitUnsavedChanges()
+{
+ if (mHasUnsavedChanges)
+ {
+ onSaveDescriptionChanges();
+ }
+}
+
+void LLPanelProfileFirstLife::onUploadPhoto()
+{
+ (new LLProfileImagePicker(PROFILE_IMAGE_FL, new LLHandle<LLPanel>(getHandle())))->getFile();
+
+ LLFloater* floaterp = mFloaterTexturePickerHandle.get();
+ if (floaterp)
+ {
+ floaterp->closeFloater();
+ }
+}
+
+void LLPanelProfileFirstLife::onChangePhoto()
+{
+ LLFloater* floaterp = mFloaterTexturePickerHandle.get();
+
+ // Show the dialog
+ if (!floaterp)
+ {
+ LLFloater* parent_floater = gFloaterView->getParentFloater(this);
+ if (parent_floater)
+ {
+ // because inventory construction is somewhat slow
+ getWindow()->setCursor(UI_CURSOR_WAIT);
+ LLFloaterTexturePicker* texture_floaterp = new LLFloaterTexturePicker(
+ this,
+ mImageId,
+ LLUUID::null,
+ mImageId,
+ FALSE,
+ FALSE,
+ "SELECT PHOTO",
+ PERM_NONE,
+ PERM_NONE,
+ PERM_NONE,
+ FALSE,
+ NULL);
+
+ mFloaterTexturePickerHandle = texture_floaterp->getHandle();
+
+ texture_floaterp->setOnFloaterCommitCallback([this](LLTextureCtrl::ETexturePickOp op, LLUUID id)
+ {
+ if (op == LLTextureCtrl::TEXTURE_SELECT)
+ {
+ LLUUID image_asset_id;
+ LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterTexturePickerHandle.get();
+ if (floaterp)
+ {
+ if (id.notNull())
+ {
+ image_asset_id = id;
+ }
+ else
+ {
+ image_asset_id = floaterp->getAssetID();
+ }
+ }
+
+ onCommitPhoto(image_asset_id);
+ }
+ });
+ texture_floaterp->setLocalTextureEnabled(FALSE);
+ texture_floaterp->setCanApply(false, true);
+
+ parent_floater->addDependentFloater(mFloaterTexturePickerHandle);
+
+ texture_floaterp->openFloater();
+ texture_floaterp->setFocus(TRUE);
+ }
+ }
+ else
+ {
+ floaterp->setMinimized(FALSE);
+ floaterp->setVisibleAndFrontmost(TRUE);
+ }
+}
+
+void LLPanelProfileFirstLife::onRemovePhoto()
+{
+ onCommitPhoto(LLUUID::null);
+
+ LLFloater* floaterp = mFloaterTexturePickerHandle.get();
+ if (floaterp)
+ {
+ floaterp->closeFloater();
+ }
+}
+
+void LLPanelProfileFirstLife::onCommitPhoto(const LLUUID& id)
+{
+ if (mImageId == id)
+ {
+ return;
+ }
+
+ std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP);
+ if (!cap_url.empty())
+ {
+ LLSD params;
+ params["fl_image_id"] = id;
+ LLCoros::instance().launch("putAgentUserInfoCoro",
+ boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), params));
+
+ mImageId = id;
+ if (mImageId.notNull())
+ {
+ mPicture->setValue(mImageId);
+ }
+ else
+ {
+ mPicture->setValue("Generic_Person_Large");
+ }
+
+ mRemovePhoto->setEnabled(mImageId.notNull());
+ }
+ else
+ {
+ LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL;
+ }
+}
+
+void LLPanelProfileFirstLife::setDescriptionText(const std::string &text)
+{
+ mSaveChanges->setEnabled(FALSE);
+ mDiscardChanges->setEnabled(FALSE);
+ mHasUnsavedChanges = false;
+
+ mCurrentDescription = text;
+ mDescriptionEdit->setValue(mCurrentDescription);
+}
+
+void LLPanelProfileFirstLife::onSetDescriptionDirty()
+{
+ mSaveChanges->setEnabled(TRUE);
+ mDiscardChanges->setEnabled(TRUE);
+ mHasUnsavedChanges = true;
+}
+
+void LLPanelProfileFirstLife::onSaveDescriptionChanges()
+{
+ mCurrentDescription = mDescriptionEdit->getValue().asString();
+ std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP);
+ if (!cap_url.empty())
+ {
+ LLCoros::instance().launch("putAgentUserInfoCoro",
+ boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), LLSD().with("fl_about_text", mCurrentDescription)));
+ }
+ else
+ {
+ LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL;
+ }
+
+ mSaveChanges->setEnabled(FALSE);
+ mDiscardChanges->setEnabled(FALSE);
+ mHasUnsavedChanges = false;
+}
+
+void LLPanelProfileFirstLife::onDiscardDescriptionChanges()
+{
+ setDescriptionText(mCurrentDescription);
+}
+
+void LLPanelProfileFirstLife::processProperties(const LLAvatarData* avatar_data)
+{
+ setDescriptionText(avatar_data->fl_about_text);
+
+ mImageId = avatar_data->fl_image_id;
+
+ if (mImageId.notNull())
+ {
+ mPicture->setValue(mImageId);
+ }
+ else
+ {
+ mPicture->setValue("Generic_Person_Large");
+ }
+
+ setLoaded();
+}
+
+void LLPanelProfileFirstLife::resetData()
+{
+ setDescriptionText(std::string());
+ mPicture->setValue("Generic_Person_Large");
+ mImageId = LLUUID::null;
+
+ mUploadPhoto->setVisible(getSelfProfile());
+ mChangePhoto->setVisible(getSelfProfile());
+ mRemovePhoto->setVisible(getSelfProfile());
+ mSaveChanges->setVisible(getSelfProfile());
+ mDiscardChanges->setVisible(getSelfProfile());
+}
+
+void LLPanelProfileFirstLife::setLoaded()
+{
+ LLPanelProfileTab::setLoaded();
+
+ if (getSelfProfile())
+ {
+ mDescriptionEdit->setEnabled(TRUE);
+ mPicture->setEnabled(TRUE);
+ mRemovePhoto->setEnabled(mImageId.notNull());
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+LLPanelProfileNotes::LLPanelProfileNotes()
+: LLPanelProfileTab()
+ , mHasUnsavedChanges(false)
+{
+
+}
+
+LLPanelProfileNotes::~LLPanelProfileNotes()
+{
+}
+
+void LLPanelProfileNotes::updateData()
+{
+ LLUUID avatar_id = getAvatarId();
+ if (!getStarted() && avatar_id.notNull())
+ {
+ setIsLoading();
+
+ std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP);
+ if (!cap_url.empty())
+ {
+ LLCoros::instance().launch("requestAgentUserInfoCoro",
+ boost::bind(request_avatar_properties_coro, cap_url, avatar_id));
+ }
+ }
+}
+
+void LLPanelProfileNotes::commitUnsavedChanges()
+{
+ if (mHasUnsavedChanges)
+ {
+ onSaveNotesChanges();
+ }
+}
+
+BOOL LLPanelProfileNotes::postBuild()
+{
+ mNotesEditor = getChild<LLTextEditor>("notes_edit");
+ mSaveChanges = getChild<LLButton>("notes_save_changes");
+ mDiscardChanges = getChild<LLButton>("notes_discard_changes");
+
+ mSaveChanges->setCommitCallback([this](LLUICtrl*, void*) { onSaveNotesChanges(); }, nullptr);
+ mDiscardChanges->setCommitCallback([this](LLUICtrl*, void*) { onDiscardNotesChanges(); }, nullptr);
+ mNotesEditor->setKeystrokeCallback([this](LLTextEditor* caller) { onSetNotesDirty(); });
+
+ return TRUE;
+}
+
+void LLPanelProfileNotes::onOpen(const LLSD& key)
+{
+ LLPanelProfileTab::onOpen(key);
+
+ resetData();
+}
+
+void LLPanelProfileNotes::setNotesText(const std::string &text)
+{
+ mSaveChanges->setEnabled(FALSE);
+ mDiscardChanges->setEnabled(FALSE);
+ mHasUnsavedChanges = false;
+
+ mCurrentNotes = text;
+ mNotesEditor->setValue(mCurrentNotes);
+}
+
+void LLPanelProfileNotes::onSetNotesDirty()
+{
+ mSaveChanges->setEnabled(TRUE);
+ mDiscardChanges->setEnabled(TRUE);
+ mHasUnsavedChanges = true;
+}
+
+void LLPanelProfileNotes::onSaveNotesChanges()
+{
+ mCurrentNotes = mNotesEditor->getValue().asString();
+ std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP);
+ if (!cap_url.empty())
+ {
+ LLCoros::instance().launch("putAgentUserInfoCoro",
+ boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), LLSD().with("notes", mCurrentNotes)));
+ }
+ else
+ {
+ LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL;
+ }
+
+ mSaveChanges->setEnabled(FALSE);
+ mDiscardChanges->setEnabled(FALSE);
+ mHasUnsavedChanges = false;
+}
+
+void LLPanelProfileNotes::onDiscardNotesChanges()
+{
+ setNotesText(mCurrentNotes);
+}
+
+void LLPanelProfileNotes::processProperties(LLAvatarNotes* avatar_notes)
+{
+ setNotesText(avatar_notes->notes);
+ mNotesEditor->setEnabled(TRUE);
+ setLoaded();
+}
+
+void LLPanelProfileNotes::resetData()
+{
+ resetLoading();
+ setNotesText(std::string());
+}
+
+void LLPanelProfileNotes::setAvatarId(const LLUUID& avatar_id)
+{
+ if (avatar_id.notNull())
+ {
+ LLPanelProfileTab::setAvatarId(avatar_id);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// LLPanelProfile
+
+LLPanelProfile::LLPanelProfile()
+ : LLPanelProfileTab()
+{
+}
+
+LLPanelProfile::~LLPanelProfile()
+{
+}
+
+BOOL LLPanelProfile::postBuild()
+{
+ return TRUE;
+}
+
+void LLPanelProfile::onTabChange()
+{
+ LLPanelProfileTab* active_panel = dynamic_cast<LLPanelProfileTab*>(mTabContainer->getCurrentPanel());
+ if (active_panel)
+ {
+ active_panel->updateData();
+ }
}
void LLPanelProfile::onOpen(const LLSD& key)
{
- getTabContainer()[PANEL_PICKS]->onOpen(getAvatarId());
+ LLUUID avatar_id = key["id"].asUUID();
- // support commands to open further pieces of UI
- if (key.has("show_tab_panel"))
- {
- std::string panel = key["show_tab_panel"].asString();
- if (panel == "create_classified")
- {
- LLPanelPicks* picks = dynamic_cast<LLPanelPicks *>(getTabContainer()[PANEL_PICKS]);
- if (picks)
- {
- picks->createNewClassified();
- }
- }
- else if (panel == "classified_details")
- {
- LLPanelPicks* picks = dynamic_cast<LLPanelPicks *>(getTabContainer()[PANEL_PICKS]);
- if (picks)
- {
- LLSD params = key;
- params.erase("show_tab_panel");
- params.erase("open_tab_name");
- picks->openClassifiedInfo(params);
- }
- }
- else if (panel == "edit_classified")
- {
- LLPanelPicks* picks = dynamic_cast<LLPanelPicks *>(getTabContainer()[PANEL_PICKS]);
- if (picks)
- {
- LLSD params = key;
- params.erase("show_tab_panel");
- params.erase("open_tab_name");
- picks->openClassifiedEdit(params);
- }
- }
- else if (panel == "create_pick")
- {
- LLPanelPicks* picks = dynamic_cast<LLPanelPicks *>(getTabContainer()[PANEL_PICKS]);
- if (picks)
- {
- picks->createNewPick();
- }
- }
- else if (panel == "edit_pick")
- {
- LLPanelPicks* picks = dynamic_cast<LLPanelPicks *>(getTabContainer()[PANEL_PICKS]);
- if (picks)
- {
- LLSD params = key;
- params.erase("show_tab_panel");
- params.erase("open_tab_name");
- picks->openPickEdit(params);
- }
- }
- }
+ // Don't reload the same profile
+ if (getAvatarId() == avatar_id)
+ {
+ return;
+ }
+
+ LLPanelProfileTab::onOpen(avatar_id);
+
+ mTabContainer = getChild<LLTabContainer>("panel_profile_tabs");
+ mPanelSecondlife = findChild<LLPanelProfileSecondLife>(PANEL_SECONDLIFE);
+ mPanelWeb = findChild<LLPanelProfileWeb>(PANEL_WEB);
+ mPanelPicks = findChild<LLPanelProfilePicks>(PANEL_PICKS);
+ mPanelClassifieds = findChild<LLPanelProfileClassifieds>(PANEL_CLASSIFIEDS);
+ mPanelFirstlife = findChild<LLPanelProfileFirstLife>(PANEL_FIRSTLIFE);
+ mPanelNotes = findChild<LLPanelProfileNotes>(PANEL_NOTES);
+
+ mPanelSecondlife->onOpen(avatar_id);
+ mPanelWeb->onOpen(avatar_id);
+ mPanelPicks->onOpen(avatar_id);
+ mPanelClassifieds->onOpen(avatar_id);
+ mPanelFirstlife->onOpen(avatar_id);
+ mPanelNotes->onOpen(avatar_id);
+
+ // Always request the base profile info
+ resetLoading();
+ updateData();
+
+ // Some tabs only request data when opened
+ mTabContainer->setCommitCallback(boost::bind(&LLPanelProfile::onTabChange, this));
}
-void LLPanelProfile::onTabSelected(const LLSD& param)
+void LLPanelProfile::updateData()
{
- std::string tab_name = param.asString();
- if (NULL != getTabContainer()[tab_name])
- {
- getTabContainer()[tab_name]->onOpen(getAvatarId());
- }
+ LLUUID avatar_id = getAvatarId();
+ // Todo: getIsloading functionality needs to be expanded to
+ // include 'inited' or 'data_provided' state to not rerequest
+ if (!getStarted() && avatar_id.notNull())
+ {
+ setIsLoading();
+
+ mPanelSecondlife->setIsLoading();
+ mPanelPicks->setIsLoading();
+ mPanelFirstlife->setIsLoading();
+ mPanelNotes->setIsLoading();
+
+ std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP);
+ if (!cap_url.empty())
+ {
+ LLCoros::instance().launch("requestAgentUserInfoCoro",
+ boost::bind(request_avatar_properties_coro, cap_url, avatar_id));
+ }
+ }
}
-void LLPanelProfile::openPanel(LLPanel* panel, const LLSD& params)
+void LLPanelProfile::refreshName()
{
- // Hide currently visible panel (STORM-690).
- mChildStack.push();
+ mPanelSecondlife->refreshName();
+}
- // Add the panel or bring it to front.
- if (panel->getParent() != this)
- {
- addChild(panel);
- }
- else
- {
- sendChildToFront(panel);
- }
+void LLPanelProfile::createPick(const LLPickData &data)
+{
+ mTabContainer->selectTabPanel(mPanelPicks);
+ mPanelPicks->createPick(data);
+}
- panel->setVisible(TRUE);
- panel->setFocus(TRUE); // prevent losing focus by the floater
- panel->onOpen(params);
+void LLPanelProfile::showPick(const LLUUID& pick_id)
+{
+ if (pick_id.notNull())
+ {
+ mPanelPicks->selectPick(pick_id);
+ }
+ mTabContainer->selectTabPanel(mPanelPicks);
+}
- LLRect new_rect = getRect();
- panel->reshape(new_rect.getWidth(), new_rect.getHeight());
- new_rect.setLeftTopAndSize(0, new_rect.getHeight(), new_rect.getWidth(), new_rect.getHeight());
- panel->setRect(new_rect);
+bool LLPanelProfile::isPickTabSelected()
+{
+ return (mTabContainer->getCurrentPanel() == mPanelPicks);
}
-void LLPanelProfile::closePanel(LLPanel* panel)
+bool LLPanelProfile::isNotesTabSelected()
{
- panel->setVisible(FALSE);
+ return (mTabContainer->getCurrentPanel() == mPanelNotes);
+}
- if (panel->getParent() == this)
- {
- removeChild(panel);
+bool LLPanelProfile::hasUnsavedChanges()
+{
+ return mPanelSecondlife->hasUnsavedChanges()
+ || mPanelPicks->hasUnsavedChanges()
+ || mPanelClassifieds->hasUnsavedChanges()
+ || mPanelFirstlife->hasUnsavedChanges()
+ || mPanelNotes->hasUnsavedChanges();
+}
- // Make the underlying panel visible.
- mChildStack.pop();
+bool LLPanelProfile::hasUnpublishedClassifieds()
+{
+ return mPanelClassifieds->hasNewClassifieds();
+}
- // Prevent losing focus by the floater
- const child_list_t* child_list = getChildList();
- if (child_list->size() > 0)
- {
- child_list->front()->setFocus(TRUE);
- }
- else
- {
- LL_WARNS() << "No underlying panel to focus." << LL_ENDL;
- }
- }
+void LLPanelProfile::commitUnsavedChanges()
+{
+ mPanelSecondlife->commitUnsavedChanges();
+ mPanelPicks->commitUnsavedChanges();
+ mPanelClassifieds->commitUnsavedChanges();
+ mPanelFirstlife->commitUnsavedChanges();
+ mPanelNotes->commitUnsavedChanges();
}
-S32 LLPanelProfile::notifyParent(const LLSD& info)
+void LLPanelProfile::showClassified(const LLUUID& classified_id, bool edit)
{
- std::string action = info["action"];
- // lets update Picks list after Pick was saved
- if("save_new_pick" == action)
- {
- onOpen(info);
- return 1;
- }
+ if (classified_id.notNull())
+ {
+ mPanelClassifieds->selectClassified(classified_id, edit);
+ }
+ mTabContainer->selectTabPanel(mPanelClassifieds);
+}
- return LLPanel::notifyParent(info);
+void LLPanelProfile::createClassified()
+{
+ mPanelClassifieds->createClassified();
+ mTabContainer->selectTabPanel(mPanelClassifieds);
}
+
diff --git a/indra/newview/llpanelprofile.h b/indra/newview/llpanelprofile.h
index d97f60ed22..ca6ef3f794 100644
--- a/indra/newview/llpanelprofile.h
+++ b/indra/newview/llpanelprofile.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file llpanelprofile.h
* @brief Profile panel
*
-* $LicenseInfo:firstyear=2009&license=viewerlgpl$
+* $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
-* Copyright (C) 2010, Linden Research, Inc.
-*
+* Copyright (C) 2022, 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$
*/
@@ -27,76 +27,384 @@
#ifndef LL_LLPANELPROFILE_H
#define LL_LLPANELPROFILE_H
+#include "llavatarpropertiesprocessor.h"
+#include "llcallingcard.h"
+#include "llfloater.h"
#include "llpanel.h"
#include "llpanelavatar.h"
+#include "llmediactrl.h"
+#include "llvoiceclient.h"
+
+// class LLPanelProfileClassifieds;
+// class LLTabContainer;
+// class LLPanelProfileSecondLife;
+// class LLPanelProfileWeb;
+// class LLPanelProfilePicks;
+// class LLPanelProfileFirstLife;
+// class LLPanelProfileNotes;
+
+class LLAvatarName;
+class LLButton;
+class LLCheckBoxCtrl;
+class LLComboBox;
+class LLIconCtrl;
class LLTabContainer;
+class LLTextBox;
+class LLTextureCtrl;
+class LLMediaCtrl;
+class LLGroupList;
+class LLTextBase;
+class LLMenuButton;
+class LLLineEditor;
+class LLTextEditor;
+class LLPanelProfileClassifieds;
+class LLPanelProfilePicks;
+class LLViewerFetchedTexture;
-std::string getProfileURL(const std::string& agent_name);
/**
-* Base class for Profile View and My Profile.
+* Panel for displaying Avatar's second life related info.
*/
-class LLPanelProfile : public LLPanel
+class LLPanelProfileSecondLife
+ : public LLPanelProfileTab
+ , public LLFriendObserver
+ , public LLVoiceClientStatusObserver
{
- LOG_CLASS(LLPanelProfile);
+public:
+ LLPanelProfileSecondLife();
+ /*virtual*/ ~LLPanelProfileSecondLife();
+
+ void onOpen(const LLSD& key) override;
+
+ /**
+ * LLFriendObserver trigger
+ */
+ void changed(U32 mask) override;
+
+ // Implements LLVoiceClientStatusObserver::onChange() to enable the call
+ // button when voice is available
+ void onChange(EStatusType status, const std::string &channelURI, bool proximal) override;
+
+ void setAvatarId(const LLUUID& avatar_id) override;
+
+ BOOL postBuild() override;
+
+ void resetData() override;
+
+ /**
+ * Sends update data request to server.
+ */
+ void updateData() override;
+ void refreshName();
+
+ void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
+
+ void setProfileImageUploading(bool loading);
+ void setProfileImageUploaded(const LLUUID &image_asset_id);
+
+ bool hasUnsavedChanges() override;
+ void commitUnsavedChanges() override;
+
+ friend void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id);
+
+protected:
+ /**
+ * Process profile related data received from server.
+ */
+ void processProfileProperties(const LLAvatarData* avatar_data);
+
+ /**
+ * Processes group related data received from server.
+ */
+ void processGroupProperties(const LLAvatarGroups* avatar_groups);
+
+ /**
+ * Fills common for Avatar profile and My Profile fields.
+ */
+ void fillCommonData(const LLAvatarData* avatar_data);
+
+ /**
+ * Fills partner data.
+ */
+ void fillPartnerData(const LLAvatarData* avatar_data);
+ /**
+ * Fills account status.
+ */
+ void fillAccountStatus(const LLAvatarData* avatar_data);
+
+ /**
+ * Sets permissions specific icon
+ */
+ void fillRightsData();
+
+ /**
+ * Fills user name, display name, age.
+ */
+ void fillAgeData(const LLDate &born_on);
+
+ void onImageLoaded(BOOL success, LLViewerFetchedTexture *imagep);
+ static void onImageLoaded(BOOL success,
+ LLViewerFetchedTexture *src_vi,
+ LLImageRaw* src,
+ LLImageRaw* aux_src,
+ S32 discard_level,
+ BOOL final,
+ void* userdata);
+
+ /**
+ * Displays avatar's online status if possible.
+ *
+ * Requirements from EXT-3880:
+ * For friends:
+ * - Online when online and privacy settings allow to show
+ * - Offline when offline and privacy settings allow to show
+ * - Else: nothing
+ * For other avatars:
+ * - Online when online and was not set in Preferences/"Only Friends & Groups can see when I am online"
+ * - Else: Offline
+ */
+ void updateOnlineStatus();
+ void processOnlineStatus(bool is_friend, bool show_online, bool online);
+
+private:
+ void setLoaded() override;
+ void onCommitMenu(const LLSD& userdata);
+ bool onEnableMenu(const LLSD& userdata);
+ bool onCheckMenu(const LLSD& userdata);
+ void onAvatarNameCacheSetName(const LLUUID& id, const LLAvatarName& av_name);
+
+ void setDescriptionText(const std::string &text);
+ void onSetDescriptionDirty();
+ void onShowInSearchCallback();
+ void onSaveDescriptionChanges();
+ void onDiscardDescriptionChanges();
+ void onShowAgentPermissionsDialog();
+ void onShowAgentProfileTexture();
+ void onShowTexturePicker();
+ void onCommitProfileImage(const LLUUID& id);
+ void onOpenNotes();
+
+private:
+ typedef std::map<std::string, LLUUID> group_map_t;
+ group_map_t mGroups;
+ void openGroupProfile();
+
+ LLGroupList* mGroupList;
+ LLComboBox* mShowInSearchCombo;
+ LLIconCtrl* mSecondLifePic;
+ LLPanel* mSecondLifePicLayout;
+ LLTextEditor* mDescriptionEdit;
+ LLMenuButton* mAgentActionMenuButton;
+ LLButton* mSaveDescriptionChanges;
+ LLButton* mDiscardDescriptionChanges;
+ LLIconCtrl* mCanSeeOnlineIcon;
+ LLIconCtrl* mCantSeeOnlineIcon;
+ LLIconCtrl* mCanSeeOnMapIcon;
+ LLIconCtrl* mCantSeeOnMapIcon;
+ LLIconCtrl* mCanEditObjectsIcon;
+ LLIconCtrl* mCantEditObjectsIcon;
+
+ LLHandle<LLFloater> mFloaterPermissionsHandle;
+ LLHandle<LLFloater> mFloaterProfileTextureHandle;
+ LLHandle<LLFloater> mFloaterTexturePickerHandle;
+
+ bool mHasUnsavedDescriptionChanges;
+ bool mVoiceStatus;
+ bool mWaitingForImageUpload;
+ bool mAllowPublish;
+ std::string mDescriptionText;
+ LLUUID mImageId;
+
+ boost::signals2::connection mAvatarNameCacheConnection;
+};
+
+
+/**
+* Panel for displaying Avatar's web profile and home page.
+*/
+class LLPanelProfileWeb
+ : public LLPanelProfileTab
+ , public LLViewerMediaObserver
+{
public:
- /*virtual*/ BOOL postBuild();
- /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
- /*virtual*/ void onOpen(const LLSD& key);
+ LLPanelProfileWeb();
+ /*virtual*/ ~LLPanelProfileWeb();
+
+ void onOpen(const LLSD& key) override;
+
+ BOOL postBuild() override;
- virtual void openPanel(LLPanel* panel, const LLSD& params);
+ void resetData() override;
- virtual void closePanel(LLPanel* panel);
+ /**
+ * Loads web profile.
+ */
+ void updateData() override;
- S32 notifyParent(const LLSD& info);
+ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) override;
+
+ void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
+
+ friend void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id);
protected:
+ void onCommitLoad(LLUICtrl* ctrl);
- LLPanelProfile();
+private:
+ std::string mURLHome;
+ std::string mURLWebProfile;
+ LLMediaCtrl* mWebBrowser;
- virtual void onTabSelected(const LLSD& param);
+ LLFrameTimer mPerformanceTimer;
+ bool mFirstNavigate;
- const LLUUID& getAvatarId() { return mAvatarId; }
+ boost::signals2::connection mAvatarNameCacheConnection;
+};
+
+/**
+* Panel for displaying Avatar's first life related info.
+*/
+class LLPanelProfileFirstLife
+ : public LLPanelProfileTab
+{
+public:
+ LLPanelProfileFirstLife();
+ /*virtual*/ ~LLPanelProfileFirstLife();
+
+ void onOpen(const LLSD& key) override;
+
+ BOOL postBuild() override;
+
+ void processProperties(const LLAvatarData* avatar_data);
+
+ void resetData() override;
+
+ void setProfileImageUploading(bool loading);
+ void setProfileImageUploaded(const LLUUID &image_asset_id);
+
+ bool hasUnsavedChanges() override { return mHasUnsavedChanges; }
+ void commitUnsavedChanges() override;
+
+ friend void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id);
+
+protected:
+ void setLoaded() override;
+
+ void onUploadPhoto();
+ void onChangePhoto();
+ void onRemovePhoto();
+ void onCommitPhoto(const LLUUID& id);
+ void setDescriptionText(const std::string &text);
+ void onSetDescriptionDirty();
+ void onSaveDescriptionChanges();
+ void onDiscardDescriptionChanges();
+
+ LLTextEditor* mDescriptionEdit;
+ LLIconCtrl* mPicture;
+ LLButton* mUploadPhoto;
+ LLButton* mChangePhoto;
+ LLButton* mRemovePhoto;
+ LLButton* mSaveChanges;
+ LLButton* mDiscardChanges;
+
+ LLHandle<LLFloater> mFloaterTexturePickerHandle;
+
+ std::string mCurrentDescription;
+ LLUUID mImageId;
+ bool mHasUnsavedChanges;
+};
+
+/**
+ * Panel for displaying Avatar's notes and modifying friend's rights.
+ */
+class LLPanelProfileNotes
+ : public LLPanelProfileTab
+{
+public:
+ LLPanelProfileNotes();
+ /*virtual*/ ~LLPanelProfileNotes();
- void setAvatarId(const LLUUID& avatar_id) { mAvatarId = avatar_id; }
+ void setAvatarId(const LLUUID& avatar_id) override;
- typedef std::map<std::string, LLPanelProfileTab*> profile_tabs_t;
+ void onOpen(const LLSD& key) override;
- profile_tabs_t& getTabContainer() { return mTabContainer; }
+ BOOL postBuild() override;
+
+ void processProperties(LLAvatarNotes* avatar_notes);
+
+ void resetData() override;
+
+ void updateData() override;
+
+ bool hasUnsavedChanges() override { return mHasUnsavedChanges; }
+ void commitUnsavedChanges() override;
+
+protected:
+ void setNotesText(const std::string &text);
+ void onSetNotesDirty();
+ void onSaveNotesChanges();
+ void onDiscardNotesChanges();
+
+ LLTextEditor* mNotesEditor;
+ LLButton* mSaveChanges;
+ LLButton* mDiscardChanges;
+
+ std::string mCurrentNotes;
+ bool mHasUnsavedChanges;
+};
+
+
+/**
+* Container panel for the profile tabs
+*/
+class LLPanelProfile
+ : public LLPanelProfileTab
+{
+public:
+ LLPanelProfile();
+ /*virtual*/ ~LLPanelProfile();
+
+ BOOL postBuild() override;
+
+ void updateData() override;
+ void refreshName();
+
+ void onOpen(const LLSD& key) override;
+
+ void createPick(const LLPickData &data);
+ void showPick(const LLUUID& pick_id = LLUUID::null);
+ bool isPickTabSelected();
+ bool isNotesTabSelected();
+ bool hasUnsavedChanges() override;
+ bool hasUnpublishedClassifieds();
+ void commitUnsavedChanges() override;
+
+ void showClassified(const LLUUID& classified_id = LLUUID::null, bool edit = false);
+ void createClassified();
+
+ LLAvatarData getAvatarData() { return mAvatarData; };
+
+ friend void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id);
private:
+ void onTabChange();
+
+ LLPanelProfileSecondLife* mPanelSecondlife;
+ LLPanelProfileWeb* mPanelWeb;
+ LLPanelProfilePicks* mPanelPicks;
+ LLPanelProfileClassifieds* mPanelClassifieds;
+ LLPanelProfileFirstLife* mPanelFirstlife;
+ LLPanelProfileNotes* mPanelNotes;
+ LLTabContainer* mTabContainer;
- //-- ChildStack begins ----------------------------------------------------
- class ChildStack
- {
- LOG_CLASS(LLPanelProfile::ChildStack);
- public:
- ChildStack();
- ~ChildStack();
- void setParent(LLPanel* parent);
-
- bool push();
- bool pop();
- void preParentReshape();
- void postParentReshape();
-
- private:
- void dump();
-
- typedef LLView::child_list_t view_list_t;
- typedef std::list<view_list_t> stack_t;
-
- stack_t mStack;
- stack_t mSavedStack;
- LLPanel* mParent;
- };
- //-- ChildStack ends ------------------------------------------------------
-
- profile_tabs_t mTabContainer;
- ChildStack mChildStack;
- LLUUID mAvatarId;
+ // Todo: due to server taking minutes to update this needs a more long term storage
+ // to reuse recently saved values if user opens floater again
+ // Storage implementation depends onto how a cap will be implemented, if cap will be
+ // enought to fully update LLAvatarPropertiesProcessor, then this storage can be
+ // implemented there.
+ LLAvatarData mAvatarData;
};
#endif //LL_LLPANELPROFILE_H
diff --git a/indra/newview/llpanelprofileclassifieds.cpp b/indra/newview/llpanelprofileclassifieds.cpp
new file mode 100644
index 0000000000..a3913ddc49
--- /dev/null
+++ b/indra/newview/llpanelprofileclassifieds.cpp
@@ -0,0 +1,1513 @@
+/**
+ * @file llpanelprofileclassifieds.cpp
+ * @brief LLPanelProfileClassifieds and related class implementations
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, 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 "llpanelprofileclassifieds.h"
+
+#include "llagent.h"
+#include "llavataractions.h"
+#include "llavatarpropertiesprocessor.h"
+#include "llclassifiedflags.h"
+#include "llcombobox.h"
+#include "llcommandhandler.h" // for classified HTML detail page click tracking
+#include "llcorehttputil.h"
+#include "lldispatcher.h"
+#include "llfloaterclassified.h"
+#include "llfloaterreg.h"
+#include "llfloatersidepanelcontainer.h"
+#include "llfloaterworldmap.h"
+#include "lliconctrl.h"
+#include "lllineeditor.h"
+#include "llnotifications.h"
+#include "llnotificationsutil.h"
+#include "llpanelavatar.h"
+#include "llparcel.h"
+#include "llregistry.h"
+#include "llscrollcontainer.h"
+#include "llstartup.h"
+#include "llstatusbar.h"
+#include "lltabcontainer.h"
+#include "lltexteditor.h"
+#include "lltexturectrl.h"
+#include "lltrans.h"
+#include "llviewergenericmessage.h" // send_generic_message
+#include "llviewerparcelmgr.h"
+#include "llviewerregion.h"
+#include "llviewertexture.h"
+#include "llviewertexture.h"
+
+
+//*TODO: verify this limit
+const S32 MAX_AVATAR_CLASSIFIEDS = 100;
+
+const S32 MINIMUM_PRICE_FOR_LISTING = 50; // L$
+const S32 DEFAULT_EDIT_CLASSIFIED_SCROLL_HEIGHT = 530;
+
+//static
+LLPanelProfileClassified::panel_list_t LLPanelProfileClassified::sAllPanels;
+
+static LLPanelInjector<LLPanelProfileClassifieds> t_panel_profile_classifieds("panel_profile_classifieds");
+static LLPanelInjector<LLPanelProfileClassified> t_panel_profile_classified("panel_profile_classified");
+
+class LLClassifiedHandler : public LLCommandHandler, public LLAvatarPropertiesObserver
+{
+public:
+ // throttle calls from untrusted browsers
+ LLClassifiedHandler() : LLCommandHandler("classified", UNTRUSTED_THROTTLE) {}
+
+ std::set<LLUUID> mClassifiedIds;
+ std::string mRequestVerb;
+
+ bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web)
+ {
+ if (LLStartUp::getStartupState() < STATE_STARTED)
+ {
+ return true;
+ }
+
+ if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnableClassifieds"))
+ {
+ LLNotificationsUtil::add("NoClassifieds", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit"));
+ return true;
+ }
+
+ // handle app/classified/create urls first
+ if (params.size() == 1 && params[0].asString() == "create")
+ {
+ LLAvatarActions::createClassified();
+ return true;
+ }
+
+ // then handle the general app/classified/{UUID}/{CMD} urls
+ if (params.size() < 2)
+ {
+ return false;
+ }
+
+ // get the ID for the classified
+ LLUUID classified_id;
+ if (!classified_id.set(params[0], FALSE))
+ {
+ return false;
+ }
+
+ // show the classified in the side tray.
+ // need to ask the server for more info first though...
+ const std::string verb = params[1].asString();
+ if (verb == "about")
+ {
+ mRequestVerb = verb;
+ mClassifiedIds.insert(classified_id);
+ LLAvatarPropertiesProcessor::getInstance()->addObserver(LLUUID(), this);
+ LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoRequest(classified_id);
+ return true;
+ }
+ else if (verb == "edit")
+ {
+ LLAvatarActions::showClassified(gAgent.getID(), classified_id, true);
+ return true;
+ }
+
+ return false;
+ }
+
+ void openClassified(LLAvatarClassifiedInfo* c_info)
+ {
+ if (mRequestVerb == "about")
+ {
+ if (c_info->creator_id == gAgent.getID())
+ {
+ LLAvatarActions::showClassified(gAgent.getID(), c_info->classified_id, false);
+ }
+ else
+ {
+ LLSD params;
+ params["id"] = c_info->creator_id;
+ params["classified_id"] = c_info->classified_id;
+ params["classified_creator_id"] = c_info->creator_id;
+ params["classified_snapshot_id"] = c_info->snapshot_id;
+ params["classified_name"] = c_info->name;
+ params["classified_desc"] = c_info->description;
+ params["from_search"] = true;
+
+ LLFloaterClassified* floaterp = LLFloaterReg::getTypedInstance<LLFloaterClassified>("classified", params);
+ if (floaterp)
+ {
+ floaterp->openFloater(params);
+ floaterp->setVisibleAndFrontmost();
+ }
+ }
+ }
+ }
+
+ void processProperties(void* data, EAvatarProcessorType type)
+ {
+ if (APT_CLASSIFIED_INFO != type)
+ {
+ return;
+ }
+
+ // is this the classified that we asked for?
+ LLAvatarClassifiedInfo* c_info = static_cast<LLAvatarClassifiedInfo*>(data);
+ if (!c_info || mClassifiedIds.find(c_info->classified_id) == mClassifiedIds.end())
+ {
+ return;
+ }
+
+ // open the detail side tray for this classified
+ openClassified(c_info);
+
+ // remove our observer now that we're done
+ mClassifiedIds.erase(c_info->classified_id);
+ LLAvatarPropertiesProcessor::getInstance()->removeObserver(LLUUID(), this);
+ }
+};
+LLClassifiedHandler gClassifiedHandler;
+
+//////////////////////////////////////////////////////////////////////////
+
+
+//-----------------------------------------------------------------------------
+// LLPanelProfileClassifieds
+//-----------------------------------------------------------------------------
+
+LLPanelProfileClassifieds::LLPanelProfileClassifieds()
+ : LLPanelProfilePropertiesProcessorTab()
+ , mClassifiedToSelectOnLoad(LLUUID::null)
+ , mClassifiedEditOnLoad(false)
+ , mSheduledClassifiedCreation(false)
+{
+}
+
+LLPanelProfileClassifieds::~LLPanelProfileClassifieds()
+{
+}
+
+void LLPanelProfileClassifieds::onOpen(const LLSD& key)
+{
+ LLPanelProfilePropertiesProcessorTab::onOpen(key);
+
+ resetData();
+
+ bool own_profile = getSelfProfile();
+ if (own_profile)
+ {
+ mNewButton->setVisible(TRUE);
+ mNewButton->setEnabled(FALSE);
+
+ mDeleteButton->setVisible(TRUE);
+ mDeleteButton->setEnabled(FALSE);
+ }
+
+ childSetVisible("buttons_header", own_profile);
+
+}
+
+void LLPanelProfileClassifieds::selectClassified(const LLUUID& classified_id, bool edit)
+{
+ if (getIsLoaded())
+ {
+ for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx)
+ {
+ LLPanelProfileClassified* classified_panel = dynamic_cast<LLPanelProfileClassified*>(mTabContainer->getPanelByIndex(tab_idx));
+ if (classified_panel)
+ {
+ if (classified_panel->getClassifiedId() == classified_id)
+ {
+ mTabContainer->selectTabPanel(classified_panel);
+ if (edit)
+ {
+ classified_panel->setEditMode(TRUE);
+ }
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ mClassifiedToSelectOnLoad = classified_id;
+ mClassifiedEditOnLoad = edit;
+ }
+}
+
+void LLPanelProfileClassifieds::createClassified()
+{
+ if (getIsLoaded())
+ {
+ mNoItemsLabel->setVisible(FALSE);
+ LLPanelProfileClassified* classified_panel = LLPanelProfileClassified::create();
+ classified_panel->onOpen(LLSD());
+ mTabContainer->addTabPanel(
+ LLTabContainer::TabPanelParams().
+ panel(classified_panel).
+ select_tab(true).
+ label(classified_panel->getClassifiedName()));
+ updateButtons();
+ }
+ else
+ {
+ mSheduledClassifiedCreation = true;
+ }
+}
+
+BOOL LLPanelProfileClassifieds::postBuild()
+{
+ mTabContainer = getChild<LLTabContainer>("tab_classifieds");
+ mNoItemsLabel = getChild<LLUICtrl>("classifieds_panel_text");
+ mNewButton = getChild<LLButton>("new_btn");
+ mDeleteButton = getChild<LLButton>("delete_btn");
+
+ mNewButton->setCommitCallback(boost::bind(&LLPanelProfileClassifieds::onClickNewBtn, this));
+ mDeleteButton->setCommitCallback(boost::bind(&LLPanelProfileClassifieds::onClickDelete, this));
+
+ return TRUE;
+}
+
+void LLPanelProfileClassifieds::onClickNewBtn()
+{
+ mNoItemsLabel->setVisible(FALSE);
+ LLPanelProfileClassified* classified_panel = LLPanelProfileClassified::create();
+ classified_panel->onOpen(LLSD());
+ mTabContainer->addTabPanel(
+ LLTabContainer::TabPanelParams().
+ panel(classified_panel).
+ select_tab(true).
+ label(classified_panel->getClassifiedName()));
+ updateButtons();
+}
+
+void LLPanelProfileClassifieds::onClickDelete()
+{
+ LLPanelProfileClassified* classified_panel = dynamic_cast<LLPanelProfileClassified*>(mTabContainer->getCurrentPanel());
+ if (classified_panel)
+ {
+ LLUUID classified_id = classified_panel->getClassifiedId();
+ LLSD args;
+ args["CLASSIFIED"] = classified_panel->getClassifiedName();
+ LLSD payload;
+ payload["classified_id"] = classified_id;
+ payload["tab_idx"] = mTabContainer->getCurrentPanelIndex();
+ LLNotificationsUtil::add("ProfileDeleteClassified", args, payload,
+ boost::bind(&LLPanelProfileClassifieds::callbackDeleteClassified, this, _1, _2));
+ }
+}
+
+void LLPanelProfileClassifieds::callbackDeleteClassified(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+
+ if (0 == option)
+ {
+ LLUUID classified_id = notification["payload"]["classified_id"].asUUID();
+ S32 tab_idx = notification["payload"]["tab_idx"].asInteger();
+
+ LLPanelProfileClassified* classified_panel = dynamic_cast<LLPanelProfileClassified*>(mTabContainer->getPanelByIndex(tab_idx));
+ if (classified_panel && classified_panel->getClassifiedId() == classified_id)
+ {
+ mTabContainer->removeTabPanel(classified_panel);
+ }
+
+ if (classified_id.notNull())
+ {
+ LLAvatarPropertiesProcessor::getInstance()->sendClassifiedDelete(classified_id);
+ }
+
+ updateButtons();
+
+ BOOL no_data = !mTabContainer->getTabCount();
+ mNoItemsLabel->setVisible(no_data);
+ }
+}
+
+void LLPanelProfileClassifieds::processProperties(void* data, EAvatarProcessorType type)
+{
+ if ((APT_CLASSIFIEDS == type) || (APT_CLASSIFIED_INFO == type))
+ {
+ LLUUID avatar_id = getAvatarId();
+
+ LLAvatarClassifieds* c_info = static_cast<LLAvatarClassifieds*>(data);
+ if (c_info && getAvatarId() == c_info->target_id)
+ {
+ // do not clear classified list in case we will receive two or more data packets.
+ // list has been cleared in updateData(). (fix for EXT-6436)
+ LLUUID selected_id = mClassifiedToSelectOnLoad;
+ bool has_selection = false;
+
+ LLAvatarClassifieds::classifieds_list_t::const_iterator it = c_info->classifieds_list.begin();
+ for (; c_info->classifieds_list.end() != it; ++it)
+ {
+ LLAvatarClassifieds::classified_data c_data = *it;
+
+ LLPanelProfileClassified* classified_panel = LLPanelProfileClassified::create();
+
+ LLSD params;
+ params["classified_creator_id"] = avatar_id;
+ params["classified_id"] = c_data.classified_id;
+ params["classified_name"] = c_data.name;
+ params["from_search"] = (selected_id == c_data.classified_id); //SLURL handling and stats tracking
+ params["edit"] = (selected_id == c_data.classified_id) && mClassifiedEditOnLoad;
+ classified_panel->onOpen(params);
+
+ mTabContainer->addTabPanel(
+ LLTabContainer::TabPanelParams().
+ panel(classified_panel).
+ select_tab(selected_id == c_data.classified_id).
+ label(c_data.name));
+
+ if (selected_id == c_data.classified_id)
+ {
+ has_selection = true;
+ }
+ }
+
+ if (mSheduledClassifiedCreation)
+ {
+ LLPanelProfileClassified* classified_panel = LLPanelProfileClassified::create();
+ classified_panel->onOpen(LLSD());
+ mTabContainer->addTabPanel(
+ LLTabContainer::TabPanelParams().
+ panel(classified_panel).
+ select_tab(!has_selection).
+ label(classified_panel->getClassifiedName()));
+ has_selection = true;
+ }
+
+ // reset 'do on load' values
+ mClassifiedToSelectOnLoad = LLUUID::null;
+ mClassifiedEditOnLoad = false;
+ mSheduledClassifiedCreation = false;
+
+ // set even if not visible, user might delete own
+ // calassified and this string will need to be shown
+ if (getSelfProfile())
+ {
+ mNoItemsLabel->setValue(LLTrans::getString("NoClassifiedsText"));
+ }
+ else
+ {
+ mNoItemsLabel->setValue(LLTrans::getString("NoAvatarClassifiedsText"));
+ }
+
+ bool has_data = mTabContainer->getTabCount() > 0;
+ mNoItemsLabel->setVisible(!has_data);
+ if (has_data && !has_selection)
+ {
+ mTabContainer->selectFirstTab();
+ }
+
+ setLoaded();
+ updateButtons();
+ }
+ }
+}
+
+void LLPanelProfileClassifieds::resetData()
+{
+ resetLoading();
+ mTabContainer->deleteAllTabs();
+}
+
+void LLPanelProfileClassifieds::updateButtons()
+{
+ if (getSelfProfile())
+ {
+ mNewButton->setEnabled(canAddNewClassified());
+ mDeleteButton->setEnabled(canDeleteClassified());
+ }
+}
+
+void LLPanelProfileClassifieds::updateData()
+{
+ // Send picks request only once
+ LLUUID avatar_id = getAvatarId();
+ if (!getStarted() && avatar_id.notNull())
+ {
+ setIsLoading();
+ mNoItemsLabel->setValue(LLTrans::getString("PicksClassifiedsLoadingText"));
+ mNoItemsLabel->setVisible(TRUE);
+
+ LLAvatarPropertiesProcessor::getInstance()->sendAvatarClassifiedsRequest(avatar_id);
+ }
+}
+
+bool LLPanelProfileClassifieds::hasNewClassifieds()
+{
+ for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx)
+ {
+ LLPanelProfileClassified* classified_panel = dynamic_cast<LLPanelProfileClassified*>(mTabContainer->getPanelByIndex(tab_idx));
+ if (classified_panel && classified_panel->isNew())
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool LLPanelProfileClassifieds::hasUnsavedChanges()
+{
+ for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx)
+ {
+ LLPanelProfileClassified* classified_panel = dynamic_cast<LLPanelProfileClassified*>(mTabContainer->getPanelByIndex(tab_idx));
+ if (classified_panel && classified_panel->isDirty()) // includes 'new'
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool LLPanelProfileClassifieds::canAddNewClassified()
+{
+ return (mTabContainer->getTabCount() < MAX_AVATAR_CLASSIFIEDS);
+}
+
+bool LLPanelProfileClassifieds::canDeleteClassified()
+{
+ return (mTabContainer->getTabCount() > 0);
+}
+
+void LLPanelProfileClassifieds::commitUnsavedChanges()
+{
+ if (getIsLoaded())
+ {
+ for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx)
+ {
+ LLPanelProfileClassified* classified_panel = dynamic_cast<LLPanelProfileClassified*>(mTabContainer->getPanelByIndex(tab_idx));
+ if (classified_panel && classified_panel->isDirty() && !classified_panel->isNew())
+ {
+ classified_panel->doSave();
+ }
+ }
+ }
+}
+//-----------------------------------------------------------------------------
+// LLDispatchClassifiedClickThrough
+//-----------------------------------------------------------------------------
+
+// "classifiedclickthrough"
+// strings[0] = classified_id
+// strings[1] = teleport_clicks
+// strings[2] = map_clicks
+// strings[3] = profile_clicks
+class LLDispatchClassifiedClickThrough : public LLDispatchHandler
+{
+public:
+ virtual bool operator()(
+ const LLDispatcher* dispatcher,
+ const std::string& key,
+ const LLUUID& invoice,
+ const sparam_t& strings)
+ {
+ if (strings.size() != 4) return false;
+ LLUUID classified_id(strings[0]);
+ S32 teleport_clicks = atoi(strings[1].c_str());
+ S32 map_clicks = atoi(strings[2].c_str());
+ S32 profile_clicks = atoi(strings[3].c_str());
+
+ LLPanelProfileClassified::setClickThrough(
+ classified_id, teleport_clicks, map_clicks, profile_clicks, false);
+
+ return true;
+ }
+};
+static LLDispatchClassifiedClickThrough sClassifiedClickThrough;
+
+
+//-----------------------------------------------------------------------------
+// LLPanelProfileClassified
+//-----------------------------------------------------------------------------
+
+static const S32 CB_ITEM_MATURE = 0;
+static const S32 CB_ITEM_PG = 1;
+
+LLPanelProfileClassified::LLPanelProfileClassified()
+ : LLPanelProfilePropertiesProcessorTab()
+ , mInfoLoaded(false)
+ , mTeleportClicksOld(0)
+ , mMapClicksOld(0)
+ , mProfileClicksOld(0)
+ , mTeleportClicksNew(0)
+ , mMapClicksNew(0)
+ , mProfileClicksNew(0)
+ , mPriceForListing(0)
+ , mSnapshotCtrl(NULL)
+ , mPublishFloater(NULL)
+ , mIsNew(false)
+ , mIsNewWithErrors(false)
+ , mCanClose(false)
+ , mEditMode(false)
+ , mEditOnLoad(false)
+{
+ sAllPanels.push_back(this);
+}
+
+LLPanelProfileClassified::~LLPanelProfileClassified()
+{
+ sAllPanels.remove(this);
+ gGenericDispatcher.addHandler("classifiedclickthrough", NULL); // deregister our handler
+}
+
+//static
+LLPanelProfileClassified* LLPanelProfileClassified::create()
+{
+ LLPanelProfileClassified* panel = new LLPanelProfileClassified();
+ panel->buildFromFile("panel_profile_classified.xml");
+ return panel;
+}
+
+BOOL LLPanelProfileClassified::postBuild()
+{
+ mScrollContainer = getChild<LLScrollContainer>("profile_scroll");
+ mInfoPanel = getChild<LLView>("info_panel");
+ mInfoScroll = getChild<LLPanel>("info_scroll_content_panel");
+ mEditPanel = getChild<LLPanel>("edit_panel");
+
+ mSnapshotCtrl = getChild<LLTextureCtrl>("classified_snapshot");
+ mEditIcon = getChild<LLUICtrl>("edit_icon");
+
+ //info
+ mClassifiedNameText = getChild<LLUICtrl>("classified_name");
+ mClassifiedDescText = getChild<LLTextEditor>("classified_desc");
+ mLocationText = getChild<LLUICtrl>("classified_location");
+ mCategoryText = getChild<LLUICtrl>("category");
+ mContentTypeText = getChild<LLUICtrl>("content_type");
+ mContentTypeM = getChild<LLIconCtrl>("content_type_moderate");
+ mContentTypeG = getChild<LLIconCtrl>("content_type_general");
+ mPriceText = getChild<LLUICtrl>("price_for_listing");
+ mAutoRenewText = getChild<LLUICtrl>("auto_renew");
+
+ mMapButton = getChild<LLButton>("show_on_map_btn");
+ mTeleportButton = getChild<LLButton>("teleport_btn");
+ mEditButton = getChild<LLButton>("edit_btn");
+
+ //edit
+ mClassifiedNameEdit = getChild<LLLineEditor>("classified_name_edit");
+ mClassifiedDescEdit = getChild<LLTextEditor>("classified_desc_edit");
+ mLocationEdit = getChild<LLUICtrl>("classified_location_edit");
+ mCategoryCombo = getChild<LLComboBox>("category_edit");
+ mContentTypeCombo = getChild<LLComboBox>("content_type_edit");
+ mAutoRenewEdit = getChild<LLUICtrl>("auto_renew_edit");
+
+ mSaveButton = getChild<LLButton>("save_changes_btn");
+ mSetLocationButton = getChild<LLButton>("set_to_curr_location_btn");
+ mCancelButton = getChild<LLButton>("cancel_btn");
+
+ mUtilityBtnCnt = getChild<LLPanel>("util_buttons_lp");
+ mPublishBtnsCnt = getChild<LLPanel>("publish_layout_panel");
+ mCancelBtnCnt = getChild<LLPanel>("cancel_btn_lp");
+ mSaveBtnCnt = getChild<LLPanel>("save_btn_lp");
+
+ mSnapshotCtrl->setOnSelectCallback(boost::bind(&LLPanelProfileClassified::onTextureSelected, this));
+ mSnapshotCtrl->setMouseEnterCallback(boost::bind(&LLPanelProfileClassified::onTexturePickerMouseEnter, this));
+ mSnapshotCtrl->setMouseLeaveCallback(boost::bind(&LLPanelProfileClassified::onTexturePickerMouseLeave, this));
+ mEditIcon->setVisible(false);
+
+ mMapButton->setCommitCallback(boost::bind(&LLPanelProfileClassified::onMapClick, this));
+ mTeleportButton->setCommitCallback(boost::bind(&LLPanelProfileClassified::onTeleportClick, this));
+ mEditButton->setCommitCallback(boost::bind(&LLPanelProfileClassified::onEditClick, this));
+ mSaveButton->setCommitCallback(boost::bind(&LLPanelProfileClassified::onSaveClick, this));
+ mSetLocationButton->setCommitCallback(boost::bind(&LLPanelProfileClassified::onSetLocationClick, this));
+ mCancelButton->setCommitCallback(boost::bind(&LLPanelProfileClassified::onCancelClick, this));
+
+ LLClassifiedInfo::cat_map::iterator iter;
+ for (iter = LLClassifiedInfo::sCategories.begin();
+ iter != LLClassifiedInfo::sCategories.end();
+ iter++)
+ {
+ mCategoryCombo->add(LLTrans::getString(iter->second));
+ }
+
+ mClassifiedNameEdit->setKeystrokeCallback(boost::bind(&LLPanelProfileClassified::onChange, this), NULL);
+ mClassifiedDescEdit->setKeystrokeCallback(boost::bind(&LLPanelProfileClassified::onChange, this));
+ mCategoryCombo->setCommitCallback(boost::bind(&LLPanelProfileClassified::onChange, this));
+ mContentTypeCombo->setCommitCallback(boost::bind(&LLPanelProfileClassified::onChange, this));
+ mAutoRenewEdit->setCommitCallback(boost::bind(&LLPanelProfileClassified::onChange, this));
+
+ return TRUE;
+}
+
+void LLPanelProfileClassified::onOpen(const LLSD& key)
+{
+ mIsNew = key.isUndefined();
+
+ resetData();
+ resetControls();
+ scrollToTop();
+
+ // classified is not created yet
+ bool is_new = isNew() || isNewWithErrors();
+
+ if(is_new)
+ {
+ LLPanelProfilePropertiesProcessorTab::setAvatarId(gAgent.getID());
+
+ setPosGlobal(gAgent.getPositionGlobal());
+
+ LLUUID snapshot_id = LLUUID::null;
+ std::string desc;
+ LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+ if(parcel)
+ {
+ desc = parcel->getDesc();
+ snapshot_id = parcel->getSnapshotID();
+ }
+
+ std::string region_name = LLTrans::getString("ClassifiedUpdateAfterPublish");
+ LLViewerRegion* region = gAgent.getRegion();
+ if (region)
+ {
+ region_name = region->getName();
+ }
+
+ setClassifiedName(makeClassifiedName());
+ setDescription(desc);
+ setSnapshotId(snapshot_id);
+ setClassifiedLocation(createLocationText(getLocationNotice(), region_name, getPosGlobal()));
+ // server will set valid parcel id
+ setParcelId(LLUUID::null);
+
+ mSaveButton->setLabelArg("[LABEL]", getString("publish_label"));
+
+ setEditMode(TRUE);
+ enableSave(true);
+ enableEditing(true);
+ resetDirty();
+ setInfoLoaded(false);
+ }
+ else
+ {
+ LLUUID avatar_id = key["classified_creator_id"];
+ if(avatar_id.isNull())
+ {
+ return;
+ }
+ LLPanelProfilePropertiesProcessorTab::setAvatarId(avatar_id);
+
+ setClassifiedId(key["classified_id"]);
+ setClassifiedName(key["classified_name"]);
+ setFromSearch(key["from_search"]);
+ mEditOnLoad = key["edit"];
+
+ LL_INFOS() << "Opening classified [" << getClassifiedName() << "] (" << getClassifiedId() << ")" << LL_ENDL;
+
+ LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoRequest(getClassifiedId());
+
+ gGenericDispatcher.addHandler("classifiedclickthrough", &sClassifiedClickThrough);
+
+ if (gAgent.getRegion())
+ {
+ // While we're at it let's get the stats from the new table if that
+ // capability exists.
+ std::string url = gAgent.getRegion()->getCapability("SearchStatRequest");
+ if (!url.empty())
+ {
+ LL_INFOS() << "Classified stat request via capability" << LL_ENDL;
+ LLSD body;
+ LLUUID classifiedId = getClassifiedId();
+ body["classified_id"] = classifiedId;
+ LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpPost(url, body,
+ boost::bind(&LLPanelProfileClassified::handleSearchStatResponse, classifiedId, _1));
+ }
+ }
+ // Update classified click stats.
+ // *TODO: Should we do this when opening not from search?
+ if (!fromSearch() )
+ {
+ sendClickMessage("profile");
+ }
+
+ setInfoLoaded(false);
+ }
+
+
+ bool is_self = getSelfProfile();
+ getChildView("auto_renew_layout_panel")->setVisible(is_self);
+ getChildView("clickthrough_layout_panel")->setVisible(is_self);
+
+ updateButtons();
+}
+
+void LLPanelProfileClassified::processProperties(void* data, EAvatarProcessorType type)
+{
+ if (APT_CLASSIFIED_INFO != type)
+ {
+ return;
+ }
+
+ LLAvatarClassifiedInfo* c_info = static_cast<LLAvatarClassifiedInfo*>(data);
+ if(c_info && getClassifiedId() == c_info->classified_id)
+ {
+ // see LLPanelProfileClassified::sendUpdate() for notes
+ if (mIsNewWithErrors)
+ {
+ // We just published it
+ setEditMode(FALSE);
+ }
+ mIsNewWithErrors = false;
+ mIsNew = false;
+
+ setClassifiedName(c_info->name);
+ setDescription(c_info->description);
+ setSnapshotId(c_info->snapshot_id);
+ setParcelId(c_info->parcel_id);
+ setPosGlobal(c_info->pos_global);
+ setSimName(c_info->sim_name);
+
+ setClassifiedLocation(createLocationText(c_info->parcel_name, c_info->sim_name, c_info->pos_global));
+
+ mCategoryText->setValue(LLClassifiedInfo::sCategories[c_info->category]);
+ // *HACK see LLPanelProfileClassified::sendUpdate()
+ setCategory(c_info->category - 1);
+
+ bool mature = is_cf_mature(c_info->flags);
+ setContentType(mature);
+
+ bool auto_renew = is_cf_auto_renew(c_info->flags);
+ std::string auto_renew_str = auto_renew ? getString("auto_renew_on") : getString("auto_renew_off");
+ mAutoRenewText->setValue(auto_renew_str);
+ mAutoRenewEdit->setValue(auto_renew);
+
+ static LLUIString price_str = getString("l$_price");
+ price_str.setArg("[PRICE]", llformat("%d", c_info->price_for_listing));
+ mPriceText->setValue(LLSD(price_str));
+
+ static std::string date_fmt = getString("date_fmt");
+ std::string date_str = date_fmt;
+ LLStringUtil::format(date_str, LLSD().with("datetime", (S32) c_info->creation_date));
+ getChild<LLUICtrl>("creation_date")->setValue(date_str);
+
+ resetDirty();
+ setInfoLoaded(true);
+ enableSave(false);
+ enableEditing(true);
+
+ // for just created classified - in case user opened edit panel before processProperties() callback
+ mSaveButton->setLabelArg("[LABEL]", getString("save_label"));
+
+ setLoaded();
+ updateButtons();
+
+ if (mEditOnLoad)
+ {
+ setEditMode(TRUE);
+ }
+ }
+
+}
+
+void LLPanelProfileClassified::setEditMode(BOOL edit_mode)
+{
+ mEditMode = edit_mode;
+
+ mInfoPanel->setVisible(!edit_mode);
+ mEditPanel->setVisible(edit_mode);
+
+ // snapshot control is common between info and edit,
+ // enable it only when in edit mode
+ mSnapshotCtrl->setEnabled(edit_mode);
+
+ scrollToTop();
+ updateButtons();
+ updateInfoRect();
+}
+
+void LLPanelProfileClassified::updateButtons()
+{
+ bool edit_mode = getEditMode();
+ mUtilityBtnCnt->setVisible(!edit_mode);
+
+ // cancel button should either delete unpublished
+ // classified or not be there at all
+ mCancelBtnCnt->setVisible(edit_mode && !mIsNew);
+ mPublishBtnsCnt->setVisible(edit_mode);
+ mSaveBtnCnt->setVisible(edit_mode);
+ mEditButton->setVisible(!edit_mode && getSelfProfile());
+}
+
+void LLPanelProfileClassified::updateInfoRect()
+{
+ if (getEditMode())
+ {
+ // info_scroll_content_panel contains both info and edit panel
+ // info panel can be very large and scroll bar will carry over.
+ // Resize info panel to prevent scroll carry over when in edit mode.
+ mInfoScroll->reshape(mInfoScroll->getRect().getWidth(), DEFAULT_EDIT_CLASSIFIED_SCROLL_HEIGHT, FALSE);
+ }
+ else
+ {
+ // Adjust text height to make description scrollable.
+ S32 new_height = mClassifiedDescText->getTextBoundingRect().getHeight();
+ LLRect visible_rect = mClassifiedDescText->getVisibleDocumentRect();
+ S32 delta_height = new_height - visible_rect.getHeight() + 5;
+
+ LLRect rect = mInfoScroll->getRect();
+ mInfoScroll->reshape(rect.getWidth(), rect.getHeight() + delta_height, FALSE);
+ }
+}
+
+void LLPanelProfileClassified::enableEditing(bool enable)
+{
+ mEditButton->setEnabled(enable);
+ mClassifiedNameEdit->setEnabled(enable);
+ mClassifiedDescEdit->setEnabled(enable);
+ mSetLocationButton->setEnabled(enable);
+ mCategoryCombo->setEnabled(enable);
+ mContentTypeCombo->setEnabled(enable);
+ mAutoRenewEdit->setEnabled(enable);
+}
+
+void LLPanelProfileClassified::resetControls()
+{
+ updateButtons();
+
+ mCategoryCombo->setCurrentByIndex(0);
+ mContentTypeCombo->setCurrentByIndex(0);
+ mAutoRenewEdit->setValue(false);
+ mPriceForListing = MINIMUM_PRICE_FOR_LISTING;
+}
+
+void LLPanelProfileClassified::onEditClick()
+{
+ setEditMode(TRUE);
+}
+
+void LLPanelProfileClassified::onCancelClick()
+{
+ if (isNew())
+ {
+ mClassifiedNameEdit->setValue(mClassifiedNameText->getValue());
+ mClassifiedDescEdit->setValue(mClassifiedDescText->getValue());
+ mLocationEdit->setValue(mLocationText->getValue());
+ mCategoryCombo->setCurrentByIndex(0);
+ mContentTypeCombo->setCurrentByIndex(0);
+ mAutoRenewEdit->setValue(false);
+ mPriceForListing = MINIMUM_PRICE_FOR_LISTING;
+ }
+ else
+ {
+ // Reload data to undo changes to forms
+ LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoRequest(getClassifiedId());
+ }
+
+ setInfoLoaded(false);
+
+ setEditMode(FALSE);
+}
+
+void LLPanelProfileClassified::onSaveClick()
+{
+ mCanClose = false;
+
+ if(!isValidName())
+ {
+ notifyInvalidName();
+ return;
+ }
+ if(isNew() || isNewWithErrors())
+ {
+ if(gStatusBar->getBalance() < getPriceForListing())
+ {
+ LLNotificationsUtil::add("ClassifiedInsufficientFunds");
+ return;
+ }
+
+ mPublishFloater = LLFloaterReg::findTypedInstance<LLPublishClassifiedFloater>(
+ "publish_classified", LLSD());
+
+ if(!mPublishFloater)
+ {
+ mPublishFloater = LLFloaterReg::getTypedInstance<LLPublishClassifiedFloater>(
+ "publish_classified", LLSD());
+
+ mPublishFloater->setPublishClickedCallback(boost::bind
+ (&LLPanelProfileClassified::onPublishFloaterPublishClicked, this));
+ }
+
+ // set spinner value before it has focus or value wont be set
+ mPublishFloater->setPrice(getPriceForListing());
+ mPublishFloater->openFloater(mPublishFloater->getKey());
+ mPublishFloater->center();
+ }
+ else
+ {
+ doSave();
+ }
+}
+
+/*static*/
+void LLPanelProfileClassified::handleSearchStatResponse(LLUUID classifiedId, LLSD result)
+{
+ S32 teleport = result["teleport_clicks"].asInteger();
+ S32 map = result["map_clicks"].asInteger();
+ S32 profile = result["profile_clicks"].asInteger();
+ S32 search_teleport = result["search_teleport_clicks"].asInteger();
+ S32 search_map = result["search_map_clicks"].asInteger();
+ S32 search_profile = result["search_profile_clicks"].asInteger();
+
+ LLPanelProfileClassified::setClickThrough(classifiedId,
+ teleport + search_teleport,
+ map + search_map,
+ profile + search_profile,
+ true);
+}
+
+void LLPanelProfileClassified::resetData()
+{
+ setClassifiedName(LLStringUtil::null);
+ setDescription(LLStringUtil::null);
+ setClassifiedLocation(LLStringUtil::null);
+ setClassifiedId(LLUUID::null);
+ setSnapshotId(LLUUID::null);
+ setPosGlobal(LLVector3d::zero);
+ setParcelId(LLUUID::null);
+ setSimName(LLStringUtil::null);
+ setFromSearch(false);
+
+ // reset click stats
+ mTeleportClicksOld = 0;
+ mMapClicksOld = 0;
+ mProfileClicksOld = 0;
+ mTeleportClicksNew = 0;
+ mMapClicksNew = 0;
+ mProfileClicksNew = 0;
+
+ mPriceForListing = MINIMUM_PRICE_FOR_LISTING;
+
+ mCategoryText->setValue(LLStringUtil::null);
+ mContentTypeText->setValue(LLStringUtil::null);
+ getChild<LLUICtrl>("click_through_text")->setValue(LLStringUtil::null);
+ mEditButton->setValue(LLStringUtil::null);
+ getChild<LLUICtrl>("creation_date")->setValue(LLStringUtil::null);
+ mContentTypeM->setVisible(FALSE);
+ mContentTypeG->setVisible(FALSE);
+}
+
+void LLPanelProfileClassified::setClassifiedName(const std::string& name)
+{
+ mClassifiedNameText->setValue(name);
+ mClassifiedNameEdit->setValue(name);
+}
+
+std::string LLPanelProfileClassified::getClassifiedName()
+{
+ return mClassifiedNameEdit->getValue().asString();
+}
+
+void LLPanelProfileClassified::setDescription(const std::string& desc)
+{
+ mClassifiedDescText->setValue(desc);
+ mClassifiedDescEdit->setValue(desc);
+
+ updateInfoRect();
+}
+
+std::string LLPanelProfileClassified::getDescription()
+{
+ return mClassifiedDescEdit->getValue().asString();
+}
+
+void LLPanelProfileClassified::setClassifiedLocation(const std::string& location)
+{
+ mLocationText->setValue(location);
+ mLocationEdit->setValue(location);
+}
+
+std::string LLPanelProfileClassified::getClassifiedLocation()
+{
+ return mLocationText->getValue().asString();
+}
+
+void LLPanelProfileClassified::setSnapshotId(const LLUUID& id)
+{
+ mSnapshotCtrl->setValue(id);
+}
+
+LLUUID LLPanelProfileClassified::getSnapshotId()
+{
+ return mSnapshotCtrl->getValue().asUUID();
+}
+
+// static
+void LLPanelProfileClassified::setClickThrough(
+ const LLUUID& classified_id,
+ S32 teleport,
+ S32 map,
+ S32 profile,
+ bool from_new_table)
+{
+ LL_INFOS() << "Click-through data for classified " << classified_id << " arrived: ["
+ << teleport << ", " << map << ", " << profile << "] ("
+ << (from_new_table ? "new" : "old") << ")" << LL_ENDL;
+
+ for (panel_list_t::iterator iter = sAllPanels.begin(); iter != sAllPanels.end(); ++iter)
+ {
+ LLPanelProfileClassified* self = *iter;
+ if (self->getClassifiedId() != classified_id)
+ {
+ continue;
+ }
+
+ // *HACK: Skip LLPanelProfileClassified instances: they don't display clicks data.
+ // Those instances should not be in the list at all.
+ if (typeid(*self) != typeid(LLPanelProfileClassified))
+ {
+ continue;
+ }
+
+ LL_INFOS() << "Updating classified info panel" << LL_ENDL;
+
+ // We need to check to see if the data came from the new stat_table
+ // or the old classified table. We also need to cache the data from
+ // the two separate sources so as to display the aggregate totals.
+
+ if (from_new_table)
+ {
+ self->mTeleportClicksNew = teleport;
+ self->mMapClicksNew = map;
+ self->mProfileClicksNew = profile;
+ }
+ else
+ {
+ self->mTeleportClicksOld = teleport;
+ self->mMapClicksOld = map;
+ self->mProfileClicksOld = profile;
+ }
+
+ static LLUIString ct_str = self->getString("click_through_text_fmt");
+
+ ct_str.setArg("[TELEPORT]", llformat("%d", self->mTeleportClicksNew + self->mTeleportClicksOld));
+ ct_str.setArg("[MAP]", llformat("%d", self->mMapClicksNew + self->mMapClicksOld));
+ ct_str.setArg("[PROFILE]", llformat("%d", self->mProfileClicksNew + self->mProfileClicksOld));
+
+ self->getChild<LLUICtrl>("click_through_text")->setValue(ct_str.getString());
+ // *HACK: remove this when there is enough room for click stats in the info panel
+ self->getChildView("click_through_text")->setToolTip(ct_str.getString());
+
+ LL_INFOS() << "teleport: " << llformat("%d", self->mTeleportClicksNew + self->mTeleportClicksOld)
+ << ", map: " << llformat("%d", self->mMapClicksNew + self->mMapClicksOld)
+ << ", profile: " << llformat("%d", self->mProfileClicksNew + self->mProfileClicksOld)
+ << LL_ENDL;
+ }
+}
+
+// static
+std::string LLPanelProfileClassified::createLocationText(
+ const std::string& original_name,
+ const std::string& sim_name,
+ const LLVector3d& pos_global)
+{
+ std::string location_text;
+
+ location_text.append(original_name);
+
+ if (!sim_name.empty())
+ {
+ if (!location_text.empty())
+ location_text.append(", ");
+ location_text.append(sim_name);
+ }
+
+ if (!location_text.empty())
+ location_text.append(" ");
+
+ if (!pos_global.isNull())
+ {
+ S32 region_x = ll_round((F32)pos_global.mdV[VX]) % REGION_WIDTH_UNITS;
+ S32 region_y = ll_round((F32)pos_global.mdV[VY]) % REGION_WIDTH_UNITS;
+ S32 region_z = ll_round((F32)pos_global.mdV[VZ]);
+ location_text.append(llformat(" (%d, %d, %d)", region_x, region_y, region_z));
+ }
+
+ return location_text;
+}
+
+void LLPanelProfileClassified::scrollToTop()
+{
+ if (mScrollContainer)
+ {
+ mScrollContainer->goToTop();
+ }
+}
+
+//info
+// static
+// *TODO: move out of the panel
+void LLPanelProfileClassified::sendClickMessage(
+ const std::string& type,
+ bool from_search,
+ const LLUUID& classified_id,
+ const LLUUID& parcel_id,
+ const LLVector3d& global_pos,
+ const std::string& sim_name)
+{
+ if (gAgent.getRegion())
+ {
+ // You're allowed to click on your own ads to reassure yourself
+ // that the system is working.
+ LLSD body;
+ body["type"] = type;
+ body["from_search"] = from_search;
+ body["classified_id"] = classified_id;
+ body["parcel_id"] = parcel_id;
+ body["dest_pos_global"] = global_pos.getValue();
+ body["region_name"] = sim_name;
+
+ std::string url = gAgent.getRegion()->getCapability("SearchStatTracking");
+ LL_INFOS() << "Sending click msg via capability (url=" << url << ")" << LL_ENDL;
+ LL_INFOS() << "body: [" << body << "]" << LL_ENDL;
+ LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(url, body,
+ "SearchStatTracking Click report sent.", "SearchStatTracking Click report NOT sent.");
+ }
+}
+
+void LLPanelProfileClassified::sendClickMessage(const std::string& type)
+{
+ sendClickMessage(
+ type,
+ fromSearch(),
+ getClassifiedId(),
+ getParcelId(),
+ getPosGlobal(),
+ getSimName());
+}
+
+void LLPanelProfileClassified::onMapClick()
+{
+ sendClickMessage("map");
+ LLFloaterWorldMap::getInstance()->trackLocation(getPosGlobal());
+ LLFloaterReg::showInstance("world_map", "center");
+}
+
+void LLPanelProfileClassified::onTeleportClick()
+{
+ if (!getPosGlobal().isExactlyZero())
+ {
+ sendClickMessage("teleport");
+ gAgent.teleportViaLocation(getPosGlobal());
+ LLFloaterWorldMap::getInstance()->trackLocation(getPosGlobal());
+ }
+}
+
+BOOL LLPanelProfileClassified::isDirty() const
+{
+ if(mIsNew)
+ {
+ return TRUE;
+ }
+
+ BOOL dirty = false;
+ dirty |= mSnapshotCtrl->isDirty();
+ dirty |= mClassifiedNameEdit->isDirty();
+ dirty |= mClassifiedDescEdit->isDirty();
+ dirty |= mCategoryCombo->isDirty();
+ dirty |= mContentTypeCombo->isDirty();
+ dirty |= mAutoRenewEdit->isDirty();
+
+ return dirty;
+}
+
+void LLPanelProfileClassified::resetDirty()
+{
+ mSnapshotCtrl->resetDirty();
+ mClassifiedNameEdit->resetDirty();
+
+ // call blockUndo() to really reset dirty(and make isDirty work as intended)
+ mClassifiedDescEdit->blockUndo();
+ mClassifiedDescEdit->resetDirty();
+
+ mCategoryCombo->resetDirty();
+ mContentTypeCombo->resetDirty();
+ mAutoRenewEdit->resetDirty();
+}
+
+bool LLPanelProfileClassified::canClose()
+{
+ return mCanClose;
+}
+
+U32 LLPanelProfileClassified::getContentType()
+{
+ return mContentTypeCombo->getCurrentIndex();
+}
+
+void LLPanelProfileClassified::setContentType(bool mature)
+{
+ static std::string mature_str = getString("type_mature");
+ static std::string pg_str = getString("type_pg");
+ mContentTypeText->setValue(mature ? mature_str : pg_str);
+ mContentTypeM->setVisible(mature);
+ mContentTypeG->setVisible(!mature);
+ mContentTypeCombo->setCurrentByIndex(mature ? CB_ITEM_MATURE : CB_ITEM_PG);
+ mContentTypeCombo->resetDirty();
+}
+
+bool LLPanelProfileClassified::getAutoRenew()
+{
+ return mAutoRenewEdit->getValue().asBoolean();
+}
+
+void LLPanelProfileClassified::sendUpdate()
+{
+ LLAvatarClassifiedInfo c_data;
+
+ if(getClassifiedId().isNull())
+ {
+ setClassifiedId(LLUUID::generateNewID());
+ }
+
+ c_data.agent_id = gAgent.getID();
+ c_data.classified_id = getClassifiedId();
+ // *HACK
+ // Categories on server start with 1 while combo-box index starts with 0
+ c_data.category = getCategory() + 1;
+ c_data.name = getClassifiedName();
+ c_data.description = getDescription();
+ c_data.parcel_id = getParcelId();
+ c_data.snapshot_id = getSnapshotId();
+ c_data.pos_global = getPosGlobal();
+ c_data.flags = getFlags();
+ c_data.price_for_listing = getPriceForListing();
+
+ LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoUpdate(&c_data);
+
+ if(isNew())
+ {
+ // Lets assume there will be some error.
+ // Successful sendClassifiedInfoUpdate will trigger processProperties and
+ // let us know there was no error.
+ mIsNewWithErrors = true;
+ }
+}
+
+U32 LLPanelProfileClassified::getCategory()
+{
+ return mCategoryCombo->getCurrentIndex();
+}
+
+void LLPanelProfileClassified::setCategory(U32 category)
+{
+ mCategoryCombo->setCurrentByIndex(category);
+ mCategoryCombo->resetDirty();
+}
+
+U8 LLPanelProfileClassified::getFlags()
+{
+ bool auto_renew = mAutoRenewEdit->getValue().asBoolean();
+
+ bool mature = mContentTypeCombo->getCurrentIndex() == CB_ITEM_MATURE;
+
+ return pack_classified_flags_request(auto_renew, false, mature, false);
+}
+
+void LLPanelProfileClassified::enableSave(bool enable)
+{
+ mSaveButton->setEnabled(enable);
+}
+
+std::string LLPanelProfileClassified::makeClassifiedName()
+{
+ std::string name;
+
+ LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+ if(parcel)
+ {
+ name = parcel->getName();
+ }
+
+ if(!name.empty())
+ {
+ return name;
+ }
+
+ LLViewerRegion* region = gAgent.getRegion();
+ if(region)
+ {
+ name = region->getName();
+ }
+
+ return name;
+}
+
+void LLPanelProfileClassified::onSetLocationClick()
+{
+ setPosGlobal(gAgent.getPositionGlobal());
+ setParcelId(LLUUID::null);
+
+ std::string region_name = LLTrans::getString("ClassifiedUpdateAfterPublish");
+ LLViewerRegion* region = gAgent.getRegion();
+ if (region)
+ {
+ region_name = region->getName();
+ }
+
+ setClassifiedLocation(createLocationText(getLocationNotice(), region_name, getPosGlobal()));
+
+ // mark classified as dirty
+ setValue(LLSD());
+
+ onChange();
+}
+
+void LLPanelProfileClassified::onChange()
+{
+ enableSave(isDirty());
+}
+
+void LLPanelProfileClassified::doSave()
+{
+ //*TODO: Fix all of this
+
+ mCanClose = true;
+ sendUpdate();
+ updateTabLabel(getClassifiedName());
+ resetDirty();
+
+ if (!canClose())
+ {
+ return;
+ }
+
+ if (!isNew() && !isNewWithErrors())
+ {
+ setEditMode(FALSE);
+ return;
+ }
+
+ updateButtons();
+}
+
+void LLPanelProfileClassified::onPublishFloaterPublishClicked()
+{
+ setPriceForListing(mPublishFloater->getPrice());
+
+ doSave();
+}
+
+std::string LLPanelProfileClassified::getLocationNotice()
+{
+ static std::string location_notice = getString("location_notice");
+ return location_notice;
+}
+
+bool LLPanelProfileClassified::isValidName()
+{
+ std::string name = getClassifiedName();
+ if (name.empty())
+ {
+ return false;
+ }
+ if (!isalnum(name[0]))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+void LLPanelProfileClassified::notifyInvalidName()
+{
+ std::string name = getClassifiedName();
+ if (name.empty())
+ {
+ LLNotificationsUtil::add("BlankClassifiedName");
+ }
+ else if (!isalnum(name[0]))
+ {
+ LLNotificationsUtil::add("ClassifiedMustBeAlphanumeric");
+ }
+}
+
+void LLPanelProfileClassified::onTexturePickerMouseEnter()
+{
+ mEditIcon->setVisible(TRUE);
+}
+
+void LLPanelProfileClassified::onTexturePickerMouseLeave()
+{
+ mEditIcon->setVisible(FALSE);
+}
+
+void LLPanelProfileClassified::onTextureSelected()
+{
+ setSnapshotId(mSnapshotCtrl->getValue().asUUID());
+ onChange();
+}
+
+void LLPanelProfileClassified::updateTabLabel(const std::string& title)
+{
+ setLabel(title);
+ LLTabContainer* parent = dynamic_cast<LLTabContainer*>(getParent());
+ if (parent)
+ {
+ parent->setCurrentTabName(title);
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// LLPublishClassifiedFloater
+//-----------------------------------------------------------------------------
+
+LLPublishClassifiedFloater::LLPublishClassifiedFloater(const LLSD& key)
+ : LLFloater(key)
+{
+}
+
+LLPublishClassifiedFloater::~LLPublishClassifiedFloater()
+{
+}
+
+BOOL LLPublishClassifiedFloater::postBuild()
+{
+ LLFloater::postBuild();
+
+ childSetAction("publish_btn", boost::bind(&LLFloater::closeFloater, this, false));
+ childSetAction("cancel_btn", boost::bind(&LLFloater::closeFloater, this, false));
+
+ return TRUE;
+}
+
+void LLPublishClassifiedFloater::setPrice(S32 price)
+{
+ getChild<LLUICtrl>("price_for_listing")->setValue(price);
+}
+
+S32 LLPublishClassifiedFloater::getPrice()
+{
+ return getChild<LLUICtrl>("price_for_listing")->getValue().asInteger();
+}
+
+void LLPublishClassifiedFloater::setPublishClickedCallback(const commit_signal_t::slot_type& cb)
+{
+ getChild<LLButton>("publish_btn")->setClickedCallback(cb);
+}
+
+void LLPublishClassifiedFloater::setCancelClickedCallback(const commit_signal_t::slot_type& cb)
+{
+ getChild<LLButton>("cancel_btn")->setClickedCallback(cb);
+}
diff --git a/indra/newview/llpanelprofileclassifieds.h b/indra/newview/llpanelprofileclassifieds.h
new file mode 100644
index 0000000000..912819e86b
--- /dev/null
+++ b/indra/newview/llpanelprofileclassifieds.h
@@ -0,0 +1,340 @@
+/**
+ * @file llpanelprofileclassifieds.h
+ * @brief LLPanelProfileClassifieds and related class implementations
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, 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_PANELPROFILECLASSIFIEDS_H
+#define LL_PANELPROFILECLASSIFIEDS_H
+
+#include "llavatarpropertiesprocessor.h"
+#include "llclassifiedinfo.h"
+#include "llfloater.h"
+#include "llpanel.h"
+#include "llpanelavatar.h"
+#include "llrect.h"
+#include "lluuid.h"
+#include "v3dmath.h"
+#include "llcoros.h"
+#include "lleventcoro.h"
+
+class LLCheckBoxCtrl;
+class LLLineEditor;
+class LLMediaCtrl;
+class LLScrollContainer;
+class LLTabContainer;
+class LLTextEditor;
+class LLTextureCtrl;
+class LLUICtrl;
+
+
+class LLPublishClassifiedFloater : public LLFloater
+{
+public:
+ LLPublishClassifiedFloater(const LLSD& key);
+ virtual ~LLPublishClassifiedFloater();
+
+ BOOL postBuild() override;
+
+ void setPrice(S32 price);
+ S32 getPrice();
+
+ void setPublishClickedCallback(const commit_signal_t::slot_type& cb);
+ void setCancelClickedCallback(const commit_signal_t::slot_type& cb);
+};
+
+
+/**
+* Panel for displaying Avatar's picks.
+*/
+class LLPanelProfileClassifieds
+ : public LLPanelProfilePropertiesProcessorTab
+{
+public:
+ LLPanelProfileClassifieds();
+ /*virtual*/ ~LLPanelProfileClassifieds();
+
+ BOOL postBuild() override;
+
+ void onOpen(const LLSD& key) override;
+
+ void selectClassified(const LLUUID& classified_id, bool edit);
+
+ void createClassified();
+
+ void processProperties(void* data, EAvatarProcessorType type) override;
+
+ void resetData() override;
+
+ void updateButtons();
+
+ void updateData() override;
+
+ bool hasNewClassifieds();
+ bool hasUnsavedChanges() override;
+ // commits changes to existing classifieds, but does not publish new classified!
+ void commitUnsavedChanges() override;
+
+private:
+ void onClickNewBtn();
+ void onClickDelete();
+ void callbackDeleteClassified(const LLSD& notification, const LLSD& response);
+
+ bool canAddNewClassified();
+ bool canDeleteClassified();
+
+ LLTabContainer* mTabContainer;
+ LLUICtrl* mNoItemsLabel;
+ LLButton* mNewButton;
+ LLButton* mDeleteButton;
+
+ LLUUID mClassifiedToSelectOnLoad;
+ bool mClassifiedEditOnLoad;
+ bool mSheduledClassifiedCreation;
+};
+
+
+class LLPanelProfileClassified
+ : public LLPanelProfilePropertiesProcessorTab
+{
+public:
+
+ static LLPanelProfileClassified* create();
+
+ LLPanelProfileClassified();
+
+ /*virtual*/ ~LLPanelProfileClassified();
+
+ BOOL postBuild() override;
+
+ void onOpen(const LLSD& key) override;
+
+ void processProperties(void* data, EAvatarProcessorType type) override;
+
+ void setSnapshotId(const LLUUID& id);
+
+ LLUUID getSnapshotId();
+
+ void setClassifiedId(const LLUUID& id) { mClassifiedId = id; }
+
+ LLUUID& getClassifiedId() { return mClassifiedId; }
+
+ void setClassifiedName(const std::string& name);
+
+ std::string getClassifiedName();
+
+ void setDescription(const std::string& desc);
+
+ std::string getDescription();
+
+ void setClassifiedLocation(const std::string& location);
+
+ std::string getClassifiedLocation();
+
+ void setPosGlobal(const LLVector3d& pos) { mPosGlobal = pos; }
+
+ LLVector3d& getPosGlobal() { return mPosGlobal; }
+
+ void setParcelId(const LLUUID& id) { mParcelId = id; }
+
+ LLUUID getParcelId() { return mParcelId; }
+
+ void setSimName(const std::string& sim_name) { mSimName = sim_name; }
+
+ std::string getSimName() { return mSimName; }
+
+ void setFromSearch(bool val) { mFromSearch = val; }
+
+ bool fromSearch() { return mFromSearch; }
+
+ bool getInfoLoaded() { return mInfoLoaded; }
+
+ void setInfoLoaded(bool loaded) { mInfoLoaded = loaded; }
+
+ BOOL isDirty() const override;
+
+ void resetDirty() override;
+
+ bool isNew() { return mIsNew; }
+
+ bool isNewWithErrors() { return mIsNewWithErrors; }
+
+ bool canClose();
+
+ U32 getCategory();
+
+ void setCategory(U32 category);
+
+ U32 getContentType();
+
+ void setContentType(bool mature);
+
+ bool getAutoRenew();
+
+ S32 getPriceForListing() { return mPriceForListing; }
+
+ void setEditMode(BOOL edit_mode);
+ bool getEditMode() {return mEditMode;}
+
+ static void setClickThrough(
+ const LLUUID& classified_id,
+ S32 teleport,
+ S32 map,
+ S32 profile,
+ bool from_new_table);
+
+ static void sendClickMessage(
+ const std::string& type,
+ bool from_search,
+ const LLUUID& classified_id,
+ const LLUUID& parcel_id,
+ const LLVector3d& global_pos,
+ const std::string& sim_name);
+
+ void doSave();
+
+protected:
+
+ void resetData() override;
+
+ void resetControls();
+
+ void updateButtons();
+ void updateInfoRect();
+
+ static std::string createLocationText(
+ const std::string& original_name,
+ const std::string& sim_name,
+ const LLVector3d& pos_global);
+
+ void sendClickMessage(const std::string& type);
+
+ void scrollToTop();
+
+ void onEditClick();
+ void onCancelClick();
+ void onSaveClick();
+ void onMapClick();
+ void onTeleportClick();
+
+ void sendUpdate();
+
+ void enableSave(bool enable);
+
+ void enableEditing(bool enable);
+
+ std::string makeClassifiedName();
+
+ void setPriceForListing(S32 price) { mPriceForListing = price; }
+
+ U8 getFlags();
+
+ std::string getLocationNotice();
+
+ bool isValidName();
+
+ void notifyInvalidName();
+
+ void onSetLocationClick();
+ void onChange();
+
+ void onPublishFloaterPublishClicked();
+
+ void onTexturePickerMouseEnter();
+ void onTexturePickerMouseLeave();
+
+ void onTextureSelected();
+
+ void updateTabLabel(const std::string& title);
+
+private:
+
+ LLTextureCtrl* mSnapshotCtrl;
+ LLUICtrl* mEditIcon;
+ LLUICtrl* mClassifiedNameText;
+ LLTextEditor* mClassifiedDescText;
+ LLLineEditor* mClassifiedNameEdit;
+ LLTextEditor* mClassifiedDescEdit;
+ LLUICtrl* mLocationText;
+ LLUICtrl* mLocationEdit;
+ LLUICtrl* mCategoryText;
+ LLComboBox* mCategoryCombo;
+ LLUICtrl* mContentTypeText;
+ LLIconCtrl* mContentTypeM;
+ LLIconCtrl* mContentTypeG;
+ LLComboBox* mContentTypeCombo;
+ LLUICtrl* mPriceText;
+ LLUICtrl* mAutoRenewText;
+ LLUICtrl* mAutoRenewEdit;
+
+ LLButton* mMapButton;
+ LLButton* mTeleportButton;
+ LLButton* mEditButton;
+ LLButton* mSaveButton;
+ LLButton* mSetLocationButton;
+ LLButton* mCancelButton;
+
+ LLPanel* mUtilityBtnCnt;
+ LLPanel* mPublishBtnsCnt;
+ LLPanel* mSaveBtnCnt;
+ LLPanel* mCancelBtnCnt;
+
+ LLScrollContainer* mScrollContainer;
+ LLView* mInfoPanel;
+ LLPanel* mInfoScroll;
+ LLPanel* mEditPanel;
+
+
+ LLUUID mClassifiedId;
+ LLVector3d mPosGlobal;
+ LLUUID mParcelId;
+ std::string mSimName;
+ bool mFromSearch;
+ bool mInfoLoaded;
+ bool mEditMode;
+
+ // Needed for stat tracking
+ S32 mTeleportClicksOld;
+ S32 mMapClicksOld;
+ S32 mProfileClicksOld;
+ S32 mTeleportClicksNew;
+ S32 mMapClicksNew;
+ S32 mProfileClicksNew;
+
+ S32 mPriceForListing;
+
+ static void handleSearchStatResponse(LLUUID classifiedId, LLSD result);
+
+ typedef std::list<LLPanelProfileClassified*> panel_list_t;
+ static panel_list_t sAllPanels;
+
+
+ bool mIsNew;
+ bool mIsNewWithErrors;
+ bool mCanClose;
+ bool mEditOnLoad;
+
+ LLPublishClassifiedFloater* mPublishFloater;
+};
+
+#endif // LL_PANELPROFILECLASSIFIEDS_H
diff --git a/indra/newview/llpanelprofilepicks.cpp b/indra/newview/llpanelprofilepicks.cpp
new file mode 100644
index 0000000000..774119f169
--- /dev/null
+++ b/indra/newview/llpanelprofilepicks.cpp
@@ -0,0 +1,883 @@
+/**
+ * @file llpanelprofilepicks.cpp
+ * @brief LLPanelProfilePicks and related class implementations
+ *
+ * $LicenseInfo:firstyear=2009&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$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llpanelprofilepicks.h"
+
+#include "llagent.h"
+#include "llagentpicksinfo.h"
+#include "llavataractions.h"
+#include "llavatarpropertiesprocessor.h"
+#include "llcommandhandler.h"
+#include "lldispatcher.h"
+#include "llfloaterreg.h"
+#include "llfloaterworldmap.h"
+#include "lllineeditor.h"
+#include "llnotificationsutil.h"
+#include "llpanelavatar.h"
+#include "llpanelprofile.h"
+#include "llparcel.h"
+#include "llstartup.h"
+#include "lltabcontainer.h"
+#include "lltextbox.h"
+#include "lltexteditor.h"
+#include "lltexturectrl.h"
+#include "lltexturectrl.h"
+#include "lltrans.h"
+#include "llviewergenericmessage.h" // send_generic_message
+#include "llviewerparcelmgr.h"
+#include "llviewerregion.h"
+
+static LLPanelInjector<LLPanelProfilePicks> t_panel_profile_picks("panel_profile_picks");
+static LLPanelInjector<LLPanelProfilePick> t_panel_profile_pick("panel_profile_pick");
+
+
+class LLPickHandler : public LLCommandHandler
+{
+public:
+
+ // requires trusted browser to trigger
+ LLPickHandler() : LLCommandHandler("pick", UNTRUSTED_THROTTLE) { }
+
+ bool handle(const LLSD& params, const LLSD& query_map,
+ LLMediaCtrl* web)
+ {
+ if (LLStartUp::getStartupState() < STATE_STARTED)
+ {
+ return true;
+ }
+
+ if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnablePicks"))
+ {
+ LLNotificationsUtil::add("NoPicks", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit"));
+ return true;
+ }
+
+ // handle app/pick/create urls first
+ if (params.size() == 1 && params[0].asString() == "create")
+ {
+ LLAvatarActions::createPick();
+ return true;
+ }
+
+ // then handle the general app/pick/{UUID}/{CMD} urls
+ if (params.size() < 2)
+ {
+ return false;
+ }
+
+ // get the ID for the pick_id
+ LLUUID pick_id;
+ if (!pick_id.set(params[0], FALSE))
+ {
+ return false;
+ }
+
+ // edit the pick in the side tray.
+ // need to ask the server for more info first though...
+ const std::string verb = params[1].asString();
+ if (verb == "edit")
+ {
+ LLAvatarActions::showPick(gAgent.getID(), pick_id);
+ return true;
+ }
+ else
+ {
+ LL_WARNS() << "unknown verb " << verb << LL_ENDL;
+ return false;
+ }
+ }
+};
+LLPickHandler gPickHandler;
+
+
+//-----------------------------------------------------------------------------
+// LLPanelProfilePicks
+//-----------------------------------------------------------------------------
+
+LLPanelProfilePicks::LLPanelProfilePicks()
+ : LLPanelProfilePropertiesProcessorTab()
+ , mPickToSelectOnLoad(LLUUID::null)
+{
+}
+
+LLPanelProfilePicks::~LLPanelProfilePicks()
+{
+}
+
+void LLPanelProfilePicks::onOpen(const LLSD& key)
+{
+ LLPanelProfilePropertiesProcessorTab::onOpen(key);
+
+ resetData();
+
+ bool own_profile = getSelfProfile();
+ if (own_profile)
+ {
+ mNewButton->setVisible(TRUE);
+ mNewButton->setEnabled(FALSE);
+
+ mDeleteButton->setVisible(TRUE);
+ mDeleteButton->setEnabled(FALSE);
+ }
+
+ childSetVisible("buttons_header", own_profile);
+}
+
+void LLPanelProfilePicks::createPick(const LLPickData &data)
+{
+ if (getIsLoaded())
+ {
+ if (canAddNewPick())
+ {
+ mNoItemsLabel->setVisible(FALSE);
+ LLPanelProfilePick* pick_panel = LLPanelProfilePick::create();
+ pick_panel->setAvatarId(getAvatarId());
+ pick_panel->processProperties(&data);
+ mTabContainer->addTabPanel(
+ LLTabContainer::TabPanelParams().
+ panel(pick_panel).
+ select_tab(true).
+ label(pick_panel->getPickName()));
+ updateButtons();
+ }
+ else
+ {
+ // This means that something doesn't properly check limits
+ // before creating a pick
+ LL_WARNS() << "failed to add pick" << LL_ENDL;
+ }
+ }
+ else
+ {
+ mSheduledPickCreation.push_back(data);
+ }
+}
+
+void LLPanelProfilePicks::selectPick(const LLUUID& pick_id)
+{
+ if (getIsLoaded())
+ {
+ for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx)
+ {
+ LLPanelProfilePick* pick_panel = dynamic_cast<LLPanelProfilePick*>(mTabContainer->getPanelByIndex(tab_idx));
+ if (pick_panel)
+ {
+ if (pick_panel->getPickId() == pick_id)
+ {
+ mTabContainer->selectTabPanel(pick_panel);
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ mPickToSelectOnLoad = pick_id;
+ }
+}
+
+BOOL LLPanelProfilePicks::postBuild()
+{
+ mTabContainer = getChild<LLTabContainer>("tab_picks");
+ mNoItemsLabel = getChild<LLUICtrl>("picks_panel_text");
+ mNewButton = getChild<LLButton>("new_btn");
+ mDeleteButton = getChild<LLButton>("delete_btn");
+
+ mNewButton->setCommitCallback(boost::bind(&LLPanelProfilePicks::onClickNewBtn, this));
+ mDeleteButton->setCommitCallback(boost::bind(&LLPanelProfilePicks::onClickDelete, this));
+
+ return TRUE;
+}
+
+void LLPanelProfilePicks::onClickNewBtn()
+{
+ mNoItemsLabel->setVisible(FALSE);
+ LLPanelProfilePick* pick_panel = LLPanelProfilePick::create();
+ pick_panel->setAvatarId(getAvatarId());
+ mTabContainer->addTabPanel(
+ LLTabContainer::TabPanelParams().
+ panel(pick_panel).
+ select_tab(true).
+ label(pick_panel->getPickName()));
+ updateButtons();
+}
+
+void LLPanelProfilePicks::onClickDelete()
+{
+ LLPanelProfilePick* pick_panel = dynamic_cast<LLPanelProfilePick*>(mTabContainer->getCurrentPanel());
+ if (pick_panel)
+ {
+ LLUUID pick_id = pick_panel->getPickId();
+ LLSD args;
+ args["PICK"] = pick_panel->getPickName();
+ LLSD payload;
+ payload["pick_id"] = pick_id;
+ payload["tab_idx"] = mTabContainer->getCurrentPanelIndex();
+ LLNotificationsUtil::add("ProfileDeletePick", args, payload,
+ boost::bind(&LLPanelProfilePicks::callbackDeletePick, this, _1, _2));
+ }
+}
+
+void LLPanelProfilePicks::callbackDeletePick(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+
+ if (0 == option)
+ {
+ LLUUID pick_id = notification["payload"]["pick_id"].asUUID();
+ S32 tab_idx = notification["payload"]["tab_idx"].asInteger();
+
+ LLPanelProfilePick* pick_panel = dynamic_cast<LLPanelProfilePick*>(mTabContainer->getPanelByIndex(tab_idx));
+ if (pick_panel && pick_panel->getPickId() == pick_id)
+ {
+ mTabContainer->removeTabPanel(pick_panel);
+ }
+
+ if (pick_id.notNull())
+ {
+ LLAvatarPropertiesProcessor::getInstance()->sendPickDelete(pick_id);
+ }
+
+ updateButtons();
+ }
+}
+
+void LLPanelProfilePicks::processProperties(void* data, EAvatarProcessorType type)
+{
+ if (APT_PICKS == type)
+ {
+ LLAvatarPicks* avatar_picks = static_cast<LLAvatarPicks*>(data);
+ if (avatar_picks && getAvatarId() == avatar_picks->target_id)
+ {
+ processProperties(avatar_picks);
+ }
+ }
+}
+
+void LLPanelProfilePicks::processProperties(const LLAvatarPicks* avatar_picks)
+{
+ LLUUID selected_id = mPickToSelectOnLoad;
+ bool has_selection = false;
+ if (mPickToSelectOnLoad.isNull())
+ {
+ if (mTabContainer->getTabCount() > 0)
+ {
+ LLPanelProfilePick* active_pick_panel = dynamic_cast<LLPanelProfilePick*>(mTabContainer->getCurrentPanel());
+ if (active_pick_panel)
+ {
+ selected_id = active_pick_panel->getPickId();
+ }
+ }
+ }
+
+ mTabContainer->deleteAllTabs();
+
+ LLAvatarPicks::picks_list_t::const_iterator it = avatar_picks->picks_list.begin();
+ for (; avatar_picks->picks_list.end() != it; ++it)
+ {
+ LLUUID pick_id = it->first;
+ std::string pick_name = it->second;
+
+ LLPanelProfilePick* pick_panel = LLPanelProfilePick::create();
+
+ pick_panel->setPickId(pick_id);
+ pick_panel->setPickName(pick_name);
+ pick_panel->setAvatarId(getAvatarId());
+
+ mTabContainer->addTabPanel(
+ LLTabContainer::TabPanelParams().
+ panel(pick_panel).
+ select_tab(selected_id == pick_id).
+ label(pick_name));
+
+ if (selected_id == pick_id)
+ {
+ has_selection = true;
+ }
+ }
+
+ while (!mSheduledPickCreation.empty() && canAddNewPick())
+ {
+ const LLPickData data =
+ mSheduledPickCreation.back();
+
+ LLPanelProfilePick* pick_panel = LLPanelProfilePick::create();
+ pick_panel->setAvatarId(getAvatarId());
+ pick_panel->processProperties(&data);
+ mTabContainer->addTabPanel(
+ LLTabContainer::TabPanelParams().
+ panel(pick_panel).
+ select_tab(!has_selection).
+ label(pick_panel->getPickName()));
+
+ mSheduledPickCreation.pop_back();
+ has_selection = true;
+ }
+
+ // reset 'do on load' values
+ mPickToSelectOnLoad = LLUUID::null;
+ mSheduledPickCreation.clear();
+
+ if (getSelfProfile())
+ {
+ mNoItemsLabel->setValue(LLTrans::getString("NoPicksText"));
+ }
+ else
+ {
+ mNoItemsLabel->setValue(LLTrans::getString("NoAvatarPicksText"));
+ }
+
+ bool has_data = mTabContainer->getTabCount() > 0;
+ mNoItemsLabel->setVisible(!has_data);
+ if (has_data && !has_selection)
+ {
+ mTabContainer->selectFirstTab();
+ }
+
+ setLoaded();
+ updateButtons();
+}
+
+void LLPanelProfilePicks::resetData()
+{
+ resetLoading();
+ mTabContainer->deleteAllTabs();
+}
+
+void LLPanelProfilePicks::updateButtons()
+{
+ if (getSelfProfile())
+ {
+ mNewButton->setEnabled(canAddNewPick());
+ mDeleteButton->setEnabled(canDeletePick());
+ }
+}
+
+void LLPanelProfilePicks::apply()
+{
+ if (getIsLoaded())
+ {
+ for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx)
+ {
+ LLPanelProfilePick* pick_panel = dynamic_cast<LLPanelProfilePick*>(mTabContainer->getPanelByIndex(tab_idx));
+ if (pick_panel)
+ {
+ pick_panel->apply();
+ }
+ }
+ }
+}
+
+void LLPanelProfilePicks::updateData()
+{
+ // Send picks request only once
+ LLUUID avatar_id = getAvatarId();
+ if (!getStarted() && avatar_id.notNull())
+ {
+ setIsLoading();
+
+ LLAvatarPropertiesProcessor::getInstance()->sendAvatarPicksRequest(avatar_id);
+ }
+ if (!getIsLoaded())
+ {
+ mNoItemsLabel->setValue(LLTrans::getString("PicksClassifiedsLoadingText"));
+ mNoItemsLabel->setVisible(TRUE);
+ }
+}
+
+bool LLPanelProfilePicks::hasUnsavedChanges()
+{
+ for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx)
+ {
+ LLPanelProfilePick* pick_panel = dynamic_cast<LLPanelProfilePick*>(mTabContainer->getPanelByIndex(tab_idx));
+ if (pick_panel && (pick_panel->isDirty() || pick_panel->isDirty()))
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+void LLPanelProfilePicks::commitUnsavedChanges()
+{
+ for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx)
+ {
+ LLPanelProfilePick* pick_panel = dynamic_cast<LLPanelProfilePick*>(mTabContainer->getPanelByIndex(tab_idx));
+ if (pick_panel)
+ {
+ pick_panel->apply();
+ }
+ }
+}
+
+bool LLPanelProfilePicks::canAddNewPick()
+{
+ return (!LLAgentPicksInfo::getInstance()->isPickLimitReached() &&
+ mTabContainer->getTabCount() < LLAgentPicksInfo::getInstance()->getMaxNumberOfPicks());
+}
+
+bool LLPanelProfilePicks::canDeletePick()
+{
+ return (mTabContainer->getTabCount() > 0);
+}
+
+
+//-----------------------------------------------------------------------------
+// LLPanelProfilePick
+//-----------------------------------------------------------------------------
+
+LLPanelProfilePick::LLPanelProfilePick()
+ : LLPanelProfilePropertiesProcessorTab()
+ , LLRemoteParcelInfoObserver()
+ , mSnapshotCtrl(NULL)
+ , mPickId(LLUUID::null)
+ , mParcelId(LLUUID::null)
+ , mRequestedId(LLUUID::null)
+ , mLocationChanged(false)
+ , mNewPick(false)
+ , mIsEditing(false)
+{
+}
+
+//static
+LLPanelProfilePick* LLPanelProfilePick::create()
+{
+ LLPanelProfilePick* panel = new LLPanelProfilePick();
+ panel->buildFromFile("panel_profile_pick.xml");
+ return panel;
+}
+
+LLPanelProfilePick::~LLPanelProfilePick()
+{
+ if (mParcelId.notNull())
+ {
+ LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mParcelId, this);
+ }
+}
+
+void LLPanelProfilePick::setAvatarId(const LLUUID& avatar_id)
+{
+ if (avatar_id.isNull())
+ {
+ return;
+ }
+ LLPanelProfilePropertiesProcessorTab::setAvatarId(avatar_id);
+
+ // creating new Pick
+ if (getPickId().isNull() && getSelfProfile())
+ {
+ mNewPick = true;
+
+ setPosGlobal(gAgent.getPositionGlobal());
+
+ LLUUID parcel_id = LLUUID::null, snapshot_id = LLUUID::null;
+ std::string pick_name, pick_desc, region_name;
+
+ LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+ if (parcel)
+ {
+ parcel_id = parcel->getID();
+ pick_name = parcel->getName();
+ pick_desc = parcel->getDesc();
+ snapshot_id = parcel->getSnapshotID();
+ }
+
+ LLViewerRegion* region = gAgent.getRegion();
+ if (region)
+ {
+ region_name = region->getName();
+ }
+
+ setParcelID(parcel_id);
+ setPickName(pick_name.empty() ? region_name : pick_name);
+ setPickDesc(pick_desc);
+ setSnapshotId(snapshot_id);
+ setPickLocation(createLocationText(getLocationNotice(), pick_name, region_name, getPosGlobal()));
+
+ enableSaveButton(TRUE);
+ }
+ else
+ {
+ LLAvatarPropertiesProcessor::getInstance()->sendPickInfoRequest(getAvatarId(), getPickId());
+
+ enableSaveButton(FALSE);
+ }
+
+ resetDirty();
+
+ if (getSelfProfile())
+ {
+ mPickName->setEnabled(TRUE);
+ mPickDescription->setEnabled(TRUE);
+ mSetCurrentLocationButton->setVisible(TRUE);
+ }
+ else
+ {
+ mSnapshotCtrl->setEnabled(FALSE);
+ }
+}
+
+BOOL LLPanelProfilePick::postBuild()
+{
+ mPickName = getChild<LLLineEditor>("pick_name");
+ mPickDescription = getChild<LLTextEditor>("pick_desc");
+ mSaveButton = getChild<LLButton>("save_changes_btn");
+ mCreateButton = getChild<LLButton>("create_changes_btn");
+ mCancelButton = getChild<LLButton>("cancel_changes_btn");
+ mSetCurrentLocationButton = getChild<LLButton>("set_to_curr_location_btn");
+
+ mSnapshotCtrl = getChild<LLTextureCtrl>("pick_snapshot");
+ mSnapshotCtrl->setCommitCallback(boost::bind(&LLPanelProfilePick::onSnapshotChanged, this));
+
+ childSetAction("teleport_btn", boost::bind(&LLPanelProfilePick::onClickTeleport, this));
+ childSetAction("show_on_map_btn", boost::bind(&LLPanelProfilePick::onClickMap, this));
+
+ mSaveButton->setCommitCallback(boost::bind(&LLPanelProfilePick::onClickSave, this));
+ mCreateButton->setCommitCallback(boost::bind(&LLPanelProfilePick::onClickSave, this));
+ mCancelButton->setCommitCallback(boost::bind(&LLPanelProfilePick::onClickCancel, this));
+ mSetCurrentLocationButton->setCommitCallback(boost::bind(&LLPanelProfilePick::onClickSetLocation, this));
+
+ mPickName->setKeystrokeCallback(boost::bind(&LLPanelProfilePick::onPickChanged, this, _1), NULL);
+ mPickName->setEnabled(FALSE);
+
+ mPickDescription->setKeystrokeCallback(boost::bind(&LLPanelProfilePick::onPickChanged, this, _1));
+ mPickDescription->setFocusReceivedCallback(boost::bind(&LLPanelProfilePick::onDescriptionFocusReceived, this));
+
+ getChild<LLUICtrl>("pick_location")->setEnabled(FALSE);
+
+ return TRUE;
+}
+
+void LLPanelProfilePick::onDescriptionFocusReceived()
+{
+ if (!mIsEditing && getSelfProfile())
+ {
+ mIsEditing = true;
+ mPickDescription->setParseHTML(false);
+ }
+}
+
+void LLPanelProfilePick::processProperties(void* data, EAvatarProcessorType type)
+{
+ if (APT_PICK_INFO != type)
+ {
+ return;
+ }
+
+ LLPickData* pick_info = static_cast<LLPickData*>(data);
+ if (!pick_info
+ || pick_info->creator_id != getAvatarId()
+ || pick_info->pick_id != getPickId())
+ {
+ return;
+ }
+
+ processProperties(pick_info);
+}
+
+void LLPanelProfilePick::processProperties(const LLPickData* pick_info)
+{
+ mIsEditing = false;
+ mPickDescription->setParseHTML(true);
+ mParcelId = pick_info->parcel_id;
+ setSnapshotId(pick_info->snapshot_id);
+ if (!getSelfProfile())
+ {
+ mSnapshotCtrl->setEnabled(FALSE);
+ }
+ setPickName(pick_info->name);
+ setPickDesc(pick_info->desc);
+ setPosGlobal(pick_info->pos_global);
+
+ // Send remote parcel info request to get parcel name and sim (region) name.
+ sendParcelInfoRequest();
+
+ // *NOTE dzaporozhan
+ // We want to keep listening to APT_PICK_INFO because user may
+ // edit the Pick and we have to update Pick info panel.
+ // revomeObserver is called from onClickBack
+
+ setLoaded();
+}
+
+void LLPanelProfilePick::apply()
+{
+ if ((mNewPick || getIsLoaded()) && isDirty())
+ {
+ sendUpdate();
+ }
+}
+
+void LLPanelProfilePick::setSnapshotId(const LLUUID& id)
+{
+ mSnapshotCtrl->setImageAssetID(id);
+ mSnapshotCtrl->setValid(TRUE);
+}
+
+void LLPanelProfilePick::setPickName(const std::string& name)
+{
+ mPickName->setValue(name);
+}
+
+const std::string LLPanelProfilePick::getPickName()
+{
+ return mPickName->getValue().asString();
+}
+
+void LLPanelProfilePick::setPickDesc(const std::string& desc)
+{
+ mPickDescription->setValue(desc);
+}
+
+void LLPanelProfilePick::setPickLocation(const std::string& location)
+{
+ getChild<LLUICtrl>("pick_location")->setValue(location);
+}
+
+void LLPanelProfilePick::onClickMap()
+{
+ LLFloaterWorldMap::getInstance()->trackLocation(getPosGlobal());
+ LLFloaterReg::showInstance("world_map", "center");
+}
+
+void LLPanelProfilePick::onClickTeleport()
+{
+ if (!getPosGlobal().isExactlyZero())
+ {
+ gAgent.teleportViaLocation(getPosGlobal());
+ LLFloaterWorldMap::getInstance()->trackLocation(getPosGlobal());
+ }
+}
+
+void LLPanelProfilePick::enableSaveButton(BOOL enable)
+{
+ childSetVisible("save_changes_lp", enable);
+
+ childSetVisible("save_btn_lp", enable && !mNewPick);
+ childSetVisible("create_btn_lp", enable && mNewPick);
+ childSetVisible("cancel_btn_lp", enable && !mNewPick);
+}
+
+void LLPanelProfilePick::onSnapshotChanged()
+{
+ enableSaveButton(TRUE);
+}
+
+void LLPanelProfilePick::onPickChanged(LLUICtrl* ctrl)
+{
+ if (ctrl && ctrl == mPickName)
+ {
+ updateTabLabel(mPickName->getText());
+ }
+
+ enableSaveButton(isDirty());
+}
+
+void LLPanelProfilePick::resetDirty()
+{
+ LLPanel::resetDirty();
+
+ mPickName->resetDirty();
+ mPickDescription->resetDirty();
+ mSnapshotCtrl->resetDirty();
+ mLocationChanged = false;
+}
+
+BOOL LLPanelProfilePick::isDirty() const
+{
+ if (mNewPick
+ || LLPanel::isDirty()
+ || mLocationChanged
+ || mSnapshotCtrl->isDirty()
+ || mPickName->isDirty()
+ || mPickDescription->isDirty())
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void LLPanelProfilePick::onClickSetLocation()
+{
+ // Save location for later use.
+ setPosGlobal(gAgent.getPositionGlobal());
+
+ std::string parcel_name, region_name;
+
+ LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+ if (parcel)
+ {
+ mParcelId = parcel->getID();
+ parcel_name = parcel->getName();
+ }
+
+ LLViewerRegion* region = gAgent.getRegion();
+ if (region)
+ {
+ region_name = region->getName();
+ }
+
+ setPickLocation(createLocationText(getLocationNotice(), parcel_name, region_name, getPosGlobal()));
+
+ mLocationChanged = true;
+ enableSaveButton(TRUE);
+}
+
+void LLPanelProfilePick::onClickSave()
+{
+ sendUpdate();
+
+ mLocationChanged = false;
+}
+
+void LLPanelProfilePick::onClickCancel()
+{
+ LLAvatarPropertiesProcessor::getInstance()->sendPickInfoRequest(getAvatarId(), getPickId());
+ mLocationChanged = false;
+ enableSaveButton(FALSE);
+}
+
+std::string LLPanelProfilePick::getLocationNotice()
+{
+ static const std::string notice = getString("location_notice");
+ return notice;
+}
+
+void LLPanelProfilePick::sendParcelInfoRequest()
+{
+ if (mParcelId != mRequestedId)
+ {
+ if (mRequestedId.notNull())
+ {
+ LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mRequestedId, this);
+ }
+ LLRemoteParcelInfoProcessor::getInstance()->addObserver(mParcelId, this);
+ LLRemoteParcelInfoProcessor::getInstance()->sendParcelInfoRequest(mParcelId);
+
+ mRequestedId = mParcelId;
+ }
+}
+
+void LLPanelProfilePick::processParcelInfo(const LLParcelData& parcel_data)
+{
+ setPickLocation(createLocationText(LLStringUtil::null, parcel_data.name, parcel_data.sim_name, getPosGlobal()));
+
+ // We have received parcel info for the requested ID so clear it now.
+ mRequestedId.setNull();
+
+ if (mParcelId.notNull())
+ {
+ LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mParcelId, this);
+ }
+}
+
+void LLPanelProfilePick::sendUpdate()
+{
+ LLPickData pick_data;
+
+ // If we don't have a pick id yet, we'll need to generate one,
+ // otherwise we'll keep overwriting pick_id 00000 in the database.
+ if (getPickId().isNull())
+ {
+ getPickId().generate();
+ }
+
+ pick_data.agent_id = gAgentID;
+ pick_data.session_id = gAgent.getSessionID();
+ pick_data.pick_id = getPickId();
+ pick_data.creator_id = gAgentID;;
+
+ //legacy var need to be deleted
+ pick_data.top_pick = FALSE;
+ pick_data.parcel_id = mParcelId;
+ pick_data.name = getPickName();
+ pick_data.desc = mPickDescription->getValue().asString();
+ pick_data.snapshot_id = mSnapshotCtrl->getImageAssetID();
+ pick_data.pos_global = getPosGlobal();
+ pick_data.sort_order = 0;
+ pick_data.enabled = TRUE;
+
+ LLAvatarPropertiesProcessor::getInstance()->sendPickInfoUpdate(&pick_data);
+
+ if(mNewPick)
+ {
+ // Assume a successful create pick operation, make new number of picks
+ // available immediately. Actual number of picks will be requested in
+ // LLAvatarPropertiesProcessor::sendPickInfoUpdate and updated upon server respond.
+ LLAgentPicksInfo::getInstance()->incrementNumberOfPicks();
+ }
+}
+
+// static
+std::string LLPanelProfilePick::createLocationText(const std::string& owner_name, const std::string& original_name, const std::string& sim_name, const LLVector3d& pos_global)
+{
+ std::string location_text(owner_name);
+ if (!original_name.empty())
+ {
+ if (!location_text.empty())
+ {
+ location_text.append(", ");
+ }
+ location_text.append(original_name);
+
+ }
+
+ if (!sim_name.empty())
+ {
+ if (!location_text.empty())
+ {
+ location_text.append(", ");
+ }
+ location_text.append(sim_name);
+ }
+
+ if (!location_text.empty())
+ {
+ location_text.append(" ");
+ }
+
+ if (!pos_global.isNull())
+ {
+ S32 region_x = ll_round((F32)pos_global.mdV[VX]) % REGION_WIDTH_UNITS;
+ S32 region_y = ll_round((F32)pos_global.mdV[VY]) % REGION_WIDTH_UNITS;
+ S32 region_z = ll_round((F32)pos_global.mdV[VZ]);
+ location_text.append(llformat(" (%d, %d, %d)", region_x, region_y, region_z));
+ }
+ return location_text;
+}
+
+void LLPanelProfilePick::updateTabLabel(const std::string& title)
+{
+ setLabel(title);
+ LLTabContainer* parent = dynamic_cast<LLTabContainer*>(getParent());
+ if (parent)
+ {
+ parent->setCurrentTabName(title);
+ }
+}
+
diff --git a/indra/newview/llpanelprofilepicks.h b/indra/newview/llpanelprofilepicks.h
new file mode 100644
index 0000000000..f84463cc9b
--- /dev/null
+++ b/indra/newview/llpanelprofilepicks.h
@@ -0,0 +1,248 @@
+/**
+ * @file llpanelprofilepicks.h
+ * @brief LLPanelProfilePicks and related class definitions
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, 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_LLPANELPICKS_H
+#define LL_LLPANELPICKS_H
+
+#include "llpanel.h"
+#include "lluuid.h"
+#include "llavatarpropertiesprocessor.h"
+#include "llpanelavatar.h"
+#include "llremoteparcelrequest.h"
+
+class LLTabContainer;
+class LLTextureCtrl;
+class LLMediaCtrl;
+class LLLineEditor;
+class LLTextEditor;
+
+
+/**
+* Panel for displaying Avatar's picks.
+*/
+class LLPanelProfilePicks
+ : public LLPanelProfilePropertiesProcessorTab
+{
+public:
+ LLPanelProfilePicks();
+ /*virtual*/ ~LLPanelProfilePicks();
+
+ BOOL postBuild() override;
+
+ void onOpen(const LLSD& key) override;
+
+ void createPick(const LLPickData &data);
+ void selectPick(const LLUUID& pick_id);
+
+ void processProperties(void* data, EAvatarProcessorType type) override;
+ void processProperties(const LLAvatarPicks* avatar_picks);
+
+ void resetData() override;
+
+ void updateButtons();
+
+ /**
+ * Saves changes.
+ */
+ virtual void apply();
+
+ /**
+ * Sends update data request to server.
+ */
+ void updateData() override;
+
+ bool hasUnsavedChanges() override;
+ void commitUnsavedChanges() override;
+
+ friend void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id);
+
+private:
+ void onClickNewBtn();
+ void onClickDelete();
+ void callbackDeletePick(const LLSD& notification, const LLSD& response);
+
+ bool canAddNewPick();
+ bool canDeletePick();
+
+ LLTabContainer* mTabContainer;
+ LLUICtrl* mNoItemsLabel;
+ LLButton* mNewButton;
+ LLButton* mDeleteButton;
+
+ LLUUID mPickToSelectOnLoad;
+ std::list<LLPickData> mSheduledPickCreation;
+};
+
+
+class LLPanelProfilePick
+ : public LLPanelProfilePropertiesProcessorTab
+ , public LLRemoteParcelInfoObserver
+{
+public:
+
+ // Creates new panel
+ static LLPanelProfilePick* create();
+
+ LLPanelProfilePick();
+
+ /*virtual*/ ~LLPanelProfilePick();
+
+ BOOL postBuild() override;
+
+ void setAvatarId(const LLUUID& avatar_id) override;
+
+ void setPickId(const LLUUID& id) { mPickId = id; }
+ virtual LLUUID& getPickId() { return mPickId; }
+
+ virtual void setPickName(const std::string& name);
+ const std::string getPickName();
+
+ void processProperties(void* data, EAvatarProcessorType type) override;
+ void processProperties(const LLPickData* pick_data);
+
+ /**
+ * Returns true if any of Pick properties was changed by user.
+ */
+ BOOL isDirty() const override;
+
+ /**
+ * Saves changes.
+ */
+ virtual void apply();
+
+ void updateTabLabel(const std::string& title);
+
+ //This stuff we got from LLRemoteParcelObserver, in the last one we intentionally do nothing
+ void processParcelInfo(const LLParcelData& parcel_data) override;
+ void setParcelID(const LLUUID& parcel_id) override { mParcelId = parcel_id; }
+ void setErrorStatus(S32 status, const std::string& reason) override {};
+
+protected:
+
+ /**
+ * Sends remote parcel info request to resolve parcel name from its ID.
+ */
+ void sendParcelInfoRequest();
+
+ /**
+ * "Location text" is actually the owner name, the original
+ * name that owner gave the parcel, and the location.
+ */
+ static std::string createLocationText(
+ const std::string& owner_name,
+ const std::string& original_name,
+ const std::string& sim_name,
+ const LLVector3d& pos_global);
+
+ /**
+ * Sets snapshot id.
+ *
+ * Will mark snapshot control as valid if id is not null.
+ * Will mark snapshot control as invalid if id is null. If null id is a valid value,
+ * you have to manually mark snapshot is valid.
+ */
+ virtual void setSnapshotId(const LLUUID& id);
+ virtual void setPickDesc(const std::string& desc);
+ virtual void setPickLocation(const std::string& location);
+
+ virtual void setPosGlobal(const LLVector3d& pos) { mPosGlobal = pos; }
+ virtual LLVector3d& getPosGlobal() { return mPosGlobal; }
+
+ /**
+ * Callback for "Map" button, opens Map
+ */
+ void onClickMap();
+
+ /**
+ * Callback for "Teleport" button, teleports user to Pick location.
+ */
+ void onClickTeleport();
+
+ /**
+ * Enables/disables "Save" button
+ */
+ void enableSaveButton(BOOL enable);
+
+ /**
+ * Called when snapshot image changes.
+ */
+ void onSnapshotChanged();
+
+ /**
+ * Callback for Pick snapshot, name and description changed event.
+ */
+ void onPickChanged(LLUICtrl* ctrl);
+
+ /**
+ * Resets panel and all cantrols to unedited state
+ */
+ void resetDirty() override;
+
+ /**
+ * Callback for "Set Location" button click
+ */
+ void onClickSetLocation();
+
+ /**
+ * Callback for "Save" and "Create" button click
+ */
+ void onClickSave();
+
+ /**
+ * Callback for "Save" button click
+ */
+ void onClickCancel();
+
+ std::string getLocationNotice();
+
+ /**
+ * Sends Pick properties to server.
+ */
+ void sendUpdate();
+
+protected:
+
+ LLTextureCtrl* mSnapshotCtrl;
+ LLLineEditor* mPickName;
+ LLTextEditor* mPickDescription;
+ LLButton* mSetCurrentLocationButton;
+ LLButton* mSaveButton;
+ LLButton* mCreateButton;
+ LLButton* mCancelButton;
+
+ LLVector3d mPosGlobal;
+ LLUUID mParcelId;
+ LLUUID mPickId;
+ LLUUID mRequestedId;
+
+ bool mLocationChanged;
+ bool mNewPick;
+ bool mIsEditing;
+
+ void onDescriptionFocusReceived();
+};
+
+#endif // LL_LLPANELPICKS_H
diff --git a/indra/newview/llpreviewtexture.cpp b/indra/newview/llpreviewtexture.cpp
index cd7b93aba7..10177c8023 100644
--- a/indra/newview/llpreviewtexture.cpp
+++ b/indra/newview/llpreviewtexture.cpp
@@ -367,7 +367,10 @@ void LLPreviewTexture::reshape(S32 width, S32 height, BOOL called_from_parent)
// add space for dimensions and aspect ratio
S32 info_height = dim_rect.mTop + CLIENT_RECT_VPAD;
-
+ if (getChild<LLLayoutPanel>("buttons_panel")->getVisible())
+ {
+ info_height += getChild<LLLayoutPanel>("buttons_panel")->getRect().getHeight();
+ }
LLRect client_rect(horiz_pad, getRect().getHeight(), getRect().getWidth() - horiz_pad, 0);
client_rect.mTop -= (PREVIEW_HEADER_SIZE + CLIENT_RECT_VPAD);
client_rect.mBottom += PREVIEW_BORDER + CLIENT_RECT_VPAD + info_height ;
@@ -412,6 +415,16 @@ void LLPreviewTexture::openToSave()
mPreviewToSave = TRUE;
}
+void LLPreviewTexture::hideCtrlButtons()
+{
+ getChildView("desc txt")->setVisible(false);
+ getChildView("desc")->setVisible(false);
+ getChild<LLLayoutStack>("preview_stack")->collapsePanel(getChild<LLLayoutPanel>("buttons_panel"), true);
+ getChild<LLLayoutPanel>("buttons_panel")->setVisible(false);
+ getChild<LLComboBox>("combo_aspect_ratio")->setCurrentByIndex(0); //unconstrained
+ reshape(getRect().getWidth(), getRect().getHeight());
+}
+
// static
void LLPreviewTexture::onFileLoadedForSave(BOOL success,
LLViewerFetchedTexture *src_vi,
diff --git a/indra/newview/llpreviewtexture.h b/indra/newview/llpreviewtexture.h
index 9b6a843875..16db51332e 100644
--- a/indra/newview/llpreviewtexture.h
+++ b/indra/newview/llpreviewtexture.h
@@ -67,6 +67,8 @@ public:
static void onSaveAsBtn(void* data);
+ void hideCtrlButtons();
+
/*virtual*/ void setObjectID(const LLUUID& object_id);
protected:
void init();
diff --git a/indra/newview/llremoteparcelrequest.cpp b/indra/newview/llremoteparcelrequest.cpp
index 055ccd5818..f4ace52faa 100644
--- a/indra/newview/llremoteparcelrequest.cpp
+++ b/indra/newview/llremoteparcelrequest.cpp
@@ -213,7 +213,12 @@ void LLRemoteParcelInfoProcessor::regionParcelInfoCoro(std::string url,
if (!status)
{
- observer->setErrorStatus(status.getStatus(), status.getMessage());
+ std::string message = status.getMessage();
+ if (message.empty())
+ {
+ message = status.toString();
+ }
+ observer->setErrorStatus(status.getStatus(), message);
}
else
{
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 0829b1a213..142dc4c46e 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -97,6 +97,7 @@
#include "llfloateravatarpicker.h"
#include "llcallbacklist.h"
#include "llcallingcard.h"
+#include "llclassifiedinfo.h"
#include "llconsole.h"
#include "llcontainerview.h"
#include "llconversationlog.h"
@@ -124,8 +125,6 @@
#include "llpanellogin.h"
#include "llmutelist.h"
#include "llavatarpropertiesprocessor.h"
-#include "llpanelclassified.h"
-#include "llpanelpick.h"
#include "llpanelgrouplandmoney.h"
#include "llpanelgroupnotices.h"
#include "llparcel.h"
@@ -194,6 +193,7 @@
#include "llavatariconctrl.h"
#include "llvoicechannel.h"
#include "llpathfindingmanager.h"
+#include "llremoteparcelrequest.h"
#include "lllogin.h"
#include "llevents.h"
@@ -2652,7 +2652,6 @@ void register_viewer_callbacks(LLMessageSystem* msg)
msg->setHandlerFunc("EventInfoReply", LLEventNotifier::processEventInfoReply);
msg->setHandlerFunc("PickInfoReply", &LLAvatarPropertiesProcessor::processPickInfoReply);
-// msg->setHandlerFunc("ClassifiedInfoReply", LLPanelClassified::processClassifiedInfoReply);
msg->setHandlerFunc("ClassifiedInfoReply", LLAvatarPropertiesProcessor::processClassifiedInfoReply);
msg->setHandlerFunc("ParcelInfoReply", LLRemoteParcelInfoProcessor::processParcelInfoReply);
msg->setHandlerFunc("ScriptDialog", process_script_dialog);
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index 51ee5b6157..0ce82a1297 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -48,6 +48,7 @@
#include "llui.h"
#include "llviewerinventory.h"
#include "llpermissions.h"
+#include "llpreviewtexture.h"
#include "llsaleinfo.h"
#include "llassetstorage.h"
#include "lltextbox.h"
@@ -1215,6 +1216,7 @@ LLTextureCtrl::LLTextureCtrl(const LLTextureCtrl::Params& p)
mNeedsRawImageData( FALSE ),
mValid( TRUE ),
mShowLoadingPlaceholder( TRUE ),
+ mOpenTexPreview(false),
mImageAssetID(p.image_id),
mDefaultImageAssetID(p.default_image_id),
mDefaultImageName(p.default_image_name),
@@ -1471,12 +1473,31 @@ BOOL LLTextureCtrl::handleMouseDown(S32 x, S32 y, MASK mask)
if (!handled && mBorder->parentPointInView(x, y))
{
- showPicker(FALSE);
- //grab textures first...
- LLInventoryModelBackgroundFetch::instance().start(gInventory.findCategoryUUIDForType(LLFolderType::FT_TEXTURE));
- //...then start full inventory fetch.
- LLInventoryModelBackgroundFetch::instance().start();
- handled = TRUE;
+ if (!mOpenTexPreview)
+ {
+ showPicker(FALSE);
+ //grab textures first...
+ LLInventoryModelBackgroundFetch::instance().start(gInventory.findCategoryUUIDForType(LLFolderType::FT_TEXTURE));
+ //...then start full inventory fetch.
+ LLInventoryModelBackgroundFetch::instance().start();
+ handled = TRUE;
+ }
+ else
+ {
+ if (getImageAssetID().notNull())
+ {
+ LLPreviewTexture* preview_texture = LLFloaterReg::showTypedInstance<LLPreviewTexture>("preview_texture", getValue());
+ if (preview_texture && !preview_texture->isDependent())
+ {
+ LLFloater* root_floater = gFloaterView->getParentFloater(this);
+ if (root_floater)
+ {
+ root_floater->addDependentFloater(preview_texture);
+ preview_texture->hideCtrlButtons();
+ }
+ }
+ }
+ }
}
return handled;
diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h
index 3769f43737..fbb38c4464 100644
--- a/indra/newview/lltexturectrl.h
+++ b/indra/newview/lltexturectrl.h
@@ -169,6 +169,8 @@ public:
void setBlankImageAssetID( const LLUUID& id ) { mBlankImageAssetID = id; }
const LLUUID& getBlankImageAssetID() const { return mBlankImageAssetID; }
+ void setOpenTexPreview(bool open_preview) { mOpenTexPreview = open_preview; }
+
void setCaption(const std::string& caption);
void setCanApplyImmediately(BOOL b);
@@ -248,6 +250,8 @@ private:
BOOL mShowLoadingPlaceholder;
std::string mLoadingPlaceholderString;
S32 mLabelWidth;
+ bool mOpenTexPreview;
+ BOOL mBakeTextureEnabled;
};
//////////////////////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/llviewerdisplayname.cpp b/indra/newview/llviewerdisplayname.cpp
new file mode 100644
index 0000000000..cec08c4f15
--- /dev/null
+++ b/indra/newview/llviewerdisplayname.cpp
@@ -0,0 +1,226 @@
+/**
+ * @file llviewerdisplayname.cpp
+ * @brief Wrapper for display name functionality
+ *
+ * $LicenseInfo:firstyear=2010&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$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llviewerdisplayname.h"
+
+// viewer includes
+#include "llagent.h"
+#include "llfloaterprofile.h"
+#include "llfloaterreg.h"
+#include "llviewerregion.h"
+#include "llvoavatar.h"
+
+// library includes
+#include "llavatarnamecache.h"
+#include "llhttpnode.h"
+#include "llnotificationsutil.h"
+#include "llui.h" // getLanguage()
+
+namespace LLViewerDisplayName
+{
+ // Fired when viewer receives server response to display name change
+ set_name_signal_t sSetDisplayNameSignal;
+
+ // Fired when there is a change in the agent's name
+ name_changed_signal_t sNameChangedSignal;
+
+ void addNameChangedCallback(const name_changed_signal_t::slot_type& cb)
+ {
+ sNameChangedSignal.connect(cb);
+ }
+
+ void doNothing() { }
+}
+
+void LLViewerDisplayName::set(const std::string& display_name, const set_name_slot_t& slot)
+{
+ // TODO: simple validation here
+
+ LLViewerRegion* region = gAgent.getRegion();
+ llassert(region);
+ std::string cap_url = region->getCapability("SetDisplayName");
+ if (cap_url.empty())
+ {
+ // this server does not support display names, report error
+ slot(false, "unsupported", LLSD());
+ return;
+ }
+
+ // People API requires both the old and new value to change a variable.
+ // Our display name will be in cache before the viewer's UI is available
+ // to request a change, so we can use direct lookup without callback.
+ LLAvatarName av_name;
+ if (!LLAvatarNameCache::get( gAgent.getID(), &av_name))
+ {
+ slot(false, "name unavailable", LLSD());
+ return;
+ }
+
+ // People API expects array of [ "old value", "new value" ]
+ LLSD change_array = LLSD::emptyArray();
+ change_array.append(av_name.getDisplayName());
+ change_array.append(display_name);
+
+ LL_INFOS() << "Set name POST to " << cap_url << LL_ENDL;
+
+ // Record our caller for when the server sends back a reply
+ sSetDisplayNameSignal.connect(slot);
+
+ // POST the requested change. The sim will not send a response back to
+ // this request directly, rather it will send a separate message after it
+ // communicates with the back-end.
+ LLSD body;
+ body["display_name"] = change_array;
+ LLCoros::instance().launch("LLViewerDisplayName::SetDisplayNameCoro",
+ boost::bind(&LLViewerDisplayName::setDisplayNameCoro, cap_url, body));
+}
+
+void LLViewerDisplayName::setDisplayNameCoro(const std::string& cap_url, const LLSD& body)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("SetDisplayNameCoro", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpHeaders::ptr_t httpHeaders(new LLCore::HttpHeaders);
+
+ // People API can return localized error messages. Indicate our
+ // language preference via header.
+ httpHeaders->append(HTTP_OUT_HEADER_ACCEPT_LANGUAGE, LLUI::getLanguage());
+
+ LLSD result = httpAdapter->postAndSuspend(httpRequest, cap_url, body, httpHeaders);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status)
+ {
+ LL_WARNS() << "Unable to set display name. Status: " << status.toString() << LL_ENDL;
+ LLViewerDisplayName::sSetDisplayNameSignal(false, "", LLSD());
+ LLViewerDisplayName::sSetDisplayNameSignal.disconnect_all_slots();
+ }
+}
+
+class LLSetDisplayNameReply : public LLHTTPNode
+{
+ LOG_CLASS(LLSetDisplayNameReply);
+public:
+ /*virtual*/ void post(
+ LLHTTPNode::ResponsePtr response,
+ const LLSD& context,
+ const LLSD& input) const
+ {
+ LLSD body = input["body"];
+
+ S32 status = body["status"].asInteger();
+ bool success = (status == HTTP_OK);
+ std::string reason = body["reason"].asString();
+ LLSD content = body["content"];
+
+ LL_INFOS() << "status " << status << " reason " << reason << LL_ENDL;
+
+ // If viewer's concept of display name is out-of-date, the set request
+ // will fail with 409 Conflict. If that happens, fetch up-to-date
+ // name information.
+ if (status == HTTP_CONFLICT)
+ {
+ LLUUID agent_id = gAgent.getID();
+ // Flush stale data
+ LLAvatarNameCache::getInstance()->erase( agent_id );
+ // Queue request for new data: nothing to do on callback though...
+ // Note: no need to disconnect the callback as it never gets out of scope
+ LLAvatarNameCache::getInstance()->get(agent_id, boost::bind(&LLViewerDisplayName::doNothing));
+ // Kill name tag, as it is wrong
+ LLVOAvatar::invalidateNameTag( agent_id );
+ }
+
+ // inform caller of result
+ LLViewerDisplayName::sSetDisplayNameSignal(success, reason, content);
+ LLViewerDisplayName::sSetDisplayNameSignal.disconnect_all_slots();
+ }
+};
+
+
+class LLDisplayNameUpdate : public LLHTTPNode
+{
+ /*virtual*/ void post(
+ LLHTTPNode::ResponsePtr response,
+ const LLSD& context,
+ const LLSD& input) const
+ {
+ LLSD body = input["body"];
+ LLUUID agent_id = body["agent_id"];
+ std::string old_display_name = body["old_display_name"];
+ // By convention this record is called "agent" in the People API
+ LLSD name_data = body["agent"];
+
+ // Inject the new name data into cache
+ LLAvatarName av_name;
+ av_name.fromLLSD( name_data );
+
+ LL_INFOS() << "name-update now " << LLDate::now()
+ << " next_update " << LLDate(av_name.mNextUpdate)
+ << LL_ENDL;
+
+ // Name expiration time may be provided in headers, or we may use a
+ // default value
+ // *TODO: get actual headers out of ResponsePtr
+ //LLSD headers = response->mHeaders;
+ LLSD headers;
+ av_name.mExpires =
+ LLAvatarNameCache::getInstance()->nameExpirationFromHeaders(headers);
+
+ LLAvatarNameCache::getInstance()->insert(agent_id, av_name);
+
+ // force name tag to update
+ LLVOAvatar::invalidateNameTag(agent_id);
+
+ LLSD args;
+ args["OLD_NAME"] = old_display_name;
+ args["SLID"] = av_name.getUserName();
+ args["NEW_NAME"] = av_name.getDisplayName();
+ LLNotificationsUtil::add("DisplayNameUpdate", args);
+ if (agent_id == gAgent.getID())
+ {
+ LLViewerDisplayName::sNameChangedSignal();
+ }
+
+ LLFloaterProfile* profile_floater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::findInstance("profile", LLSD().with("id", agent_id)));
+ if (profile_floater)
+ {
+ profile_floater->refreshName();
+ }
+ }
+};
+
+LLHTTPRegistration<LLSetDisplayNameReply>
+ gHTTPRegistrationMessageSetDisplayNameReply(
+ "/message/SetDisplayNameReply");
+
+LLHTTPRegistration<LLDisplayNameUpdate>
+ gHTTPRegistrationMessageDisplayNameUpdate(
+ "/message/DisplayNameUpdate");
diff --git a/indra/newview/llviewerdisplayname.h b/indra/newview/llviewerdisplayname.h
new file mode 100644
index 0000000000..337aaa68b6
--- /dev/null
+++ b/indra/newview/llviewerdisplayname.h
@@ -0,0 +1,55 @@
+/**
+ * @file llviewerdisplayname.h
+ * @brief Wrapper for display name functionality
+ *
+ * $LicenseInfo:firstyear=2010&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$
+ */
+
+#ifndef LLVIEWERDISPLAYNAME_H
+#define LLVIEWERDISPLAYNAME_H
+
+#include <boost/signals2.hpp>
+
+class LLSD;
+class LLUUID;
+
+namespace LLViewerDisplayName
+{
+ typedef boost::signals2::signal<
+ void (bool success, const std::string& reason, const LLSD& content)>
+ set_name_signal_t;
+ typedef set_name_signal_t::slot_type set_name_slot_t;
+
+ typedef boost::signals2::signal<void (void)> name_changed_signal_t;
+ typedef name_changed_signal_t::slot_type name_changed_slot_t;
+
+ // Sends an update to the server to change a display name
+ // and call back when done. May not succeed due to service
+ // unavailable or name not available.
+ void set(const std::string& display_name, const set_name_slot_t& slot);
+
+ void setDisplayNameCoro(const std::string& cap_url, const LLSD& body);
+
+ void addNameChangedCallback(const name_changed_signal_t::slot_type& cb);
+}
+
+#endif // LLVIEWERDISPLAYNAME_H
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index dd03d6cfdd..06a6c5e373 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -57,11 +57,13 @@
#include "llfloatercamera.h"
#include "llfloatercamerapresets.h"
#include "llfloaterchatvoicevolume.h"
+#include "llfloaterclassified.h"
#include "llfloaterconversationlog.h"
#include "llfloaterconversationpreview.h"
#include "llfloatercreatelandmark.h"
#include "llfloaterdeleteprefpreset.h"
#include "llfloaterdestinations.h"
+#include "llfloaterdisplayname.h"
#include "llfloatereditextdaycycle.h"
#include "llfloaterenvironmentadjust.h"
#include "llfloaterexperienceprofile.h"
@@ -111,6 +113,7 @@
#include "llfloaterpreference.h"
#include "llfloaterpreferenceviewadvanced.h"
#include "llfloaterpreviewtrash.h"
+#include "llfloaterprofile.h"
#include "llfloaterproperties.h"
#include "llfloaterregiondebugconsole.h"
#include "llfloaterregioninfo.h"
@@ -141,7 +144,6 @@
#include "llfloateruipreview.h"
#include "llfloatervoiceeffect.h"
#include "llfloaterwebcontent.h"
-#include "llfloaterwebprofile.h"
#include "llfloatervoicevolume.h"
#include "llfloaterwhitelistentry.h"
#include "llfloaterwindowsize.h"
@@ -155,7 +157,7 @@
#include "llmoveview.h"
#include "llfloaterimnearbychat.h"
#include "llpanelblockedlist.h"
-#include "llpanelclassified.h"
+#include "llpanelprofileclassifieds.h"
#include "llpreviewanim.h"
#include "llpreviewgesture.h"
#include "llpreviewnotecard.h"
@@ -228,6 +230,7 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("camera_presets", "floater_camera_presets.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCameraPresets>);
LLFloaterReg::add("chat_voice", "floater_voice_chat_volume.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterChatVoiceVolume>);
LLFloaterReg::add("nearby_chat", "floater_im_session.xml", (LLFloaterBuildFunc)&LLFloaterIMNearbyChat::buildFloater);
+ LLFloaterReg::add("classified", "floater_classified.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterClassified>);
LLFloaterReg::add("compile_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCompileQueue>);
LLFloaterReg::add("conversation", "floater_conversation_log.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterConversationLog>);
LLFloaterReg::add("add_landmark", "floater_create_landmark.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCreateLandmark>);
@@ -275,6 +278,7 @@ void LLViewerFloaterReg::registerFloaters()
LLInspectRemoteObjectUtil::registerFloater();
LLFloaterVoiceVolumeUtil::registerFloater();
LLNotificationsUI::registerFloater();
+ LLFloaterDisplayNameUtil::registerFloater();
LLFloaterReg::add("lagmeter", "floater_lagmeter.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLagMeter>);
LLFloaterReg::add("land_holdings", "floater_land_holdings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLandHoldings>);
@@ -320,7 +324,6 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("prefs_translation", "floater_translation_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTranslationSettings>);
LLFloaterReg::add("prefs_spellchecker", "floater_spellcheck.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSpellCheckerSettings>);
LLFloaterReg::add("prefs_autoreplace", "floater_autoreplace.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAutoReplaceSettings>);
- LLFloaterReg::add("picks", "floater_picks.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSidePanelContainer>);
LLFloaterReg::add("pref_joystick", "floater_joystick.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterJoystick>);
LLFloaterReg::add("preview_anim", "floater_preview_animation.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPreviewAnim>, "preview");
LLFloaterReg::add("preview_conversation", "floater_conversation_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterConversationPreview>);
@@ -367,8 +370,7 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("snapshot", "floater_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSnapshot>);
LLFloaterReg::add("outfit_snapshot", "floater_outfit_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterOutfitSnapshot>);
LLFloaterReg::add("search", "floater_search.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSearch>);
- LLFloaterReg::add("my_profile", "floater_my_web_profile.xml", (LLFloaterBuildFunc)&LLFloaterWebProfile::create);
- LLFloaterReg::add("profile", "floater_web_profile.xml", (LLFloaterBuildFunc)&LLFloaterWebProfile::create);
+ LLFloaterReg::add("profile", "floater_profile.xml",(LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterProfile>);
LLFloaterReg::add("guidebook", "floater_how_to.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHowTo>);
LLFloaterReg::add("big_preview", "floater_big_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterBigPreview>);
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 812f804ea9..661f70972d 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -48,7 +48,7 @@
#include "llmutelist.h"
#include "llnotifications.h"
#include "llnotificationsutil.h"
-#include "llpanelprofile.h"
+#include "llavataractions.h"
#include "llparcel.h"
#include "llpluginclassmedia.h"
#include "llurldispatcher.h"
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 459bbaa00a..ac516b8460 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -3635,6 +3635,11 @@ bool my_profile_visible()
return floaterp && floaterp->isInVisibleChain();
}
+bool picks_tab_visible()
+{
+ return my_profile_visible() && LLAvatarActions::isPickTabSelected(gAgentID);
+}
+
bool enable_freeze_eject(const LLSD& avatar_id)
{
// Use avatar_id if available, otherwise default to right-click avatar
@@ -6328,6 +6333,29 @@ class LLAvatarToggleMyProfile : public view_listener_t
}
};
+class LLAvatarTogglePicks : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLFloater * instance = LLAvatarActions::getProfileFloater(gAgent.getID());
+ if (LLFloater::isMinimized(instance) || (instance && !instance->hasFocus() && !instance->getIsChrome()))
+ {
+ instance->setMinimized(FALSE);
+ instance->setFocus(TRUE);
+ LLAvatarActions::showPicks(gAgent.getID());
+ }
+ else if (picks_tab_visible())
+ {
+ instance->closeFloater();
+ }
+ else
+ {
+ LLAvatarActions::showPicks(gAgent.getID());
+ }
+ return true;
+ }
+};
+
class LLAvatarToggleSearch : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -6798,6 +6826,15 @@ class LLShowAgentProfile : public view_listener_t
}
};
+class LLShowAgentProfilePicks : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLAvatarActions::showPicks(gAgent.getID());
+ return true;
+ }
+};
+
class LLToggleAgentProfile : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -9521,12 +9558,14 @@ void initialize_menus()
enable.add("Avatar.EnableCall", boost::bind(&LLAvatarActions::canCall));
view_listener_t::addMenu(new LLAvatarReportAbuse(), "Avatar.ReportAbuse");
view_listener_t::addMenu(new LLAvatarToggleMyProfile(), "Avatar.ToggleMyProfile");
+ view_listener_t::addMenu(new LLAvatarTogglePicks(), "Avatar.TogglePicks");
view_listener_t::addMenu(new LLAvatarToggleSearch(), "Avatar.ToggleSearch");
view_listener_t::addMenu(new LLAvatarResetSkeleton(), "Avatar.ResetSkeleton");
view_listener_t::addMenu(new LLAvatarEnableResetSkeleton(), "Avatar.EnableResetSkeleton");
view_listener_t::addMenu(new LLAvatarResetSkeletonAndAnimations(), "Avatar.ResetSkeletonAndAnimations");
view_listener_t::addMenu(new LLAvatarResetSelfSkeletonAndAnimations(), "Avatar.ResetSelfSkeletonAndAnimations");
enable.add("Avatar.IsMyProfileOpen", boost::bind(&my_profile_visible));
+ enable.add("Avatar.IsPicksTabOpen", boost::bind(&picks_tab_visible));
commit.add("Avatar.OpenMarketplace", boost::bind(&LLWeb::loadURLExternal, gSavedSettings.getString("MarketplaceURL")));
@@ -9603,6 +9642,7 @@ void initialize_menus()
view_listener_t::addMenu(new LLToggleSpeak(), "ToggleSpeak");
view_listener_t::addMenu(new LLPromptShowURL(), "PromptShowURL");
view_listener_t::addMenu(new LLShowAgentProfile(), "ShowAgentProfile");
+ view_listener_t::addMenu(new LLShowAgentProfilePicks(), "ShowAgentProfilePicks");
view_listener_t::addMenu(new LLToggleAgentProfile(), "ToggleAgentProfile");
view_listener_t::addMenu(new LLToggleControl(), "ToggleControl");
view_listener_t::addMenu(new LLToggleShaderControl(), "ToggleShaderControl");
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index b282a2b90c..f48543822a 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -266,14 +266,13 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)
return;
}
- LLWorld *world_inst = LLWorld::getInstance(); // Not a singleton!
- if (!world_inst)
+ if (!LLWorld::instanceExists())
{
LL_WARNS("AppInit", "Capabilities") << "Attempting to get capabilities, but world no longer exists!" << LL_ENDL;
return;
}
- regionp = world_inst->getRegionFromHandle(regionHandle);
+ regionp = LLWorld::getInstance()->getRegionFromHandle(regionHandle);
if (!regionp) //region was removed
{
LL_WARNS("AppInit", "Capabilities") << "Attempting to get capabilities for region that no longer exists!" << LL_ENDL;
@@ -321,7 +320,6 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)
regionp = NULL;
impl = NULL;
- world_inst = NULL;
result = httpAdapter->postAndSuspend(httpRequest, url, capabilityNames);
if (STATE_WORLD_INIT > LLStartUp::getStartupState())
@@ -332,17 +330,36 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)
if (LLApp::isExiting() || gDisconnected)
{
+ LL_DEBUGS("AppInit", "Capabilities") << "Shutting down" << LL_ENDL;
return;
}
- world_inst = LLWorld::getInstance();
- if (!world_inst)
+ if (!result.isMap() || result.has("error"))
+ {
+ LL_WARNS("AppInit", "Capabilities") << "Malformed response" << LL_ENDL;
+ // setup for retry.
+ continue;
+ }
+
+ LLSD httpResults = result["http_result"];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+ if (!status)
+ {
+ LL_WARNS("AppInit", "Capabilities") << "HttpStatus error " << LL_ENDL;
+ // setup for retry.
+ continue;
+ }
+
+ // remove the http_result from the llsd
+ result.erase("http_result");
+
+ if (!LLWorld::instanceExists())
{
LL_WARNS("AppInit", "Capabilities") << "Received capabilities, but world no longer exists!" << LL_ENDL;
return;
}
- regionp = world_inst->getRegionFromHandle(regionHandle);
+ regionp = LLWorld::getInstance()->getRegionFromHandle(regionHandle);
if (!regionp) //region was removed
{
LL_WARNS("AppInit", "Capabilities") << "Received capabilities for region that no longer exists!" << LL_ENDL;
@@ -351,7 +368,7 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)
impl = regionp->getRegionImplNC();
- ++impl->mSeedCapAttempts;
+ ++(impl->mSeedCapAttempts);
if (id != impl->mHttpResponderID) // region is no longer referring to this request
{
@@ -360,25 +377,6 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)
continue;
}
- if (!result.isMap() || result.has("error"))
- {
- LL_WARNS("AppInit", "Capabilities") << "Malformed response" << LL_ENDL;
- // setup for retry.
- continue;
- }
-
- LLSD httpResults = result["http_result"];
- LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
- if (!status)
- {
- LL_WARNS("AppInit", "Capabilities") << "HttpStatus error " << LL_ENDL;
- // setup for retry.
- continue;
- }
-
- // remove the http_result from the llsd
- result.erase("http_result");
-
LLSD::map_const_iterator iter;
for (iter = result.beginMap(); iter != result.endMap(); ++iter)
{
@@ -3002,6 +3000,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
capabilityNames.append("AcceptFriendship");
capabilityNames.append("AcceptGroupInvite"); // ReadOfflineMsgs recieved messages only!!!
capabilityNames.append("AgentPreferences");
+ capabilityNames.append("AgentProfile");
capabilityNames.append("AgentState");
capabilityNames.append("AttachmentResources");
capabilityNames.append("AvatarPickerSearch");
@@ -3096,6 +3095,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
capabilityNames.append("UpdateScriptTask");
capabilityNames.append("UpdateSettingsAgentInventory");
capabilityNames.append("UpdateSettingsTaskInventory");
+ capabilityNames.append("UploadAgentProfileImage");
capabilityNames.append("UploadBakedTexture");
capabilityNames.append("UserInfo");
capabilityNames.append("ViewerAsset");
diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
index ce7432964e..815d8e9486 100644
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -1261,7 +1261,8 @@ void LLViewerTextureList::decodeAllImages(F32 max_time)
BOOL LLViewerTextureList::createUploadFile(const std::string& filename,
const std::string& out_filename,
- const U8 codec)
+ const U8 codec,
+ const S32 max_image_dimentions)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
// Load the image
@@ -1290,7 +1291,7 @@ BOOL LLViewerTextureList::createUploadFile(const std::string& filename,
return FALSE;
}
// Convert to j2c (JPEG2000) and save the file locally
- LLPointer<LLImageJ2C> compressedImage = convertToUploadFile(raw_image);
+ LLPointer<LLImageJ2C> compressedImage = convertToUploadFile(raw_image, max_image_dimentions);
if (compressedImage.isNull())
{
image->setLastError("Couldn't convert the image to jpeg2000.");
@@ -1315,10 +1316,10 @@ BOOL LLViewerTextureList::createUploadFile(const std::string& filename,
}
// note: modifies the argument raw_image!!!!
-LLPointer<LLImageJ2C> LLViewerTextureList::convertToUploadFile(LLPointer<LLImageRaw> raw_image)
+LLPointer<LLImageJ2C> LLViewerTextureList::convertToUploadFile(LLPointer<LLImageRaw> raw_image, const S32 max_image_dimentions)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- raw_image->biasedScaleToPowerOfTwo(LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT);
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
+ raw_image->biasedScaleToPowerOfTwo(max_image_dimentions);
LLPointer<LLImageJ2C> compressedImage = new LLImageJ2C();
if (gSavedSettings.getBOOL("LosslessJ2CUpload") &&
diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h
index fead2e52b2..6fb0d3552e 100644
--- a/indra/newview/llviewertexturelist.h
+++ b/indra/newview/llviewertexturelist.h
@@ -92,8 +92,11 @@ class LLViewerTextureList
friend class LLLocalBitmap;
public:
- static BOOL createUploadFile(const std::string& filename, const std::string& out_filename, const U8 codec);
- static LLPointer<LLImageJ2C> convertToUploadFile(LLPointer<LLImageRaw> raw_image);
+ static BOOL createUploadFile(const std::string& filename,
+ const std::string& out_filename,
+ const U8 codec,
+ const S32 max_image_dimentions = LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT);
+ static LLPointer<LLImageJ2C> convertToUploadFile(LLPointer<LLImageRaw> raw_image, const S32 max_image_dimentions = LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT);
static void processImageNotInDatabase( LLMessageSystem *msg, void **user_data );
static void receiveImageHeader(LLMessageSystem *msg, void **user_data);
static void receiveImagePacket(LLMessageSystem *msg, void **user_data);
diff --git a/indra/newview/llwebprofile.cpp b/indra/newview/llwebprofile.cpp
index ff899fe895..3cc82621c4 100644
--- a/indra/newview/llwebprofile.cpp
+++ b/indra/newview/llwebprofile.cpp
@@ -36,7 +36,7 @@
#include "llstring.h"
// newview
-#include "llpanelprofile.h" // for getProfileURL(). FIXME: move the method to LLAvatarActions
+#include "llavataractions.h" // for getProfileURL()
#include "llviewermedia.h" // FIXME: don't use LLViewerMedia internals
#include "llcorehttputil.h"
diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml
index 7beb013fba..1085972d9e 100644
--- a/indra/newview/skins/default/colors.xml
+++ b/indra/newview/skins/default/colors.xml
@@ -886,6 +886,22 @@
name="PanelNotificationListItem"
value="0.3 0.3 0.3 .3" />
+ <!-- profiles -->
+ <color
+ name="StatusUserOnline"
+ reference="White" />
+ <color
+ name="StatusUserOffline"
+ reference="LtGray_35" />
+ <!-- Groups visible in own profiles -->
+ <color
+ name="GroupVisibleInProfile"
+ reference="TextBgFocusColor" />
+ <color
+ name="GroupHiddenInProfile"
+ reference="Gray" />
+
+
<!-- Generic color names (legacy) -->
<color
name="white"
diff --git a/indra/newview/skins/default/textures/icons/CopyBright.png b/indra/newview/skins/default/textures/icons/CopyBright.png
new file mode 100644
index 0000000000..8d21c47295
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/CopyBright.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Profile_Friend_Offline.png b/indra/newview/skins/default/textures/icons/Profile_Friend_Offline.png
new file mode 100644
index 0000000000..aeba6b70f7
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Profile_Friend_Offline.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Profile_Friend_Online.png b/indra/newview/skins/default/textures/icons/Profile_Friend_Online.png
new file mode 100644
index 0000000000..d668fd8dfa
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Profile_Friend_Online.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Profile_Perm_Find_Disabled.png b/indra/newview/skins/default/textures/icons/Profile_Perm_Find_Disabled.png
new file mode 100644
index 0000000000..8f8caa10d8
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Profile_Perm_Find_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Profile_Perm_Find_Enabled.png b/indra/newview/skins/default/textures/icons/Profile_Perm_Find_Enabled.png
new file mode 100644
index 0000000000..42a209dda5
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Profile_Perm_Find_Enabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Profile_Perm_Objects_Disabled.png b/indra/newview/skins/default/textures/icons/Profile_Perm_Objects_Disabled.png
new file mode 100644
index 0000000000..644edf0ef6
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Profile_Perm_Objects_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Profile_Perm_Objects_Enabled.png b/indra/newview/skins/default/textures/icons/Profile_Perm_Objects_Enabled.png
new file mode 100644
index 0000000000..629c05ecb8
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Profile_Perm_Objects_Enabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Profile_Perm_Online_Disabled.png b/indra/newview/skins/default/textures/icons/Profile_Perm_Online_Disabled.png
new file mode 100644
index 0000000000..ecf66c0ee1
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Profile_Perm_Online_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Profile_Perm_Online_Enabled.png b/indra/newview/skins/default/textures/icons/Profile_Perm_Online_Enabled.png
new file mode 100644
index 0000000000..26123938fa
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Profile_Perm_Online_Enabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_off.png b/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_off.png
new file mode 100644
index 0000000000..3a2ed399b2
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_off_pressed.png b/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_off_pressed.png
new file mode 100644
index 0000000000..789f59a491
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_off_pressed.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_on.png b/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_on.png
new file mode 100644
index 0000000000..4fb56c389c
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_on.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_on_pressed.png b/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_on_pressed.png
new file mode 100644
index 0000000000..ae04a256a4
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_on_pressed.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index e9ef888a7f..0d0fc5c58e 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -191,6 +191,7 @@ with the same filename but different name
<texture name="Conv_log_inbox" file_name="icons/Conv_log_inbox.png" preload="false" />
<texture name="Copy" file_name="icons/Copy.png" preload="false" />
+ <texture name="CopyBright" file_name="icons/CopyBright.png" preload="false" />
<texture name="DisclosureArrow_Opened_Off" file_name="widgets/DisclosureArrow_Opened_Off.png" preload="true" />
@@ -512,6 +513,19 @@ with the same filename but different name
<texture name="Play_Over" file_name="icons/Play_Over.png" preload="false" />
<texture name="Play_Press" file_name="icons/Play_Press.png" preload="false" />
+ <texture name="Profile_Group_Visibility_Off" file_name="icons/profile_group_visibility_eye_off.png" preload="true"/>
+ <texture name="Profile_Group_Visibility_Off_Pressed" file_name="icons/profile_group_visibility_eye_off_pressed.png" preload="true"/>
+ <texture name="Profile_Group_Visibility_On" file_name="icons/profile_group_visibility_eye_on.png" preload="true"/>
+ <texture name="Profile_Group_Visibility_On_Pressed" file_name="icons/profile_group_visibility_eye_on_pressed.png" preload="true"/>
+ <texture name="Profile_Friend_Offline" file_name="icons/Profile_Friend_Offline.png" preload="true"/>
+ <texture name="Profile_Friend_Online" file_name="icons/Profile_Friend_Online.png" preload="true"/>
+ <texture name="Profile_Perm_Find_Disabled" file_name="icons/Profile_Perm_Find_Disabled.png" preload="true"/>
+ <texture name="Profile_Perm_Find_Enabled" file_name="icons/Profile_Perm_Find_Enabled.png" preload="true"/>
+ <texture name="Profile_Perm_Objects_Disabled" file_name="icons/Profile_Perm_Objects_Disabled.png" preload="true"/>
+ <texture name="Profile_Perm_Objects_Enabled" file_name="icons/Profile_Perm_Objects_Enabled.png" preload="true"/>
+ <texture name="Profile_Perm_Online_Disabled" file_name="icons/Profile_Perm_Online_Disabled.png" preload="true"/>
+ <texture name="Profile_Perm_Online_Enabled" file_name="icons/Profile_Perm_Online_Enabled.png" preload="true"/>
+
<texture name="ProgressBar" file_name="widgets/ProgressBar.png" preload="true" scale.left="4" scale.top="11" scale.right="48" scale.bottom="3" />
<texture name="ProgressBarSolid" file_name="widgets/ProgressBarSolid.png" preload="true" scale.left="4" scale.top="11" scale.right="48" scale.bottom="3" />
<texture name="ProgressTrack" file_name="widgets/ProgressTrack.png" preload="true" scale.left="4" scale.top="13" scale.right="148" scale.bottom="2" />
diff --git a/indra/newview/skins/default/xui/da/panel_me.xml b/indra/newview/skins/default/xui/da/panel_me.xml
deleted file mode 100644
index f98ced5f91..0000000000
--- a/indra/newview/skins/default/xui/da/panel_me.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="Min profil" name="panel_me">
- <tab_container name="tabs">
- <panel label="MIN PROFIL" name="panel_profile"/>
- <panel label="MINE FAVORITTER" name="panel_picks"/>
- </tab_container>
-</panel>
diff --git a/indra/newview/skins/default/xui/da/panel_side_tray.xml b/indra/newview/skins/default/xui/da/panel_side_tray.xml
deleted file mode 100644
index 66c3e69904..0000000000
--- a/indra/newview/skins/default/xui/da/panel_side_tray.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<!-- Side tray cannot show background because it is always
- partially on screen to hold tab buttons. -->
-<side_tray name="sidebar">
- <sidetray_tab description="Åbn/luk sidebar" name="sidebar_openclose" tab_title="Åbn/luk sidebar"/>
- <sidetray_tab description="Hjem." name="sidebar_home" tab_title="Hjem">
- <panel label="hjem" name="panel_home"/>
- </sidetray_tab>
- <sidetray_tab description="Redigér din profile og favoritter." name="sidebar_me" tab_title="Min profil">
- <panel_container name="panel_container">
- <panel label="Mig" name="panel_me"/>
- </panel_container>
- </sidetray_tab>
- <sidetray_tab description="Find venner, kontakter og personer tæt på." name="sidebar_people" tab_title="Personer">
- <panel_container name="panel_container">
- <panel label="Gruppe profil" name="panel_group_info_sidetray"/>
- <panel label="Blokerede beboere og objekter" name="panel_block_list_sidetray"/>
- </panel_container>
- </sidetray_tab>
- <sidetray_tab description="Find steder du vil hen og steder du har været før." label="Steder" name="sidebar_places" tab_title="Steder">
- <panel label="Steder" name="panel_places"/>
- </sidetray_tab>
- <sidetray_tab description="Browse din beholdning." name="sidebar_inventory" tab_title="Min beholdning">
- <panel label="Redigér beholdning" name="sidepanel_inventory"/>
- </sidetray_tab>
- <sidetray_tab description="Ændre dit nuværende udseende" name="sidebar_appearance" tab_title="Mit udseende">
- <panel label="Redigér udseende" name="sidepanel_appearance"/>
- </sidetray_tab>
-</side_tray>
diff --git a/indra/newview/skins/default/xui/de/floater_preview_texture.xml b/indra/newview/skins/default/xui/de/floater_preview_texture.xml
index eacd11c3e6..b386d0288c 100644
--- a/indra/newview/skins/default/xui/de/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/de/floater_preview_texture.xml
@@ -6,42 +6,23 @@
<floater.string name="Copy">
In Inventar kopieren
</floater.string>
- <text name="desc txt">
- Beschreibung:
- </text>
- <text name="dimensions">
- [WIDTH]px x [HEIGHT]px
- </text>
- <text name="aspect_ratio">
- Vorschau Seitenverhältnis
- </text>
- <combo_box name="combo_aspect_ratio" tool_tip="Mit einem vordefinierten Seitenverhältnis anzeigen">
- <combo_item name="Unconstrained">
- keines
- </combo_item>
- <combo_item name="1:1" tool_tip="Gruppeninsignien oder Beschreibung">
- 1:1
- </combo_item>
- <combo_item name="4:3" tool_tip="[SECOND_LIFE]-Profil">
- 4:3
- </combo_item>
- <combo_item name="10:7" tool_tip="Anzeigen und Suchergebnisse, Landmarken">
- 10:7
- </combo_item>
- <combo_item name="3:2" tool_tip="Über Land">
- 3:2
- </combo_item>
- <combo_item name="16:10">
- 16:10
- </combo_item>
- <combo_item name="16:9" tool_tip="Profilauswahl">
- 16:9
- </combo_item>
- <combo_item name="2:1">
- 2:1
- </combo_item>
- </combo_box>
- <button label="OK" name="Keep"/>
- <button label="Verwerfen" name="Discard"/>
- <button label="Speichern unter" name="save_tex_btn"/>
+ <layout_stack name="preview_stack">
+ <layout_panel name="texture_panel">
+ <text name="desc txt">
+ Beschreibung:
+ </text>
+ <text name="dimensions">
+ [WIDTH]px x [HEIGHT]px
+ </text>
+ <text name="aspect_ratio">
+ Vorschau Seitenverhältnis
+ </text>
+ <combo_box name="combo_aspect_ratio" tool_tip="Mit einem vordefinierten Seitenverhältnis anzeigen"/>
+ </layout_panel>
+ <layout_panel name="buttons_panel">
+ <button label="OK" name="Keep"/>
+ <button label="Verwerfen" name="Discard"/>
+ <button label="Speichern unter" name="save_tex_btn"/>
+ </layout_panel>
+ </layout_stack>
</floater>
diff --git a/indra/newview/skins/default/xui/de/floater_profile.xml b/indra/newview/skins/default/xui/de/floater_profile.xml
new file mode 100644
index 0000000000..eb03463930
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/floater_profile.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="avatarinfo" title="Profil">
+ <panel name="panel_profile_view">
+ <tab_container name="panel_profile_tabs">
+ <panel label="Second Life" name="panel_profile_secondlife"/>
+ <panel label="Web" name="panel_profile_web"/>
+ <panel label="Interessen" name="panel_profile_interests"/>
+ <panel label="Auswahlen" name="panel_profile_picks"/>
+ <panel label="Anzeige" name="panel_profile_classifieds"/>
+ <panel label="Echtes Leben" name="panel_profile_firstlife"/>
+ <panel label="Hinweise" name="panel_profile_notes"/>
+ </tab_container>
+ <button label="OK" name="ok_btn" tool_tip="Profiländerungen speichern und schließen"/>
+ <button label="Abbrechen" label_selected="Abbrechen" name="cancel_btn"/>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/de/floater_snapshot.xml b/indra/newview/skins/default/xui/de/floater_snapshot.xml
index f0152ad8cd..636f320a95 100644
--- a/indra/newview/skins/default/xui/de/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/de/floater_snapshot.xml
@@ -6,6 +6,9 @@
<string name="postcard_progress_str">
E-Mail senden
</string>
+ <string name="facebook_progress_str">
+ Auf Facebook posten
+ </string>
<string name="profile_progress_str">
Posten
</string>
@@ -15,6 +18,9 @@
<string name="local_progress_str">
Speichern auf Computer
</string>
+ <string name="facebook_succeeded_str">
+ Bild hochgeladen
+ </string>
<string name="profile_succeeded_str">
Bild hochgeladen
</string>
@@ -27,6 +33,9 @@
<string name="local_succeeded_str">
Auf Computer gespeichert!
</string>
+ <string name="facebook_failed_str">
+ Fehler beim Hochladen des Bilds in Ihre Facebook-Chronik.
+ </string>
<string name="profile_failed_str">
Fehler beim Hochladen des Bilds in Ihr Profil.
</string>
diff --git a/indra/newview/skins/default/xui/de/menu_name_field.xml b/indra/newview/skins/default/xui/de/menu_name_field.xml
new file mode 100644
index 0000000000..1d293c9361
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/menu_name_field.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="CopyMenu">
+ <menu_item_call label="Anzeigenamen kopieren" name="copy_display"/>
+ <menu_item_call label="Agent-Namen kopieren" name="copy_name"/>
+ <menu_item_call label="Agent-ID kopieren" name="copy_id"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/de/notifications.xml b/indra/newview/skins/default/xui/de/notifications.xml
index 359a835630..a72784f70b 100644
--- a/indra/newview/skins/default/xui/de/notifications.xml
+++ b/indra/newview/skins/default/xui/de/notifications.xml
@@ -2698,6 +2698,9 @@ Wählen Sie eine kleinere Landfläche.
<notification name="SystemMessage">
[MESSAGE]
</notification>
+ <notification name="FacebookConnect">
+ [MESSAGE]
+ </notification>
<notification name="FlickrConnect">
[MESSAGE]
</notification>
diff --git a/indra/newview/skins/default/xui/de/panel_edit_classified.xml b/indra/newview/skins/default/xui/de/panel_edit_classified.xml
index bd270697ea..8adacb4a5f 100644
--- a/indra/newview/skins/default/xui/de/panel_edit_classified.xml
+++ b/indra/newview/skins/default/xui/de/panel_edit_classified.xml
@@ -46,7 +46,7 @@
<layout_panel name="save_changes_btn_lp">
<button label="[LABEL]" name="save_changes_btn"/>
</layout_panel>
- <layout_panel name="show_on_map_btn_lp">
+ <layout_panel name="cancel_btn_lp">
<button label="Abbrechen" name="cancel_btn"/>
</layout_panel>
</layout_stack>
diff --git a/indra/newview/skins/default/xui/de/panel_facebook_friends.xml b/indra/newview/skins/default/xui/de/panel_facebook_friends.xml
index f6a8fda23e..1a0bbc7d30 100644
--- a/indra/newview/skins/default/xui/de/panel_facebook_friends.xml
+++ b/indra/newview/skins/default/xui/de/panel_facebook_friends.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<panel name="panel_facebook_friends">
- <string name="facebook_friends_empty" value="Sie haben gegenwärtig keine Facebook-Freunde, die gleichzeitig Einwohner von Second Life sind. Laden Sie Ihre Facebook-Freunde ein, Second Life beizutreten!"/>
- <string name="facebook_friends_no_connected" value="Sie sind gegenwärtig nicht mit Facebook verbunden. Um eine Verbindung herzustellen und diese Funktion zu aktivieren, gehen Sie zur Registerkarte „Status“."/>
+ <string name="facebook_friends_empty" value="Sie haben gegenwärtig keine Facebook-Freunde, die ebenfalls Second Life-Einwohner sind. Laden Sie Ihre Facebook-Freunde ein, Second Life beizutreten!"/>
+ <string name="facebook_friends_no_connected" value="Sie sind gegenwärtig nicht mit Facebook verbunden. Um eine Verbindung herzustellen und diese Funktion zu aktivieren, wechseln Sie zur Registerkarte &quot;Status&quot;."/>
<accordion name="friends_accordion">
<accordion_tab name="tab_second_life_friends" title="SL-Freunde"/>
<accordion_tab name="tab_suggested_friends" title="Diese Personen als SL-Freunde hinzufügen"/>
diff --git a/indra/newview/skins/default/xui/de/panel_facebook_photo.xml b/indra/newview/skins/default/xui/de/panel_facebook_photo.xml
index bc48931129..fac9fe9984 100644
--- a/indra/newview/skins/default/xui/de/panel_facebook_photo.xml
+++ b/indra/newview/skins/default/xui/de/panel_facebook_photo.xml
@@ -2,10 +2,10 @@
<panel name="panel_facebook_photo">
<combo_box name="resolution_combobox" tool_tip="Bildauflösung">
<combo_box.item label="Aktuelles Fenster" name="CurrentWindow"/>
- <combo_box.item label="640x480" name="640x480"/>
- <combo_box.item label="800x600" name="800x600"/>
- <combo_box.item label="1024x768" name="1024x768"/>
- <combo_box.item label="1200x630" name="1200x630"/>
+ <combo_box.item label="640 x 480" name="640x480"/>
+ <combo_box.item label="800 x 600" name="800x600"/>
+ <combo_box.item label="1024 x 768" name="1024x768"/>
+ <combo_box.item label="1200 x 630" name="1200x630"/>
</combo_box>
<combo_box name="filters_combobox" tool_tip="Bildfilter">
<combo_box.item label="Kein Filter" name="NoFilter"/>
diff --git a/indra/newview/skins/default/xui/de/panel_facebook_status.xml b/indra/newview/skins/default/xui/de/panel_facebook_status.xml
index 23c9d3b75f..1fefef548e 100644
--- a/indra/newview/skins/default/xui/de/panel_facebook_status.xml
+++ b/indra/newview/skins/default/xui/de/panel_facebook_status.xml
@@ -13,7 +13,7 @@
</text>
</panel>
<text name="status_caption_label">
- Was machst du gerade?
+ Was machen Sie gerade?
</text>
<button label="Posten" name="post_status_btn"/>
<button label="Abbrechen" name="cancel_status_btn"/>
diff --git a/indra/newview/skins/default/xui/de/panel_group_general.xml b/indra/newview/skins/default/xui/de/panel_group_general.xml
index 9fec5a242d..e50124c37e 100644
--- a/indra/newview/skins/default/xui/de/panel_group_general.xml
+++ b/indra/newview/skins/default/xui/de/panel_group_general.xml
@@ -46,7 +46,7 @@ Bewegen Sie die Maus über die Optionen, um weitere Informationen anzuzeigen.
<check_box label="Jeder kann beitreten" name="open_enrollement" tool_tip="Festlegen, ob der Gruppenbeitritt ohne Einladung zulässig ist."/>
<check_box label="Kosten für Beitritt" name="check_enrollment_fee" tool_tip="Festlegen, ob Neumitglieder eine Beitrittsgebühr zahlen müssen"/>
<spinner label="L$" name="spin_enrollment_fee" tool_tip="Wenn Beitrittsgebühr aktiviert ist, müssen neue Mitglieder diesen Betrag zahlen."/>
- <combo_box name="group_mature_check" tool_tip="Inhaltseinstufungen kennzeichnen die in einer Gruppe zulässigen Inhalte und Verhaltensweisen">
+ <combo_box name="group_mature_check" tool_tip="Legt fest, ob Ihre Gruppe als moderat eingestufte Informationen enthält">
<combo_item name="select_mature">
- Inhaltseinstufung auswählen -
</combo_item>
diff --git a/indra/newview/skins/default/xui/de/panel_group_list_item_short.xml b/indra/newview/skins/default/xui/de/panel_group_list_item_short.xml
new file mode 100644
index 0000000000..fc911a64df
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_group_list_item_short.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="group_list_item">
+ <text name="group_name" value="Unbekannt"/>
+ <button name="info_btn" tool_tip="Mehr Infos"/>
+ <button name="profile_btn" tool_tip="Profil anzeigen"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_me.xml b/indra/newview/skins/default/xui/de/panel_me.xml
deleted file mode 100644
index f49446fbbf..0000000000
--- a/indra/newview/skins/default/xui/de/panel_me.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="Mein Profil" name="panel_me">
- <panel label="MEINE AUSWAHLEN" name="panel_picks"/>
-</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_people.xml b/indra/newview/skins/default/xui/de/panel_people.xml
index 81de679429..e4a4c1033e 100644
--- a/indra/newview/skins/default/xui/de/panel_people.xml
+++ b/indra/newview/skins/default/xui/de/panel_people.xml
@@ -40,6 +40,7 @@ Sie suchen nach Leuten? Verwenden Sie die [secondlife:///app/worldmap Karte].
<accordion name="friends_accordion">
<accordion_tab name="tab_online" title="Online"/>
<accordion_tab name="tab_all" title="Alle"/>
+ <accordion_tab name="tab_suggested_friends" title="Potenzielle Freunde"/>
</accordion>
</panel>
<panel label="GRUPPEN" name="groups_panel">
diff --git a/indra/newview/skins/default/xui/de/panel_profile_classified.xml b/indra/newview/skins/default/xui/de/panel_profile_classified.xml
new file mode 100644
index 0000000000..5c11a01977
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_profile_classified.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_profile_classified">
+ <panel.string name="type_mature">
+ Moderat
+ </panel.string>
+ <panel.string name="type_pg">
+ Generelle Inhalte
+ </panel.string>
+ <panel.string name="l$_price">
+ L$[PRICE]
+ </panel.string>
+ <panel.string name="click_through_text_fmt">
+ [TELEPORT] Teleportieren, [MAP] Karten, [PROFILE] Profil
+ </panel.string>
+ <panel.string name="date_fmt">
+ [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt]
+ </panel.string>
+ <panel.string name="auto_renew_on">
+ Aktiviert
+ </panel.string>
+ <panel.string name="auto_renew_off">
+ Deaktiviert
+ </panel.string>
+ <panel.string name="location_notice">
+ (wird nach dem Speichern aktualisiert)
+ </panel.string>
+ <string name="publish_label">
+ Veröffentlichen
+ </string>
+ <string name="save_label">
+ Speichern
+ </string>
+ <scroll_container name="profile_scroll">
+ <panel name="info_scroll_content_panel">
+ <icon label="" name="edit_icon" tool_tip="Klicken, um ein Bild auszuwählen"/>
+ <layout_stack name="info_panel">
+ <layout_panel name="main_info_panel">
+ <text_editor name="classified_name">
+ [name]
+ </text_editor>
+ <text name="classified_location_label" value="Standort:"/>
+ <text_editor name="classified_location" value="[loading...]"/>
+ <text name="content_type_label" value="Inhaltsart:"/>
+ <text_editor name="content_type" value="[content type]"/>
+ <text name="category_label" value="Kategorie:"/>
+ <text_editor name="category" value="[category]"/>
+ <text name="creation_date_label" value="Erstellungsdatum:"/>
+ <text_editor name="creation_date" tool_tip="Erstellungsdatum" value="[date]"/>
+ <text name="price_for_listing_label" value="Preis für Auflistung:"/>
+ <text_editor name="price_for_listing" tool_tip="Preis für Auflistung.">
+ [PRICE]
+ </text_editor>
+ </layout_panel>
+ <layout_panel name="clickthrough_layout_panel">
+ <text name="click_through_label" value="Klicks:"/>
+ <text_editor name="click_through_text" tool_tip="Click-Through-Daten" value="[clicks]"/>
+ </layout_panel>
+ <layout_panel name="auto_renew_layout_panel">
+ <text name="auto_renew_label" value="Autom. erneuern:"/>
+ <text name="auto_renew" value="Aktiviert"/>
+ </layout_panel>
+ <layout_panel name="descr_layout_panel">
+ <text name="classified_desc_label" value="Beschreibung:"/>
+ <text_editor name="classified_desc" value="[description]"/>
+ </layout_panel>
+ </layout_stack>
+ <panel name="edit_panel">
+ <text name="Name:">
+ Titel:
+ </text>
+ <text name="description_label">
+ Beschreibung:
+ </text>
+ <text name="location_label">
+ Standort:
+ </text>
+ <text name="classified_location_edit">
+ Laden...
+ </text>
+ <button label="Aktuellen Standort verwenden" name="set_to_curr_location_btn"/>
+ <text name="category_label" value="Kategorie:"/>
+ <text name="content_type_label" value="Inhaltsart:"/>
+ <icons_combo_box label="Generelle Inhalte" name="content_type_edit">
+ <icons_combo_box.item label="Moderate Inhalte" name="mature_ci" value="Adult"/>
+ <icons_combo_box.item label="Generelle Inhalte" name="pg_ci" value="PG"/>
+ </icons_combo_box>
+ <check_box label="Jede Woche automatisch erneuern" name="auto_renew_edit"/>
+ <text name="price_for_listing_edit_label" value="Preis für Auflistung:"/>
+ <spinner label="L$" name="price_for_listing_edit" tool_tip="Preis für Auflistung." value="50"/>
+ </panel>
+ </panel>
+ </scroll_container>
+ <layout_stack name="edit_btns_pnl">
+ <layout_panel name="teleport_btn_lp">
+ <button label="Teleportieren" name="teleport_btn"/>
+ </layout_panel>
+ <layout_panel name="map_btn_lp">
+ <button label="Karte" name="show_on_map_btn"/>
+ </layout_panel>
+ <layout_panel name="edit_btn_lp">
+ <button label="Bearbeiten" name="edit_btn"/>
+ </layout_panel>
+ <layout_panel name="save_btn_lp">
+ <button label="[LABEL]" name="save_changes_btn"/>
+ </layout_panel>
+ <layout_panel name="cancel_btn_lp">
+ <button label="Abbrechen" name="cancel_btn"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_profile_classifieds.xml b/indra/newview/skins/default/xui/de/panel_profile_classifieds.xml
new file mode 100644
index 0000000000..83549cb138
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_profile_classifieds.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Anzeige" name="panel_profile_classifieds">
+ <string name="no_classifieds" value="Keine Anzeigen"/>
+ <button label="Neu..." name="new_btn"/>
+ <button label="Löschen..." name="delete_btn"/>
+ <text name="classifieds_panel_text">
+ Laden...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/floater_picks.xml b/indra/newview/skins/default/xui/de/panel_profile_firstlife.xml
index 2521920e83..0f65090209 100644
--- a/indra/newview/skins/default/xui/de/floater_picks.xml
+++ b/indra/newview/skins/default/xui/de/panel_profile_firstlife.xml
@@ -1,2 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_picks" title="Auswahlen"/>
+<panel label="Profil" name="panel_profile_firstlife"/>
diff --git a/indra/newview/skins/default/xui/de/panel_profile_interests.xml b/indra/newview/skins/default/xui/de/panel_profile_interests.xml
new file mode 100644
index 0000000000..0f36f76aa0
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_profile_interests.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Interessen" name="panel_profile_interests">
+ <text name="I Want To:">
+ Ich möchte:
+ </text>
+ <check_box label="Erstellen" name="chk0"/>
+ <check_box label="Erkunden" name="chk1"/>
+ <check_box label="Treffen" name="chk2"/>
+ <check_box label="Angestellt werden" name="chk6"/>
+ <check_box label="Gruppe" name="chk3"/>
+ <check_box label="Kaufen" name="chk4"/>
+ <check_box label="Verkaufen" name="chk5"/>
+ <check_box label="Anstellen" name="chk7"/>
+ <line_editor name="want_to_edit">
+ (wird geladen...)
+ </line_editor>
+ <text name="Skills:">
+ Fähigkeiten:
+ </text>
+ <check_box label="Texturen" name="schk0"/>
+ <check_box label="Architektur" name="schk1"/>
+ <check_box label="Modellierung" name="schk3"/>
+ <check_box label="Eventplanung" name="schk2"/>
+ <check_box label="Scripting" name="schk4"/>
+ <check_box label="Benutzerdefinierte Charaktere" name="schk5"/>
+ <line_editor name="skills_edit">
+ (wird geladen...)
+ </line_editor>
+ <text name="Languages:">
+ Sprachen:
+ </text>
+ <line_editor name="languages_edit">
+ (wird geladen...)
+ </line_editor>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_profile_notes.xml b/indra/newview/skins/default/xui/de/panel_profile_notes.xml
new file mode 100644
index 0000000000..05c46ff858
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_profile_notes.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Anmerkungen &amp; Privatsphäre" name="panel_notes">
+ <text name="status_message" value="Private Anmerkungen zu diesem Avatar:"/>
+ <text name="status_message2" value="Dieser Avatar darf:"/>
+ <check_box label="Sehen, wenn ich online bin" name="status_check"/>
+ <check_box label="Mich auf der Weltkarte sehen" name="map_check"/>
+ <check_box label="Meine Objekte bearbeiten, löschen oder nehmen" name="objects_check"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_profile_pick.xml b/indra/newview/skins/default/xui/de/panel_profile_pick.xml
new file mode 100644
index 0000000000..1f44ba8b1b
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_profile_pick.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_pick_info">
+ <panel.string name="location_notice">
+ (wird nach dem Speichern aktualisiert)
+ </panel.string>
+ <line_editor name="pick_location">
+ Laden...
+ </line_editor>
+ <button label="Teleportieren" name="teleport_btn"/>
+ <button label="Auf Karte anzeigen" name="show_on_map_btn"/>
+ <button label="Standort festlegen" name="set_to_curr_location_btn" tool_tip="Aktuellen Standort verwenden"/>
+ <button label="Auswahl speichern" name="save_changes_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_profile_picks.xml b/indra/newview/skins/default/xui/de/panel_profile_picks.xml
new file mode 100644
index 0000000000..96403715e4
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_profile_picks.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Auswahlen" name="panel_picks">
+ <string name="no_picks" value="Keine Auswahl"/>
+ <text name="Tell everyone about your favorite places in Second Life.">
+ Erzählen Sie von Ihren Lieblingsorten in Second Life.
+ </text>
+ <button label="Neu..." name="new_btn"/>
+ <button label="Löschen..." name="delete_btn"/>
+ <text name="picks_panel_text">
+ Laden...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/de/panel_profile_secondlife.xml
new file mode 100644
index 0000000000..baaa58e1d7
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_profile_secondlife.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Profil" name="panel_profile">
+ <string name="status_online">
+ Zurzeit online
+ </string>
+ <string name="status_offline">
+ Zurzeit offline
+ </string>
+ <string name="CaptionTextAcctInfo">
+ [ACCTTYPE]
+[PAYMENTINFO]
+ </string>
+ <string name="payment_update_link_url">
+ http://www.secondlife.com/account/billing.php?lang=de
+ </string>
+ <string name="partner_edit_link_url">
+ http://www.secondlife.com/account/partners.php?lang=de
+ </string>
+ <string name="my_account_link_url" value="http://secondlife.com/account"/>
+ <string name="no_partner_text" value="Keine"/>
+ <string name="no_group_text" value="Keine"/>
+ <string name="RegisterDateFormat">
+ [REG_DATE]
+ </string>
+ <string name="name_text_args">
+ [NAME]
+ </string>
+ <string name="display_name_text_args">
+ [DISPLAY_NAME]
+ </string>
+ <string name="FSDev" value="Entwickler"/>
+ <string name="FSSupp" value="Support"/>
+ <string name="FSQualityAssurance" value="Fehlersuche"/>
+ <string name="FSGW" value="Gateway"/>
+ <text name="name_label" value="Name:"/>
+ <button label="Name:" name="set_name" tool_tip="Anzeigenamen festlegen"/>
+ <panel name="name_holder">
+ <text_editor name="complete_name" value="(wird geladen...)"/>
+ </panel>
+ <layout_stack name="imagepositioner">
+ <layout_panel name="label_stack">
+ <text name="status" value="Status unbekannt"/>
+ <text name="label" value="Second Life-Geburtsdatum:"/>
+ <text name="label2" value="Konto:"/>
+ <text name="partner_label" value="Partner:"/>
+ </layout_panel>
+ </layout_stack>
+ <text name="Groups:" value="Gruppen:"/>
+ <button label="+" label_selected="+" name="group_invite" tool_tip="In Gruppe einladen"/>
+ <layout_stack name="aboutpositioner">
+ <layout_panel name="about_stack">
+ <text name="About:" value="Info:"/>
+ </layout_panel>
+ <layout_panel name="give_stack">
+ <text name="Give item:" value="Objekt geben:"/>
+ <text name="Give inventory" tool_tip="Legen Sie hier Inventarobjekte ab, um Sie dieser Person zu geben.">
+ Inventarobjekt hier ablegen.
+ </text>
+ </layout_panel>
+ </layout_stack>
+ <layout_stack name="buttonstack">
+ <layout_panel name="left_buttonstack">
+ <button label="Auf Karte anzeigen" label_selected="Auf Karte anzeigen" name="show_on_map_btn" tool_tip="Einwohner auf Karte lokalisieren"/>
+ <button label="Bezahlen" label_selected="Bezahlen" name="pay" tool_tip="Geld an den Einwohner zahlen"/>
+ </layout_panel>
+ <layout_panel name="middle_buttonstack">
+ <button label="Teleportation anbieten" label_selected="Teleportation anbieten" name="teleport" tool_tip="Dem Einwohner eine Teleportation anbieten"/>
+ <button label="Instant Message" label_selected="Instant Message" name="im" tool_tip="Instant Message-Sitzung öffnen"/>
+ </layout_panel>
+ <layout_panel name="right_buttonstack">
+ <button label="Freund hinzufügen" label_selected="Freund hinzufügen" name="add_friend" tool_tip="Dem Einwohner die Freundschaft anbieten"/>
+ <button label="Blockieren" name="block" tool_tip="Diesen Einwohner blockieren"/>
+ <button label="Blockierung aufheben" name="unblock" tool_tip="Diesen Einwohner nicht mehr blockieren"/>
+ </layout_panel>
+ </layout_stack>
+ <check_box label="In Suche anzeigen" name="show_in_search_checkbox"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_profile_web.xml b/indra/newview/skins/default/xui/de/panel_profile_web.xml
new file mode 100644
index 0000000000..a03918f4b5
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_profile_web.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Web" name="panel_profile_web">
+ <panel.string name="LoadTime" value="Ladezeit: [TIME] Sekunden"/>
+ <line_editor name="url_edit">
+ (wird geladen..)
+ </line_editor>
+ <flyout_button label="Laden" name="load" tool_tip="Lädt diese Profilseite im integrierten Webbrowser.">
+ <flyout_button.item label="Im Viewer-Browser öffnen" name="open_item"/>
+ <flyout_button.item label="In externem Browser öffnen" name="home_item"/>
+ </flyout_button>
+ <button name="web_profile_popout_btn" tool_tip="Webprofil ausklappen"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/strings.xml b/indra/newview/skins/default/xui/de/strings.xml
index 97ace4fc18..4625c48714 100644
--- a/indra/newview/skins/default/xui/de/strings.xml
+++ b/indra/newview/skins/default/xui/de/strings.xml
@@ -356,6 +356,24 @@ Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden.
<string name="TestingDisconnect">
Verbindungsabbruch wird getestet
</string>
+ <string name="SocialFacebookConnecting">
+ Mit Facebook verbinden...
+ </string>
+ <string name="SocialFacebookPosting">
+ Posten...
+ </string>
+ <string name="SocialFacebookDisconnecting">
+ Facebook-Verbindung trennen...
+ </string>
+ <string name="SocialFacebookErrorConnecting">
+ Problem beim Verbinden mit Facebook
+ </string>
+ <string name="SocialFacebookErrorPosting">
+ Problem beim Posten auf Facebook
+ </string>
+ <string name="SocialFacebookErrorDisconnecting">
+ Problem beim Trennen der Facebook-Verbindung
+ </string>
<string name="SocialFlickrConnecting">
Verbinden mit Flickr...
</string>
@@ -2578,9 +2596,21 @@ Falls diese Meldung weiterhin angezeigt wird, wenden Sie sich unter http://suppo
<string name="NoPicksClassifiedsText">
Sie haben keine Auswahl oder Anzeigen erstelllt. Klicken Sie auf die „Plus&quot;-Schaltfläche, um eine Auswahl oder Anzeige zu erstellen.
</string>
+ <string name="NoPicksText">
+ Sie haben keine Auswahl erstellt. Klicken Sie auf die Schaltfläche &quot;Neu&quot;, um eine Auswahl zu erstellen.
+ </string>
+ <string name="NoClassifiedsText">
+ Sie haben keine Anzeigen erstellt. Klicken Sie auf die Schaltfläche &quot;Neu&quot;, um eine Anzeige zu erstellen.
+ </string>
<string name="NoAvatarPicksClassifiedsText">
Der Einwohner hat keine Auswahl oder Anzeigen
</string>
+ <string name="NoAvatarPicksText">
+ Der Einwohner hat keine Auswahl
+ </string>
+ <string name="NoAvatarClassifiedsText">
+ Der Einwohner hat keine Anzeigen
+ </string>
<string name="PicksClassifiedsLoadingText">
Wird geladen...
</string>
@@ -4558,6 +4588,9 @@ Falls diese Meldung weiterhin angezeigt wird, wenden Sie sich bitte an [SUPPORT_
<string name="share_alert">
Objekte aus dem Inventar hier her ziehen
</string>
+ <string name="facebook_post_success">
+ Sie haben auf Facebook gepostet.
+ </string>
<string name="flickr_post_success">
Sie haben auf Flickr gepostet.
</string>
diff --git a/indra/newview/skins/default/xui/en/floater_picks.xml b/indra/newview/skins/default/xui/en/floater_classified.xml
index 984894b016..5b14c827d0 100644
--- a/indra/newview/skins/default/xui/en/floater_picks.xml
+++ b/indra/newview/skins/default/xui/en/floater_classified.xml
@@ -2,20 +2,19 @@
<floater
positioning="cascading"
can_close="true"
- can_resize="true"
+ can_resize="false"
height="572"
help_topic="sidebar_me"
min_width="333"
min_height="440"
- name="floater_picks"
+ name="floater_classified"
save_rect="true"
- save_visibility="true"
- reuse_instance="true"
- title="Picks"
+ save_visibility="false"
+ title="Classified"
width="333" >
<panel
- class="panel_me"
+ class="panel_classified_info"
name="main_panel"
- filename="panel_me.xml"
+ filename="panel_classified_info.xml"
follows="all"/>
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_display_name.xml b/indra/newview/skins/default/xui/en/floater_display_name.xml
index 9a9fd32a77..3c8f415860 100644
--- a/indra/newview/skins/default/xui/en/floater_display_name.xml
+++ b/indra/newview/skins/default/xui/en/floater_display_name.xml
@@ -23,7 +23,7 @@
use_ellipses="true"
width="380"
wrap="true">
- The name you give your avatar is called your Display Name. You can change it once a week.
+ Your display name is what other people see above your head. It is different from your login name. You can change it once a week.
</text>
<text
type="string"
@@ -85,19 +85,10 @@
width="120" />
<button
height="23"
- label="Reset"
- layout="topleft"
- font="SansSerif"
- left_pad="5"
- name="reset_btn"
- tool_tip="Make Display Name the same as Username"
- width="120" />
- <button
- height="23"
label="Cancel"
font="SansSerif"
layout="topleft"
- left_pad="5"
+ left_pad="125"
name="cancel_btn"
width="120" />
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_preview_texture.xml b/indra/newview/skins/default/xui/en/floater_preview_texture.xml
index e1e7e1c8c8..048cf7df62 100644
--- a/indra/newview/skins/default/xui/en/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/en/floater_preview_texture.xml
@@ -17,94 +17,122 @@
name="Copy">
Copy To Inventory
</floater.string>
- <text
- type="string"
- length="1"
- follows="left|top"
- font="SansSerif"
- height="19"
- layout="topleft"
- left="10"
- name="desc txt"
- top="21"
- width="90">
- Description:
- </text>
- <line_editor
- border_style="line"
- border_thickness="1"
- follows="left|top|right"
- font="SansSerif"
- height="19"
- layout="topleft"
- left_pad="0"
- max_length_bytes="127"
- name="desc"
- width="190" />
- <text
- type="string"
- halign="right"
- length="1"
- follows="right|bottom"
- height="16"
- layout="topleft"
- left="110"
- name="dimensions"
- top="255"
- width="200">
- [WIDTH]px x [HEIGHT]px
- </text>
- <text
- type="string"
- halign="right"
- length="1"
- follows="right|bottom"
- height="16"
- layout="topleft"
- left_delta="-110"
- name="aspect_ratio"
- top_pad="5"
- width="200">
- Preview aspect ratio
- </text>
- <combo_box
- allow_text_entry="true"
- top_delta="-3"
- follows="right|bottom"
- height="23"
- left_pad="10"
- max_chars="20"
- mouse_opaque="true"
- enabled="true"
- width="108"
- name="combo_aspect_ratio"
- tool_tip="Preview at a fixed aspect ratio">
- </combo_box>
- <button
- follows="right|bottom"
- height="22"
- label="OK"
- layout="topleft"
- left="6"
- name="Keep"
- top_pad="5"
- width="110" />
- <button
- follows="right|bottom"
- height="22"
- label="Discard"
- layout="topleft"
- left_pad="5"
- name="Discard"
- top_delta="0"
- width="110" />
- <button
- follows="right|bottom"
- height="22"
- label="Save As"
- layout="topleft"
- left_pad="5"
- name="save_tex_btn"
- top_delta="0"
- width="110" />
+ <layout_stack
+ animate="false"
+ name="preview_stack"
+ top_pad="15"
+ left="0"
+ follows="all"
+ orientation="vertical"
+ height="350"
+ width="370"
+ layout="topleft">
+ <layout_panel
+ name="texture_panel"
+ height="305"
+ top_pad="0"
+ left="0"
+ follows="left|top"
+ layout="topleft">
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ height="19"
+ layout="topleft"
+ left="10"
+ name="desc txt"
+ top="6"
+ width="90">
+ Description:
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="19"
+ layout="topleft"
+ left_pad="0"
+ max_length_bytes="127"
+ name="desc"
+ width="190" />
+ <text
+ type="string"
+ halign="right"
+ length="1"
+ follows="right|bottom"
+ height="16"
+ layout="topleft"
+ left="110"
+ name="dimensions"
+ bottom="-40"
+ width="200">
+ [WIDTH]px x [HEIGHT]px
+ </text>
+ <text
+ type="string"
+ halign="right"
+ length="1"
+ follows="right|bottom"
+ height="16"
+ layout="topleft"
+ left_delta="-110"
+ name="aspect_ratio"
+ top_pad="5"
+ width="200">
+ Preview aspect ratio
+ </text>
+ <combo_box
+ allow_text_entry="true"
+ top_delta="-3"
+ follows="right|bottom"
+ height="23"
+ left_pad="10"
+ max_chars="20"
+ mouse_opaque="true"
+ enabled="true"
+ width="108"
+ name="combo_aspect_ratio"
+ tool_tip="Preview at a fixed aspect ratio">
+ </combo_box>
+ </layout_panel>
+ <layout_panel
+ name="buttons_panel"
+ height="45"
+ bottom="-40"
+ left="0"
+ follows="right|bottom"
+ auto_resize="false"
+ layout="topleft">
+ <button
+ follows="right|bottom"
+ height="22"
+ label="OK"
+ layout="topleft"
+ left="6"
+ name="Keep"
+ top_pad="0"
+ width="110" />
+ <button
+ follows="right|bottom"
+ height="22"
+ label="Discard"
+ layout="topleft"
+ left_pad="5"
+ name="Discard"
+ top_delta="0"
+ width="110" />
+ <button
+ follows="right|bottom"
+ height="22"
+ label="Save As"
+ layout="topleft"
+ left_pad="5"
+ name="save_tex_btn"
+ top_delta="0"
+ width="110" />
+ </layout_panel>
+ </layout_stack>
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_profile.xml b/indra/newview/skins/default/xui/en/floater_profile.xml
new file mode 100644
index 0000000000..32ab811a6e
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_profile.xml
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater
+ name="avatarinfo"
+ height="510"
+ width="510"
+ layout="topleft"
+ can_close="true"
+ can_resize="true"
+ help_topic="panel_my_profile_tab"
+ min_height="510"
+ min_width="510"
+ positioning="centered"
+ save_rect="true"
+ title="Profile"
+>
+ <panel
+ name="panel_profile_view"
+ top="0"
+ left="0"
+ height="500"
+ width="505"
+ follows="all"
+ class="panel_profile"
+ >
+ <tab_container
+ name="panel_profile_tabs"
+ top_pad="5"
+ left="0"
+ height="500"
+ width="505"
+ follows="all"
+ layout="topleft"
+ halign="center"
+ tab_min_width="81"
+ tab_height="30"
+ tab_position="top"
+ >
+ <panel
+ name="panel_profile_secondlife"
+ label="BIO"
+ layout="topleft"
+ class="panel_profile_secondlife"
+ filename="panel_profile_secondlife.xml"
+ help_topic="profile_secondlife_tab"
+ />
+ <panel
+ name="panel_profile_web"
+ label="FEED"
+ layout="topleft"
+ class="panel_profile_web"
+ filename="panel_profile_web.xml"
+ help_topic="profile_web_tab"
+ />
+ <panel
+ name="panel_profile_picks"
+ label="PICKS"
+ layout="topleft"
+ class="panel_profile_picks"
+ filename="panel_profile_picks.xml"
+ help_topic="profile_picks_tab"
+ />
+ <panel
+ name="panel_profile_classifieds"
+ label="CLASSIFIEDS"
+ layout="topleft"
+ class="panel_profile_classifieds"
+ filename="panel_profile_classifieds.xml"
+ help_topic="profile_classified_tab"
+ />
+ <panel
+ name="panel_profile_firstlife"
+ label="REAL LIFE"
+ layout="topleft"
+ class="panel_profile_firstlife"
+ filename="panel_profile_firstlife.xml"
+ help_topic="profile_firstlife_tab"
+ />
+ <panel
+ name="panel_profile_notes"
+ label="MY NOTES"
+ layout="topleft"
+ class="panel_profile_notes"
+ filename="panel_profile_notes.xml"
+ help_topic="profile_notes_tab"
+ />
+ </tab_container>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_profile_permissions.xml b/indra/newview/skins/default/xui/en/floater_profile_permissions.xml
new file mode 100644
index 0000000000..9f3b4d9a00
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_profile_permissions.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_resize="false"
+ show_title="false"
+ can_minimize="false"
+ can_close="false"
+ header_height="10"
+ bg_opaque_image="Window_NoTitle_Foreground"
+ bg_alpha_image="Window_NoTitle_Background"
+ height="115"
+ layout="topleft"
+ name="profile_permissions"
+ width="300">
+ <string
+ name="description_string"
+ value="Allow [AGENT_NAME] to:" />
+ <text
+ name="perm_description"
+ value="Allow agent to:"
+ top="1"
+ left="12"
+ right="-6"
+ height="16"
+ follows="top|left"
+ layout="topleft"
+ font.style="BOLD"
+ />
+ <check_box
+ name="online_check"
+ label="See when I am online"
+ top_pad="5"
+ left="16"
+ height="16"
+ width="293"
+ follows="top|left"
+ layout="topleft"
+ />
+ <check_box
+ name="map_check"
+ label="Find me on the world map"
+ top_pad="5"
+ left="16"
+ height="16"
+ width="293"
+ follows="top|left"
+ layout="topleft"
+ />
+ <check_box
+ name="objects_check"
+ label="Edit, delete or take my objects from my land"
+ top_pad="5"
+ left="16"
+ height="16"
+ width="293"
+ follows="top|left"
+ layout="topleft"
+ />
+ <button
+ name="perms_btn_ok"
+ label="OK"
+ top_pad="5"
+ left="42"
+ height="20"
+ width="100"
+ follows="top|left"
+ layout="topleft"/>
+ <button
+ name="perms_btn_cancel"
+ label="Cancel"
+ top_delta="0"
+ left_pad="12"
+ height="20"
+ width="100"
+ follows="top|left"
+ layout="topleft"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_profile_texture.xml b/indra/newview/skins/default/xui/en/floater_profile_texture.xml
new file mode 100644
index 0000000000..3b351a3325
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_profile_texture.xml
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_resize="false"
+ show_title="false"
+ can_minimize="false"
+ can_close="false"
+ header_height="10"
+ height="223"
+ width="200"
+ layout="topleft"
+ min_height="128"
+ min_width="128"
+ name="profile_texture">
+ <layout_stack
+ name="preview_stack"
+ top="0"
+ left="0"
+ right="-1"
+ bottom="-1"
+ follows="all"
+ orientation="vertical"
+ layout="topleft"
+ animate="false">
+ <layout_panel
+ name="texture_panel"
+ height="196"
+ follows="left|top"
+ auto_resize="true"
+ layout="topleft">
+ <icon
+ name="profile_pic"
+ image_name="Generic_Person_Large"
+ layout="topleft"
+ follows="all"
+ top="5"
+ left="5"
+ bottom="-1"
+ right="-5"/>
+ </layout_panel>
+ <layout_panel
+ name="buttons_panel"
+ height="26"
+ auto_resize="false"
+ layout="topleft">
+ <layout_stack
+ name="buttons_stack"
+ top="0"
+ left="0"
+ right="-1"
+ bottom="-1"
+ follows="all"
+ orientation="horizontal"
+ layout="topleft"
+ animate="false">
+ <layout_panel
+ follows="all"
+ layout="topleft"
+ name="resizer_left"
+ auto_resize="true"
+ width="1">
+ </layout_panel>
+ <layout_panel
+ follows="all"
+ layout="topleft"
+ name="close_panel"
+ auto_resize="false"
+ width="112">
+ <button
+ follows="top|left"
+ height="22"
+ label="Close"
+ layout="topleft"
+ left="1"
+ top="0"
+ width="110"
+ name="close_btn"/>
+ </layout_panel>
+ <layout_panel
+ follows="all"
+ layout="topleft"
+ name="resizer_right"
+ auto_resize="true"
+ width="1">
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/inspect_avatar.xml b/indra/newview/skins/default/xui/en/inspect_avatar.xml
index ef4f19cd4c..fceb9b2184 100644
--- a/indra/newview/skins/default/xui/en/inspect_avatar.xml
+++ b/indra/newview/skins/default/xui/en/inspect_avatar.xml
@@ -85,6 +85,8 @@
use_ellipses="true" />
<text
follows="left|top|right"
+ trusted_content="false"
+ always_show_icons="true"
height="35"
left="8"
name="user_details"
diff --git a/indra/newview/skins/default/xui/en/menu_avatar_self.xml b/indra/newview/skins/default/xui/en/menu_avatar_self.xml
index 500b6fffc2..20f3ad080b 100644
--- a/indra/newview/skins/default/xui/en/menu_avatar_self.xml
+++ b/indra/newview/skins/default/xui/en/menu_avatar_self.xml
@@ -290,4 +290,11 @@
<menu_item_call.on_visible
function="EnableMuteParticle" />
</menu_item_call>
+ <menu_item_separator/>
+ <menu_item_call label="View Profile"
+ layout="topleft"
+ name="show_avatar_profile">
+ <menu_item_call.on_click
+ function="Avatar.ToggleMyProfile" />
+ </menu_item_call>
</context_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_gesture_gear.xml b/indra/newview/skins/default/xui/en/menu_gesture_gear.xml
index 5cae643e44..359c093eff 100644
--- a/indra/newview/skins/default/xui/en/menu_gesture_gear.xml
+++ b/indra/newview/skins/default/xui/en/menu_gesture_gear.xml
@@ -9,7 +9,7 @@
layout="topleft"
name="activate">
<on_click
- function="Gesture.Action.ToogleActiveState" />
+ function="Gesture.Action.ToggleActiveState" />
</menu_item_call>
<menu_item_call
label="Rename"
diff --git a/indra/newview/skins/default/xui/en/menu_profile_other.xml b/indra/newview/skins/default/xui/en/menu_profile_other.xml
new file mode 100644
index 0000000000..4db4d0922b
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_profile_other.xml
@@ -0,0 +1,171 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ layout="topleft"
+ name="Avatar Profile Menu">
+ <menu_item_call
+ label="IM"
+ layout="topleft"
+ name="im">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="im"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Offer Teleport"
+ name="offer_teleport">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="offer_teleport"/>
+ <menu_item_call.on_enable
+ function="Profile.EnableItem"
+ parameter="offer_teleport"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Request Teleport"
+ name="request_teleport">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="request_teleport"/>
+ <menu_item_call.on_enable
+ function="Profile.EnableItem"
+ parameter="request_teleport"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Voice call"
+ layout="topleft"
+ name="voice_call">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="voice_call"/>
+ <menu_item_call.on_enable
+ function="Profile.EnableItem"
+ parameter="voice_call"/>
+ </menu_item_call>
+ <menu_item_separator />
+ <menu_item_call
+ label="View chat history..."
+ layout="topleft"
+ name="chat_history">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="chat_history"/>
+ <menu_item_call.on_enable
+ function="Profile.EnableItem"
+ parameter="chat_history"/>
+ </menu_item_call>
+ <menu_item_separator name="separator_chat_history"/>
+ <menu_item_call
+ label="Add Friend"
+ layout="topleft"
+ name="add_friend">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="add_friend"/>
+ <menu_item_call.on_visible
+ function="Profile.EnableItem"
+ parameter="add_friend"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Remove Friend"
+ layout="topleft"
+ name="remove_friend">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="remove_friend"/>
+ <menu_item_call.on_enable
+ function="Profile.EnableItem"
+ parameter="remove_friend"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Invite to group..."
+ layout="topleft"
+ name="invite_to_group">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="invite_to_group"/>
+ </menu_item_call>
+ <menu_item_separator name="separator_invite_to_group"/>
+ <menu_item_call
+ label="Permissions"
+ layout="topleft"
+ name="agent_permissions">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="agent_permissions"/>
+ <menu_item_call.on_visible
+ function="Profile.EnableItem"
+ parameter="agent_permissions"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Map"
+ layout="topleft"
+ name="map">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="can_show_on_map"/>
+ <menu_item_call.on_enable
+ function="Profile.EnableItem"
+ parameter="can_show_on_map"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Share"
+ layout="topleft"
+ name="share">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="share"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Pay"
+ layout="topleft"
+ name="pay">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="pay"/>
+ </menu_item_call>
+ <menu_item_check
+ label="Block/Unblock"
+ layout="topleft"
+ name="block_unblock">
+ <menu_item_check.on_click
+ function="Profile.Commit"
+ parameter="toggle_block_agent"/>
+ <menu_item_check.on_check
+ function="Profile.CheckItem"
+ parameter="toggle_block_agent"/>
+ <menu_item_check.on_enable
+ function="Profile.EnableItem"
+ parameter="toggle_block_agent"/>
+ </menu_item_check>
+ <menu_item_separator name="separator_copy_options"/>
+ <menu_item_call
+ label="Copy Display Name"
+ layout="topleft"
+ name="copy_display_name">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="copy_display_name"/>
+ <menu_item_call.on_enable
+ function="Profile.EnableItem"
+ parameter="copy_display_name"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Copy Agent Name"
+ layout="topleft"
+ name="copy_name">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="copy_username"/>
+ <menu_item_call.on_enable
+ function="Profile.EnableItem"
+ parameter="copy_username"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Copy Agent Id"
+ layout="topleft"
+ name="copy_id">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="copy_user_id"/>
+ </menu_item_call>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_profile_self.xml b/indra/newview/skins/default/xui/en/menu_profile_self.xml
new file mode 100644
index 0000000000..d0bd4000f8
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_profile_self.xml
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ layout="topleft"
+ name="Avatar Profile Menu Self">
+ <menu_item_call
+ label="Edit Display Name"
+ layout="topleft"
+ name="edit_display_name">
+ <on_click
+ function="Profile.Commit"
+ parameter="edit_display_name"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Edit Partner"
+ layout="topleft"
+ name="edit_partner">
+ <on_click
+ function="Profile.Commit"
+ parameter="edit_partner"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Upload Photo"
+ layout="topleft"
+ name="upload_photo">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="upload_photo"/>
+ <menu_item_call.on_enable
+ function="Profile.EnableItem"
+ parameter="upload_photo"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Change Photo"
+ layout="topleft"
+ name="change_photo">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="change_photo"/>
+ <menu_item_call.on_enable
+ function="Profile.EnableItem"
+ parameter="change_photo"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Remove Photo"
+ layout="topleft"
+ name="remove_photo">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="remove_photo"/>
+ <menu_item_call.on_enable
+ function="Profile.EnableItem"
+ parameter="remove_photo"/>
+ </menu_item_call>
+ <menu_item_separator name="separator_copy_options"/>
+ <menu_item_call
+ label="Copy Display Name"
+ layout="topleft"
+ name="copy_display_name">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="copy_display_name"/>
+ <menu_item_call.on_enable
+ function="Profile.EnableItem"
+ parameter="copy_display_name"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Copy Agent Name"
+ layout="topleft"
+ name="copy_name">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="copy_username"/>
+ <menu_item_call.on_enable
+ function="Profile.EnableItem"
+ parameter="copy_username"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Copy Agent Id"
+ layout="topleft"
+ name="copy_id">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="copy_user_id"/>
+ </menu_item_call>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 1caa0908ea..e2d088c697 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -47,8 +47,7 @@
label="Picks..."
name="Picks">
<menu_item_call.on_click
- function="Floater.ToggleOrBringToFront"
- parameter="picks" />
+ function="ShowAgentProfilePicks" />
</menu_item_call>
<menu_item_call
label="Experiences..."
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 1ee0d9c64a..998c7a08d1 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -1496,7 +1496,19 @@ Insufficient funds to create classified.
<notification
icon="alertmodal.tga"
- name="DeleteAvatarPick"
+ name="ProfileDeleteClassified"
+ type="alertmodal">
+Delete classified &lt;nolink&gt;[CLASSIFIED]&lt;/nolink&gt;?
+ <tag>confirm</tag>
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ProfileDeletePick"
type="alertmodal">
Delete pick &lt;nolink&gt;[PICK]&lt;/nolink&gt;?
<tag>confirm</tag>
@@ -1507,6 +1519,32 @@ Delete pick &lt;nolink&gt;[PICK]&lt;/nolink&gt;?
</notification>
<notification
+ icon="alert.tga"
+ name="ProfileUnpublishedClassified"
+ type="alert">
+ You have unpublished classifieds. They will be lost if you close the window.
+ <tag>confirm</tag>
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alert.tga"
+ name="ProfileUnsavedChanges"
+ type="alert">
+ You have usaved changes.
+ <tag>confirm</tag>
+ <tag>save</tag>
+ <usetemplate
+ canceltext="Cancel"
+ name="yesnocancelbuttons"
+ notext="Discard"
+ yestext="Save"/>
+ </notification>
+
+ <notification
icon="alertmodal.tga"
name="DeleteOutfits"
type="alertmodal">
diff --git a/indra/newview/skins/default/xui/en/panel_classified_info.xml b/indra/newview/skins/default/xui/en/panel_classified_info.xml
index d4a2745d1d..04a0bc800d 100644
--- a/indra/newview/skins/default/xui/en/panel_classified_info.xml
+++ b/indra/newview/skins/default/xui/en/panel_classified_info.xml
@@ -38,28 +38,15 @@
name="auto_renew_off">
Disabled
</panel.string>
- <button
- follows="top|left"
- height="24"
- image_hover_unselected="BackButton_Over"
- image_pressed="BackButton_Press"
- image_unselected="BackButton_Off"
- layout="topleft"
- name="back_btn"
- left="10"
- tab_stop="false"
- top="2"
- width="30"
- use_draw_context_alpha="false" />
<text
follows="top|left|right"
font="SansSerifHugeBold"
height="26"
layout="topleft"
- left_pad="4"
+ left="12"
name="title"
text_color="LtGray"
- top="0"
+ top="2"
value="Classified Info"
use_ellipses="true"
width="275" />
@@ -420,7 +407,7 @@
height="23"
label="Teleport"
layout="topleft"
- left="0"
+ left="2"
name="teleport_btn"
top="0"
width="101" />
@@ -443,24 +430,6 @@
top="0"
width="100" />
</layout_panel>
-
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="bottomleft"
- left_pad="3"
- name="edit_btn_lp"
- auto_resize="true"
- width="101">
- <button
- follows="bottom|left|right"
- height="23"
- label="Edit"
- layout="topleft"
- name="edit_btn"
- top="0"
- width="101" />
- </layout_panel>
</layout_stack>
</panel>
</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_edit_classified.xml b/indra/newview/skins/default/xui/en/panel_edit_classified.xml
deleted file mode 100644
index e846edf1d4..0000000000
--- a/indra/newview/skins/default/xui/en/panel_edit_classified.xml
+++ /dev/null
@@ -1,354 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel
- background_visible="true"
- bevel_style="in"
- follows="left|top|right|bottom"
- height="569"
- label="Edit Classified"
- layout="topleft"
- left="0"
- min_height="350"
- name="panel_edit_classified"
- help_topic="profile_edit_classified"
- top="0"
- width="333">
- <panel.string
- name="location_notice">
- (will update after save)
- </panel.string>
- <string name="publish_label">
- Publish
- </string>
- <string name="save_label">
- Save
- </string>
- <button
- follows="top|left"
- height="24"
- image_hover_unselected="BackButton_Over"
- image_pressed="BackButton_Press"
- image_unselected="BackButton_Off"
- layout="topleft"
- name="back_btn"
- left="10"
- tab_stop="false"
- top="2"
- width="30"
- use_draw_context_alpha="false" />
- <text
- type="string"
- length="1"
- follows="top"
- font="SansSerifHugeBold"
- height="26"
- layout="topleft"
- left_pad="4"
- name="title"
- text_color="LtGray"
- top="0"
- width="250">
- Edit Classified
- </text>
- <scroll_container
- color="DkGray2"
- follows="all"
- height="502"
- layout="topleft"
- left="8"
- top_pad="10"
- name="profile_scroll"
- reserve_scroll_corner="false"
- opaque="true"
- width="312">
- <panel
- name="scroll_content_panel"
- follows="left|top"
- min_height="300"
- layout="topleft"
- top="0"
- background_visible="false"
- height="690"
- left="0"
- width="285">
- <panel
- name="snapshot_panel"
- layout="topleft"
- follows="left|top|right"
- height="197"
- left="10"
- top="10"
- width="272">
- <texture_picker
- fallback_image="default_land_picture.j2c"
- follows="left|top|right"
- height="197"
- width="272"
- layout="topleft"
- top="0"
- left="0"
- name="classified_snapshot" />
- <icon
- height="197"
- image_name="spacer24.tga"
- layout="topleft"
- name="edit_icon"
- label=""
- tool_tip="Click to select an image"
- top="0"
- left="0"
- width="272" />
- </panel>
- <text
- type="string"
- length="1"
- follows="left|top"
- height="15"
- font="SansSerifSmall"
- font.style="BOLD"
- layout="topleft"
- left="10"
- top="215"
- name="Name:"
- text_color="white"
- width="280">
- Title:
- </text>
- <line_editor
- follows="left|top|right"
- font="SansSerif"
- height="20"
- layout="topleft"
- left="10"
- top_pad="2"
- max_length_bytes="30"
- name="classified_name"
- prevalidate_callback="ascii"
- text_color="black"
- width="273" />
- <text
- type="string"
- length="1"
- follows="left|top"
- height="15"
- font="SansSerifSmall"
- font.style="BOLD"
- layout="topleft"
- left="10"
- top_pad="20"
- name="description_label"
- text_color="white"
- width="280">
- Description:
- </text>
- <text_editor
- follows="left|top|right"
- height="100"
- width="273"
- layout="topleft"
- left="10"
- top_pad="2"
- max_length="256"
- name="classified_desc"
- text_color="black"
- word_wrap="true" />
- <text
- type="string"
- length="1"
- font="SansSerifSmall"
- font.style="BOLD"
- follows="left|top"
- height="15"
- layout="topleft"
- left="10"
- name="location_label"
- text_color="white"
- top_pad="20"
- width="280">
- Location:
- </text>
- <text
- type="string"
- length="1"
- follows="left|top"
- height="30"
- layout="topleft"
- left="10"
- name="classified_location"
- right="-10"
- top_pad="2"
- width="280"
- word_wrap="true">
- loading...
- </text>
- <button
- follows="left|top"
- height="23"
- label="Set to Current Location"
- layout="topleft"
- left="10"
- top_pad="5"
- name="set_to_curr_location_btn"
- width="200" />
- <text
- follows="left|top"
- font.style="BOLD"
- height="10"
- layout="topleft"
- left="10"
- name="category_label"
- text_color="white"
- top_pad="15"
- value="Category:"
- width="250" />
- <combo_box
- follows="left|top"
- height="23"
- label=""
- left="10"
- name="category"
- top_pad="5"
- width="156" />
- <text
- follows="left|top"
- font.style="BOLD"
- height="10"
- layout="topleft"
- left="10"
- name="content_type_label"
- text_color="white"
- top_pad="15"
- value="Content type:"
- width="250" />
- <icons_combo_box
- follows="left|top"
- height="23"
- label="General Content"
- layout="topleft"
- left="10"
- name="content_type"
- top_pad="5"
- width="156">
- <icons_combo_box.drop_down_button
- image_overlay="Parcel_PG_Light"
- image_overlay_alignment="left"
- imgoverlay_label_space="3"
- pad_left="3"/>
- <icons_combo_box.item
- label="Moderate Content"
- name="mature_ci"
- value="Mature">
- <item.columns
- halign="center"
- type="icon"
- value="Parcel_M_Light"
- width="20"/>
- </icons_combo_box.item>
- <icons_combo_box.item
- label="General Content"
- name="pg_ci"
- value="PG">
- <item.columns
- halign="center"
- type="icon"
- value="Parcel_PG_Light"
- width="20"/>
- </icons_combo_box.item>
- </icons_combo_box>
- <check_box
- height="16"
- label="Auto renew each week"
- layout="topleft"
- left="10"
- name="auto_renew"
- top_pad="15"
- width="250" />
- <text
- follows="left|top"
- height="10"
- layout="topleft"
- left="10"
- name="price_for_listing_label"
- text_color="white"
- top_pad="15"
- value="Price for listing:"
- width="250" />
- <spinner
- decimal_digits="0"
- follows="left|top"
- halign="left"
- height="23"
- increment="1"
- label_width="20"
- label="L$"
- v_pad="10"
- layout="topleft"
- left="10"
- value="50"
- min_val="50"
- max_val="99999"
- name="price_for_listing"
- top_pad="5"
- tool_tip="Price for listing."
- width="105" />
- </panel>
- </scroll_container>
- <panel
- follows="left|right|bottom"
- height="23"
- label="bottom_panel"
- layout="topleft"
- left="8"
- name="bottom_panel"
- top_pad="5"
- width="303">
-
- <layout_stack
- follows="bottom|left|right"
- height="23"
- layout="topleft"
- name="bottom_panel_ls"
- left="1"
- orientation="horizontal"
- top_pad="0"
- width="309">
-
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="bottomleft"
- left="0"
- name="save_changes_btn_lp"
- auto_resize="true"
- width="156">
- <button
- follows="bottom|left|right"
- height="23"
- label="[LABEL]"
- layout="topleft"
- name="save_changes_btn"
- left="1"
- top="0"
- width="155" />
- </layout_panel>
-
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="bottomleft"
- left_pad="3"
- name="show_on_map_btn_lp"
- auto_resize="true"
- width="157">
- <button
- follows="bottom|left|right"
- height="23"
- label="Cancel"
- layout="topleft"
- name="cancel_btn"
- left="1"
- top="0"
- width="156" />
- </layout_panel>
- </layout_stack>
- </panel>
-</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_edit_pick.xml b/indra/newview/skins/default/xui/en/panel_edit_pick.xml
deleted file mode 100644
index 357a5559bf..0000000000
--- a/indra/newview/skins/default/xui/en/panel_edit_pick.xml
+++ /dev/null
@@ -1,239 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel
- background_visible="true"
- bevel_style="in"
- follows="left|top|right|bottom"
- height="569"
- label="Edit Pick"
- layout="topleft"
- left="0"
- min_height="350"
- name="panel_edit_pick"
- help_topic="profile_edit_pick"
- top="0"
- width="333">
- <panel.string
- name="location_notice">
- (will update after save)
- </panel.string>
- <button
- follows="top|left"
- height="24"
- image_hover_unselected="BackButton_Over"
- image_pressed="BackButton_Press"
- image_unselected="BackButton_Off"
- layout="topleft"
- name="back_btn"
- left="10"
- tab_stop="false"
- top="4"
- width="30"
- use_draw_context_alpha="false" />
- <text
- type="string"
- length="1"
- follows="top"
- font="SansSerifHugeBold"
- height="26"
- layout="topleft"
- left_pad="4"
- name="title"
- text_color="LtGray"
- top="4"
- width="250">
- Edit Pick
- </text>
- <scroll_container
- color="DkGray2"
- follows="all"
- height="501"
- layout="topleft"
- left="8"
- top_pad="9"
- name="profile_scroll"
- opaque="true"
- width="312">
- <panel
- name="scroll_content_panel"
- follows="left|top|right"
- min_height="300"
- layout="topleft"
- top="0"
- background_visible="false"
- height="500"
- left="0"
- width="285">
- <texture_picker
- fallback_image="default_land_picture.j2c"
- follows="left|top|right"
- height="197"
- width="272"
- layout="topleft"
- no_commit_on_selection="true"
- top="10"
- left="11"
- name="pick_snapshot" />
- <icon
- height="197"
- image_name="spacer24.tga"
- layout="topleft"
- name="edit_icon"
- label=""
- tool_tip="Click to select an image"
- top="10"
- left="11"
- width="286" />
- <text
- type="string"
- length="1"
- follows="left|top|right"
- height="15"
- font="SansSerifSmall"
- font.style="BOLD"
- layout="topleft"
- left="10"
- top="215"
- name="Name:"
- text_color="white"
- width="280">
- Title:
- </text>
- <line_editor
- follows="left|top|right"
- font="SansSerif"
- height="20"
- layout="topleft"
- left="10"
- top_pad="2"
- max_length_bytes="63"
- name="pick_name"
- text_color="black"
- width="273" />
- <text
- type="string"
- length="1"
- follows="left|top|right"
- height="15"
- font="SansSerifSmall"
- font.style="BOLD"
- layout="topleft"
- left="10"
- top_pad="20"
- name="description_label"
- text_color="white"
- width="280">
- Description:
- </text>
- <text_editor
- follows="left|top|right"
- height="100"
- width="273"
- hide_scrollbar="false"
- layout="topleft"
- left="10"
- top_pad="2"
- max_length="1023"
- name="pick_desc"
- spellcheck="true"
- text_color="black"
- word_wrap="true" />
- <text
- type="string"
- length="1"
- font="SansSerifSmall"
- font.style="BOLD"
- follows="left|top|right"
- height="15"
- layout="topleft"
- left="10"
- name="location_label"
- text_color="white"
- top_pad="20"
- width="280">
- Location:
- </text>
- <text
- type="string"
- length="1"
- follows="left|top|right"
- height="50"
- layout="topleft"
- left="10"
- name="pick_location"
- top_pad="2"
- width="280"
- word_wrap="true">
- loading...
- </text>
- <button
- follows="left|top"
- height="23"
- label="Set to Current Location"
- layout="topleft"
- left="8"
- top_pad="0"
- name="set_to_curr_location_btn"
- width="200" />
- </panel>
- </scroll_container>
- <panel
- follows="left|right|bottom"
- height="23"
- label="bottom_panel"
- layout="topleft"
- left="8"
- name="bottom_panel"
- top_pad="5"
- width="315">
-
- <layout_stack
- follows="bottom|left|right"
- height="23"
- layout="topleft"
- name="layout_stack1"
- left="0"
- orientation="horizontal"
- top_pad="0"
- width="313">
-
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="topleft"
- left="0"
- name="layout_panel1"
- auto_resize="true"
- width="150">
- <button
- follows="bottom|left|right"
- height="23"
- label="Save Pick"
- layout="topleft"
- name="save_changes_btn"
- top="0"
- left="1"
- width="149" />
- </layout_panel>
-
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="topleft"
- left_pad="4"
- name="layout_panel2"
- auto_resize="true"
- width="146">
- <button
- follows="bottom|left|right"
- height="23"
- label="Cancel"
- layout="topleft"
- name="cancel_btn"
- top="0"
- left="1"
- width="145" />
- </layout_panel>
- </layout_stack>
-
- </panel>
-</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_edit_profile.xml b/indra/newview/skins/default/xui/en/panel_edit_profile.xml
deleted file mode 100644
index 2c7c8133d1..0000000000
--- a/indra/newview/skins/default/xui/en/panel_edit_profile.xml
+++ /dev/null
@@ -1,472 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel
- background_visible="true"
- class="edit_profile_panel"
- follows="all"
- height="585"
- label="Profile Edit"
- layout="topleft"
- left="0"
- name="edit_profile_panel"
- top="0"
- width="313">
- <string
- name="CaptionTextAcctInfo">
- [ACCTTYPE]
-[PAYMENTINFO] [AGEVERIFICATION]
- </string>
- <string
- name="RegisterDateFormat">
- [REG_DATE] ([AGE])
- </string>
- <string
- name="AcctTypeResident"
- value="Resident" />
- <string
- name="AcctTypeTrial"
- value="Trial" />
- <string
- name="AcctTypeCharterMember"
- value="Charter Member" />
- <string
- name="AcctTypeEmployee"
- value="Linden Lab Employee" />
- <string
- name="PaymentInfoUsed"
- value="Payment Info Used" />
- <string
- name="PaymentInfoOnFile"
- value="Payment Info On File" />
- <string
- name="NoPaymentInfoOnFile"
- value="No Payment Info On File" />
- <string
- name="AgeVerified"
- value="Age-verified" />
- <string
- name="NotAgeVerified"
- value="Not Age-verified" />
- <string
- name="partner_edit_link_url">
- http://www.secondlife.com/account/partners.php?lang=en
- </string>
- <string
- name="my_account_link_url">
- http://secondlife.com/my
- </string>
- <string
- name="no_partner_text"
- value="None" />
- <scroll_container
- color="DkGray2"
- follows="all"
- height="537"
- min_height="300"
- layout="topleft"
- left="8"
- width="292"
- name="profile_scroll"
- reserve_scroll_corner="true"
- opaque="true"
- top="10">
- <panel
- name="scroll_content_panel"
- follows="left|top|right"
- layout="topleft"
- top="0"
- height="537"
- min_height="300"
- left="0"
- width="292">
- <panel
- name="data_panel"
- follows="left|top|right"
- layout="topleft"
- top="0"
- height="537"
- min_height="300"
- left="0"
- width="292">
- <text
- top="5"
- follows="top|left"
- height="13"
- layout="topleft"
- left="10"
- name="display_name_label"
- text_color="LtGray"
- value="Display Name:"
- width="80" />
- <text
- top="5"
- follows="top|left"
- height="13"
- layout="topleft"
- left="10"
- name="solo_username_label"
- text_color="LtGray"
- value="Username:"
- visible="false"
- width="80" />
- <button
- name="set_name"
- layout="topleft"
- follows="top|left"
- image_overlay="Edit_Wrench"
- top="21"
- left="10"
- height="23"
- width="23"
- tool_tip="Set Display Name"/>
- <text
- follows="top|left"
- font="SansSerifBigBold"
- height="20"
- layout="topleft"
- left="10"
- name="solo_user_name"
- text_color="white"
- top_delta="3"
- translate="false"
- value="TestString PleaseIgnore"
- use_ellipses="true"
- visible="false"
- width="275" />
- <text
- follows="top|left"
- font="SansSerifBigBold"
- height="20"
- layout="topleft"
- left="43"
- name="user_name"
- text_color="white"
- top_delta="0"
- translate="false"
- value="TestString PleaseIgnore"
- use_ellipses="true"
- visible="true"
- width="250" />
- <text
- follows="top|left"
- font="SansSerifBold"
- height="20"
- layout="topleft"
- left_delta="0"
- name="user_name_small"
- text_color="white"
- top_delta="-4"
- translate="false"
- value="TestString PleaseIgnore"
- use_ellipses="true"
- visible="false"
- wrap="true"
- width="245" />
- <text
- follows="top|left"
- height="13"
- layout="topleft"
- left="10"
- name="user_label"
- text_color="LtGray"
- top_pad="8"
- value="Username:"
- width="70" />
- <text
- follows="top|left"
- height="20"
- layout="topleft"
- left_pad="0"
- name="user_slid"
- text_color="EmphasisColor"
- font="SansSerifBold"
- top_delta="-2"
- translate="false"
- use_ellipses="true"
- value="teststring.pleaseignore"
- wrap="true"
- width="205" />
- <panel
- name="lifes_images_panel"
- follows="left|top|right"
- height="244"
- layout="topleft"
- top="65"
- left="0"
- width="292">
- <panel
- follows="left|top"
- height="117"
- layout="topleft"
- left="10"
- name="second_life_image_panel"
- top="0"
- width="282">
- <text
- follows="left|top|right"
- font.style="BOLD"
- height="15"
- layout="topleft"
- left="0"
- top="10"
- name="second_life_photo_title_text"
- text_color="white"
- value="[SECOND_LIFE]:"
- width="100" />
- <texture_picker
- allow_no_texture="true"
- default_image_name="None"
- enabled="false"
- fallback_image="default_profile_picture.j2c"
- follows="top|left"
- height="124"
- layout="topleft"
- left="1"
- name="2nd_life_pic"
- top_pad="0"
- width="102" />
- </panel>
- <icon
- height="102"
- image_name="spacer24.tga"
- layout="topleft"
- name="2nd_life_edit_icon"
- label=""
- left="11"
- top_pad="-92"
- tool_tip="Click to select an image"
- width="102" />
- </panel>
- <text_editor
- type="string"
- length="1"
- follows="left|top|right"
- font="SansSerifSmall"
- height="102"
- layout="topleft"
- left="123"
- top="90"
- max_length="512"
- name="sl_description_edit"
- width="157"
- word_wrap="true">
- </text_editor>
- <panel
- follows="left|top"
- height="117"
- layout="topleft"
- top_pad="5"
- left="10"
- name="first_life_image_panel"
- width="285">
- <text
- follows="left|top|right"
- font.style="BOLD"
- height="15"
- layout="topleft"
- left="0"
- top_pad="10"
- name="real_world_photo_title_text"
- text_color="white"
- value="Real World:"
- width="100" />
- <texture_picker
- allow_no_texture="true"
- default_image_name="None"
- enabled="false"
- fallback_image="Generic_Person_Large"
- follows="top|left"
- height="124"
- layout="topleft"
- left="1"
- name="real_world_pic"
- top_pad="0"
- width="102" />
- </panel>
- <icon
- height="102"
- image_name="spacer24.tga"
- layout="topleft"
- name="real_world_edit_icon"
- label=""
- left="11"
- top_pad="-92"
- tool_tip="Click to select an image"
- width="102" />
- <text_editor
- type="string"
- length="1"
- follows="left|top|right"
- font="SansSerifSmall"
- height="102"
- layout="topleft"
- left="123"
- max_length="512"
- top="223"
- name="fl_description_edit"
- width="157"
- word_wrap="true">
- </text_editor>
- <text
- type="string"
- length="1"
- follows="left|top"
- font="SansSerifSmall"
- font.style="BOLD"
- height="15"
- layout="topleft"
- left="10"
- name="title_homepage_text"
- text_color="white"
- top_pad="10"
- width="100">
- Homepage:
- </text>
- <line_editor
- follows="left|top|right"
- font="SansSerifSmall"
- height="20"
- layout="topleft"
- left="10"
- top_pad="0"
- value="http://"
- name="homepage_edit"
- width="272">
- </line_editor>
- <text
- follows="left|top"
- font="SansSerifSmall"
- font.style="BOLD"
- height="15"
- layout="topleft"
- left="10"
- name="title_acc_status_text"
- text_color="white"
- top_pad="10"
- value="My Account:"
- width="100" />
- <text_editor
- allow_scroll="false"
- bg_visible="false"
- follows="left|top|right"
- h_pad="0"
- height="28"
- layout="topleft"
- left="10"
- name="acc_status_text"
- read_only="true"
- top_pad="5"
- v_pad="0"
- value="Resident. No payment info on file."
- width="200"
- word_wrap="true" />
- <text
- type="string"
- follows="left|top"
- font="SansSerifSmall"
- height="15"
- layout="topleft"
- left="10"
- name="my_account_link"
- value="[[URL] Go to My Dashboard]"
- width="200" />
- <text
- follows="left|top"
- font="SansSerifSmall"
- font.style="BOLD"
- height="15"
- layout="topleft"
- left="10"
- name="title_partner_text"
- text_color="white"
- top_pad="10"
- value="My Partner:"
- width="150" />
- <panel
- follows="left|top|right"
- height="15"
- layout="topleft"
- left="10"
- name="partner_data_panel"
- width="200">
- <text
- follows="left|top|right"
- height="12"
- initial_value="(retrieving)"
- layout="topleft"
- left="0"
- name="partner_text"
- top="0"
- use_ellipses="true"
- width="280"/>
- </panel>
- <text
- follows="left|top"
- height="15"
- layout="topleft"
- link="true"
- left="10"
- name="partner_edit_link"
- value="[[URL] Edit]"
- width="70" />
- </panel>
- </panel>
- </scroll_container>
- <panel
- follows="bottom|left|right"
- height="28"
- left="0"
- name="profile_me_buttons_panel"
- top_pad="0"
- width="313">
-
- <layout_stack
- follows="bottom|left|right"
- height="28"
- layout="topleft"
- name="bottom_panel_ls"
- left="7"
- orientation="horizontal"
- top_pad="0"
- width="295">
-
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="bottomleft"
- name="save_changes_btn_lp"
- top="0"
- auto_resize="true"
- width="153">
- <button
- follows="bottom|left|right"
- height="23"
- label="Save Changes"
- layout="topleft"
- left="1"
- name="save_btn"
- top="0"
- width="152" />
- </layout_panel>
-
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="bottomleft"
- left_pad="3"
- name="show_on_map_btn_lp"
- top="0"
- auto_resize="true"
- width="154">
- <button
- follows="bottom|left|right"
- height="23"
- label="Cancel"
- layout="topleft"
- left="1"
- name="cancel_btn"
- top="0"
- width="153" />
- </layout_panel>
- </layout_stack>
- </panel>
-</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_group_list_item_short.xml b/indra/newview/skins/default/xui/en/panel_group_list_item_short.xml
new file mode 100644
index 0000000000..b72af7221e
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_group_list_item_short.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ name="group_list_item"
+ top="0"
+ left="0"
+ height="16"
+ width="320"
+ follows="top|right|left"
+ layout="topleft"
+>
+ <icon
+ name="hovered_icon"
+ top="0"
+ left="0"
+ height="16"
+ width="320"
+ follows="top|right|left"
+ layout="topleft"
+ image_name="ListItem_Over"
+ visible="false"
+ />
+ <icon
+ name="selected_icon"
+ top="0"
+ left="0"
+ height="16"
+ width="320"
+ follows="top|right|left"
+ layout="topleft"
+ image_name="ListItem_Select"
+ visible="false"
+ />
+ <group_icon
+ name="group_icon"
+ top="2"
+ left="5"
+ height="14"
+ width="14"
+ image_name="Generic_Group"
+ mouse_opaque="true"
+ use_draw_context_alpha="false"
+ />
+ <text
+ name="group_name"
+ value="Unknown"
+ top="2"
+ left_pad="5"
+ right="-2"
+ height="16"
+ follows="left|right"
+ layout="topleft"
+ parse_urls="false"
+ text_color="ScrollUnselectedColor"
+ use_ellipses="true"
+ />
+ <button
+ name="visibility_hide_btn"
+ tool_tip="Hide group on my profile"
+ top_delta="-3"
+ left_pad="3"
+ right="-53"
+ height="20"
+ width="20"
+ follows="right"
+ image_pressed="Profile_Group_Visibility_Off_Pressed"
+ image_unselected="Profile_Group_Visibility_Off"
+ tab_stop="false"
+ visible="false"
+ />
+ <button
+ name="visibility_show_btn"
+ tool_tip="Show group on my profile"
+ top_delta="0"
+ right_delta="0"
+ height="20"
+ width="20"
+ follows="right"
+ image_pressed="Profile_Group_Visibility_On_Pressed"
+ image_unselected="Profile_Group_Visibility_On"
+ tab_stop="false"
+ visible="false"
+ />
+ <button
+ name="info_btn"
+ tool_tip="More info"
+ top_delta="2"
+ left_pad="3"
+ right="-30"
+ height="16"
+ width="16"
+ follows="right"
+ image_pressed="Info_Press"
+ image_unselected="Info_Over"
+ tab_stop="false"
+ />
+ <!--*TODO: Should only appear on rollover-->
+ <button
+ name="profile_btn"
+ tool_tip="View profile"
+ top_delta="-2"
+ left_pad="5"
+ right="-3"
+ height="20"
+ width="20"
+ follows="right"
+ layout="topleft"
+ image_overlay="Web_Profile_Off"
+ tab_stop="false"
+ />
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_me.xml b/indra/newview/skins/default/xui/en/panel_me.xml
deleted file mode 100644
index 23e7814cad..0000000000
--- a/indra/newview/skins/default/xui/en/panel_me.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel
- background_visible="true"
- border="false"
- follows="all"
- height="570"
- label="My Profile"
- layout="topleft"
- left="0"
- name="panel_me"
- top="0"
- width="333">
- <panel
- class="panel_picks"
- filename="panel_picks.xml"
- label="MY PICKS"
- help_topic="panel_my_picks_tab"
- name="panel_picks"/>
-</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_pick_info.xml b/indra/newview/skins/default/xui/en/panel_pick_info.xml
deleted file mode 100644
index 99c47eb825..0000000000
--- a/indra/newview/skins/default/xui/en/panel_pick_info.xml
+++ /dev/null
@@ -1,190 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel
- background_visible="true"
- follows="all"
- height="570"
- layout="topleft"
- left="0"
- min_height="350"
- name="panel_pick_info"
- help_topic="profile_pick_info"
- top="0"
- width="333">
- <button
- follows="top|left"
- height="24"
- image_hover_unselected="BackButton_Over"
- image_pressed="BackButton_Press"
- image_unselected="BackButton_Off"
- layout="topleft"
- name="back_btn"
- left="10"
- tab_stop="false"
- top="2"
- width="30"
- use_draw_context_alpha="false" />
- <text
- follows="top|left|right"
- font="SansSerifHugeBold"
- height="26"
- layout="topleft"
- left_pad="4"
- name="title"
- text_color="LtGray"
- top="2"
- value="Pick Info"
- use_ellipses="true"
- width="275" />
- <scroll_container
- color="DkGray2"
- opaque="true"
- follows="all"
- height="503"
- layout="topleft"
- left="8"
- top_pad="10"
- name="profile_scroll"
- width="312">
- <panel
- name="scroll_content_panel"
- follows="left|top|right"
- min_height="300"
- layout="topleft"
- top="0"
- background_visible="false"
- height="400"
- left="0"
- width="285">
- <texture_picker
- fallback_image="default_land_picture.j2c"
- enabled="false"
- follows="left|top|right"
- height="197"
- layout="topleft"
- left="11"
- name="pick_snapshot"
- top="10"
- width="272" />
- <text_editor
- allow_scroll="false"
- bg_visible="false"
- follows="left|top|right"
- h_pad="0"
- height="35"
- width="280"
- layout="topleft"
- font="SansSerifBig"
- font.style="BOLD"
- left="10"
- top_pad="10"
- name="pick_name"
- read_only="true"
- text_color="white"
- v_pad="0"
- value="[name]"
- use_ellipses="true" />
- <text_editor
- allow_scroll="false"
- bg_visible="false"
- follows="left|top|right"
- h_pad="0"
- height="25"
- layout="topleft"
- left="10"
- name="pick_location"
- read_only="true"
- width="280"
- word_wrap="true"
- v_pad="0"
- value="[loading...]" />
- <text_editor
- bg_readonly_color="DkGray2"
- follows="all"
- height="100"
- width="280"
- parse_urls="true"
- layout="topleft"
- left="10"
- top_pad="2"
- max_length="1023"
- name="pick_desc"
- read_only="true"
- text_readonly_color="white"
- value="[description]"
- wrap="true" />
- </panel>
- </scroll_container>
- <panel
- follows="left|right|bottom"
- height="23"
- layout="topleft"
- top_pad="5"
- left="8"
- name="buttons">
-
- <layout_stack
- follows="bottom|left|right"
- height="23"
- layout="topleft"
- name="layout_stack1"
- left="0"
- orientation="horizontal"
- top_pad="0"
- width="312">
-
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="bottomleft"
- left="0"
- name="layout_panel1"
- auto_resize="true"
- width="101">
- <button
- follows="bottom|left|right"
- height="23"
- label="Teleport"
- layout="topleft"
- name="teleport_btn"
- top="0"
- width="101" />
- </layout_panel>
-
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="bottomleft"
- left_pad="3"
- name="show_on_map_btn_lp"
- auto_resize="true"
- width="100">
- <button
- follows="bottom|left|right"
- height="23"
- label="Map"
- layout="topleft"
- name="show_on_map_btn"
- top_pad="0"
- width="100" />
- </layout_panel>
-
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="bottomleft"
- left_pad="3"
- name="edit_btn_lp"
- auto_resize="true"
- width="101">
- <button
- follows="bottom|left|right"
- height="23"
- label="Edit"
- layout="topleft"
- name="edit_btn"
- top_pad="0"
- width="101" />
- </layout_panel>
- </layout_stack>
- </panel>
-</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_picks.xml b/indra/newview/skins/default/xui/en/panel_picks.xml
deleted file mode 100644
index 8def96cada..0000000000
--- a/indra/newview/skins/default/xui/en/panel_picks.xml
+++ /dev/null
@@ -1,227 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel
-bg_opaque_color="DkGray2"
- background_visible="true"
- background_opaque="true"
- follows="all"
- height="571"
- label="Picks"
- layout="topleft"
- left="8"
- name="panel_picks"
- top_pad="0"
- width="313">
- <string
- name="no_picks"
- value="No Picks" />
- <string
- name="no_classifieds"
- value="No Classifieds" />
- <text
- type="string"
- follows="all"
- height="535"
- layout="topleft"
- left="6"
- name="picks_panel_text"
- wrap="true"
- top="10"
- width="313"/>
- <accordion
- fit_parent="true"
- follows="all"
- height="514"
- layout="topleft"
- left="0"
- name="accordion"
- top="0"
- single_expansion="true"
- width="313">
- <accordion_tab
- layout="topleft"
- height="235"
- min_height="150"
- name="tab_picks"
- title="Picks"
- visible="false">
- <flat_list_view
- color="DkGray2"
- follows="all"
- layout="topleft"
- left="0"
- name="picks_list"
- opaque="true"
- top="0"
- width="313" />
- </accordion_tab>
- <accordion_tab
- layout="topleft"
- height="235"
- name="tab_classifieds"
- title="Classifieds"
- visible="false">
- <flat_list_view
- color="DkGray2"
- follows="all"
- layout="topleft"
- left="0"
- name="classifieds_list"
- opaque="true"
- top="0"
- width="313" />
- </accordion_tab>
- </accordion>
- <panel
- bg_opaque_color="DkGray2"
- background_visible="true"
- background_opaque="true"
- bevel_style="none"
- enabled="false"
- follows="bottom|left|right"
- left="1"
- height="27"
- label="bottom_panel"
- layout="topleft"
- name="edit_panel"
- top_pad="0"
- width="312">
-
- <layout_stack
- follows="bottom|left|right"
- height="23"
- layout="bottomleft"
- name="edit_panel_ls"
- left="10"
- orientation="horizontal"
- top_pad="0"
- width="293">
-
- <layout_panel
- follows="bottom|left"
- height="18"
- layout="bottomleft"
- left="0"
- name="gear_menu_btn"
- auto_resize="true"
- width="51">
- <button
- follows="bottom|left"
- height="18"
- image_disabled="AddItem_Disabled"
- image_selected="AddItem_Press"
- image_unselected="AddItem_Off"
- layout="topleft"
- left="0"
- name="new_btn"
- tool_tip="Create a new pick or classified at the current location"
- top="0"
- width="18" />
- </layout_panel>
-
- <layout_panel
- follows="bottom|right"
- height="18"
- layout="bottomleft"
- name="trash_btn_lp"
- auto_resize="true"
- width="18">
- <button
- follows="bottom|right"
- height="18"
- image_disabled="TrashItem_Disabled"
- image_selected="TrashItem_Press"
- image_unselected="TrashItem_Off"
- layout="topleft"
- name="trash_btn"
- top="0"
- width="18" />
- </layout_panel>
-
- </layout_stack>
- </panel>
-
- <panel
- bg_opaque_color="DkGray"
- background_visible="true"
- background_opaque="true"
- follows="bottom|left|right"
- layout="topleft"
- left="0"
- height="30"
- name="buttons_cucks"
- top_pad="0"
- width="313">
-
- <layout_stack
- follows="bottom|left|right"
- height="28"
- layout="topleft"
- left="2"
- name="buttons_cucks_ls"
- orientation="horizontal"
- top="0"
- width="313">
-
- <layout_panel
- follows="bottom|left|right"
- height="28"
- layout="topleft"
- left="0"
- name="info_btn_lp"
- auto_resize="true"
- top="0"
- width="95">
- <button
- enabled="false"
- follows="top|left|right"
- height="23"
- label="Info"
- layout="topleft"
- name="info_btn"
- tab_stop="false"
- tool_tip="Show pick information"
- width="95" />
- </layout_panel>
-
- <layout_panel
- follows="bottom|left|right"
- height="28"
- layout="bottomleft"
- left_pad="2"
- name="teleport_btn_lp"
- auto_resize="true"
- width="117">
- <button
- enabled="false"
- follows="top|left|right"
- height="23"
- label="Teleport"
- layout="topleft"
- name="teleport_btn"
- tab_stop="false"
- tool_tip="Teleport to the corresponding area"
- width="117" />
- </layout_panel>
-
- <layout_panel
- follows="bottom|left|right"
- height="28"
- layout="bottomleft"
- name="show_on_map_btn_lp"
- auto_resize="true"
- left_pad="2"
- width="90">
- <button
- enabled="false"
- follows="top|left|right"
- height="23"
- label="Map"
- layout="topleft"
- name="show_on_map_btn"
- tab_stop="false"
- tool_tip="Show the corresponding area on the World Map"
- width="88" />
- </layout_panel>
- </layout_stack>
- </panel>
-</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_profile_classified.xml b/indra/newview/skins/default/xui/en/panel_profile_classified.xml
new file mode 100644
index 0000000000..c9e8b242d4
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_profile_classified.xml
@@ -0,0 +1,830 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ name="panel_profile_classified"
+ top="0"
+ left="0"
+ height="420"
+ width="315"
+ follows="all"
+ layout="topleft"
+ help_topic="panel_profile_classified"
+ min_height="250"
+>
+ <panel.string
+ name="type_mature"
+ >
+ Moderate
+ </panel.string>
+ <panel.string
+ name="type_pg"
+ >
+ General Content
+ </panel.string>
+ <panel.string
+ name="l$_price"
+ >
+ L$[PRICE]
+ </panel.string>
+ <panel.string
+ name="click_through_text_fmt"
+ >
+ [TELEPORT] teleport, [MAP] map, [PROFILE] profile
+ </panel.string>
+ <panel.string
+ name="date_fmt"
+ >
+ [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt]
+ </panel.string>
+ <panel.string
+ name="auto_renew_on"
+ >
+ Enabled
+ </panel.string>
+ <panel.string
+ name="auto_renew_off"
+ >
+ Disabled
+ </panel.string>
+ <panel.string
+ name="location_notice"
+ >
+ (will update after save)
+ </panel.string>
+ <string
+ name="publish_label"
+ >
+ Publish
+ </string>
+ <string
+ name="save_label"
+ >
+ Save
+ </string>
+
+ <layout_stack
+ name="main_classifieds_stack"
+ top="0"
+ bottom="-1"
+ left="0"
+ width="310"
+ follows="all"
+ layout="topleft"
+ orientation="vertical"
+ animate="false"
+ >
+ <layout_panel
+ follows="all"
+ width="310"
+ height="300"
+ layout="topleft"
+ name="scroll_layout_panel"
+ auto_resize="true">
+ <scroll_container
+ name="profile_scroll"
+ top="0"
+ left="0"
+ height="300"
+ width="310"
+ follows="all"
+ layout="topleft"
+ color="DkGray2"
+ opaque="true"
+ reserve_scroll_corner="false"
+ >
+ <panel
+ name="info_scroll_content_panel"
+ top="0"
+ left="0"
+ height="562"
+ width="280"
+ follows="left|top|right"
+ layout="topleft"
+ background_visible="false"
+ min_height="200"
+ >
+ <texture_picker
+ name="classified_snapshot"
+ enabled="false"
+ top="0"
+ left="10"
+ height="161"
+ width="260"
+ follows="left|top"
+ layout="topleft"
+ fallback_image="default_land_picture.j2c"
+ />
+ <icon
+ name="edit_icon"
+ label=""
+ tool_tip="Click to select an image"
+ top="0"
+ left="0"
+ height="161"
+ width="260"
+ layout="topleft"
+ follows="left|top"
+ image_name="spacer24.tga"
+ visible="false"
+ />
+ <layout_stack
+ name="info_panel"
+ top="145"
+ left="0"
+ height="375"
+ width="310"
+ follows="all"
+ layout="topleft"
+ visible="true"
+ animate="false"
+ orientation="vertical"
+ >
+ <layout_panel
+ name="main_info_panel"
+ top="0"
+ left="0"
+ height="160"
+ width="280"
+ follows="all"
+ layout="topleft"
+ auto_resize="false"
+ >
+ <text_editor
+ name="classified_name"
+ top="0"
+ left="10"
+ height="35"
+ width="270"
+ follows="left|top|right"
+ layout="topleft"
+ allow_scroll="false"
+ bg_visible="false"
+ font="SansSerifBig"
+ font.style="BOLD"
+ h_pad="0"
+ read_only="true"
+ text_color="white"
+ use_ellipses="true"
+ v_pad="0"
+ >
+ [name]
+ </text_editor>
+ <text
+ name="classified_location_label"
+ value="Location:"
+ top_pad="-2"
+ left="10"
+ height="10"
+ width="250"
+ follows="left|top"
+ layout="topleft"
+ font.style="BOLD"
+ text_color="white"
+ />
+ <text_editor
+ name="classified_location"
+ value="[loading...]"
+ top_pad="5"
+ left="10"
+ height="30"
+ width="280"
+ follows="left|top"
+ layout="topleft"
+ allow_scroll="false"
+ bg_visible="false"
+ h_pad="0"
+ read_only="true"
+ v_pad="0"
+ word_wrap="true"
+ />
+ <text
+ name="content_type_label"
+ value="Content Type:"
+ top_pad="10"
+ left="10"
+ height="10"
+ width="140"
+ follows="left|top"
+ layout="topleft"
+ font.style="BOLD"
+ text_color="white"
+ />
+ <icon
+ name="content_type_moderate"
+ top_pad="-11"
+ left_pad="0"
+ height="16"
+ width="18"
+ follows="top|left"
+ layout="topleft"
+ image_name="Parcel_M_Light"
+ />
+ <icon
+ name="content_type_general"
+ top_delta="0"
+ left_delta="0"
+ height="16"
+ width="18"
+ follows="top|left"
+ layout="topleft"
+ image_name="Parcel_PG_Light"
+ />
+ <text_editor
+ name="content_type"
+ value="[content type]"
+ top_delta="1"
+ left_pad="2"
+ height="18"
+ width="130"
+ follows="left|top|right"
+ layout="topleft"
+ allow_scroll="false"
+ bg_visible="false"
+ h_pad="0"
+ read_only="true"
+ v_pad="0"
+ />
+ <text
+ name="category_label"
+ value="Category:"
+ top_pad="0"
+ left="10"
+ height="10"
+ width="140"
+ follows="left|top"
+ layout="topleft"
+ font.style="BOLD"
+ text_color="white"
+ />
+ <text_editor
+ name="category"
+ value="[category]"
+ top_pad="-10"
+ left_pad="0"
+ height="18"
+ width="150"
+ follows="left|top|right"
+ layout="topleft"
+ allow_scroll="false"
+ bg_visible="false"
+ h_pad="0"
+ parse_urls="true"
+ read_only="true"
+ v_pad="0"
+ />
+ <text
+ name="creation_date_label"
+ value="Creation date:"
+ top_pad="0"
+ left="10"
+ height="10"
+ width="140"
+ follows="left|top"
+ layout="topleft"
+ font.style="BOLD"
+ text_color="white"
+ />
+ <text_editor
+ name="creation_date"
+ value="[date]"
+ tool_tip="Creation date"
+ top_pad="-10"
+ left_pad="0"
+ height="16"
+ width="150"
+ follows="left|top"
+ layout="topleft"
+ allow_scroll="false"
+ bg_visible="false"
+ h_pad="0"
+ halign="left"
+ read_only="true"
+ v_pad="0"
+ />
+ <text
+ name="price_for_listing_label"
+ value="Price for listing:"
+ top_pad="5"
+ left="10"
+ height="10"
+ width="140"
+ follows="left|top"
+ layout="topleft"
+ font.style="BOLD"
+ text_color="white"
+ />
+ <text_editor
+ name="price_for_listing"
+ tool_tip="Price for listing."
+ top_pad="-10"
+ left_pad="0"
+ height="16"
+ width="105"
+ follows="left|top"
+ layout="topleft"
+ allow_scroll="false"
+ bg_visible="false"
+ h_pad="0"
+ halign="left"
+ read_only="true"
+ v_pad="0"
+ >
+ [PRICE]
+ </text_editor>
+ </layout_panel>
+ <layout_panel
+ name="clickthrough_layout_panel"
+ top="0"
+ left="0"
+ height="16"
+ width="290"
+ follows="all"
+ layout="topleft"
+ auto_resize="false"
+ >
+ <text
+ name="click_through_label"
+ value="Clicks:"
+ top_pad="0"
+ left="10"
+ height="10"
+ width="140"
+ follows="left|top"
+ layout="topleft"
+ font.style="BOLD"
+ text_color="white"
+ />
+ <text_editor
+ name="click_through_text"
+ value="[clicks]"
+ tool_tip="Click through data"
+ top_pad="-10"
+ left_pad="0"
+ height="16"
+ width="150"
+ follows="left|top"
+ layout="topleft"
+ allow_scroll="false"
+ bg_visible="false"
+ h_pad="0"
+ halign="left"
+ read_only="true"
+ v_pad="0"
+ />
+ </layout_panel>
+ <layout_panel
+ name="auto_renew_layout_panel"
+ top="0"
+ left="0"
+ height="16"
+ width="290"
+ follows="all"
+ layout="topleft"
+ auto_resize="false"
+ >
+ <text
+ name="auto_renew_label"
+ value="Auto renew:"
+ top="0"
+ left="10"
+ height="10"
+ width="140"
+ follows="left|top"
+ layout="topleft"
+ font.style="BOLD"
+ text_color="white"
+ />
+ <text
+ name="auto_renew"
+ value="Enabled"
+ top_pad="-10"
+ left_pad="0"
+ height="16"
+ width="150"
+ follows="top|left"
+ layout="topleft"
+ />
+ </layout_panel>
+ <layout_panel
+ name="descr_layout_panel"
+ top="0"
+ left="0"
+ height="220"
+ width="290"
+ follows="all"
+ layout="topleft"
+ auto_resize="true"
+ >
+ <text
+ name="classified_desc_label"
+ value="Description:"
+ top="0"
+ left="10"
+ height="10"
+ width="250"
+ follows="left|top"
+ layout="topleft"
+ font.style="BOLD"
+ text_color="white"
+ />
+ <text_editor
+ name="classified_desc"
+ trusted_content="false"
+ value="[description]"
+ top_pad="7"
+ left="10"
+ height="200"
+ width="280"
+ follows="all"
+ layout="topleft"
+ allow_scroll="false"
+ bg_visible="false"
+ h_pad="0"
+ max_length="1023"
+ parse_urls="true"
+ read_only="true"
+ v_pad="0"
+ word_wrap="true"
+ />
+ </layout_panel>
+ </layout_stack>
+ <panel
+ name="edit_panel"
+ top="145"
+ left="0"
+ height="420"
+ width="320"
+ follows="left|top|right"
+ layout="topleft"
+ visible="false"
+ >
+ <text
+ name="Name:"
+ top="0"
+ left="10"
+ height="15"
+ width="280"
+ follows="left|top"
+ layout="topleft"
+ font="SansSerifSmall"
+ font.style="BOLD"
+ length="1"
+ text_color="white"
+ type="string"
+ >
+ Title:
+ </text>
+ <line_editor
+ name="classified_name_edit"
+ top_pad="2"
+ left="10"
+ height="20"
+ width="273"
+ follows="left|top|right"
+ layout="topleft"
+ font="SansSerif"
+ max_length_bytes="30"
+ prevalidate_callback="ascii"
+ commit_on_focus_lost="false"
+ text_color="black"
+ />
+ <text
+ name="description_label"
+ top_pad="10"
+ left="10"
+ height="15"
+ width="280"
+ follows="left|top"
+ layout="topleft"
+ font="SansSerifSmall"
+ font.style="BOLD"
+ length="1"
+ text_color="white"
+ type="string"
+ >
+ Description:
+ </text>
+ <text_editor
+ name="classified_desc_edit"
+ top_pad="2"
+ left="10"
+ height="100"
+ width="273"
+ follows="left|top|right"
+ layout="topleft"
+ max_length="256"
+ text_color="black"
+ word_wrap="true"
+ />
+ <text
+ name="location_label"
+ top_pad="10"
+ left="10"
+ height="15"
+ width="280"
+ follows="left|top"
+ layout="topleft"
+ font="SansSerifSmall"
+ font.style="BOLD"
+ length="1"
+ text_color="white"
+ type="string"
+ >
+ Location:
+ </text>
+ <text
+ name="classified_location_edit"
+ top_pad="2"
+ left="10"
+ right="-10"
+ height="30"
+ width="280"
+ follows="left|top"
+ layout="topleft"
+ length="1"
+ type="string"
+ word_wrap="true"
+ >
+ loading...
+ </text>
+ <button
+ name="set_to_curr_location_btn"
+ label="Set to Current Location"
+ top_pad="5"
+ left="10"
+ height="23"
+ width="200"
+ follows="left|top"
+ layout="topleft"
+ />
+ <text
+ name="category_label"
+ value="Category:"
+ top_pad="10"
+ left="10"
+ height="10"
+ width="120"
+ follows="left|top"
+ layout="topleft"
+ font.style="BOLD"
+ text_color="white"
+ />
+ <combo_box
+ name="category_edit"
+ label=""
+ top_delta="-3"
+ left_pad="0"
+ height="23"
+ width="156"
+ follows="left|top"
+ />
+ <text
+ name="content_type_label"
+ value="Content type:"
+ top_pad="15"
+ left="10"
+ height="10"
+ width="120"
+ follows="left|top"
+ layout="topleft"
+ font.style="BOLD"
+ text_color="white"
+ />
+ <icons_combo_box
+ name="content_type_edit"
+ label="General Content"
+ top_delta="-3"
+ left_pad="0"
+ height="23"
+ width="156"
+ follows="left|top"
+ layout="topleft"
+ >
+ <icons_combo_box.drop_down_button
+ image_overlay="Parcel_PG_Light"
+ image_overlay_alignment="left"
+ imgoverlay_label_space="3"
+ pad_left="3"
+ />
+ <icons_combo_box.item
+ name="mature_ci"
+ label="Moderate Content"
+ value="Mature"
+ >
+ <item.columns
+ value="Parcel_M_Light"
+ width="20"
+ halign="center"
+ type="icon"
+ />
+ </icons_combo_box.item>
+ <icons_combo_box.item
+ name="pg_ci"
+ label="General Content"
+ value="PG"
+ >
+ <item.columns
+ value="Parcel_PG_Light"
+ width="20"
+ halign="center"
+ type="icon"
+ />
+ </icons_combo_box.item>
+ </icons_combo_box>
+ <check_box
+ name="auto_renew_edit"
+ label="Auto renew each week"
+ top_pad="10"
+ left="10"
+ height="16"
+ width="250"
+ layout="topleft"
+ />
+ </panel>
+ </panel>
+ </scroll_container>
+ </layout_panel>
+
+ <layout_panel
+ follows="all"
+ width="310"
+ height="25"
+ layout="topleft"
+ name="util_buttons_lp"
+ auto_resize="true">
+ <layout_stack
+ name="util_buttons_stack"
+ bottom="-1"
+ left="1"
+ right="-1"
+ height="25"
+ follows="left|bottom|right"
+ layout="topleft"
+ orientation="horizontal"
+ animate="false"
+ >
+ <layout_panel
+ follows="all"
+ layout="topleft"
+ name="util_resizer_left"
+ auto_resize="true"
+ user_resize="false"
+ width="1"/>
+
+ <layout_panel
+ follows="all"
+ height="25"
+ layout="topleft"
+ left="0"
+ name="teleport_btn_lp"
+ auto_resize="false"
+ top="0"
+ width="85">
+ <button
+ name="teleport_btn"
+ label="Teleport"
+ top="0"
+ left="0"
+ height="23"
+ max_width="101"
+ width="85"
+ follows="bottom|left|right"
+ layout="topleft"
+ />
+ </layout_panel>
+
+ <layout_panel
+ follows="all"
+ height="25"
+ layout="bottomleft"
+ left_pad="2"
+ name="map_btn_lp"
+ auto_resize="false"
+ max_width="101"
+ width="85">
+ <button
+ name="show_on_map_btn"
+ label="Map"
+ top="0"
+ left="0"
+ height="23"
+ width="85"
+ follows="bottom|left|right"
+ layout="topleft"
+ />
+ </layout_panel>
+
+ <layout_panel
+ follows="all"
+ height="25"
+ layout="bottomleft"
+ left_pad="2"
+ name="edit_btn_lp"
+ auto_resize="false"
+ max_width="101"
+ width="85">
+ <button
+ name="edit_btn"
+ label="Edit"
+ top="0"
+ left="0"
+ height="23"
+ width="85"
+ follows="bottom|left|right"
+ layout="topleft"
+ />
+ </layout_panel>
+
+ <layout_panel
+ follows="all"
+ layout="topleft"
+ name="util_resizer_right"
+ auto_resize="true"
+ width="1">
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ <layout_panel
+ follows="all"
+ width="310"
+ height="41"
+ layout="topleft"
+ name="publish_layout_panel"
+ auto_resize="false">
+ <view_border
+ bevel_style="none"
+ height="0"
+ follows="left|top|right"
+ layout="topleft"
+ left="0"
+ name="publish_emphasis_border"
+ top="5"
+ width="310"/>
+ <layout_stack
+ name="publish_stack"
+ left="1"
+ right="-1"
+ top="11"
+ height="25"
+ follows="left|top|right"
+ layout="topleft"
+ orientation="horizontal"
+ animate="false"
+ >
+ <layout_panel
+ follows="all"
+ layout="topleft"
+ name="pbl_resizer_left"
+ auto_resize="true"
+ user_resize="false"
+ width="1"/>
+
+ <layout_panel
+ follows="all"
+ layout="topleft"
+ name="save_btn_lp"
+ auto_resize="false"
+ width="134">
+ <button
+ name="save_changes_btn"
+ label="[LABEL]"
+ top="0"
+ left="0"
+ left_pad="5"
+ height="23"
+ width="134"
+ follows="left|top"
+ layout="topleft"
+ />
+ </layout_panel>
+
+ <layout_panel
+ follows="all"
+ layout="bottomleft"
+ left_pad="2"
+ name="cancel_btn_lp"
+ auto_resize="false"
+ width="134">
+ <button
+ name="cancel_btn"
+ label="Cancel"
+ top="0"
+ left="0"
+ height="23"
+ width="134"
+ follows="left|top"
+ layout="topleft"
+ />
+ </layout_panel>
+
+ <layout_panel
+ follows="all"
+ layout="topleft"
+ name="pbl_resizer_right"
+ auto_resize="true"
+ width="1">
+ </layout_panel>
+
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_profile_classifieds.xml b/indra/newview/skins/default/xui/en/panel_profile_classifieds.xml
new file mode 100644
index 0000000000..2b2f60e0c2
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_profile_classifieds.xml
@@ -0,0 +1,142 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ name="panel_profile_classifieds"
+ label="Classified"
+ top="0"
+ left="0"
+ height="480"
+ width="420"
+ follows="all"
+ layout="topleft"
+>
+ <string
+ name="no_classifieds"
+ value="No Classifieds"
+ />
+
+ <layout_stack
+ name="main_stack"
+ top="0"
+ left="0"
+ right="-1"
+ bottom="-1"
+ follows="all"
+ layout="topleft"
+ animate="false"
+ orientation="vertical">
+ <layout_panel
+ name="buttons_header"
+ follows="all"
+ layout="topleft"
+ height="50"
+ auto_resize="false"
+ user_resize="false">
+ <button
+ name="new_btn"
+ label="New..."
+ tool_tip="Create a new classified at the current location"
+ enabled="false"
+ top="25"
+ left="5"
+ height="20"
+ width="70"
+ follows="left|top"
+ layout="topleft"
+ visible="true"
+ />
+ <button
+ name="delete_btn"
+ label="Delete..."
+ tool_tip="Delete currently selected classified"
+ enabled="false"
+ left_pad="5"
+ height="20"
+ width="70"
+ follows="left|top"
+ layout="topleft"
+ visible="true"
+ />
+ </layout_panel>
+ <layout_panel
+ name="main_body"
+ follows="all"
+ layout="topleft"
+ height="430"
+ auto_resize="true"
+ user_resize="false">
+ <tab_container
+ name="tab_classifieds"
+ top="0"
+ bottom="-1"
+ left="4"
+ right="-4"
+ follows="all"
+ layout="topleft"
+ halign="left"
+ tab_position="left"
+ tab_width="150"
+ use_ellipses="true"
+ />
+
+ <layout_stack
+ name="indicator_stack"
+ top="220"
+ left="0"
+ right="-1"
+ height="28"
+ follows="top|left|right"
+ layout="topleft"
+ animate="false"
+ orientation="horizontal">
+ <layout_panel
+ name="indicator_spacer_left"
+ follows="all"
+ layout="topleft"
+ width="100"
+ auto_resize="true"
+ user_resize="false">
+ </layout_panel>
+ <layout_panel
+ name="buttons_header"
+ follows="all"
+ layout="topleft"
+ width="25"
+ auto_resize="false"
+ user_resize="false">
+ <loading_indicator
+ name="progress_indicator"
+ top="1"
+ left="1"
+ height="23"
+ width="23"
+ follows="top|left"
+ layout="topleft"
+ visible="false"
+ />
+ </layout_panel>
+ <layout_panel
+ name="indicator_spacer_right"
+ follows="all"
+ layout="topleft"
+ width="100"
+ auto_resize="true"
+ user_resize="false">
+ </layout_panel>
+ </layout_stack>
+ <text
+ name="classifieds_panel_text"
+ top="250"
+ left="110"
+ right="-110"
+ height="25"
+ follows="left|top|right"
+ layout="topleft"
+ halign="center"
+ mouse_opaque="false"
+ wrap="true"
+ >
+ Loading...
+ </text>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_profile_firstlife.xml b/indra/newview/skins/default/xui/en/panel_profile_firstlife.xml
new file mode 100644
index 0000000000..ca1e405a62
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_profile_firstlife.xml
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ name="panel_profile_firstlife"
+ label="Profile"
+ top="0"
+ left="0"
+ height="480"
+ width="420"
+ follows="all"
+ layout="topleft"
+>
+ <loading_indicator
+ name="progress_indicator"
+ top="5"
+ right="-10"
+ height="23"
+ width="23"
+ follows="top|right"
+ layout="topleft"
+ visible="false"
+ />
+ <icon
+ name="real_world_pic"
+ image_name="Generic_Person_Large"
+ follows="top|left"
+ layout="topleft"
+ top="10"
+ left="8"
+ height="160"
+ width="160"/>
+ <loading_indicator
+ name="image_upload_indicator"
+ top="79"
+ left="77"
+ height="23"
+ width="23"
+ follows="top|left"
+ layout="topleft"
+ visible="false"/>
+ <button
+ name="fl_upload_image"
+ label="Upload Photo"
+ top="102"
+ left="175"
+ height="20"
+ width="120"
+ follows="top|left"
+ layout="topleft"/>
+ <button
+ name="fl_change_image"
+ label="Change Photo"
+ top_pad="5"
+ left="175"
+ height="20"
+ width="120"
+ follows="top|left"
+ layout="topleft"/>
+ <button
+ name="fl_remove_image"
+ label="Remove Photo"
+ top_pad="5"
+ left_delta="0"
+ height="20"
+ width="120"
+ follows="top|left"
+ layout="topleft"/>
+ <text_editor
+ name="fl_description_edit"
+ trusted_content="false"
+ enabled="false"
+ top="180"
+ left="6"
+ right="-6"
+ height="224"
+ follows="all"
+ layout="topleft"
+ bg_readonly_color="Transparent"
+ border_visible="true"
+ max_length="65000"
+ parse_urls="true"
+ word_wrap="true"
+ />
+ <button
+ name="fl_save_changes"
+ label="Save"
+ top_pad="5"
+ right="-108"
+ height="20"
+ width="80"
+ enabled="false"
+ follows="right|bottom"
+ layout="topleft"/>
+ <button
+ name="fl_discard_changes"
+ label="Discard"
+ top_delta="0"
+ right="-4"
+ height="20"
+ width="100"
+ enabled="false"
+ follows="right|bottom"
+ layout="topleft"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_profile_notes.xml b/indra/newview/skins/default/xui/en/panel_profile_notes.xml
new file mode 100644
index 0000000000..16e7365042
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_profile_notes.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ name="panel_notes"
+ label="Notes &amp; Privacy"
+ top="0"
+ left="0"
+ height="480"
+ width="420"
+ follows="all"
+ layout="topleft"
+>
+ <loading_indicator
+ name="progress_indicator"
+ top="3"
+ right="-10"
+ height="23"
+ width="23"
+ follows="top|right"
+ layout="topleft"
+ visible="false"
+ />
+ <text
+ name="status_message"
+ value="Make notes about this person here. No one else can see your notes."
+ top="6"
+ left="6"
+ right="-6"
+ height="16"
+ follows="left|top|right"
+ layout="topleft"
+ font.style="BOLD"
+ />
+ <text_editor
+ name="notes_edit"
+ enabled="false"
+ top="28"
+ left="6"
+ right="-6"
+ bottom="-26"
+ follows="all"
+ layout="topleft"
+ max_length="65530"
+ word_wrap="true"
+ />
+ <button
+ name="notes_save_changes"
+ label="Save"
+ bottom="-1"
+ right="-108"
+ height="20"
+ width="80"
+ enabled="false"
+ follows="bottom|right"
+ layout="topleft"/>
+ <button
+ name="notes_discard_changes"
+ label="Discard"
+ bottom="-1"
+ right="-4"
+ height="20"
+ width="100"
+ enabled="false"
+ follows="bottom|right"
+ layout="topleft"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_profile_pick.xml b/indra/newview/skins/default/xui/en/panel_profile_pick.xml
new file mode 100644
index 0000000000..3e91640093
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_profile_pick.xml
@@ -0,0 +1,314 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ name="panel_pick_info"
+ top="0"
+ left="0"
+ height="360"
+ width="310"
+ follows="all"
+ layout="topleft"
+ help_topic="profile_pick_info"
+>
+ <panel.string
+ name="location_notice"
+ >
+ (will update after save)
+ </panel.string>
+
+ <layout_stack
+ name="main_pick_stack"
+ left="1"
+ right="-1"
+ top="0"
+ bottom="-1"
+ follows="all"
+ layout="topleft"
+ orientation="vertical"
+ animate="false">
+ <layout_panel
+ follows="all"
+ layout="bottomleft"
+ left_pad="2"
+ name="main_pick_lp"
+ auto_resize="true"
+ height="314">
+ <texture_picker
+ name="pick_snapshot"
+ top="10"
+ left="10"
+ height="161"
+ width="260"
+ follows="left|top"
+ layout="topleft"
+ fallback_image="default_land_picture.j2c"
+ />
+ <text
+ name="title_label"
+ top_pad="-15"
+ left="10"
+ height="15"
+ width="280"
+ follows="left|top"
+ layout="topleft"
+ font="SansSerifSmall"
+ font.style="BOLD"
+ length="1"
+ text_color="white"
+ type="string"
+ >
+ Title:
+ </text>
+ <line_editor
+ name="pick_name"
+ enabled="false"
+ top_pad="2"
+ left="10"
+ height="20"
+ width="290"
+ follows="left|right|top"
+ layout="topleft"
+ />
+ <text
+ name="description_label"
+ top_pad="10"
+ left="10"
+ height="15"
+ width="280"
+ follows="left|top"
+ layout="topleft"
+ font="SansSerifSmall"
+ font.style="BOLD"
+ length="1"
+ text_color="white"
+ type="string"
+ >
+ Description:
+ </text>
+ <text_editor
+ name="pick_desc"
+ trusted_content="false"
+ always_show_icons="true"
+ enabled="false"
+ top_pad="2"
+ left="10"
+ height="45"
+ width="290"
+ follows="all"
+ layout="topleft"
+ allow_html="true"
+ border_visible="true"
+ h_pad="4"
+ max_length="1023"
+ v_pad="3"
+ word_wrap="true"
+ />
+ <text
+ name="location_label"
+ bottom="-25"
+ left="10"
+ height="15"
+ width="280"
+ follows="left|right|bottom"
+ layout="topleft"
+ font="SansSerifSmall"
+ font.style="BOLD"
+ length="1"
+ text_color="white"
+ type="string"
+ >
+ Location:
+ </text>
+ <line_editor
+ name="pick_location"
+ enabled="false"
+ bottom="-1"
+ left="10"
+ height="23"
+ width="290"
+ follows="left|right|bottom"
+ layout="topleft"
+ length="1"
+ type="string"
+ >
+ Loading...
+ </line_editor>
+ </layout_panel>
+
+
+ <layout_panel
+ follows="all"
+ layout="bottomleft"
+ name="save_changes_lp"
+ auto_resize="false"
+ height="25">
+ <layout_stack
+ name="save_changes_stack"
+ left="1"
+ right="-1"
+ top="0"
+ height="25"
+ follows="left|top|right"
+ layout="topleft"
+ orientation="horizontal"
+ animate="false">
+
+ <layout_panel
+ follows="all"
+ layout="topleft"
+ name="util_resizer_left"
+ auto_resize="true"
+ width="1">
+ </layout_panel>
+
+ <layout_panel
+ follows="all"
+ layout="bottomleft"
+ left_pad="2"
+ name="map_btn_lp"
+ auto_resize="false"
+ width="100">
+ <button
+ name="show_on_map_btn"
+ label="Show on Map"
+ left="0"
+ top="0"
+ height="23"
+ width="100"
+ follows="left|top"
+ layout="topleft"
+ />
+ </layout_panel>
+
+ <layout_panel
+ follows="all"
+ layout="bottomleft"
+ left_pad="2"
+ name="tp_btn_lp"
+ auto_resize="false"
+ width="100">
+ <button
+ name="teleport_btn"
+ label="Teleport"
+ left="0"
+ top="0"
+ height="23"
+ width="100"
+ follows="left|top"
+ layout="topleft"
+ />
+ </layout_panel>
+
+ <layout_panel
+ follows="all"
+ layout="topleft"
+ name="util_resizer_right"
+ auto_resize="true"
+ width="1">
+ </layout_panel>
+
+ </layout_stack>
+ </layout_panel>
+
+ <layout_panel
+ follows="all"
+ layout="bottomleft"
+ name="save_changes_lp"
+ auto_resize="false"
+ height="41">
+ <view_border
+ bevel_style="none"
+ height="0"
+ follows="left|top|right"
+ layout="topleft"
+ left="0"
+ name="save_emphasis_border"
+ top="5"
+ width="310"/>
+ <layout_stack
+ name="save_changes_stack"
+ left="1"
+ right="-1"
+ top="11"
+ height="25"
+ follows="left|top|right"
+ layout="topleft"
+ orientation="horizontal"
+ animate="false">
+
+ <layout_panel
+ follows="all"
+ layout="topleft"
+ name="save_resizer_left"
+ auto_resize="true"
+ width="1">
+ </layout_panel>
+
+ <layout_panel
+ follows="all"
+ layout="bottomleft"
+ left_pad="2"
+ name="create_btn_lp"
+ auto_resize="false"
+ width="130">
+ <button
+ name="create_changes_btn"
+ label="Create Pick"
+ left="0"
+ top="0"
+ height="23"
+ width="130"
+ follows="left|top"
+ layout="topleft"
+ />
+ </layout_panel>
+
+ <layout_panel
+ follows="all"
+ layout="bottomleft"
+ left_pad="2"
+ name="save_btn_lp"
+ auto_resize="false"
+ width="130">
+ <button
+ name="save_changes_btn"
+ label="Save Pick"
+ left="0"
+ top="0"
+ height="23"
+ width="130"
+ follows="left|top"
+ layout="topleft"
+ />
+ </layout_panel>
+
+ <layout_panel
+ follows="all"
+ layout="bottomleft"
+ left_pad="2"
+ name="cancel_btn_lp"
+ auto_resize="false"
+ width="130">
+ <button
+ name="cancel_changes_btn"
+ label="Cancel"
+ left="0"
+ top="0"
+ height="23"
+ width="130"
+ follows="left|top"
+ layout="topleft"
+ />
+ </layout_panel>
+
+ <layout_panel
+ follows="all"
+ layout="topleft"
+ name="save_resizer_right"
+ auto_resize="true"
+ width="1">
+ </layout_panel>
+
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_profile_picks.xml b/indra/newview/skins/default/xui/en/panel_profile_picks.xml
new file mode 100644
index 0000000000..44d5c448c0
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_profile_picks.xml
@@ -0,0 +1,154 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ name="panel_picks"
+ label="Picks"
+ top="0"
+ left="0"
+ height="480"
+ width="420"
+ follows="all"
+ layout="topleft"
+>
+ <string
+ name="no_picks"
+ value="No Picks"
+ />
+
+ <layout_stack
+ name="main_stack"
+ top="0"
+ left="0"
+ right="-1"
+ bottom="-1"
+ follows="all"
+ layout="topleft"
+ animate="false"
+ orientation="vertical">
+ <layout_panel
+ name="buttons_header"
+ follows="all"
+ layout="topleft"
+ height="50"
+ auto_resize="false"
+ user_resize="false">
+ <text
+ name="header_text"
+ top="5"
+ left="5"
+ right="-5"
+ height="16"
+ follows="left|top|right"
+ layout="topleft"
+ halign="center"
+ >
+ Tell everyone about your favorite places in Second Life.
+ </text>
+ <button
+ name="new_btn"
+ label="New..."
+ tool_tip="Create a new pick at the current location"
+ enabled="false"
+ top_pad="4"
+ left="5"
+ height="20"
+ width="70"
+ follows="left|top"
+ layout="topleft"
+ visible="false"
+ />
+ <button
+ name="delete_btn"
+ label="Delete..."
+ tool_tip="Delete currently selected pick"
+ enabled="false"
+ left_pad="5"
+ height="20"
+ width="70"
+ follows="left|top"
+ layout="topleft"
+ visible="false"
+ />
+ </layout_panel>
+ <layout_panel
+ name="main_body"
+ follows="all"
+ layout="topleft"
+ height="430"
+ auto_resize="true"
+ user_resize="false">
+ <tab_container
+ name="tab_picks"
+ top="0"
+ bottom="-5"
+ left="4"
+ right="-4"
+ tab_width="150"
+ follows="all"
+ layout="topleft"
+ halign="left"
+ tab_position="left"
+ use_ellipses="true"
+ />
+
+ <layout_stack
+ name="indicator_stack"
+ top="220"
+ left="0"
+ right="-1"
+ height="28"
+ follows="top|left|right"
+ layout="topleft"
+ animate="false"
+ orientation="horizontal">
+ <layout_panel
+ name="indicator_spacer_left"
+ follows="all"
+ layout="topleft"
+ width="100"
+ auto_resize="true"
+ user_resize="false">
+ </layout_panel>
+ <layout_panel
+ name="buttons_header"
+ follows="all"
+ layout="topleft"
+ width="25"
+ auto_resize="false"
+ user_resize="false">
+ <loading_indicator
+ name="progress_indicator"
+ top="1"
+ left="1"
+ height="23"
+ width="23"
+ follows="top|left"
+ layout="topleft"
+ visible="false"
+ />
+ </layout_panel>
+ <layout_panel
+ name="indicator_spacer_right"
+ follows="all"
+ layout="topleft"
+ width="100"
+ auto_resize="true"
+ user_resize="false">
+ </layout_panel>
+ </layout_stack>
+ <text
+ name="picks_panel_text"
+ top="250"
+ left="100"
+ right="-100"
+ height="25"
+ follows="left|top|right"
+ layout="topleft"
+ halign="center"
+ mouse_opaque="false"
+ wrap="true"
+ >
+ Loading...
+ </text>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml
new file mode 100644
index 0000000000..551b477876
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml
@@ -0,0 +1,549 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ name="panel_profile"
+ label="Profile"
+ top="0"
+ left="0"
+ height="480"
+ width="420"
+ follows="all"
+ layout="topleft"
+>
+ <string
+ name="date_format"
+ value="SL birthdate: [mth,datetime,slt] [day,datetime,slt], [year,datetime,slt]" />
+ <string
+ name="age_format"
+ value="[AGE]" />
+ <string
+ name="partner_text"
+ value="Partner: [LINK]" />
+ <string
+ name="CaptionTextAcctInfo">
+Account: [ACCTTYPE]
+[PAYMENTINFO]
+ </string>
+
+ <layout_stack
+ name="image_stack"
+ top="8"
+ left="6"
+ bottom="-1"
+ width="160"
+ border_size="0"
+ follows="left|top|bottom"
+ layout="topleft"
+ animate="false"
+ orientation="vertical">
+ <layout_panel
+ name="image_panel"
+ follows="all"
+ layout="topleft"
+ width="160"
+ height="160"
+ auto_resize="false"
+ user_resize="false">
+
+ <icon
+ name="2nd_life_pic"
+ image_name="Generic_Person_Large"
+ layout="topleft"
+ follows="all"
+ interactable="true"
+ top="0"
+ left="2"
+ bottom="-1"
+ right="-1"/>
+
+ <loading_indicator
+ name="image_upload_indicator"
+ top="69"
+ left="69"
+ height="23"
+ width="23"
+ follows="top|left"
+ layout="topleft"
+ visible="false"/>
+ </layout_panel>
+
+ <layout_panel
+ name="basics_panel"
+ follows="all"
+ layout="topleft"
+ height="54"
+ auto_resize="false"
+ user_resize="false"
+ >
+ <line_editor
+ name="user_name"
+ border_thickness="0"
+ use_bg_color="false"
+ background_image_disabled=""
+ background_image_focused=""
+ enabled="false"
+ value="(loading...)"
+ top="4"
+ left="3"
+ right="-1"
+ height="16"
+ follows="left|top|right"
+ layout="topleft"/>
+
+ <line_editor
+ name="sl_birth_date"
+ border_thickness="0"
+ use_bg_color="false"
+ background_image_disabled=""
+ background_image_focused=""
+ enabled="false"
+ value="(loading...)"
+ top_pad="0"
+ left_delta="0"
+ right="-1"
+ height="16"
+ follows="left|top|right"
+ layout="topleft"/>
+
+ <line_editor
+ name="user_age"
+ border_thickness="0"
+ use_bg_color="false"
+ background_image_disabled=""
+ background_image_focused=""
+ enabled="false"
+ value="(loading...)"
+ top_pad="0"
+ left_delta="0"
+ right="-1"
+ height="16"
+ follows="left|top|right"
+ layout="topleft"/>
+ </layout_panel>
+ <layout_panel
+ name="partner_layout"
+ follows="all"
+ layout="topleft"
+ height="30"
+ auto_resize="false"
+ user_resize="false"
+ visible="true">
+ <text
+ type="string"
+ name="partner_link"
+ value="Partner: (loading...)"
+ top="0"
+ left="5"
+ right="-1"
+ height="28"
+ follows="left|top|right"
+ layout="topleft"
+ translate="false"
+ use_ellipses="true"
+ word_wrap="true"
+ visible="true"/>
+ </layout_panel>
+
+ <layout_panel
+ name="partner_spacer_layout"
+ follows="all"
+ layout="topleft"
+ height="14"
+ auto_resize="false"
+ user_resize="false"
+ visible="true">
+ </layout_panel>
+
+ <layout_panel
+ name="frind_layout"
+ follows="all"
+ layout="topleft"
+ height="16"
+ auto_resize="false"
+ user_resize="false"
+ visible="false">
+ <text
+ name="frind_text"
+ value="You are friends"
+ text_color="ConversationFriendColor"
+ top="0"
+ left="5"
+ right="-1"
+ height="16"
+ follows="left|top|right"
+ layout="topleft"
+ translate="false"
+ visible="true"/>
+ </layout_panel>
+ <layout_panel
+ name="online_layout"
+ follows="all"
+ layout="topleft"
+ height="16"
+ auto_resize="false"
+ user_resize="false"
+ visible="false">
+ <icon
+ name="online_icon"
+ image_name="Profile_Friend_Online"
+ layout="topleft"
+ follows="left|top"
+ top="0"
+ left="5"
+ height="10"
+ width="10"/>
+ <text
+ name="online_text"
+ value="Online"
+ top="0"
+ left="18"
+ right="-1"
+ height="16"
+ follows="left|top|right"
+ layout="topleft"
+ translate="false"
+ visible="true"/>
+ </layout_panel>
+ <layout_panel
+ name="offline_layout"
+ follows="all"
+ layout="topleft"
+ height="16"
+ auto_resize="false"
+ user_resize="false"
+ visible="false">
+ <icon
+ name="offline_icon"
+ image_name="Profile_Friend_Offline"
+ layout="topleft"
+ follows="left|top"
+ top="0"
+ left="5"
+ height="10"
+ width="10"/>
+ <text
+ name="offline_text"
+ value="Offline"
+ top="0"
+ left="18"
+ right="-1"
+ height="16"
+ follows="left|top|right"
+ layout="topleft"
+ translate="false"
+ visible="true"/>
+ </layout_panel>
+ <layout_panel
+ name="account_layout"
+ follows="all"
+ layout="topleft"
+ height="33"
+ auto_resize="false"
+ user_resize="false">
+ <text
+ name="account_info"
+ value="Account: (loading...)"
+ top="0"
+ left="5"
+ right="-1"
+ height="16"
+ follows="left|top|right"
+ layout="topleft"
+ word_wrap="true"/>
+ </layout_panel>
+ <layout_panel
+ name="indicator_stack"
+ follows="all"
+ layout="topleft"
+ height="33"
+ auto_resize="false"
+ user_resize="false">
+ <loading_indicator
+ name="progress_indicator"
+ left="67"
+ top="0"
+ height="23"
+ width="23"
+ follows="left|top"
+ layout="topleft"
+ visible="true"/>
+ </layout_panel>
+ <layout_panel
+ name="settings_panel"
+ follows="all"
+ layout="topleft"
+ height="50"
+ auto_resize="false"
+ user_resize="false">
+ <!-- only for self -->
+ <text
+ name="search_label"
+ value="Show my profile in search:"
+ top="1"
+ left="6"
+ right="-1"
+ height="16"
+ follows="left|top|right"
+ layout="topleft"/>
+ <combo_box
+ name="show_in_search"
+ tool_tip="Let people see you in search results"
+ left="1"
+ top="18"
+ height="23"
+ width="140"
+ follows="left|top"
+ layout="topleft"
+ visible="true"
+ enabled="false">
+ <combo_box.item
+ name="Hide"
+ label="Hide"
+ value="0" />
+ <combo_box.item
+ name="Show"
+ label="Show"
+ value="1" />
+ </combo_box>
+ </layout_panel>
+
+ <layout_panel
+ name="menu_panel"
+ follows="all"
+ layout="topleft"
+ height="55"
+ auto_resize="false"
+ user_resize="false"
+ >
+ <menu_button
+ layout="topleft"
+ follows="left|top"
+ left="1"
+ top="25"
+ height="25"
+ width="140"
+ label="Actions"
+ halign="left"
+ image_unselected="DropDown_Off"
+ image_selected="DropDown_On"
+ image_pressed="DropDown_Press"
+ image_pressed_selected="DropDown_Press"
+ image_disabled="DropDown_Disabled"
+ name="agent_actions_menu" />
+ </layout_panel>
+ </layout_stack>
+
+ <layout_stack
+ name="main_stack"
+ top="8"
+ left="168"
+ bottom="-1"
+ right="-1"
+ follows="all"
+ layout="topleft"
+ animate="false"
+ orientation="vertical">
+ <layout_panel
+ name="display_name_panel"
+ follows="all"
+ layout="topleft"
+ height="24"
+ auto_resize="false"
+ user_resize="false">
+ <line_editor
+ name="display_name"
+ border_thickness="0"
+ use_bg_color="false"
+ background_image_disabled=""
+ background_image_focused=""
+ enabled="false"
+ value="(loading...)"
+ font="SansSerifBigLarge"
+ top="0"
+ left="6"
+ height="19"
+ right="-86"
+ follows="left|top|right"
+ layout="topleft"/>
+
+ <icon
+ tool_tip="Friend can see my online status"
+ mouse_opaque="true"
+ name="can_see_online"
+ image_name="Profile_Perm_Online_Enabled"
+ layout="topleft"
+ follows="right|top"
+ interactable="true"
+ top="0"
+ right="-61"
+ height="24"
+ width="24"
+ left_pad="2" />
+
+ <icon
+ tool_tip="Friend can not see my online status"
+ mouse_opaque="true"
+ name="cant_see_online"
+ image_name="Profile_Perm_Online_Disabled"
+ layout="topleft"
+ follows="right|top"
+ interactable="true"
+ top="0"
+ right="-61"
+ height="24"
+ width="24"
+ left_pad="2" />
+
+ <icon
+ tool_tip="Friend can see me on map"
+ mouse_opaque="true"
+ name="can_see_on_map"
+ image_name="Profile_Perm_Find_Enabled"
+ layout="topleft"
+ follows="right|top"
+ interactable="true"
+ top="0"
+ right="-30"
+ height="24"
+ width="24"
+ left_pad="2" />
+
+ <icon
+ tool_tip="Friend can not see me on map"
+ mouse_opaque="true"
+ name="cant_see_on_map"
+ image_name="Profile_Perm_Find_Disabled"
+ layout="topleft"
+ follows="right|top"
+ interactable="true"
+ top="0"
+ right="-30"
+ height="24"
+ width="24"
+ left_pad="2" />
+
+ <icon
+ tool_tip="Friend can edit my objects"
+ mouse_opaque="true"
+ name="can_edit_objects"
+ image_name="Profile_Perm_Objects_Enabled"
+ layout="topleft"
+ follows="right|top"
+ interactable="true"
+ top="0"
+ right="-1"
+ height="24"
+ width="24"
+ left_pad="2" />
+
+ <icon
+ tool_tip="Friend can not edit my objects"
+ mouse_opaque="true"
+ name="cant_edit_objects"
+ image_name="Profile_Perm_Objects_Disabled"
+ layout="topleft"
+ follows="right|top"
+ interactable="true"
+ top="0"
+ right="-1"
+ height="24"
+ width="24"
+ left_pad="2" />
+
+ </layout_panel>
+
+ <layout_panel
+ name="about_panel"
+ follows="all"
+ layout="topleft"
+ height="159"
+ auto_resize="true"
+ user_resize="false">
+ <text_editor
+ name="sl_description_edit"
+ trusted_content="false"
+ always_show_icons="true"
+ commit_on_focus_lost="false"
+ enabled="false"
+ top="0"
+ left="2"
+ right="-1"
+ bottom="-1"
+ follows="all"
+ layout="topleft"
+ bg_readonly_color="Transparent"
+ border_visible="true"
+ font="SansSerifSmall"
+ h_pad="2"
+ max_length="65000"
+ parse_urls="true"
+ word_wrap="true"
+ />
+ </layout_panel>
+ <layout_panel
+ name="about_buttons_panel"
+ follows="all"
+ layout="topleft"
+ height="34"
+ auto_resize="false"
+ user_resize="false">
+ <button
+ name="save_description_changes"
+ label="Save"
+ top="1"
+ right="-105"
+ height="20"
+ width="80"
+ enabled="false"
+ follows="top|right"
+ layout="topleft"/>
+ <button
+ name="discard_description_changes"
+ label="Discard"
+ top="1"
+ right="-1"
+ height="20"
+ width="100"
+ enabled="false"
+ follows="top|right"
+ layout="topleft"/>
+ <view_border
+ bevel_style="none"
+ height="0"
+ layout="topleft"
+ left="0"
+ name="cost_text_border"
+ top_pad="9"
+ width="492"/>
+ </layout_panel>
+
+ <layout_panel
+ name="groups_panel"
+ follows="all"
+ layout="topleft"
+ height="159"
+ auto_resize="true"
+ user_resize="false">
+ <text
+ name="group_label"
+ value="Group memberships"
+ top="1"
+ left="2"
+ right="-1"
+ height="16"
+ follows="left|top|right"
+ layout="topleft"/>
+ <group_list
+ name="group_list"
+ top="18"
+ left="2"
+ right="-1"
+ bottom="-1"
+ follows="all"
+ layout="topleft"
+ border_visible="true"
+ color="ScrollBgWriteableColor"
+ for_agent="false"/>
+
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_profile_web.xml b/indra/newview/skins/default/xui/en/panel_profile_web.xml
new file mode 100644
index 0000000000..e0cb4d3d06
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_profile_web.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ name="panel_profile_web"
+ label="Web"
+ top="0"
+ left="0"
+ height="480"
+ width="420"
+ follows="all"
+ layout="topleft"
+>
+ <panel.string
+ name="LoadTime"
+ value="Load Time: [TIME] seconds"
+ />
+ <web_browser
+ name="profile_html"
+ top="10"
+ bottom="-18"
+ left="10"
+ right="-10"
+ follows="all"
+ layout="topleft"
+ start_url=""
+ />
+ <text
+ name="status_text"
+ bottom="-4"
+ left="110"
+ right="-110"
+ follows="bottom|left|right"
+ layout="topleft"
+ halign="center"
+ parse_urls="false"
+ />
+</panel>
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 8382e3970c..8c2db9bde3 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -2808,10 +2808,14 @@ If you continue to receive this message, please contact Second Life support for
<string name="ClassifiedClicksTxt">Clicks: [TELEPORT] teleport, [MAP] map, [PROFILE] profile</string>
<string name="ClassifiedUpdateAfterPublish">(will update after publish)</string>
- <!-- panel picks -->
- <string name="NoPicksClassifiedsText">You haven't created any Picks or Classifieds. Click the Plus button below to create a Pick or Classified.</string>
- <string name="NoAvatarPicksClassifiedsText">User has no picks or classifieds</string>
- <string name="PicksClassifiedsLoadingText">Loading...</string>
+ <!-- panel picks -->
+ <string name="NoPicksClassifiedsText">You haven't created any Picks or Classifieds. Click the Plus button below to create a Pick or Classified.</string>
+ <string name="NoPicksText">You haven't created any Picks. Click the New button to create a Pick.</string>
+ <string name="NoClassifiedsText">You haven't created any Classifieds. Click the New button to create a Classified.</string>
+ <string name="NoAvatarPicksClassifiedsText">User has no picks or classifieds</string>
+ <string name="NoAvatarPicksText">This person has no picks</string>
+ <string name="NoAvatarClassifiedsText">This person has no classifieds</string>
+ <string name="PicksClassifiedsLoadingText">Loading...</string>
<!-- Multi Preview Floater -->
<string name="MultiPreviewTitle">Preview</string>
diff --git a/indra/newview/skins/default/xui/es/floater_inventory_view_finder.xml b/indra/newview/skins/default/xui/es/floater_inventory_view_finder.xml
index 4f3c177976..87f93e8fcf 100644
--- a/indra/newview/skins/default/xui/es/floater_inventory_view_finder.xml
+++ b/indra/newview/skins/default/xui/es/floater_inventory_view_finder.xml
@@ -6,7 +6,7 @@
<check_box label="Gestos" name="check_gesture"/>
<check_box label="Hitos" name="check_landmark"/>
<check_box label="Notas" name="check_notecard"/>
- <check_box label="Redes" name="check_mesh"/>
+ <check_box label="Meshs" name="check_mesh"/>
<check_box label="Objetos" name="check_object"/>
<check_box label="Scripts" name="check_script"/>
<check_box label="Sonidos" name="check_sound"/>
diff --git a/indra/newview/skins/default/xui/es/floater_preview_texture.xml b/indra/newview/skins/default/xui/es/floater_preview_texture.xml
index b0afd44750..2543508c40 100644
--- a/indra/newview/skins/default/xui/es/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/es/floater_preview_texture.xml
@@ -6,42 +6,23 @@
<floater.string name="Copy">
Copiar al inventario
</floater.string>
- <text name="desc txt">
- Descripción:
- </text>
- <text name="dimensions">
- [WIDTH]px x [HEIGHT]px
- </text>
- <text name="aspect_ratio">
- Previsualizar la ratio de las proporciones
- </text>
- <combo_box name="combo_aspect_ratio" tool_tip="Vista previa en una proporción concreta">
- <combo_item name="Unconstrained">
- Sin restricciones
- </combo_item>
- <combo_item name="1:1" tool_tip="Emblema del grupo o perfil del Mundo real">
- 1:1
- </combo_item>
- <combo_item name="4:3" tool_tip="Perfil de [SECOND_LIFE]">
- 4:3
- </combo_item>
- <combo_item name="10:7" tool_tip="Clasificados (también en las listas de búsqueda), hitos">
- 10:7
- </combo_item>
- <combo_item name="3:2" tool_tip="Acerca del terreno">
- 3:2
- </combo_item>
- <combo_item name="16:10">
- 16:10
- </combo_item>
- <combo_item name="16:9" tool_tip="Destacados del perfil">
- 16:9
- </combo_item>
- <combo_item name="2:1">
- 2:1
- </combo_item>
- </combo_box>
- <button label="OK" name="Keep"/>
- <button label="Descartar" name="Discard"/>
- <button label="Guardar como" name="save_tex_btn"/>
+ <layout_stack name="preview_stack">
+ <layout_panel name="texture_panel">
+ <text name="desc txt">
+ Descripción:
+ </text>
+ <text name="dimensions">
+ [WIDTH]px x [HEIGHT]px
+ </text>
+ <text name="aspect_ratio">
+ Previsualizar la ratio de las proporciones
+ </text>
+ <combo_box name="combo_aspect_ratio" tool_tip="Vista previa en una proporción concreta"/>
+ </layout_panel>
+ <layout_panel name="buttons_panel">
+ <button label="OK" name="Keep"/>
+ <button label="Descartar" name="Discard"/>
+ <button label="Guardar como" name="save_tex_btn"/>
+ </layout_panel>
+ </layout_stack>
</floater>
diff --git a/indra/newview/skins/default/xui/es/floater_profile.xml b/indra/newview/skins/default/xui/es/floater_profile.xml
new file mode 100644
index 0000000000..c9448a0d4e
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/floater_profile.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="avatarinfo" title="Perfil">
+ <panel name="panel_profile_view">
+ <tab_container name="panel_profile_tabs">
+ <panel label="Second Life" name="panel_profile_secondlife"/>
+ <panel label="Web" name="panel_profile_web"/>
+ <panel label="Intereses" name="panel_profile_interests"/>
+ <panel label="Destacados" name="panel_profile_picks"/>
+ <panel label="Clasificado" name="panel_profile_classifieds"/>
+ <panel label="Vida real" name="panel_profile_firstlife"/>
+ <panel label="Notas" name="panel_profile_notes"/>
+ </tab_container>
+ <button label="OK" name="ok_btn" tool_tip="Salvar cambios en el perfil y cerrar"/>
+ <button label="Cancelar" label_selected="Cancelar" name="cancel_btn"/>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/es/floater_snapshot.xml b/indra/newview/skins/default/xui/es/floater_snapshot.xml
index c2c996aa8a..2dfaecf3e3 100644
--- a/indra/newview/skins/default/xui/es/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/es/floater_snapshot.xml
@@ -6,6 +6,9 @@
<string name="postcard_progress_str">
Enviando el correo electrónico
</string>
+ <string name="facebook_progress_str">
+ Publicando en Facebook
+ </string>
<string name="profile_progress_str">
Publicando
</string>
@@ -15,6 +18,9 @@
<string name="local_progress_str">
Guardando en el equipo
</string>
+ <string name="facebook_succeeded_str">
+ Imagen subida
+ </string>
<string name="profile_succeeded_str">
Imagen subida
</string>
@@ -27,6 +33,9 @@
<string name="local_succeeded_str">
¡Guardado en el equipo!
</string>
+ <string name="facebook_failed_str">
+ Error al subir la imagen a tu biografía de Facebook.
+ </string>
<string name="profile_failed_str">
Error al subir la imagen a los comentarios de tu perfil.
</string>
diff --git a/indra/newview/skins/default/xui/es/menu_name_field.xml b/indra/newview/skins/default/xui/es/menu_name_field.xml
new file mode 100644
index 0000000000..0d51fbffeb
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/menu_name_field.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="CopyMenu">
+ <menu_item_call label="Copiar Nombre mostrado" name="copy_display"/>
+ <menu_item_call label="Copiar Nombre de agente" name="copy_name"/>
+ <menu_item_call label="Copiar ID de agente" name="copy_id"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/es/notifications.xml b/indra/newview/skins/default/xui/es/notifications.xml
index 54707116d4..36f27bc3c6 100644
--- a/indra/newview/skins/default/xui/es/notifications.xml
+++ b/indra/newview/skins/default/xui/es/notifications.xml
@@ -2690,6 +2690,9 @@ Inténtalo seleccionando un trozo más pequeño de terreno.
<notification name="SystemMessage">
[MESSAGE]
</notification>
+ <notification name="FacebookConnect">
+ [MESSAGE]
+ </notification>
<notification name="FlickrConnect">
[MESSAGE]
</notification>
diff --git a/indra/newview/skins/default/xui/es/panel_edit_classified.xml b/indra/newview/skins/default/xui/es/panel_edit_classified.xml
index ffad843732..09f87015cc 100644
--- a/indra/newview/skins/default/xui/es/panel_edit_classified.xml
+++ b/indra/newview/skins/default/xui/es/panel_edit_classified.xml
@@ -46,7 +46,7 @@
<layout_panel name="save_changes_btn_lp">
<button label="[LABEL]" name="save_changes_btn"/>
</layout_panel>
- <layout_panel name="show_on_map_btn_lp">
+ <layout_panel name="cancel_btn_lp">
<button label="Cancelar" name="cancel_btn"/>
</layout_panel>
</layout_stack>
diff --git a/indra/newview/skins/default/xui/es/panel_facebook_place.xml b/indra/newview/skins/default/xui/es/panel_facebook_place.xml
index 5139bd1d0b..29f6147f23 100644
--- a/indra/newview/skins/default/xui/es/panel_facebook_place.xml
+++ b/indra/newview/skins/default/xui/es/panel_facebook_place.xml
@@ -3,7 +3,7 @@
<text name="place_caption_label">
Cuenta algo del lugar donde te encuentras:
</text>
- <check_box initial_value="false" label="Incluir una vista general del lugar" name="add_place_view_cb"/>
+ <check_box initial_value="false" label="Incluye una vista general del lugar" name="add_place_view_cb"/>
<button label="Publicar" name="post_place_btn"/>
<button label="Cancelar" name="cancel_place_btn"/>
</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_group_general.xml b/indra/newview/skins/default/xui/es/panel_group_general.xml
index a17814d15d..ef919f396e 100644
--- a/indra/newview/skins/default/xui/es/panel_group_general.xml
+++ b/indra/newview/skins/default/xui/es/panel_group_general.xml
@@ -46,7 +46,7 @@ Deja el cursor sobre las opciones para ver más ayuda.
<check_box label="Cualquiera puede entrar" name="open_enrollement" tool_tip="Configura si se permite la entrada de nuevos miembros sin ser invitados."/>
<check_box label="Cuota de entrada" name="check_enrollment_fee" tool_tip="Configura si hay que pagar una cuota para entrar al grupo"/>
<spinner label="L$" left_delta="130" name="spin_enrollment_fee" tool_tip="Si la opción Cuota de entrada está marcada, los nuevos miembros han de pagar esta cuota para entrar al grupo." width="60"/>
- <combo_box bottom_delta="-38" name="group_mature_check" tool_tip="La calificación de contenido designa el tipo de contenido y conducta que se permiten en un grupo" width="150">
+ <combo_box bottom_delta="-38" name="group_mature_check" tool_tip="Establece si tu grupo contiene información clasificada como Moderada" width="150">
<combo_item name="select_mature">
- Selecciona el nivel de calificación -
</combo_item>
diff --git a/indra/newview/skins/default/xui/es/panel_group_list_item_short.xml b/indra/newview/skins/default/xui/es/panel_group_list_item_short.xml
new file mode 100644
index 0000000000..4d682068d7
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_group_list_item_short.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="group_list_item">
+ <text name="group_name" value="Desconocido"/>
+ <button name="info_btn" tool_tip="Más información"/>
+ <button name="profile_btn" tool_tip="Ver el perfil"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_me.xml b/indra/newview/skins/default/xui/es/panel_me.xml
deleted file mode 100644
index 850cd6ec71..0000000000
--- a/indra/newview/skins/default/xui/es/panel_me.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="Mi perfil" name="panel_me">
- <panel label="MIS DESTACADOS" name="panel_picks"/>
-</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_people.xml b/indra/newview/skins/default/xui/es/panel_people.xml
index 73b9af3665..2aaf7e89be 100644
--- a/indra/newview/skins/default/xui/es/panel_people.xml
+++ b/indra/newview/skins/default/xui/es/panel_people.xml
@@ -40,6 +40,7 @@
<accordion name="friends_accordion">
<accordion_tab name="tab_online" title="Conectado"/>
<accordion_tab name="tab_all" title="Todos"/>
+ <accordion_tab name="tab_suggested_friends" title="Personas de las que podrías querer ser amigo"/>
</accordion>
</panel>
<panel label="GRUPOS" name="groups_panel">
diff --git a/indra/newview/skins/default/xui/es/panel_profile_classified.xml b/indra/newview/skins/default/xui/es/panel_profile_classified.xml
new file mode 100644
index 0000000000..679026d350
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_profile_classified.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_profile_classified">
+ <panel.string name="type_mature">
+ Moderado
+ </panel.string>
+ <panel.string name="type_pg">
+ Contenido general
+ </panel.string>
+ <panel.string name="l$_price">
+ L$[PRICE]
+ </panel.string>
+ <panel.string name="click_through_text_fmt">
+ [TELEPORT] teleportes, [MAP] mapa, [PROFILE] perfil
+ </panel.string>
+ <panel.string name="date_fmt">
+ [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt]
+ </panel.string>
+ <panel.string name="auto_renew_on">
+ Activados
+ </panel.string>
+ <panel.string name="auto_renew_off">
+ Inhabilitado
+ </panel.string>
+ <panel.string name="location_notice">
+ (se actualizará tras guardarlo)
+ </panel.string>
+ <string name="publish_label">
+ Publicar
+ </string>
+ <string name="save_label">
+ Guardar
+ </string>
+ <scroll_container name="profile_scroll">
+ <panel name="info_scroll_content_panel">
+ <icon label="" name="edit_icon" tool_tip="Pulsa para elegir una imagen"/>
+ <layout_stack name="info_panel">
+ <layout_panel name="main_info_panel">
+ <text_editor name="classified_name">
+ [name]
+ </text_editor>
+ <text name="classified_location_label" value="Ubicación:"/>
+ <text_editor name="classified_location" value="[loading...]"/>
+ <text name="content_type_label" value="Tipo de contenido:"/>
+ <text_editor name="content_type" value="[content type]"/>
+ <text name="category_label" value="Categoría:"/>
+ <text_editor name="category" value="[category]"/>
+ <text name="creation_date_label" value="Fecha de creación:"/>
+ <text_editor name="creation_date" tool_tip="Fecha de creación" value="[date]"/>
+ <text name="price_for_listing_label" value="Precio por publicarlo:"/>
+ <text_editor name="price_for_listing" tool_tip="Precio por publicarlo.">
+ [PRICE]
+ </text_editor>
+ </layout_panel>
+ <layout_panel name="clickthrough_layout_panel">
+ <text name="click_through_label" value="Clics:"/>
+ <text_editor name="click_through_text" tool_tip="Información sobre Click through" value="[clicks]"/>
+ </layout_panel>
+ <layout_panel name="auto_renew_layout_panel">
+ <text name="auto_renew_label" value="Renovación:"/>
+ <text name="auto_renew" value="Activados"/>
+ </layout_panel>
+ <layout_panel name="descr_layout_panel">
+ <text name="classified_desc_label" value="Descripción:"/>
+ <text_editor name="classified_desc" value="[description]"/>
+ </layout_panel>
+ </layout_stack>
+ <panel name="edit_panel">
+ <text name="Name:">
+ Título:
+ </text>
+ <text name="description_label">
+ Descripción:
+ </text>
+ <text name="location_label">
+ Ubicación:
+ </text>
+ <text name="classified_location_edit">
+ cargando...
+ </text>
+ <button label="Configurar en mi posición" name="set_to_curr_location_btn"/>
+ <text name="category_label" value="Categoría:"/>
+ <text name="content_type_label" value="Tipo de contenido:"/>
+ <icons_combo_box label="Contenido general" name="content_type_edit">
+ <icons_combo_box.item label="Contenido Moderado" name="mature_ci" value="Contenido para adultos"/>
+ <icons_combo_box.item label="Contenido general" name="pg_ci" value="General"/>
+ </icons_combo_box>
+ <check_box label="Renovar automáticamente cada semana" name="auto_renew_edit"/>
+ <text name="price_for_listing_edit_label" value="Precio por publicarlo:"/>
+ <spinner label="L$" name="price_for_listing_edit" tool_tip="Precio por publicarlo." value="50"/>
+ </panel>
+ </panel>
+ </scroll_container>
+ <layout_stack name="edit_btns_pnl">
+ <layout_panel name="teleport_btn_lp">
+ <button label="Teleporte" name="teleport_btn"/>
+ </layout_panel>
+ <layout_panel name="map_btn_lp">
+ <button label="Mapa" name="show_on_map_btn"/>
+ </layout_panel>
+ <layout_panel name="edit_btn_lp">
+ <button label="Editar" name="edit_btn"/>
+ </layout_panel>
+ <layout_panel name="save_btn_lp">
+ <button label="[LABEL]" name="save_changes_btn"/>
+ </layout_panel>
+ <layout_panel name="cancel_btn_lp">
+ <button label="Cancelar" name="cancel_btn"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_profile_classifieds.xml b/indra/newview/skins/default/xui/es/panel_profile_classifieds.xml
new file mode 100644
index 0000000000..2520348094
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_profile_classifieds.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Clasificado" name="panel_profile_classifieds">
+ <string name="no_classifieds" value="No hay clasificados"/>
+ <button label="Nuevo..." name="new_btn"/>
+ <button label="Eliminar..." name="delete_btn"/>
+ <text name="classifieds_panel_text">
+ Cargando...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/floater_picks.xml b/indra/newview/skins/default/xui/es/panel_profile_firstlife.xml
index f058ff668b..0fb502e441 100644
--- a/indra/newview/skins/default/xui/fr/floater_picks.xml
+++ b/indra/newview/skins/default/xui/es/panel_profile_firstlife.xml
@@ -1,2 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_picks" title="Favoris"/>
+<panel label="Perfil" name="panel_profile_firstlife"/>
diff --git a/indra/newview/skins/default/xui/es/panel_profile_interests.xml b/indra/newview/skins/default/xui/es/panel_profile_interests.xml
new file mode 100644
index 0000000000..86dd63390c
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_profile_interests.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Intereses" name="panel_profile_interests">
+ <text name="I Want To:">
+ Quiero:
+ </text>
+ <check_box label="Construye" name="chk0"/>
+ <check_box label="Explora" name="chk1"/>
+ <check_box label="Conoce" name="chk2"/>
+ <check_box label="Encuentra empleo" name="chk6"/>
+ <check_box label="Agrupa" name="chk3"/>
+ <check_box label="Compra" name="chk4"/>
+ <check_box label="Vende" name="chk5"/>
+ <check_box label="Contrata" name="chk7"/>
+ <line_editor name="want_to_edit">
+ (cargando...)
+ </line_editor>
+ <text name="Skills:">
+ Habilidades:
+ </text>
+ <check_box label="Texturas" name="schk0"/>
+ <check_box label="Arquitectura" name="schk1"/>
+ <check_box label="Modelo" name="schk3"/>
+ <check_box label="Planificación de eventos" name="schk2"/>
+ <check_box label="Preparación de scripts" name="schk4"/>
+ <check_box label="Personajes personalizados" name="schk5"/>
+ <line_editor name="skills_edit">
+ (cargando...)
+ </line_editor>
+ <text name="Languages:">
+ Idiomas:
+ </text>
+ <line_editor name="languages_edit">
+ (cargando...)
+ </line_editor>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_profile_notes.xml b/indra/newview/skins/default/xui/es/panel_profile_notes.xml
new file mode 100644
index 0000000000..4cc14e1487
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_profile_notes.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Notas y Privacidad" name="panel_notes">
+ <text name="status_message" value="Notas privadas en este avatar:"/>
+ <text name="status_message2" value="Permitir que este avatar:"/>
+ <check_box label="Ver cuándo estoy conectado" name="status_check"/>
+ <check_box label="Encontrarme en el mapa del mundo" name="map_check"/>
+ <check_box label="Edita, borrar o tomar mis objetos" name="objects_check"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_profile_pick.xml b/indra/newview/skins/default/xui/es/panel_profile_pick.xml
new file mode 100644
index 0000000000..4e9f5bbdd5
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_profile_pick.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_pick_info">
+ <panel.string name="location_notice">
+ (se actualizará tras guardarlo)
+ </panel.string>
+ <line_editor name="pick_location">
+ Cargando...
+ </line_editor>
+ <button label="Teleporte" name="teleport_btn"/>
+ <button label="Mostrar en el mapa" name="show_on_map_btn"/>
+ <button label="Establecer ubicación" name="set_to_curr_location_btn" tool_tip="Configurar en mi posición"/>
+ <button label="Guardar" name="save_changes_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_profile_picks.xml b/indra/newview/skins/default/xui/es/panel_profile_picks.xml
new file mode 100644
index 0000000000..0641b72c13
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_profile_picks.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Destacados" name="panel_picks">
+ <string name="no_picks" value="No hay destacados"/>
+ <text name="Tell everyone about your favorite places in Second Life.">
+ Cuéntale a todos sobre tus lugares favoritos de Second Life.
+ </text>
+ <button label="Nuevo..." name="new_btn"/>
+ <button label="Eliminar..." name="delete_btn"/>
+ <text name="picks_panel_text">
+ Cargando...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/es/panel_profile_secondlife.xml
new file mode 100644
index 0000000000..541593660d
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_profile_secondlife.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Perfil" name="panel_profile">
+ <string name="status_online">
+ Actualmente en línea
+ </string>
+ <string name="status_offline">
+ Actualmente sin conexión
+ </string>
+ <string name="CaptionTextAcctInfo">
+ [ACCTTYPE]
+[PAYMENTINFO]
+ </string>
+ <string name="payment_update_link_url">
+ http://www.secondlife.com/account/billing.php?lang=en
+ </string>
+ <string name="partner_edit_link_url">
+ http://www.secondlife.com/account/partners.php?lang=en
+ </string>
+ <string name="my_account_link_url" value="http://secondlife.com/account"/>
+ <string name="no_partner_text" value="Ninguno"/>
+ <string name="no_group_text" value="Ninguno"/>
+ <string name="RegisterDateFormat">
+ [REG_DATE]
+ </string>
+ <string name="name_text_args">
+ [NAME]
+ </string>
+ <string name="display_name_text_args">
+ [DISPLAY_NAME]
+ </string>
+ <string name="FSDev" value="Desarrollador"/>
+ <string name="FSSupp" value="Soporte"/>
+ <string name="FSQualityAssurance" value="Buscador de fallos"/>
+ <string name="FSGW" value="Portal"/>
+ <text name="name_label" value="Nombre:"/>
+ <button label="Nombre:" name="set_name" tool_tip="Configurar nombre mostrado"/>
+ <panel name="name_holder">
+ <text_editor name="complete_name" value="(cargando...)"/>
+ </panel>
+ <layout_stack name="imagepositioner">
+ <layout_panel name="label_stack">
+ <text name="status" value="Status Desconocido"/>
+ <text name="label" value="Fecha de nacimiento en Second Life:"/>
+ <text name="label2" value="Cuenta:"/>
+ <text name="partner_label" value="Compañero/a:"/>
+ </layout_panel>
+ </layout_stack>
+ <text name="Groups:" value="Grupos:"/>
+ <button label="+" label_selected="+" name="group_invite" tool_tip="Invitar al grupo"/>
+ <layout_stack name="aboutpositioner">
+ <layout_panel name="about_stack">
+ <text name="About:" value="Acerca de:"/>
+ </layout_panel>
+ <layout_panel name="give_stack">
+ <text name="Give item:" value="Dar objeto:"/>
+ <text name="Give inventory" tool_tip="Soltar elementos de inventario aquí para dárselos a esta persona.">
+ Soltar aquí el nuevo elemento de inventario.
+ </text>
+ </layout_panel>
+ </layout_stack>
+ <layout_stack name="buttonstack">
+ <layout_panel name="left_buttonstack">
+ <button label="Encontrar en el mapa" label_selected="Encontrar en el mapa" name="show_on_map_btn" tool_tip="Mostrar al Residente en el mapa"/>
+ <button label="Pagar" label_selected="Pagar" name="pay" tool_tip="Pagar a este Residente"/>
+ </layout_panel>
+ <layout_panel name="middle_buttonstack">
+ <button label="Ofrecer teleporte" label_selected="Ofrecer teleporte" name="teleport" tool_tip="Ofrecer teleporte al residente"/>
+ <button label="Mensaje instantáneo" label_selected="Mensaje instantáneo" name="im" tool_tip="Abrir una sesión de mensajes instantáneos"/>
+ </layout_panel>
+ <layout_panel name="right_buttonstack">
+ <button label="Añadir como amigo" label_selected="Añadir como amigo" name="add_friend" tool_tip="Ofrecer amistad a este Residente"/>
+ <button label="Bloquear" name="block" tool_tip="Bloquear al residente"/>
+ <button label="Desbloquear" name="unblock" tool_tip="Desbloquear al residente"/>
+ </layout_panel>
+ </layout_stack>
+ <check_box label="Mostrar en la búsqueda" name="show_in_search_checkbox"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_profile_web.xml b/indra/newview/skins/default/xui/es/panel_profile_web.xml
new file mode 100644
index 0000000000..f9a8f4b113
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_profile_web.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Web" name="panel_profile_web">
+ <panel.string name="LoadTime" value="Tiempo de carga: [TIME] segundos"/>
+ <line_editor name="url_edit">
+ (cargando..)
+ </line_editor>
+ <flyout_button label="Cargar" name="load" tool_tip="Cargar esta página de perfil con el navegador incorporado.">
+ <flyout_button.item label="Abrir navegador in-viewer" name="open_item"/>
+ <flyout_button.item label="Abrir navegador externo" name="home_item"/>
+ </flyout_button>
+ <button name="web_profile_popout_btn" tool_tip="Perfil web emergente"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/strings.xml b/indra/newview/skins/default/xui/es/strings.xml
index 4b7f6a0081..20f7f81962 100644
--- a/indra/newview/skins/default/xui/es/strings.xml
+++ b/indra/newview/skins/default/xui/es/strings.xml
@@ -348,6 +348,24 @@ Intenta iniciar sesión de nuevo en unos instantes.
<string name="TestingDisconnect">
Probando la desconexión del visor
</string>
+ <string name="SocialFacebookConnecting">
+ Conectando con Facebook...
+ </string>
+ <string name="SocialFacebookPosting">
+ Publicando...
+ </string>
+ <string name="SocialFacebookDisconnecting">
+ Desconectando de Facebook...
+ </string>
+ <string name="SocialFacebookErrorConnecting">
+ Problema al conectar con Facebook
+ </string>
+ <string name="SocialFacebookErrorPosting">
+ Problema al publicar en Facebook
+ </string>
+ <string name="SocialFacebookErrorDisconnecting">
+ Problema al desconectar de Facebook
+ </string>
<string name="SocialFlickrConnecting">
Conectándose a Flickr...
</string>
@@ -2549,9 +2567,21 @@ Si sigues recibiendo el mismo mensaje, solicita ayuda al personal de asistencia
<string name="NoPicksClassifiedsText">
No has creado destacados ni clasificados. Pulsa el botón Más para crear uno.
</string>
+ <string name="NoPicksText">
+ No has creado destacados. Haz clic en el botón Más para crear uno.
+ </string>
+ <string name="NoClassifiedsText">
+ No has creado clasificados. Haz clic en el botón Nuevo para crear un anuncio clasificado.
+ </string>
<string name="NoAvatarPicksClassifiedsText">
El usuario no tiene clasificados ni destacados
</string>
+ <string name="NoAvatarPicksText">
+ El usuario no tiene destacados
+ </string>
+ <string name="NoAvatarClassifiedsText">
+ El usuario no tiene clasificados
+ </string>
<string name="PicksClassifiedsLoadingText">
Cargando...
</string>
@@ -4469,6 +4499,9 @@ Si sigues recibiendo este mensaje, contacta con [SUPPORT_SITE].
<string name="share_alert">
Arrastra los ítems desde el invenbtario hasta aquí
</string>
+ <string name="facebook_post_success">
+ Has publicado en Facebook.
+ </string>
<string name="flickr_post_success">
Has publicado en Flickr.
</string>
diff --git a/indra/newview/skins/default/xui/fr/floater_facebook.xml b/indra/newview/skins/default/xui/fr/floater_facebook.xml
index f5097e7a88..f6e8696e53 100644
--- a/indra/newview/skins/default/xui/fr/floater_facebook.xml
+++ b/indra/newview/skins/default/xui/fr/floater_facebook.xml
@@ -10,6 +10,6 @@
Erreur
</text>
<text name="connection_loading_text">
- Chargement...
+ En cours de chargement...
</text>
</floater>
diff --git a/indra/newview/skins/default/xui/fr/floater_preview_texture.xml b/indra/newview/skins/default/xui/fr/floater_preview_texture.xml
index d63d9903ec..46703fe612 100644
--- a/indra/newview/skins/default/xui/fr/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/fr/floater_preview_texture.xml
@@ -6,42 +6,23 @@
<floater.string name="Copy">
Copier dans l&apos;inventaire
</floater.string>
- <text name="desc txt">
- Description :
- </text>
- <text name="dimensions">
- [WIDTH]px x [HEIGHT]px
- </text>
- <text name="aspect_ratio">
- Rapport d&apos;aspect fixe
- </text>
- <combo_box name="combo_aspect_ratio" tool_tip="Prévisualiser avec un rapport d&apos;aspect fixe">
- <combo_item name="Unconstrained">
- Sans contraintes
- </combo_item>
- <combo_item name="1:1" tool_tip="Logo du groupe ou profil dans la vie réelle">
- 1:1
- </combo_item>
- <combo_item name="4:3" tool_tip="Profil [SECOND_LIFE]">
- 4:3
- </combo_item>
- <combo_item name="10:7" tool_tip="Petites annonces, repères">
- 10:7
- </combo_item>
- <combo_item name="3:2" tool_tip="À propos du terrain">
- 3:2
- </combo_item>
- <combo_item name="16:10">
- 16:10
- </combo_item>
- <combo_item name="16:9" tool_tip="Favoris du profil">
- 16:9
- </combo_item>
- <combo_item name="2:1">
- 2:1
- </combo_item>
- </combo_box>
- <button label="OK" name="Keep"/>
- <button label="Jeter" name="Discard"/>
- <button label="Enregistrer sous" name="save_tex_btn"/>
+ <layout_stack name="preview_stack">
+ <layout_panel name="texture_panel">
+ <text name="desc txt">
+ Description :
+ </text>
+ <text name="dimensions">
+ [WIDTH]px x [HEIGHT]px
+ </text>
+ <text name="aspect_ratio">
+ Rapport d&apos;aspect fixe
+ </text>
+ <combo_box name="combo_aspect_ratio" tool_tip="Prévisualiser avec un rapport d&apos;aspect fixe"/>
+ </layout_panel>
+ <layout_panel name="buttons_panel">
+ <button label="OK" name="Keep"/>
+ <button label="Jeter" name="Discard"/>
+ <button label="Enregistrer sous" name="save_tex_btn"/>
+ </layout_panel>
+ </layout_stack>
</floater>
diff --git a/indra/newview/skins/default/xui/fr/floater_profile.xml b/indra/newview/skins/default/xui/fr/floater_profile.xml
new file mode 100644
index 0000000000..c4af79e946
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/floater_profile.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="avatarinfo" title="Profil">
+ <panel name="panel_profile_view">
+ <tab_container name="panel_profile_tabs">
+ <panel label="Second Life" name="panel_profile_secondlife"/>
+ <panel label="Web" name="panel_profile_web"/>
+ <panel label="Centres d&apos;intérêt" name="panel_profile_interests"/>
+ <panel label="Favoris" name="panel_profile_picks"/>
+ <panel label="Petite annonce" name="panel_profile_classifieds"/>
+ <panel label="Vie réelle" name="panel_profile_firstlife"/>
+ <panel label="Remarques" name="panel_profile_notes"/>
+ </tab_container>
+ <button label="OK" name="ok_btn" tool_tip="Enregistrer les changements apportés au profil et fermer"/>
+ <button label="Annuler" label_selected="Annuler" name="cancel_btn"/>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/fr/floater_snapshot.xml b/indra/newview/skins/default/xui/fr/floater_snapshot.xml
index 8eb05dd945..adb98a68d2 100644
--- a/indra/newview/skins/default/xui/fr/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/fr/floater_snapshot.xml
@@ -6,6 +6,9 @@
<string name="postcard_progress_str">
Envoi par e-mail
</string>
+ <string name="facebook_progress_str">
+ Publication sur Facebook
+ </string>
<string name="profile_progress_str">
Publication
</string>
@@ -15,6 +18,9 @@
<string name="local_progress_str">
Enregistrement sur l&apos;ordinateur
</string>
+ <string name="facebook_succeeded_str">
+ Image chargée
+ </string>
<string name="profile_succeeded_str">
Image chargée
</string>
@@ -27,6 +33,9 @@
<string name="local_succeeded_str">
Enregistrement sur l&apos;ordinateur effectué !
</string>
+ <string name="facebook_failed_str">
+ Échec de chargement de l&apos;image dans votre journal Facebook.
+ </string>
<string name="profile_failed_str">
Échec de chargement de l&apos;image sur le flux de votre profil.
</string>
diff --git a/indra/newview/skins/default/xui/fr/menu_name_field.xml b/indra/newview/skins/default/xui/fr/menu_name_field.xml
new file mode 100644
index 0000000000..6c3fba4110
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/menu_name_field.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="CopyMenu">
+ <menu_item_call label="Copier le Nom d&apos;affichage" name="copy_display"/>
+ <menu_item_call label="Copier le Nom de l&apos;agent" name="copy_name"/>
+ <menu_item_call label="Copier l&apos;ID de l&apos;agent" name="copy_id"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/fr/notifications.xml b/indra/newview/skins/default/xui/fr/notifications.xml
index e84de375d8..09905f4e5d 100644
--- a/indra/newview/skins/default/xui/fr/notifications.xml
+++ b/indra/newview/skins/default/xui/fr/notifications.xml
@@ -2683,6 +2683,9 @@ Veuillez sélectionner un terrain plus petit.
<notification name="SystemMessage">
[MESSAGE]
</notification>
+ <notification name="FacebookConnect">
+ [MESSAGE]
+ </notification>
<notification name="FlickrConnect">
[MESSAGE]
</notification>
diff --git a/indra/newview/skins/default/xui/fr/panel_edit_classified.xml b/indra/newview/skins/default/xui/fr/panel_edit_classified.xml
index 7b58f2e825..b892d25f26 100644
--- a/indra/newview/skins/default/xui/fr/panel_edit_classified.xml
+++ b/indra/newview/skins/default/xui/fr/panel_edit_classified.xml
@@ -46,7 +46,7 @@
<layout_panel name="save_changes_btn_lp">
<button label="[LABEL]" name="save_changes_btn"/>
</layout_panel>
- <layout_panel name="show_on_map_btn_lp">
+ <layout_panel name="cancel_btn_lp">
<button label="Annuler" name="cancel_btn"/>
</layout_panel>
</layout_stack>
diff --git a/indra/newview/skins/default/xui/fr/panel_facebook_friends.xml b/indra/newview/skins/default/xui/fr/panel_facebook_friends.xml
index 319737a2af..0e36c2092c 100644
--- a/indra/newview/skins/default/xui/fr/panel_facebook_friends.xml
+++ b/indra/newview/skins/default/xui/fr/panel_facebook_friends.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<panel name="panel_facebook_friends">
- <string name="facebook_friends_empty" value="Vous n&apos;avez actuellement aucun ami Facebook qui est également résident de Second Life. Invitez vos amis Facebook à rejoindre Second Life !"/>
+ <string name="facebook_friends_empty" value="Vous n&apos;avez actuellement aucun ami Facebook qui est également résident de Second Life. Invitez vos amis Facebook à rejoindre Second Life aujourd&apos;hui !"/>
<string name="facebook_friends_no_connected" value="Vous n&apos;êtes pas connecté(e) à Facebook. Allez à l&apos;onglet Statut pour vous connecter et activer cette fonctionnalité."/>
<accordion name="friends_accordion">
<accordion_tab name="tab_second_life_friends" title="Amis SL"/>
diff --git a/indra/newview/skins/default/xui/fr/panel_facebook_photo.xml b/indra/newview/skins/default/xui/fr/panel_facebook_photo.xml
index 3236f35b55..cc4045bc74 100644
--- a/indra/newview/skins/default/xui/fr/panel_facebook_photo.xml
+++ b/indra/newview/skins/default/xui/fr/panel_facebook_photo.xml
@@ -4,14 +4,14 @@
<combo_box.item label="Fenêtre actuelle" name="CurrentWindow"/>
<combo_box.item label="640 x 480" name="640x480"/>
<combo_box.item label="800 x 600" name="800x600"/>
- <combo_box.item label="1 024 x 768" name="1024x768"/>
- <combo_box.item label="1 200 x 630" name="1200x630"/>
+ <combo_box.item label="1024 x 768" name="1024x768"/>
+ <combo_box.item label="1200 x 630" name="1200x630"/>
</combo_box>
- <combo_box name="filters_combobox" tool_tip="Filtres d&apos;image">
+ <combo_box name="filters_combobox" tool_tip="Filtres d’image">
<combo_box.item label="Aucun filtre" name="NoFilter"/>
</combo_box>
<button label="Actualiser" name="new_snapshot_btn" tool_tip="Cliquer pour actualiser"/>
- <button label="Aperçu" name="big_preview_btn" tool_tip="Cliquer pour activer/désactiver l&apos;aperçu"/>
+ <button label="Aperçu" name="big_preview_btn" tool_tip="Cliquer pour basculer l&apos;aperçu"/>
<text name="caption_label">
Commentaire (facultatif) :
</text>
diff --git a/indra/newview/skins/default/xui/fr/panel_facebook_status.xml b/indra/newview/skins/default/xui/fr/panel_facebook_status.xml
index 9afa42d2aa..dc8e4b9ecc 100644
--- a/indra/newview/skins/default/xui/fr/panel_facebook_status.xml
+++ b/indra/newview/skins/default/xui/fr/panel_facebook_status.xml
@@ -6,7 +6,7 @@
Pas connecté(e) à Facebook.
</text>
<panel name="panel_buttons">
- <button label="Connexion..." name="connect_btn"/>
+ <button label="Connexion en cours..." name="connect_btn"/>
<button label="Déconnexion" name="disconnect_btn"/>
<text name="account_learn_more_label">
[http://community.secondlife.com/t5/English-Knowledge-Base/Second-Life-Share-Facebook/ta-p/2149711 Apprenez comment publier sur Facebook]
diff --git a/indra/newview/skins/default/xui/fr/panel_group_list_item_short.xml b/indra/newview/skins/default/xui/fr/panel_group_list_item_short.xml
new file mode 100644
index 0000000000..b1b32af7c6
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_group_list_item_short.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="group_list_item">
+ <text name="group_name" value="Inconnu"/>
+ <button name="info_btn" tool_tip="En savoir plus"/>
+ <button name="profile_btn" tool_tip="Voir le profil"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_me.xml b/indra/newview/skins/default/xui/fr/panel_me.xml
deleted file mode 100644
index 5676986228..0000000000
--- a/indra/newview/skins/default/xui/fr/panel_me.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="Mon profil" name="panel_me">
- <panel label="MES FAVORIS" name="panel_picks"/>
-</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_people.xml b/indra/newview/skins/default/xui/fr/panel_people.xml
index 3be6bae52a..e096b5cfe0 100644
--- a/indra/newview/skins/default/xui/fr/panel_people.xml
+++ b/indra/newview/skins/default/xui/fr/panel_people.xml
@@ -40,6 +40,7 @@ Pour rechercher des résidents avec qui passer du temps, utilisez [secondlife://
<accordion name="friends_accordion">
<accordion_tab name="tab_online" title="En ligne"/>
<accordion_tab name="tab_all" title="Tout"/>
+ <accordion_tab name="tab_suggested_friends" title="Personnes avec lesquelles vous aimeriez peut-être devenir ami(e)"/>
</accordion>
</panel>
<panel label="GROUPES" name="groups_panel">
diff --git a/indra/newview/skins/default/xui/fr/panel_profile_classified.xml b/indra/newview/skins/default/xui/fr/panel_profile_classified.xml
new file mode 100644
index 0000000000..b223684c60
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_profile_classified.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_profile_classified">
+ <panel.string name="type_mature">
+ Modéré
+ </panel.string>
+ <panel.string name="type_pg">
+ Contenu Général
+ </panel.string>
+ <panel.string name="l$_price">
+ L$[PRICE]
+ </panel.string>
+ <panel.string name="click_through_text_fmt">
+ [TELEPORT] téléporter, [MAP] carte, [PROFILE] profile
+ </panel.string>
+ <panel.string name="date_fmt">
+ [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt]
+ </panel.string>
+ <panel.string name="auto_renew_on">
+ Activé
+ </panel.string>
+ <panel.string name="auto_renew_off">
+ Désactivé
+ </panel.string>
+ <panel.string name="location_notice">
+ (mise à jour après enregistrement)
+ </panel.string>
+ <string name="publish_label">
+ Publier
+ </string>
+ <string name="save_label">
+ Enregistrer
+ </string>
+ <scroll_container name="profile_scroll">
+ <panel name="info_scroll_content_panel">
+ <icon label="" name="edit_icon" tool_tip="Cliquer pour sélectionner une image"/>
+ <layout_stack name="info_panel">
+ <layout_panel name="main_info_panel">
+ <text_editor name="classified_name">
+ [name]
+ </text_editor>
+ <text name="classified_location_label" value="Endroit :"/>
+ <text_editor name="classified_location" value="[loading...]"/>
+ <text name="content_type_label" value="Type de contenu :"/>
+ <text_editor name="content_type" value="[content type]"/>
+ <text name="category_label" value="Catégorie :"/>
+ <text_editor name="category" value="[category]"/>
+ <text name="creation_date_label" value="Date de création :"/>
+ <text_editor name="creation_date" tool_tip="Date de création" value="[date]"/>
+ <text name="price_for_listing_label" value="Coût de l&apos;annonce :"/>
+ <text_editor name="price_for_listing" tool_tip="Coût de l’annonce.">
+ [PRICE]
+ </text_editor>
+ </layout_panel>
+ <layout_panel name="clickthrough_layout_panel">
+ <text name="click_through_label" value="Clics :"/>
+ <text_editor name="click_through_text" tool_tip="Parcourir les données en cliquant" value="[clicks]"/>
+ </layout_panel>
+ <layout_panel name="auto_renew_layout_panel">
+ <text name="auto_renew_label" value="Renouv. auto :"/>
+ <text name="auto_renew" value="Activé"/>
+ </layout_panel>
+ <layout_panel name="descr_layout_panel">
+ <text name="classified_desc_label" value="Description :"/>
+ <text_editor name="classified_desc" value="[description]"/>
+ </layout_panel>
+ </layout_stack>
+ <panel name="edit_panel">
+ <text name="Name:">
+ Titre :
+ </text>
+ <text name="description_label">
+ Description :
+ </text>
+ <text name="location_label">
+ Endroit :
+ </text>
+ <text name="classified_location_edit">
+ en cours de chargement...
+ </text>
+ <button label="Définir sur l’emplacement actuel" name="set_to_curr_location_btn"/>
+ <text name="category_label" value="Catégorie :"/>
+ <text name="content_type_label" value="Type de contenu :"/>
+ <icons_combo_box label="Contenu Général" name="content_type_edit">
+ <icons_combo_box.item label="Contenu Modéré" name="mature_ci" value="Adulte"/>
+ <icons_combo_box.item label="Contenu Général" name="pg_ci" value="PG"/>
+ </icons_combo_box>
+ <check_box label="Renouvellement auto toutes les semaines" name="auto_renew_edit"/>
+ <text name="price_for_listing_edit_label" value="Coût de l&apos;annonce :"/>
+ <spinner label="L$" name="price_for_listing_edit" tool_tip="Coût de l’annonce." value="50"/>
+ </panel>
+ </panel>
+ </scroll_container>
+ <layout_stack name="edit_btns_pnl">
+ <layout_panel name="teleport_btn_lp">
+ <button label="Téléportation" name="teleport_btn"/>
+ </layout_panel>
+ <layout_panel name="map_btn_lp">
+ <button label="Carte" name="show_on_map_btn"/>
+ </layout_panel>
+ <layout_panel name="edit_btn_lp">
+ <button label="Modifier" name="edit_btn"/>
+ </layout_panel>
+ <layout_panel name="save_btn_lp">
+ <button label="[LABEL]" name="save_changes_btn"/>
+ </layout_panel>
+ <layout_panel name="cancel_btn_lp">
+ <button label="Annuler" name="cancel_btn"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_profile_classifieds.xml b/indra/newview/skins/default/xui/fr/panel_profile_classifieds.xml
new file mode 100644
index 0000000000..adb3501422
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_profile_classifieds.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Petite annonce" name="panel_profile_classifieds">
+ <string name="no_classifieds" value="Pas de petites annonces"/>
+ <button label="Nouveau..." name="new_btn"/>
+ <button label="Supprimer..." name="delete_btn"/>
+ <text name="classifieds_panel_text">
+ En cours de chargement...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/floater_picks.xml b/indra/newview/skins/default/xui/fr/panel_profile_firstlife.xml
index 255aa5dcdc..0f65090209 100644
--- a/indra/newview/skins/default/xui/es/floater_picks.xml
+++ b/indra/newview/skins/default/xui/fr/panel_profile_firstlife.xml
@@ -1,2 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_picks" title="Destacados"/>
+<panel label="Profil" name="panel_profile_firstlife"/>
diff --git a/indra/newview/skins/default/xui/fr/panel_profile_interests.xml b/indra/newview/skins/default/xui/fr/panel_profile_interests.xml
new file mode 100644
index 0000000000..e8212817d2
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_profile_interests.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Centres d&apos;intérêt" name="panel_profile_interests">
+ <text name="I Want To:">
+ Je veux :
+ </text>
+ <check_box label="Construire" name="chk0"/>
+ <check_box label="Explorer" name="chk1"/>
+ <check_box label="Rencontrer" name="chk2"/>
+ <check_box label="Être recruté" name="chk6"/>
+ <check_box label="Grouper" name="chk3"/>
+ <check_box label="Acheter" name="chk4"/>
+ <check_box label="Vendre" name="chk5"/>
+ <check_box label="Louer" name="chk7"/>
+ <line_editor name="want_to_edit">
+ (en cours de chargement...)
+ </line_editor>
+ <text name="Skills:">
+ Compétences :
+ </text>
+ <check_box label="Textures" name="schk0"/>
+ <check_box label="Architecture" name="schk1"/>
+ <check_box label="Modèle" name="schk3"/>
+ <check_box label="Planification des événements" name="schk2"/>
+ <check_box label="Langage de scripts" name="schk4"/>
+ <check_box label="Personnages personnalisés" name="schk5"/>
+ <line_editor name="skills_edit">
+ (en cours de chargement...)
+ </line_editor>
+ <text name="Languages:">
+ Langues :
+ </text>
+ <line_editor name="languages_edit">
+ (en cours de chargement...)
+ </line_editor>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_profile_notes.xml b/indra/newview/skins/default/xui/fr/panel_profile_notes.xml
new file mode 100644
index 0000000000..03fb37d72b
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_profile_notes.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Notes &amp; respect de la vie privée" name="panel_notes">
+ <text name="status_message" value="Notes personnelles sur cet avatar:"/>
+ <text name="status_message2" value="Autoriser cet avatar à :"/>
+ <check_box label="Voir quand je suis en ligne" name="status_check"/>
+ <check_box label="Me trouver sur la carte du monde" name="map_check"/>
+ <check_box label="Modifier, supprimer ou prendre mes objets" name="objects_check"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_profile_pick.xml b/indra/newview/skins/default/xui/fr/panel_profile_pick.xml
new file mode 100644
index 0000000000..017fcff88a
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_profile_pick.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_pick_info">
+ <panel.string name="location_notice">
+ (mise à jour après enregistrement)
+ </panel.string>
+ <line_editor name="pick_location">
+ En cours de chargement...
+ </line_editor>
+ <button label="Téléportation" name="teleport_btn"/>
+ <button label="Voir sur la carte" name="show_on_map_btn"/>
+ <button label="Définir l&apos;emplacement" name="set_to_curr_location_btn" tool_tip="Définir sur l’emplacement actuel"/>
+ <button label="Enregistrer les favoris" name="save_changes_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_profile_picks.xml b/indra/newview/skins/default/xui/fr/panel_profile_picks.xml
new file mode 100644
index 0000000000..1644722813
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_profile_picks.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Favoris" name="panel_picks">
+ <string name="no_picks" value="Pas de favoris"/>
+ <text name="Tell everyone about your favorite places in Second Life.">
+ Faites connaître aux autres résidents vos endroits favoris dans Second Life.
+ </text>
+ <button label="Nouveau..." name="new_btn"/>
+ <button label="Supprimer..." name="delete_btn"/>
+ <text name="picks_panel_text">
+ En cours de chargement...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/fr/panel_profile_secondlife.xml
new file mode 100644
index 0000000000..de9cbf6dce
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_profile_secondlife.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Profil" name="panel_profile">
+ <string name="status_online">
+ Actuellement connecté
+ </string>
+ <string name="status_offline">
+ Actuellement déconnecté
+ </string>
+ <string name="CaptionTextAcctInfo">
+ [ACCTTYPE]
+[PAYMENTINFO]
+ </string>
+ <string name="payment_update_link_url">
+ http://www.secondlife.com/account/billing.php?lang=en
+ </string>
+ <string name="partner_edit_link_url">
+ http://www.secondlife.com/account/partners.php?lang=en
+ </string>
+ <string name="my_account_link_url" value="http://secondlife.com/account"/>
+ <string name="no_partner_text" value="Aucun"/>
+ <string name="no_group_text" value="Aucun"/>
+ <string name="RegisterDateFormat">
+ [REG_DATE]
+ </string>
+ <string name="name_text_args">
+ [NAME]
+ </string>
+ <string name="display_name_text_args">
+ [DISPLAY_NAME]
+ </string>
+ <string name="FSDev" value="Développeur"/>
+ <string name="FSSupp" value="Assistance"/>
+ <string name="FSQualityAssurance" value="Suivi des anomalies"/>
+ <string name="FSGW" value="Portail"/>
+ <text name="name_label" value="Nom :"/>
+ <button label="Nom :" name="set_name" tool_tip="Définir un nom d&apos;affichage"/>
+ <panel name="name_holder">
+ <text_editor name="complete_name" value="(en cours de chargement...)"/>
+ </panel>
+ <layout_stack name="imagepositioner">
+ <layout_panel name="label_stack">
+ <text name="status" value="Statut inconnu"/>
+ <text name="label" value="Date de naissance dans Second Life :"/>
+ <text name="label2" value="Compte :"/>
+ <text name="partner_label" value="Partenaire :"/>
+ </layout_panel>
+ </layout_stack>
+ <text name="Groups:" value="Groupes :"/>
+ <button label="+" label_selected="+" name="group_invite" tool_tip="Inviter dans le groupe"/>
+ <layout_stack name="aboutpositioner">
+ <layout_panel name="about_stack">
+ <text name="About:" value="À propos :"/>
+ </layout_panel>
+ <layout_panel name="give_stack">
+ <text name="Give item:" value="Donner des objets :"/>
+ <text name="Give inventory" tool_tip="Placer les objets de l&apos;inventaire ici pour les donner à cette personne">
+ Placer les objets de l&apos;inventaire ici.
+ </text>
+ </layout_panel>
+ </layout_stack>
+ <layout_stack name="buttonstack">
+ <layout_panel name="left_buttonstack">
+ <button label="Situer sur la carte" label_selected="Situer sur la carte" name="show_on_map_btn" tool_tip="Localiser le Résident sur la carte"/>
+ <button label="Payer" label_selected="Payer" name="pay" tool_tip="Payer le résident"/>
+ </layout_panel>
+ <layout_panel name="middle_buttonstack">
+ <button label="Proposer de téléporter" label_selected="Proposer de téléporter" name="teleport" tool_tip="Proposer une téléportation au Résident"/>
+ <button label="Message instantané" label_selected="Message instantané" name="im" tool_tip="Ouvrir une session IM."/>
+ </layout_panel>
+ <layout_panel name="right_buttonstack">
+ <button label="Ajouter un ami" label_selected="Ajouter un ami" name="add_friend" tool_tip="Proposer à ce résident de devenir votre ami"/>
+ <button label="Bloquer" name="block" tool_tip="Bloquer ce Résident"/>
+ <button label="Débloquer" name="unblock" tool_tip="Débloquer ce Résident"/>
+ </layout_panel>
+ </layout_stack>
+ <check_box label="Afficher avec la recherche" name="show_in_search_checkbox"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_profile_web.xml b/indra/newview/skins/default/xui/fr/panel_profile_web.xml
new file mode 100644
index 0000000000..70e145ade9
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_profile_web.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Web" name="panel_profile_web">
+ <panel.string name="LoadTime" value="Heure de chargement : [TIME] secondes"/>
+ <line_editor name="url_edit">
+ (en cours de chargement..)
+ </line_editor>
+ <flyout_button label="Charger" name="load" tool_tip="Charger ce profil avec le navigateur Web incorporé">
+ <flyout_button.item label="Ouvrir dans mon navigateur Web" name="open_item"/>
+ <flyout_button.item label="Ouvrir dans un navigateur externe" name="home_item"/>
+ </flyout_button>
+ <button name="web_profile_popout_btn" tool_tip="Profil de fenêtres web"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/strings.xml b/indra/newview/skins/default/xui/fr/strings.xml
index 16423503e7..943d1635cd 100644
--- a/indra/newview/skins/default/xui/fr/strings.xml
+++ b/indra/newview/skins/default/xui/fr/strings.xml
@@ -357,6 +357,24 @@ Veuillez réessayer de vous connecter dans une minute.
<string name="TestingDisconnect">
Test de déconnexion du client
</string>
+ <string name="SocialFacebookConnecting">
+ Connexion à Facebook…
+ </string>
+ <string name="SocialFacebookPosting">
+ Publication…
+ </string>
+ <string name="SocialFacebookDisconnecting">
+ Déconnexion de Facebook…
+ </string>
+ <string name="SocialFacebookErrorConnecting">
+ Un problème est survenu lors de la connexion à Facebook.
+ </string>
+ <string name="SocialFacebookErrorPosting">
+ Un problème est survenu lors de la publication sur Facebook.
+ </string>
+ <string name="SocialFacebookErrorDisconnecting">
+ Un problème est survenu lors de la déconnexion à Facebook.
+ </string>
<string name="SocialFlickrConnecting">
Connexion à Flickr...
</string>
@@ -2579,9 +2597,21 @@ Si vous continuez de recevoir ce message, contactez l’assistance Second Life
<string name="NoPicksClassifiedsText">
Vous n&apos;avez pas créé de favoris ni de petites annonces Cliquez sur le bouton Plus pour créer un favori ou une petite annonce.
</string>
+ <string name="NoPicksText">
+ Vous n&apos;avez pas créé de favoris Cliquer sur le bouton Nouveau pour créer un favori
+ </string>
+ <string name="NoClassifiedsText">
+ Vous n&apos;avez pas créé de petites annonces Cliquer sur le bouton Nouveau pour créer une petite annonce.
+ </string>
<string name="NoAvatarPicksClassifiedsText">
L&apos;utilisateur n&apos;a ni favoris ni petites annonces.
</string>
+ <string name="NoAvatarPicksText">
+ L&apos;utilisateur n&apos;a pas de favoris
+ </string>
+ <string name="NoAvatarClassifiedsText">
+ L&apos;utilisateur n&apos;a pas de petites annonces
+ </string>
<string name="PicksClassifiedsLoadingText">
Chargement...
</string>
@@ -4559,6 +4589,9 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE].
<string name="share_alert">
Faire glisser les objets de l&apos;inventaire ici
</string>
+ <string name="facebook_post_success">
+ Vous avez publié sur Facebook.
+ </string>
<string name="flickr_post_success">
Vous avez publié sur Flickr.
</string>
diff --git a/indra/newview/skins/default/xui/it/floater_preview_texture.xml b/indra/newview/skins/default/xui/it/floater_preview_texture.xml
index 8e8d020067..02f15b6b7b 100644
--- a/indra/newview/skins/default/xui/it/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/it/floater_preview_texture.xml
@@ -6,42 +6,23 @@
<floater.string name="Copy">
Copia nell&apos;Inventario
</floater.string>
- <text name="desc txt">
- Descrizione:
- </text>
- <text name="dimensions">
- [WIDTH]px x [HEIGHT]px
- </text>
- <text name="aspect_ratio">
- Antreprima rapporto di visualizzazione
- </text>
- <combo_box name="combo_aspect_ratio" tool_tip="Anteprima con rapporto di visualizzazione fisso">
- <combo_item name="Unconstrained">
- Libero
- </combo_item>
- <combo_item name="1:1" tool_tip="Logo del gruppo o profilo nel mondo reale">
- 1:1
- </combo_item>
- <combo_item name="4:3" tool_tip="Profilo [SECOND_LIFE]">
- 4:3
- </combo_item>
- <combo_item name="10:7" tool_tip="Annunci e inserzioni, punti di riferimento">
- 10:7
- </combo_item>
- <combo_item name="3:2" tool_tip="Informazioni sul terreno">
- 3:2
- </combo_item>
- <combo_item name="16:10">
- 16:10
- </combo_item>
- <combo_item name="16:9" tool_tip="Preferiti del Profilo">
- 16:9
- </combo_item>
- <combo_item name="2:1">
- 2:1
- </combo_item>
- </combo_box>
- <button label="OK" name="Keep"/>
- <button label="Elimina" name="Discard"/>
- <button label="Salva con nome" name="save_tex_btn"/>
+ <layout_stack name="preview_stack">
+ <layout_panel name="texture_panel">
+ <text name="desc txt">
+ Descrizione:
+ </text>
+ <text name="dimensions">
+ [WIDTH]px x [HEIGHT]px
+ </text>
+ <text name="aspect_ratio">
+ Antreprima rapporto di visualizzazione
+ </text>
+ <combo_box name="combo_aspect_ratio" tool_tip="Anteprima con rapporto di visualizzazione fisso"/>
+ </layout_panel>
+ <layout_panel name="buttons_panel">
+ <button label="OK" name="Keep"/>
+ <button label="Elimina" name="Discard"/>
+ <button label="Salva con nome" name="save_tex_btn"/>
+ </layout_panel>
+ </layout_stack>
</floater>
diff --git a/indra/newview/skins/default/xui/it/floater_profile.xml b/indra/newview/skins/default/xui/it/floater_profile.xml
new file mode 100644
index 0000000000..7e23f9bbbb
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/floater_profile.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="avatarinfo" title="Profilo">
+ <panel name="panel_profile_view">
+ <tab_container name="panel_profile_tabs">
+ <panel label="Second Life" name="panel_profile_secondlife"/>
+ <panel label="Web" name="panel_profile_web"/>
+ <panel label="Interessi" name="panel_profile_interests"/>
+ <panel label="Preferiti" name="panel_profile_picks"/>
+ <panel label="Annuncio" name="panel_profile_classifieds"/>
+ <panel label="Vita reale" name="panel_profile_firstlife"/>
+ <panel label="Note" name="panel_profile_notes"/>
+ </tab_container>
+ <button label="OK" name="ok_btn" tool_tip="Salva modifiche al profilo e chiudi"/>
+ <button label="Annulla" label_selected="Annulla" name="cancel_btn"/>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/it/floater_snapshot.xml b/indra/newview/skins/default/xui/it/floater_snapshot.xml
index d21c206f6f..c9f71a167e 100644
--- a/indra/newview/skins/default/xui/it/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/it/floater_snapshot.xml
@@ -6,6 +6,9 @@
<string name="postcard_progress_str">
Invio e-mail in corso
</string>
+ <string name="facebook_progress_str">
+ Pubblicazione su Facebook in corso
+ </string>
<string name="profile_progress_str">
Caricamento post
</string>
@@ -15,6 +18,9 @@
<string name="local_progress_str">
Salvataggio sul computer in corso
</string>
+ <string name="facebook_succeeded_str">
+ Immagine caricata
+ </string>
<string name="profile_succeeded_str">
Immagine caricata
</string>
@@ -27,6 +33,9 @@
<string name="local_succeeded_str">
Salvato sul computer.
</string>
+ <string name="facebook_failed_str">
+ Caricamento immagine sul diario di Facebook non riuscito.
+ </string>
<string name="profile_failed_str">
Caricamento immagine sul feed del profilo non riuscito.
</string>
diff --git a/indra/newview/skins/default/xui/it/menu_name_field.xml b/indra/newview/skins/default/xui/it/menu_name_field.xml
new file mode 100644
index 0000000000..9ac863323c
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/menu_name_field.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="CopyMenu">
+ <menu_item_call label="Copia Nome Visualizzato" name="copy_display"/>
+ <menu_item_call label="Copia Nome Agente" name="copy_name"/>
+ <menu_item_call label="Copia ID Agente" name="copy_id"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/it/notifications.xml b/indra/newview/skins/default/xui/it/notifications.xml
index 1c43013255..a69fa07c50 100644
--- a/indra/newview/skins/default/xui/it/notifications.xml
+++ b/indra/newview/skins/default/xui/it/notifications.xml
@@ -2685,6 +2685,9 @@ Prova a selezionare una parte di terreno più piccola.
<notification name="SystemMessage">
[MESSAGE]
</notification>
+ <notification name="FacebookConnect">
+ [MESSAGE]
+ </notification>
<notification name="FlickrConnect">
[MESSAGE]
</notification>
diff --git a/indra/newview/skins/default/xui/it/panel_edit_classified.xml b/indra/newview/skins/default/xui/it/panel_edit_classified.xml
index ad827696ff..57e422a25b 100644
--- a/indra/newview/skins/default/xui/it/panel_edit_classified.xml
+++ b/indra/newview/skins/default/xui/it/panel_edit_classified.xml
@@ -46,7 +46,7 @@
<layout_panel name="save_changes_btn_lp">
<button label="[LABEL]" name="save_changes_btn"/>
</layout_panel>
- <layout_panel name="show_on_map_btn_lp">
+ <layout_panel name="cancel_btn_lp">
<button label="Annulla" name="cancel_btn"/>
</layout_panel>
</layout_stack>
diff --git a/indra/newview/skins/default/xui/it/panel_facebook_friends.xml b/indra/newview/skins/default/xui/it/panel_facebook_friends.xml
index c1c0489f88..28769a010f 100644
--- a/indra/newview/skins/default/xui/it/panel_facebook_friends.xml
+++ b/indra/newview/skins/default/xui/it/panel_facebook_friends.xml
@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<panel name="panel_facebook_friends">
- <string name="facebook_friends_empty" value="Attualmente non hai amici su Facebook che sono anche residenti in Second Life. Invita i tuoi amici di Facebook a partecipare a Second Life!"/>
- <string name="facebook_friends_no_connected" value="Attualmente non sei in collegamento con Facebook. Accedi alla scheda Stato per collegarti e attivare questa funzionalità."/>
+ <string name="facebook_friends_empty" value="Attualmente non hai amici su Facebook che sono anche residenti Second Life. Invita ora i tuoi amici di Facebook a unirsi a Second Life!"/>
+ <string name="facebook_friends_no_connected" value="Non sei connesso a Facebook. Accedi alla scheda Stato per collegarti e attivare questa funzionalità."/>
<accordion name="friends_accordion">
<accordion_tab name="tab_second_life_friends" title="Amici SL"/>
<accordion_tab name="tab_suggested_friends" title="Aggiungi queste persone come amici SL"/>
</accordion>
<text name="facebook_friends_status">
- Non in collegamento con Facebook.
+ Non connesso a Facebook.
</text>
</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_facebook_photo.xml b/indra/newview/skins/default/xui/it/panel_facebook_photo.xml
index 044b8b6164..8d66f35c3c 100644
--- a/indra/newview/skins/default/xui/it/panel_facebook_photo.xml
+++ b/indra/newview/skins/default/xui/it/panel_facebook_photo.xml
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<panel name="panel_facebook_photo">
- <combo_box name="resolution_combobox" tool_tip="Risoluzione immagini">
+ <combo_box name="resolution_combobox" tool_tip="Risoluzione immagine">
<combo_box.item label="Finestra attuale" name="CurrentWindow"/>
<combo_box.item label="640x480" name="640x480"/>
<combo_box.item label="800x600" name="800x600"/>
<combo_box.item label="1024x768" name="1024x768"/>
<combo_box.item label="1200x630" name="1200x630"/>
</combo_box>
- <combo_box name="filters_combobox" tool_tip="Filtri immagini">
+ <combo_box name="filters_combobox" tool_tip="Filtri immagine">
<combo_box.item label="Nessun filtro" name="NoFilter"/>
</combo_box>
<button label="Aggiorna" name="new_snapshot_btn" tool_tip="Fai clic per aggiornare"/>
diff --git a/indra/newview/skins/default/xui/it/panel_facebook_status.xml b/indra/newview/skins/default/xui/it/panel_facebook_status.xml
index 9b5171043a..7fb1cec78e 100644
--- a/indra/newview/skins/default/xui/it/panel_facebook_status.xml
+++ b/indra/newview/skins/default/xui/it/panel_facebook_status.xml
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<panel name="panel_facebook_status">
- <string name="facebook_connected" value="Sei in collegamento con Facebook come:"/>
- <string name="facebook_disconnected" value="Non in collegamento con Facebook"/>
+ <string name="facebook_connected" value="Sei connesso a Facebook come:"/>
+ <string name="facebook_disconnected" value="Non connesso a Facebook"/>
<text name="account_caption_label">
- Non in collegamento con Facebook.
+ Non connesso a Facebook.
</text>
<panel name="panel_buttons">
- <button label="Collegamento..." name="connect_btn"/>
- <button label="Interrompi collegamento" name="disconnect_btn"/>
+ <button label="Connessione in corso..." name="connect_btn"/>
+ <button label="Disconnetti" name="disconnect_btn"/>
<text name="account_learn_more_label">
[http://community.secondlife.com/t5/English-Knowledge-Base/Second-Life-Share-Facebook/ta-p/2149711 Come pubblicare su Facebook]
</text>
diff --git a/indra/newview/skins/default/xui/it/panel_group_general.xml b/indra/newview/skins/default/xui/it/panel_group_general.xml
index 60028e6098..168524d1ad 100644
--- a/indra/newview/skins/default/xui/it/panel_group_general.xml
+++ b/indra/newview/skins/default/xui/it/panel_group_general.xml
@@ -46,7 +46,7 @@ Muovi il tuo mouse sopra le opzioni per maggiore aiuto.
<check_box label="Chiunque può aderire" name="open_enrollement" tool_tip="Imposta se questo gruppo permette ai nuovi membri di aderire senza essere invitati."/>
<check_box label="Quota di adesione" name="check_enrollment_fee" tool_tip="Imposta se richiedere una tassa d&apos;iscrizione per aderire al gruppo"/>
<spinner label="L$" left_delta="136" name="spin_enrollment_fee" tool_tip="I nuovi soci devono pagare questa tassa d&apos;iscrizione quando è selezionata." width="60"/>
- <combo_box name="group_mature_check" tool_tip="Le categorie di accesso definiscono il tipo di contenuti e di comportamenti ammessi in un gruppo">
+ <combo_box name="group_mature_check" tool_tip="Determina se il tuo gruppo contiene informazioni contrassegnate come Moderate opppure no">
<combo_item name="select_mature">
- Seleziona categoria di accesso -
</combo_item>
diff --git a/indra/newview/skins/default/xui/it/panel_group_list_item_short.xml b/indra/newview/skins/default/xui/it/panel_group_list_item_short.xml
new file mode 100644
index 0000000000..72e644008c
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_group_list_item_short.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="group_list_item">
+ <text name="group_name" value="Sconosciuto"/>
+ <button name="info_btn" tool_tip="Maggiori informazioni"/>
+ <button name="profile_btn" tool_tip="Vedi profilo"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_me.xml b/indra/newview/skins/default/xui/it/panel_me.xml
deleted file mode 100644
index a134f6f1de..0000000000
--- a/indra/newview/skins/default/xui/it/panel_me.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="Il mio profilo" name="panel_me">
- <panel label="I MIEI PREFERITI" name="panel_picks"/>
-</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_people.xml b/indra/newview/skins/default/xui/it/panel_people.xml
index 3df2368ae0..9eb93a26e5 100644
--- a/indra/newview/skins/default/xui/it/panel_people.xml
+++ b/indra/newview/skins/default/xui/it/panel_people.xml
@@ -40,6 +40,7 @@ Stai cercando persone da frequentare? Prova la [secondlife:///app/worldmap Mappa
<accordion name="friends_accordion">
<accordion_tab name="tab_online" title="Online"/>
<accordion_tab name="tab_all" title="Tutto"/>
+ <accordion_tab name="tab_suggested_friends" title="Persone che potresti voler aggiungere agli amici"/>
</accordion>
</panel>
<panel label="GRUPPI" name="groups_panel">
diff --git a/indra/newview/skins/default/xui/it/panel_profile_classified.xml b/indra/newview/skins/default/xui/it/panel_profile_classified.xml
new file mode 100644
index 0000000000..3c88fbe92f
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_profile_classified.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_profile_classified">
+ <panel.string name="type_mature">
+ Moderato
+ </panel.string>
+ <panel.string name="type_pg">
+ Contenuto Generale
+ </panel.string>
+ <panel.string name="l$_price">
+ L$[PRICE]
+ </panel.string>
+ <panel.string name="click_through_text_fmt">
+ [TELEPORT] teletrasporto, [MAP] mappa, [PROFILE] profilo
+ </panel.string>
+ <panel.string name="date_fmt">
+ [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt]
+ </panel.string>
+ <panel.string name="auto_renew_on">
+ Abilitato
+ </panel.string>
+ <panel.string name="auto_renew_off">
+ Disabilitato
+ </panel.string>
+ <panel.string name="location_notice">
+ (si aggiornerà dopo il salvataggio)
+ </panel.string>
+ <string name="publish_label">
+ Pubblica
+ </string>
+ <string name="save_label">
+ Salva
+ </string>
+ <scroll_container name="profile_scroll">
+ <panel name="info_scroll_content_panel">
+ <icon label="" name="edit_icon" tool_tip="Fai clic per selezionare un&apos;immagine"/>
+ <layout_stack name="info_panel">
+ <layout_panel name="main_info_panel">
+ <text_editor name="classified_name">
+ [name]
+ </text_editor>
+ <text name="classified_location_label" value="Posizione:"/>
+ <text_editor name="classified_location" value="[loading...]"/>
+ <text name="content_type_label" value="Tipo di contenuto:"/>
+ <text_editor name="content_type" value="[content type]"/>
+ <text name="category_label" value="Categoria:"/>
+ <text_editor name="category" value="[category]"/>
+ <text name="creation_date_label" value="Data di creazione:"/>
+ <text_editor name="creation_date" tool_tip="Data di creazione" value="[date]"/>
+ <text name="price_for_listing_label" value="Prezzo per inserzione:"/>
+ <text_editor name="price_for_listing" tool_tip="Prezzo per inserzione.">
+ [PRICE]
+ </text_editor>
+ </layout_panel>
+ <layout_panel name="clickthrough_layout_panel">
+ <text name="click_through_label" value="Clic:"/>
+ <text_editor name="click_through_text" tool_tip="Numero di clic" value="[clicks]"/>
+ </layout_panel>
+ <layout_panel name="auto_renew_layout_panel">
+ <text name="auto_renew_label" value="Rinnovo automatico:"/>
+ <text name="auto_renew" value="Abilitato"/>
+ </layout_panel>
+ <layout_panel name="descr_layout_panel">
+ <text name="classified_desc_label" value="Descrizione:"/>
+ <text_editor name="classified_desc" value="[description]"/>
+ </layout_panel>
+ </layout_stack>
+ <panel name="edit_panel">
+ <text name="Name:">
+ Titolo:
+ </text>
+ <text name="description_label">
+ Descrizione:
+ </text>
+ <text name="location_label">
+ Posizione:
+ </text>
+ <text name="classified_location_edit">
+ caricamento in corso...
+ </text>
+ <button label="Imposta come Luogo Attuale" name="set_to_curr_location_btn"/>
+ <text name="category_label" value="Categoria:"/>
+ <text name="content_type_label" value="Tipo di contenuto:"/>
+ <icons_combo_box label="Contenuto Generale" name="content_type_edit">
+ <icons_combo_box.item label="Contenuto Moderato" name="mature_ci" value="Per adulti"/>
+ <icons_combo_box.item label="Contenuto Generale" name="pg_ci" value="PG"/>
+ </icons_combo_box>
+ <check_box label="Rinnovo automatico ogni settimana" name="auto_renew_edit"/>
+ <text name="price_for_listing_edit_label" value="Prezzo per inserzione:"/>
+ <spinner label="L$" name="price_for_listing_edit" tool_tip="Prezzo per inserzione." value="50"/>
+ </panel>
+ </panel>
+ </scroll_container>
+ <layout_stack name="edit_btns_pnl">
+ <layout_panel name="teleport_btn_lp">
+ <button label="Teletrasporto" name="teleport_btn"/>
+ </layout_panel>
+ <layout_panel name="map_btn_lp">
+ <button label="Mappa" name="show_on_map_btn"/>
+ </layout_panel>
+ <layout_panel name="edit_btn_lp">
+ <button label="Modifica" name="edit_btn"/>
+ </layout_panel>
+ <layout_panel name="save_btn_lp">
+ <button label="[LABEL]" name="save_changes_btn"/>
+ </layout_panel>
+ <layout_panel name="cancel_btn_lp">
+ <button label="Annulla" name="cancel_btn"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_profile_classifieds.xml b/indra/newview/skins/default/xui/it/panel_profile_classifieds.xml
new file mode 100644
index 0000000000..6fc0fd0729
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_profile_classifieds.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Annuncio" name="panel_profile_classifieds">
+ <string name="no_classifieds" value="Nessuno annuncio"/>
+ <button label="Nuovo..." name="new_btn"/>
+ <button label="Elimina..." name="delete_btn"/>
+ <text name="classifieds_panel_text">
+ Caricamento in corso...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_profile_firstlife.xml b/indra/newview/skins/default/xui/it/panel_profile_firstlife.xml
new file mode 100644
index 0000000000..bf8ccef273
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_profile_firstlife.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Profilo" name="panel_profile_firstlife"/>
diff --git a/indra/newview/skins/default/xui/it/panel_profile_interests.xml b/indra/newview/skins/default/xui/it/panel_profile_interests.xml
new file mode 100644
index 0000000000..9fe7331e5c
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_profile_interests.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Interessi" name="panel_profile_interests">
+ <text name="I Want To:">
+ Desidero:
+ </text>
+ <check_box label="Costruire" name="chk0"/>
+ <check_box label="Esplorare" name="chk1"/>
+ <check_box label="Incontrare" name="chk2"/>
+ <check_box label="Essere assunto" name="chk6"/>
+ <check_box label="Gruppo" name="chk3"/>
+ <check_box label="Acquistare" name="chk4"/>
+ <check_box label="Vendere" name="chk5"/>
+ <check_box label="Assumere" name="chk7"/>
+ <line_editor name="want_to_edit">
+ (caricamento in corso...)
+ </line_editor>
+ <text name="Skills:">
+ Abilità:
+ </text>
+ <check_box label="Texture" name="schk0"/>
+ <check_box label="Architettura" name="schk1"/>
+ <check_box label="Realizzazione modelli 3D" name="schk3"/>
+ <check_box label="Organizzazione eventi" name="schk2"/>
+ <check_box label="Scripting" name="schk4"/>
+ <check_box label="Personaggi personalizzati" name="schk5"/>
+ <line_editor name="skills_edit">
+ (caricamento in corso...)
+ </line_editor>
+ <text name="Languages:">
+ Lingue:
+ </text>
+ <line_editor name="languages_edit">
+ (caricamento in corso...)
+ </line_editor>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_profile_notes.xml b/indra/newview/skins/default/xui/it/panel_profile_notes.xml
new file mode 100644
index 0000000000..abd5a347c3
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_profile_notes.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Note e Privacy" name="panel_notes">
+ <text name="status_message" value="Annotazioni private su questo avatar:"/>
+ <text name="status_message2" value="Consenti a questo avatar di:"/>
+ <check_box label="Vedere quando sono in linea" name="status_check"/>
+ <check_box label="Trovarmi sulla mappa del mondo" name="map_check"/>
+ <check_box label="Modificare, eliminare o prendere i miei oggetti" name="objects_check"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_profile_pick.xml b/indra/newview/skins/default/xui/it/panel_profile_pick.xml
new file mode 100644
index 0000000000..5d2b145565
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_profile_pick.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_pick_info">
+ <panel.string name="location_notice">
+ (si aggiornerà dopo il salvataggio)
+ </panel.string>
+ <line_editor name="pick_location">
+ Caricamento in corso...
+ </line_editor>
+ <button label="Teletrasporto" name="teleport_btn"/>
+ <button label="Mostra sulla mappa" name="show_on_map_btn"/>
+ <button label="Imposta Luogo" name="set_to_curr_location_btn" tool_tip="Imposta come Luogo Attuale"/>
+ <button label="Salva Luogo preferito" name="save_changes_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_profile_picks.xml b/indra/newview/skins/default/xui/it/panel_profile_picks.xml
new file mode 100644
index 0000000000..37cffcf622
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_profile_picks.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Preferiti" name="panel_picks">
+ <string name="no_picks" value="Nessun preferito"/>
+ <text name="Tell everyone about your favorite places in Second Life.">
+ Comunica a tutti quali sono i tuoi posti preferiti in Second Life.
+ </text>
+ <button label="Nuovo..." name="new_btn"/>
+ <button label="Elimina..." name="delete_btn"/>
+ <text name="picks_panel_text">
+ Caricamento in corso...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/it/panel_profile_secondlife.xml
new file mode 100644
index 0000000000..47af1960a5
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_profile_secondlife.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Profilo" name="panel_profile">
+ <string name="status_online">
+ Ora in linea
+ </string>
+ <string name="status_offline">
+ Ora non in linea
+ </string>
+ <string name="CaptionTextAcctInfo">
+ [ACCTTYPE]
+[PAYMENTINFO]
+ </string>
+ <string name="payment_update_link_url">
+ http://www.secondlife.com/account/billing.php?lang=en
+ </string>
+ <string name="partner_edit_link_url">
+ http://www.secondlife.com/account/partners.php?lang=en
+ </string>
+ <string name="my_account_link_url" value="http://secondlife.com/account"/>
+ <string name="no_partner_text" value="Nessuno"/>
+ <string name="no_group_text" value="Nessuno"/>
+ <string name="RegisterDateFormat">
+ [REG_DATE]
+ </string>
+ <string name="name_text_args">
+ [NAME]
+ </string>
+ <string name="display_name_text_args">
+ [DISPLAY_NAME]
+ </string>
+ <string name="FSDev" value="Sviluppatore"/>
+ <string name="FSSupp" value="Assistenza"/>
+ <string name="FSQualityAssurance" value="Bug Hunter"/>
+ <string name="FSGW" value="Gateway"/>
+ <text name="name_label" value="Nome:"/>
+ <button label="Nome:" name="set_name" tool_tip="Imposta nome visualizzato"/>
+ <panel name="name_holder">
+ <text_editor name="complete_name" value="(caricamento in corso...)"/>
+ </panel>
+ <layout_stack name="imagepositioner">
+ <layout_panel name="label_stack">
+ <text name="status" value="Stato Sconosciuto"/>
+ <text name="label" value="Compleanno Second Life:"/>
+ <text name="label2" value="Account:"/>
+ <text name="partner_label" value="Partner:"/>
+ </layout_panel>
+ </layout_stack>
+ <text name="Groups:" value="Gruppi:"/>
+ <button label="+" label_selected="+" name="group_invite" tool_tip="Invita al gruppo:"/>
+ <layout_stack name="aboutpositioner">
+ <layout_panel name="about_stack">
+ <text name="About:" value="Informazioni generali:"/>
+ </layout_panel>
+ <layout_panel name="give_stack">
+ <text name="Give item:" value="Consegna oggetto:"/>
+ <text name="Give inventory" tool_tip="Rilascia gli oggetti dell’inventario per consegnarli a questa persona.">
+ Rilascia l’oggetto dell’inventario qui.
+ </text>
+ </layout_panel>
+ </layout_stack>
+ <layout_stack name="buttonstack">
+ <layout_panel name="left_buttonstack">
+ <button label="Trova sulla mappa" label_selected="Trova sulla mappa" name="show_on_map_btn" tool_tip="Localizza il Residente sulla mappa"/>
+ <button label="Paga" label_selected="Paga" name="pay" tool_tip="Paga del denaro al Residente"/>
+ </layout_panel>
+ <layout_panel name="middle_buttonstack">
+ <button label="Offri Teletrasporto" label_selected="Offri Teletrasporto" name="teleport" tool_tip="Offri il teletrasporto al Residente"/>
+ <button label="Messaggio istantaneo" label_selected="Messaggio istantaneo" name="im" tool_tip="Apri sessione di messaggistica istantanea"/>
+ </layout_panel>
+ <layout_panel name="right_buttonstack">
+ <button label="Aggiungi come amico" label_selected="Aggiungi come amico" name="add_friend" tool_tip="Offri amicizia al Residente"/>
+ <button label="Blocca" name="block" tool_tip="Blocca questo Residente"/>
+ <button label="Sblocca" name="unblock" tool_tip="Sblocca questo Residente"/>
+ </layout_panel>
+ </layout_stack>
+ <check_box label="Mostra nella ricerca" name="show_in_search_checkbox"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_profile_web.xml b/indra/newview/skins/default/xui/it/panel_profile_web.xml
new file mode 100644
index 0000000000..0c3a8ddcf5
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_profile_web.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Web" name="panel_profile_web">
+ <panel.string name="LoadTime" value="Tempo di caricamento: [TIME] secondi"/>
+ <line_editor name="url_edit">
+ (caricamento in corso..)
+ </line_editor>
+ <flyout_button label="Carica" name="load" tool_tip="Carica la pagina profilo con il browser Web integrato.">
+ <flyout_button.item label="Apri browser interno" name="open_item"/>
+ <flyout_button.item label="Apri browser esterno" name="home_item"/>
+ </flyout_button>
+ <button name="web_profile_popout_btn" tool_tip="Profilo web a comparsa"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/strings.xml b/indra/newview/skins/default/xui/it/strings.xml
index ea972e5a13..52f5f7af18 100644
--- a/indra/newview/skins/default/xui/it/strings.xml
+++ b/indra/newview/skins/default/xui/it/strings.xml
@@ -353,6 +353,24 @@ Prova ad accedere nuovamente tra un minuto.
<string name="TestingDisconnect">
Verifica scollegamento viewer
</string>
+ <string name="SocialFacebookConnecting">
+ Connessione a Facebook in corso...
+ </string>
+ <string name="SocialFacebookPosting">
+ Caricamento post...
+ </string>
+ <string name="SocialFacebookDisconnecting">
+ Disconnessione da Facebook in corso...
+ </string>
+ <string name="SocialFacebookErrorConnecting">
+ Problemi con la connessione a Facebook
+ </string>
+ <string name="SocialFacebookErrorPosting">
+ Problemi con la connessione a Facebook
+ </string>
+ <string name="SocialFacebookErrorDisconnecting">
+ Problemi con la disconnessione da Facebook
+ </string>
<string name="SocialFlickrConnecting">
Collegamento a Flickr...
</string>
@@ -2557,9 +2575,21 @@ Se continui a ricevere questo messaggio, contatta l&apos;assistenza Second Life
<string name="NoPicksClassifiedsText">
Non hai creato luoghi preferiti né inserzioni. Clicca il pulsante + qui sotto per creare un luogo preferito o un&apos;inserzione.
</string>
+ <string name="NoPicksText">
+ Non hai creato Luoghi preferiti. Fai clic sul pulsante Nuovo per creare un Luogo preferito.
+ </string>
+ <string name="NoClassifiedsText">
+ Non hai creato Annunci. Fai clic sul pulsante Nuovo per creare un Annuncio.
+ </string>
<string name="NoAvatarPicksClassifiedsText">
L&apos;utente non ha luoghi preferiti né inserzioni
</string>
+ <string name="NoAvatarPicksText">
+ L&apos;utente non ha luoghi preferiti
+ </string>
+ <string name="NoAvatarClassifiedsText">
+ L&apos;utente non ha annunci
+ </string>
<string name="PicksClassifiedsLoadingText">
Caricamento in corso...
</string>
@@ -4474,6 +4504,9 @@ Se il messaggio persiste, contatta [SUPPORT_SITE].
<string name="inventory_folder_offered-im">
Offerta cartella di inventario &quot;[ITEM_NAME]&quot;
</string>
+ <string name="facebook_post_success">
+ Hai pubblicato su Facebook.
+ </string>
<string name="flickr_post_success">
Hai pubblicato su Flickr.
</string>
diff --git a/indra/newview/skins/default/xui/ja/floater_picks.xml b/indra/newview/skins/default/xui/ja/floater_picks.xml
deleted file mode 100644
index 359585eb86..0000000000
--- a/indra/newview/skins/default/xui/ja/floater_picks.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_picks" title="ピック"/>
diff --git a/indra/newview/skins/default/xui/ja/floater_preview_texture.xml b/indra/newview/skins/default/xui/ja/floater_preview_texture.xml
index 4617fd1d92..66ef13948a 100644
--- a/indra/newview/skins/default/xui/ja/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/ja/floater_preview_texture.xml
@@ -6,42 +6,23 @@
<floater.string name="Copy">
インベントリにコピー
</floater.string>
- <text name="desc txt">
- 説明:
- </text>
- <text name="dimensions">
- [WIDTH]px x [HEIGHT]px
- </text>
- <text name="aspect_ratio">
- 縦横比のプレビュー
- </text>
- <combo_box name="combo_aspect_ratio" tool_tip="固定した縦横比のプレビュー">
- <combo_item name="Unconstrained">
- 非拘束
- </combo_item>
- <combo_item name="1:1" tool_tip="グループ記章か現実世界のプロフィール">
- 1:1
- </combo_item>
- <combo_item name="4:3" tool_tip="[SECOND_LIFE] プロフィール">
- 4:3
- </combo_item>
- <combo_item name="10:7" tool_tip="クラシファイド広告、検索一覧、ランドマーク">
- 10:7
- </combo_item>
- <combo_item name="3:2" tool_tip="土地情報">
- 3:2
- </combo_item>
- <combo_item name="16:10">
- 16:10
- </combo_item>
- <combo_item name="16:9" tool_tip="プロフィールのピック">
- 16:9
- </combo_item>
- <combo_item name="2:1">
- 2:1
- </combo_item>
- </combo_box>
- <button label="OK" name="Keep"/>
- <button label="処分する" name="Discard"/>
- <button label="別名で保存" name="save_tex_btn"/>
+ <layout_stack name="preview_stack">
+ <layout_panel name="texture_panel">
+ <text name="desc txt">
+ 説明:
+ </text>
+ <text name="dimensions">
+ [WIDTH]px x [HEIGHT]px
+ </text>
+ <text name="aspect_ratio">
+ 縦横比のプレビュー
+ </text>
+ <combo_box name="combo_aspect_ratio" tool_tip="固定した縦横比のプレビュー"/>
+ </layout_panel>
+ <layout_panel name="buttons_panel">
+ <button label="OK" name="Keep"/>
+ <button label="処分する" name="Discard"/>
+ <button label="別名で保存" name="save_tex_btn"/>
+ </layout_panel>
+ </layout_stack>
</floater>
diff --git a/indra/newview/skins/default/xui/ja/floater_profile.xml b/indra/newview/skins/default/xui/ja/floater_profile.xml
new file mode 100644
index 0000000000..e06cd6e8f6
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/floater_profile.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="avatarinfo" title="プロフィール">
+ <panel name="panel_profile_view">
+ <tab_container name="panel_profile_tabs">
+ <panel label="Second Life" name="panel_profile_secondlife"/>
+ <panel label="Web" name="panel_profile_web"/>
+ <panel label="趣味" name="panel_profile_interests"/>
+ <panel label="ピック" name="panel_profile_picks"/>
+ <panel label="クラシファイド広告" name="panel_profile_classifieds"/>
+ <panel label="リアルライフ(現実世界)" name="panel_profile_firstlife"/>
+ <panel label="メモ" name="panel_profile_notes"/>
+ </tab_container>
+ <button label="OK" name="ok_btn" tool_tip="プロフィールの変更を保存して閉じる"/>
+ <button label="キャンセル" label_selected="キャンセル" name="cancel_btn"/>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/ja/floater_snapshot.xml b/indra/newview/skins/default/xui/ja/floater_snapshot.xml
index f04193d034..64f292c75c 100644
--- a/indra/newview/skins/default/xui/ja/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/ja/floater_snapshot.xml
@@ -6,6 +6,9 @@
<string name="postcard_progress_str">
メールの送信
</string>
+ <string name="facebook_progress_str">
+ Facebook へ投稿中
+ </string>
<string name="profile_progress_str">
投稿
</string>
@@ -15,6 +18,9 @@
<string name="local_progress_str">
コンピュータに保存
</string>
+ <string name="facebook_succeeded_str">
+ 画像がアップロードされました
+ </string>
<string name="profile_succeeded_str">
画像がアップロードされました
</string>
@@ -27,6 +33,9 @@
<string name="local_succeeded_str">
コンピュータに保存されました
</string>
+ <string name="facebook_failed_str">
+ Facebook のタイムラインに画像をアップロードできませんでした。
+ </string>
<string name="profile_failed_str">
プロフィールフィードに画像をアップロードできませんでした。
</string>
diff --git a/indra/newview/skins/default/xui/ja/menu_name_field.xml b/indra/newview/skins/default/xui/ja/menu_name_field.xml
new file mode 100644
index 0000000000..8c37d95073
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/menu_name_field.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="CopyMenu">
+ <menu_item_call label="表示名をコピー" name="copy_display"/>
+ <menu_item_call label="エージェント名をコピー" name="copy_name"/>
+ <menu_item_call label="エージェント ID をコピー" name="copy_id"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/ja/notifications.xml b/indra/newview/skins/default/xui/ja/notifications.xml
index a66552d3fe..92952f4c8a 100644
--- a/indra/newview/skins/default/xui/ja/notifications.xml
+++ b/indra/newview/skins/default/xui/ja/notifications.xml
@@ -2727,6 +2727,9 @@ Web ページにリンクすると、他人がこの場所に簡単にアクセ
<notification name="SystemMessage">
[MESSAGE]
</notification>
+ <notification name="FacebookConnect">
+ [MESSAGE]
+ </notification>
<notification name="FlickrConnect">
[MESSAGE]
</notification>
diff --git a/indra/newview/skins/default/xui/ja/panel_edit_classified.xml b/indra/newview/skins/default/xui/ja/panel_edit_classified.xml
index cf5f2489f1..619e9de65a 100644
--- a/indra/newview/skins/default/xui/ja/panel_edit_classified.xml
+++ b/indra/newview/skins/default/xui/ja/panel_edit_classified.xml
@@ -46,7 +46,7 @@
<layout_panel name="save_changes_btn_lp">
<button label="[LABEL]" name="save_changes_btn"/>
</layout_panel>
- <layout_panel name="show_on_map_btn_lp">
+ <layout_panel name="cancel_btn_lp">
<button label="キャンセル" name="cancel_btn"/>
</layout_panel>
</layout_stack>
diff --git a/indra/newview/skins/default/xui/ja/panel_facebook_photo.xml b/indra/newview/skins/default/xui/ja/panel_facebook_photo.xml
index c48f13456b..ee57d178e8 100644
--- a/indra/newview/skins/default/xui/ja/panel_facebook_photo.xml
+++ b/indra/newview/skins/default/xui/ja/panel_facebook_photo.xml
@@ -16,5 +16,5 @@
コメント (オプション):
</text>
<button label="投稿" name="post_photo_btn"/>
- <button label="取り消し" name="cancel_photo_btn"/>
+ <button label="キャンセル" name="cancel_photo_btn"/>
</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_facebook_place.xml b/indra/newview/skins/default/xui/ja/panel_facebook_place.xml
index 61138f90c1..e97422a9df 100644
--- a/indra/newview/skins/default/xui/ja/panel_facebook_place.xml
+++ b/indra/newview/skins/default/xui/ja/panel_facebook_place.xml
@@ -5,5 +5,5 @@
</text>
<check_box initial_value="false" label="場所の俯瞰図を含める" name="add_place_view_cb"/>
<button label="投稿" name="post_place_btn"/>
- <button label="取り消し" name="cancel_place_btn"/>
+ <button label="キャンセル" name="cancel_place_btn"/>
</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_facebook_status.xml b/indra/newview/skins/default/xui/ja/panel_facebook_status.xml
index 9d962c9d62..1f48c9c8c7 100644
--- a/indra/newview/skins/default/xui/ja/panel_facebook_status.xml
+++ b/indra/newview/skins/default/xui/ja/panel_facebook_status.xml
@@ -9,12 +9,12 @@
<button label="接続..." name="connect_btn"/>
<button label="切断" name="disconnect_btn"/>
<text name="account_learn_more_label">
- [http://community.secondlife.com/t5/English-Knowledge-Base/Second-Life-Share-Facebook/ta-p/2149711 Facebook への投稿について]]
+ [http://community.secondlife.com/t5/English-Knowledge-Base/Second-Life-Share-Facebook/ta-p/2149711 Facebook への投稿について]
</text>
</panel>
<text name="status_caption_label">
今、何を考えている?
</text>
<button label="投稿" name="post_status_btn"/>
- <button label="取り消し" name="cancel_status_btn"/>
+ <button label="キャンセル" name="cancel_status_btn"/>
</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_group_list_item_short.xml b/indra/newview/skins/default/xui/ja/panel_group_list_item_short.xml
new file mode 100644
index 0000000000..77d3d8f391
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_group_list_item_short.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="group_list_item">
+ <text name="group_name" value="不明"/>
+ <button name="info_btn" tool_tip="詳細"/>
+ <button name="profile_btn" tool_tip="プロフィールの表示"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_me.xml b/indra/newview/skins/default/xui/ja/panel_me.xml
deleted file mode 100644
index 9b1cf1c8a4..0000000000
--- a/indra/newview/skins/default/xui/ja/panel_me.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="プロフィール" name="panel_me">
- <panel label="マイ ピック" name="panel_picks"/>
-</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_people.xml b/indra/newview/skins/default/xui/ja/panel_people.xml
index 0a295855d0..be00a3c122 100644
--- a/indra/newview/skins/default/xui/ja/panel_people.xml
+++ b/indra/newview/skins/default/xui/ja/panel_people.xml
@@ -40,6 +40,7 @@
<accordion name="friends_accordion">
<accordion_tab name="tab_online" title="オンライン"/>
<accordion_tab name="tab_all" title="全員"/>
+ <accordion_tab name="tab_suggested_friends" title="友だちになりたくない人"/>
</accordion>
</panel>
<panel label="グループ" name="groups_panel">
diff --git a/indra/newview/skins/default/xui/ja/panel_profile_classified.xml b/indra/newview/skins/default/xui/ja/panel_profile_classified.xml
new file mode 100644
index 0000000000..2d1bc07e2c
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_profile_classified.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_profile_classified">
+ <panel.string name="type_mature">
+ Moderate
+ </panel.string>
+ <panel.string name="type_pg">
+ General コンテンツ
+ </panel.string>
+ <panel.string name="l$_price">
+ L$[PRICE]
+ </panel.string>
+ <panel.string name="click_through_text_fmt">
+ [TELEPORT] テレポート、 [MAP] 地図、 [PROFILE] プロフィール
+ </panel.string>
+ <panel.string name="date_fmt">
+ [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt]
+ </panel.string>
+ <panel.string name="auto_renew_on">
+ 有効
+ </panel.string>
+ <panel.string name="auto_renew_off">
+ 無効
+ </panel.string>
+ <panel.string name="location_notice">
+ (掲載後更新)
+ </panel.string>
+ <string name="publish_label">
+ 掲載
+ </string>
+ <string name="save_label">
+ 保存
+ </string>
+ <scroll_container name="profile_scroll">
+ <panel name="info_scroll_content_panel">
+ <icon label="" name="edit_icon" tool_tip="クリックして画像を選択"/>
+ <layout_stack name="info_panel">
+ <layout_panel name="main_info_panel">
+ <text_editor name="classified_name">
+ [name]
+ </text_editor>
+ <text name="classified_location_label" value="場所:"/>
+ <text_editor name="classified_location" value="[loading...]"/>
+ <text name="content_type_label" value="コンテンツの種類:"/>
+ <text_editor name="content_type" value="[content type]"/>
+ <text name="category_label" value="カテゴリ:"/>
+ <text_editor name="category" value="[category]"/>
+ <text name="creation_date_label" value="制作日:"/>
+ <text_editor name="creation_date" tool_tip="制作日" value="[date]"/>
+ <text name="price_for_listing_label" value="掲載価格:"/>
+ <text_editor name="price_for_listing" tool_tip="掲載価格。">
+ [PRICE]
+ </text_editor>
+ </layout_panel>
+ <layout_panel name="clickthrough_layout_panel">
+ <text name="click_through_label" value="クリック数:"/>
+ <text_editor name="click_through_text" tool_tip="クリックスルーデータ" value="[clicks]"/>
+ </layout_panel>
+ <layout_panel name="auto_renew_layout_panel">
+ <text name="auto_renew_label" value="自動更新:"/>
+ <text name="auto_renew" value="有効"/>
+ </layout_panel>
+ <layout_panel name="descr_layout_panel">
+ <text name="classified_desc_label" value="説明:"/>
+ <text_editor name="classified_desc" value="[description]"/>
+ </layout_panel>
+ </layout_stack>
+ <panel name="edit_panel">
+ <text name="Name:">
+ タイトル:
+ </text>
+ <text name="description_label">
+ 説明:
+ </text>
+ <text name="location_label">
+ 場所:
+ </text>
+ <text name="classified_location_edit">
+ ロード中...
+ </text>
+ <button label="現在地に設定" name="set_to_curr_location_btn"/>
+ <text name="category_label" value="カテゴリ:"/>
+ <text name="content_type_label" value="コンテンツの種類:"/>
+ <icons_combo_box label="General コンテンツ" name="content_type_edit">
+ <icons_combo_box.item label="Moderate コンテンツ" name="mature_ci" value="Mature"/>
+ <icons_combo_box.item label="General コンテンツ" name="pg_ci" value="PG"/>
+ </icons_combo_box>
+ <check_box label="毎週自動更新" name="auto_renew_edit"/>
+ <text name="price_for_listing_edit_label" value="掲載価格:"/>
+ <spinner label="L$" name="price_for_listing_edit" tool_tip="掲載価格。" value="50"/>
+ </panel>
+ </panel>
+ </scroll_container>
+ <layout_stack name="edit_btns_pnl">
+ <layout_panel name="teleport_btn_lp">
+ <button label="テレポート" name="teleport_btn"/>
+ </layout_panel>
+ <layout_panel name="map_btn_lp">
+ <button label="地図" name="show_on_map_btn"/>
+ </layout_panel>
+ <layout_panel name="edit_btn_lp">
+ <button label="編集" name="edit_btn"/>
+ </layout_panel>
+ <layout_panel name="save_btn_lp">
+ <button label="[LABEL]" name="save_changes_btn"/>
+ </layout_panel>
+ <layout_panel name="cancel_btn_lp">
+ <button label="キャンセル" name="cancel_btn"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_profile_classifieds.xml b/indra/newview/skins/default/xui/ja/panel_profile_classifieds.xml
new file mode 100644
index 0000000000..1980c0fa62
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_profile_classifieds.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="クラシファイド広告" name="panel_profile_classifieds">
+ <string name="no_classifieds" value="クラシファイド広告なし"/>
+ <button label="新規…" name="new_btn"/>
+ <button label="削除…" name="delete_btn"/>
+ <text name="classifieds_panel_text">
+ ロード中...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_profile_firstlife.xml b/indra/newview/skins/default/xui/ja/panel_profile_firstlife.xml
new file mode 100644
index 0000000000..a4ee262cb3
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_profile_firstlife.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="プロフィール" name="panel_profile_firstlife"/>
diff --git a/indra/newview/skins/default/xui/ja/panel_profile_interests.xml b/indra/newview/skins/default/xui/ja/panel_profile_interests.xml
new file mode 100644
index 0000000000..93cde6ffec
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_profile_interests.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="趣味" name="panel_profile_interests">
+ <text name="I Want To:">
+ 次の内容を実行:
+ </text>
+ <check_box label="作る" name="chk0"/>
+ <check_box label="探検" name="chk1"/>
+ <check_box label="出会う" name="chk2"/>
+ <check_box label="雇ってもらう" name="chk6"/>
+ <check_box label="グループ" name="chk3"/>
+ <check_box label="買う" name="chk4"/>
+ <check_box label="販売する" name="chk5"/>
+ <check_box label="雇う" name="chk7"/>
+ <line_editor name="want_to_edit">
+ (ロード中...)
+ </line_editor>
+ <text name="Skills:">
+ スキル:
+ </text>
+ <check_box label="テクスチャ" name="schk0"/>
+ <check_box label="建築" name="schk1"/>
+ <check_box label="モデリング" name="schk3"/>
+ <check_box label="イベント計画" name="schk2"/>
+ <check_box label="スクリプト" name="schk4"/>
+ <check_box label="キャラクターのカスタマイズ" name="schk5"/>
+ <line_editor name="skills_edit">
+ (ロード中...)
+ </line_editor>
+ <text name="Languages:">
+ 言語:
+ </text>
+ <line_editor name="languages_edit">
+ (ロード中...)
+ </line_editor>
+</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_profile_notes.xml b/indra/newview/skins/default/xui/ja/panel_profile_notes.xml
new file mode 100644
index 0000000000..4b4e0d5e4e
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_profile_notes.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="メモとプライバシー" name="panel_notes">
+ <text name="status_message" value="このアバターのプライベートメモ:"/>
+ <text name="status_message2" value="このアバターに次の許可を与える:"/>
+ <check_box label="自分のオンラインステータスを表示する" name="status_check"/>
+ <check_box label="世界地図で自分を探せるようにする" name="map_check"/>
+ <check_box label="自分のオブジェクトを編集・削除・取得できるようにする" name="objects_check"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_profile_pick.xml b/indra/newview/skins/default/xui/ja/panel_profile_pick.xml
new file mode 100644
index 0000000000..0a20c04ad6
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_profile_pick.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_pick_info">
+ <panel.string name="location_notice">
+ (掲載後更新)
+ </panel.string>
+ <line_editor name="pick_location">
+ ロード中...
+ </line_editor>
+ <button label="テレポート" name="teleport_btn"/>
+ <button label="地図に表示" name="show_on_map_btn"/>
+ <button label="場所を設定" name="set_to_curr_location_btn" tool_tip="現在地に設定"/>
+ <button label="ピックを保存" name="save_changes_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_profile_picks.xml b/indra/newview/skins/default/xui/ja/panel_profile_picks.xml
new file mode 100644
index 0000000000..4cbfadd09d
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_profile_picks.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="ピック" name="panel_picks">
+ <string name="no_picks" value="ピックなし"/>
+ <text name="Tell everyone about your favorite places in Second Life.">
+ Second Life のお気に入りの場所を紹介しましょう。
+ </text>
+ <button label="新規…" name="new_btn"/>
+ <button label="削除…" name="delete_btn"/>
+ <text name="picks_panel_text">
+ ロード中...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/ja/panel_profile_secondlife.xml
new file mode 100644
index 0000000000..5470dc6c82
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_profile_secondlife.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="プロフィール" name="panel_profile">
+ <string name="status_online">
+ オンライン中
+ </string>
+ <string name="status_offline">
+ オフライン中
+ </string>
+ <string name="CaptionTextAcctInfo">
+ [ACCTTYPE]
+[PAYMENTINFO]
+ </string>
+ <string name="payment_update_link_url">
+ http://www.secondlife.com/account/billing.php?lang=en
+ </string>
+ <string name="partner_edit_link_url">
+ http://www.secondlife.com/account/partners.php?lang=en
+ </string>
+ <string name="my_account_link_url" value="http://secondlife.com/account"/>
+ <string name="no_partner_text" value="なし"/>
+ <string name="no_group_text" value="なし"/>
+ <string name="RegisterDateFormat">
+ [REG_DATE]
+ </string>
+ <string name="name_text_args">
+ [NAME]
+ </string>
+ <string name="display_name_text_args">
+ [DISPLAY_NAME]
+ </string>
+ <string name="FSDev" value="開発者"/>
+ <string name="FSSupp" value="サポート"/>
+ <string name="FSQualityAssurance" value="バグハンター"/>
+ <string name="FSGW" value="ゲートウェイ"/>
+ <text name="name_label" value="名前:"/>
+ <button label="名前:" name="set_name" tool_tip="表示名を設定"/>
+ <panel name="name_holder">
+ <text_editor name="complete_name" value="(ロード中...)"/>
+ </panel>
+ <layout_stack name="imagepositioner">
+ <layout_panel name="label_stack">
+ <text name="status" value="ステータス不明"/>
+ <text name="label" value="Second Life 生年月日:"/>
+ <text name="label2" value="アカウント:"/>
+ <text name="partner_label" value="パートナー:"/>
+ </layout_panel>
+ </layout_stack>
+ <text name="Groups:" value="グループ:"/>
+ <button label="+" label_selected="+" name="group_invite" tool_tip="グループに招待"/>
+ <layout_stack name="aboutpositioner">
+ <layout_panel name="about_stack">
+ <text name="About:" value="詳細:"/>
+ </layout_panel>
+ <layout_panel name="give_stack">
+ <text name="Give item:" value="アイテムを渡す:"/>
+ <text name="Give inventory" tool_tip="インベントリのアイテムをここにドロップしてこの人に渡します。">
+ インベントリのアイテムをここにドロップしてください。
+ </text>
+ </layout_panel>
+ </layout_stack>
+ <layout_stack name="buttonstack">
+ <layout_panel name="left_buttonstack">
+ <button label="地図上で見つける" label_selected="地図上で見つける" name="show_on_map_btn" tool_tip="住人を地図上で探す"/>
+ <button label="お金を払う" label_selected="お金を払う" name="pay" tool_tip="住人にお金を支払う"/>
+ </layout_panel>
+ <layout_panel name="middle_buttonstack">
+ <button label="テレポートを送る" label_selected="テレポートを送る" name="teleport" tool_tip="住人にテレポートを送る"/>
+ <button label="インスタントメッセージ" label_selected="インスタントメッセージ" name="im" tool_tip="インスタントメッセージを開きます"/>
+ </layout_panel>
+ <layout_panel name="right_buttonstack">
+ <button label="フレンド登録" label_selected="フレンド登録" name="add_friend" tool_tip="フレンド登録を申し出ます"/>
+ <button label="ブロック" name="block" tool_tip="この住人をブロックする"/>
+ <button label="ブロック解除" name="unblock" tool_tip="この住人のブロックを解除する"/>
+ </layout_panel>
+ </layout_stack>
+ <check_box label="検索に表示" name="show_in_search_checkbox"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_profile_web.xml b/indra/newview/skins/default/xui/ja/panel_profile_web.xml
new file mode 100644
index 0000000000..4f56a7e98d
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_profile_web.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Web" name="panel_profile_web">
+ <panel.string name="LoadTime" value="ロード時間:[TIME] 秒"/>
+ <line_editor name="url_edit">
+ (ロード中...)
+ </line_editor>
+ <flyout_button label="ロード" name="load" tool_tip="このプロフィールページを、組み込み Web ブラウザでロードします。">
+ <flyout_button.item label="ビューワ内のブラウザを開く" name="open_item"/>
+ <flyout_button.item label="外部ブラウザを開く" name="home_item"/>
+ </flyout_button>
+ <button name="web_profile_popout_btn" tool_tip="Web プロフィールのポップアウト"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_snapshot_options.xml b/indra/newview/skins/default/xui/ja/panel_snapshot_options.xml
index 04dfc0176d..f222a4d61a 100644
--- a/indra/newview/skins/default/xui/ja/panel_snapshot_options.xml
+++ b/indra/newview/skins/default/xui/ja/panel_snapshot_options.xml
@@ -3,7 +3,7 @@
<button label="ディスクに保存" name="save_to_computer_btn"/>
<button label="持ち物に保存(L$[AMOUNT])" name="save_to_inventory_btn"/>
<button label="プロフィールフィードで共有する" name="save_to_profile_btn"/>
- <button label="Facebook で共有する" name="send_to_facebook_btn"/>
+ <button label="Facebook でシェア" name="send_to_facebook_btn"/>
<button label="Twitter で共有する" name="send_to_twitter_btn"/>
<button label="Flickr で共有する" name="send_to_flickr_btn"/>
<button label="メールにより送信" name="save_to_email_btn"/>
diff --git a/indra/newview/skins/default/xui/ja/strings.xml b/indra/newview/skins/default/xui/ja/strings.xml
index 344f9fcd94..c5bba021ac 100644
--- a/indra/newview/skins/default/xui/ja/strings.xml
+++ b/indra/newview/skins/default/xui/ja/strings.xml
@@ -356,6 +356,24 @@ support@secondlife.com にお問い合わせください。
<string name="TestingDisconnect">
ビューワの接続を切るテスト中
</string>
+ <string name="SocialFacebookConnecting">
+ Facebook に接続中...
+ </string>
+ <string name="SocialFacebookPosting">
+ 投稿中...
+ </string>
+ <string name="SocialFacebookDisconnecting">
+ Facebook から切断中...
+ </string>
+ <string name="SocialFacebookErrorConnecting">
+ Facebook への接続時のエラー
+ </string>
+ <string name="SocialFacebookErrorPosting">
+ Facebook への投稿時のエラー
+ </string>
+ <string name="SocialFacebookErrorDisconnecting">
+ Facebook からの切断時のエラー
+ </string>
<string name="SocialFlickrConnecting">
Flickr に接続中...
</string>
@@ -2577,9 +2595,21 @@ support@secondlife.com にお問い合わせください。
<string name="NoPicksClassifiedsText">
ピックやクラシファイド広告を作成していません。 作成するには、下にある「プラス」ボタンをクリックします。
</string>
+ <string name="NoPicksText">
+ ピックを作成していません。[新規] ボタンをクリックしてピックを作成する。
+ </string>
+ <string name="NoClassifiedsText">
+ クラシファイド広告を作成していません。[新規] ボタンをクリックしてクラシファイド広告を作成する。
+ </string>
<string name="NoAvatarPicksClassifiedsText">
ピック、またはクラシファイド広告がありません
</string>
+ <string name="NoAvatarPicksText">
+ ピックがありません
+ </string>
+ <string name="NoAvatarClassifiedsText">
+ クラシファイド広告がありません
+ </string>
<string name="PicksClassifiedsLoadingText">
ローディング...
</string>
@@ -4557,6 +4587,9 @@ www.secondlife.com から最新バージョンをダウンロードしてくだ
<string name="share_alert">
インベントリからここにアイテムをドラッグします
</string>
+ <string name="facebook_post_success">
+ Facebook に投稿しました。
+ </string>
<string name="flickr_post_success">
Flickr に投稿しました。
</string>
diff --git a/indra/newview/skins/default/xui/pl/floater_picks.xml b/indra/newview/skins/default/xui/pl/floater_picks.xml
deleted file mode 100644
index a329e834db..0000000000
--- a/indra/newview/skins/default/xui/pl/floater_picks.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<floater name="floater_picks" title="Miejsca" />
diff --git a/indra/newview/skins/default/xui/pl/panel_me.xml b/indra/newview/skins/default/xui/pl/panel_me.xml
deleted file mode 100644
index 431929420a..0000000000
--- a/indra/newview/skins/default/xui/pl/panel_me.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel label="Mój Profil" name="panel_me">
- <panel label="MIEJSCA" name="panel_picks" />
-</panel>
diff --git a/indra/newview/skins/default/xui/pt/floater_inventory_view_finder.xml b/indra/newview/skins/default/xui/pt/floater_inventory_view_finder.xml
index c50d7dcda0..a43dec4e7b 100644
--- a/indra/newview/skins/default/xui/pt/floater_inventory_view_finder.xml
+++ b/indra/newview/skins/default/xui/pt/floater_inventory_view_finder.xml
@@ -6,7 +6,7 @@
<check_box label="Gestos" name="check_gesture"/>
<check_box label="Landmarks" name="check_landmark"/>
<check_box label="Anotações" name="check_notecard"/>
- <check_box label="Meshes:" name="check_mesh"/>
+ <check_box label="Malhas" name="check_mesh"/>
<check_box label="Objetos" name="check_object"/>
<check_box label="Scripts" name="check_script"/>
<check_box label="Sons" name="check_sound"/>
diff --git a/indra/newview/skins/default/xui/pt/floater_picks.xml b/indra/newview/skins/default/xui/pt/floater_picks.xml
deleted file mode 100644
index 9766196319..0000000000
--- a/indra/newview/skins/default/xui/pt/floater_picks.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_picks" title="Destaques"/>
diff --git a/indra/newview/skins/default/xui/pt/floater_preview_texture.xml b/indra/newview/skins/default/xui/pt/floater_preview_texture.xml
index 6f39635240..90102023a3 100644
--- a/indra/newview/skins/default/xui/pt/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/pt/floater_preview_texture.xml
@@ -6,42 +6,23 @@
<floater.string name="Copy">
Copiar para inventário
</floater.string>
- <text name="desc txt">
- Descrição:
- </text>
- <text name="dimensions">
- [WIDTH]px x [HEIGHT]px
- </text>
- <text name="aspect_ratio">
- Visualizar relação de aspecto
- </text>
- <combo_box name="combo_aspect_ratio" tool_tip="Visualizar com proporção de aspecto fixa">
- <combo_item name="Unconstrained">
- Sem limites
- </combo_item>
- <combo_item name="1:1" tool_tip="Símbolo ou perfil RW do grupo">
- 1:1
- </combo_item>
- <combo_item name="4:3" tool_tip="[SECOND_LIFE] perfil">
- 4:3
- </combo_item>
- <combo_item name="10:7" tool_tip="Procurar anúncios classificados e marcos">
- 10:7
- </combo_item>
- <combo_item name="3:2" tool_tip="Sobre terrenos">
- 3:2
- </combo_item>
- <combo_item name="16:10">
- 16:10
- </combo_item>
- <combo_item name="16:9" tool_tip="Perfis destacados">
- 16:9
- </combo_item>
- <combo_item name="2:1">
- 2:1
- </combo_item>
- </combo_box>
- <button label="OK" name="Keep"/>
- <button label="Descartar" name="Discard"/>
- <button label="Salvar como" name="save_tex_btn"/>
+ <layout_stack name="preview_stack">
+ <layout_panel name="texture_panel">
+ <text name="desc txt">
+ Descrição:
+ </text>
+ <text name="dimensions">
+ [WIDTH]px x [HEIGHT]px
+ </text>
+ <text name="aspect_ratio">
+ Visualizar relação de aspecto
+ </text>
+ <combo_box name="combo_aspect_ratio" tool_tip="Visualizar com proporção de aspecto fixa"/>
+ </layout_panel>
+ <layout_panel name="buttons_panel">
+ <button label="OK" name="Keep"/>
+ <button label="Descartar" name="Discard"/>
+ <button label="Salvar como" name="save_tex_btn"/>
+ </layout_panel>
+ </layout_stack>
</floater>
diff --git a/indra/newview/skins/default/xui/pt/floater_profile.xml b/indra/newview/skins/default/xui/pt/floater_profile.xml
new file mode 100644
index 0000000000..0327211d8f
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/floater_profile.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="avatarinfo" title="Perfil">
+ <panel name="panel_profile_view">
+ <tab_container name="panel_profile_tabs">
+ <panel label="Second Life" name="panel_profile_secondlife"/>
+ <panel label="Web" name="panel_profile_web"/>
+ <panel label="Interesses" name="panel_profile_interests"/>
+ <panel label="Destaques" name="panel_profile_picks"/>
+ <panel label="Anúncio" name="panel_profile_classifieds"/>
+ <panel label="Vida real" name="panel_profile_firstlife"/>
+ <panel label="Observações" name="panel_profile_notes"/>
+ </tab_container>
+ <button label="OK" name="ok_btn" tool_tip="Salvar alterações do perfil e fechar"/>
+ <button label="Cancelar" label_selected="Cancelar" name="cancel_btn"/>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/pt/floater_snapshot.xml b/indra/newview/skins/default/xui/pt/floater_snapshot.xml
index e3812ed708..89901b539f 100644
--- a/indra/newview/skins/default/xui/pt/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/pt/floater_snapshot.xml
@@ -6,6 +6,9 @@
<string name="postcard_progress_str">
Enviando e-mail
</string>
+ <string name="facebook_progress_str">
+ Como publicar no Facebook
+ </string>
<string name="profile_progress_str">
Postando
</string>
@@ -15,6 +18,9 @@
<string name="local_progress_str">
Salvo no computador
</string>
+ <string name="facebook_succeeded_str">
+ Imagem carregada
+ </string>
<string name="profile_succeeded_str">
Imagem carregada
</string>
@@ -27,6 +33,9 @@
<string name="local_succeeded_str">
Salvo no computador!
</string>
+ <string name="facebook_failed_str">
+ Falha ao carregar a imagem na sua linha do tempo no Facebook.
+ </string>
<string name="profile_failed_str">
Falha ao carregar a imagem no feed do seu perfil.
</string>
diff --git a/indra/newview/skins/default/xui/pt/menu_name_field.xml b/indra/newview/skins/default/xui/pt/menu_name_field.xml
new file mode 100644
index 0000000000..2157de9813
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/menu_name_field.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="CopyMenu">
+ <menu_item_call label="Exibir Cópia do Nome" name="copy_display"/>
+ <menu_item_call label="Copiar Nome do Agente" name="copy_name"/>
+ <menu_item_call label="Copiar Id do Agente" name="copy_id"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/pt/notifications.xml b/indra/newview/skins/default/xui/pt/notifications.xml
index bd1185bdd2..733ec2c709 100644
--- a/indra/newview/skins/default/xui/pt/notifications.xml
+++ b/indra/newview/skins/default/xui/pt/notifications.xml
@@ -2673,6 +2673,9 @@ Selecione só um objeto.
<notification name="SystemMessage">
[MESSAGE]
</notification>
+ <notification name="FacebookConnect">
+ [MESSAGE]
+ </notification>
<notification name="FlickrConnect">
[MESSAGE]
</notification>
diff --git a/indra/newview/skins/default/xui/pt/panel_edit_classified.xml b/indra/newview/skins/default/xui/pt/panel_edit_classified.xml
index 23e00bfc3a..7b27c811f5 100644
--- a/indra/newview/skins/default/xui/pt/panel_edit_classified.xml
+++ b/indra/newview/skins/default/xui/pt/panel_edit_classified.xml
@@ -46,7 +46,7 @@
<layout_panel name="save_changes_btn_lp">
<button label="[LABEL]" name="save_changes_btn"/>
</layout_panel>
- <layout_panel name="show_on_map_btn_lp">
+ <layout_panel name="cancel_btn_lp">
<button label="Cancelar" name="cancel_btn"/>
</layout_panel>
</layout_stack>
diff --git a/indra/newview/skins/default/xui/pt/panel_group_general.xml b/indra/newview/skins/default/xui/pt/panel_group_general.xml
index 64a7d13fdb..f6c6d11b87 100644
--- a/indra/newview/skins/default/xui/pt/panel_group_general.xml
+++ b/indra/newview/skins/default/xui/pt/panel_group_general.xml
@@ -46,7 +46,7 @@ Para obter mais ajuda, passe o mouse sobre as opções.
<check_box label="Qualquer um pode entrar" name="open_enrollement" tool_tip="Controla a entrada de novos membros, com ou sem convite."/>
<check_box label="Taxa de inscrição" name="check_enrollment_fee" tool_tip="Controla a cobrança de uma taxa de associação ao grupo."/>
<spinner label="L$" left_delta="120" name="spin_enrollment_fee" tool_tip="Se a opção &apos;Taxa de associação&apos; estiver marcada, novos membros precisam pagar o valor definido para entrar no grupo." width="60"/>
- <combo_box name="group_mature_check" tool_tip="Os níveis de maturidade determinam o tipo de conteúdo e comportamento permitidos em um grupo" width="170">
+ <combo_box name="group_mature_check" tool_tip="Definir se o seu grupo contém informações classificadas como Moderado" width="170">
<combo_item name="select_mature">
- Selecione o nível de maturidade -
</combo_item>
diff --git a/indra/newview/skins/default/xui/pt/panel_group_list_item_short.xml b/indra/newview/skins/default/xui/pt/panel_group_list_item_short.xml
new file mode 100644
index 0000000000..0490878507
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_group_list_item_short.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="group_list_item">
+ <text name="group_name" value="Desconhecido"/>
+ <button name="info_btn" tool_tip="Mais informações"/>
+ <button name="profile_btn" tool_tip="Ver perfil"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_me.xml b/indra/newview/skins/default/xui/pt/panel_me.xml
deleted file mode 100644
index 281c886bd4..0000000000
--- a/indra/newview/skins/default/xui/pt/panel_me.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="Meu perfil" name="panel_me">
- <panel label="MEUS DESTAQUES" name="panel_picks"/>
-</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_people.xml b/indra/newview/skins/default/xui/pt/panel_people.xml
index 2ef01841c5..ce50449b03 100644
--- a/indra/newview/skins/default/xui/pt/panel_people.xml
+++ b/indra/newview/skins/default/xui/pt/panel_people.xml
@@ -40,6 +40,7 @@ Em busca de alguém para conversar? Procure no [secondlife:///app/worldmap Mapa-
<accordion name="friends_accordion">
<accordion_tab name="tab_online" title="Online"/>
<accordion_tab name="tab_all" title="Todos"/>
+ <accordion_tab name="tab_suggested_friends" title="Pessoas que talvez você deseje adicionar"/>
</accordion>
</panel>
<panel label="GRUPOS" name="groups_panel">
diff --git a/indra/newview/skins/default/xui/pt/panel_profile_classified.xml b/indra/newview/skins/default/xui/pt/panel_profile_classified.xml
new file mode 100644
index 0000000000..b43a0ad9f2
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_profile_classified.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_profile_classified">
+ <panel.string name="type_mature">
+ Moderado
+ </panel.string>
+ <panel.string name="type_pg">
+ Conteúdo Geral
+ </panel.string>
+ <panel.string name="l$_price">
+ L$[PRICE]-
+ </panel.string>
+ <panel.string name="click_through_text_fmt">
+ [TELEPORT] teletransporte, [MAP] mapa, [PROFILE] perfil
+ </panel.string>
+ <panel.string name="date_fmt">
+ [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt]
+ </panel.string>
+ <panel.string name="auto_renew_on">
+ Ativado
+ </panel.string>
+ <panel.string name="auto_renew_off">
+ Desativado
+ </panel.string>
+ <panel.string name="location_notice">
+ (salvar para atualizar)
+ </panel.string>
+ <string name="publish_label">
+ Publicar
+ </string>
+ <string name="save_label">
+ Salvar
+ </string>
+ <scroll_container name="profile_scroll">
+ <panel name="info_scroll_content_panel">
+ <icon label="" name="edit_icon" tool_tip="Selecione uma imagem"/>
+ <layout_stack name="info_panel">
+ <layout_panel name="main_info_panel">
+ <text_editor name="classified_name">
+ [name]
+ </text_editor>
+ <text name="classified_location_label" value="Localização:"/>
+ <text_editor name="classified_location" value="[loading...]"/>
+ <text name="content_type_label" value="Tipo de conteúdo:"/>
+ <text_editor name="content_type" value="[content type]"/>
+ <text name="category_label" value="Categoria:"/>
+ <text_editor name="category" value="[category]"/>
+ <text name="creation_date_label" value="Data de criação:"/>
+ <text_editor name="creation_date" tool_tip="Data de criação" value="[date]"/>
+ <text name="price_for_listing_label" value="Preço do anúncio:"/>
+ <text_editor name="price_for_listing" tool_tip="Preço do anúncio.">
+ [PRICE]
+ </text_editor>
+ </layout_panel>
+ <layout_panel name="clickthrough_layout_panel">
+ <text name="click_through_label" value="Cliques:"/>
+ <text_editor name="click_through_text" tool_tip="Dados de click-through" value="[clicks]"/>
+ </layout_panel>
+ <layout_panel name="auto_renew_layout_panel">
+ <text name="auto_renew_label" value="Renovação automática:"/>
+ <text name="auto_renew" value="Ativado"/>
+ </layout_panel>
+ <layout_panel name="descr_layout_panel">
+ <text name="classified_desc_label" value="Descrição:"/>
+ <text_editor name="classified_desc" value="[description]"/>
+ </layout_panel>
+ </layout_stack>
+ <panel name="edit_panel">
+ <text name="Name:">
+ Título:
+ </text>
+ <text name="description_label">
+ Descrição:
+ </text>
+ <text name="location_label">
+ Localização:
+ </text>
+ <text name="classified_location_edit">
+ Carregando...
+ </text>
+ <button label="Usar configuração local" name="set_to_curr_location_btn"/>
+ <text name="category_label" value="Categoria:"/>
+ <text name="content_type_label" value="Tipo de conteúdo:"/>
+ <icons_combo_box label="Conteúdo Geral" name="content_type_edit">
+ <icons_combo_box.item label="Conteúdo Moderado" name="mature_ci" value="Moderado"/>
+ <icons_combo_box.item label="Conteúdo Geral" name="pg_ci" value="Adequado para menores"/>
+ </icons_combo_box>
+ <check_box label="Renovar automaticamente todas as semanas" name="auto_renew_edit"/>
+ <text name="price_for_listing_edit_label" value="Preço do anúncio:"/>
+ <spinner label="L$" name="price_for_listing_edit" tool_tip="Preço do anúncio." value="50"/>
+ </panel>
+ </panel>
+ </scroll_container>
+ <layout_stack name="edit_btns_pnl">
+ <layout_panel name="teleport_btn_lp">
+ <button label="Teletransportar" name="teleport_btn"/>
+ </layout_panel>
+ <layout_panel name="map_btn_lp">
+ <button label="Mapa" name="show_on_map_btn"/>
+ </layout_panel>
+ <layout_panel name="edit_btn_lp">
+ <button label="Editar" name="edit_btn"/>
+ </layout_panel>
+ <layout_panel name="save_btn_lp">
+ <button label="[LABEL]" name="save_changes_btn"/>
+ </layout_panel>
+ <layout_panel name="cancel_btn_lp">
+ <button label="Cancelar" name="cancel_btn"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_profile_classifieds.xml b/indra/newview/skins/default/xui/pt/panel_profile_classifieds.xml
new file mode 100644
index 0000000000..f8369954fd
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_profile_classifieds.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Anúncio" name="panel_profile_classifieds">
+ <string name="no_classifieds" value="Nenhum classificado"/>
+ <button label="Novo..." name="new_btn"/>
+ <button label="Excluir..." name="delete_btn"/>
+ <text name="classifieds_panel_text">
+ Carregando...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/floater_picks.xml b/indra/newview/skins/default/xui/pt/panel_profile_firstlife.xml
index dfc539da66..0fb502e441 100644
--- a/indra/newview/skins/default/xui/it/floater_picks.xml
+++ b/indra/newview/skins/default/xui/pt/panel_profile_firstlife.xml
@@ -1,2 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_picks" title="Preferiti"/>
+<panel label="Perfil" name="panel_profile_firstlife"/>
diff --git a/indra/newview/skins/default/xui/pt/panel_profile_interests.xml b/indra/newview/skins/default/xui/pt/panel_profile_interests.xml
new file mode 100644
index 0000000000..edf74115f2
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_profile_interests.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Interesses" name="panel_profile_interests">
+ <text name="I Want To:">
+ Quero:
+ </text>
+ <check_box label="Crie" name="chk0"/>
+ <check_box label="Explore" name="chk1"/>
+ <check_box label="Encontrar" name="chk2"/>
+ <check_box label="Seja contratado" name="chk6"/>
+ <check_box label="Grupo" name="chk3"/>
+ <check_box label="Comprar" name="chk4"/>
+ <check_box label="Venda" name="chk5"/>
+ <check_box label="Contratar" name="chk7"/>
+ <line_editor name="want_to_edit">
+ (carregando...)
+ </line_editor>
+ <text name="Skills:">
+ Habilidades:
+ </text>
+ <check_box label="Texturas" name="schk0"/>
+ <check_box label="Arquitetura" name="schk1"/>
+ <check_box label="Modelo" name="schk3"/>
+ <check_box label="Planejamento de evento" name="schk2"/>
+ <check_box label="Scripts" name="schk4"/>
+ <check_box label="Personagens personalizados" name="schk5"/>
+ <line_editor name="skills_edit">
+ (carregando...)
+ </line_editor>
+ <text name="Languages:">
+ Idiomas:
+ </text>
+ <line_editor name="languages_edit">
+ (carregando...)
+ </line_editor>
+</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_profile_notes.xml b/indra/newview/skins/default/xui/pt/panel_profile_notes.xml
new file mode 100644
index 0000000000..499e371bb7
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_profile_notes.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Anotações e Privacidade" name="panel_notes">
+ <text name="status_message" value="Notas particulares neste avatar:"/>
+ <text name="status_message2" value="Permitir que esse avatar:"/>
+ <check_box label="Ver quando eu estiver conectado" name="status_check"/>
+ <check_box label="Encontre-me no mapa-múndi" name="map_check"/>
+ <check_box label="Pegar, editar ou excluir objetos meus" name="objects_check"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_profile_pick.xml b/indra/newview/skins/default/xui/pt/panel_profile_pick.xml
new file mode 100644
index 0000000000..2dd37b38f9
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_profile_pick.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_pick_info">
+ <panel.string name="location_notice">
+ (salvar para atualizar)
+ </panel.string>
+ <line_editor name="pick_location">
+ Carregando...
+ </line_editor>
+ <button label="Teletransportar" name="teleport_btn"/>
+ <button label="Mostrar no mapa" name="show_on_map_btn"/>
+ <button label="Definir Localização" name="set_to_curr_location_btn" tool_tip="Usar configuração local"/>
+ <button label="Salvar destaque" name="save_changes_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_profile_picks.xml b/indra/newview/skins/default/xui/pt/panel_profile_picks.xml
new file mode 100644
index 0000000000..f9ead974dc
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_profile_picks.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Destaques" name="panel_picks">
+ <string name="no_picks" value="Nenhum"/>
+ <text name="Tell everyone about your favorite places in Second Life.">
+ Conte a todos sobre os seu lugares favoritos no Second Life.
+ </text>
+ <button label="Novo..." name="new_btn"/>
+ <button label="Excluir..." name="delete_btn"/>
+ <text name="picks_panel_text">
+ Carregando...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/pt/panel_profile_secondlife.xml
new file mode 100644
index 0000000000..8723b1bf58
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_profile_secondlife.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Perfil" name="panel_profile">
+ <string name="status_online">
+ Atualmente Online
+ </string>
+ <string name="status_offline">
+ Atualmente Offline
+ </string>
+ <string name="CaptionTextAcctInfo">
+ [ACCTTYPE]
+[PAYMENTINFO]
+ </string>
+ <string name="payment_update_link_url">
+ http://www.secondlife.com/account/billing.php?lang=en
+ </string>
+ <string name="partner_edit_link_url">
+ http://www.secondlife.com/account/partners.php?lang=en
+ </string>
+ <string name="my_account_link_url" value="http://secondlife.com/account"/>
+ <string name="no_partner_text" value="Nenhum"/>
+ <string name="no_group_text" value="Nenhum"/>
+ <string name="RegisterDateFormat">
+ [REG_DATE]
+ </string>
+ <string name="name_text_args">
+ [NAME]
+ </string>
+ <string name="display_name_text_args">
+ [DISPLAY_NAME]
+ </string>
+ <string name="FSDev" value="Desenvolvedor"/>
+ <string name="FSSupp" value="Suporte"/>
+ <string name="FSQualityAssurance" value="Caçador de Bug"/>
+ <string name="FSGW" value="Gateway"/>
+ <text name="name_label" value="Nome:"/>
+ <button label="Nome:" name="set_name" tool_tip="Definir nome de tela"/>
+ <panel name="name_holder">
+ <text_editor name="complete_name" value="(carregando...)"/>
+ </panel>
+ <layout_stack name="imagepositioner">
+ <layout_panel name="label_stack">
+ <text name="status" value="Status desconhecido"/>
+ <text name="label" value="Aniversário Second Life:"/>
+ <text name="label2" value="Conta:"/>
+ <text name="partner_label" value="Parceiro(a):"/>
+ </layout_panel>
+ </layout_stack>
+ <text name="Groups:" value="Grupos:"/>
+ <button label="+" label_selected="+" name="group_invite" tool_tip="Convidar para entrar no grupo"/>
+ <layout_stack name="aboutpositioner">
+ <layout_panel name="about_stack">
+ <text name="About:" value="Sobre:"/>
+ </layout_panel>
+ <layout_panel name="give_stack">
+ <text name="Give item:" value="Dar o item:"/>
+ <text name="Give inventory" tool_tip="Arraste e solte o item novo do inventário aqui para dá-los a esta pessoa.">
+ Arraste e solte o item novo do inventário aqui.
+ </text>
+ </layout_panel>
+ </layout_stack>
+ <layout_stack name="buttonstack">
+ <layout_panel name="left_buttonstack">
+ <button label="Localizar no mapa" label_selected="Localizar no mapa" name="show_on_map_btn" tool_tip="Localizar o Residente no mapa"/>
+ <button label="Pagar" label_selected="Pagar" name="pay" tool_tip="Pague em dinheiro para o Residente"/>
+ </layout_panel>
+ <layout_panel name="middle_buttonstack">
+ <button label="Teletransportar?" label_selected="Teletransportar?" name="teleport" tool_tip="Oferecer teletransporte ao Residente"/>
+ <button label="Mensagem instantânea" label_selected="Mensagem instantânea" name="im" tool_tip="Abrir sessão de mensagem instantânea"/>
+ </layout_panel>
+ <layout_panel name="right_buttonstack">
+ <button label="Adicionar amigo" label_selected="Adicionar amigo" name="add_friend" tool_tip="Oferecer amizade ao residente"/>
+ <button label="Bloquear" name="block" tool_tip="Bloquear este Residente"/>
+ <button label="Desbloquear" name="unblock" tool_tip="Desbloquear este Residente"/>
+ </layout_panel>
+ </layout_stack>
+ <check_box label="Mostrar nos resultados de busca" name="show_in_search_checkbox"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_profile_web.xml b/indra/newview/skins/default/xui/pt/panel_profile_web.xml
new file mode 100644
index 0000000000..0f556c7dad
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_profile_web.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Web" name="panel_profile_web">
+ <panel.string name="LoadTime" value="Carregar tempo: [TIME] segundos"/>
+ <line_editor name="url_edit">
+ (carregando..)
+ </line_editor>
+ <flyout_button label="Carregar" name="load" tool_tip="Carregar esta página de perfil com navegador embutido">
+ <flyout_button.item label="Abrir no visualizador do navegador" name="open_item"/>
+ <flyout_button.item label="Abrir no navegador externo" name="home_item"/>
+ </flyout_button>
+ <button name="web_profile_popout_btn" tool_tip="Abra o perfil da web"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/pt/strings.xml b/indra/newview/skins/default/xui/pt/strings.xml
index 7c593ab3be..7a425a2622 100644
--- a/indra/newview/skins/default/xui/pt/strings.xml
+++ b/indra/newview/skins/default/xui/pt/strings.xml
@@ -313,6 +313,24 @@ Aguarde um minuto antes que tentar logar-se novamente.
<string name="TestingDisconnect">
Teste de desconexão
</string>
+ <string name="SocialFacebookConnecting">
+ Conectando ao Facebook...
+ </string>
+ <string name="SocialFacebookPosting">
+ Publicando...
+ </string>
+ <string name="SocialFacebookDisconnecting">
+ Desconectando do Facebook...
+ </string>
+ <string name="SocialFacebookErrorConnecting">
+ Problema ao conectar ao Facebook
+ </string>
+ <string name="SocialFacebookErrorPosting">
+ Problema ao publicar no Facebook
+ </string>
+ <string name="SocialFacebookErrorDisconnecting">
+ Problema ao desconectar do Facebook
+ </string>
<string name="SocialFlickrConnecting">
Conectando ao Flickr...
</string>
@@ -2517,9 +2535,21 @@ Se você continuar a receber essa mensagem, entre em contato com o suporte do Se
<string name="NoPicksClassifiedsText">
Você não criou nenhum Destaque ou Anúncio. Clique no botão &quot;+&quot; para criar um Destaque ou Anúncio.
</string>
+ <string name="NoPicksText">
+ Você não criou nenhuma Escolha. Clique em Novo Botão para criar um Escolher
+ </string>
+ <string name="NoClassifiedsText">
+ Você criou nenhum Anúncio. Clique em Novo Botão para criar um Classificado
+ </string>
<string name="NoAvatarPicksClassifiedsText">
O usuário não tem nenhum destaque ou anúncio
</string>
+ <string name="NoAvatarPicksText">
+ Usuário não tem escolha
+ </string>
+ <string name="NoAvatarClassifiedsText">
+ Usuário não tem anúncio
+ </string>
<string name="PicksClassifiedsLoadingText">
Carregando...
</string>
@@ -4433,6 +4463,9 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
<string name="inventory_folder_offered-im">
Pasta do inventário &apos;[ITEM_NAME]&apos; oferecida
</string>
+ <string name="facebook_post_success">
+ Você publicou no Facebook.
+ </string>
<string name="flickr_post_success">
Você publicou no Flickr.
</string>
diff --git a/indra/newview/skins/default/xui/ru/floater_inventory_view_finder.xml b/indra/newview/skins/default/xui/ru/floater_inventory_view_finder.xml
index 7c1d3b52c5..bf90d898f9 100644
--- a/indra/newview/skins/default/xui/ru/floater_inventory_view_finder.xml
+++ b/indra/newview/skins/default/xui/ru/floater_inventory_view_finder.xml
@@ -6,7 +6,7 @@
<check_box label="Жесты" name="check_gesture"/>
<check_box label="Закладки" name="check_landmark"/>
<check_box label="Заметки" name="check_notecard"/>
- <check_box label="Меши" name="check_mesh"/>
+ <check_box label="Полисетки" name="check_mesh"/>
<check_box label="Объекты" name="check_object"/>
<check_box label="Скрипты" name="check_script"/>
<check_box label="Звуки" name="check_sound"/>
diff --git a/indra/newview/skins/default/xui/ru/floater_picks.xml b/indra/newview/skins/default/xui/ru/floater_picks.xml
deleted file mode 100644
index e0ae8d6f03..0000000000
--- a/indra/newview/skins/default/xui/ru/floater_picks.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_picks" title="Подборка"/>
diff --git a/indra/newview/skins/default/xui/ru/floater_preview_texture.xml b/indra/newview/skins/default/xui/ru/floater_preview_texture.xml
index 46d2a37503..e3921a75ac 100644
--- a/indra/newview/skins/default/xui/ru/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/ru/floater_preview_texture.xml
@@ -6,42 +6,23 @@
<floater.string name="Copy">
Копировать в инвентарь
</floater.string>
- <text name="desc txt">
- Описание:
- </text>
- <text name="dimensions">
- [WIDTH]пикселей x [HEIGHT]пикселей
- </text>
- <text name="aspect_ratio">
- Просмотр изображения с соотношением сторон
- </text>
- <combo_box name="combo_aspect_ratio" tool_tip="Просмотр изображения с фиксированным соотношением сторон">
- <combo_item name="Unconstrained">
- Без ограничения
- </combo_item>
- <combo_item name="1:1" tool_tip="Символ группы или профиль в реальном мире">
- 1:1
- </combo_item>
- <combo_item name="4:3" tool_tip="Профиль для [SECOND_LIFE]">
- 4:3
- </combo_item>
- <combo_item name="10:7" tool_tip="Реклама, поиск и закладки">
- 10:7
- </combo_item>
- <combo_item name="3:2" tool_tip="О земле">
- 3:2
- </combo_item>
- <combo_item name="16:10">
- 16:10
- </combo_item>
- <combo_item name="16:9" tool_tip="Профиль подборки">
- 16:9
- </combo_item>
- <combo_item name="2:1">
- 2:1
- </combo_item>
- </combo_box>
- <button label="OK" name="Keep"/>
- <button label="Отменить" name="Discard"/>
- <button label="Сохранить как" name="save_tex_btn"/>
+ <layout_stack name="preview_stack">
+ <layout_panel name="texture_panel">
+ <text name="desc txt">
+ Описание:
+ </text>
+ <text name="dimensions">
+ [WIDTH]пикселей x [HEIGHT]пикселей
+ </text>
+ <text name="aspect_ratio">
+ Предварительный просмотр соотношения сторон
+ </text>
+ <combo_box name="combo_aspect_ratio" tool_tip="Просмотр изображения с фиксированным соотношением сторон"/>
+ </layout_panel>
+ <layout_panel name="buttons_panel">
+ <button label="OK" name="Keep"/>
+ <button label="Сбросить" name="Discard"/>
+ <button label="Сохранить как" name="save_tex_btn"/>
+ </layout_panel>
+ </layout_stack>
</floater>
diff --git a/indra/newview/skins/default/xui/ru/floater_profile.xml b/indra/newview/skins/default/xui/ru/floater_profile.xml
new file mode 100644
index 0000000000..6f8daf0a62
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/floater_profile.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="avatarinfo" title="Профиль">
+ <panel name="panel_profile_view">
+ <tab_container name="panel_profile_tabs">
+ <panel label="Second Life" name="panel_profile_secondlife"/>
+ <panel label="Веб" name="panel_profile_web"/>
+ <panel label="Круг интересов" name="panel_profile_interests"/>
+ <panel label="Подборка" name="panel_profile_picks"/>
+ <panel label="Объявление" name="panel_profile_classifieds"/>
+ <panel label="Реальная жизнь" name="panel_profile_firstlife"/>
+ <panel label="Примечания" name="panel_profile_notes"/>
+ </tab_container>
+ <button label="OK" name="ok_btn" tool_tip="Сохранить изменения в профиле и закрыть"/>
+ <button label="Отменить" label_selected="Отменить" name="cancel_btn"/>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/ru/floater_report_abuse.xml b/indra/newview/skins/default/xui/ru/floater_report_abuse.xml
index 3ac8cb74b4..89a453d9cd 100644
--- a/indra/newview/skins/default/xui/ru/floater_report_abuse.xml
+++ b/indra/newview/skins/default/xui/ru/floater_report_abuse.xml
@@ -67,7 +67,7 @@
<combo_box.item label="Земля &gt; Посягательство &gt; Объекты или текстуры" name="Land__Encroachment__Objects_textures"/>
<combo_box.item label="Земля &gt; Посягательство &gt; Частицы" name="Land__Encroachment__Particles"/>
<combo_box.item label="Земля &gt; Посягательство &gt; Деревья/растения" name="Land__Encroachment__Trees_plants"/>
- <combo_box.item label="Нарушение правил игр на ловкость" name="Wagering_gambling"/>
+ <combo_box.item label="Нарушение игровых правил" name="Wagering_gambling"/>
<combo_box.item label="Другое" name="Other"/>
</combo_box>
<text name="abuser_name_title">
diff --git a/indra/newview/skins/default/xui/ru/floater_snapshot.xml b/indra/newview/skins/default/xui/ru/floater_snapshot.xml
index 97de279b8f..a796d942f3 100644
--- a/indra/newview/skins/default/xui/ru/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/ru/floater_snapshot.xml
@@ -6,6 +6,9 @@
<string name="postcard_progress_str">
Отправка письма
</string>
+ <string name="facebook_progress_str">
+ Публикация в Facebook
+ </string>
<string name="profile_progress_str">
Публикация
</string>
@@ -15,6 +18,9 @@
<string name="local_progress_str">
Сохранение на компьютере
</string>
+ <string name="facebook_succeeded_str">
+ Изображение загружено
+ </string>
<string name="profile_succeeded_str">
Изображение отправлено
</string>
@@ -27,6 +33,9 @@
<string name="local_succeeded_str">
Сохранено на компьютере!
</string>
+ <string name="facebook_failed_str">
+ Не удалось передать изображение на вашу хронику Facebook.
+ </string>
<string name="profile_failed_str">
Не удалось передать изображение в ваш профиль.
</string>
diff --git a/indra/newview/skins/default/xui/ru/menu_name_field.xml b/indra/newview/skins/default/xui/ru/menu_name_field.xml
new file mode 100644
index 0000000000..889f3c37ab
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/menu_name_field.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="CopyMenu">
+ <menu_item_call label="Копировать отображаемое имя" name="copy_display"/>
+ <menu_item_call label="Копировать имя агента" name="copy_name"/>
+ <menu_item_call label="Копировать Id агента" name="copy_id"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/ru/notifications.xml b/indra/newview/skins/default/xui/ru/notifications.xml
index bfcda798be..e75fd1fd82 100644
--- a/indra/newview/skins/default/xui/ru/notifications.xml
+++ b/indra/newview/skins/default/xui/ru/notifications.xml
@@ -2682,6 +2682,9 @@
<notification name="SystemMessage">
[MESSAGE]
</notification>
+ <notification name="FacebookConnect">
+ [MESSAGE]
+ </notification>
<notification name="FlickrConnect">
[MESSAGE]
</notification>
diff --git a/indra/newview/skins/default/xui/ru/panel_edit_classified.xml b/indra/newview/skins/default/xui/ru/panel_edit_classified.xml
index a2f06dbadf..ec457c4565 100644
--- a/indra/newview/skins/default/xui/ru/panel_edit_classified.xml
+++ b/indra/newview/skins/default/xui/ru/panel_edit_classified.xml
@@ -46,8 +46,8 @@
<layout_panel name="save_changes_btn_lp">
<button label="[LABEL]" name="save_changes_btn"/>
</layout_panel>
- <layout_panel name="show_on_map_btn_lp">
- <button label="Отмена" name="cancel_btn"/>
+ <layout_panel name="cancel_btn_lp">
+ <button label="Отменить" name="cancel_btn"/>
</layout_panel>
</layout_stack>
</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_facebook_friends.xml b/indra/newview/skins/default/xui/ru/panel_facebook_friends.xml
index 746da8d523..1e4d1346f7 100644
--- a/indra/newview/skins/default/xui/ru/panel_facebook_friends.xml
+++ b/indra/newview/skins/default/xui/ru/panel_facebook_friends.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<panel name="panel_facebook_friends">
- <string name="facebook_friends_empty" value="Сейчас у вас нет друзей по Facebook, которые также были бы жителями Second Life. Предложите своим друзьям по Facebook присоединиться к Second Life!"/>
+ <string name="facebook_friends_empty" value="Сейчас у вас нет друзей в Facebook, которые являются также жителями Second Life. Предложите своим друзьям в Facebook присоединиться к Second Life!"/>
<string name="facebook_friends_no_connected" value="Сейчас вы не подключены к Facebook. Перейдите на вкладку «Статус», чтобы подключиться и включить эту функцию."/>
<accordion name="friends_accordion">
<accordion_tab name="tab_second_life_friends" title="Друзья по SL"/>
diff --git a/indra/newview/skins/default/xui/ru/panel_facebook_photo.xml b/indra/newview/skins/default/xui/ru/panel_facebook_photo.xml
index 143a57fec7..50296778ff 100644
--- a/indra/newview/skins/default/xui/ru/panel_facebook_photo.xml
+++ b/indra/newview/skins/default/xui/ru/panel_facebook_photo.xml
@@ -2,19 +2,19 @@
<panel name="panel_facebook_photo">
<combo_box name="resolution_combobox" tool_tip="Разрешение изображения">
<combo_box.item label="Текущее окно" name="CurrentWindow"/>
- <combo_box.item label="640x480" name="640x480"/>
- <combo_box.item label="800x600" name="800x600"/>
- <combo_box.item label="1024x768" name="1024x768"/>
- <combo_box.item label="1200x630" name="1200x630"/>
+ <combo_box.item label="640 x 480" name="640x480"/>
+ <combo_box.item label="800 x 600" name="800x600"/>
+ <combo_box.item label="1024 x 768" name="1024x768"/>
+ <combo_box.item label="1200 x 630" name="1200x630"/>
</combo_box>
<combo_box name="filters_combobox" tool_tip="Фильтры изображений">
<combo_box.item label="Без фильтра" name="NoFilter"/>
</combo_box>
- <button label="Обновить" name="new_snapshot_btn" tool_tip="Щелкните для обновления"/>
- <button label="Просмотр" name="big_preview_btn" tool_tip="Щелкните для смены вида"/>
+ <button label="Обновить" name="new_snapshot_btn" tool_tip="Щелкнуть для обновления"/>
+ <button label="Предпросмотр" name="big_preview_btn" tool_tip="Щелкнуть для смены вида"/>
<text name="caption_label">
Комментарий (не обязательно):
</text>
<button label="Опубликовать" name="post_photo_btn"/>
- <button label="Отмена" name="cancel_photo_btn"/>
+ <button label="Отменить" name="cancel_photo_btn"/>
</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_facebook_place.xml b/indra/newview/skins/default/xui/ru/panel_facebook_place.xml
index 7d0917a43a..a7fadca059 100644
--- a/indra/newview/skins/default/xui/ru/panel_facebook_place.xml
+++ b/indra/newview/skins/default/xui/ru/panel_facebook_place.xml
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<panel name="panel_facebook_place">
<text name="place_caption_label">
- Напишите о том, где вы:
+ Сообщите, где вы находитесь:
</text>
<check_box initial_value="false" label="Включить вид места сверху" name="add_place_view_cb"/>
<button label="Опубликовать" name="post_place_btn"/>
- <button label="Отмена" name="cancel_place_btn"/>
+ <button label="Отменить" name="cancel_place_btn"/>
</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_facebook_status.xml b/indra/newview/skins/default/xui/ru/panel_facebook_status.xml
index c651a8087c..826ac6a08c 100644
--- a/indra/newview/skins/default/xui/ru/panel_facebook_status.xml
+++ b/indra/newview/skins/default/xui/ru/panel_facebook_status.xml
@@ -1,20 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<panel name="panel_facebook_status">
<string name="facebook_connected" value="Вы подключились к Facebook как:"/>
- <string name="facebook_disconnected" value="Не подключено к Facebook"/>
+ <string name="facebook_disconnected" value="Нет подключения к Facebook"/>
<text name="account_caption_label">
- Не подключено к Facebook.
+ Нет подключения к Facebook.
</text>
<panel name="panel_buttons">
- <button label="Подключение..." name="connect_btn"/>
- <button label="Отключить" name="disconnect_btn"/>
+ <button label="Соединение..." name="connect_btn"/>
+ <button label="Разъединить" name="disconnect_btn"/>
<text name="account_learn_more_label">
- [http://community.secondlife.com/t5/English-Knowledge-Base/Second-Life-Share-Facebook/ta-p/2149711 О публикации в Facebook]
+ [http://community.secondlife.com/t5/English-Knowledge-Base/Second-Life-Share-Facebook/ta-p/2149711 Узнать о публикации в Facebook]
</text>
</panel>
<text name="status_caption_label">
О чем вы думаете?
</text>
<button label="Опубликовать" name="post_status_btn"/>
- <button label="Отмена" name="cancel_status_btn"/>
+ <button label="Отменить" name="cancel_status_btn"/>
</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_group_list_item_short.xml b/indra/newview/skins/default/xui/ru/panel_group_list_item_short.xml
new file mode 100644
index 0000000000..3408969d09
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_group_list_item_short.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="group_list_item">
+ <text name="group_name" value="Неизвестно"/>
+ <button name="info_btn" tool_tip="Больше информации"/>
+ <button name="profile_btn" tool_tip="Посмотреть профиль"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_me.xml b/indra/newview/skins/default/xui/ru/panel_me.xml
deleted file mode 100644
index 21a125af87..0000000000
--- a/indra/newview/skins/default/xui/ru/panel_me.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="Мой профиль" name="panel_me">
- <panel label="МОЯ ПОДБОРКА" name="panel_picks"/>
-</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_people.xml b/indra/newview/skins/default/xui/ru/panel_people.xml
index 0812eb7433..8170c8d26f 100644
--- a/indra/newview/skins/default/xui/ru/panel_people.xml
+++ b/indra/newview/skins/default/xui/ru/panel_people.xml
@@ -40,6 +40,7 @@
<accordion name="friends_accordion">
<accordion_tab name="tab_online" title="Онлайн"/>
<accordion_tab name="tab_all" title="Все"/>
+ <accordion_tab name="tab_suggested_friends" title="С кем вы можете подружиться"/>
</accordion>
</panel>
<panel label="ГРУППЫ" name="groups_panel">
diff --git a/indra/newview/skins/default/xui/ru/panel_profile_classified.xml b/indra/newview/skins/default/xui/ru/panel_profile_classified.xml
new file mode 100644
index 0000000000..2d3ed685c0
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_profile_classified.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_profile_classified">
+ <panel.string name="type_mature">
+ Умеренная
+ </panel.string>
+ <panel.string name="type_pg">
+ Общий контент
+ </panel.string>
+ <panel.string name="l$_price">
+ L$[PRICE]
+ </panel.string>
+ <panel.string name="click_through_text_fmt">
+ Телепорт [TELEPORT], карта [MAP], профиль [PROFILE]
+ </panel.string>
+ <panel.string name="date_fmt">
+ [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt]
+ </panel.string>
+ <panel.string name="auto_renew_on">
+ Включен
+ </panel.string>
+ <panel.string name="auto_renew_off">
+ Отключен
+ </panel.string>
+ <panel.string name="location_notice">
+ (будет обновлено после сохранения)
+ </panel.string>
+ <string name="publish_label">
+ Опубликовать
+ </string>
+ <string name="save_label">
+ Сохранить
+ </string>
+ <scroll_container name="profile_scroll">
+ <panel name="info_scroll_content_panel">
+ <icon label="" name="edit_icon" tool_tip="Щелкнуть для выбора изображения"/>
+ <layout_stack name="info_panel">
+ <layout_panel name="main_info_panel">
+ <text_editor name="classified_name">
+ [name]
+ </text_editor>
+ <text name="classified_location_label" value="Местоположение:"/>
+ <text_editor name="classified_location" value="[loading...]"/>
+ <text name="content_type_label" value="Тип контента:"/>
+ <text_editor name="content_type" value="[content type]"/>
+ <text name="category_label" value="Категория:"/>
+ <text_editor name="category" value="[category]"/>
+ <text name="creation_date_label" value="Дата создания:"/>
+ <text_editor name="creation_date" tool_tip="Дата создания" value="[date]"/>
+ <text name="price_for_listing_label" value="Стоимость размещения:"/>
+ <text_editor name="price_for_listing" tool_tip="Цена за размещение.">
+ [PRICE]
+ </text_editor>
+ </layout_panel>
+ <layout_panel name="clickthrough_layout_panel">
+ <text name="click_through_label" value="Клики:"/>
+ <text_editor name="click_through_text" tool_tip="Информация о переходах" value="[clicks]"/>
+ </layout_panel>
+ <layout_panel name="auto_renew_layout_panel">
+ <text name="auto_renew_label" value="Автоматическое продление:"/>
+ <text name="auto_renew" value="Включен"/>
+ </layout_panel>
+ <layout_panel name="descr_layout_panel">
+ <text name="classified_desc_label" value="Описание:"/>
+ <text_editor name="classified_desc" value="[description]"/>
+ </layout_panel>
+ </layout_stack>
+ <panel name="edit_panel">
+ <text name="Name:">
+ Название:
+ </text>
+ <text name="description_label">
+ Описание:
+ </text>
+ <text name="location_label">
+ Местоположение:
+ </text>
+ <text name="classified_location_edit">
+ загрузка...
+ </text>
+ <button label="Установить в текущее местоположение" name="set_to_curr_location_btn"/>
+ <text name="category_label" value="Категория:"/>
+ <text name="content_type_label" value="Тип контента:"/>
+ <icons_combo_box label="Общий контент" name="content_type_edit">
+ <icons_combo_box.item label="Умеренный контент" name="mature_ci" value="Возрастной"/>
+ <icons_combo_box.item label="Общий контент" name="pg_ci" value="C разрешения родителей"/>
+ </icons_combo_box>
+ <check_box label="Автоматическое обновление каждую неделю" name="auto_renew_edit"/>
+ <text name="price_for_listing_edit_label" value="Стоимость размещения:"/>
+ <spinner label="L$" name="price_for_listing_edit" tool_tip="Цена за размещение." value="50"/>
+ </panel>
+ </panel>
+ </scroll_container>
+ <layout_stack name="edit_btns_pnl">
+ <layout_panel name="teleport_btn_lp">
+ <button label="Телепорт" name="teleport_btn"/>
+ </layout_panel>
+ <layout_panel name="map_btn_lp">
+ <button label="Карта" name="show_on_map_btn"/>
+ </layout_panel>
+ <layout_panel name="edit_btn_lp">
+ <button label="Редактировать" name="edit_btn"/>
+ </layout_panel>
+ <layout_panel name="save_btn_lp">
+ <button label="[LABEL]" name="save_changes_btn"/>
+ </layout_panel>
+ <layout_panel name="cancel_btn_lp">
+ <button label="Отменить" name="cancel_btn"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_profile_classifieds.xml b/indra/newview/skins/default/xui/ru/panel_profile_classifieds.xml
new file mode 100644
index 0000000000..fac494682a
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_profile_classifieds.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Объявление" name="panel_profile_classifieds">
+ <string name="no_classifieds" value="Нет рекламы"/>
+ <button label="Новый..." name="new_btn"/>
+ <button label="Удалить..." name="delete_btn"/>
+ <text name="classifieds_panel_text">
+ Загрузка...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_profile_firstlife.xml b/indra/newview/skins/default/xui/ru/panel_profile_firstlife.xml
new file mode 100644
index 0000000000..f5ac5e906a
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_profile_firstlife.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Профиль" name="panel_profile_firstlife"/>
diff --git a/indra/newview/skins/default/xui/ru/panel_profile_interests.xml b/indra/newview/skins/default/xui/ru/panel_profile_interests.xml
new file mode 100644
index 0000000000..ba1c3d0357
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_profile_interests.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Круг интересов" name="panel_profile_interests">
+ <text name="I Want To:">
+ Я собираюсь:
+ </text>
+ <check_box label="Построить" name="chk0"/>
+ <check_box label="Просмотреть" name="chk1"/>
+ <check_box label="Встретить" name="chk2"/>
+ <check_box label="Получить работу" name="chk6"/>
+ <check_box label="Группа" name="chk3"/>
+ <check_box label="Купить" name="chk4"/>
+ <check_box label="Продать" name="chk5"/>
+ <check_box label="Нанять" name="chk7"/>
+ <line_editor name="want_to_edit">
+ (загрузка…)
+ </line_editor>
+ <text name="Skills:">
+ Навыки:
+ </text>
+ <check_box label="Текстуры" name="schk0"/>
+ <check_box label="Архитектура" name="schk1"/>
+ <check_box label="Моделирование" name="schk3"/>
+ <check_box label="Планирование мероприятия" name="schk2"/>
+ <check_box label="Создавать сценарии" name="schk4"/>
+ <check_box label="Пользовательские символы" name="schk5"/>
+ <line_editor name="skills_edit">
+ (загрузка…)
+ </line_editor>
+ <text name="Languages:">
+ Языки:
+ </text>
+ <line_editor name="languages_edit">
+ (загрузка…)
+ </line_editor>
+</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_profile_notes.xml b/indra/newview/skins/default/xui/ru/panel_profile_notes.xml
new file mode 100644
index 0000000000..41117c743a
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_profile_notes.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Примечания и конфиденциальность" name="panel_notes">
+ <text name="status_message" value="Личные заметки об этом аватаре:"/>
+ <text name="status_message2" value="Разрешить этому аватару:"/>
+ <check_box label="Смотреть, когда я в сети" name="status_check"/>
+ <check_box label="Найти меня на карте мира" name="map_check"/>
+ <check_box label="Редактировать, удалять или брать мои объекты" name="objects_check"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_profile_pick.xml b/indra/newview/skins/default/xui/ru/panel_profile_pick.xml
new file mode 100644
index 0000000000..a2ff5710ea
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_profile_pick.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_pick_info">
+ <panel.string name="location_notice">
+ (будет обновлено после сохранения)
+ </panel.string>
+ <line_editor name="pick_location">
+ Загрузка...
+ </line_editor>
+ <button label="Телепорт" name="teleport_btn"/>
+ <button label="Показать на карте" name="show_on_map_btn"/>
+ <button label="Указать местоположение" name="set_to_curr_location_btn" tool_tip="Установить в текущее местоположение"/>
+ <button label="Сохранить подборку" name="save_changes_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_profile_picks.xml b/indra/newview/skins/default/xui/ru/panel_profile_picks.xml
new file mode 100644
index 0000000000..227b3f82b8
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_profile_picks.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Подборка" name="panel_picks">
+ <string name="no_picks" value="Нет подборки"/>
+ <text name="Tell everyone about your favorite places in Second Life.">
+ Сообщить всем о ваших избранных службах в Second Life.
+ </text>
+ <button label="Новый..." name="new_btn"/>
+ <button label="Удалить..." name="delete_btn"/>
+ <text name="picks_panel_text">
+ Загрузка...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/ru/panel_profile_secondlife.xml
new file mode 100644
index 0000000000..e7a66ba29e
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_profile_secondlife.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Профиль" name="panel_profile">
+ <string name="status_online">
+ В настоящее время в режиме онлайн
+ </string>
+ <string name="status_offline">
+ В настоящее время в режиме оффлайн
+ </string>
+ <string name="CaptionTextAcctInfo">
+ [ACCTTYPE]
+[PAYMENTINFO]
+ </string>
+ <string name="payment_update_link_url">
+ http://www.secondlife.com/account/billing.php?lang=en
+ </string>
+ <string name="partner_edit_link_url">
+ http://www.secondlife.com/account/partners.php?lang=en
+ </string>
+ <string name="my_account_link_url" value="http://secondlife.com/account"/>
+ <string name="no_partner_text" value="Никто"/>
+ <string name="no_group_text" value="Никто"/>
+ <string name="RegisterDateFormat">
+ [REG_DATE]
+ </string>
+ <string name="name_text_args">
+ [NAME]
+ </string>
+ <string name="display_name_text_args">
+ [DISPLAY_NAME]
+ </string>
+ <string name="FSDev" value="Разработчик"/>
+ <string name="FSSupp" value="Поддержка"/>
+ <string name="FSQualityAssurance" value="Отладчик"/>
+ <string name="FSGW" value="Межсетевой интерфейс"/>
+ <text name="name_label" value="Имя:"/>
+ <button label="Имя:" name="set_name" tool_tip="Задать отображаемое имя"/>
+ <panel name="name_holder">
+ <text_editor name="complete_name" value="(загрузка…)"/>
+ </panel>
+ <layout_stack name="imagepositioner">
+ <layout_panel name="label_stack">
+ <text name="status" value="Статус неизвестен"/>
+ <text name="label" value="Дата рождения в Second Life:"/>
+ <text name="label2" value="Аккаунт:"/>
+ <text name="partner_label" value="Партнер:"/>
+ </layout_panel>
+ </layout_stack>
+ <text name="Groups:" value="Группы:"/>
+ <button label="+" label_selected="+" name="group_invite" tool_tip="Пригласить в группу"/>
+ <layout_stack name="aboutpositioner">
+ <layout_panel name="about_stack">
+ <text name="About:" value="О нас:"/>
+ </layout_panel>
+ <layout_panel name="give_stack">
+ <text name="Give item:" value="Передать вещь:"/>
+ <text name="Give inventory" tool_tip="Сбросить вещи из инвентаря здесь для передачи их этому игроку.">
+ Сбросить вещь из инвентаря здесь.
+ </text>
+ </layout_panel>
+ </layout_stack>
+ <layout_stack name="buttonstack">
+ <layout_panel name="left_buttonstack">
+ <button label="Найти на карте" label_selected="Найти на карте" name="show_on_map_btn" tool_tip="Найти жителя на карте"/>
+ <button label="Оплатить" label_selected="Оплатить" name="pay" tool_tip="Выплатить деньги резиденту"/>
+ </layout_panel>
+ <layout_panel name="middle_buttonstack">
+ <button label="Предложить телепорт" label_selected="Предложить телепорт" name="teleport" tool_tip="Предложить телепорт этому жителю"/>
+ <button label="Мгновенное сообщение" label_selected="Мгновенное сообщение" name="im" tool_tip="Начать сеанс IM"/>
+ </layout_panel>
+ <layout_panel name="right_buttonstack">
+ <button label="Добавить друга" label_selected="Добавить друга" name="add_friend" tool_tip="Предложить дружбу этому жителю"/>
+ <button label="Заблокировать" name="block" tool_tip="Заблокировать этого жителя"/>
+ <button label="Разблокировать" name="unblock" tool_tip="Разблокировать этого жителя"/>
+ </layout_panel>
+ </layout_stack>
+ <check_box label="Показать в поиске" name="show_in_search_checkbox"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_profile_web.xml b/indra/newview/skins/default/xui/ru/panel_profile_web.xml
new file mode 100644
index 0000000000..18a17e2586
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_profile_web.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Веб" name="panel_profile_web">
+ <panel.string name="LoadTime" value="Время загрузки: [TIME] секунд"/>
+ <line_editor name="url_edit">
+ (загрузка…)
+ </line_editor>
+ <flyout_button label="Загрузить" name="load" tool_tip="Загрузить эту страницу с профилем с помощью встроенного веб-браузера.">
+ <flyout_button.item label="Открыть в просмотрщике браузера" name="open_item"/>
+ <flyout_button.item label="Открыть во внешнем браузере" name="home_item"/>
+ </flyout_button>
+ <button name="web_profile_popout_btn" tool_tip="Всплывающий веб-профиль"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ru/strings.xml b/indra/newview/skins/default/xui/ru/strings.xml
index 95b1664279..c0dc32340a 100644
--- a/indra/newview/skins/default/xui/ru/strings.xml
+++ b/indra/newview/skins/default/xui/ru/strings.xml
@@ -357,6 +357,24 @@ support@secondlife.com.
<string name="TestingDisconnect">
Тестирование отключения клиента
</string>
+ <string name="SocialFacebookConnecting">
+ Подключение к Facebook...
+ </string>
+ <string name="SocialFacebookPosting">
+ Публикация...
+ </string>
+ <string name="SocialFacebookDisconnecting">
+ Отключение от Facebook...
+ </string>
+ <string name="SocialFacebookErrorConnecting">
+ Проблема с подключением к Facebook
+ </string>
+ <string name="SocialFacebookErrorPosting">
+ Проблемы при публикации в Facebook
+ </string>
+ <string name="SocialFacebookErrorDisconnecting">
+ Проблема с отключением от Facebook
+ </string>
<string name="SocialFlickrConnecting">
Подключение к Flickr...
</string>
@@ -2576,9 +2594,21 @@ support@secondlife.com.
<string name="NoPicksClassifiedsText">
Вы не создали подборки или рекламы. Нажмите кнопку со знаком «плюс» ниже, чтобы создать подборку или рекламу
</string>
+ <string name="NoPicksText">
+ Вы не сделали никакой подборки. Нажмите кнопку Создать, чтобы сделать подборку.
+ </string>
+ <string name="NoClassifiedsText">
+ Вы не сделали никакой рекламы. Нажмите кнопку Создать, чтобы сделать рекламу.
+ </string>
<string name="NoAvatarPicksClassifiedsText">
У жителя нет подборки или рекламы
</string>
+ <string name="NoAvatarPicksText">
+ У пользователя нет подборки
+ </string>
+ <string name="NoAvatarClassifiedsText">
+ У пользователя нет объявлений
+ </string>
<string name="PicksClassifiedsLoadingText">
Загрузка...
</string>
@@ -4553,6 +4583,9 @@ support@secondlife.com.
<string name="share_alert">
Перетаскивайте вещи из инвентаря сюда
</string>
+ <string name="facebook_post_success">
+ Вы опубликовали сообщение в Facebook.
+ </string>
<string name="flickr_post_success">
Вы опубликовали сообщение в Flickr.
</string>
diff --git a/indra/newview/skins/default/xui/tr/floater_facebook.xml b/indra/newview/skins/default/xui/tr/floater_facebook.xml
index 656a4a81c9..d8cbd84ed1 100644
--- a/indra/newview/skins/default/xui/tr/floater_facebook.xml
+++ b/indra/newview/skins/default/xui/tr/floater_facebook.xml
@@ -3,7 +3,7 @@
<tab_container name="tabs">
<panel label="DURUM" name="panel_facebook_status"/>
<panel label="FOTOĞRAF" name="panel_facebook_photo"/>
- <panel label="KONUMA GİRİŞ YAPIN" name="panel_facebook_place"/>
+ <panel label="GİRİŞ YAP" name="panel_facebook_place"/>
<panel label="ARKADAŞLAR" name="panel_facebook_friends"/>
</tab_container>
<text name="connection_error_text">
diff --git a/indra/newview/skins/default/xui/tr/floater_inventory_view_finder.xml b/indra/newview/skins/default/xui/tr/floater_inventory_view_finder.xml
index accb1ed71c..caa8497d3a 100644
--- a/indra/newview/skins/default/xui/tr/floater_inventory_view_finder.xml
+++ b/indra/newview/skins/default/xui/tr/floater_inventory_view_finder.xml
@@ -6,7 +6,7 @@
<check_box label="Mimikler" name="check_gesture"/>
<check_box label="Yer İmleri" name="check_landmark"/>
<check_box label="Not Kartları" name="check_notecard"/>
- <check_box label="Örgüler" name="check_mesh"/>
+ <check_box label="Ağlar" name="check_mesh"/>
<check_box label="Nesneler" name="check_object"/>
<check_box label="Komut Dosyaları" name="check_script"/>
<check_box label="Sesler" name="check_sound"/>
diff --git a/indra/newview/skins/default/xui/tr/floater_picks.xml b/indra/newview/skins/default/xui/tr/floater_picks.xml
deleted file mode 100644
index 5aee6ae091..0000000000
--- a/indra/newview/skins/default/xui/tr/floater_picks.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_picks" title="Seçimler"/>
diff --git a/indra/newview/skins/default/xui/tr/floater_preview_texture.xml b/indra/newview/skins/default/xui/tr/floater_preview_texture.xml
index 8302c62070..8ba9123545 100644
--- a/indra/newview/skins/default/xui/tr/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/tr/floater_preview_texture.xml
@@ -6,42 +6,23 @@
<floater.string name="Copy">
Envantere Kopyala
</floater.string>
- <text name="desc txt">
- Açıklama:
- </text>
- <text name="dimensions">
- [WIDTH] pks x [HEIGHT] pks
- </text>
- <text name="aspect_ratio">
- En boy oranını önizle
- </text>
- <combo_box name="combo_aspect_ratio" tool_tip="Sabit en boy oranında önizle">
- <combo_item name="Unconstrained">
- Kısıtsız
- </combo_item>
- <combo_item name="1:1" tool_tip="Grup işaretleri veya Real World profili">
- 1:1
- </combo_item>
- <combo_item name="4:3" tool_tip="[SECOND_LIFE] profili">
- 4:3
- </combo_item>
- <combo_item name="10:7" tool_tip="İlanlar ve arama listeleri, yer imleri">
- 10:7
- </combo_item>
- <combo_item name="3:2" tool_tip="Arazi hakkında">
- 3:2
- </combo_item>
- <combo_item name="16:10">
- 16:10
- </combo_item>
- <combo_item name="16:9" tool_tip="Profil seçmeleri">
- 16:9
- </combo_item>
- <combo_item name="2:1">
- 2:1
- </combo_item>
- </combo_box>
- <button label="Tamam" name="Keep"/>
- <button label="At" name="Discard"/>
- <button label="Farklı Kaydet" name="save_tex_btn"/>
+ <layout_stack name="preview_stack">
+ <layout_panel name="texture_panel">
+ <text name="desc txt">
+ Açıklama:
+ </text>
+ <text name="dimensions">
+ [WIDTH]pks x [HEIGHT]pks
+ </text>
+ <text name="aspect_ratio">
+ En boy oranını önizle
+ </text>
+ <combo_box name="combo_aspect_ratio" tool_tip="Sabit en boy oranında önizle"/>
+ </layout_panel>
+ <layout_panel name="buttons_panel">
+ <button label="Tamam" name="Keep"/>
+ <button label="At" name="Discard"/>
+ <button label="Farklı Kaydet" name="save_tex_btn"/>
+ </layout_panel>
+ </layout_stack>
</floater>
diff --git a/indra/newview/skins/default/xui/tr/floater_profile.xml b/indra/newview/skins/default/xui/tr/floater_profile.xml
new file mode 100644
index 0000000000..bb158ddf66
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/floater_profile.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="avatarinfo" title="Profil">
+ <panel name="panel_profile_view">
+ <tab_container name="panel_profile_tabs">
+ <panel label="Second Life" name="panel_profile_secondlife"/>
+ <panel label="Web" name="panel_profile_web"/>
+ <panel label="İlgi alanları" name="panel_profile_interests"/>
+ <panel label="Favoriler" name="panel_profile_picks"/>
+ <panel label="İlan" name="panel_profile_classifieds"/>
+ <panel label="Gerçek Hayat" name="panel_profile_firstlife"/>
+ <panel label="Notlar" name="panel_profile_notes"/>
+ </tab_container>
+ <button label="Tamam" name="ok_btn" tool_tip="Değişiklikleri profile kaydet ve kapat"/>
+ <button label="İptal Et" label_selected="İptal Et" name="cancel_btn"/>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/tr/floater_snapshot.xml b/indra/newview/skins/default/xui/tr/floater_snapshot.xml
index be6c58e8cf..8496194700 100644
--- a/indra/newview/skins/default/xui/tr/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/tr/floater_snapshot.xml
@@ -6,6 +6,9 @@
<string name="postcard_progress_str">
E-posta Gönderiliyor
</string>
+ <string name="facebook_progress_str">
+ Facebook&apos;ta yayınlanıyor
+ </string>
<string name="profile_progress_str">
Yayınlanıyor
</string>
@@ -15,6 +18,9 @@
<string name="local_progress_str">
Bilgisayara Kaydediliyor
</string>
+ <string name="facebook_succeeded_str">
+ Görüntü yüklendi
+ </string>
<string name="profile_succeeded_str">
Görüntü yüklendi
</string>
@@ -27,6 +33,9 @@
<string name="local_succeeded_str">
Bilgisayara Kaydedildi!
</string>
+ <string name="facebook_failed_str">
+ Görüntü Facebook zaman tünelinize yüklenemedi.
+ </string>
<string name="profile_failed_str">
Görüntü Profil Akışınıza yüklenemedi.
</string>
diff --git a/indra/newview/skins/default/xui/tr/menu_name_field.xml b/indra/newview/skins/default/xui/tr/menu_name_field.xml
new file mode 100644
index 0000000000..b1afd737c3
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/menu_name_field.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="CopyMenu">
+ <menu_item_call label="Görünen Adı Kopyala" name="copy_display"/>
+ <menu_item_call label="Aracı Adını Kopyala" name="copy_name"/>
+ <menu_item_call label="Aracı Kimliğini Kopyala" name="copy_id"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/tr/notifications.xml b/indra/newview/skins/default/xui/tr/notifications.xml
index 5403a78f22..17d2969d19 100644
--- a/indra/newview/skins/default/xui/tr/notifications.xml
+++ b/indra/newview/skins/default/xui/tr/notifications.xml
@@ -2682,6 +2682,9 @@ Daha küçük bir arazi parçası seçmeyi deneyin.
<notification name="SystemMessage">
[MESSAGE]
</notification>
+ <notification name="FacebookConnect">
+ [MESSAGE]
+ </notification>
<notification name="FlickrConnect">
[MESSAGE]
</notification>
diff --git a/indra/newview/skins/default/xui/tr/panel_edit_classified.xml b/indra/newview/skins/default/xui/tr/panel_edit_classified.xml
index fc444f21f6..78c34a3ac0 100644
--- a/indra/newview/skins/default/xui/tr/panel_edit_classified.xml
+++ b/indra/newview/skins/default/xui/tr/panel_edit_classified.xml
@@ -46,7 +46,7 @@
<layout_panel name="save_changes_btn_lp">
<button label="[LABEL]" name="save_changes_btn"/>
</layout_panel>
- <layout_panel name="show_on_map_btn_lp">
+ <layout_panel name="cancel_btn_lp">
<button label="İptal Et" name="cancel_btn"/>
</layout_panel>
</layout_stack>
diff --git a/indra/newview/skins/default/xui/tr/panel_facebook_friends.xml b/indra/newview/skins/default/xui/tr/panel_facebook_friends.xml
index 8184d6d7cf..edbe87d74c 100644
--- a/indra/newview/skins/default/xui/tr/panel_facebook_friends.xml
+++ b/indra/newview/skins/default/xui/tr/panel_facebook_friends.xml
@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<panel name="panel_facebook_friends">
- <string name="facebook_friends_empty" value="Şu an için aynı zamanda bir Second Life sakini olan hiçbir Facebook arkadaşınız yok. Facebook arkadaşlarınızı bugün Second Life&apos;a katılmaya davet edin!"/>
+ <string name="facebook_friends_empty" value="Şu anda aynı zamanda bir Second Life sakini olan hiçbir Facebook arkadaşınız yok. Facebook arkadaşlarınızdan bugün Second Life&apos;a katılmalarını isteyin!"/>
<string name="facebook_friends_no_connected" value="Şu anda Facebook&apos;a bağlı değilsiniz. Bağlanmak ve bu özelliği etkinleştirmek için lütfen Durum sekmesine gidin."/>
<accordion name="friends_accordion">
<accordion_tab name="tab_second_life_friends" title="SL arkadaşları"/>
<accordion_tab name="tab_suggested_friends" title="Bu kişileri SL arkadaşları olarak ekle"/>
</accordion>
<text name="facebook_friends_status">
- Facebook&apos;a bağlanılmadı.
+ Facebook&apos;a bağlanılamadı.
</text>
</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_facebook_photo.xml b/indra/newview/skins/default/xui/tr/panel_facebook_photo.xml
index d772aff937..e3150f258d 100644
--- a/indra/newview/skins/default/xui/tr/panel_facebook_photo.xml
+++ b/indra/newview/skins/default/xui/tr/panel_facebook_photo.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<panel name="panel_facebook_photo">
<combo_box name="resolution_combobox" tool_tip="Görüntü çözünürlüğü">
- <combo_box.item label="Mevcut Pencere" name="CurrentWindow"/>
+ <combo_box.item label="Geçerli Pencere" name="CurrentWindow"/>
<combo_box.item label="640x480" name="640x480"/>
<combo_box.item label="800x600" name="800x600"/>
<combo_box.item label="1024x768" name="1024x768"/>
@@ -11,10 +11,10 @@
<combo_box.item label="Filtre Yok" name="NoFilter"/>
</combo_box>
<button label="Yenile" name="new_snapshot_btn" tool_tip="Yenilemek için tıklayın"/>
- <button label="Önizleme" name="big_preview_btn" tool_tip="Önizleme ayarları arasında geçiş yapmak için tıklayın"/>
+ <button label="Önizleme" name="big_preview_btn" tool_tip="Önizlemeye geçmek için tıklayın"/>
<text name="caption_label">
Yorum (isteğe bağlı):
</text>
<button label="Yayınla" name="post_photo_btn"/>
- <button label="İptal" name="cancel_photo_btn"/>
+ <button label="İptal Et" name="cancel_photo_btn"/>
</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_facebook_place.xml b/indra/newview/skins/default/xui/tr/panel_facebook_place.xml
index 85b401a1a0..96c34d03d0 100644
--- a/indra/newview/skins/default/xui/tr/panel_facebook_place.xml
+++ b/indra/newview/skins/default/xui/tr/panel_facebook_place.xml
@@ -5,5 +5,5 @@
</text>
<check_box initial_value="false" label="Konumun üstten görünümünü ekle" name="add_place_view_cb"/>
<button label="Yayınla" name="post_place_btn"/>
- <button label="İptal" name="cancel_place_btn"/>
+ <button label="İptal Et" name="cancel_place_btn"/>
</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_facebook_status.xml b/indra/newview/skins/default/xui/tr/panel_facebook_status.xml
index e6feff5949..f5dba088de 100644
--- a/indra/newview/skins/default/xui/tr/panel_facebook_status.xml
+++ b/indra/newview/skins/default/xui/tr/panel_facebook_status.xml
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<panel name="panel_facebook_status">
<string name="facebook_connected" value="Facebook&apos;a şu kimlikle bağlandınız:"/>
- <string name="facebook_disconnected" value="Facebook&apos;a bağlanılmadı"/>
+ <string name="facebook_disconnected" value="Facebook&apos;a bağlanılamadı"/>
<text name="account_caption_label">
- Facebook&apos;a bağlanılmadı.
+ Facebook&apos;a bağlanılamadı.
</text>
<panel name="panel_buttons">
<button label="Bağlan..." name="connect_btn"/>
@@ -13,8 +13,8 @@
</text>
</panel>
<text name="status_caption_label">
- Ne düşünüyorsunuz?
+ Aklınızdan ne geçiyor?
</text>
<button label="Yayınla" name="post_status_btn"/>
- <button label="İptal" name="cancel_status_btn"/>
+ <button label="İptal Et" name="cancel_status_btn"/>
</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_group_general.xml b/indra/newview/skins/default/xui/tr/panel_group_general.xml
index c666778c69..5578b36f3f 100644
--- a/indra/newview/skins/default/xui/tr/panel_group_general.xml
+++ b/indra/newview/skins/default/xui/tr/panel_group_general.xml
@@ -45,7 +45,7 @@ Daha fazla yardım edinmek için farenizi seçeneklerin üzerine getirin.
<check_box label="Herkes katılabilir" name="open_enrollement" tool_tip="Bu grubun davet edilmeden yeni üyelerin katılmasına imkan tanıyıp tanımayacağını belirler."/>
<check_box label="Katılma ücreti" name="check_enrollment_fee" tool_tip="Bu gruba katılmak için bir kayıt ücretinin gerekip gerekmeyeceğini belirler"/>
<spinner label="L$" name="spin_enrollment_fee" tool_tip="Kayıt Ücreti işaretlendiğinde yeni üyeler gruba katılmak için bu ücreti ödemelidir."/>
- <combo_box name="group_mature_check" tool_tip="Erişkinlik dereceleri bir grupta izin verilen içerik ve davranış türlerini belirler">
+ <combo_box name="group_mature_check" tool_tip="Grubunuzun Orta olarak sınıflandırılmış bilgiler içerip içermeyeceğini belirler">
<combo_item name="select_mature">
- Erişkinlik seviyesini seçin -
</combo_item>
diff --git a/indra/newview/skins/default/xui/tr/panel_group_list_item_short.xml b/indra/newview/skins/default/xui/tr/panel_group_list_item_short.xml
new file mode 100644
index 0000000000..0ed905ed35
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_group_list_item_short.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="group_list_item">
+ <text name="group_name" value="Bilinmiyor"/>
+ <button name="info_btn" tool_tip="Ek bilgi"/>
+ <button name="profile_btn" tool_tip="Profili görüntüle"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_me.xml b/indra/newview/skins/default/xui/tr/panel_me.xml
deleted file mode 100644
index d9e79d171c..0000000000
--- a/indra/newview/skins/default/xui/tr/panel_me.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="Profilim" name="panel_me">
- <panel label="SEÇTİKLERİM" name="panel_picks"/>
-</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_people.xml b/indra/newview/skins/default/xui/tr/panel_people.xml
index 25d29fcbb5..acbcd2a544 100644
--- a/indra/newview/skins/default/xui/tr/panel_people.xml
+++ b/indra/newview/skins/default/xui/tr/panel_people.xml
@@ -40,6 +40,7 @@ Birlikte takılacak kişiler mi arıyorsunuz? [secondlife:///app/worldmap Dünya
<accordion name="friends_accordion">
<accordion_tab name="tab_online" title="Çevrimiçi"/>
<accordion_tab name="tab_all" title="Tümü"/>
+ <accordion_tab name="tab_suggested_friends" title="Arkadaş olmak isteyebileceğiniz kişiler"/>
</accordion>
</panel>
<panel label="GRUPLAR" name="groups_panel">
diff --git a/indra/newview/skins/default/xui/tr/panel_profile_classified.xml b/indra/newview/skins/default/xui/tr/panel_profile_classified.xml
new file mode 100644
index 0000000000..805de24c11
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_profile_classified.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_profile_classified">
+ <panel.string name="type_mature">
+ Orta
+ </panel.string>
+ <panel.string name="type_pg">
+ Genel İçerik
+ </panel.string>
+ <panel.string name="l$_price">
+ L$[PRICE]
+ </panel.string>
+ <panel.string name="click_through_text_fmt">
+ [TELEPORT] ışınlanma, [MAP] harita, [PROFILE] profil
+ </panel.string>
+ <panel.string name="date_fmt">
+ [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt]
+ </panel.string>
+ <panel.string name="auto_renew_on">
+ Etkin
+ </panel.string>
+ <panel.string name="auto_renew_off">
+ Devre dışı
+ </panel.string>
+ <panel.string name="location_notice">
+ (kaydedildikten sonra güncellenir)
+ </panel.string>
+ <string name="publish_label">
+ Yayınla
+ </string>
+ <string name="save_label">
+ Kaydet
+ </string>
+ <scroll_container name="profile_scroll">
+ <panel name="info_scroll_content_panel">
+ <icon label="" name="edit_icon" tool_tip="Bir görüntü seçmek için tıklayın"/>
+ <layout_stack name="info_panel">
+ <layout_panel name="main_info_panel">
+ <text_editor name="classified_name">
+ [name]
+ </text_editor>
+ <text name="classified_location_label" value="Konum:"/>
+ <text_editor name="classified_location" value="[loading...]"/>
+ <text name="content_type_label" value="İçerik Türü:"/>
+ <text_editor name="content_type" value="[content type]"/>
+ <text name="category_label" value="Kategori:"/>
+ <text_editor name="category" value="[category]"/>
+ <text name="creation_date_label" value="Oluşturma tarihi:"/>
+ <text_editor name="creation_date" tool_tip="Oluşturma tarihi" value="[date]"/>
+ <text name="price_for_listing_label" value="İlan fiyatı:"/>
+ <text_editor name="price_for_listing" tool_tip="İlan fiyatı.">
+ [PRICE]
+ </text_editor>
+ </layout_panel>
+ <layout_panel name="clickthrough_layout_panel">
+ <text name="click_through_label" value="Tıklama sayısı:"/>
+ <text_editor name="click_through_text" tool_tip="Tıklama verileri" value="[clicks]"/>
+ </layout_panel>
+ <layout_panel name="auto_renew_layout_panel">
+ <text name="auto_renew_label" value="Otomatik yenileme:"/>
+ <text name="auto_renew" value="Etkin"/>
+ </layout_panel>
+ <layout_panel name="descr_layout_panel">
+ <text name="classified_desc_label" value="Açıklama:"/>
+ <text_editor name="classified_desc" value="[description]"/>
+ </layout_panel>
+ </layout_stack>
+ <panel name="edit_panel">
+ <text name="Name:">
+ Başlık:
+ </text>
+ <text name="description_label">
+ Açıklama:
+ </text>
+ <text name="location_label">
+ Konum:
+ </text>
+ <text name="classified_location_edit">
+ yükleniyor...
+ </text>
+ <button label="Geçerli Konuma Ayarla" name="set_to_curr_location_btn"/>
+ <text name="category_label" value="Kategori:"/>
+ <text name="content_type_label" value="İçerik türü:"/>
+ <icons_combo_box label="Genel İçerik" name="content_type_edit">
+ <icons_combo_box.item label="Orta İçerik" name="mature_ci" value="Yetişkin"/>
+ <icons_combo_box.item label="Genel İçerik" name="pg_ci" value="PG"/>
+ </icons_combo_box>
+ <check_box label="Her hafta otomatik yenile" name="auto_renew_edit"/>
+ <text name="price_for_listing_edit_label" value="İlan fiyatı:"/>
+ <spinner label="L$" name="price_for_listing_edit" tool_tip="İlan fiyatı." value="50"/>
+ </panel>
+ </panel>
+ </scroll_container>
+ <layout_stack name="edit_btns_pnl">
+ <layout_panel name="teleport_btn_lp">
+ <button label="Işınlanma" name="teleport_btn"/>
+ </layout_panel>
+ <layout_panel name="map_btn_lp">
+ <button label="Harita" name="show_on_map_btn"/>
+ </layout_panel>
+ <layout_panel name="edit_btn_lp">
+ <button label="Düzenle" name="edit_btn"/>
+ </layout_panel>
+ <layout_panel name="save_btn_lp">
+ <button label="[LABEL]" name="save_changes_btn"/>
+ </layout_panel>
+ <layout_panel name="cancel_btn_lp">
+ <button label="İptal Et" name="cancel_btn"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_profile_classifieds.xml b/indra/newview/skins/default/xui/tr/panel_profile_classifieds.xml
new file mode 100644
index 0000000000..0edae1ab2a
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_profile_classifieds.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="İlan" name="panel_profile_classifieds">
+ <string name="no_classifieds" value="İlan Yok"/>
+ <button label="Yeni..." name="new_btn"/>
+ <button label="Sil..." name="delete_btn"/>
+ <text name="classifieds_panel_text">
+ Yükleniyor...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_profile_firstlife.xml b/indra/newview/skins/default/xui/tr/panel_profile_firstlife.xml
new file mode 100644
index 0000000000..0f65090209
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_profile_firstlife.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Profil" name="panel_profile_firstlife"/>
diff --git a/indra/newview/skins/default/xui/tr/panel_profile_interests.xml b/indra/newview/skins/default/xui/tr/panel_profile_interests.xml
new file mode 100644
index 0000000000..b068aa3dad
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_profile_interests.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="İlgi alanları" name="panel_profile_interests">
+ <text name="I Want To:">
+ Şunu Yapmak İstiyorum:
+ </text>
+ <check_box label="İnşa Et" name="chk0"/>
+ <check_box label="Keşfet" name="chk1"/>
+ <check_box label="Tanış" name="chk2"/>
+ <check_box label="İşe Gir" name="chk6"/>
+ <check_box label="Gruplandır" name="chk3"/>
+ <check_box label="Satın Al" name="chk4"/>
+ <check_box label="Sat" name="chk5"/>
+ <check_box label="İşe Al" name="chk7"/>
+ <line_editor name="want_to_edit">
+ (yükleniyor...)
+ </line_editor>
+ <text name="Skills:">
+ Beceriler:
+ </text>
+ <check_box label="Dokular" name="schk0"/>
+ <check_box label="Mimari" name="schk1"/>
+ <check_box label="Modelleme" name="schk3"/>
+ <check_box label="Etkinlik Planlama" name="schk2"/>
+ <check_box label="Kodlama" name="schk4"/>
+ <check_box label="Özel Karakterler" name="schk5"/>
+ <line_editor name="skills_edit">
+ (yükleniyor...)
+ </line_editor>
+ <text name="Languages:">
+ Diller:
+ </text>
+ <line_editor name="languages_edit">
+ (yükleniyor...)
+ </line_editor>
+</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_profile_notes.xml b/indra/newview/skins/default/xui/tr/panel_profile_notes.xml
new file mode 100644
index 0000000000..fff75dd685
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_profile_notes.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Notlar ve Gizlilik" name="panel_notes">
+ <text name="status_message" value="Bu avatar ile ilgili özel notlar:"/>
+ <text name="status_message2" value="Bu avatar için şunlara izin ver:"/>
+ <check_box label="Çevrimiçi olduğumu görme" name="status_check"/>
+ <check_box label="Beni dünya haritasında bulma" name="map_check"/>
+ <check_box label="Nesnelerimi düzenleme, silme veya alma" name="objects_check"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_profile_pick.xml b/indra/newview/skins/default/xui/tr/panel_profile_pick.xml
new file mode 100644
index 0000000000..d42c1eff7f
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_profile_pick.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_pick_info">
+ <panel.string name="location_notice">
+ (kaydedildikten sonra güncellenir)
+ </panel.string>
+ <line_editor name="pick_location">
+ Yükleniyor...
+ </line_editor>
+ <button label="Işınlanma" name="teleport_btn"/>
+ <button label="Haritada Göster" name="show_on_map_btn"/>
+ <button label="Konumu Ayarla" name="set_to_curr_location_btn" tool_tip="Geçerli Konuma Ayarla"/>
+ <button label="Favoriyi Kaydet" name="save_changes_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_profile_picks.xml b/indra/newview/skins/default/xui/tr/panel_profile_picks.xml
new file mode 100644
index 0000000000..7222a2fc2e
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_profile_picks.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Favoriler" name="panel_picks">
+ <string name="no_picks" value="Favori Yok"/>
+ <text name="Tell everyone about your favorite places in Second Life.">
+ Second Life&apos;ta favori yerlerinizi herkese anlatın!
+ </text>
+ <button label="Yeni..." name="new_btn"/>
+ <button label="Sil..." name="delete_btn"/>
+ <text name="picks_panel_text">
+ Yükleniyor...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/tr/panel_profile_secondlife.xml
new file mode 100644
index 0000000000..00e81d005e
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_profile_secondlife.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Profil" name="panel_profile">
+ <string name="status_online">
+ Şu Anda Çevrimiçi
+ </string>
+ <string name="status_offline">
+ Şu Anda Çevrimdışı
+ </string>
+ <string name="CaptionTextAcctInfo">
+ [ACCTTYPE]
+[PAYMENTINFO]
+ </string>
+ <string name="payment_update_link_url">
+ http://www.secondlife.com/account/billing.php?lang=en
+ </string>
+ <string name="partner_edit_link_url">
+ http://www.secondlife.com/account/partners.php?lang=en
+ </string>
+ <string name="my_account_link_url" value="http://secondlife.com/account"/>
+ <string name="no_partner_text" value="Yok"/>
+ <string name="no_group_text" value="Yok"/>
+ <string name="RegisterDateFormat">
+ [REG_DATE]
+ </string>
+ <string name="name_text_args">
+ [NAME]
+ </string>
+ <string name="display_name_text_args">
+ [DISPLAY_NAME]
+ </string>
+ <string name="FSDev" value="Geliştirici"/>
+ <string name="FSSupp" value="Destek"/>
+ <string name="FSQualityAssurance" value="Böcek bilimci"/>
+ <string name="FSGW" value="Ağ geçidi"/>
+ <text name="name_label" value="Ad:"/>
+ <button label="Ad:" name="set_name" tool_tip="Görünen Adı Ayarla"/>
+ <panel name="name_holder">
+ <text_editor name="complete_name" value="(yükleniyor...)"/>
+ </panel>
+ <layout_stack name="imagepositioner">
+ <layout_panel name="label_stack">
+ <text name="status" value="Durum Bilinmiyor"/>
+ <text name="label" value="Second Life Doğum Tarihi:"/>
+ <text name="label2" value="Hesap:"/>
+ <text name="partner_label" value="Ortak:"/>
+ </layout_panel>
+ </layout_stack>
+ <text name="Groups:" value="Gruplar:"/>
+ <button label="+" label_selected="+" name="group_invite" tool_tip="Gruba Davet Et"/>
+ <layout_stack name="aboutpositioner">
+ <layout_panel name="about_stack">
+ <text name="About:" value="Hakkında:"/>
+ </layout_panel>
+ <layout_panel name="give_stack">
+ <text name="Give item:" value="Öğe ver:"/>
+ <text name="Give inventory" tool_tip="Envanter öğelerini bu kişiye vermek için buraya bırakın.">
+ Envanter öğesini buraya bırakın.
+ </text>
+ </layout_panel>
+ </layout_stack>
+ <layout_stack name="buttonstack">
+ <layout_panel name="left_buttonstack">
+ <button label="Haritada Bul" label_selected="Haritada Bul" name="show_on_map_btn" tool_tip="Sakini haritada bul"/>
+ <button label="Öde" label_selected="Öde" name="pay" tool_tip="Sakine para öde"/>
+ </layout_panel>
+ <layout_panel name="middle_buttonstack">
+ <button label="Işınlanma Teklif Et" label_selected="Işınlanma Teklif Et" name="teleport" tool_tip="Sakine ışınlanma teklif et"/>
+ <button label="Anlık İleti" label_selected="Anlık İleti" name="im" tool_tip="Anlık ileti oturumu aç"/>
+ </layout_panel>
+ <layout_panel name="right_buttonstack">
+ <button label="Arkadaş Ekle" label_selected="Arkadaş Ekle" name="add_friend" tool_tip="Sakine arkadaşlık teklif et"/>
+ <button label="Engelle" name="block" tool_tip="Bu Sakini engelle"/>
+ <button label="Engellemeyi Kaldır" name="unblock" tool_tip="Bu Sakinin engellemesini kaldır"/>
+ </layout_panel>
+ </layout_stack>
+ <check_box label="Aramada göster" name="show_in_search_checkbox"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_profile_web.xml b/indra/newview/skins/default/xui/tr/panel_profile_web.xml
new file mode 100644
index 0000000000..265b1fee7e
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_profile_web.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Web" name="panel_profile_web">
+ <panel.string name="LoadTime" value="Yükleme Süresi: [TIME] saniye"/>
+ <line_editor name="url_edit">
+ (yükleniyor..)
+ </line_editor>
+ <flyout_button label="Yükle" name="load" tool_tip="Bu profil sayfasını tümleşik web tarayıcı ile yükleyin.">
+ <flyout_button.item label="Görüntüleyici içindeki tarayıcıda aç" name="open_item"/>
+ <flyout_button.item label="Dış tarayıcıda aç" name="home_item"/>
+ </flyout_button>
+ <button name="web_profile_popout_btn" tool_tip="Açılır web profili"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/tr/strings.xml b/indra/newview/skins/default/xui/tr/strings.xml
index 74a6b3cac3..d1076b8b79 100644
--- a/indra/newview/skins/default/xui/tr/strings.xml
+++ b/indra/newview/skins/default/xui/tr/strings.xml
@@ -357,6 +357,24 @@ Lütfen bir dakika içerisinde tekrar oturum açmayı deneyin.
<string name="TestingDisconnect">
Görüntüleyici bağlantısının kesilmesi test ediliyor
</string>
+ <string name="SocialFacebookConnecting">
+ Facebook ile bağlantı kuruluyor...
+ </string>
+ <string name="SocialFacebookPosting">
+ Yayınlanıyor...
+ </string>
+ <string name="SocialFacebookDisconnecting">
+ Facebook bağlantısı kesiliyor...
+ </string>
+ <string name="SocialFacebookErrorConnecting">
+ Facebook ile bağlantı kurulurken sorun oluştu
+ </string>
+ <string name="SocialFacebookErrorPosting">
+ Facebook&apos;ta yayınlarken sorun oluştu
+ </string>
+ <string name="SocialFacebookErrorDisconnecting">
+ Facebook bağlantısı kesilirken sorun oluştu
+ </string>
<string name="SocialFlickrConnecting">
Flickr bağlantısı kuruluyor...
</string>
@@ -2576,9 +2594,21 @@ Bu mesaj size gelmeye devam ederse lütfen http://support.secondlife.com adresin
<string name="NoPicksClassifiedsText">
Herhangi bir Seçme veya İlan oluşturmadınız. Bir Seçme veya İlan oluşturmak için aşağıdaki Artı düğmesine tıklayın.
</string>
+ <string name="NoPicksText">
+ Herhangi bir Favori oluşturmadınız. Bir Favori oluşturmak için Yeni düğmesine tıklayın.
+ </string>
+ <string name="NoClassifiedsText">
+ Herhangi bir İlan oluşturmadınız. Bir İlan oluşturmak için Yeni düğmesine tıklayın.
+ </string>
<string name="NoAvatarPicksClassifiedsText">
Kullanıcının herhangi bir seçmesi veya ilanı yok
</string>
+ <string name="NoAvatarPicksText">
+ Kullanıcının favorisi yok
+ </string>
+ <string name="NoAvatarClassifiedsText">
+ Kullanıcının ilanı yok
+ </string>
<string name="PicksClassifiedsLoadingText">
Yükleniyor...
</string>
@@ -4556,6 +4586,9 @@ Bu iletiyi almaya devam ederseniz, lütfen [SUPPORT_SITE] bölümüne başvurun.
<string name="share_alert">
Envanterinizden buraya öğeler sürükleyin
</string>
+ <string name="facebook_post_success">
+ Facebook&apos;ta yayınladınız.
+ </string>
<string name="flickr_post_success">
Flickr&apos;da yayınladınız.
</string>
diff --git a/indra/newview/skins/default/xui/zh/floater_picks.xml b/indra/newview/skins/default/xui/zh/floater_picks.xml
deleted file mode 100644
index a8bfcd99e3..0000000000
--- a/indra/newview/skins/default/xui/zh/floater_picks.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_picks" title="精選地點"/>
diff --git a/indra/newview/skins/default/xui/zh/floater_preview_texture.xml b/indra/newview/skins/default/xui/zh/floater_preview_texture.xml
index 2b6eac48b3..9213cc212d 100644
--- a/indra/newview/skins/default/xui/zh/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/zh/floater_preview_texture.xml
@@ -6,42 +6,23 @@
<floater.string name="Copy">
覆製到收納區
</floater.string>
- <text name="desc txt">
- 描述:
- </text>
- <text name="dimensions">
- [WIDTH]像素 x [HEIGHT]像素
- </text>
- <text name="aspect_ratio">
- 預覽長寬比
- </text>
- <combo_box name="combo_aspect_ratio" tool_tip="以固定長寬比預覽">
- <combo_item name="Unconstrained">
- 不受限
- </combo_item>
- <combo_item name="1:1" tool_tip="群組徽章或現實世界小檔案">
- 1:1
- </combo_item>
- <combo_item name="4:3" tool_tip="[SECOND_LIFE] 檔案">
- 4:3
- </combo_item>
- <combo_item name="10:7" tool_tip="個人廣告和搜索刊登廣告、地標">
- 10:7
- </combo_item>
- <combo_item name="3:2" tool_tip="土地資料">
- 3:2
- </combo_item>
- <combo_item name="16:10">
- 16:10
- </combo_item>
- <combo_item name="16:9" tool_tip="個人檔案精選">
- 16:9
- </combo_item>
- <combo_item name="2:1">
- 2:1
- </combo_item>
- </combo_box>
- <button label="確定" name="Keep"/>
- <button label="丟棄" name="Discard"/>
- <button label="另存為" name="save_tex_btn"/>
+ <layout_stack name="preview_stack">
+ <layout_panel name="texture_panel">
+ <text name="desc txt">
+ 描述:
+ </text>
+ <text name="dimensions">
+ [WIDTH]像素 x [HEIGHT]像素
+ </text>
+ <text name="aspect_ratio">
+ 預覽長寬比
+ </text>
+ <combo_box name="combo_aspect_ratio" tool_tip="以固定長寬比預覽"/>
+ </layout_panel>
+ <layout_panel name="buttons_panel">
+ <button label="確定" name="Keep"/>
+ <button label="丟棄" name="Discard"/>
+ <button label="另存為" name="save_tex_btn"/>
+ </layout_panel>
+ </layout_stack>
</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_profile.xml b/indra/newview/skins/default/xui/zh/floater_profile.xml
new file mode 100644
index 0000000000..0f73f527a9
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/floater_profile.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="avatarinfo" title="簡覽">
+ <panel name="panel_profile_view">
+ <tab_container name="panel_profile_tabs">
+ <panel label="第二人生" name="panel_profile_secondlife"/>
+ <panel label="網頁" name="panel_profile_web"/>
+ <panel label="興趣" name="panel_profile_interests"/>
+ <panel label="精選地點" name="panel_profile_picks"/>
+ <panel label="分類廣告" name="panel_profile_classifieds"/>
+ <panel label="真實世界" name="panel_profile_firstlife"/>
+ <panel label="筆記" name="panel_profile_notes"/>
+ </tab_container>
+ <button label="確定" name="ok_btn" tool_tip="儲存變更到個人檔案後關閉"/>
+ <button label="取消" label_selected="取消" name="cancel_btn"/>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_snapshot.xml b/indra/newview/skins/default/xui/zh/floater_snapshot.xml
index 4090248083..6e1a156762 100644
--- a/indra/newview/skins/default/xui/zh/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/zh/floater_snapshot.xml
@@ -6,6 +6,9 @@
<string name="postcard_progress_str">
正在發送電郵
</string>
+ <string name="facebook_progress_str">
+ 發佈到臉書
+ </string>
<string name="profile_progress_str">
發佈
</string>
@@ -15,6 +18,9 @@
<string name="local_progress_str">
正在存到電腦
</string>
+ <string name="facebook_succeeded_str">
+ 圖像已上傳
+ </string>
<string name="profile_succeeded_str">
圖像已上傳
</string>
@@ -27,6 +33,9 @@
<string name="local_succeeded_str">
成功存入電腦!
</string>
+ <string name="facebook_failed_str">
+ 上傳圖像到你的臉書時間線時失敗。
+ </string>
<string name="profile_failed_str">
上傳圖像到你的檔案訊息發佈時出錯。
</string>
diff --git a/indra/newview/skins/default/xui/zh/menu_name_field.xml b/indra/newview/skins/default/xui/zh/menu_name_field.xml
new file mode 100644
index 0000000000..5eaf3461cd
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/menu_name_field.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="CopyMenu">
+ <menu_item_call label="複製顯示名稱" name="copy_display"/>
+ <menu_item_call label="複製代理名稱" name="copy_name"/>
+ <menu_item_call label="複製代理ID" name="copy_id"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/zh/notifications.xml b/indra/newview/skins/default/xui/zh/notifications.xml
index cfde824349..4d0f1cb85b 100644
--- a/indra/newview/skins/default/xui/zh/notifications.xml
+++ b/indra/newview/skins/default/xui/zh/notifications.xml
@@ -2666,6 +2666,9 @@ SHA1 指紋:[MD5_DIGEST]
<notification name="SystemMessage">
[MESSAGE]
</notification>
+ <notification name="FacebookConnect">
+ [MESSAGE]
+ </notification>
<notification name="FlickrConnect">
[MESSAGE]
</notification>
diff --git a/indra/newview/skins/default/xui/zh/panel_edit_classified.xml b/indra/newview/skins/default/xui/zh/panel_edit_classified.xml
index b06ece02ad..4d3248db46 100644
--- a/indra/newview/skins/default/xui/zh/panel_edit_classified.xml
+++ b/indra/newview/skins/default/xui/zh/panel_edit_classified.xml
@@ -46,7 +46,7 @@
<layout_panel name="save_changes_btn_lp">
<button label="[LABEL]" name="save_changes_btn"/>
</layout_panel>
- <layout_panel name="show_on_map_btn_lp">
+ <layout_panel name="cancel_btn_lp">
<button label="取消" name="cancel_btn"/>
</layout_panel>
</layout_stack>
diff --git a/indra/newview/skins/default/xui/zh/panel_group_list_item_short.xml b/indra/newview/skins/default/xui/zh/panel_group_list_item_short.xml
new file mode 100644
index 0000000000..fec4bb572a
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_group_list_item_short.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="group_list_item">
+ <text name="group_name" value="未知"/>
+ <button name="info_btn" tool_tip="詳情"/>
+ <button name="profile_btn" tool_tip="察看檔案"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_me.xml b/indra/newview/skins/default/xui/zh/panel_me.xml
deleted file mode 100644
index aad1348e46..0000000000
--- a/indra/newview/skins/default/xui/zh/panel_me.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="我的個人檔案" name="panel_me">
- <panel label="我的精選地點" name="panel_picks"/>
-</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_people.xml b/indra/newview/skins/default/xui/zh/panel_people.xml
index b0e60218cf..b95dd96026 100644
--- a/indra/newview/skins/default/xui/zh/panel_people.xml
+++ b/indra/newview/skins/default/xui/zh/panel_people.xml
@@ -40,6 +40,7 @@
<accordion name="friends_accordion">
<accordion_tab name="tab_online" title="上線"/>
<accordion_tab name="tab_all" title="全部"/>
+ <accordion_tab name="tab_suggested_friends" title="你可能想要加為好友的人"/>
</accordion>
</panel>
<panel label="群組" name="groups_panel">
diff --git a/indra/newview/skins/default/xui/zh/panel_profile_classified.xml b/indra/newview/skins/default/xui/zh/panel_profile_classified.xml
new file mode 100644
index 0000000000..4eee4e8855
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_profile_classified.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_profile_classified">
+ <panel.string name="type_mature">
+ 適度成人
+ </panel.string>
+ <panel.string name="type_pg">
+ 一般普級內容
+ </panel.string>
+ <panel.string name="l$_price">
+ L$[PRICE]
+ </panel.string>
+ <panel.string name="click_through_text_fmt">
+ [TELEPORT] 瞬間傳送,[MAP] 地圖,[PROFILE] 檔案
+ </panel.string>
+ <panel.string name="date_fmt">
+ [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt]
+ </panel.string>
+ <panel.string name="auto_renew_on">
+ 已啟用
+ </panel.string>
+ <panel.string name="auto_renew_off">
+ 已停用
+ </panel.string>
+ <panel.string name="location_notice">
+ (儲存後將會更新)
+ </panel.string>
+ <string name="publish_label">
+ 發布
+ </string>
+ <string name="save_label">
+ 儲存
+ </string>
+ <scroll_container name="profile_scroll">
+ <panel name="info_scroll_content_panel">
+ <icon label="" name="edit_icon" tool_tip="點按以選擇圖像"/>
+ <layout_stack name="info_panel">
+ <layout_panel name="main_info_panel">
+ <text_editor name="classified_name">
+ [name]
+ </text_editor>
+ <text name="classified_location_label" value="位置:"/>
+ <text_editor name="classified_location" value="[loading...]"/>
+ <text name="content_type_label" value="內容類型:"/>
+ <text_editor name="content_type" value="[content type]"/>
+ <text name="category_label" value="分類:"/>
+ <text_editor name="category" value="[category]"/>
+ <text name="creation_date_label" value="建立日期:"/>
+ <text_editor name="creation_date" tool_tip="建立日期" value="[date]"/>
+ <text name="price_for_listing_label" value="刊登費:"/>
+ <text_editor name="price_for_listing" tool_tip="刊登費。">
+ [PRICE]
+ </text_editor>
+ </layout_panel>
+ <layout_panel name="clickthrough_layout_panel">
+ <text name="click_through_label" value="點按狀況:"/>
+ <text_editor name="click_through_text" tool_tip="點按資料" value="[clicks]"/>
+ </layout_panel>
+ <layout_panel name="auto_renew_layout_panel">
+ <text name="auto_renew_label" value="自動續訂:"/>
+ <text name="auto_renew" value="已啟用"/>
+ </layout_panel>
+ <layout_panel name="descr_layout_panel">
+ <text name="classified_desc_label" value="描述:"/>
+ <text_editor name="classified_desc" value="[description]"/>
+ </layout_panel>
+ </layout_stack>
+ <panel name="edit_panel">
+ <text name="Name:">
+ 標題:
+ </text>
+ <text name="description_label">
+ 描述:
+ </text>
+ <text name="location_label">
+ 位置:
+ </text>
+ <text name="classified_location_edit">
+ 載入中...
+ </text>
+ <button label="設定為目前位置" name="set_to_curr_location_btn"/>
+ <text name="category_label" value="分類:"/>
+ <text name="content_type_label" value="內容類型:"/>
+ <icons_combo_box label="一般普級內容" name="content_type_edit">
+ <icons_combo_box.item label="適度成人內容" name="mature_ci" value="適度成人"/>
+ <icons_combo_box.item label="一般普級內容" name="pg_ci" value="一般普級"/>
+ </icons_combo_box>
+ <check_box label="每星期自動續訂" name="auto_renew_edit"/>
+ <text name="price_for_listing_edit_label" value="刊登費:"/>
+ <spinner label="L$" name="price_for_listing_edit" tool_tip="刊登費。" value="50"/>
+ </panel>
+ </panel>
+ </scroll_container>
+ <layout_stack name="edit_btns_pnl">
+ <layout_panel name="teleport_btn_lp">
+ <button label="瞬間傳送" name="teleport_btn"/>
+ </layout_panel>
+ <layout_panel name="map_btn_lp">
+ <button label="地圖" name="show_on_map_btn"/>
+ </layout_panel>
+ <layout_panel name="edit_btn_lp">
+ <button label="編輯" name="edit_btn"/>
+ </layout_panel>
+ <layout_panel name="save_btn_lp">
+ <button label="[LABEL]" name="save_changes_btn"/>
+ </layout_panel>
+ <layout_panel name="cancel_btn_lp">
+ <button label="取消" name="cancel_btn"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_profile_classifieds.xml b/indra/newview/skins/default/xui/zh/panel_profile_classifieds.xml
new file mode 100644
index 0000000000..89b5cdf641
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_profile_classifieds.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="分類廣告" name="panel_profile_classifieds">
+ <string name="no_classifieds" value="禁止個人廣告"/>
+ <button label="新增…" name="new_btn"/>
+ <button label="刪除…" name="delete_btn"/>
+ <text name="classifieds_panel_text">
+ 載入中…
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_profile_firstlife.xml b/indra/newview/skins/default/xui/zh/panel_profile_firstlife.xml
new file mode 100644
index 0000000000..9370661d7f
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_profile_firstlife.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="簡覽" name="panel_profile_firstlife"/>
diff --git a/indra/newview/skins/default/xui/zh/panel_profile_interests.xml b/indra/newview/skins/default/xui/zh/panel_profile_interests.xml
new file mode 100644
index 0000000000..150f3cca4f
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_profile_interests.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="興趣" name="panel_profile_interests">
+ <text name="I Want To:">
+ 我想要:
+ </text>
+ <check_box label="建造" name="chk0"/>
+ <check_box label="探索" name="chk1"/>
+ <check_box label="見面" name="chk2"/>
+ <check_box label="受雇" name="chk6"/>
+ <check_box label="群組" name="chk3"/>
+ <check_box label="購買" name="chk4"/>
+ <check_box label="出售" name="chk5"/>
+ <check_box label="招人" name="chk7"/>
+ <line_editor name="want_to_edit">
+ (載入中...)
+ </line_editor>
+ <text name="Skills:">
+ 技能:
+ </text>
+ <check_box label="材質" name="schk0"/>
+ <check_box label="架構" name="schk1"/>
+ <check_box label="建模" name="schk3"/>
+ <check_box label="計畫活動" name="schk2"/>
+ <check_box label="建腳本" name="schk4"/>
+ <check_box label="定製角色" name="schk5"/>
+ <line_editor name="skills_edit">
+ (載入中...)
+ </line_editor>
+ <text name="Languages:">
+ 語言:
+ </text>
+ <line_editor name="languages_edit">
+ (載入中...)
+ </line_editor>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_profile_notes.xml b/indra/newview/skins/default/xui/zh/panel_profile_notes.xml
new file mode 100644
index 0000000000..17e1a997da
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_profile_notes.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="筆記和隱私" name="panel_notes">
+ <text name="status_message" value="關於這化身的私人筆記:"/>
+ <text name="status_message2" value="允許這個化身:"/>
+ <check_box label="看見我何時上線" name="status_check"/>
+ <check_box label="在世界地圖上找到我" name="map_check"/>
+ <check_box label="邊輯,刪除或取下我的物件" name="objects_check"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_profile_pick.xml b/indra/newview/skins/default/xui/zh/panel_profile_pick.xml
new file mode 100644
index 0000000000..5f8d6a2ba5
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_profile_pick.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_pick_info">
+ <panel.string name="location_notice">
+ (儲存後將會更新)
+ </panel.string>
+ <line_editor name="pick_location">
+ 載入中…
+ </line_editor>
+ <button label="瞬間傳送" name="teleport_btn"/>
+ <button label="顯示在地圖上" name="show_on_map_btn"/>
+ <button label="設定位置" name="set_to_curr_location_btn" tool_tip="設定為目前位置"/>
+ <button label="儲存精選地點" name="save_changes_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_profile_picks.xml b/indra/newview/skins/default/xui/zh/panel_profile_picks.xml
new file mode 100644
index 0000000000..8f189d1308
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_profile_picks.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="精選地點" name="panel_picks">
+ <string name="no_picks" value="無精選地點"/>
+ <text name="Tell everyone about your favorite places in Second Life.">
+ 告訴大家你在Second Life中最愛的去處。
+ </text>
+ <button label="新增…" name="new_btn"/>
+ <button label="刪除…" name="delete_btn"/>
+ <text name="picks_panel_text">
+ 載入中…
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/zh/panel_profile_secondlife.xml
new file mode 100644
index 0000000000..da4aafce55
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_profile_secondlife.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="簡覽" name="panel_profile">
+ <string name="status_online">
+ 目前在線
+ </string>
+ <string name="status_offline">
+ 目前離線
+ </string>
+ <string name="CaptionTextAcctInfo">
+ [ACCTTYPE]
+[PAYMENTINFO]
+ </string>
+ <string name="payment_update_link_url">
+ http://www.secondlife.com/account/billing.php?lang=en
+ </string>
+ <string name="partner_edit_link_url">
+ http://www.secondlife.com/account/partners.php?lang=en
+ </string>
+ <string name="my_account_link_url" value="http://secondlife.com/account"/>
+ <string name="no_partner_text" value="無"/>
+ <string name="no_group_text" value="無"/>
+ <string name="RegisterDateFormat">
+ [REG_DATE]
+ </string>
+ <string name="name_text_args">
+ [NAME]
+ </string>
+ <string name="display_name_text_args">
+ [DISPLAY_NAME]
+ </string>
+ <string name="FSDev" value="開發者"/>
+ <string name="FSSupp" value="支援"/>
+ <string name="FSQualityAssurance" value="除錯獵人"/>
+ <string name="FSGW" value="網關"/>
+ <text name="name_label" value="名稱:"/>
+ <button label="名稱:" name="set_name" tool_tip="設定顯示名稱"/>
+ <panel name="name_holder">
+ <text_editor name="complete_name" value="(載入中...)"/>
+ </panel>
+ <layout_stack name="imagepositioner">
+ <layout_panel name="label_stack">
+ <text name="status" value="狀態不明"/>
+ <text name="label" value="Second Life生日:"/>
+ <text name="label2" value="帳戶:"/>
+ <text name="partner_label" value="伴侶:"/>
+ </layout_panel>
+ </layout_stack>
+ <text name="Groups:" value="群組:"/>
+ <button label="+" label_selected="+" name="group_invite" tool_tip="邀請加入群組"/>
+ <layout_stack name="aboutpositioner">
+ <layout_panel name="about_stack">
+ <text name="About:" value="關於:"/>
+ </layout_panel>
+ <layout_panel name="give_stack">
+ <text name="Give item:" value="贈與物品:"/>
+ <text name="Give inventory" tool_tip="把收納區物品放到這裡,送給此人。">
+ 把收納區物品放到這裡。
+ </text>
+ </layout_panel>
+ </layout_stack>
+ <layout_stack name="buttonstack">
+ <layout_panel name="left_buttonstack">
+ <button label="在地圖上查找" label_selected="在地圖上查找" name="show_on_map_btn" tool_tip="在地圖上找出這個居民"/>
+ <button label="支付" label_selected="支付" name="pay" tool_tip="付款給這個居民"/>
+ </layout_panel>
+ <layout_panel name="middle_buttonstack">
+ <button label="發出瞬間傳送邀請" label_selected="發出瞬間傳送邀請" name="teleport" tool_tip="向這個居民發出瞬間傳送邀請"/>
+ <button label="即時訊息" label_selected="即時訊息" name="im" tool_tip="開啟即時訊息會話"/>
+ </layout_panel>
+ <layout_panel name="right_buttonstack">
+ <button label="加為朋友" label_selected="加為朋友" name="add_friend" tool_tip="向這個居民發出交友邀請"/>
+ <button label="封鎖" name="block" tool_tip="封鎖這位居民"/>
+ <button label="解除封鎖" name="unblock" tool_tip="不再封鎖這位居民"/>
+ </layout_panel>
+ </layout_stack>
+ <check_box label="在搜尋結果中顯示" name="show_in_search_checkbox"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_profile_web.xml b/indra/newview/skins/default/xui/zh/panel_profile_web.xml
new file mode 100644
index 0000000000..566651dceb
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_profile_web.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="網頁" name="panel_profile_web">
+ <panel.string name="LoadTime" value="載入時間:[TIME]秒"/>
+ <line_editor name="url_edit">
+ (載入中…)
+ </line_editor>
+ <flyout_button label="載入" name="load" tool_tip="用內嵌瀏覽器載入此個人檔案頁面。">
+ <flyout_button.item label="開啓内部瀏覽器" name="open_item"/>
+ <flyout_button.item label="開啓外部瀏覽器" name="home_item"/>
+ </flyout_button>
+ <button name="web_profile_popout_btn" tool_tip="彈出式個人檔案網頁"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/strings.xml b/indra/newview/skins/default/xui/zh/strings.xml
index a8d5fd90bb..a4e1b21ce6 100644
--- a/indra/newview/skins/default/xui/zh/strings.xml
+++ b/indra/newview/skins/default/xui/zh/strings.xml
@@ -353,6 +353,24 @@ http://secondlife.com/viewer-access-faq
<string name="TestingDisconnect">
測試瀏覽器斷線
</string>
+ <string name="SocialFacebookConnecting">
+ 連通臉書中…
+ </string>
+ <string name="SocialFacebookPosting">
+ 發佈中…
+ </string>
+ <string name="SocialFacebookDisconnecting">
+ 臉書連通中斷中…
+ </string>
+ <string name="SocialFacebookErrorConnecting">
+ 連通臉書時出問題
+ </string>
+ <string name="SocialFacebookErrorPosting">
+ 發佈到臉書時出問題
+ </string>
+ <string name="SocialFacebookErrorDisconnecting">
+ 試圖中斷臉書連通時出問題
+ </string>
<string name="SocialFlickrConnecting">
連通 Flickr 中…
</string>
@@ -2569,9 +2587,21 @@ http://secondlife.com/support 求助解決問題。
<string name="NoPicksClassifiedsText">
你尚未建立任何精選地點或個人廣告。 點按下面的 + 按鈕建立精選地點或個人廣告。
</string>
+ <string name="NoPicksText">
+ 你尚未建立任何精選地點。 點按「新增」按鈕建立精選地點。
+ </string>
+ <string name="NoClassifiedsText">
+ 你尚未建立任何分類廣告。 點按「新增」按鈕建立分類廣告。
+ </string>
<string name="NoAvatarPicksClassifiedsText">
使用者無精選地點或個人廣告
</string>
+ <string name="NoAvatarPicksText">
+ 使用者沒有精選地點
+ </string>
+ <string name="NoAvatarClassifiedsText">
+ 使用者沒有分類廣告
+ </string>
<string name="PicksClassifiedsLoadingText">
載入中...
</string>
@@ -4549,6 +4579,9 @@ http://secondlife.com/support 求助解決問題。
<string name="share_alert">
將收納區物品拖曳到這裡
</string>
+ <string name="facebook_post_success">
+ 成功發佈到臉書。
+ </string>
<string name="flickr_post_success">
成功發佈到 Flickr。
</string>