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