summaryrefslogtreecommitdiff
path: root/indra/newview/llfavoritesbar.h
blob: 8f40ad5a6212c347b0d63c45abb6a727d784c3f2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
/** 
 * @file llfavoritesbar.h
 * @brief LLFavoritesBarCtrl base class
 *
 * $LicenseInfo:firstyear=2009&license=viewerlgpl$
 * Second Life Viewer Source Code
 * Copyright (C) 2010, Linden Research, Inc.
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation;
 * version 2.1 of the License only.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 * 
 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 * $/LicenseInfo$
 */

#ifndef LL_LLFAVORITESBARCTRL_H
#define LL_LLFAVORITESBARCTRL_H

#include "llbutton.h"
#include "lluictrl.h"
#include "lltextbox.h"

#include "llinventoryobserver.h"
#include "llinventorymodel.h"
#include "llviewerinventory.h"
#include "llinitdestroyclass.h"

class LLMenuItemCallGL;
class LLToggleableMenu;

class LLFavoritesBarCtrl : public LLUICtrl, public LLInventoryObserver
{
public:
	struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
	{
		Optional<LLUIImage*> image_drag_indication;
		Optional<LLTextBox::Params> more_button;
		Optional<LLTextBox::Params> label;
		Params();
	};

protected:
	LLFavoritesBarCtrl(const Params&);
	friend class LLUICtrlFactory;
    friend class LLItemCopiedCallback;
public:
	virtual ~LLFavoritesBarCtrl();

	/*virtual*/ bool postBuild() override;

	/*virtual*/ bool handleDragAndDrop(S32 x, S32 y, MASK mask, bool drop,
		EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept, std::string& tooltip_msg) override;
	bool handleDragAndDropToMenu(S32 x, S32 y, MASK mask, bool drop,
		EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept, std::string& tooltip_msg);

	/*virtual*/ bool	handleHover(S32 x, S32 y, MASK mask) override;
	/*virtual*/ bool	handleRightMouseDown(S32 x, S32 y, MASK mask) override;
	// LLInventoryObserver observer trigger
    /*virtual*/ void changed(U32 mask) override;
    /*virtual*/ void reshape(S32 width, S32 height, bool called_from_parent = true) override;
    /*virtual*/ void draw() override;

	void showDragMarker(bool show) { mShowDragMarker = show; }
	void setLandingTab(LLUICtrl* tab) { mLandingTab = tab; }

protected:
    void updateButtons(bool force_update = false);
	LLButton* createButton(const LLPointer<LLViewerInventoryItem> item, const LLButton::Params& button_params, S32 x_offset );
	const LLButton::Params& getButtonParams();
	bool collectFavoriteItems(LLInventoryModel::item_array_t &items);

	void onButtonClick(LLUUID id);
	void onButtonRightClick(LLUUID id,LLView* button,S32 x,S32 y,MASK mask);
	
	void onButtonMouseDown(LLUUID id, LLUICtrl* button, S32 x, S32 y, MASK mask);
	void onButtonMouseUp(LLUUID id, LLUICtrl* button, S32 x, S32 y, MASK mask);

	void onEndDrag();

	bool enableSelected(const LLSD& userdata);
	void doToSelected(const LLSD& userdata);
	static bool onRenameCommit(const LLSD& notification, const LLSD& response);
	bool isClipboardPasteable() const;
	void pasteFromClipboard() const;
	
	void showDropDownMenu();

	void onMoreTextBoxClicked();

	LLHandle<LLView> mOverflowMenuHandle;
	LLHandle<LLView> mContextMenuHandle;

	LLUUID mFavoriteFolderId;
	const LLFontGL *mFont;
	S32 mFirstDropDownItem;
	S32 mDropDownItemsCount;
	bool mUpdateDropDownItems;
	bool mRestoreOverflowMenu;
	bool mDragToOverflowMenu;
	bool mGetPrevItems;

	LLUUID mSelectedItemID;
	LLFrameTimer mItemsChangedTimer;
	LLUIImage* mImageDragIndication;

private:
	/*
	 * Helper function to make code more readable. It handles all drag and drop
	 * operations of the existing favorites items to the favorites bar to on the overflow menu.
	 */
	void handleExistingFavoriteDragAndDrop(S32 x, S32 y);

	/*
	 * Helper function to make code more readable. It handles all drag and drop
	 * operations of the new landmark to the favorites bar or to the overflow menu.
	 */
	void handleNewFavoriteDragAndDrop(LLInventoryItem *item, const LLUUID& favorites_id, S32 x, S32 y);

	// finds a control under the specified LOCAL point
	LLUICtrl* findChildByLocalCoords(S32 x, S32 y);

	bool findDragAndDropTarget(LLUUID &target_id, bool &insert_before, S32 x, S32 y);

	// checks if the current order of the favorites items must be saved
	bool needToSaveItemsOrder(const LLInventoryModel::item_array_t& items);

	/**
	 * inserts an item identified by insertedItemId BEFORE an item identified by beforeItemId.
	 * this function assumes that an item identified by insertedItemId doesn't exist in items array.
	 */
	void insertItem(LLInventoryModel::item_array_t& items, const LLUUID& dest_item_id, LLViewerInventoryItem* insertedItem, bool insert_before);

	// finds an item by it's UUID in the items array
	LLInventoryModel::item_array_t::iterator findItemByUUID(LLInventoryModel::item_array_t& items, const LLUUID& id);

	void createOverflowMenu();

	void updateOverflowMenuItems();

	// Fits menu item label width with favorites menu width
	void fitLabelWidth(LLMenuItemCallGL* menu_item);

	void addOpenLandmarksMenuItem(LLToggleableMenu* menu);

	void positionAndShowOverflowMenu();

	bool mShowDragMarker;
	LLUICtrl* mLandingTab;
	LLUICtrl* mLastTab;
	LLTextBox* mMoreTextBox;
	LLTextBox* mBarLabel;

	LLUUID mDragItemId;
	bool mStartDrag;
	LLInventoryModel::item_array_t mItems;

    static F64 sWaitingForCallabck;
    bool mItemsListDirty;

	S32 mMouseX;
	S32 mMouseY;

	boost::signals2::connection mEndDragConnection;
};

/**
 * Class to store sorting order of favorites landmarks in a local file. EXT-3985.
 * It replaced previously implemented solution to store sort index in landmark's name as a "<N>@" prefix.
 * Data are stored in user home directory.
 */
class LLFavoritesOrderStorage : public LLSingleton<LLFavoritesOrderStorage>
	, public LLDestroyClass<LLFavoritesOrderStorage>
{
	LLSINGLETON(LLFavoritesOrderStorage);
	LOG_CLASS(LLFavoritesOrderStorage);
public:
	/**
	 * Sets sort index for specified with LLUUID favorite landmark
	 */
	void setSortIndex(const LLViewerInventoryItem* inv_item, S32 sort_index);

	/**
	 * Gets sort index for specified with LLUUID favorite landmark
	 */
	S32 getSortIndex(const LLUUID& inv_item_id);
	void removeSortIndex(const LLUUID& inv_item_id);

	void getSLURL(const LLUUID& asset_id);

	// Saves current order of the passed items using inventory item sort field.
	// Resets 'items' sort fields and saves them on server.
	// Is used to save order for Favorites folder.
	void saveItemsOrder(const LLInventoryModel::item_array_t& items);

	void saveOrder();

	void rearrangeFavoriteLandmarks(const LLUUID& source_item_id, const LLUUID& target_item_id);

	/**
	 * Implementation of LLDestroyClass. Calls cleanup() instance method.
	 *
	 * It is important this callback is called before gInventory is cleaned.
	 * For now it is called from LLAppViewer::cleanup() -> LLAppViewer::disconnectViewer(),
	 * Inventory is cleaned later from LLAppViewer::cleanup() after LLAppViewer::disconnectViewer() is called.
	 * @see cleanup()
	 */
	static void destroyClass();
	static std::string getStoredFavoritesFilename(const std::string &grid);
	static std::string getStoredFavoritesFilename();
	static std::string getSavedOrderFileName();

	// Remove record of specified user's favorites from file on disk.
	static void removeFavoritesRecordOfUser(const std::string &user, const std::string &grid);
	// Remove record of current user's favorites from file on disk.
	static void removeFavoritesRecordOfUser();

	bool saveFavoritesRecord(bool pref_changed = false);
	void showFavoritesOnLoginChanged(bool show);

	bool isStorageUpdateNeeded();

	LLInventoryModel::item_array_t mPrevFavorites;
	LLSD mStorageFavorites;
	bool mRecreateFavoriteStorage;

	const static S32 NO_INDEX;
	static bool mSaveOnExit;
	bool mUpdateRequired;
	std::map<LLUUID,std::string> mFavoriteNames;

private:
	/**
	 * Removes sort indexes for items which are not in Favorites bar for now.
	 */
	void cleanup();

	const static std::string SORTING_DATA_FILE_NAME;

	void load();

	void onLandmarkLoaded(const LLUUID& asset_id, class LLLandmark* landmark);
	void storeFavoriteSLURL(const LLUUID& asset_id, std::string& slurl);

	typedef std::map<LLUUID, S32> sort_index_map_t;
	sort_index_map_t mSortIndexes;

	typedef std::map<LLUUID, std::string> slurls_map_t;
	slurls_map_t mSLURLs;
	std::set<LLUUID> mMissingSLURLs;
	bool mIsDirty;

	struct IsNotInFavorites
	{
		IsNotInFavorites(const LLInventoryModel::item_array_t& items)
			: mFavoriteItems(items)
		{

		}

		/**
		 * Returns true if specified item is not found among inventory items
		 */
		bool operator()(const sort_index_map_t::value_type& id_index_pair) const
		{
			LLPointer<LLViewerInventoryItem> item = gInventory.getItem(id_index_pair.first);
			if (item.isNull()) return true;

			LLInventoryModel::item_array_t::const_iterator found_it =
				std::find(mFavoriteItems.begin(), mFavoriteItems.end(), item);

			return found_it == mFavoriteItems.end();
		}
	private:
		LLInventoryModel::item_array_t mFavoriteItems;
	};

};

inline
LLFavoritesOrderStorage::LLFavoritesOrderStorage() :
	mIsDirty(false),
	mUpdateRequired(false),
	mRecreateFavoriteStorage(false)
{ load(); }

#endif // LL_LLFAVORITESBARCTRL_H