llpanelgroupnotices.cpp

Go to the documentation of this file.
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 // LLPanelGroupNotices //
00062 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00063 // Class LLDropTarget
00064 //
00065 // This handy class is a simple way to drop something on another
00066 // view. It handles drop events, always setting itself to the size of
00067 // its parent.
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         // LLView functionality
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                 // check if inside
00119                 //LLRect parent_rect = mParentView->getRect();
00120                 //getRect().set(0, parent_rect.getHeight(), parent_rect.getWidth(), 0);
00121                 handled = TRUE;
00122 
00123                 // check the type
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                                 // *TODO: get multiple object transfers working
00142                                 *accept = ACCEPT_YES_COPY_SINGLE;
00143                                 if(drop)
00144                                 {
00145                                         mGroupNoticesPanel->setItem(inv_item);
00146                                 }
00147                         }
00148                         else
00149                         {
00150                                 // It's not in the user's inventory (it's probably
00151                                 // in an object's contents), so disallow dragging
00152                                 // it here.  You can't give something you don't
00153                                 // yet have.
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 // LLPanelGroupNotices
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         //for some reason, the month is off by 1.  See other uses of
00177         //"local" time in the code...
00178         snprintf(buffer, NOTICE_DATE_STRING_SIZE, "%i/%i/%i", lt->tm_mon + 1, lt->tm_mday, lt->tm_year + 1900);         /*Flawfinder: ignore*/
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                 // Cancel the inventory offer.
00198                 inventory_offer_callback( IOR_DECLINE , mInventoryOffer); 
00199                 mInventoryOffer = NULL;
00200         }
00201 }
00202 
00203 // static
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         // Create
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         // View
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         // Must be in front of all other UI elements.
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         // Always disabled to stop direct editing of attachment names
00299         mCreateInventoryName->setEnabled(FALSE);
00300         mViewInventoryName->setEnabled(FALSE);
00301 
00302         // If we can receive notices, grab them right away.
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 //static 
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                 // Must supply a subject
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 //static 
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); // TRUE == don't commit on chnage
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 //static
00415 std::map<LLUUID,LLPanelGroupNotices*> LLPanelGroupNotices::sInstances;
00416 
00417 // static
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];          /*Flawfinder: ignore*/
00446         char name[MAX_STRING];          /*Flawfinder: ignore*/
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                         // Only one entry, the dummy entry.
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];           /*Flawfinder: ignore*/
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);                  /* Flawfinder: ignore */
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                 // Cancel the inventory offer for the previously viewed notice
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 }

Generated on Fri May 16 08:33:53 2008 for SecondLife by  doxygen 1.5.5