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