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 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                 // check if inside
00131                 //LLRect parent_rect = mParentView->getRect();
00132                 //mRect.set(0, parent_rect.getHeight(), parent_rect.getWidth(), 0);
00133                 handled = TRUE;
00134 
00135                 // check the type
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                                 // *TODO: get multiple object transfers working
00154                                 *accept = ACCEPT_YES_COPY_SINGLE;
00155                                 if(drop)
00156                                 {
00157                                         mGroupNoticesPanel->setItem(inv_item);
00158                                 }
00159                         }
00160                         else
00161                         {
00162                                 // It's not in the user's inventory (it's probably
00163                                 // in an object's contents), so disallow dragging
00164                                 // it here.  You can't give something you don't
00165                                 // yet have.
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 // LLPanelGroupNotices
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         //for some reason, the month is off by 1.  See other uses of
00189         //"local" time in the code...
00190         snprintf(buffer, NOTICE_DATE_STRING_SIZE, "%i/%i/%i", lt->tm_mon + 1, lt->tm_mday, lt->tm_year + 1900);         /*Flawfinder: ignore*/
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                 // Cancel the inventory offer.
00210                 inventory_offer_callback( IOR_DECLINE , mInventoryOffer); 
00211                 mInventoryOffer = NULL;
00212         }
00213 }
00214 
00215 // static
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         // Create
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         // View
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         // Must be in front of all other UI elements.
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         // Always disabled to stop direct editing of attachment names
00316         mCreateInventoryName->setEnabled(FALSE);
00317         mViewInventoryName->setEnabled(FALSE);
00318 
00319         // If we can receive notices, grab them right away.
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 //static 
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                 // Must supply a subject
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 //static 
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); // TRUE == don't commit on chnage
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 //static
00432 std::map<LLUUID,LLPanelGroupNotices*> LLPanelGroupNotices::sInstances;
00433 
00434 // static
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];          /*Flawfinder: ignore*/
00463         char name[MAX_STRING];          /*Flawfinder: ignore*/
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                         // Only one entry, the dummy entry.
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];           /*Flawfinder: ignore*/
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);                  /* Flawfinder: ignore */
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                 // Cancel the inventory offer for the previously viewed notice
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 }

Generated on Thu Jul 1 06:08:57 2010 for Second Life Viewer by  doxygen 1.4.7