00001
00032 #include "llviewerprecompiledheaders.h"
00033
00034 #include <boost/tokenizer.hpp>
00035
00036 #include "llnamelistctrl.h"
00037
00038 #include "llcachename.h"
00039 #include "llagent.h"
00040 #include "llinventory.h"
00041
00042
00043 std::set<LLNameListCtrl*> LLNameListCtrl::sInstances;
00044
00045 LLNameListCtrl::LLNameListCtrl(const LLString& name,
00046 const LLRect& rect,
00047 LLUICtrlCallback cb,
00048 void* userdata,
00049 BOOL allow_multiple_selection,
00050 BOOL draw_border,
00051 S32 name_column_index,
00052 const LLString& tooltip)
00053 : LLScrollListCtrl(name, rect, cb, userdata, allow_multiple_selection,
00054 draw_border),
00055 mNameColumnIndex(name_column_index),
00056 mAllowCallingCardDrop(FALSE)
00057 {
00058 setToolTip(tooltip);
00059 LLNameListCtrl::sInstances.insert(this);
00060 }
00061
00062
00063
00064 LLNameListCtrl::~LLNameListCtrl()
00065 {
00066 LLNameListCtrl::sInstances.erase(this);
00067 }
00068
00069
00070
00071 BOOL LLNameListCtrl::addNameItem(const LLUUID& agent_id, EAddPosition pos,
00072 BOOL enabled, LLString& suffix)
00073 {
00074
00075
00076 char first[DB_FIRST_NAME_BUF_SIZE];
00077 char last[DB_LAST_NAME_BUF_SIZE];
00078
00079 BOOL result = gCacheName->getName(agent_id, first, last);
00080
00081 LLString fullname;
00082 fullname.assign(first);
00083 fullname.append(1, ' ');
00084 fullname.append(last);
00085 fullname.append(suffix);
00086
00087 addStringUUIDItem(fullname, agent_id, pos, enabled);
00088
00089 return result;
00090 }
00091
00092
00093 BOOL LLNameListCtrl::handleDragAndDrop(
00094 S32 x, S32 y, MASK mask,
00095 BOOL drop,
00096 EDragAndDropType cargo_type, void *cargo_data,
00097 EAcceptance *accept,
00098 LLString& tooltip_msg)
00099 {
00100 if (!mAllowCallingCardDrop)
00101 {
00102 return FALSE;
00103 }
00104
00105 BOOL handled = FALSE;
00106
00107 if (cargo_type == DAD_CALLINGCARD)
00108 {
00109 if (drop)
00110 {
00111 LLInventoryItem* item = (LLInventoryItem *)cargo_data;
00112 addNameItem(item->getCreatorUUID());
00113 }
00114
00115 *accept = ACCEPT_YES_MULTI;
00116 }
00117 else
00118 {
00119 *accept = ACCEPT_NO;
00120 if (tooltip_msg.empty())
00121 {
00122 if (!getToolTip().empty())
00123 {
00124 tooltip_msg = getToolTip();
00125 }
00126 else
00127 {
00128
00129 tooltip_msg.assign("Drag a calling card here\nto add a resident.");
00130 }
00131 }
00132 }
00133
00134 handled = TRUE;
00135 lldebugst(LLERR_USER_INPUT) << "dragAndDrop handled by LLNameListCtrl " << getName() << llendl;
00136
00137 return handled;
00138 }
00139
00140
00141 void LLNameListCtrl::addGroupNameItem(const LLUUID& group_id, EAddPosition pos,
00142 BOOL enabled)
00143 {
00144
00145 char group_name[DB_GROUP_NAME_BUF_SIZE];
00146 gCacheName->getGroupName(group_id, group_name);
00147 addStringUUIDItem(group_name, group_id, pos, enabled);
00148 }
00149
00150
00151 void LLNameListCtrl::addGroupNameItem(LLScrollListItem* item, EAddPosition pos)
00152
00153 {
00154
00155
00156 char group_name[DB_GROUP_NAME_BUF_SIZE];
00157 gCacheName->getGroupName(item->getUUID(), group_name);
00158
00159 LLScrollListCell* cell = (LLScrollListCell*)item->getColumn(mNameColumnIndex);
00160 ((LLScrollListText*)cell)->setText( LLString(group_name) );
00161
00162 addItem(item, pos);
00163 }
00164
00165 BOOL LLNameListCtrl::addNameItem(LLScrollListItem* item, EAddPosition pos)
00166 {
00167
00168
00169 char first[DB_FIRST_NAME_BUF_SIZE];
00170 char last[DB_LAST_NAME_BUF_SIZE];
00171
00172 BOOL result = gCacheName->getName(item->getUUID(), first, last);
00173
00174 LLString fullname;
00175 fullname.assign(first);
00176 fullname.append(1, ' ');
00177 fullname.append(last);
00178
00179 LLScrollListCell* cell = (LLScrollListCell*)item->getColumn(mNameColumnIndex);
00180 ((LLScrollListText*)cell)->setText( fullname );
00181
00182 addItem(item, pos);
00183
00184
00185 LLScrollListColumn* columnp = getColumn(mNameColumnIndex);
00186 if (columnp && columnp->mHeader)
00187 {
00188 columnp->mHeader->setHasResizableElement(TRUE);
00189 }
00190
00191 return result;
00192 }
00193
00194 LLScrollListItem* LLNameListCtrl::addElement(const LLSD& value, EAddPosition pos, void* userdata)
00195 {
00196 LLScrollListItem* item = LLScrollListCtrl::addElement(value, pos, userdata);
00197
00198 char first[DB_FIRST_NAME_BUF_SIZE];
00199 char last[DB_LAST_NAME_BUF_SIZE];
00200
00201
00202 LLString fullname = value["name"].asString();
00203 if (value["target"].asString() == "GROUP")
00204 {
00205 char group_name[DB_GROUP_NAME_BUF_SIZE];
00206 gCacheName->getGroupName(item->getUUID(), group_name);
00207
00208 fullname = group_name;
00209 }
00210 else if (value["target"].asString() == "SPECIAL")
00211 {
00212
00213 }
00214 else
00215 {
00216 if (gCacheName->getName(item->getUUID(), first, last))
00217 {
00218 fullname.assign(first);
00219 fullname.append(1, ' ');
00220 fullname.append(last);
00221 }
00222 }
00223
00224 LLScrollListCell* cell = (LLScrollListCell*)item->getColumn(mNameColumnIndex);
00225 ((LLScrollListText*)cell)->setText( fullname );
00226
00227 updateMaxContentWidth(item);
00228
00229
00230 LLScrollListColumn* columnp = getColumn(mNameColumnIndex);
00231 if (columnp && columnp->mHeader)
00232 {
00233 columnp->mHeader->setHasResizableElement(TRUE);
00234 }
00235
00236 return item;
00237 }
00238
00239
00240 void LLNameListCtrl::removeNameItem(const LLUUID& agent_id)
00241 {
00242 BOOL item_exists = selectByID( agent_id );
00243 if(item_exists)
00244 {
00245 S32 index = getItemIndex(getFirstSelected());
00246 if(index >= 0)
00247 {
00248 deleteSingleItem(index);
00249 }
00250 }
00251 }
00252
00253
00254 void LLNameListCtrl::refresh(const LLUUID& id, const char* first,
00255 const char* last,
00256 BOOL is_group)
00257 {
00258
00259
00260
00261 LLString fullname;
00262 fullname.assign(first);
00263 if (last[0] && !is_group)
00264 {
00265 fullname.append(1, ' ');
00266 fullname.append(last);
00267 }
00268
00269
00270 item_list::iterator iter;
00271 for (iter = mItemList.begin(); iter != mItemList.end(); iter++)
00272 {
00273 LLScrollListItem* item = *iter;
00274 if (item->getUUID() == id)
00275 {
00276 LLScrollListCell* cell = (LLScrollListCell*)item->getColumn(0);
00277 cell = (LLScrollListCell*)item->getColumn(mNameColumnIndex);
00278
00279 ((LLScrollListText*)cell)->setText( fullname );
00280 updateMaxContentWidth(item);
00281 }
00282 }
00283 }
00284
00285
00286
00287 void LLNameListCtrl::refreshAll(const LLUUID& id, const char* first,
00288 const char* last,
00289 BOOL is_group)
00290 {
00291 std::set<LLNameListCtrl*>::iterator it;
00292 for (it = LLNameListCtrl::sInstances.begin();
00293 it != LLNameListCtrl::sInstances.end();
00294 ++it)
00295 {
00296 LLNameListCtrl* ctrl = *it;
00297 ctrl->refresh(id, first, last, is_group);
00298 }
00299 }
00300
00301
00302 LLXMLNodePtr LLNameListCtrl::getXML(bool save_children) const
00303 {
00304 LLXMLNodePtr node = LLScrollListCtrl::getXML();
00305
00306 node->createChild("allow_calling_card_drop", TRUE)->setBoolValue(mAllowCallingCardDrop);
00307
00308 if (mNameColumnIndex != 0)
00309 {
00310 node->createChild("name_column_index", TRUE)->setIntValue(mNameColumnIndex);
00311 }
00312
00313
00314
00315 return node;
00316 }
00317
00318 LLView* LLNameListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
00319 {
00320 LLString name("name_list");
00321 node->getAttributeString("name", name);
00322
00323 LLRect rect;
00324 createRect(node, rect, parent, LLRect());
00325
00326 BOOL multi_select = FALSE;
00327 node->getAttributeBOOL("multi_select", multi_select);
00328
00329 BOOL draw_border = TRUE;
00330 node->getAttributeBOOL("draw_border", draw_border);
00331
00332 BOOL draw_heading = FALSE;
00333 node->getAttributeBOOL("draw_heading", draw_heading);
00334
00335 BOOL collapse_empty_columns = FALSE;
00336 node->getAttributeBOOL("collapse_empty_columns", collapse_empty_columns);
00337
00338 S32 name_column_index = 0;
00339 node->getAttributeS32("name_column_index", name_column_index);
00340
00341 LLUICtrlCallback callback = NULL;
00342
00343 LLNameListCtrl* name_list = new LLNameListCtrl(name,
00344 rect,
00345 callback,
00346 NULL,
00347 multi_select,
00348 draw_border,
00349 name_column_index);
00350
00351 name_list->setDisplayHeading(draw_heading);
00352 if (node->hasAttribute("heading_height"))
00353 {
00354 S32 heading_height;
00355 node->getAttributeS32("heading_height", heading_height);
00356 name_list->setHeadingHeight(heading_height);
00357 }
00358 name_list->setCollapseEmptyColumns(collapse_empty_columns);
00359
00360 BOOL allow_calling_card_drop = FALSE;
00361 if (node->getAttributeBOOL("allow_calling_card_drop", allow_calling_card_drop))
00362 {
00363 name_list->setAllowCallingCardDrop(allow_calling_card_drop);
00364 }
00365
00366 name_list->setScrollListParameters(node);
00367
00368 name_list->initFromXML(node, parent);
00369
00370 LLSD columns;
00371 S32 index = 0;
00372 LLXMLNodePtr child;
00373 for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling())
00374 {
00375 if (child->hasName("column"))
00376 {
00377 LLString labelname("");
00378 child->getAttributeString("label", labelname);
00379
00380 LLString columnname(labelname);
00381 child->getAttributeString("name", columnname);
00382
00383 if (child->hasAttribute("relwidth"))
00384 {
00385 F32 columnrelwidth = 0.f;
00386 child->getAttributeF32("relwidth", columnrelwidth);
00387 columns[index]["relwidth"] = columnrelwidth;
00388 }
00389 else
00390 {
00391 S32 columnwidth = -1;
00392 child->getAttributeS32("width", columnwidth);
00393 columns[index]["width"] = columnwidth;
00394 }
00395
00396 LLFontGL::HAlign h_align = LLFontGL::LEFT;
00397 h_align = LLView::selectFontHAlign(child);
00398
00399 columns[index]["name"] = columnname;
00400 columns[index]["label"] = labelname;
00401 columns[index]["halign"] = (S32)h_align;
00402 index++;
00403 }
00404 }
00405 name_list->setColumnHeadings(columns);
00406
00407 for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling())
00408 {
00409 if (child->hasName("row"))
00410 {
00411 LLUUID id;
00412 child->getAttributeUUID("id", id);
00413
00414 LLSD row;
00415
00416 row["id"] = id;
00417
00418 S32 column_idx = 0;
00419 LLXMLNodePtr row_child;
00420 for (row_child = node->getFirstChild(); row_child.notNull(); row_child = row_child->getNextSibling())
00421 {
00422 if (row_child->hasName("column"))
00423 {
00424 LLString value = row_child->getTextContents();
00425
00426 LLString columnname("");
00427 row_child->getAttributeString("name", columnname);
00428
00429 LLString font("");
00430 row_child->getAttributeString("font", font);
00431
00432 LLString font_style("");
00433 row_child->getAttributeString("font-style", font_style);
00434
00435 row["columns"][column_idx]["column"] = columnname;
00436 row["columns"][column_idx]["value"] = value;
00437 row["columns"][column_idx]["font"] = font;
00438 row["columns"][column_idx]["font-style"] = font_style;
00439 column_idx++;
00440 }
00441 }
00442 name_list->addElement(row);
00443 }
00444 }
00445
00446 LLString contents = node->getTextContents();
00447
00448 typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
00449 boost::char_separator<char> sep("\t\n");
00450 tokenizer tokens(contents, sep);
00451 tokenizer::iterator token_iter = tokens.begin();
00452
00453 while(token_iter != tokens.end())
00454 {
00455 const char* line = token_iter->c_str();
00456 name_list->addSimpleItem(line);
00457 ++token_iter;
00458 }
00459
00460 return name_list;
00461 }
00462
00463
00464