summaryrefslogtreecommitdiff
path: root/indra/newview/llpanelgroupnotices.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llpanelgroupnotices.cpp')
-rw-r--r--indra/newview/llpanelgroupnotices.cpp565
1 files changed, 565 insertions, 0 deletions
diff --git a/indra/newview/llpanelgroupnotices.cpp b/indra/newview/llpanelgroupnotices.cpp
new file mode 100644
index 0000000000..9f774db2e9
--- /dev/null
+++ b/indra/newview/llpanelgroupnotices.cpp
@@ -0,0 +1,565 @@
+/**
+ * @file llpanelgroupnotices.cpp
+ * @brief A panel to display group notices.
+ *
+ * Copyright (c) 2006-$CurrentYear$, Linden Research, Inc.
+ * $License$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llpanelgroupnotices.h"
+
+#include "llview.h"
+
+#include "llinventory.h"
+#include "llviewerinventory.h"
+#include "llinventorymodel.h"
+#include "llinventoryview.h"
+#include "llagent.h"
+#include "lltooldraganddrop.h"
+
+#include "lllineeditor.h"
+#include "lltexteditor.h"
+#include "llbutton.h"
+#include "lliconctrl.h"
+#include "llcheckboxctrl.h"
+#include "llscrolllistctrl.h"
+#include "lltextbox.h"
+
+#include "roles_constants.h"
+#include "llviewerwindow.h"
+#include "llviewermessage.h"
+
+/////////////////////////
+// LLPanelGroupNotices //
+/////////////////////////
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLDropTarget
+//
+// This handy class is a simple way to drop something on another
+// view. It handles drop events, always setting itself to the size of
+// its parent.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+class LLGroupDropTarget : public LLView
+{
+public:
+ LLGroupDropTarget(const std::string& name, const LLRect& rect, LLPanelGroupNotices* panel, const LLUUID& group_id);
+ ~LLGroupDropTarget() {};
+
+ void doDrop(EDragAndDropType cargo_type, void* cargo_data);
+
+ //
+ // LLView functionality
+ virtual EWidgetType getWidgetType() const;
+ virtual LLString getWidgetTag() const;
+ virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ LLString& tooltip_msg);
+protected:
+ LLPanelGroupNotices* mGroupNoticesPanel;
+ LLUUID mGroupID;
+};
+
+LLGroupDropTarget::LLGroupDropTarget(const std::string& name, const LLRect& rect,
+ LLPanelGroupNotices* panel, const LLUUID& group_id) :
+ LLView(name, rect, NOT_MOUSE_OPAQUE, FOLLOWS_ALL),
+ mGroupNoticesPanel(panel),
+ mGroupID(group_id)
+{
+}
+
+EWidgetType LLGroupDropTarget::getWidgetType() const
+{
+ return WIDGET_TYPE_DONTCARE;
+}
+
+LLString LLGroupDropTarget::getWidgetTag() const
+{
+ return LL_GROUP_DROP_TARGET_TAG;
+}
+
+void LLGroupDropTarget::doDrop(EDragAndDropType cargo_type, void* cargo_data)
+{
+ llinfos << "LLGroupDropTarget::doDrop()" << llendl;
+}
+
+BOOL LLGroupDropTarget::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ LLString& tooltip_msg)
+{
+ BOOL handled = FALSE;
+
+ if (!gAgent.hasPowerInGroup(mGroupID,GP_NOTICES_SEND))
+ {
+ *accept = ACCEPT_NO;
+ return TRUE;
+ }
+
+ if(getParent())
+ {
+ // check if inside
+ //LLRect parent_rect = mParentView->getRect();
+ //mRect.set(0, parent_rect.getHeight(), parent_rect.getWidth(), 0);
+ handled = TRUE;
+
+ // check the type
+ switch(cargo_type)
+ {
+ case DAD_TEXTURE:
+ case DAD_SOUND:
+ case DAD_LANDMARK:
+ case DAD_SCRIPT:
+ case DAD_OBJECT:
+ case DAD_NOTECARD:
+ case DAD_CLOTHING:
+ case DAD_BODYPART:
+ case DAD_ANIMATION:
+ case DAD_GESTURE:
+ {
+ LLViewerInventoryItem* inv_item = (LLViewerInventoryItem*)cargo_data;
+ if(gInventory.getItem(inv_item->getUUID())
+ && LLToolDragAndDrop::isInventoryGroupGiveAcceptable(inv_item))
+ {
+ //FIXME: get multiple object transfers working
+ *accept = ACCEPT_YES_COPY_SINGLE;
+ if(drop)
+ {
+ mGroupNoticesPanel->setItem(inv_item);
+ }
+ }
+ else
+ {
+ // It's not in the user's inventory (it's probably
+ // in an object's contents), so disallow dragging
+ // it here. You can't give something you don't
+ // yet have.
+ *accept = ACCEPT_NO;
+ }
+ break;
+ }
+ case DAD_CATEGORY:
+ case DAD_CALLINGCARD:
+ default:
+ *accept = ACCEPT_NO;
+ break;
+ }
+ }
+ return handled;
+}
+
+//-----------------------------------------------------------------------------
+// LLPanelGroupNotices
+//-----------------------------------------------------------------------------
+char* build_notice_date(const time_t& the_time, char* buffer)
+{
+ time_t t = the_time;
+ if (!t) time(&t);
+ tm* lt = localtime(&t);
+ //for some reason, the month is off by 1. See other uses of
+ //"local" time in the code...
+ sprintf(buffer,"%i/%i/%i", lt->tm_mon + 1, lt->tm_mday, lt->tm_year + 1900);
+
+ return buffer;
+}
+
+LLPanelGroupNotices::LLPanelGroupNotices(const std::string& name,
+ const LLUUID& group_id) :
+ LLPanelGroupTab(name,group_id),
+ mInventoryItem(NULL),
+ mInventoryOffer(NULL)
+{
+ sInstances[group_id] = this;
+}
+
+LLPanelGroupNotices::~LLPanelGroupNotices()
+{
+ sInstances.erase(mGroupID);
+
+ if (mInventoryOffer)
+ {
+ // Cancel the inventory offer.
+ inventory_offer_callback( 1 , mInventoryOffer);
+ mInventoryOffer = NULL;
+ }
+}
+
+// static
+void* LLPanelGroupNotices::createTab(void* data)
+{
+ LLUUID* group_id = static_cast<LLUUID*>(data);
+ return new LLPanelGroupNotices("panel group notices", *group_id);
+}
+
+BOOL LLPanelGroupNotices::isVisibleByAgent(LLAgent* agentp)
+{
+ return mAllowEdit &&
+ agentp->hasPowerInGroup(mGroupID, GP_NOTICES_SEND | GP_NOTICES_RECEIVE);
+}
+
+BOOL LLPanelGroupNotices::postBuild()
+{
+ bool recurse = true;
+
+ mNoticesList = (LLScrollListCtrl*)getChildByName("notice_list",recurse);
+ mNoticesList->setCommitOnSelectionChange(TRUE);
+ mNoticesList->setCommitCallback(onSelectNotice);
+ mNoticesList->setCallbackUserData(this);
+
+ mBtnNewMessage = (LLButton*)getChildByName("create_new_notice",recurse);
+ mBtnNewMessage->setClickedCallback(onClickNewMessage);
+ mBtnNewMessage->setCallbackUserData(this);
+ mBtnNewMessage->setEnabled(gAgent.hasPowerInGroup(mGroupID, GP_NOTICES_SEND));
+
+ mBtnGetPastNotices = (LLButton*)getChildByName("refresh_notices",recurse);
+ mBtnGetPastNotices->setClickedCallback(onClickRefreshNotices);
+ mBtnGetPastNotices->setCallbackUserData(this);
+
+ // Create
+ mCreateSubject = (LLLineEditor*)getChildByName("create_subject",recurse);
+ mCreateMessage = (LLTextEditor*)getChildByName("create_message",recurse);
+
+ mCreateInventoryName = (LLLineEditor*)getChildByName("create_inventory_name",recurse);
+ mCreateInventoryName->setTabStop(FALSE);
+ mCreateInventoryName->setEnabled(FALSE);
+
+ mCreateInventoryIcon = (LLIconCtrl*)getChildByName("create_inv_icon",recurse);
+ mCreateInventoryIcon->setVisible(FALSE);
+
+ mBtnSendMessage = (LLButton*)getChildByName("send_notice",recurse);
+ mBtnSendMessage->setClickedCallback(onClickSendMessage);
+ mBtnSendMessage->setCallbackUserData(this);
+
+ mBtnRemoveAttachment = (LLButton*)getChildByName("remove_attachment",recurse);
+ mBtnRemoveAttachment->setClickedCallback(onClickRemoveAttachment);
+ mBtnRemoveAttachment->setCallbackUserData(this);
+ mBtnRemoveAttachment->setEnabled(FALSE);
+
+ // View
+ mViewSubject = (LLLineEditor*)getChildByName("view_subject",recurse);
+ mViewMessage = (LLTextEditor*)getChildByName("view_message",recurse);
+
+ mViewInventoryName = (LLLineEditor*)getChildByName("view_inventory_name",recurse);
+ mViewInventoryName->setTabStop(FALSE);
+ mViewInventoryName->setEnabled(FALSE);
+
+ mViewInventoryIcon = (LLIconCtrl*)getChildByName("view_inv_icon",recurse);
+ mViewInventoryIcon->setVisible(FALSE);
+
+ mBtnOpenAttachment = (LLButton*)getChildByName("open_attachment",recurse);
+ mBtnOpenAttachment->setClickedCallback(onClickOpenAttachment);
+ mBtnOpenAttachment->setCallbackUserData(this);
+
+ LLTextBox *txt = (LLTextBox*) getChildByName("no_notices_text",false);
+ if (txt)
+ {
+ mNoNoticesStr = txt->getText();
+ removeChild(txt);
+ }
+
+ mPanelCreateNotice = (LLPanel*) getChildByName("panel_create_new_notice",recurse);
+ mPanelViewNotice = (LLPanel*) getChildByName("panel_view_past_notice",recurse);
+
+ // Must be in front of all other UI elements.
+ LLPanel* dtv = (LLPanel*)getChildByName("drop_target",recurse);
+ LLGroupDropTarget* target = new LLGroupDropTarget("drop_target",
+ dtv->getRect(),
+ this, mGroupID);
+ target->setEnabled(TRUE);
+ target->setToolTip(dtv->getToolTip());
+
+ mPanelCreateNotice->addChild(target);
+ mPanelCreateNotice->removeChild(dtv);
+
+ arrangeNoticeView(VIEW_PAST_NOTICE);
+
+ return LLPanelGroupTab::postBuild();
+}
+
+void LLPanelGroupNotices::activate()
+{
+ BOOL can_send = gAgent.hasPowerInGroup(mGroupID,GP_NOTICES_SEND);
+ BOOL can_receive = gAgent.hasPowerInGroup(mGroupID,GP_NOTICES_RECEIVE);
+
+ mPanelViewNotice->setEnabled(can_receive);
+ mPanelCreateNotice->setEnabled(can_send);
+
+ // Always disabled to stop direct editing of attachment names
+ mCreateInventoryName->setEnabled(FALSE);
+ mViewInventoryName->setEnabled(FALSE);
+
+ // If we can receive notices, grab them right away.
+ if (can_receive)
+ {
+ onClickRefreshNotices(this);
+ }
+}
+
+void LLPanelGroupNotices::setItem(LLPointer<LLInventoryItem> inv_item)
+{
+ mInventoryItem = inv_item;
+
+ LLViewerImage* item_icon = get_item_icon(inv_item->getType(),
+ inv_item->getInventoryType(),
+ inv_item->getFlags());
+
+ mCreateInventoryIcon->setImage(item_icon->getID());
+ mCreateInventoryIcon->setVisible(TRUE);
+
+ std::stringstream ss;
+ ss << " " << mInventoryItem->getName();
+
+ mCreateInventoryName->setText(ss.str());
+ mBtnRemoveAttachment->setEnabled(TRUE);
+}
+
+void LLPanelGroupNotices::onClickRemoveAttachment(void* data)
+{
+ LLPanelGroupNotices* self = (LLPanelGroupNotices*)data;
+ self->mInventoryItem = NULL;
+ self->mCreateInventoryName->clear();
+ self->mCreateInventoryIcon->setVisible(FALSE);
+ self->mBtnRemoveAttachment->setEnabled(FALSE);
+}
+
+//static
+void LLPanelGroupNotices::onClickOpenAttachment(void* data)
+{
+ LLPanelGroupNotices* self = (LLPanelGroupNotices*)data;
+
+ inventory_offer_callback( 0 , self->mInventoryOffer);
+ self->mInventoryOffer = NULL;
+ self->mBtnOpenAttachment->setEnabled(FALSE);
+}
+
+void LLPanelGroupNotices::onClickSendMessage(void* data)
+{
+ LLPanelGroupNotices* self = (LLPanelGroupNotices*)data;
+
+ if (self->mCreateSubject->getText().empty())
+ {
+ // Must supply a subject
+ gViewerWindow->alertXml("MustSpecifyGroupNoticeSubject");
+ return;
+ }
+ send_group_notice(
+ self->mGroupID,
+ self->mCreateSubject->getText().c_str(),
+ self->mCreateMessage->getText().c_str(),
+ self->mInventoryItem);
+
+ self->mCreateMessage->clear();
+ self->mCreateSubject->clear();
+ onClickRemoveAttachment(data);
+
+ self->arrangeNoticeView(VIEW_PAST_NOTICE);
+ onClickRefreshNotices(self);
+
+}
+
+//static
+void LLPanelGroupNotices::onClickNewMessage(void* data)
+{
+ LLPanelGroupNotices* self = (LLPanelGroupNotices*)data;
+
+ self->arrangeNoticeView(CREATE_NEW_NOTICE);
+
+ if (self->mInventoryOffer)
+ {
+ inventory_offer_callback( 1 , self->mInventoryOffer);
+ self->mInventoryOffer = NULL;
+ }
+
+ self->mCreateSubject->clear();
+ self->mCreateMessage->clear();
+ if (self->mInventoryItem) onClickRemoveAttachment(self);
+ self->mNoticesList->deselectAllItems(TRUE); // TRUE == don't commit on chnage
+}
+
+void LLPanelGroupNotices::onClickRefreshNotices(void* data)
+{
+ lldebugs << "LLPanelGroupNotices::onClickGetPastNotices" << llendl;
+ LLPanelGroupNotices* self = (LLPanelGroupNotices*)data;
+
+ self->mNoticesList->deleteAllItems();
+
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessage("GroupNoticesListRequest");
+ msg->nextBlock("AgentData");
+ msg->addUUID("AgentID",gAgent.getID());
+ msg->addUUID("SessionID",gAgent.getSessionID());
+ msg->nextBlock("Data");
+ msg->addUUID("GroupID",self->mGroupID);
+ gAgent.sendReliableMessage();
+}
+
+//static
+std::map<LLUUID,LLPanelGroupNotices*> LLPanelGroupNotices::sInstances;
+
+// static
+void LLPanelGroupNotices::processGroupNoticesListReply(LLMessageSystem* msg, void** data)
+{
+ LLUUID group_id;
+ msg->getUUID("AgentData", "GroupID", group_id);
+
+ std::map<LLUUID,LLPanelGroupNotices*>::iterator it = sInstances.find(group_id);
+ if (it == sInstances.end())
+ {
+ llinfos << "Group Panel Notices " << group_id << " no longer in existence."
+ << llendl;
+ return;
+ }
+
+ LLPanelGroupNotices* selfp = it->second;
+ if(!selfp)
+ {
+ llinfos << "Group Panel Notices " << group_id << " no longer in existence."
+ << llendl;
+ return;
+ }
+
+ selfp->processNotices(msg);
+}
+
+void LLPanelGroupNotices::processNotices(LLMessageSystem* msg)
+{
+ LLUUID id;
+ char subj[MAX_STRING];
+ char name[MAX_STRING];
+ U32 timestamp;
+ BOOL has_attachment;
+ U8 asset_type;
+
+ S32 i=0;
+ S32 count = msg->getNumberOfBlocks("Data");
+ for (;i<count;++i)
+ {
+ msg->getUUID("Data","NoticeID",id,i);
+ if (1 == count && id.isNull())
+ {
+ // Only one entry, the dummy entry.
+ mNoticesList->addSimpleItem(mNoNoticesStr,ADD_BOTTOM,FALSE);
+ mNoticesList->setEnabled(FALSE);
+ return;
+ }
+
+ msg->getString("Data","Subject",MAX_STRING,subj,i);
+ msg->getString("Data","FromName",MAX_STRING,name,i);
+ msg->getBOOL("Data","HasAttachment",has_attachment,i);
+ msg->getU8("Data","AssetType",asset_type,i);
+ msg->getU32("Data","Timestamp",timestamp,i);
+ time_t t = timestamp;
+
+ LLSD row;
+ row["id"] = id;
+
+ row["columns"][0]["column"] = "icon";
+ if (has_attachment)
+ {
+ LLUUID icon_id = get_item_icon_uuid(
+ (LLAssetType::EType)asset_type,
+ LLInventoryType::IT_NONE,FALSE);
+ row["columns"][0]["type"] = "icon";
+ row["columns"][0]["value"] = icon_id;
+ }
+
+ row["columns"][1]["column"] = "subject";
+ row["columns"][1]["value"] = subj;
+
+ row["columns"][2]["column"] = "from";
+ row["columns"][2]["value"] = name;
+
+ char buffer[30];
+ build_notice_date(t, buffer);
+ row["columns"][3]["column"] = "date";
+ row["columns"][3]["value"] = buffer;
+
+ snprintf(buffer, 30, "%u", timestamp);
+ row["columns"][4]["column"] = "sort";
+ row["columns"][4]["value"] = buffer;
+
+ mNoticesList->addElement(row, ADD_SORTED);
+ }
+}
+
+void LLPanelGroupNotices::onSelectNotice(LLUICtrl* ctrl, void* data)
+{
+ LLPanelGroupNotices* self = (LLPanelGroupNotices*)data;
+
+ if(!self) return;
+ LLScrollListItem* item = self->mNoticesList->getFirstSelected();
+ if (!item) return;
+
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessage("GroupNoticeRequest");
+ msg->nextBlock("AgentData");
+ msg->addUUID("AgentID",gAgent.getID());
+ msg->addUUID("SessionID",gAgent.getSessionID());
+ msg->nextBlock("Data");
+ msg->addUUID("GroupNoticeID",item->getUUID());
+ gAgent.sendReliableMessage();
+
+ lldebugs << "Item " << item->getUUID().getString().c_str() << " selected." << llendl;
+}
+
+void LLPanelGroupNotices::showNotice(const char* subject,
+ const char* message,
+ const bool& has_inventory,
+ const char* inventory_name,
+ LLOfferInfo* inventory_offer)
+{
+ arrangeNoticeView(VIEW_PAST_NOTICE);
+
+ if(mViewSubject) mViewSubject->setText(subject);
+ if(mViewMessage) mViewMessage->setText(message);
+
+ if (mInventoryOffer)
+ {
+ // Cancel the inventory offer for the previously viewed notice
+ inventory_offer_callback( 1 , mInventoryOffer);
+ mInventoryOffer = NULL;
+ }
+
+ if (inventory_offer)
+ {
+ mInventoryOffer = inventory_offer;
+
+ LLViewerImage* item_icon = get_item_icon(mInventoryOffer->mType,
+ LLInventoryType::IT_TEXTURE,
+ 0);
+
+ mViewInventoryIcon->setImage(item_icon->getID());
+ mViewInventoryIcon->setVisible(TRUE);
+
+ std::stringstream ss;
+ ss << " " << inventory_name;
+
+ mViewInventoryName->setText(ss.str());
+ mBtnOpenAttachment->setEnabled(TRUE);
+ }
+ else
+ {
+ mViewInventoryName->clear();
+ mViewInventoryIcon->setVisible(FALSE);
+ mBtnOpenAttachment->setEnabled(FALSE);
+ }
+}
+
+void LLPanelGroupNotices::arrangeNoticeView(ENoticeView view_type)
+{
+ if (CREATE_NEW_NOTICE == view_type)
+ {
+ mPanelCreateNotice->setVisible(TRUE);
+ mPanelViewNotice->setVisible(FALSE);
+ }
+ else
+ {
+ mPanelCreateNotice->setVisible(FALSE);
+ mPanelViewNotice->setVisible(TRUE);
+ mBtnOpenAttachment->setEnabled(FALSE);
+ }
+}