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