00001
00023 #include "llviewerprecompiledheaders.h"
00024
00025 #include "llfloaterlandmark.h"
00026
00027 #include "llagent.h"
00028 #include "llviewerimagelist.h"
00029 #include "llcheckboxctrl.h"
00030 #include "llcombobox.h"
00031 #include "llbutton.h"
00032 #include "lldraghandle.h"
00033 #include "llfocusmgr.h"
00034 #include "llviewerimage.h"
00035 #include "llviewerparcelmgr.h"
00036 #include "llfolderview.h"
00037 #include "llinventory.h"
00038 #include "llinventorymodel.h"
00039 #include "llinventoryview.h"
00040 #include "lllineeditor.h"
00041 #include "llui.h"
00042 #include "llviewerinventory.h"
00043 #include "llpermissions.h"
00044 #include "llsaleinfo.h"
00045 #include "llassetstorage.h"
00046 #include "lltextbox.h"
00047 #include "llparcel.h"
00048 #include "llresizehandle.h"
00049 #include "llscrollcontainer.h"
00050 #include "lltoolmgr.h"
00051 #include "lltoolpipette.h"
00052
00053 #include "lltool.h"
00054 #include "llviewerwindow.h"
00055 #include "llviewerobject.h"
00056 #include "llviewercontrol.h"
00057 #include "llglheaders.h"
00058 #include "llvieweruictrlfactory.h"
00059
00060 #include "roles_constants.h"
00061
00062
00063
00064 static const S32 CLOSE_BTN_WIDTH = 100;
00065 const S32 PIPETTE_BTN_WIDTH = 32;
00066 static const S32 HPAD = 4;
00067 static const S32 VPAD = 4;
00068 static const S32 LINE = 16;
00069 static const S32 SMALL_BTN_WIDTH = 64;
00070 static const S32 TEX_PICKER_MIN_WIDTH =
00071 (HPAD +
00072 CLOSE_BTN_WIDTH +
00073 HPAD +
00074 CLOSE_BTN_WIDTH +
00075 HPAD +
00076 SMALL_BTN_WIDTH +
00077 HPAD +
00078 SMALL_BTN_WIDTH +
00079 HPAD +
00080 30 +
00081 RESIZE_HANDLE_WIDTH * 2);
00082 static const S32 CLEAR_BTN_WIDTH = 50;
00083 static const S32 TEX_PICKER_MIN_HEIGHT = 290;
00084 static const S32 FOOTER_HEIGHT = 100;
00085 static const S32 BORDER_PAD = HPAD;
00086 static const S32 TEXTURE_INVENTORY_PADDING = 30;
00087 static const F32 CONTEXT_CONE_IN_ALPHA = 0.0f;
00088 static const F32 CONTEXT_CONE_OUT_ALPHA = 1.f;
00089 static const F32 CONTEXT_FADE_TIME = 0.08f;
00090
00091
00092
00093
00094
00095
00096 LLFloaterLandmark::LLFloaterLandmark(const LLSD& data)
00097 :
00098 mTentativeLabel(NULL),
00099 mResolutionLabel(NULL),
00100 mIsDirty( FALSE ),
00101 mActive( TRUE ),
00102 mSearchEdit(NULL),
00103 mContextConeOpacity(0.f)
00104 {
00105 gUICtrlFactory->buildFloater(this,"floater_landmark_ctrl.xml");
00106
00107 mTentativeLabel = LLUICtrlFactory::getTextBoxByName(this,"Multiple");
00108
00109 mResolutionLabel = LLUICtrlFactory::getTextBoxByName(this,"unknown");
00110
00111
00112 childSetCommitCallback("show_folders_check", onShowFolders, this);
00113 childSetVisible("show_folders_check", FALSE);
00114
00115 mSearchEdit = (LLSearchEditor*)getCtrlByNameAndType("inventory search editor", WIDGET_TYPE_SEARCH_EDITOR);
00116 mSearchEdit->setSearchCallback(onSearchEdit, this);
00117
00118 mInventoryPanel = (LLInventoryPanel*)this->getCtrlByNameAndType("inventory panel", WIDGET_TYPE_INVENTORY_PANEL);
00119
00120 if(mInventoryPanel)
00121 {
00122 U32 filter_types = 0x0;
00123 filter_types |= 0x1 << LLInventoryType::IT_LANDMARK;
00124
00125
00126 mInventoryPanel->setFilterTypes(filter_types);
00127
00128 mInventoryPanel->setSelectCallback(onSelectionChange, this);
00129 mInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
00130 mInventoryPanel->setAllowMultiSelect(FALSE);
00131
00132
00133 mInventoryPanel->getRootFolder()->getFilter()->markDefault();
00134
00135
00136 mInventoryPanel->openDefaultFolderForType(LLAssetType::AT_LANDMARK);
00137
00138
00139
00140 mInventoryPanel->setSelection(findItemID(mImageAssetID, FALSE), TAKE_FOCUS_NO);
00141 }
00142
00143 mSavedFolderState = new LLSaveFolderState();
00144 mNoCopyLandmarkSelected = FALSE;
00145
00146 childSetAction("Close", LLFloaterLandmark::onBtnClose,this);
00147 childSetAction("New", LLFloaterLandmark::onBtnNew,this);
00148 childSetAction("NewFolder", LLFloaterLandmark::onBtnNewFolder,this);
00149 childSetAction("Edit", LLFloaterLandmark::onBtnEdit,this);
00150 childSetAction("Rename", LLFloaterLandmark::onBtnRename,this);
00151 childSetAction("Delete", LLFloaterLandmark::onBtnDelete,this);
00152
00153 setCanMinimize(FALSE);
00154
00155 mSavedFolderState->setApply(FALSE);
00156 }
00157
00158 LLFloaterLandmark::~LLFloaterLandmark()
00159 {
00160 delete mSavedFolderState;
00161 }
00162
00163 void LLFloaterLandmark::setActive( BOOL active )
00164 {
00165 mActive = active;
00166 }
00167
00168
00169 BOOL LLFloaterLandmark::handleDragAndDrop(
00170 S32 x, S32 y, MASK mask,
00171 BOOL drop,
00172 EDragAndDropType cargo_type, void *cargo_data,
00173 EAcceptance *accept,
00174 LLString& tooltip_msg)
00175 {
00176 BOOL handled = FALSE;
00177
00178 if (cargo_type == DAD_LANDMARK)
00179 {
00180 LLInventoryItem *item = (LLInventoryItem *)cargo_data;
00181
00182 BOOL copy = item->getPermissions().allowCopyBy(gAgent.getID());
00183 BOOL mod = item->getPermissions().allowModifyBy(gAgent.getID());
00184 BOOL xfer = item->getPermissions().allowOperationBy(PERM_TRANSFER,
00185 gAgent.getID());
00186
00187 PermissionMask item_perm_mask = 0;
00188 if (copy) item_perm_mask |= PERM_COPY;
00189 if (mod) item_perm_mask |= PERM_MODIFY;
00190 if (xfer) item_perm_mask |= PERM_TRANSFER;
00191
00192
00193 PermissionMask filter_perm_mask = mImmediateFilterPermMask;
00194 if ( (item_perm_mask & filter_perm_mask) == filter_perm_mask )
00195 {
00196
00197 *accept = ACCEPT_YES_SINGLE;
00198 }
00199 else
00200 {
00201 *accept = ACCEPT_NO;
00202 }
00203 }
00204 else
00205 {
00206 *accept = ACCEPT_NO;
00207 }
00208
00209 handled = TRUE;
00210 lldebugst(LLERR_USER_INPUT) << "dragAndDrop handled by LLFloaterLandmark " << getName() << llendl;
00211
00212 return handled;
00213 }
00214
00215 BOOL LLFloaterLandmark::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent)
00216 {
00217 LLFolderView* root_folder = mInventoryPanel->getRootFolder();
00218
00219 if (root_folder && mSearchEdit)
00220 {
00221 if (!called_from_parent && mSearchEdit->hasFocus() &&
00222 (key == KEY_RETURN || key == KEY_DOWN) &&
00223 mask == MASK_NONE)
00224 {
00225 if (!root_folder->getCurSelectedItem())
00226 {
00227 LLFolderViewItem* itemp = root_folder->getItemByID(gAgent.getInventoryRootID());
00228 if (itemp)
00229 {
00230 root_folder->setSelection(itemp, FALSE, FALSE);
00231 }
00232 }
00233 root_folder->scrollToShowSelection();
00234
00235
00236 root_folder->setFocus(TRUE);
00237
00238 return TRUE;
00239 }
00240
00241 if (root_folder->hasFocus() && key == KEY_UP)
00242 {
00243 mSearchEdit->focusFirstItem(TRUE);
00244 }
00245 }
00246
00247 return LLFloater::handleKeyHere(key, mask, called_from_parent);
00248 }
00249
00250
00251 void LLFloaterLandmark::onClose(bool app_quitting)
00252 {
00253 destroy();
00254 }
00255
00256
00257
00258 const LLUUID& LLFloaterLandmark::findItemID(const LLUUID& asset_id, BOOL copyable_only)
00259 {
00260 LLViewerInventoryCategory::cat_array_t cats;
00261 LLViewerInventoryItem::item_array_t items;
00262 LLAssetIDMatches asset_id_matches(asset_id);
00263 gInventory.collectDescendentsIf(LLUUID::null,
00264 cats,
00265 items,
00266 LLInventoryModel::INCLUDE_TRASH,
00267 asset_id_matches);
00268
00269 if (items.count())
00270 {
00271
00272 for (S32 i = 0; i < items.count(); i++)
00273 {
00274 LLInventoryItem* itemp = items[i];
00275 LLPermissions item_permissions = itemp->getPermissions();
00276 if (item_permissions.allowCopyBy(gAgent.getID(), gAgent.getGroupID()))
00277 {
00278 return itemp->getUUID();
00279 }
00280 }
00281
00282 if (copyable_only)
00283 {
00284 return LLUUID::null;
00285 }
00286 else
00287 {
00288 return items[0]->getUUID();
00289 }
00290 }
00291
00292 return LLUUID::null;
00293 }
00294
00295
00296 void LLFloaterLandmark::onBtnClose(void* userdata)
00297 {
00298 LLFloaterLandmark* self = (LLFloaterLandmark*) userdata;
00299 self->mIsDirty = FALSE;
00300 self->close();
00301 }
00302
00303
00304 void LLFloaterLandmark::onBtnEdit(void* userdata)
00305 {
00306 LLFloaterLandmark* self = (LLFloaterLandmark*) userdata;
00307
00308 LLViewerInventoryItem* itemp = gInventory.getItem(self->mImageAssetID);
00309 if(itemp)
00310 {
00311 open_landmark(itemp, itemp->getName(), TRUE);
00312 }
00313 }
00314
00315 void LLFloaterLandmark::onBtnNew(void* userdata)
00316 {
00317 LLViewerRegion* agent_region = gAgent.getRegion();
00318 if(!agent_region)
00319 {
00320 llwarns << "No agent region" << llendl;
00321 return;
00322 }
00323 LLParcel* agent_parcel = gParcelMgr->getAgentParcel();
00324 if (!agent_parcel)
00325 {
00326 llwarns << "No agent parcel" << llendl;
00327 return;
00328 }
00329 if (!agent_parcel->getAllowLandmark()
00330 && !LLViewerParcelMgr::isParcelOwnedByAgent(agent_parcel, GP_LAND_ALLOW_LANDMARK))
00331 {
00332 gViewerWindow->alertXml("CannotCreateLandmarkNotOwner");
00333 return;
00334 }
00335
00336 LLUUID folder_id;
00337 folder_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_LANDMARK);
00338 std::string pos_string;
00339 gAgent.buildLocationString(pos_string);
00340
00341 create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
00342 folder_id, LLTransactionID::tnull,
00343 pos_string, pos_string,
00344 LLAssetType::AT_LANDMARK,
00345 LLInventoryType::IT_LANDMARK,
00346 NOT_WEARABLE, PERM_ALL,
00347 NULL);
00348 }
00349
00350 void LLFloaterLandmark::onBtnNewFolder(void* userdata)
00351 {
00352
00353 }
00354
00355 void LLFloaterLandmark::onBtnDelete(void* userdata)
00356 {
00357 LLFloaterLandmark* self = (LLFloaterLandmark*)userdata;
00358
00359 LLViewerInventoryItem* item = gInventory.getItem(self->mImageAssetID);
00360 if(item)
00361 {
00362
00363 LLUUID trash_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_TRASH);
00364 if (item->getParentUUID() != trash_id)
00365 {
00366 LLInventoryModel::update_list_t update;
00367 LLInventoryModel::LLCategoryUpdate old_folder(item->getParentUUID(),-1);
00368 update.push_back(old_folder);
00369 LLInventoryModel::LLCategoryUpdate new_folder(trash_id, 1);
00370 update.push_back(new_folder);
00371 gInventory.accountForUpdate(update);
00372
00373 LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
00374 new_item->setParent(trash_id);
00375
00376
00377 new_item->updateParentOnServer(FALSE);
00378 gInventory.updateItem(new_item);
00379 gInventory.notifyObservers();
00380 }
00381 }
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391 }
00392
00393
00394 void LLFloaterLandmark::onBtnRename(void* userdata)
00395 {
00396
00397 }
00398
00399
00400 void LLFloaterLandmark::onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action, void* data)
00401 {
00402 LLFloaterLandmark* self = (LLFloaterLandmark*)data;
00403 if (items.size())
00404 {
00405 LLFolderViewItem* first_item = items.front();
00406 LLInventoryItem* itemp = gInventory.getItem(first_item->getListener()->getUUID());
00407 self->mNoCopyLandmarkSelected = FALSE;
00408 if (itemp)
00409 {
00410 if (!itemp->getPermissions().allowCopyBy(gAgent.getID()))
00411 {
00412 self->mNoCopyLandmarkSelected = TRUE;
00413 }
00414 self->mImageAssetID = itemp->getUUID();
00415 self->mIsDirty = TRUE;
00416 }
00417 }
00418 }
00419
00420
00421 void LLFloaterLandmark::onShowFolders(LLUICtrl* ctrl, void *user_data)
00422 {
00423 LLCheckBoxCtrl* check_box = (LLCheckBoxCtrl*)ctrl;
00424 LLFloaterLandmark* picker = (LLFloaterLandmark*)user_data;
00425
00426 if (check_box->get())
00427 {
00428 picker->mInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
00429 }
00430 else
00431 {
00432 picker->mInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_NO_FOLDERS);
00433 }
00434 }
00435
00436 void LLFloaterLandmark::onSearchEdit(const LLString& search_string, void* user_data )
00437 {
00438 LLFloaterLandmark* picker = (LLFloaterLandmark*)user_data;
00439
00440 std::string upper_case_search_string = search_string;
00441 LLString::toUpper(upper_case_search_string);
00442
00443 if (upper_case_search_string.empty())
00444 {
00445 if (picker->mInventoryPanel->getFilterSubString().empty())
00446 {
00447
00448 return;
00449 }
00450
00451 picker->mSavedFolderState->setApply(TRUE);
00452 picker->mInventoryPanel->getRootFolder()->applyFunctorRecursively(*picker->mSavedFolderState);
00453
00454 LLOpenFoldersWithSelection opener;
00455 picker->mInventoryPanel->getRootFolder()->applyFunctorRecursively(opener);
00456 picker->mInventoryPanel->getRootFolder()->scrollToShowSelection();
00457
00458 }
00459 else if (picker->mInventoryPanel->getFilterSubString().empty())
00460 {
00461
00462 if (!picker->mInventoryPanel->getRootFolder()->isFilterModified())
00463 {
00464 picker->mSavedFolderState->setApply(FALSE);
00465 picker->mInventoryPanel->getRootFolder()->applyFunctorRecursively(*picker->mSavedFolderState);
00466 }
00467 }
00468
00469 picker->mInventoryPanel->setFilterSubString(upper_case_search_string);
00470 }
00471