00001
00032 #include "llviewerprecompiledheaders.h"
00033
00034 #include "llpanelgroupnotices.h"
00035
00036 #include "llview.h"
00037
00038 #include "llinventory.h"
00039 #include "llviewerinventory.h"
00040 #include "llinventorymodel.h"
00041 #include "llinventoryview.h"
00042 #include "llagent.h"
00043 #include "lltooldraganddrop.h"
00044
00045 #include "lllineeditor.h"
00046 #include "lltexteditor.h"
00047 #include "llbutton.h"
00048 #include "lliconctrl.h"
00049 #include "llcheckboxctrl.h"
00050 #include "llscrolllistctrl.h"
00051 #include "lltextbox.h"
00052
00053 #include "roles_constants.h"
00054 #include "llviewerwindow.h"
00055 #include "llviewermessage.h"
00056
00057 const S32 NOTICE_DATE_STRING_SIZE = 30;
00058
00060
00062
00063
00064
00065
00066
00067
00068
00069 class LLGroupDropTarget : public LLView
00070 {
00071 public:
00072 LLGroupDropTarget(const std::string& name, const LLRect& rect, LLPanelGroupNotices* panel, const LLUUID& group_id);
00073 ~LLGroupDropTarget() {};
00074
00075 void doDrop(EDragAndDropType cargo_type, void* cargo_data);
00076
00077
00078
00079 virtual EWidgetType getWidgetType() const;
00080 virtual LLString getWidgetTag() const;
00081 virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
00082 EDragAndDropType cargo_type,
00083 void* cargo_data,
00084 EAcceptance* accept,
00085 LLString& tooltip_msg);
00086 protected:
00087 LLPanelGroupNotices* mGroupNoticesPanel;
00088 LLUUID mGroupID;
00089 };
00090
00091 LLGroupDropTarget::LLGroupDropTarget(const std::string& name, const LLRect& rect,
00092 LLPanelGroupNotices* panel, const LLUUID& group_id) :
00093 LLView(name, rect, NOT_MOUSE_OPAQUE, FOLLOWS_ALL),
00094 mGroupNoticesPanel(panel),
00095 mGroupID(group_id)
00096 {
00097 }
00098
00099 EWidgetType LLGroupDropTarget::getWidgetType() const
00100 {
00101 return WIDGET_TYPE_DONTCARE;
00102 }
00103
00104 LLString LLGroupDropTarget::getWidgetTag() const
00105 {
00106 return LL_GROUP_DROP_TARGET_TAG;
00107 }
00108
00109 void LLGroupDropTarget::doDrop(EDragAndDropType cargo_type, void* cargo_data)
00110 {
00111 llinfos << "LLGroupDropTarget::doDrop()" << llendl;
00112 }
00113
00114 BOOL LLGroupDropTarget::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
00115 EDragAndDropType cargo_type,
00116 void* cargo_data,
00117 EAcceptance* accept,
00118 LLString& tooltip_msg)
00119 {
00120 BOOL handled = FALSE;
00121
00122 if (!gAgent.hasPowerInGroup(mGroupID,GP_NOTICES_SEND))
00123 {
00124 *accept = ACCEPT_NO;
00125 return TRUE;
00126 }
00127
00128 if(getParent())
00129 {
00130
00131
00132
00133 handled = TRUE;
00134
00135
00136 switch(cargo_type)
00137 {
00138 case DAD_TEXTURE:
00139 case DAD_SOUND:
00140 case DAD_LANDMARK:
00141 case DAD_SCRIPT:
00142 case DAD_OBJECT:
00143 case DAD_NOTECARD:
00144 case DAD_CLOTHING:
00145 case DAD_BODYPART:
00146 case DAD_ANIMATION:
00147 case DAD_GESTURE:
00148 {
00149 LLViewerInventoryItem* inv_item = (LLViewerInventoryItem*)cargo_data;
00150 if(gInventory.getItem(inv_item->getUUID())
00151 && LLToolDragAndDrop::isInventoryGroupGiveAcceptable(inv_item))
00152 {
00153
00154 *accept = ACCEPT_YES_COPY_SINGLE;
00155 if(drop)
00156 {
00157 mGroupNoticesPanel->setItem(inv_item);
00158 }
00159 }
00160 else
00161 {
00162
00163
00164
00165
00166 *accept = ACCEPT_NO;
00167 }
00168 break;
00169 }
00170 case DAD_CATEGORY:
00171 case DAD_CALLINGCARD:
00172 default:
00173 *accept = ACCEPT_NO;
00174 break;
00175 }
00176 }
00177 return handled;
00178 }
00179
00180
00181
00182
00183 char* build_notice_date(const time_t& the_time, char* buffer)
00184 {
00185 time_t t = the_time;
00186 if (!t) time(&t);
00187 tm* lt = localtime(&t);
00188
00189
00190 snprintf(buffer, NOTICE_DATE_STRING_SIZE, "%i/%i/%i", lt->tm_mon + 1, lt->tm_mday, lt->tm_year + 1900);
00191 return buffer;
00192 }
00193
00194 LLPanelGroupNotices::LLPanelGroupNotices(const std::string& name,
00195 const LLUUID& group_id) :
00196 LLPanelGroupTab(name,group_id),
00197 mInventoryItem(NULL),
00198 mInventoryOffer(NULL)
00199 {
00200 sInstances[group_id] = this;
00201 }
00202
00203 LLPanelGroupNotices::~LLPanelGroupNotices()
00204 {
00205 sInstances.erase(mGroupID);
00206
00207 if (mInventoryOffer)
00208 {
00209
00210 inventory_offer_callback( IOR_DECLINE , mInventoryOffer);
00211 mInventoryOffer = NULL;
00212 }
00213 }
00214
00215
00216 void* LLPanelGroupNotices::createTab(void* data)
00217 {
00218 LLUUID* group_id = static_cast<LLUUID*>(data);
00219 return new LLPanelGroupNotices("panel group notices", *group_id);
00220 }
00221
00222 BOOL LLPanelGroupNotices::isVisibleByAgent(LLAgent* agentp)
00223 {
00224 return mAllowEdit &&
00225 agentp->hasPowerInGroup(mGroupID, GP_NOTICES_SEND | GP_NOTICES_RECEIVE);
00226 }
00227
00228 BOOL LLPanelGroupNotices::postBuild()
00229 {
00230 bool recurse = true;
00231
00232 mNoticesList = (LLScrollListCtrl*)getChildByName("notice_list",recurse);
00233 mNoticesList->setCommitOnSelectionChange(TRUE);
00234 mNoticesList->setCommitCallback(onSelectNotice);
00235 mNoticesList->setCallbackUserData(this);
00236
00237 mBtnNewMessage = (LLButton*)getChildByName("create_new_notice",recurse);
00238 mBtnNewMessage->setClickedCallback(onClickNewMessage);
00239 mBtnNewMessage->setCallbackUserData(this);
00240 mBtnNewMessage->setEnabled(gAgent.hasPowerInGroup(mGroupID, GP_NOTICES_SEND));
00241
00242 mBtnGetPastNotices = (LLButton*)getChildByName("refresh_notices",recurse);
00243 mBtnGetPastNotices->setClickedCallback(onClickRefreshNotices);
00244 mBtnGetPastNotices->setCallbackUserData(this);
00245
00246
00247 mCreateSubject = (LLLineEditor*)getChildByName("create_subject",recurse);
00248 mCreateMessage = (LLTextEditor*)getChildByName("create_message",recurse);
00249
00250 mCreateInventoryName = (LLLineEditor*)getChildByName("create_inventory_name",recurse);
00251 mCreateInventoryName->setTabStop(FALSE);
00252 mCreateInventoryName->setEnabled(FALSE);
00253
00254 mCreateInventoryIcon = (LLIconCtrl*)getChildByName("create_inv_icon",recurse);
00255 mCreateInventoryIcon->setVisible(FALSE);
00256
00257 mBtnSendMessage = (LLButton*)getChildByName("send_notice",recurse);
00258 mBtnSendMessage->setClickedCallback(onClickSendMessage);
00259 mBtnSendMessage->setCallbackUserData(this);
00260
00261 mBtnRemoveAttachment = (LLButton*)getChildByName("remove_attachment",recurse);
00262 mBtnRemoveAttachment->setClickedCallback(onClickRemoveAttachment);
00263 mBtnRemoveAttachment->setCallbackUserData(this);
00264 mBtnRemoveAttachment->setEnabled(FALSE);
00265
00266
00267 mViewSubject = (LLLineEditor*)getChildByName("view_subject",recurse);
00268 mViewMessage = (LLTextEditor*)getChildByName("view_message",recurse);
00269
00270 mViewInventoryName = (LLLineEditor*)getChildByName("view_inventory_name",recurse);
00271 mViewInventoryName->setTabStop(FALSE);
00272 mViewInventoryName->setEnabled(FALSE);
00273
00274 mViewInventoryIcon = (LLIconCtrl*)getChildByName("view_inv_icon",recurse);
00275 mViewInventoryIcon->setVisible(FALSE);
00276
00277 mBtnOpenAttachment = (LLButton*)getChildByName("open_attachment",recurse);
00278 mBtnOpenAttachment->setClickedCallback(onClickOpenAttachment);
00279 mBtnOpenAttachment->setCallbackUserData(this);
00280
00281 LLTextBox *txt = (LLTextBox*) getChildByName("no_notices_text",false);
00282 if (txt)
00283 {
00284 mNoNoticesStr = txt->getText();
00285 removeChild(txt, TRUE);
00286 }
00287
00288 mPanelCreateNotice = (LLPanel*) getChildByName("panel_create_new_notice",recurse);
00289 mPanelViewNotice = (LLPanel*) getChildByName("panel_view_past_notice",recurse);
00290
00291
00292 LLPanel* dtv = (LLPanel*)getChildByName("drop_target",recurse);
00293 LLGroupDropTarget* target = new LLGroupDropTarget("drop_target",
00294 dtv->getRect(),
00295 this, mGroupID);
00296 target->setEnabled(TRUE);
00297 target->setToolTip(dtv->getToolTip());
00298
00299 mPanelCreateNotice->addChild(target);
00300 mPanelCreateNotice->removeChild(dtv, TRUE);
00301
00302 arrangeNoticeView(VIEW_PAST_NOTICE);
00303
00304 return LLPanelGroupTab::postBuild();
00305 }
00306
00307 void LLPanelGroupNotices::activate()
00308 {
00309 BOOL can_send = gAgent.hasPowerInGroup(mGroupID,GP_NOTICES_SEND);
00310 BOOL can_receive = gAgent.hasPowerInGroup(mGroupID,GP_NOTICES_RECEIVE);
00311
00312 mPanelViewNotice->setEnabled(can_receive);
00313 mPanelCreateNotice->setEnabled(can_send);
00314
00315
00316 mCreateInventoryName->setEnabled(FALSE);
00317 mViewInventoryName->setEnabled(FALSE);
00318
00319
00320 if (can_receive)
00321 {
00322 onClickRefreshNotices(this);
00323 }
00324 }
00325
00326 void LLPanelGroupNotices::setItem(LLPointer<LLInventoryItem> inv_item)
00327 {
00328 mInventoryItem = inv_item;
00329
00330 BOOL item_is_multi = FALSE;
00331 if ( inv_item->getFlags() & LLInventoryItem::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS )
00332 {
00333 item_is_multi = TRUE;
00334 };
00335
00336 LLViewerImage* item_icon = get_item_icon(inv_item->getType(),
00337 inv_item->getInventoryType(),
00338 inv_item->getFlags(),
00339 item_is_multi );
00340
00341 mCreateInventoryIcon->setImage(item_icon->getID());
00342 mCreateInventoryIcon->setVisible(TRUE);
00343
00344 std::stringstream ss;
00345 ss << " " << mInventoryItem->getName();
00346
00347 mCreateInventoryName->setText(ss.str());
00348 mBtnRemoveAttachment->setEnabled(TRUE);
00349 }
00350
00351 void LLPanelGroupNotices::onClickRemoveAttachment(void* data)
00352 {
00353 LLPanelGroupNotices* self = (LLPanelGroupNotices*)data;
00354 self->mInventoryItem = NULL;
00355 self->mCreateInventoryName->clear();
00356 self->mCreateInventoryIcon->setVisible(FALSE);
00357 self->mBtnRemoveAttachment->setEnabled(FALSE);
00358 }
00359
00360
00361 void LLPanelGroupNotices::onClickOpenAttachment(void* data)
00362 {
00363 LLPanelGroupNotices* self = (LLPanelGroupNotices*)data;
00364
00365 inventory_offer_callback( IOR_ACCEPT , self->mInventoryOffer);
00366 self->mInventoryOffer = NULL;
00367 self->mBtnOpenAttachment->setEnabled(FALSE);
00368 }
00369
00370 void LLPanelGroupNotices::onClickSendMessage(void* data)
00371 {
00372 LLPanelGroupNotices* self = (LLPanelGroupNotices*)data;
00373
00374 if (self->mCreateSubject->getText().empty())
00375 {
00376
00377 gViewerWindow->alertXml("MustSpecifyGroupNoticeSubject");
00378 return;
00379 }
00380 send_group_notice(
00381 self->mGroupID,
00382 self->mCreateSubject->getText().c_str(),
00383 self->mCreateMessage->getText().c_str(),
00384 self->mInventoryItem);
00385
00386 self->mCreateMessage->clear();
00387 self->mCreateSubject->clear();
00388 onClickRemoveAttachment(data);
00389
00390 self->arrangeNoticeView(VIEW_PAST_NOTICE);
00391 onClickRefreshNotices(self);
00392
00393 }
00394
00395
00396 void LLPanelGroupNotices::onClickNewMessage(void* data)
00397 {
00398 LLPanelGroupNotices* self = (LLPanelGroupNotices*)data;
00399
00400 self->arrangeNoticeView(CREATE_NEW_NOTICE);
00401
00402 if (self->mInventoryOffer)
00403 {
00404 inventory_offer_callback( IOR_DECLINE , self->mInventoryOffer);
00405 self->mInventoryOffer = NULL;
00406 }
00407
00408 self->mCreateSubject->clear();
00409 self->mCreateMessage->clear();
00410 if (self->mInventoryItem) onClickRemoveAttachment(self);
00411 self->mNoticesList->deselectAllItems(TRUE);
00412 }
00413
00414 void LLPanelGroupNotices::onClickRefreshNotices(void* data)
00415 {
00416 lldebugs << "LLPanelGroupNotices::onClickGetPastNotices" << llendl;
00417 LLPanelGroupNotices* self = (LLPanelGroupNotices*)data;
00418
00419 self->mNoticesList->deleteAllItems();
00420
00421 LLMessageSystem* msg = gMessageSystem;
00422 msg->newMessage("GroupNoticesListRequest");
00423 msg->nextBlock("AgentData");
00424 msg->addUUID("AgentID",gAgent.getID());
00425 msg->addUUID("SessionID",gAgent.getSessionID());
00426 msg->nextBlock("Data");
00427 msg->addUUID("GroupID",self->mGroupID);
00428 gAgent.sendReliableMessage();
00429 }
00430
00431
00432 std::map<LLUUID,LLPanelGroupNotices*> LLPanelGroupNotices::sInstances;
00433
00434
00435 void LLPanelGroupNotices::processGroupNoticesListReply(LLMessageSystem* msg, void** data)
00436 {
00437 LLUUID group_id;
00438 msg->getUUID("AgentData", "GroupID", group_id);
00439
00440 std::map<LLUUID,LLPanelGroupNotices*>::iterator it = sInstances.find(group_id);
00441 if (it == sInstances.end())
00442 {
00443 llinfos << "Group Panel Notices " << group_id << " no longer in existence."
00444 << llendl;
00445 return;
00446 }
00447
00448 LLPanelGroupNotices* selfp = it->second;
00449 if(!selfp)
00450 {
00451 llinfos << "Group Panel Notices " << group_id << " no longer in existence."
00452 << llendl;
00453 return;
00454 }
00455
00456 selfp->processNotices(msg);
00457 }
00458
00459 void LLPanelGroupNotices::processNotices(LLMessageSystem* msg)
00460 {
00461 LLUUID id;
00462 char subj[MAX_STRING];
00463 char name[MAX_STRING];
00464 U32 timestamp;
00465 BOOL has_attachment;
00466 U8 asset_type;
00467
00468 S32 i=0;
00469 S32 count = msg->getNumberOfBlocks("Data");
00470 for (;i<count;++i)
00471 {
00472 msg->getUUID("Data","NoticeID",id,i);
00473 if (1 == count && id.isNull())
00474 {
00475
00476 mNoticesList->addSimpleItem(mNoNoticesStr,ADD_BOTTOM,FALSE);
00477 mNoticesList->setEnabled(FALSE);
00478 return;
00479 }
00480
00481 msg->getString("Data","Subject",MAX_STRING,subj,i);
00482 msg->getString("Data","FromName",MAX_STRING,name,i);
00483 msg->getBOOL("Data","HasAttachment",has_attachment,i);
00484 msg->getU8("Data","AssetType",asset_type,i);
00485 msg->getU32("Data","Timestamp",timestamp,i);
00486 time_t t = timestamp;
00487
00488 LLSD row;
00489 row["id"] = id;
00490
00491 row["columns"][0]["column"] = "icon";
00492 if (has_attachment)
00493 {
00494 LLUUID icon_id = get_item_icon_uuid(
00495 (LLAssetType::EType)asset_type,
00496 LLInventoryType::IT_NONE,FALSE, FALSE);
00497 row["columns"][0]["type"] = "icon";
00498 row["columns"][0]["value"] = icon_id;
00499 }
00500
00501 row["columns"][1]["column"] = "subject";
00502 row["columns"][1]["value"] = subj;
00503
00504 row["columns"][2]["column"] = "from";
00505 row["columns"][2]["value"] = name;
00506
00507 char buffer[NOTICE_DATE_STRING_SIZE];
00508 build_notice_date(t, buffer);
00509 row["columns"][3]["column"] = "date";
00510 row["columns"][3]["value"] = buffer;
00511
00512 snprintf(buffer, 30, "%u", timestamp);
00513 row["columns"][4]["column"] = "sort";
00514 row["columns"][4]["value"] = buffer;
00515
00516 mNoticesList->addElement(row, ADD_SORTED);
00517 }
00518 }
00519
00520 void LLPanelGroupNotices::onSelectNotice(LLUICtrl* ctrl, void* data)
00521 {
00522 LLPanelGroupNotices* self = (LLPanelGroupNotices*)data;
00523
00524 if(!self) return;
00525 LLScrollListItem* item = self->mNoticesList->getFirstSelected();
00526 if (!item) return;
00527
00528 LLMessageSystem* msg = gMessageSystem;
00529 msg->newMessage("GroupNoticeRequest");
00530 msg->nextBlock("AgentData");
00531 msg->addUUID("AgentID",gAgent.getID());
00532 msg->addUUID("SessionID",gAgent.getSessionID());
00533 msg->nextBlock("Data");
00534 msg->addUUID("GroupNoticeID",item->getUUID());
00535 gAgent.sendReliableMessage();
00536
00537 lldebugs << "Item " << item->getUUID() << " selected." << llendl;
00538 }
00539
00540 void LLPanelGroupNotices::showNotice(const char* subject,
00541 const char* message,
00542 const bool& has_inventory,
00543 const char* inventory_name,
00544 LLOfferInfo* inventory_offer)
00545 {
00546 arrangeNoticeView(VIEW_PAST_NOTICE);
00547
00548 if(mViewSubject) mViewSubject->setText(LLString(subject));
00549 if(mViewMessage) mViewMessage->setText(LLString(message));
00550
00551 if (mInventoryOffer)
00552 {
00553
00554 inventory_offer_callback( IOR_DECLINE , mInventoryOffer);
00555 mInventoryOffer = NULL;
00556 }
00557
00558 if (inventory_offer)
00559 {
00560 mInventoryOffer = inventory_offer;
00561
00562 LLViewerImage* item_icon = get_item_icon(mInventoryOffer->mType,
00563 LLInventoryType::IT_TEXTURE,
00564 0, FALSE);
00565
00566 mViewInventoryIcon->setImage(item_icon->getID());
00567 mViewInventoryIcon->setVisible(TRUE);
00568
00569 std::stringstream ss;
00570 ss << " " << inventory_name;
00571
00572 mViewInventoryName->setText(ss.str());
00573 mBtnOpenAttachment->setEnabled(TRUE);
00574 }
00575 else
00576 {
00577 mViewInventoryName->clear();
00578 mViewInventoryIcon->setVisible(FALSE);
00579 mBtnOpenAttachment->setEnabled(FALSE);
00580 }
00581 }
00582
00583 void LLPanelGroupNotices::arrangeNoticeView(ENoticeView view_type)
00584 {
00585 if (CREATE_NEW_NOTICE == view_type)
00586 {
00587 mPanelCreateNotice->setVisible(TRUE);
00588 mPanelViewNotice->setVisible(FALSE);
00589 }
00590 else
00591 {
00592 mPanelCreateNotice->setVisible(FALSE);
00593 mPanelViewNotice->setVisible(TRUE);
00594 mBtnOpenAttachment->setEnabled(FALSE);
00595 }
00596 }