summaryrefslogtreecommitdiff
path: root/indra/newview/llpanelteleporthistory.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llpanelteleporthistory.cpp')
-rw-r--r--indra/newview/llpanelteleporthistory.cpp401
1 files changed, 331 insertions, 70 deletions
diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp
index 1fd7928bfc..9754094aaa 100644
--- a/indra/newview/llpanelteleporthistory.cpp
+++ b/indra/newview/llpanelteleporthistory.cpp
@@ -40,6 +40,182 @@
#include "llteleporthistorystorage.h"
#include "llaccordionctrl.h"
#include "llaccordionctrltab.h"
+#include "llflatlistview.h"
+#include "lltextbox.h"
+#include "llviewermenu.h"
+#include "llviewerinventory.h"
+#include "lllandmarkactions.h"
+#include "llclipboard.h"
+
+class LLTeleportHistoryFlatItem : public LLPanel
+{
+public:
+ LLTeleportHistoryFlatItem(S32 index, LLTeleportHistoryPanel::ContextMenu *context_menu, const std::string &region_name);
+ virtual ~LLTeleportHistoryFlatItem() {};
+
+ virtual BOOL postBuild();
+
+ S32 getIndex() { return mIndex; }
+
+ /*virtual*/ void setValue(const LLSD& value);
+
+ void onMouseEnter(S32 x, S32 y, MASK mask);
+ void onMouseLeave(S32 x, S32 y, MASK mask);
+ virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
+
+ static void showPlaceInfoPanel(S32 index);
+private:
+ void onInfoBtnClick();
+
+ LLButton* mInfoBtn;
+ LLTeleportHistoryPanel::ContextMenu *mContextMenu;
+
+ S32 mIndex;
+ std::string mRegionName;
+};
+
+LLTeleportHistoryFlatItem::LLTeleportHistoryFlatItem(S32 index, LLTeleportHistoryPanel::ContextMenu *context_menu, const std::string &region_name)
+: LLPanel(),
+ mIndex(index),
+ mContextMenu(context_menu),
+ mRegionName(region_name)
+{
+ LLUICtrlFactory::getInstance()->buildPanel(this, "panel_teleport_history_item.xml");
+}
+
+//virtual
+BOOL LLTeleportHistoryFlatItem::postBuild()
+{
+ LLTextBox *region = getChild<LLTextBox>("region");
+ region->setValue(mRegionName);
+
+ mInfoBtn = getChild<LLButton>("info_btn");
+ mInfoBtn->setClickedCallback(boost::bind(&LLTeleportHistoryFlatItem::onInfoBtnClick, this));
+
+ return true;
+}
+
+void LLTeleportHistoryFlatItem::setValue(const LLSD& value)
+{
+ if (!value.isMap()) return;;
+ if (!value.has("selected")) return;
+ childSetVisible("selected_icon", value["selected"]);
+}
+
+void LLTeleportHistoryFlatItem::onMouseEnter(S32 x, S32 y, MASK mask)
+{
+ childSetVisible("hovered_icon", true);
+ mInfoBtn->setVisible(true);
+
+ LLPanel::onMouseEnter(x, y, mask);
+}
+
+void LLTeleportHistoryFlatItem::onMouseLeave(S32 x, S32 y, MASK mask)
+{
+ childSetVisible("hovered_icon", false);
+ mInfoBtn->setVisible(false);
+
+ LLPanel::onMouseLeave(x, y, mask);
+}
+
+// virtual
+BOOL LLTeleportHistoryFlatItem::handleRightMouseDown(S32 x, S32 y, MASK mask)
+{
+ if (mContextMenu)
+ mContextMenu->show(this, mIndex, x, y);
+
+ return LLPanel::handleRightMouseDown(x, y, mask);
+}
+
+void LLTeleportHistoryFlatItem::showPlaceInfoPanel(S32 index)
+{
+ LLSD params;
+ params["id"] = index;
+ params["type"] = "teleport_history";
+
+ LLSideTray::getInstance()->showPanel("panel_places", params);
+}
+
+void LLTeleportHistoryFlatItem::onInfoBtnClick()
+{
+ LLTeleportHistoryFlatItem::showPlaceInfoPanel(mIndex);
+}
+
+LLTeleportHistoryPanel::ContextMenu::ContextMenu() :
+ mMenu(NULL)
+{
+}
+
+void LLTeleportHistoryPanel::ContextMenu::show(LLView* spawning_view, S32 index, S32 x, S32 y)
+{
+ if (mMenu)
+ {
+ //preventing parent (menu holder) from deleting already "dead" context menus on exit
+ LLView* parent = mMenu->getParent();
+ if (parent)
+ {
+ parent->removeChild(mMenu);
+ mMenu->setParent(NULL);
+ }
+ delete mMenu;
+ }
+
+ mIndex = index;
+ mMenu = createMenu();
+
+ LLViewerInventoryItem *landmark = LLLandmarkActions::findLandmarkForGlobalPos(
+ LLTeleportHistoryStorage::getInstance()->getItems()[index].mGlobalPos);
+
+ mMenu->setItemEnabled("Make Landmark", !landmark || landmark->getUUID().isNull());
+
+ mMenu->show(x, y);
+ LLMenuGL::showPopup(spawning_view, mMenu, x, y);
+}
+
+LLContextMenu* LLTeleportHistoryPanel::ContextMenu::createMenu()
+{
+ // set up the callbacks for all of the avatar menu items
+ // (N.B. callbacks don't take const refs as mID is local scope)
+ LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+
+ registrar.add("TeleportHistory.Teleport", boost::bind(&LLTeleportHistoryPanel::ContextMenu::onTeleport, this));
+ registrar.add("TeleportHistory.MoreInformation",boost::bind(&LLTeleportHistoryPanel::ContextMenu::onInfo, this));
+ registrar.add("TeleportHistory.Copy", boost::bind(&LLTeleportHistoryPanel::ContextMenu::onCopy, this));
+ registrar.add("TeleportHistory.MakeLandmark", boost::bind(&LLTeleportHistoryPanel::ContextMenu::onMakeLandmark, this));
+
+ // create the context menu from the XUI
+ return LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(
+ "menu_teleport_history_item.xml", LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance());
+}
+
+void LLTeleportHistoryPanel::ContextMenu::onTeleport()
+{
+ LLTeleportHistoryStorage::getInstance()->goToItem(mIndex);
+}
+
+void LLTeleportHistoryPanel::ContextMenu::onInfo()
+{
+ LLTeleportHistoryFlatItem::showPlaceInfoPanel(mIndex);
+}
+
+//static
+void LLTeleportHistoryPanel::ContextMenu::gotSLURLCallback(const std::string& slurl)
+{
+ gClipboard.copyFromString(utf8str_to_wstring(slurl));
+}
+
+void LLTeleportHistoryPanel::ContextMenu::onCopy()
+{
+ LLVector3d globalPos = LLTeleportHistoryStorage::getInstance()->getItems()[mIndex].mGlobalPos;
+ LLLandmarkActions::getSLURLfromPosGlobal(globalPos,
+ boost::bind(&LLTeleportHistoryPanel::ContextMenu::gotSLURLCallback, _1), false);
+}
+
+void LLTeleportHistoryPanel::ContextMenu::onMakeLandmark()
+{
+ //FIXME: it creates landmark for current agent positon, not for the global position of item of teleport history
+ LLSideTray::getInstance()->showPanel("panel_places", LLSD().insert("type", "create_landmark"));
+}
// Not yet implemented; need to remove buildPanel() from constructor when we switch
//static LLRegisterPanelClassWrapper<LLTeleportHistoryPanel> t_teleport_history("panel_teleport_history");
@@ -48,7 +224,8 @@ LLTeleportHistoryPanel::LLTeleportHistoryPanel()
: LLPanelPlacesTab(),
mFilterSubString(LLStringUtil::null),
mTeleportHistory(NULL),
- mHistoryAccordeon(NULL),
+ mHistoryAccordion(NULL),
+ mAccordionTabMenu(NULL),
mLastSelectedScrollList(NULL)
{
LLUICtrlFactory::getInstance()->buildPanel(this, "panel_teleport_history.xml");
@@ -66,26 +243,27 @@ BOOL LLTeleportHistoryPanel::postBuild()
mTeleportHistory->setHistoryChangedCallback(boost::bind(&LLTeleportHistoryPanel::showTeleportHistory, this));
}
- mHistoryAccordeon = getChild<LLAccordionCtrl>("history_accordion");
+ mHistoryAccordion = getChild<LLAccordionCtrl>("history_accordion");
- if (mHistoryAccordeon)
+ if (mHistoryAccordion)
{
- for (child_list_const_iter_t iter = mHistoryAccordeon->beginChild(); iter != mHistoryAccordeon->endChild(); iter++)
+ for (child_list_const_iter_t iter = mHistoryAccordion->beginChild(); iter != mHistoryAccordion->endChild(); iter++)
{
if (dynamic_cast<LLAccordionCtrlTab*>(*iter))
{
LLAccordionCtrlTab* tab = (LLAccordionCtrlTab*)*iter;
+ tab->setRightMouseDownCallback(boost::bind(&LLTeleportHistoryPanel::onAccordionTabRightClick, this, _1, _2, _3, _4));
+
mItemContainers.put(tab);
- LLScrollListCtrl* sl = getScrollListFromTab(tab);
- if (sl)
+ LLFlatListView* fl = getFlatListViewFromTab(tab);
+ if (fl)
{
- sl->setDoubleClickCallback(onDoubleClickItem, this);
- sl->setCommitOnSelectionChange(FALSE);
- sl->setCommitCallback(boost::bind(&LLTeleportHistoryPanel::handleItemSelect, this, sl));
+ fl->setCommitOnSelectionChange(true);
+ //fl->setDoubleClickCallback(onDoubleClickItem, this);
+ fl->setCommitCallback(boost::bind(&LLTeleportHistoryPanel::handleItemSelect, this, fl));
}
-
}
}
}
@@ -109,13 +287,12 @@ void LLTeleportHistoryPanel::onShowOnMap()
if (!mLastSelectedScrollList)
return;
- LLScrollListItem* itemp = mLastSelectedScrollList->getFirstSelected();
+ LLTeleportHistoryFlatItem* itemp = dynamic_cast<LLTeleportHistoryFlatItem *> (mLastSelectedScrollList->getSelectedItem());
+
if(!itemp)
return;
- S32 index = itemp->getColumn(LIST_INDEX)->getValue().asInteger();
-
- LLVector3d global_pos = mTeleportHistory->getItems()[mTeleportHistory->getItems().size() - 1 - index].mGlobalPos;
+ LLVector3d global_pos = mTeleportHistory->getItems()[itemp->getIndex()].mGlobalPos;
if (!global_pos.isExactlyZero())
{
@@ -130,14 +307,12 @@ void LLTeleportHistoryPanel::onTeleport()
if (!mLastSelectedScrollList)
return;
- LLScrollListItem* itemp = mLastSelectedScrollList->getFirstSelected();
+ LLTeleportHistoryFlatItem* itemp = dynamic_cast<LLTeleportHistoryFlatItem *> (mLastSelectedScrollList->getSelectedItem());
if(!itemp)
return;
- S32 index = itemp->getColumn(LIST_INDEX)->getValue().asInteger();
-
// teleport to existing item in history, so we don't add it again
- mTeleportHistory->goToItem(mTeleportHistory->getItems().size() - 1 - index);
+ mTeleportHistory->goToItem(itemp->getIndex());
}
/*
@@ -177,15 +352,15 @@ void LLTeleportHistoryPanel::updateVerbs()
return;
}
- LLScrollListItem* itemp = mLastSelectedScrollList->getFirstSelected();
+ LLTeleportHistoryFlatItem* itemp = dynamic_cast<LLTeleportHistoryFlatItem *> (mLastSelectedScrollList->getSelectedItem());
- mTeleportBtn->setEnabled(NULL != itemp && 0 < itemp->getColumn(LIST_INDEX)->getValue().asInteger());
+ mTeleportBtn->setEnabled(NULL != itemp && 0 < itemp->getIndex());
mShowOnMapBtn->setEnabled(NULL != itemp);
}
void LLTeleportHistoryPanel::showTeleportHistory()
{
- if (!mHistoryAccordeon)
+ if (!mHistoryAccordion)
return;
const LLTeleportHistoryStorage::slurl_list_t& hist_items = mTeleportHistory->getItems();
@@ -193,15 +368,17 @@ void LLTeleportHistoryPanel::showTeleportHistory()
const U32 seconds_in_day = 24 * 60 * 60;
LLDate curr_date = LLDate::now();
- curr_date.secondsSinceEpoch(curr_date.secondsSinceEpoch() + seconds_in_day);
-
S32 curr_tab = -1;
S32 tabs_cnt = mItemContainers.size();
S32 curr_year = 0, curr_month = 0, curr_day = 0;
+
+ curr_date.split(&curr_year, &curr_month, &curr_day);
+ curr_date.fromYMDHMS(curr_year, curr_month, curr_day); // Set hour, min, and sec to 0
+ curr_date.secondsSinceEpoch(curr_date.secondsSinceEpoch() + seconds_in_day);
- LLScrollListCtrl *curr_scroll_list = NULL;
+ LLFlatListView* curr_flat_view = NULL;
- S32 index = 0;
+ S32 index = hist_items.size() - 1;
for (LLTeleportHistoryStorage::slurl_list_t::const_reverse_iterator iter = hist_items.rbegin();
iter != hist_items.rend(); ++iter)
@@ -219,71 +396,104 @@ void LLTeleportHistoryPanel::showTeleportHistory()
{
const LLDate &date = (*iter).mDate;
- S32 year, month, day;
- if (!date.split(&year, &month, &day))
- {
- llwarns << "Failed to split date: " << date << llendl;
- continue;
- }
-
- if (day != curr_day || month != curr_month || year != curr_year)
+ if (date < curr_date)
{
LLAccordionCtrlTab* tab = NULL;
- while (curr_tab < tabs_cnt - 1 && (day != curr_day || month != curr_month || year != curr_year))
+ while (curr_tab < tabs_cnt - 1 && date < curr_date)
{
curr_tab++;
tab = mItemContainers.get(mItemContainers.size() - 1 - curr_tab);
tab->setVisible(false);
-
- curr_date.secondsSinceEpoch(curr_date.secondsSinceEpoch() - seconds_in_day);
- curr_date.split(&curr_year, &curr_month, &curr_day);
- }
+
+ if (curr_tab <= tabs_cnt - 4)
+ {
+ curr_date.secondsSinceEpoch(curr_date.secondsSinceEpoch() - seconds_in_day);
+ }
+ else if (curr_tab == tabs_cnt - 3) // 6 day and older, low boundary is 1 month
+ {
+ curr_date = LLDate::now();
+ curr_date.split(&curr_year, &curr_month, &curr_day);
+ curr_month--;
+ if (0 == curr_month)
+ {
+ curr_month = 12;
+ curr_year--;
+ }
+ curr_date.fromYMDHMS(curr_year, curr_month, curr_day);
+ }
+ else if (curr_tab == tabs_cnt - 2) // 1 month and older, low boundary is 6 months
+ {
+ curr_date = LLDate::now();
+ curr_date.split(&curr_year, &curr_month, &curr_day);
+ if (curr_month > 6)
+ {
+ curr_month -= 6;
+ }
+ else
+ {
+ curr_month += 6;
+ curr_year--;
+ }
+ curr_date.fromYMDHMS(curr_year, curr_month, curr_day);
+
+ }
+ else // 6 months and older
+ {
+ curr_date.secondsSinceEpoch(0);
+ }
+ }
tab->setVisible(true);
- curr_scroll_list = getScrollListFromTab(tab);
- if (curr_scroll_list)
+ curr_flat_view = getFlatListViewFromTab(tab);
+ if (curr_flat_view)
{
- curr_scroll_list->deleteAllItems();
+ curr_flat_view->clear();
}
}
}
- LLSD row;
- row["id"] = index;
-
- if (curr_scroll_list)
- {
- LLSD& icon_column = row["columns"][LIST_ICON];
- icon_column["column"] = "landmark_icon";
- icon_column["type"] = "icon";
- icon_column["value"] = "inv_item_landmark.tga";
-
- LLSD& region_column = row["columns"][LIST_ITEM_TITLE];
- region_column["column"] = "region";
- region_column["type"] = "text";
- region_column["value"] = (*iter).mTitle;
-
- LLSD& index_column = row["columns"][LIST_INDEX];
- index_column["column"] = "index";
- index_column["type"] = "text";
- index_column["value"] = index;
-
- index++;
-
- curr_scroll_list->addElement(row);
+ if (curr_flat_view)
+ {
+ curr_flat_view->addItem(new LLTeleportHistoryFlatItem(index, &mContextMenu, (*iter).mTitle));
}
+
+ index--;
}
- mHistoryAccordeon->arrange();
+ // Hide empty tabs from current to bottom
+ for (curr_tab++; curr_tab < tabs_cnt; curr_tab++)
+ mItemContainers.get(mItemContainers.size() - 1 - curr_tab)->setVisible(false);
+
+ mHistoryAccordion->arrange();
updateVerbs();
}
-void LLTeleportHistoryPanel::handleItemSelect(LLScrollListCtrl* sl)
+void LLTeleportHistoryPanel::handleItemSelect(LLFlatListView* selected)
{
- mLastSelectedScrollList = sl;
+ mLastSelectedScrollList = selected;
+
+ S32 tabs_cnt = mItemContainers.size();
+
+ for (S32 n = 0; n < tabs_cnt; n++)
+ {
+ LLAccordionCtrlTab* tab = mItemContainers.get(n);
+
+ if (!tab->getVisible())
+ continue;
+
+ LLFlatListView *flv = getFlatListViewFromTab(tab);
+ if (!flv)
+ continue;
+
+ if (flv == selected)
+ continue;
+
+ flv->resetSelection(true);
+ }
+
updateVerbs();
}
@@ -303,15 +513,66 @@ void LLTeleportHistoryPanel::onDoubleClickItem(void* user_data)
LLSideTray::getInstance()->showPanel("panel_places", key);*/
}
-LLScrollListCtrl* LLTeleportHistoryPanel::getScrollListFromTab(LLAccordionCtrlTab *tab)
+void LLTeleportHistoryPanel::onAccordionTabRightClick(LLView *view, S32 x, S32 y, MASK mask)
+{
+ LLAccordionCtrlTab *tab = (LLAccordionCtrlTab *) view;
+
+ // If click occurred below the header, don't show this menu
+ if (y < tab->getRect().getHeight() - tab->getHeaderHeight() - tab->getPaddingBottom())
+ return;
+
+ if (mAccordionTabMenu)
+ {
+ //preventing parent (menu holder) from deleting already "dead" context menus on exit
+ LLView* parent = mAccordionTabMenu->getParent();
+ if (parent)
+ {
+ parent->removeChild(mAccordionTabMenu);
+ mAccordionTabMenu->setParent(NULL);
+ }
+ delete mAccordionTabMenu;
+ }
+
+ // set up the callbacks for all of the avatar menu items
+ // (N.B. callbacks don't take const refs as mID is local scope)
+ LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+
+ registrar.add("TeleportHistory.TabOpen", boost::bind(&LLTeleportHistoryPanel::onAccordionTabOpen, this, tab));
+ registrar.add("TeleportHistory.TabClose", boost::bind(&LLTeleportHistoryPanel::onAccordionTabClose, this, tab));
+
+ // create the context menu from the XUI
+ mAccordionTabMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(
+ "menu_teleport_history_tab.xml", LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance());
+
+ mAccordionTabMenu->setItemVisible("TabOpen", !tab->isExpanded() ? true : false);
+ mAccordionTabMenu->setItemVisible("TabClose", tab->isExpanded() ? true : false);
+
+ mAccordionTabMenu->show(x, y);
+ LLMenuGL::showPopup(tab, mAccordionTabMenu, x, y);
+}
+
+void LLTeleportHistoryPanel::onAccordionTabOpen(LLAccordionCtrlTab *tab)
+{
+ tab->setDisplayChildren(true);
+ mHistoryAccordion->arrange();
+}
+
+void LLTeleportHistoryPanel::onAccordionTabClose(LLAccordionCtrlTab *tab)
+{
+ tab->setDisplayChildren(false);
+ mHistoryAccordion->arrange();
+}
+
+LLFlatListView* LLTeleportHistoryPanel::getFlatListViewFromTab(LLAccordionCtrlTab *tab)
{
for (child_list_const_iter_t iter = tab->beginChild(); iter != tab->endChild(); iter++)
{
- if (dynamic_cast<LLScrollListCtrl*>(*iter))
+ if (dynamic_cast<LLFlatListView*>(*iter))
{
- return (LLScrollListCtrl*)*iter; // There should be one scroll list per tab.
+ return (LLFlatListView*)*iter; // There should be one scroll list per tab.
}
}
return NULL;
}
+