aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden
diff options
context:
space:
mode:
authorMcCabe Maxsted2010-04-06 22:27:24 -0700
committerMcCabe Maxsted2010-04-06 22:27:24 -0700
commitc6fbf529fce49017cbb7f3cbbfd3a11d611aa137 (patch)
tree23b0f3cf4f21a42a5da77a6e05a207f04792ae28 /linden
parentCreated new Advanced preferences panel, ready for filling (diff)
downloadmeta-impy-c6fbf529fce49017cbb7f3cbbfd3a11d611aa137.zip
meta-impy-c6fbf529fce49017cbb7f3cbbfd3a11d611aa137.tar.gz
meta-impy-c6fbf529fce49017cbb7f3cbbfd3a11d611aa137.tar.bz2
meta-impy-c6fbf529fce49017cbb7f3cbbfd3a11d611aa137.tar.xz
Ported IM autoresponse options from Emerald, added them to a new window in Preferences > IM
Diffstat (limited to 'linden')
-rw-r--r--linden/indra/newview/CMakeLists.txt3
-rw-r--r--linden/indra/newview/app_settings/settings_per_account.xml126
-rw-r--r--linden/indra/newview/floaterbusy.cpp242
-rw-r--r--linden/indra/newview/floaterbusy.h88
-rw-r--r--linden/indra/newview/llprefsim.cpp12
-rw-r--r--linden/indra/newview/llviewermessage.cpp252
-rw-r--r--linden/indra/newview/skins/default/xui/en-us/floater_busy.xml93
-rw-r--r--linden/indra/newview/skins/default/xui/en-us/panel_preferences_im.xml7
8 files changed, 820 insertions, 3 deletions
diff --git a/linden/indra/newview/CMakeLists.txt b/linden/indra/newview/CMakeLists.txt
index f75360c..1af5e9e 100644
--- a/linden/indra/newview/CMakeLists.txt
+++ b/linden/indra/newview/CMakeLists.txt
@@ -67,6 +67,7 @@ include_directories(
67set(viewer_SOURCE_FILES 67set(viewer_SOURCE_FILES
68 emeraldboobutils.cpp 68 emeraldboobutils.cpp
69 floaterao.cpp 69 floaterao.cpp
70 floaterbusy.cpp
70 floaterlogin.cpp 71 floaterlogin.cpp
71 hippoGridManager.cpp 72 hippoGridManager.cpp
72 hippoLimits.cpp 73 hippoLimits.cpp
@@ -491,6 +492,7 @@ set(viewer_HEADER_FILES
491 ViewerInstall.cmake 492 ViewerInstall.cmake
492 emeraldboobutils.h 493 emeraldboobutils.h
493 floaterao.h 494 floaterao.h
495 floaterbusy.h
494 floaterlogin.h 496 floaterlogin.h
495 hippoGridManager.h 497 hippoGridManager.h
496 hippoLimits.h 498 hippoLimits.h
@@ -1096,6 +1098,7 @@ set(viewer_XUI_FILES
1096 skins/default/xui/en-us/floater_build_options.xml 1098 skins/default/xui/en-us/floater_build_options.xml
1097 skins/default/xui/en-us/floater_bulk_perms.xml 1099 skins/default/xui/en-us/floater_bulk_perms.xml
1098 skins/default/xui/en-us/floater_bumps.xml 1100 skins/default/xui/en-us/floater_bumps.xml
1101 skins/default/xui/en-us/floater_busy.xml
1099 skins/default/xui/en-us/floater_buy_contents.xml 1102 skins/default/xui/en-us/floater_buy_contents.xml
1100 skins/default/xui/en-us/floater_buy_currency.xml 1103 skins/default/xui/en-us/floater_buy_currency.xml
1101 skins/default/xui/en-us/floater_buy_land.xml 1104 skins/default/xui/en-us/floater_buy_land.xml
diff --git a/linden/indra/newview/app_settings/settings_per_account.xml b/linden/indra/newview/app_settings/settings_per_account.xml
index e43df49..071e53c 100644
--- a/linden/indra/newview/app_settings/settings_per_account.xml
+++ b/linden/indra/newview/app_settings/settings_per_account.xml
@@ -228,6 +228,132 @@
228 </map> 228 </map>
229 229
230 <!-- End AO --> 230 <!-- End AO -->
231
232 <!-- Begin IM auto-response -->
233
234 <key>InstantMessageResponseFriends</key>
235 <map>
236 <key>Comment</key>
237 <string>Whether to auto-respond to non-friends</string>
238 <key>Persist</key>
239 <integer>1</integer>
240 <key>Type</key>
241 <string>Boolean</string>
242 <key>Value</key>
243 <integer>0</integer>
244 </map>
245 <key>InstantMessageResponseMuted</key>
246 <map>
247 <key>Comment</key>
248 <string>Whether to auto-respond to muted people</string>
249 <key>Persist</key>
250 <integer>1</integer>
251 <key>Type</key>
252 <string>Boolean</string>
253 <key>Value</key>
254 <integer>0</integer>
255 </map>
256 <key>InstantMessageResponseAnyone</key>
257 <map>
258 <key>Comment</key>
259 <string>Whether to auto-respond to anyone</string>
260 <key>Persist</key>
261 <integer>1</integer>
262 <key>Type</key>
263 <string>Boolean</string>
264 <key>Value</key>
265 <integer>0</integer>
266 </map>
267 <key>InstantMessageShowResponded</key>
268 <map>
269 <key>Comment</key>
270 <string>Whether to hide IMs entirely from those you have chosen to send autoresponses</string>
271 <key>Persist</key>
272 <integer>1</integer>
273 <key>Type</key>
274 <string>Boolean</string>
275 <key>Value</key>
276 <integer>0</integer>
277 </map>
278 <key>InstantMessageShowOnTyping</key>
279 <map>
280 <key>Comment</key>
281 <string>Whether to perform the autorespond the moment they begin to type instead of waiting for a actual message</string>
282 <key>Persist</key>
283 <integer>1</integer>
284 <key>Type</key>
285 <string>Boolean</string>
286 <key>Value</key>
287 <integer>0</integer>
288 </map>
289 <key>InstantMessageResponseRepeat</key>
290 <map>
291 <key>Comment</key>
292 <string>Whether to keep on resending the autoresponse every line they send</string>
293 <key>Persist</key>
294 <integer>1</integer>
295 <key>Type</key>
296 <string>Boolean</string>
297 <key>Value</key>
298 <integer>0</integer>
299 </map>
300 <key>InstantMessageResponseItem</key>
301 <map>
302 <key>Comment</key>
303 <string>Whether to send a item along with the autoresponse</string>
304 <key>Persist</key>
305 <integer>1</integer>
306 <key>Type</key>
307 <string>Boolean</string>
308 <key>Value</key>
309 <integer>0</integer>
310 </map>
311 <key>InstantMessageResponse</key>
312 <map>
313 <key>Comment</key>
314 <string>Auto response to instant messages</string>
315 <key>Persist</key>
316 <integer>1</integer>
317 <key>Type</key>
318 <string>String</string>
319 <key>Value</key>
320 <string>This is an autoresponse!</string>
321 </map>
322 <key>InstantMessageResponseItemData</key>
323 <map>
324 <key>Comment</key>
325 <string>UUID</string>
326 <key>Persist</key>
327 <integer>1</integer>
328 <key>Type</key>
329 <string>String</string>
330 <key>Value</key>
331 <string></string>
332 </map>
333 <key>InstantMessageAnnounceIncoming</key>
334 <map>
335 <key>Comment</key>
336 <string>Open a new IM tab when another person begins typing to you and announce that they are doing so.</string>
337 <key>Persist</key>
338 <integer>1</integer>
339 <key>Type</key>
340 <string>Boolean</string>
341 <key>Value</key>
342 <integer>0</integer>
343 </map>
344 <key>InstantMessageAnnounceStealFocus</key>
345 <map>
346 <key>Comment</key>
347 <string>Steal focus when opening new IM tab due to other person begins first typing this session</string>
348 <key>Persist</key>
349 <integer>1</integer>
350 <key>Type</key>
351 <string>Boolean</string>
352 <key>Value</key>
353 <integer>1</integer>
354 </map>
355
356 <!-- End IM auto-response -->
231 357
232 <key>RLVaLoginLastLocation</key> 358 <key>RLVaLoginLastLocation</key>
233 <map> 359 <map>
diff --git a/linden/indra/newview/floaterbusy.cpp b/linden/indra/newview/floaterbusy.cpp
new file mode 100644
index 0000000..5823dfa
--- /dev/null
+++ b/linden/indra/newview/floaterbusy.cpp
@@ -0,0 +1,242 @@
1/**
2* @file floaterbusy.cpp
3* @brief Custom busy mode settings for Imprudence
4*
5* $LicenseInfo:firstyear=2009&license=viewergpl$
6*
7* Copyright (c) 2010, McCabe Maxsted
8*
9* Imprudence Viewer Source Code
10* The source code in this file ("Source Code") is provided to you
11* under the terms of the GNU General Public License, version 2.0
12* ("GPL"). Terms of the GPL can be found in doc/GPL-license.txt in
13* this distribution, or online at
14* http://secondlifegrid.net/programs/open_source/licensing/gplv2
15*
16* There are special exceptions to the terms and conditions of the GPL as
17* it is applied to this Source Code. View the full text of the exception
18* in the file doc/FLOSS-exception.txt in this software distribution, or
19* online at http://secondlifegrid.net/programs/open_source/licensing/flossexception
20*
21* By copying, modifying or distributing this software, you acknowledge
22* that you have read and understood your obligations described above,
23* and agree to abide by those obligations.
24*
25* ALL SOURCE CODE IS PROVIDED "AS IS." THE AUTHOR MAKES NO
26* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
27* COMPLETENESS OR PERFORMANCE.
28* $/LicenseInfo$
29*/
30
31#include "llviewerprecompiledheaders.h"
32
33#include "floaterbusy.h"
34
35#include "llinventorymodel.h"
36#include "llstartup.h"
37#include "lltexteditor.h"
38#include "lluictrlfactory.h"
39#include "llviewercontrol.h"
40#include "llviewerinventory.h"
41
42////////begin drop utility/////////////
43//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
44// Class InvDropTarget
45//
46// This handy class is a simple way to drop something on another
47// view. It handles drop events, always setting itself to the size of
48// its parent.
49//
50// altered to support a callback so i can slap it in things and it just return the item to a func of my choice
51//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
52
53InvDropTarget::InvDropTarget(const std::string& name, const LLRect& rect,
54 void (*callback)(LLViewerInventoryItem*)) :
55 LLView(name, rect, NOT_MOUSE_OPAQUE, FOLLOWS_ALL),
56 mDownCallback(callback)
57{
58}
59
60InvDropTarget::~InvDropTarget()
61{
62}
63
64void InvDropTarget::doDrop(EDragAndDropType cargo_type, void* cargo_data)
65{
66 llinfos << "InvDropTarget::doDrop()" << llendl;
67}
68
69BOOL InvDropTarget::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
70 EDragAndDropType cargo_type,
71 void* cargo_data,
72 EAcceptance* accept,
73 std::string& tooltip_msg)
74{
75 BOOL handled = FALSE;
76 if (getParent())
77 {
78 handled = TRUE;
79 // check the type
80 //switch(cargo_type)
81 //{
82 //case DAD_ANIMATION:
83 //{
84 LLViewerInventoryItem* inv_item = (LLViewerInventoryItem*)cargo_data;
85 if (gInventory.getItem(inv_item->getUUID()))
86 {
87 *accept = ACCEPT_YES_COPY_SINGLE;
88 if (drop)
89 {
90 //printchat("accepted");
91 mDownCallback(inv_item);
92 }
93 }
94 else
95 {
96 *accept = ACCEPT_NO;
97 }
98 // break;
99 //}
100 //default:
101 // *accept = ACCEPT_NO;
102 // break;
103 //}
104 }
105 return handled;
106}
107////////end drop utility///////////////
108
109// static
110InvDropTarget * FloaterBusy::mObjectDropTarget;
111
112FloaterBusy::FloaterBusy(const LLSD& seed) : LLFloater("floater_busy")
113{
114 LLUICtrlFactory::getInstance()->buildFloater(this, "floater_busy.xml");
115}
116
117BOOL FloaterBusy::postBuild()
118{
119 childSetAction("btn_ok", onClickOK, this);
120 childSetAction("btn_cancel", onClickCancel, this);
121
122 LLView *target_view = getChild<LLView>("im_give_drop_target_rect");
123 if (target_view)
124 {
125 if (mObjectDropTarget)//shouldn't happen
126 {
127 delete mObjectDropTarget;
128 }
129 mObjectDropTarget = new InvDropTarget("drop target", target_view->getRect(), IMAutoResponseItemDrop);//, mAvatarID);
130 addChild(mObjectDropTarget);
131 }
132
133 if (LLStartUp::getStartupState() == STATE_STARTED)
134 {
135 LLUUID itemid = (LLUUID)gSavedPerAccountSettings.getString("InstantMessageResponseItemData");
136 LLViewerInventoryItem* item = gInventory.getItem(itemid);
137
138 if (item)
139 {
140 childSetValue("im_give_disp_rect_txt","Currently set to: "+item->getName());
141 }
142 else if (itemid.isNull())
143 {
144 childSetValue("im_give_disp_rect_txt","Currently not set");
145 }
146 else
147 {
148 childSetValue("im_give_disp_rect_txt","Currently set to a item not on this account");
149 }
150
151 itemid = (LLUUID)gSavedSettings.getString("EmeraldBuildPrefs_Item");
152 item = gInventory.getItem(itemid);
153
154 if (item)
155 {
156 childSetValue("build_item_add_disp_rect_txt","Currently set to: "+item->getName());
157 }
158 else if (itemid.isNull())
159 {
160 childSetValue("build_item_add_disp_rect_txt","Currently not set");
161 }
162 else
163 {
164 childSetValue("build_item_add_disp_rect_txt","Currently set to a item not on this account");
165 }
166 }
167 else
168 {
169 childSetValue("im_give_disp_rect_txt","Not logged in");
170 childSetValue("build_item_add_disp_rect_txt","Not logged in");
171 }
172
173 LLWString auto_response = utf8str_to_wstring( gSavedPerAccountSettings.getString("InstantMessageResponse") );
174 LLWStringUtil::replaceChar(auto_response, '^', '\n');
175 LLWStringUtil::replaceChar(auto_response, '%', ' ');
176 childSetText("im_response", wstring_to_utf8str(auto_response));
177
178 childSetValue("InstantMessageResponseFriends", gSavedPerAccountSettings.getBOOL("InstantMessageResponseFriends"));
179 childSetValue("InstantMessageResponseMuted", gSavedPerAccountSettings.getBOOL("InstantMessageResponseMuted"));
180 childSetValue("InstantMessageResponseAnyone", gSavedPerAccountSettings.getBOOL("InstantMessageResponseAnyone"));
181 childSetValue("InstantMessageShowResponded", gSavedPerAccountSettings.getBOOL("InstantMessageShowResponded"));
182 childSetValue("InstantMessageShowOnTyping", gSavedPerAccountSettings.getBOOL("InstantMessageShowOnTyping"));
183 childSetValue("InstantMessageResponseRepeat", gSavedPerAccountSettings.getBOOL("InstantMessageResponseRepeat" ));
184 childSetValue("InstantMessageResponseItem", gSavedPerAccountSettings.getBOOL("InstantMessageResponseItem"));
185 childSetValue("InstantMessageAnnounceIncoming", gSavedPerAccountSettings.getBOOL("InstantMessageAnnounceIncoming"));
186 childSetValue("InstantMessageAnnounceStealFocus", gSavedPerAccountSettings.getBOOL("InstantMessageAnnounceStealFocus"));
187
188 return TRUE;
189}
190
191FloaterBusy::~FloaterBusy()
192{
193 delete mObjectDropTarget;
194 mObjectDropTarget = NULL;
195}
196
197void FloaterBusy::IMAutoResponseItemDrop(LLViewerInventoryItem* item)
198{
199 gSavedPerAccountSettings.setString("InstantMessageResponseItemData", item->getUUID().asString());
200 FloaterBusy::getInstance()->childSetValue("im_give_disp_rect_txt","Currently set to: "+item->getName());
201}
202
203// static
204void FloaterBusy::onClickOK(void* userdata)
205{
206 FloaterBusy* self = (FloaterBusy*)userdata;
207 self->apply();
208 self->close();
209}
210
211// static
212void FloaterBusy::onClickCancel(void* userdata)
213{
214 FloaterBusy* self = (FloaterBusy*)userdata;
215 self->cancel();
216}
217
218void FloaterBusy::cancel()
219{
220 close();
221}
222
223void FloaterBusy::apply()
224{
225 LLTextEditor* im = getChild<LLTextEditor>("im_response");
226 LLWString im_response;
227 if (im) im_response = im->getWText();
228 LLWStringUtil::replaceTabsWithSpaces(im_response, 4);
229 LLWStringUtil::replaceChar(im_response, '\n', '^');
230 LLWStringUtil::replaceChar(im_response, ' ', '%');
231 gSavedPerAccountSettings.setString("InstantMessageResponse", std::string(wstring_to_utf8str(im_response)));
232 gSavedPerAccountSettings.setBOOL("InstantMessageResponseMuted", childGetValue("InstantMessageResponseMuted").asBoolean());
233 gSavedPerAccountSettings.setBOOL("InstantMessageResponseFriends", childGetValue("InstantMessageResponseFriends").asBoolean());
234 gSavedPerAccountSettings.setBOOL("InstantMessageResponseMuted", childGetValue("InstantMessageResponseMuted").asBoolean());
235 gSavedPerAccountSettings.setBOOL("InstantMessageResponseAnyone", childGetValue("InstantMessageResponseAnyone").asBoolean());
236 gSavedPerAccountSettings.setBOOL("InstantMessageShowResponded", childGetValue("InstantMessageShowResponded").asBoolean());
237 gSavedPerAccountSettings.setBOOL("InstantMessageShowOnTyping", childGetValue("InstantMessageShowOnTyping").asBoolean());
238 gSavedPerAccountSettings.setBOOL("InstantMessageResponseRepeat", childGetValue("InstantMessageResponseRepeat").asBoolean());
239 gSavedPerAccountSettings.setBOOL("InstantMessageResponseItem", childGetValue("InstantMessageResponseItem").asBoolean());
240 gSavedPerAccountSettings.setBOOL("InstantMessageAnnounceIncoming", childGetValue("InstantMessageAnnounceIncoming").asBoolean());
241 gSavedPerAccountSettings.setBOOL("InstantMessageAnnounceStealFocus", childGetValue("InstantMessageAnnounceStealFocus").asBoolean());
242}
diff --git a/linden/indra/newview/floaterbusy.h b/linden/indra/newview/floaterbusy.h
new file mode 100644
index 0000000..821d00d
--- /dev/null
+++ b/linden/indra/newview/floaterbusy.h
@@ -0,0 +1,88 @@
1/**
2* @file floaterbusy.h
3* @brief Custom busy mode settings for Imprudence
4*
5* $LicenseInfo:firstyear=2009&license=viewergpl$
6*
7* Copyright (c) 2010, McCabe Maxsted
8*
9* Imprudence Viewer Source Code
10* The source code in this file ("Source Code") is provided to you
11* under the terms of the GNU General Public License, version 2.0
12* ("GPL"). Terms of the GPL can be found in doc/GPL-license.txt in
13* this distribution, or online at
14* http://secondlifegrid.net/programs/open_source/licensing/gplv2
15*
16* There are special exceptions to the terms and conditions of the GPL as
17* it is applied to this Source Code. View the full text of the exception
18* in the file doc/FLOSS-exception.txt in this software distribution, or
19* online at http://secondlifegrid.net/programs/open_source/licensing/flossexception
20*
21* By copying, modifying or distributing this software, you acknowledge
22* that you have read and understood your obligations described above,
23* and agree to abide by those obligations.
24*
25* ALL SOURCE CODE IS PROVIDED "AS IS." THE AUTHOR MAKES NO
26* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
27* COMPLETENESS OR PERFORMANCE.
28* $/LicenseInfo$
29*/
30
31#ifndef FLOATERBUSY_H
32#define FLOATERBUSY_H
33
34#include "llfloater.h"
35
36class LLViewerInventoryItem;
37
38////////begin drop utility/////////////
39//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
40// Class InvDropTarget
41//
42// This handy class is a simple way to drop something on another
43// view. It handles drop events, always setting itself to the size of
44// its parent.
45//
46// altered to support a callback so i can slap it in things and it just return the item to a func of my choice
47//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
48class InvDropTarget : public LLView
49{
50public:
51 InvDropTarget(const std::string& name, const LLRect& rect, void (*callback)(LLViewerInventoryItem*));
52 ~InvDropTarget();
53
54 void doDrop(EDragAndDropType cargo_type, void* cargo_data);
55
56 //
57 // LLView functionality
58 virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
59 EDragAndDropType cargo_type,
60 void* cargo_data,
61 EAcceptance* accept,
62 std::string& tooltip_msg);
63protected:
64 void (*mDownCallback)(LLViewerInventoryItem*);
65};
66////////end drop utility///////////////
67
68class FloaterBusy : public LLFloater, public LLFloaterSingleton<FloaterBusy>
69{
70public:
71 FloaterBusy(const LLSD& seed);
72 virtual ~FloaterBusy();
73
74 BOOL postBuild();
75
76 void apply();
77 void cancel();
78
79private:
80 static InvDropTarget* mObjectDropTarget;
81
82 static void onClickOK(void* userdata);
83 static void onClickCancel(void* userdata);
84
85 static void IMAutoResponseItemDrop(LLViewerInventoryItem* item);
86};
87
88#endif FLOATERBUSY_H
diff --git a/linden/indra/newview/llprefsim.cpp b/linden/indra/newview/llprefsim.cpp
index 0c06122..045139c 100644
--- a/linden/indra/newview/llprefsim.cpp
+++ b/linden/indra/newview/llprefsim.cpp
@@ -35,6 +35,7 @@
35 35
36#include "llprefsim.h" 36#include "llprefsim.h"
37 37
38#include "floaterbusy.h"
38#include "llpanel.h" 39#include "llpanel.h"
39#include "llcheckboxctrl.h" 40#include "llcheckboxctrl.h"
40#include "llstring.h" 41#include "llstring.h"
@@ -65,6 +66,8 @@ public:
65 static void onClickLogPath(void* user_data); 66 static void onClickLogPath(void* user_data);
66 static void onCommitLogging(LLUICtrl* ctrl, void* user_data); 67 static void onCommitLogging(LLUICtrl* ctrl, void* user_data);
67 68
69 static void onClickBusyAdvanced(void* user_data);
70
68protected: 71protected:
69 72
70 bool mGotPersonalInfo; 73 bool mGotPersonalInfo;
@@ -136,6 +139,8 @@ BOOL LLPrefsIMImpl::postBuild()
136 childSetAction("log_path_button", onClickLogPath, this); 139 childSetAction("log_path_button", onClickLogPath, this);
137 childSetCommitCallback("log_chat",onCommitLogging,this); 140 childSetCommitCallback("log_chat",onCommitLogging,this);
138 childSetCommitCallback("log_instant_messages",onCommitLogging,this); 141 childSetCommitCallback("log_instant_messages",onCommitLogging,this);
142
143 childSetAction("busy_adv_btn", onClickBusyAdvanced, this);
139 144
140 return TRUE; 145 return TRUE;
141} 146}
@@ -287,6 +292,13 @@ void LLPrefsIMImpl::setPersonalInfo(const std::string& visibility, bool im_via_e
287 292
288 293
289// static 294// static
295void LLPrefsIMImpl::onClickBusyAdvanced(void* user_data)
296{
297 FloaterBusy::getInstance()->open();
298 FloaterBusy::getInstance()->center();
299}
300
301// static
290void LLPrefsIMImpl::onClickLogPath(void* user_data) 302void LLPrefsIMImpl::onClickLogPath(void* user_data)
291{ 303{
292 LLPrefsIMImpl* self=(LLPrefsIMImpl*)user_data; 304 LLPrefsIMImpl* self=(LLPrefsIMImpl*)user_data;
diff --git a/linden/indra/newview/llviewermessage.cpp b/linden/indra/newview/llviewermessage.cpp
index 8bdbc30..ba01583 100644
--- a/linden/indra/newview/llviewermessage.cpp
+++ b/linden/indra/newview/llviewermessage.cpp
@@ -139,6 +139,7 @@
139#include "llkeythrottle.h" 139#include "llkeythrottle.h"
140 140
141#include <boost/tokenizer.hpp> 141#include <boost/tokenizer.hpp>
142#include <boost/regex.hpp> // Boost Reg Expresions
142 143
143#if LL_WINDOWS // For Windows specific error handler 144#if LL_WINDOWS // For Windows specific error handler
144#include "llwindebug.h" // For the invalid message handler 145#include "llwindebug.h" // For the invalid message handler
@@ -1479,6 +1480,8 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
1479 BOOL is_muted = LLMuteList::getInstance()->isMuted(from_id, name, LLMute::flagTextChat); 1480 BOOL is_muted = LLMuteList::getInstance()->isMuted(from_id, name, LLMute::flagTextChat);
1480 BOOL is_linden = LLMuteList::getInstance()->isLinden(name); 1481 BOOL is_linden = LLMuteList::getInstance()->isLinden(name);
1481 BOOL is_owned_by_me = FALSE; 1482 BOOL is_owned_by_me = FALSE;
1483
1484 LLUUID computed_session_id = LLIMMgr::computeSessionID(dialog,from_id);
1482 1485
1483 chat.mMuted = is_muted && !is_linden; 1486 chat.mMuted = is_muted && !is_linden;
1484 chat.mFromID = from_id; 1487 chat.mFromID = from_id;
@@ -1502,12 +1505,259 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
1502 message_offset = 3; 1505 message_offset = 3;
1503 } 1506 }
1504 1507
1508 if(dialog == IM_TYPING_START
1509 || dialog == IM_NOTHING_SPECIAL
1510 || dialog == IM_TYPING_STOP
1511 || dialog == IM_BUSY_AUTO_RESPONSE)
1512 {
1513
1514 if(session_id != computed_session_id)
1515 {
1516 session_id = computed_session_id;
1517 /*if(!gIMMgr->hasSession(correct_session))
1518 {
1519 //LLUUID sess = gIMMgr->addSession(name, dialog, from_id);
1520 LLUUID sess = gIMMgr->addSession(name, IM_NOTHING_SPECIAL, from_id);
1521 make_ui_sound("UISndNewIncomingIMSession");
1522 gIMMgr->addMessage(
1523 sess,
1524 from_id,
1525 SYSTEM_FROM,
1526 "Invalid session id used by "+name+", corrected.",
1527 LLStringUtil::null,
1528 IM_NOTHING_SPECIAL,
1529 parent_estate_id,
1530 region_id,
1531 position,
1532 false);
1533 }*/
1534 }
1535 }
1536 /*if(dialog == IM_NOTHING_SPECIAL)
1537 {
1538 LLVOAvatar* avatarp = find_avatar(from_id);
1539 if(avatarp)
1540 {
1541 if(avatarp->mCheckingCryolife < 2 && avatarp->mIsCryolife == FALSE)
1542 {
1543 boost::regex re(
1544 ".* \\d+\\.\\d+\\.\\d+ \\(\\d+\\) \\w{3,5} \\d+ \\d+ \\d+:\\d+:\\d+ \\(.*\\) <.+,.+,.+>:.+"
1545 , boost::regex_constants::icase);
1546 if(boost::regex_match(message,re))
1547 {
1548 //llinfos << "CryoLife user detected " << from_id.asString() << llendl;
1549 avatarp->mCheckingCryolife = 2;
1550 avatarp->mIsCryolife = TRUE;
1551 LLVector3 root_pos_last = avatarp->mRoot.getWorldPosition();
1552 avatarp->idleUpdateNameTag(root_pos_last);
1553 return;
1554 }
1555 else
1556 {
1557 llinfos << "CryoLife user not detected " << from_id.asString() << llendl;
1558 }
1559 }
1560 }
1561 }*/
1562 bool typing_init = false;
1563 if( dialog == IM_TYPING_START && !is_muted )
1564 {
1565 if(!gIMMgr->hasSession(computed_session_id) && gSavedPerAccountSettings.getBOOL("InstantMessageAnnounceIncoming"))
1566 {
1567 typing_init = true;
1568 if( gSavedPerAccountSettings.getBOOL("InstantMessageAnnounceStealFocus") )
1569 {
1570 /*LLUUID sess =*/ gIMMgr->addSession(name, IM_NOTHING_SPECIAL, from_id);
1571 make_ui_sound("UISndNewIncomingIMSession");
1572 }
1573 gIMMgr->addMessage(
1574 computed_session_id,
1575 from_id,
1576 name,
1577 llformat("You sense a disturbance in the force... (%s is typing)",name.c_str()),
1578 name,
1579 IM_NOTHING_SPECIAL,
1580 parent_estate_id,
1581 region_id,
1582 position,
1583 false);
1584 }
1585 }
1586
1587 bool is_auto_response = false;
1588 if(dialog == IM_NOTHING_SPECIAL) {
1589 // detect auto responses from GreenLife and compatible viewers
1590 is_auto_response = ( message.substr(0, 21) == "/me (auto-response): " );
1591 }
1592
1593 bool do_auto_response = false;
1594 if( gSavedPerAccountSettings.getBOOL("InstantMessageResponseAnyone" ) )
1595 do_auto_response = true;
1596
1597 // odd name for auto respond to non-friends
1598 if( gSavedPerAccountSettings.getBOOL("InstantMessageResponseFriends") &&
1599 LLAvatarTracker::instance().getBuddyInfo(from_id) == NULL )
1600 do_auto_response = true;
1601
1602 if( is_muted && !gSavedPerAccountSettings.getBOOL("InstantMessageResponseMuted") )
1603 do_auto_response = false;
1604
1605 if( offline != IM_ONLINE )
1606 do_auto_response = false;
1607
1608 if( is_auto_response )
1609 do_auto_response = false;
1610
1611 // handle cases where IM_NOTHING_SPECIAL is not an IM
1612 if( name == SYSTEM_FROM ||
1613 from_id.isNull() ||
1614 to_id.isNull() )
1615 do_auto_response = false;
1616
1617// if( do_auto_response )
1618// [RLVa:KB] - Alternate: Emerald-370
1619 // Emerald specific: auto-response should be blocked if the avie is RLV @sendim=n restricted and the recipient is not an exception
1620 if ( (do_auto_response) && ( (!gRlvHandler.hasBehaviour(RLV_BHVR_SENDIM)) || (gRlvHandler.isException(RLV_BHVR_SENDIM, from_id)) ) )
1621// [/RLVa:KB]
1622 {
1623 if((dialog == IM_NOTHING_SPECIAL && !is_auto_response) ||
1624 (dialog == IM_TYPING_START && gSavedPerAccountSettings.getBOOL("InstantMessageShowOnTyping"))
1625 )
1626 {
1627 BOOL has = gIMMgr->hasSession(computed_session_id);
1628 if(!has || gSavedPerAccountSettings.getBOOL("InstantMessageResponseRepeat") || typing_init)
1629 {
1630 BOOL show = !gSavedPerAccountSettings.getBOOL("InstantMessageShowResponded");
1631 if(!has && show)
1632 {
1633 gIMMgr->addSession(name, IM_NOTHING_SPECIAL, from_id);
1634 }
1635 if(show)
1636 {
1637 gIMMgr->addMessage(
1638 computed_session_id,
1639 from_id,
1640 SYSTEM_FROM,
1641 llformat("Autoresponse sent to %s.",name.c_str()),
1642 LLStringUtil::null,
1643 IM_NOTHING_SPECIAL,
1644 parent_estate_id,
1645 region_id,
1646 position,
1647 false);
1648 }
1649 std::string my_name;
1650 gAgent.buildFullname(my_name);
1651
1652 //<-- Personalized Autoresponse by Madgeek
1653 std::string autoresponse = gSavedPerAccountSettings.getText("InstantMessageResponse");
1654 //Define Wildcards
1655 std::string fname_wildcard = "#f";
1656 std::string lname_wildcard = "#l";
1657 std::string time_wildcard = "#t";
1658 //Extract Name
1659 std::string f_name, l_name;
1660 std::istringstream inname(name);
1661 inname >> f_name >> l_name;
1662 //Generate a Timestamp
1663 time_t rawtime;
1664 time(&rawtime);
1665 char * timestamp_chars;
1666 timestamp_chars = asctime(localtime(&rawtime));
1667 std::string timestamp;
1668 timestamp.assign(timestamp_chars);
1669 timestamp = timestamp.substr(0, timestamp.find('\n'));
1670 //Handle Replacements
1671 size_t found = autoresponse.find(fname_wildcard);
1672 while(found != std::string::npos)
1673 {
1674 autoresponse.replace(found, 2, f_name);
1675 found = autoresponse.find(fname_wildcard);
1676 }
1677 found = autoresponse.find(lname_wildcard);
1678 while(found != std::string::npos)
1679 {
1680 autoresponse.replace(found, 2, l_name);
1681 found = autoresponse.find(lname_wildcard);
1682 }
1683 found = autoresponse.find(time_wildcard);
1684 while(found != std::string::npos)
1685 {
1686 autoresponse.replace(found, 2, timestamp);
1687 found = autoresponse.find(time_wildcard);
1688 }
1689 //--> Personalized Autoresponse
1690
1691 if(gSavedPerAccountSettings.getBOOL("InstantMessageResponseRepeat") && has && !typing_init) {
1692 // send as busy auto response instead to prevent endless repeating replies
1693 // when other end is a bot or broken client that answers to every usual IM
1694 // reasoning for this decision can be found in RFC2812 3.3.2 Notices
1695 // where PRIVMSG can be seen as IM_NOTHING_SPECIAL and NOTICE can be seen as
1696 // IM_BUSY_AUTO_RESPONSE. The assumption here is that no existing client
1697 // responds to IM_BUSY_AUTO_RESPONSE. --TS
1698 std::string response = autoresponse;
1699 pack_instant_message(
1700 gMessageSystem,
1701 gAgent.getID(),
1702 FALSE,
1703 gAgent.getSessionID(),
1704 from_id,
1705 my_name,
1706 response,
1707 IM_OFFLINE,
1708 IM_BUSY_AUTO_RESPONSE,
1709 session_id);
1710 } else {
1711 std::string response = "/me (auto-response): "+autoresponse;
1712 pack_instant_message(
1713 gMessageSystem,
1714 gAgent.getID(),
1715 FALSE,
1716 gAgent.getSessionID(),
1717 from_id,
1718 my_name,
1719 response,
1720 IM_OFFLINE,
1721 IM_NOTHING_SPECIAL,
1722 session_id);
1723 }
1724 gAgent.sendReliableMessage();
1725 if(gSavedPerAccountSettings.getBOOL("InstantMessageResponseItem") && (!has || typing_init))
1726 {
1727 LLUUID itemid = (LLUUID)gSavedPerAccountSettings.getString("InstantMessageResponseItemData");
1728 LLViewerInventoryItem* item = gInventory.getItem(itemid);
1729 if(item)
1730 {
1731 //childSetValue("im_give_disp_rect_txt","Currently set to: "+item->getName());
1732 if(show)
1733 {
1734 gIMMgr->addMessage(
1735 computed_session_id,
1736 from_id,
1737 SYSTEM_FROM,
1738 llformat("Sent %s auto-response item \"%s\"",name.c_str(),item->getName().c_str()),
1739 LLStringUtil::null,
1740 IM_NOTHING_SPECIAL,
1741 parent_estate_id,
1742 region_id,
1743 position,
1744 false);
1745 }
1746 LLToolDragAndDrop::giveInventory(from_id, item);
1747 }
1748 }
1749 //InstantMessageResponseItem<
1750
1751 }
1752 }
1753 }
1754
1505 LLSD args; 1755 LLSD args;
1506 switch(dialog) 1756 switch(dialog)
1507 { 1757 {
1508 case IM_CONSOLE_AND_CHAT_HISTORY: 1758 case IM_CONSOLE_AND_CHAT_HISTORY:
1509 // These are used for system messages, hence don't need the name, 1759 // These are used for system messages, hence don't need the name,
1510 // as it is always "Second Life". 1760 // as it is always "Imprudence".
1511 // *TODO:translate 1761 // *TODO:translate
1512 args["MESSAGE"] = message; 1762 args["MESSAGE"] = message;
1513 1763
diff --git a/linden/indra/newview/skins/default/xui/en-us/floater_busy.xml b/linden/indra/newview/skins/default/xui/en-us/floater_busy.xml
new file mode 100644
index 0000000..a9bd613
--- /dev/null
+++ b/linden/indra/newview/skins/default/xui/en-us/floater_busy.xml
@@ -0,0 +1,93 @@
1<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
2<floater name="busy" title="IM Response Options"
3 height="446" width="255" min_height="446" min_width="255"
4 follows="top|right" can_close="true" can_drag_on_left="false"
5 can_minimize="true" can_resize="false" can_tear_off="false">
6
7 <check_box bottom="-40" enabled="true" follows="left|top" font="SansSerifSmall" height="16"
8 initial_value="false" label="Announce incoming instant messages" left="10" mouse_opaque="true"
9 name="InstantMessageAnnounceIncoming" radio_style="false" width="270"/>
10 <check_box bottom_delta="-20" enabled="true" follows="left|top" font="SansSerifSmall" height="16"
11 initial_value="false" label="Steal focus" left_delta="10" mouse_opaque="true" name="InstantMessageAnnounceStealFocus"
12 radio_style="false" width="270"/>
13 <check_box bottom_delta="-20" enabled="true" follows="left|top" font="SansSerifSmall" height="16"
14 initial_value="false" label="Autorespond to non-friends" left_delta="-10" mouse_opaque="true"
15 name="InstantMessageResponseFriends" radio_style="false" width="270"/>
16 <check_box bottom_delta="-20" enabled="true" follows="left|top" font="SansSerifSmall" height="16"
17 initial_value="false" label="Autorespond to people you have muted" left_delta="0"
18 mouse_opaque="true" name="InstantMessageResponseMuted" radio_style="false"
19 width="270"/>
20 <check_box bottom_delta="-20" enabled="true" follows="left|top" font="SansSerifSmall" height="16"
21 initial_value="false" label="Autorespond to anyone" left_delta="0" mouse_opaque="true"
22 name="InstantMessageResponseAnyone" radio_style="false" width="270"/>
23 <check_box bottom_delta="-20" enabled="true" follows="left|top" font="SansSerifSmall" height="16"
24 initial_value="false" label="Send as soon as they start typing" left_delta="10" mouse_opaque="true"
25 name="InstantMessageShowOnTyping" radio_style="false" width="270"/>
26 <check_box bottom_delta="-20" enabled="true" follows="left|top" font="SansSerifSmall" height="26"
27 initial_value="false" label="Don't show IMs you auto-responsed to" left_delta="0"
28 mouse_opaque="true" name="InstantMessageShowResponded" radio_style="false"
29 width="170"/>
30 <check_box bottom_delta="-20" enabled="true" follows="left|top" font="SansSerifSmall" height="16"
31 initial_value="false" label="Autorespond to every message" left_delta="0" mouse_opaque="true"
32 name="InstantMessageResponseRepeat" radio_style="false" width="270"/>
33
34 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
35 bottom_delta="-25" drop_shadow_visible="true" enabled="true" follows="left|top" font="SansSerifSmall"
36 h_pad="0" halign="left" height="20" left_delta="-10" mouse_opaque="false"
37 name="text_box1" v_pad="0" width="425">
38 Response Text:
39 </text>
40 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
41 bottom_delta="-20" drop_shadow_visible="true" enabled="true" follows="left|top" font="SansSerifSmall"
42 h_pad="0" halign="left" height="20" left_delta="15" mouse_opaque="false"
43 name="text_box_a" v_pad="0" width="425">
44 Use "#f" for recipient's first name
45 </text>
46 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
47 bottom_delta="-20" drop_shadow_visible="true" enabled="true" follows="left|top" font="SansSerifSmall"
48 h_pad="0" halign="left" height="20" left_delta="0" mouse_opaque="false"
49 name="text_box_b" v_pad="0" width="425">
50 Use "#l" for last name
51 </text>
52 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
53 bottom_delta="-20" drop_shadow_visible="true" enabled="true" follows="left|top" font="SansSerifSmall"
54 h_pad="0" halign="left" height="20" left_delta="0" mouse_opaque="false"
55 name="text_box_c" v_pad="0" width="425">
56 Use "#t" for timestamp
57 </text>
58
59 <text_editor type="string" length="1" bottom_delta="-85" embedded_items="false" enabled="true"
60 follows="left|top" font="SansSerifSmall" height="75" left_delta="-15" max_length="1100"
61 mouse_opaque="true" name="im_response" width="230" word_wrap="true"/>
62
63 <check_box bottom_delta="-30" enabled="true" follows="left|top" font="SansSerifSmall" height="16"
64 initial_value="false" label="Send an item along with the response" left_delta="0"
65 mouse_opaque="true" name="InstantMessageResponseItem" radio_style="false"
66 width="270"/>
67
68 <view_border blevel_style="in" bottom_delta="-20" follows="left|top" height="16" left_delta="0"
69 mouse_opaque="false" name="im_give_drop_target_rect" width="230"/>
70
71 <text bg_visible="false" border_drop_shadow_visible="false" border_visible="false" bottom_delta="0"
72 drop_shadow_visible="true" follows="left|top" font="SansSerifSmall" h_pad="0" halign="center"
73 height="16" left_delta="0" mouse_opaque="true" name="Give inventory" tool_tip="Drop an inventory item here to have it given along with the auto-response."
74 v_pad="2" width="230">
75 Drop an inventory item here
76 </text>
77
78 <view_border blevel_style="in" bottom_delta="-18" follows="left|top" height="16" left_delta="0"
79 mouse_opaque="false" name="im_give_disp_rect" width="230"/>
80
81 <text bg_visible="false" border_drop_shadow_visible="false" border_visible="false" bottom_delta="0"
82 drop_shadow_visible="true" follows="left|top" font="SansSerifSmall" h_pad="0" halign="center"
83 height="16" left_delta="0" mouse_opaque="true" name="im_give_disp_rect_txt" tool_tip=""
84 v_pad="2" width="230">
85 Currently set to: ITEM
86 </text>
87
88 <button bottom_delta="-26" follows="top|right" height="22" label="Cancel"
89 right="-10" name="btn_cancel" tool_tip="" enagled="true" width="80" />
90 <button bottom_delta="0" follows="top|right" height="22" label="OK"
91 right="-90" name="btn_ok" tool_tip="" enabled="true" width="80" />
92
93</floater> \ No newline at end of file
diff --git a/linden/indra/newview/skins/default/xui/en-us/panel_preferences_im.xml b/linden/indra/newview/skins/default/xui/en-us/panel_preferences_im.xml
index 9b18e11..582e230 100644
--- a/linden/indra/newview/skins/default/xui/en-us/panel_preferences_im.xml
+++ b/linden/indra/newview/skins/default/xui/en-us/panel_preferences_im.xml
@@ -62,8 +62,11 @@
62 <text_editor type="string" length="1" bottom_delta="-60" embedded_items="false" enabled="true" follows="left|top" 62 <text_editor type="string" length="1" bottom_delta="-60" embedded_items="false" enabled="true" follows="left|top"
63 font="SansSerifSmall" height="70" left="148" max_length="255" 63 font="SansSerifSmall" height="70" left="148" max_length="255"
64 mouse_opaque="true" name="busy_response" width="330" word_wrap="true" /> 64 mouse_opaque="true" name="busy_response" width="330" word_wrap="true" />
65 <button bottom_delta="-25" follows="top|right" height="22" label="IM Response Options"
66 left="164" name="busy_adv_btn" tool_tip="Auto response options"
67 width="180" />
65 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" 68 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
66 bottom_delta="-33" drop_shadow_visible="true" enabled="true" follows="left|top" 69 bottom_delta="-23" drop_shadow_visible="true" enabled="true" follows="left|top"
67 font="SansSerifSmall" h_pad="0" halign="left" height="10" left="12" 70 font="SansSerifSmall" h_pad="0" halign="left" height="10" left="12"
68 mouse_opaque="false" name="text_box4" v_pad="0" width="128"> 71 mouse_opaque="false" name="text_box4" v_pad="0" width="128">
69 Logging Options: 72 Logging Options:
@@ -100,7 +103,7 @@
100 name="log_date_timestamp" radio_style="false" width="237" /> 103 name="log_date_timestamp" radio_style="false" width="237" />
101 <button bottom_delta="-22" follows="right|bottom" font="SansSerif" halign="center" 104 <button bottom_delta="-22" follows="right|bottom" font="SansSerif" halign="center"
102 height="20" label="Change Path" label_selected="Change Path" left="170" 105 height="20" label="Change Path" label_selected="Change Path" left="170"
103 mouse_opaque="true" name="log_path_button" width="90" /> 106 mouse_opaque="true" name="log_path_button" width="96" />
104 <line_editor border_drop_shadow_visible="false" border_visible="false" bottom_delta="1" 107 <line_editor border_drop_shadow_visible="false" border_visible="false" bottom_delta="1"
105 drop_shadow_visible="true" enabled="false" follows="top|left|right" 108 drop_shadow_visible="true" enabled="false" follows="top|left|right"
106 font="SansSerifSmall" halign="right" height="19" left="248" 109 font="SansSerifSmall" halign="right" height="19" left="248"