aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llpanelgroupnotices.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:44:46 -0500
committerJacek Antonelli2008-08-15 23:44:46 -0500
commit38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch)
treeadca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/newview/llpanelgroupnotices.cpp
parentREADME.txt (diff)
downloadmeta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.zip
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.gz
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.bz2
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.xz
Second Life viewer sources 1.13.2.12
Diffstat (limited to 'linden/indra/newview/llpanelgroupnotices.cpp')
-rw-r--r--linden/indra/newview/llpanelgroupnotices.cpp584
1 files changed, 584 insertions, 0 deletions
diff --git a/linden/indra/newview/llpanelgroupnotices.cpp b/linden/indra/newview/llpanelgroupnotices.cpp
new file mode 100644
index 0000000..b8b2f2c
--- /dev/null
+++ b/linden/indra/newview/llpanelgroupnotices.cpp
@@ -0,0 +1,584 @@
1/**
2 * @file llpanelgroupnotices.cpp
3 * @brief A panel to display group notices.
4 *
5 * Copyright (c) 2006-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#include "llviewerprecompiledheaders.h"
29
30#include "llpanelgroupnotices.h"
31
32#include "llview.h"
33
34#include "llinventory.h"
35#include "llviewerinventory.h"
36#include "llinventorymodel.h"
37#include "llinventoryview.h"
38#include "llagent.h"
39#include "lltooldraganddrop.h"
40
41#include "lllineeditor.h"
42#include "lltexteditor.h"
43#include "llbutton.h"
44#include "lliconctrl.h"
45#include "llcheckboxctrl.h"
46#include "llscrolllistctrl.h"
47#include "lltextbox.h"
48
49#include "roles_constants.h"
50#include "llviewerwindow.h"
51#include "llviewermessage.h"
52
53/////////////////////////
54// LLPanelGroupNotices //
55/////////////////////////
56//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
57// Class LLDropTarget
58//
59// This handy class is a simple way to drop something on another
60// view. It handles drop events, always setting itself to the size of
61// its parent.
62//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
63class LLGroupDropTarget : public LLView
64{
65public:
66 LLGroupDropTarget(const std::string& name, const LLRect& rect, LLPanelGroupNotices* panel, const LLUUID& group_id);
67 ~LLGroupDropTarget() {};
68
69 void doDrop(EDragAndDropType cargo_type, void* cargo_data);
70
71 //
72 // LLView functionality
73 virtual EWidgetType getWidgetType() const;
74 virtual LLString getWidgetTag() const;
75 virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
76 EDragAndDropType cargo_type,
77 void* cargo_data,
78 EAcceptance* accept,
79 LLString& tooltip_msg);
80protected:
81 LLPanelGroupNotices* mGroupNoticesPanel;
82 LLUUID mGroupID;
83};
84
85LLGroupDropTarget::LLGroupDropTarget(const std::string& name, const LLRect& rect,
86 LLPanelGroupNotices* panel, const LLUUID& group_id) :
87 LLView(name, rect, NOT_MOUSE_OPAQUE, FOLLOWS_ALL),
88 mGroupNoticesPanel(panel),
89 mGroupID(group_id)
90{
91}
92
93EWidgetType LLGroupDropTarget::getWidgetType() const
94{
95 return WIDGET_TYPE_DONTCARE;
96}
97
98LLString LLGroupDropTarget::getWidgetTag() const
99{
100 return LL_GROUP_DROP_TARGET_TAG;
101}
102
103void LLGroupDropTarget::doDrop(EDragAndDropType cargo_type, void* cargo_data)
104{
105 llinfos << "LLGroupDropTarget::doDrop()" << llendl;
106}
107
108BOOL LLGroupDropTarget::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
109 EDragAndDropType cargo_type,
110 void* cargo_data,
111 EAcceptance* accept,
112 LLString& tooltip_msg)
113{
114 BOOL handled = FALSE;
115
116 if (!gAgent.hasPowerInGroup(mGroupID,GP_NOTICES_SEND))
117 {
118 *accept = ACCEPT_NO;
119 return TRUE;
120 }
121
122 if(getParent())
123 {
124 // check if inside
125 //LLRect parent_rect = mParentView->getRect();
126 //mRect.set(0, parent_rect.getHeight(), parent_rect.getWidth(), 0);
127 handled = TRUE;
128
129 // check the type
130 switch(cargo_type)
131 {
132 case DAD_TEXTURE:
133 case DAD_SOUND:
134 case DAD_LANDMARK:
135 case DAD_SCRIPT:
136 case DAD_OBJECT:
137 case DAD_NOTECARD:
138 case DAD_CLOTHING:
139 case DAD_BODYPART:
140 case DAD_ANIMATION:
141 case DAD_GESTURE:
142 {
143 LLViewerInventoryItem* inv_item = (LLViewerInventoryItem*)cargo_data;
144 if(gInventory.getItem(inv_item->getUUID())
145 && LLToolDragAndDrop::isInventoryGroupGiveAcceptable(inv_item))
146 {
147 // *TODO: get multiple object transfers working
148 *accept = ACCEPT_YES_COPY_SINGLE;
149 if(drop)
150 {
151 mGroupNoticesPanel->setItem(inv_item);
152 }
153 }
154 else
155 {
156 // It's not in the user's inventory (it's probably
157 // in an object's contents), so disallow dragging
158 // it here. You can't give something you don't
159 // yet have.
160 *accept = ACCEPT_NO;
161 }
162 break;
163 }
164 case DAD_CATEGORY:
165 case DAD_CALLINGCARD:
166 default:
167 *accept = ACCEPT_NO;
168 break;
169 }
170 }
171 return handled;
172}
173
174//-----------------------------------------------------------------------------
175// LLPanelGroupNotices
176//-----------------------------------------------------------------------------
177char* build_notice_date(const time_t& the_time, char* buffer)
178{
179 time_t t = the_time;
180 if (!t) time(&t);
181 tm* lt = localtime(&t);
182 //for some reason, the month is off by 1. See other uses of
183 //"local" time in the code...
184 sprintf(buffer,"%i/%i/%i", lt->tm_mon + 1, lt->tm_mday, lt->tm_year + 1900);
185
186 return buffer;
187}
188
189LLPanelGroupNotices::LLPanelGroupNotices(const std::string& name,
190 const LLUUID& group_id) :
191 LLPanelGroupTab(name,group_id),
192 mInventoryItem(NULL),
193 mInventoryOffer(NULL)
194{
195 sInstances[group_id] = this;
196}
197
198LLPanelGroupNotices::~LLPanelGroupNotices()
199{
200 sInstances.erase(mGroupID);
201
202 if (mInventoryOffer)
203 {
204 // Cancel the inventory offer.
205 inventory_offer_callback( 1 , mInventoryOffer);
206 mInventoryOffer = NULL;
207 }
208}
209
210// static
211void* LLPanelGroupNotices::createTab(void* data)
212{
213 LLUUID* group_id = static_cast<LLUUID*>(data);
214 return new LLPanelGroupNotices("panel group notices", *group_id);
215}
216
217BOOL LLPanelGroupNotices::isVisibleByAgent(LLAgent* agentp)
218{
219 return mAllowEdit &&
220 agentp->hasPowerInGroup(mGroupID, GP_NOTICES_SEND | GP_NOTICES_RECEIVE);
221}
222
223BOOL LLPanelGroupNotices::postBuild()
224{
225 bool recurse = true;
226
227 mNoticesList = (LLScrollListCtrl*)getChildByName("notice_list",recurse);
228 mNoticesList->setCommitOnSelectionChange(TRUE);
229 mNoticesList->setCommitCallback(onSelectNotice);
230 mNoticesList->setCallbackUserData(this);
231
232 mBtnNewMessage = (LLButton*)getChildByName("create_new_notice",recurse);
233 mBtnNewMessage->setClickedCallback(onClickNewMessage);
234 mBtnNewMessage->setCallbackUserData(this);
235 mBtnNewMessage->setEnabled(gAgent.hasPowerInGroup(mGroupID, GP_NOTICES_SEND));
236
237 mBtnGetPastNotices = (LLButton*)getChildByName("refresh_notices",recurse);
238 mBtnGetPastNotices->setClickedCallback(onClickRefreshNotices);
239 mBtnGetPastNotices->setCallbackUserData(this);
240
241 // Create
242 mCreateSubject = (LLLineEditor*)getChildByName("create_subject",recurse);
243 mCreateMessage = (LLTextEditor*)getChildByName("create_message",recurse);
244
245 mCreateInventoryName = (LLLineEditor*)getChildByName("create_inventory_name",recurse);
246 mCreateInventoryName->setTabStop(FALSE);
247 mCreateInventoryName->setEnabled(FALSE);
248
249 mCreateInventoryIcon = (LLIconCtrl*)getChildByName("create_inv_icon",recurse);
250 mCreateInventoryIcon->setVisible(FALSE);
251
252 mBtnSendMessage = (LLButton*)getChildByName("send_notice",recurse);
253 mBtnSendMessage->setClickedCallback(onClickSendMessage);
254 mBtnSendMessage->setCallbackUserData(this);
255
256 mBtnRemoveAttachment = (LLButton*)getChildByName("remove_attachment",recurse);
257 mBtnRemoveAttachment->setClickedCallback(onClickRemoveAttachment);
258 mBtnRemoveAttachment->setCallbackUserData(this);
259 mBtnRemoveAttachment->setEnabled(FALSE);
260
261 // View
262 mViewSubject = (LLLineEditor*)getChildByName("view_subject",recurse);
263 mViewMessage = (LLTextEditor*)getChildByName("view_message",recurse);
264
265 mViewInventoryName = (LLLineEditor*)getChildByName("view_inventory_name",recurse);
266 mViewInventoryName->setTabStop(FALSE);
267 mViewInventoryName->setEnabled(FALSE);
268
269 mViewInventoryIcon = (LLIconCtrl*)getChildByName("view_inv_icon",recurse);
270 mViewInventoryIcon->setVisible(FALSE);
271
272 mBtnOpenAttachment = (LLButton*)getChildByName("open_attachment",recurse);
273 mBtnOpenAttachment->setClickedCallback(onClickOpenAttachment);
274 mBtnOpenAttachment->setCallbackUserData(this);
275
276 LLTextBox *txt = (LLTextBox*) getChildByName("no_notices_text",false);
277 if (txt)
278 {
279 mNoNoticesStr = txt->getText();
280 removeChild(txt);
281 }
282
283 mPanelCreateNotice = (LLPanel*) getChildByName("panel_create_new_notice",recurse);
284 mPanelViewNotice = (LLPanel*) getChildByName("panel_view_past_notice",recurse);
285
286 // Must be in front of all other UI elements.
287 LLPanel* dtv = (LLPanel*)getChildByName("drop_target",recurse);
288 LLGroupDropTarget* target = new LLGroupDropTarget("drop_target",
289 dtv->getRect(),
290 this, mGroupID);
291 target->setEnabled(TRUE);
292 target->setToolTip(dtv->getToolTip());
293
294 mPanelCreateNotice->addChild(target);
295 mPanelCreateNotice->removeChild(dtv);
296
297 arrangeNoticeView(VIEW_PAST_NOTICE);
298
299 return LLPanelGroupTab::postBuild();
300}
301
302void LLPanelGroupNotices::activate()
303{
304 BOOL can_send = gAgent.hasPowerInGroup(mGroupID,GP_NOTICES_SEND);
305 BOOL can_receive = gAgent.hasPowerInGroup(mGroupID,GP_NOTICES_RECEIVE);
306
307 mPanelViewNotice->setEnabled(can_receive);
308 mPanelCreateNotice->setEnabled(can_send);
309
310 // Always disabled to stop direct editing of attachment names
311 mCreateInventoryName->setEnabled(FALSE);
312 mViewInventoryName->setEnabled(FALSE);
313
314 // If we can receive notices, grab them right away.
315 if (can_receive)
316 {
317 onClickRefreshNotices(this);
318 }
319}
320
321void LLPanelGroupNotices::setItem(LLPointer<LLInventoryItem> inv_item)
322{
323 mInventoryItem = inv_item;
324
325 LLViewerImage* item_icon = get_item_icon(inv_item->getType(),
326 inv_item->getInventoryType(),
327 inv_item->getFlags());
328
329 mCreateInventoryIcon->setImage(item_icon->getID());
330 mCreateInventoryIcon->setVisible(TRUE);
331
332 std::stringstream ss;
333 ss << " " << mInventoryItem->getName();
334
335 mCreateInventoryName->setText(ss.str());
336 mBtnRemoveAttachment->setEnabled(TRUE);
337}
338
339void LLPanelGroupNotices::onClickRemoveAttachment(void* data)
340{
341 LLPanelGroupNotices* self = (LLPanelGroupNotices*)data;
342 self->mInventoryItem = NULL;
343 self->mCreateInventoryName->clear();
344 self->mCreateInventoryIcon->setVisible(FALSE);
345 self->mBtnRemoveAttachment->setEnabled(FALSE);
346}
347
348//static
349void LLPanelGroupNotices::onClickOpenAttachment(void* data)
350{
351 LLPanelGroupNotices* self = (LLPanelGroupNotices*)data;
352
353 inventory_offer_callback( 0 , self->mInventoryOffer);
354 self->mInventoryOffer = NULL;
355 self->mBtnOpenAttachment->setEnabled(FALSE);
356}
357
358void LLPanelGroupNotices::onClickSendMessage(void* data)
359{
360 LLPanelGroupNotices* self = (LLPanelGroupNotices*)data;
361
362 if (self->mCreateSubject->getText().empty())
363 {
364 // Must supply a subject
365 gViewerWindow->alertXml("MustSpecifyGroupNoticeSubject");
366 return;
367 }
368 send_group_notice(
369 self->mGroupID,
370 self->mCreateSubject->getText().c_str(),
371 self->mCreateMessage->getText().c_str(),
372 self->mInventoryItem);
373
374 self->mCreateMessage->clear();
375 self->mCreateSubject->clear();
376 onClickRemoveAttachment(data);
377
378 self->arrangeNoticeView(VIEW_PAST_NOTICE);
379 onClickRefreshNotices(self);
380
381}
382
383//static
384void LLPanelGroupNotices::onClickNewMessage(void* data)
385{
386 LLPanelGroupNotices* self = (LLPanelGroupNotices*)data;
387
388 self->arrangeNoticeView(CREATE_NEW_NOTICE);
389
390 if (self->mInventoryOffer)
391 {
392 inventory_offer_callback( 1 , self->mInventoryOffer);
393 self->mInventoryOffer = NULL;
394 }
395
396 self->mCreateSubject->clear();
397 self->mCreateMessage->clear();
398 if (self->mInventoryItem) onClickRemoveAttachment(self);
399 self->mNoticesList->deselectAllItems(TRUE); // TRUE == don't commit on chnage
400}
401
402void LLPanelGroupNotices::onClickRefreshNotices(void* data)
403{
404 lldebugs << "LLPanelGroupNotices::onClickGetPastNotices" << llendl;
405 LLPanelGroupNotices* self = (LLPanelGroupNotices*)data;
406
407 self->mNoticesList->deleteAllItems();
408
409 LLMessageSystem* msg = gMessageSystem;
410 msg->newMessage("GroupNoticesListRequest");
411 msg->nextBlock("AgentData");
412 msg->addUUID("AgentID",gAgent.getID());
413 msg->addUUID("SessionID",gAgent.getSessionID());
414 msg->nextBlock("Data");
415 msg->addUUID("GroupID",self->mGroupID);
416 gAgent.sendReliableMessage();
417}
418
419//static
420std::map<LLUUID,LLPanelGroupNotices*> LLPanelGroupNotices::sInstances;
421
422// static
423void LLPanelGroupNotices::processGroupNoticesListReply(LLMessageSystem* msg, void** data)
424{
425 LLUUID group_id;
426 msg->getUUID("AgentData", "GroupID", group_id);
427
428 std::map<LLUUID,LLPanelGroupNotices*>::iterator it = sInstances.find(group_id);
429 if (it == sInstances.end())
430 {
431 llinfos << "Group Panel Notices " << group_id << " no longer in existence."
432 << llendl;
433 return;
434 }
435
436 LLPanelGroupNotices* selfp = it->second;
437 if(!selfp)
438 {
439 llinfos << "Group Panel Notices " << group_id << " no longer in existence."
440 << llendl;
441 return;
442 }
443
444 selfp->processNotices(msg);
445}
446
447void LLPanelGroupNotices::processNotices(LLMessageSystem* msg)
448{
449 LLUUID id;
450 char subj[MAX_STRING];
451 char name[MAX_STRING];
452 U32 timestamp;
453 BOOL has_attachment;
454 U8 asset_type;
455
456 S32 i=0;
457 S32 count = msg->getNumberOfBlocks("Data");
458 for (;i<count;++i)
459 {
460 msg->getUUID("Data","NoticeID",id,i);
461 if (1 == count && id.isNull())
462 {
463 // Only one entry, the dummy entry.
464 mNoticesList->addSimpleItem(mNoNoticesStr,ADD_BOTTOM,FALSE);
465 mNoticesList->setEnabled(FALSE);
466 return;
467 }
468
469 msg->getString("Data","Subject",MAX_STRING,subj,i);
470 msg->getString("Data","FromName",MAX_STRING,name,i);
471 msg->getBOOL("Data","HasAttachment",has_attachment,i);
472 msg->getU8("Data","AssetType",asset_type,i);
473 msg->getU32("Data","Timestamp",timestamp,i);
474 time_t t = timestamp;
475
476 LLSD row;
477 row["id"] = id;
478
479 row["columns"][0]["column"] = "icon";
480 if (has_attachment)
481 {
482 LLUUID icon_id = get_item_icon_uuid(
483 (LLAssetType::EType)asset_type,
484 LLInventoryType::IT_NONE,FALSE);
485 row["columns"][0]["type"] = "icon";
486 row["columns"][0]["value"] = icon_id;
487 }
488
489 row["columns"][1]["column"] = "subject";
490 row["columns"][1]["value"] = subj;
491
492 row["columns"][2]["column"] = "from";
493 row["columns"][2]["value"] = name;
494
495 char buffer[30];
496 build_notice_date(t, buffer);
497 row["columns"][3]["column"] = "date";
498 row["columns"][3]["value"] = buffer;
499
500 snprintf(buffer, 30, "%u", timestamp);
501 row["columns"][4]["column"] = "sort";
502 row["columns"][4]["value"] = buffer;
503
504 mNoticesList->addElement(row, ADD_SORTED);
505 }
506}
507
508void LLPanelGroupNotices::onSelectNotice(LLUICtrl* ctrl, void* data)
509{
510 LLPanelGroupNotices* self = (LLPanelGroupNotices*)data;
511
512 if(!self) return;
513 LLScrollListItem* item = self->mNoticesList->getFirstSelected();
514 if (!item) return;
515
516 LLMessageSystem* msg = gMessageSystem;
517 msg->newMessage("GroupNoticeRequest");
518 msg->nextBlock("AgentData");
519 msg->addUUID("AgentID",gAgent.getID());
520 msg->addUUID("SessionID",gAgent.getSessionID());
521 msg->nextBlock("Data");
522 msg->addUUID("GroupNoticeID",item->getUUID());
523 gAgent.sendReliableMessage();
524
525 lldebugs << "Item " << item->getUUID().getString().c_str() << " selected." << llendl;
526}
527
528void LLPanelGroupNotices::showNotice(const char* subject,
529 const char* message,
530 const bool& has_inventory,
531 const char* inventory_name,
532 LLOfferInfo* inventory_offer)
533{
534 arrangeNoticeView(VIEW_PAST_NOTICE);
535
536 if(mViewSubject) mViewSubject->setText(subject);
537 if(mViewMessage) mViewMessage->setText(message);
538
539 if (mInventoryOffer)
540 {
541 // Cancel the inventory offer for the previously viewed notice
542 inventory_offer_callback( 1 , mInventoryOffer);
543 mInventoryOffer = NULL;
544 }
545
546 if (inventory_offer)
547 {
548 mInventoryOffer = inventory_offer;
549
550 LLViewerImage* item_icon = get_item_icon(mInventoryOffer->mType,
551 LLInventoryType::IT_TEXTURE,
552 0);
553
554 mViewInventoryIcon->setImage(item_icon->getID());
555 mViewInventoryIcon->setVisible(TRUE);
556
557 std::stringstream ss;
558 ss << " " << inventory_name;
559
560 mViewInventoryName->setText(ss.str());
561 mBtnOpenAttachment->setEnabled(TRUE);
562 }
563 else
564 {
565 mViewInventoryName->clear();
566 mViewInventoryIcon->setVisible(FALSE);
567 mBtnOpenAttachment->setEnabled(FALSE);
568 }
569}
570
571void LLPanelGroupNotices::arrangeNoticeView(ENoticeView view_type)
572{
573 if (CREATE_NEW_NOTICE == view_type)
574 {
575 mPanelCreateNotice->setVisible(TRUE);
576 mPanelViewNotice->setVisible(FALSE);
577 }
578 else
579 {
580 mPanelCreateNotice->setVisible(FALSE);
581 mPanelViewNotice->setVisible(TRUE);
582 mBtnOpenAttachment->setEnabled(FALSE);
583 }
584}