Merge branch 'friend_list_groups_and_notes' into 'atys'

Friend list groups

See merge request ryzom/ryzom-core!4
ryzom/ui/improvements
Nuno Gonçalves (Ulukyn) 4 years ago
commit bca2a28187

@ -90,7 +90,7 @@ static const sint PARTY_CHAT_SPAWN_DELTA = 20; // to avoid that all party chat a
////////////////////////////////// //////////////////////////////////
/** Display an error msg in the system info window, and also in the last window that triggered the command (so that the user is sure to see it) /** Display an error msg in the system info window, and also in the last window that triggered the command (so that the user is sure to see it)
*/ */
static void displayVisibleSystemMsg(const ucstring &msg, const string &cat = "CHK"); static void displayVisibleSystemMsg(const ucstring &msg, const string &cat = "CHK");
@ -289,13 +289,13 @@ void CChatStdInput::registerListeningWindow(CChatWindow *cw)
//=========================================================================================================== //===========================================================================================================
CPeopleInterraction::CPeopleInterraction() : Region(NULL), CPeopleInterraction::CPeopleInterraction() : Region(NULL),
Universe(NULL), Universe(NULL),
TeamChat(NULL), TeamChat(NULL),
GuildChat(NULL), GuildChat(NULL),
SystemInfo(NULL), SystemInfo(NULL),
TellWindow(NULL), TellWindow(NULL),
DebugInfo(NULL), DebugInfo(NULL),
CurrPartyChatID(0) CurrPartyChatID(0)
{ {
for(uint i=0;i<CChatGroup::MaxDynChanPerPlayer;i++) for(uint i=0;i<CChatGroup::MaxDynChanPerPlayer;i++)
{ {
@ -311,6 +311,8 @@ void CPeopleInterraction::release()
ChatInput.Tell.removeListeningPeopleList(&TeamList); ChatInput.Tell.removeListeningPeopleList(&TeamList);
ChatInput.Team.removeListeningPeopleList(&TeamList); ChatInput.Team.removeListeningPeopleList(&TeamList);
FriendList.saveContactGroups();
CChatWindowManager &cwm = getChatWndMgr(); CChatWindowManager &cwm = getChatWndMgr();
AroundMe.release(); AroundMe.release();
@ -333,7 +335,7 @@ void CPeopleInterraction::release()
SystemInfo = NULL; SystemInfo = NULL;
TellWindow = NULL; TellWindow = NULL;
DebugInfo = NULL; DebugInfo = NULL;
// TellWindow = NULL; // TellWindow = NULL;
for(uint i=0;i<CChatGroup::MaxDynChanPerPlayer;i++) for(uint i=0;i<CChatGroup::MaxDynChanPerPlayer;i++)
{ {
@ -390,7 +392,7 @@ void CPeopleInterraction::removeAllPartyChat()
//=========================================================================================================== //===========================================================================================================
bool CPeopleInterraction::isUserChat(CChatWindow *cw) const bool CPeopleInterraction::isUserChat(CChatWindow *cw) const
{ {
// if (cw == MainChat.Window) return true; // if (cw == MainChat.Window) return true;
if (cw == ChatGroup.Window) return true; if (cw == ChatGroup.Window) return true;
for(uint k = 0; k < MaxNumUserChats; ++k) for(uint k = 0; k < MaxNumUserChats; ++k)
{ {
@ -432,8 +434,8 @@ void CPeopleInterraction::init()
void CPeopleInterraction::initAfterLoad() void CPeopleInterraction::initAfterLoad()
{ {
/* activate the USER chat per default. /* activate the USER chat per default.
Important: we must do it after ChatGroup.Window var init, DB color init etc... Important: we must do it after ChatGroup.Window var init, DB color init etc...
because the latest are used in chat_group_filter ActionHandler because the latest are used in chat_group_filter ActionHandler
*/ */
CChatGroupWindow *pCGW= PeopleInterraction.getChatGroupWindow(); CChatGroupWindow *pCGW= PeopleInterraction.getChatGroupWindow();
if(pCGW) if(pCGW)
@ -562,12 +564,12 @@ void CPeopleInterraction::createFriendList()
// //
FriendList.create(peopleListDesc); FriendList.create(peopleListDesc);
FriendList.setPeopleMenuEx("ui:interface:friend_list_menu_offline_unblocked", FriendList.setPeopleMenuEx("ui:interface:friend_list_menu_offline_unblocked",
"ui:interface:friend_list_menu_online_unblocked", "ui:interface:friend_list_menu_online_unblocked",
"ui:interface:friend_list_menu_online_abroad_unblocked", "ui:interface:friend_list_menu_online_abroad_unblocked",
"ui:interface:friend_list_menu_offline_blocked", "ui:interface:friend_list_menu_offline_blocked",
"ui:interface:friend_list_menu_online_blocked", "ui:interface:friend_list_menu_online_blocked",
"ui:interface:friend_list_menu_online_abroad_blocked" "ui:interface:friend_list_menu_online_abroad_blocked"
); );
FriendList.setMenu("ui:interface:sort_menu"); FriendList.setMenu("ui:interface:sort_menu");
} }
@ -703,21 +705,21 @@ void CPeopleInterraction::createUniverseWindow()
void CPeopleInterraction::createTellWindow() void CPeopleInterraction::createTellWindow()
{ {
/*CChatWindowDesc chatDesc; /*CChatWindowDesc chatDesc;
chatDesc.FatherContainer = "ui:interface"; chatDesc.FatherContainer = "ui:interface";
chatDesc.Title = "uiTellWindow"; chatDesc.Title = "uiTellWindow";
chatDesc.Listener = NULL; chatDesc.Listener = NULL;
chatDesc.Savable = true; chatDesc.Savable = true;
chatDesc.Localize = true; chatDesc.Localize = true;
chatDesc.Id = "tell"; chatDesc.Id = "tell";
chatDesc.ChatTemplate ="chat_no_eb_id"; chatDesc.ChatTemplate ="chat_no_eb_id";
chatDesc.AHOnActive = "set"; chatDesc.AHOnActive = "set";
chatDesc.AHOnActiveParams = "dblink=UI:SAVE:ISDETACHED:TELL|value=1"; chatDesc.AHOnActiveParams = "dblink=UI:SAVE:ISDETACHED:TELL|value=1";
chatDesc.AHOnDeactive = "set"; chatDesc.AHOnDeactive = "set";
chatDesc.AHOnDeactiveParams = "dblink=UI:SAVE:ISDETACHED:TELL|value=0"; chatDesc.AHOnDeactiveParams = "dblink=UI:SAVE:ISDETACHED:TELL|value=0";
TellWindow = getChatWndMgr().createChatWindow(chatDesc); TellWindow = getChatWndMgr().createChatWindow(chatDesc);
if (!TellWindow) return; if (!TellWindow) return;
TellWindow->setMenu("ui:interface:base_chat_box_menu"); */ TellWindow->setMenu("ui:interface:base_chat_box_menu"); */
} }
//=========================================================================================================== //===========================================================================================================
@ -826,13 +828,13 @@ class CHandlerUserChatActive : public IActionHandler
CChatGroup::TGroupType m = PeopleInterraction.TheUserChat.Filter.getTargetGroup(); CChatGroup::TGroupType m = PeopleInterraction.TheUserChat.Filter.getTargetGroup();
switch(m) switch(m)
{ {
default: default:
case CChatGroup::arround: case CChatGroup::arround:
case CChatGroup::say: pUserBut->setHardText("uiFilterAround"); break; case CChatGroup::say: pUserBut->setHardText("uiFilterAround"); break;
case CChatGroup::region: pUserBut->setHardText("uiFilterRegion"); break; case CChatGroup::region: pUserBut->setHardText("uiFilterRegion"); break;
case CChatGroup::universe: pUserBut->setHardText("uiFilterUniverse"); break; case CChatGroup::universe: pUserBut->setHardText("uiFilterUniverse"); break;
case CChatGroup::team: pUserBut->setHardText("uiFilterTeam"); break; case CChatGroup::team: pUserBut->setHardText("uiFilterTeam"); break;
case CChatGroup::guild: pUserBut->setHardText("uiFilterGuild"); break; case CChatGroup::guild: pUserBut->setHardText("uiFilterGuild"); break;
} }
pUserBut->getParent()->updateCoords(); pUserBut->getParent()->updateCoords();
pUserBut->updateCoords(); pUserBut->updateCoords();
@ -925,29 +927,29 @@ class CHandlerChatGroupFilter : public IActionHandler
CChatGroup::TGroupType m = PeopleInterraction.TheUserChat.Filter.getTargetGroup(); CChatGroup::TGroupType m = PeopleInterraction.TheUserChat.Filter.getTargetGroup();
switch(m) switch(m)
{ {
default: default:
case CChatGroup::arround: case CChatGroup::arround:
case CChatGroup::say: pUserBut->setHardText("uiFilterAround"); break; case CChatGroup::say: pUserBut->setHardText("uiFilterAround"); break;
case CChatGroup::region: pUserBut->setHardText("uiFilterRegion"); break; case CChatGroup::region: pUserBut->setHardText("uiFilterRegion"); break;
case CChatGroup::team: pUserBut->setHardText("uiFilterTeam"); break; case CChatGroup::team: pUserBut->setHardText("uiFilterTeam"); break;
case CChatGroup::guild: pUserBut->setHardText("uiFilterGuild"); break; case CChatGroup::guild: pUserBut->setHardText("uiFilterGuild"); break;
case CChatGroup::universe: pUserBut->setHardText("uiFilterUniverse"); break; case CChatGroup::universe: pUserBut->setHardText("uiFilterUniverse"); break;
case CChatGroup::dyn_chat: case CChatGroup::dyn_chat:
uint32 index = PeopleInterraction.TheUserChat.Filter.getTargetDynamicChannelDbIndex(); uint32 index = PeopleInterraction.TheUserChat.Filter.getTargetDynamicChannelDbIndex();
uint32 textId = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:DYN_CHAT:CHANNEL"+toString(index)+":NAME")->getValue32(); uint32 textId = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:DYN_CHAT:CHANNEL"+toString(index)+":NAME")->getValue32();
ucstring title; ucstring title;
STRING_MANAGER::CStringManagerClient::instance()->getDynString(textId, title); STRING_MANAGER::CStringManagerClient::instance()->getDynString(textId, title);
if (title.empty()) if (title.empty())
{ {
// Dyn channel not available yet, so set to around // Dyn channel not available yet, so set to around
PeopleInterraction.TheUserChat.Filter.setTargetGroup(CChatGroup::arround); PeopleInterraction.TheUserChat.Filter.setTargetGroup(CChatGroup::arround);
pUserBut->setHardText("uiFilterAround"); pUserBut->setHardText("uiFilterAround");
} }
else else
{ {
pUserBut->setHardText(title.toUtf8()); pUserBut->setHardText(title.toUtf8());
} }
break; break;
} }
pUserBut->setActive(true); pUserBut->setActive(true);
@ -1252,8 +1254,8 @@ void CPeopleInterraction::askRemoveContact(uint peopleIndex, CPeopleList *pl)
//================================================================================================================= //=================================================================================================================
void CPeopleInterraction::initContactLists( const std::vector<uint32> &vFriendListName, void CPeopleInterraction::initContactLists( const std::vector<uint32> &vFriendListName,
const std::vector<TCharConnectionState> &vFriendListOnline, const std::vector<TCharConnectionState> &vFriendListOnline,
const std::vector<ucstring> &vIgnoreListName ) const std::vector<ucstring> &vIgnoreListName )
{ {
// clear the current lists if any // clear the current lists if any
@ -1266,6 +1268,9 @@ void CPeopleInterraction::initContactLists( const std::vector<uint32> &vFriendLi
addContactInList(contactIdPool++, vFriendListName[i], vFriendListOnline[i], 0); addContactInList(contactIdPool++, vFriendListName[i], vFriendListOnline[i], 0);
for (uint i = 0; i < vIgnoreListName.size(); ++i) for (uint i = 0; i < vIgnoreListName.size(); ++i)
addContactInList(contactIdPool++, vIgnoreListName[i], ccs_offline, 1); addContactInList(contactIdPool++, vIgnoreListName[i], ccs_offline, 1);
FriendList.readContactGroups();
CPeopleList::TSortOrder order = (CPeopleList::TSortOrder)(NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:CONTACT_LIST:SORT_ORDER")->getValue32());
FriendList.sortEx(order);
updateAllFreeTellerHeaders(); updateAllFreeTellerHeaders();
} }
@ -1278,6 +1283,8 @@ void CPeopleInterraction::addContactInList(uint32 contactId, const ucstring &nam
// remove the shard name if possible // remove the shard name if possible
ucstring name= CEntityCL::removeShardFromName(nameIn); ucstring name= CEntityCL::removeShardFromName(nameIn);
// add the contact to this list // add the contact to this list
sint index = pl.getIndexFromName(name); sint index = pl.getIndexFromName(name);
// try to create if not found // try to create if not found
@ -1477,7 +1484,7 @@ bool CPeopleInterraction::testValidPartyChatName(const ucstring &title)
index = IgnoreList.getIndexFromName(title); index = IgnoreList.getIndexFromName(title);
if (index != -1) return false; if (index != -1) return false;
// TODO_GAMEDEV server test for the name (not only local), & modify callers of this function // TODO_GAMEDEV server test for the name (not only local), & modify callers of this function
// The party chat should NOT have the name of a player // The party chat should NOT have the name of a player
// A player name is NOT valid if it is the same that a party chat name // A player name is NOT valid if it is the same that a party chat name
return true; return true;
} }
@ -1547,14 +1554,14 @@ bool CPeopleInterraction::createNewPartyChat(const ucstring &title)
{ {
// popup the container // popup the container
/* /*
newPartyChat->getContainer()->setup(); newPartyChat->getContainer()->setup();
newPartyChat->getContainer()->setOpen(true); newPartyChat->getContainer()->setOpen(true);
newPartyChat->getContainer()->popupCurrentPos(); newPartyChat->getContainer()->popupCurrentPos();
newPartyChat->getContainer()->updateCoords(); newPartyChat->getContainer()->updateCoords();
newPartyChat->getContainer()->center(); newPartyChat->getContainer()->center();
newPartyChat->getContainer()->setX(newPartyChat->getContainer()->getX() + (sint32) (rand() % PARTY_CHAT_SPAWN_DELTA)); newPartyChat->getContainer()->setX(newPartyChat->getContainer()->getX() + (sint32) (rand() % PARTY_CHAT_SPAWN_DELTA));
newPartyChat->getContainer()->setY(newPartyChat->getContainer()->getY() + (sint32) (rand() % PARTY_CHAT_SPAWN_DELTA)); newPartyChat->getContainer()->setY(newPartyChat->getContainer()->getY() + (sint32) (rand() % PARTY_CHAT_SPAWN_DELTA));
newPartyChat->getContainer()->enableBlink(2); newPartyChat->getContainer()->enableBlink(2);
*/ */
CPartyChatInfo pci; CPartyChatInfo pci;
@ -1742,15 +1749,15 @@ bool CPeopleInterraction::loadUserChatsInfos(NLMISC::IStream &f)
f.serialCheck(NELID("TAHC")); f.serialCheck(NELID("TAHC"));
if (ver>=1) if (ver>=1)
{ {
// CChatGroupWindow *pCGW = PeopleInterraction.getChatGroupWindow(); // CChatGroupWindow *pCGW = PeopleInterraction.getChatGroupWindow();
sint32 index; sint32 index;
f.serial(index); f.serial(index);
/* Yoyo: decide to always start with the default channel (user) activated /* Yoyo: decide to always start with the default channel (user) activated
because complex (at this time, the buttons are not all active, must wait guild loading, UI:SAVE loading etc...) because complex (at this time, the buttons are not all active, must wait guild loading, UI:SAVE loading etc...)
Hence this doesn't work for anything but User and Sysinfo (if it is activated....) Hence this doesn't work for anything but User and Sysinfo (if it is activated....)
NB: must still load the index for file format reason NB: must still load the index for file format reason
//if (pCGW) pCGW->setTabIndex(index); //if (pCGW) pCGW->setTabIndex(index);
*/ */
f.serial(present); f.serial(present);
if (present) if (present)
{ {
@ -2012,17 +2019,17 @@ public:
if (list == &PeopleInterraction.TeamList) // check for good list if (list == &PeopleInterraction.TeamList) // check for good list
{ {
/* /*
const string msgName = "TEAM:SET_LEADER"; const string msgName = "TEAM:SET_LEADER";
CBitMemStream out; CBitMemStream out;
if(GenericMsgHeaderMngr.pushNameToStream(msgName, out)) if(GenericMsgHeaderMngr.pushNameToStream(msgName, out))
{ {
uint8 teamMember = (uint8)(peopleIndex); uint8 teamMember = (uint8)(peopleIndex);
out.serial(teamMember); out.serial(teamMember);
NetMngr.push(out); NetMngr.push(out);
//nlinfo("impulseCallBack : %s %d sent", msgName.c_str(), teamMember); //nlinfo("impulseCallBack : %s %d sent", msgName.c_str(), teamMember);
} }
else else
nlwarning("command 'set_leader': unknown message named '%s'.", msgName.c_str()); nlwarning("command 'set_leader': unknown message named '%s'.", msgName.c_str());
*/ */
NLMISC::ICommand::execute("a setTeamLeader " + toString(peopleIndex), g_log); NLMISC::ICommand::execute("a setTeamLeader " + toString(peopleIndex), g_log);
} }
@ -2177,8 +2184,8 @@ public:
void execute (CCtrlBase *pCaller, const std::string &sParams) void execute (CCtrlBase *pCaller, const std::string &sParams)
{ {
/** This msg may have been triggered from valid button or from the edit box itself, so retrieve /** This msg may have been triggered from valid button or from the edit box itself, so retrieve
* the edit box from the enclosing group * the edit box from the enclosing group
*/ */
// Get enclosing container to know in which people list we are // Get enclosing container to know in which people list we are
if (pCaller) if (pCaller)
{ {
@ -2221,8 +2228,8 @@ public:
CInterfaceManager *pIM = CInterfaceManager::getInstance(); CInterfaceManager *pIM = CInterfaceManager::getInstance();
/** This msg may have been triggered from valid button or from the edit box itself, so retrieve /** This msg may have been triggered from valid button or from the edit box itself, so retrieve
* the edit box from the enclosing group * the edit box from the enclosing group
*/ */
// Get enclosing container to know in which people list we are // Get enclosing container to know in which people list we are
if (!LastFatherAddContactId.empty() && pCaller) if (!LastFatherAddContactId.empty() && pCaller)
{ {
@ -2292,13 +2299,13 @@ public:
} }
switch(listIndex) switch(listIndex)
{ {
case 0: case 0:
destList = &PeopleInterraction.IgnoreList; destList = &PeopleInterraction.IgnoreList;
break; break;
case 1: case 1:
destList = &PeopleInterraction.FriendList; destList = &PeopleInterraction.FriendList;
break; break;
default: nlwarning("Bad list index"); return; default: nlwarning("Bad list index"); return;
} }
PeopleInterraction.askMoveContact(peopleIndex, srcList, destList); PeopleInterraction.askMoveContact(peopleIndex, srcList, destList);
@ -2307,6 +2314,56 @@ public:
}; };
REGISTER_ACTION_HANDLER( CHandlerMoveContact, "move_contact"); REGISTER_ACTION_HANDLER( CHandlerMoveContact, "move_contact");
uint lastPeopleIndexChangeGroup;
//=================================================================================================================
class CHandlerChangeContactGroupBegin : public IActionHandler
{
public:
void execute (CCtrlBase * pCaller, const std::string &sParams)
{
// retrieve the index of the people
CPeopleList *srcList;
if (PeopleInterraction.getPeopleFromCurrentMenu(srcList, lastPeopleIndexChangeGroup))
{
string groupName= getParam(sParams, "group");
CInterfaceGroup *gc = dynamic_cast<CInterfaceGroup *>(CWidgetManager::getInstance()->getElementFromId(groupName));
if (gc)
{
CGroupEditBox *geb = dynamic_cast<CGroupEditBox *>(gc->getGroup("change_contact_group_eb:eb"));
geb->setInputString(ucstring(""));
}
CAHManager::getInstance()->runActionHandler("enter_modal", pCaller, sParams);
}
}
};
REGISTER_ACTION_HANDLER( CHandlerChangeContactGroupBegin, "change_contact_group_begin");
//=================================================================================================================
// Change the group of a contact in the list
class CHandlerChangeContactGroup : public IActionHandler
{
public:
void execute (CCtrlBase *pCaller, const std::string &/* sParams */)
{
CInterfaceManager *pIM = CInterfaceManager::getInstance();
if (pCaller)
{
// Get the modal edit box
CGroupEditBox *geb = dynamic_cast<CGroupEditBox *>(CWidgetManager::getInstance()->getElementFromId("ui:interface:change_contact_group:change_contact_group_eb:eb"));
if (geb)
{
PeopleInterraction.FriendList.changeGroup(lastPeopleIndexChangeGroup, geb->getInputString());
geb->setInputString(ucstring(""));
CPeopleList::TSortOrder order = (CPeopleList::TSortOrder)(NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:CONTACT_LIST:SORT_ORDER")->getValue32());
PeopleInterraction.FriendList.sortEx(order);
}
}
CAHManager::getInstance()->runActionHandler("leave_modal", pCaller, "");
}
};
REGISTER_ACTION_HANDLER( CHandlerChangeContactGroup, "change_contact_group");
//================================================================================================================= //=================================================================================================================
class CHandlerSortContacts : public IActionHandler class CHandlerSortContacts : public IActionHandler
@ -2372,7 +2429,7 @@ REGISTER_ACTION_HANDLER( CHandlerContactDirectChat, "contact_direct_chat");
//================================================================================================================= //=================================================================================================================
/** Menu to create a new party chat /** Menu to create a new party chat
*/ */
class CHandlerNewPartyChat : public IActionHandler class CHandlerNewPartyChat : public IActionHandler
{ {
public: public:
@ -2406,7 +2463,7 @@ REGISTER_ACTION_HANDLER( CHandlerNewPartyChat, "new_party_chat");
//================================================================================================================= //=================================================================================================================
/** The name of a party chat has been validated /** The name of a party chat has been validated
*/ */
class CHandlerValidatePartyChatName : public IActionHandler class CHandlerValidatePartyChatName : public IActionHandler
{ {
void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */) void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */)
@ -2439,12 +2496,12 @@ REGISTER_ACTION_HANDLER(CHandlerValidatePartyChatName, "validate_party_chat_name
//================================================================================================================= //=================================================================================================================
/** Menu to create a new party chat /** Menu to create a new party chat
*/ */
//================================================================================================================= //=================================================================================================================
/** Menu to remove a currenlty created party chat /** Menu to remove a currenlty created party chat
*/ */
class CHandlerRemovePartyChat : public IActionHandler class CHandlerRemovePartyChat : public IActionHandler
{ {
void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */) void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */)
@ -2457,7 +2514,7 @@ REGISTER_ACTION_HANDLER( CHandlerRemovePartyChat, "remove_party_chat");
//================================================================================================================= //=================================================================================================================
/** TEMP : just create an 'invite' command in the 'around me' edit box /** TEMP : just create an 'invite' command in the 'around me' edit box
*/ */
class CHandlerPartyChatInvite : public IActionHandler class CHandlerPartyChatInvite : public IActionHandler
{ {
void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */) void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */)
@ -2483,12 +2540,12 @@ REGISTER_ACTION_HANDLER( CHandlerPartyChatInvite, "party_chat_invite" );
//================================================================================================================= //=================================================================================================================
/** Add all members of the team to the party chat /** Add all members of the team to the party chat
*/ */
class CHandlerAddAllTeamMembersToPartyChat : public IActionHandler class CHandlerAddAllTeamMembersToPartyChat : public IActionHandler
{ {
void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */) void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */)
{ {
// CChatWindow *chat = getChatWndMgr().getChatWindowFromCaller(CWidgetManager::getInstance()->getCtrlLaunchingModal()); // CChatWindow *chat = getChatWndMgr().getChatWindowFromCaller(CWidgetManager::getInstance()->getCtrlLaunchingModal());
// TODO GAMEDEV : add all team members // TODO GAMEDEV : add all team members
} }
}; };
@ -2496,12 +2553,12 @@ REGISTER_ACTION_HANDLER( CHandlerAddAllTeamMembersToPartyChat, "add_all_team_mem
//================================================================================================================= //=================================================================================================================
/** Remove all members of the team to the party chat /** Remove all members of the team to the party chat
*/ */
class CHandlerRemoveAllTeamMembersToPartyChat : public IActionHandler class CHandlerRemoveAllTeamMembersToPartyChat : public IActionHandler
{ {
void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */) void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */)
{ {
// CChatWindow *chat = getChatWndMgr().getChatWindowFromCaller(CWidgetManager::getInstance()->getCtrlLaunchingModal()); // CChatWindow *chat = getChatWndMgr().getChatWindowFromCaller(CWidgetManager::getInstance()->getCtrlLaunchingModal());
// TODO GAMEDEV : remove all team members // TODO GAMEDEV : remove all team members
} }
}; };
@ -2509,12 +2566,12 @@ REGISTER_ACTION_HANDLER( CHandlerRemoveAllTeamMembersToPartyChat, "remove_all_te
//================================================================================================================= //=================================================================================================================
/** Add all members of the guild to the party chat /** Add all members of the guild to the party chat
*/ */
class CHandlerAddAllGuildMembersToPartyChat : public IActionHandler class CHandlerAddAllGuildMembersToPartyChat : public IActionHandler
{ {
void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */) void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */)
{ {
// CChatWindow *chat = getChatWndMgr().getChatWindowFromCaller(CWidgetManager::getInstance()->getCtrlLaunchingModal()); // CChatWindow *chat = getChatWndMgr().getChatWindowFromCaller(CWidgetManager::getInstance()->getCtrlLaunchingModal());
// TODO GAMEDEV : add all guild members // TODO GAMEDEV : add all guild members
} }
}; };
@ -2522,12 +2579,12 @@ REGISTER_ACTION_HANDLER( CHandlerAddAllGuildMembersToPartyChat, "add_all_guild_m
//================================================================================================================= //=================================================================================================================
/** Remove all members of the team to the party chat /** Remove all members of the team to the party chat
*/ */
class CHandlerRemoveAllGuildMembersToPartyChat : public IActionHandler class CHandlerRemoveAllGuildMembersToPartyChat : public IActionHandler
{ {
void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */) void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */)
{ {
// CChatWindow *chat = getChatWndMgr().getChatWindowFromCaller(CWidgetManager::getInstance()->getCtrlLaunchingModal()); // CChatWindow *chat = getChatWndMgr().getChatWindowFromCaller(CWidgetManager::getInstance()->getCtrlLaunchingModal());
// TODO_GAMEDEV : remove all guild members // TODO_GAMEDEV : remove all guild members
} }
}; };
@ -2539,8 +2596,8 @@ REGISTER_ACTION_HANDLER( CHandlerRemoveAllGuildMembersToPartyChat, "remove_all_g
//================================================================================================================= //=================================================================================================================
/** Select the target on a filtered chat window /** Select the target on a filtered chat window
* This create a menu with the standard window (team, around me ...) + the party chat windows * This create a menu with the standard window (team, around me ...) + the party chat windows
*/ */
class CHandlerSelectChatTarget : public IActionHandler class CHandlerSelectChatTarget : public IActionHandler
{ {
public: public:
@ -2603,7 +2660,7 @@ public:
{ {
CInterfaceManager *pIM = CInterfaceManager::getInstance(); CInterfaceManager *pIM = CInterfaceManager::getInstance();
cw = PeopleInterraction.TheUserChat.Window; cw = PeopleInterraction.TheUserChat.Window;
// CChatStdInput &ci = PeopleInterraction.ChatInput; // CChatStdInput &ci = PeopleInterraction.ChatInput;
CGroupMenu *pMenu = dynamic_cast<CGroupMenu*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:user_chat_target_menu")); CGroupMenu *pMenu = dynamic_cast<CGroupMenu*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:user_chat_target_menu"));
CViewTextMenu *pMenuAround = dynamic_cast<CViewTextMenu*>(pMenu->getElement("ui:interface:user_chat_target_menu:around")); CViewTextMenu *pMenuAround = dynamic_cast<CViewTextMenu*>(pMenu->getElement("ui:interface:user_chat_target_menu:around"));
CViewTextMenu *pMenuRegion = dynamic_cast<CViewTextMenu*>(pMenu->getElement("ui:interface:user_chat_target_menu:region")); CViewTextMenu *pMenuRegion = dynamic_cast<CViewTextMenu*>(pMenu->getElement("ui:interface:user_chat_target_menu:region"));
@ -2659,7 +2716,7 @@ REGISTER_ACTION_HANDLER( CHandlerSelectChatTarget, "select_chat_target");
//================================================================================================================= //=================================================================================================================
/** A target has been selected for a filtered chat /** A target has been selected for a filtered chat
*/ */
class CHandlerChatTargetSelected : public IActionHandler class CHandlerChatTargetSelected : public IActionHandler
{ {
void execute (CCtrlBase * /* pCaller */, const std::string &sParams) void execute (CCtrlBase * /* pCaller */, const std::string &sParams)
@ -2748,7 +2805,7 @@ REGISTER_ACTION_HANDLER( CHandlerChatTargetSelected, "chat_target_selected");
//================================================================================================================= //=================================================================================================================
/** If no more in team, leave team chat mode /** If no more in team, leave team chat mode
*/ */
class CHandlerLeaveTeamChat : public IActionHandler class CHandlerLeaveTeamChat : public IActionHandler
{ {
void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */) void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */)
@ -2773,7 +2830,7 @@ REGISTER_ACTION_HANDLER( CHandlerLeaveTeamChat, "leave_team_chat");
/** Create checkbox for a menu. /** Create checkbox for a menu.
*/ */
static CInterfaceGroup *createMenuCheckBox(const std::string &onclickL, const std::string &paramsL, bool checked) static CInterfaceGroup *createMenuCheckBox(const std::string &onclickL, const std::string &paramsL, bool checked)
{ {
pair<string, string> params [2]; pair<string, string> params [2];
@ -2795,7 +2852,7 @@ static CInterfaceGroup *createMenuCheckBox(const std::string &onclickL, const st
//================================================================================================================= //=================================================================================================================
/** Display a menu to select the source on a filtered chat /** Display a menu to select the source on a filtered chat
*/ */
class CHandlerSelectChatSource : public IActionHandler class CHandlerSelectChatSource : public IActionHandler
{ {
void execute (CCtrlBase *pCaller, const std::string &/* sParams */) void execute (CCtrlBase *pCaller, const std::string &/* sParams */)
@ -2977,7 +3034,7 @@ REGISTER_ACTION_HANDLER(CHandlerSelectChatSource, "select_chat_source");
//================================================================================================================= //=================================================================================================================
/** A new source has been selected / unselected from a filtered chat /** A new source has been selected / unselected from a filtered chat
*/ */
class CHandlerChatSourceSelected : public IActionHandler class CHandlerChatSourceSelected : public IActionHandler
{ {
void execute (CCtrlBase * /* pCaller */, const std::string &sParams) void execute (CCtrlBase * /* pCaller */, const std::string &sParams)
@ -3001,10 +3058,10 @@ class CHandlerChatSourceSelected : public IActionHandler
/*CCtrlBaseButton *button = dynamic_cast<CCtrlBaseButton *>(pCaller); /*CCtrlBaseButton *button = dynamic_cast<CCtrlBaseButton *>(pCaller);
if (button) if (button)
{ {
button->setPushed(!button->getPushed()); button->setPushed(!button->getPushed());
}*/ }*/
// GUILD // GUILD
if (nlstricmp(sParams, "guild") == 0) if (nlstricmp(sParams, "guild") == 0)
{ {
@ -3012,71 +3069,71 @@ class CHandlerChatSourceSelected : public IActionHandler
else ci.Guild.addListeningWindow(cw); else ci.Guild.addListeningWindow(cw);
} }
else else
// TEAM // TEAM
if (nlstricmp(sParams, "team") == 0) if (nlstricmp(sParams, "team") == 0)
{
if (ci.Team.isListeningWindow(cw)) ci.Team.removeListeningWindow(cw);
else ci.Team.addListeningWindow(cw);
}
else
// AROUND ME
if (nlstricmp(sParams, "am") == 0)
{
if (ci.AroundMe.isListeningWindow(cw)) ci.AroundMe.removeListeningWindow(cw);
else ci.AroundMe.addListeningWindow(cw);
}
else
// REGION
if (nlstricmp(sParams, "region") == 0)
{
if (ci.Region.isListeningWindow(cw)) ci.Region.removeListeningWindow(cw);
else ci.Region.addListeningWindow(cw);
}
else
// UNIVERSE
if (nlstricmp(sParams, "universe") == 0)
{
if (ci.Universe.isListeningWindow(cw)) ci.Universe.removeListeningWindow(cw);
else ci.Universe.addListeningWindow(cw);
}
else
// TELL
if (nlstricmp(sParams, "tell") == 0)
{
if (ci.Tell.isListeningWindow(cw)) ci.Tell.removeListeningWindow(cw);
else ci.Tell.addListeningWindow(cw);
}
else
// SYSTEM INFOS
if (nlstricmp(sParams, "si") == 0)
{
if (ci.SystemInfo.isListeningWindow(cw)) ci.SystemInfo.removeListeningWindow(cw);
else ci.SystemInfo.addListeningWindow(cw);
}
else
// PARTY CHAT
if (fromString(sParams, partyChatID))
{
std::vector<CPartyChatInfo> &partyChats = PeopleInterraction.PartyChats;
for(uint k = 0; k < partyChats.size(); ++k)
{ {
if (partyChats[k].ID == (uint) partyChatID) if (ci.Team.isListeningWindow(cw)) ci.Team.removeListeningWindow(cw);
else ci.Team.addListeningWindow(cw);
}
else
// AROUND ME
if (nlstricmp(sParams, "am") == 0)
{ {
if (partyChats[k].Filter != NULL) if (ci.AroundMe.isListeningWindow(cw)) ci.AroundMe.removeListeningWindow(cw);
else ci.AroundMe.addListeningWindow(cw);
}
else
// REGION
if (nlstricmp(sParams, "region") == 0)
{ {
if (partyChats[k].Filter->isListeningWindow(cw)) partyChats[k].Filter->removeListeningWindow(partyChats[k].Window); if (ci.Region.isListeningWindow(cw)) ci.Region.removeListeningWindow(cw);
else partyChats[k].Filter->addListeningWindow(cw); else ci.Region.addListeningWindow(cw);
} }
} else
} // UNIVERSE
} if (nlstricmp(sParams, "universe") == 0)
else if (nlstricmp(sParams.substr(0, 3), "dyn") == 0) {
{ if (ci.Universe.isListeningWindow(cw)) ci.Universe.removeListeningWindow(cw);
uint8 i = 0; else ci.Universe.addListeningWindow(cw);
fromString(sParams.substr(3), i); }
if (ci.DynamicChat[i].isListeningWindow(cw)) ci.DynamicChat[i].removeListeningWindow(cw); else
else ci.DynamicChat[i].addListeningWindow(cw); // TELL
} if (nlstricmp(sParams, "tell") == 0)
{
if (ci.Tell.isListeningWindow(cw)) ci.Tell.removeListeningWindow(cw);
else ci.Tell.addListeningWindow(cw);
}
else
// SYSTEM INFOS
if (nlstricmp(sParams, "si") == 0)
{
if (ci.SystemInfo.isListeningWindow(cw)) ci.SystemInfo.removeListeningWindow(cw);
else ci.SystemInfo.addListeningWindow(cw);
}
else
// PARTY CHAT
if (fromString(sParams, partyChatID))
{
std::vector<CPartyChatInfo> &partyChats = PeopleInterraction.PartyChats;
for(uint k = 0; k < partyChats.size(); ++k)
{
if (partyChats[k].ID == (uint) partyChatID)
{
if (partyChats[k].Filter != NULL)
{
if (partyChats[k].Filter->isListeningWindow(cw)) partyChats[k].Filter->removeListeningWindow(partyChats[k].Window);
else partyChats[k].Filter->addListeningWindow(cw);
}
}
}
}
else if (nlstricmp(sParams.substr(0, 3), "dyn") == 0)
{
uint8 i = 0;
fromString(sParams.substr(3), i);
if (ci.DynamicChat[i].isListeningWindow(cw)) ci.DynamicChat[i].removeListeningWindow(cw);
else ci.DynamicChat[i].addListeningWindow(cw);
}
} }
}; };
REGISTER_ACTION_HANDLER( CHandlerChatSourceSelected, "chat_source_selected"); REGISTER_ACTION_HANDLER( CHandlerChatSourceSelected, "chat_source_selected");
@ -3186,80 +3243,80 @@ NLMISC_COMMAND(ignore, "add or remove a player from the ignore list", "<player n
} // ignore // } // ignore //
/* /*
**** ****
Yoyo: Party chat is not ended: DON'T LET THOSE COMMANDS AVAILABLE! Yoyo: Party chat is not ended: DON'T LET THOSE COMMANDS AVAILABLE!
they made the client crash (cf createNewPartyChat)... they made the client crash (cf createNewPartyChat)...
**** ****
// create a new party chat with the given name // create a new party chat with the given name
NLMISC_COMMAND(party_chat, "Create a new party chat", "<party_chat_name>") NLMISC_COMMAND(party_chat, "Create a new party chat", "<party_chat_name>")
{ {
if (args.size() != 1) if (args.size() != 1)
{ {
displayVisibleSystemMsg(CI18N::get("uiPartyChatCmd")); displayVisibleSystemMsg(CI18N::get("uiPartyChatCmd"));
return true; return true;
} }
CPeopleInterraction &pi = PeopleInterraction; CPeopleInterraction &pi = PeopleInterraction;
ucstring title = args[0]; ucstring title = args[0];
if (!pi.testValidPartyChatName(title)) if (!pi.testValidPartyChatName(title))
{ {
displayVisibleSystemMsg(CI18N::get("uiInvalidPartyChatName")); displayVisibleSystemMsg(CI18N::get("uiInvalidPartyChatName"));
return true; return true;
} }
PeopleInterraction.createNewPartyChat(title); PeopleInterraction.createNewPartyChat(title);
return true; return true;
} }
// Remove the party chat with the given name // Remove the party chat with the given name
NLMISC_COMMAND(remove_party_chat, "Remove a party chat", "<party_chat_name>") NLMISC_COMMAND(remove_party_chat, "Remove a party chat", "<party_chat_name>")
{ {
if (args.size() != 1) if (args.size() != 1)
{ {
displayVisibleSystemMsg(CI18N::get("uiRemovePartyChatCmd")); displayVisibleSystemMsg(CI18N::get("uiRemovePartyChatCmd"));
return true; return true;
} }
ucstring title = ucstring(args[0]); ucstring title = ucstring(args[0]);
CChatWindow *chat = getChatWndMgr().getChatWindow(title); CChatWindow *chat = getChatWndMgr().getChatWindow(title);
if (!chat) if (!chat)
{ {
displayVisibleSystemMsg(title + ucstring(" : ") + CI18N::get("uiBadPartyChatName")); displayVisibleSystemMsg(title + ucstring(" : ") + CI18N::get("uiBadPartyChatName"));
return true; return true;
} }
if (!PeopleInterraction.removePartyChat(chat)) if (!PeopleInterraction.removePartyChat(chat))
{ {
displayVisibleSystemMsg(title + ucstring(" : ") + CI18N::get("uiCantRemovePartyChat")); displayVisibleSystemMsg(title + ucstring(" : ") + CI18N::get("uiCantRemovePartyChat"));
return true; return true;
} }
return true; return true;
} }
// Join a party chat whose name is known // Join a party chat whose name is known
NLMISC_COMMAND(add_to_party_chat, "Join the given party chat", "<party_chat_name>") NLMISC_COMMAND(add_to_party_chat, "Join the given party chat", "<party_chat_name>")
{ {
if (args.size() != 1) if (args.size() != 1)
{ {
displayVisibleSystemMsg(CI18N::get("uiAddPartyChatCmd")); displayVisibleSystemMsg(CI18N::get("uiAddPartyChatCmd"));
return true; return true;
} }
// TODO GAMEDEV : join the party chat // TODO GAMEDEV : join the party chat
return true; return true;
} }
// Invite someone in a party chat // Invite someone in a party chat
NLMISC_COMMAND(invite, "Invite someone to a party chat", "<people_name> <party_chat_name>") NLMISC_COMMAND(invite, "Invite someone to a party chat", "<people_name> <party_chat_name>")
{ {
if (args.size() != 2) if (args.size() != 2)
{ {
displayVisibleSystemMsg(CI18N::get("uiInviteCmd")); displayVisibleSystemMsg(CI18N::get("uiInviteCmd"));
return true; return true;
} }
// TODO GAMEDEV : Send invite message to the server // TODO GAMEDEV : Send invite message to the server
// Check that the inviter has created the chat ? // Check that the inviter has created the chat ?
// The people being invited should receive a popup to announce that he is being invited // The people being invited should receive a popup to announce that he is being invited
return true; return true;
} }
*/ */

@ -31,6 +31,7 @@
#include "chat_text_manager.h" #include "chat_text_manager.h"
#include "people_interraction.h" #include "people_interraction.h"
#include "../user_entity.h" #include "../user_entity.h"
#include "nel/misc/o_xml.h"
using namespace std; using namespace std;
using namespace NLMISC; using namespace NLMISC;
@ -49,9 +50,9 @@ extern CClientChatManager ChatMngr;
//================================================================== //==================================================================
CPeopleList::CPeopleList() : _ChatWindow(NULL), CPeopleList::CPeopleList() : _ChatWindow(NULL),
_ContactType(CPeopleListDesc::Unknown), _ContactType(CPeopleListDesc::Unknown),
_CurrPeopleID(0), _CurrPeopleID(0),
_Savable(false) _Savable(false)
{ {
// Construct // Construct
@ -191,34 +192,41 @@ sint CPeopleList::getIndexFromContainerID(const std::string &id) const
//================================================================== //==================================================================
bool CPeopleList::sortExByContactId(const CPeople& a, const CPeople& b) bool CPeopleList::sortExByContactId(const CPeople& a, const CPeople& b)
{ {
return (a.ContactId < b.ContactId); if (a.Group == b.Group)
return (a.ContactId < b.ContactId);
else
return (a.Group < b.Group);
} }
//================================================================== //==================================================================
bool CPeopleList::sortExByName(const CPeople& a, const CPeople& b) bool CPeopleList::sortExByName(const CPeople& a, const CPeople& b)
{ {
ucstring name_a = toUpper(a.getName()); if (a.Group == b.Group) {
ucstring name_b = toUpper(b.getName()); ucstring name_a = toUpper(a.getName());
ucstring name_b = toUpper(b.getName());
return (name_a < name_b); return (name_a < name_b);
}
else
return (a.Group < b.Group);
} }
//================================================================== //==================================================================
bool CPeopleList::sortExByOnline(const CPeople& a, const CPeople& b) bool CPeopleList::sortExByOnline(const CPeople& a, const CPeople& b)
{ {
ucstring name_a = toUpper(a.getName()); if (a.Group == b.Group) {
ucstring name_b = toUpper(b.getName()); ucstring name_a = toUpper(a.getName());
ucstring name_b = toUpper(b.getName());
// We want order: online/alpha, offworld/alpha, offline/alpha // We want order: online/alpha, offworld/alpha, offline/alpha
if (a.Online == b.Online) if (a.Online == b.Online)
{
return (name_a < name_b);
}
else
{
// Compare online status
switch (a.Online)
{ {
return (name_a < name_b);
}
else
{
// Compare online status
switch (a.Online)
{
case ccs_online: case ccs_online:
// a is > if a is online // a is > if a is online
return true; return true;
@ -232,11 +240,11 @@ bool CPeopleList::sortExByOnline(const CPeople& a, const CPeople& b)
// b is always > if a is offline // b is always > if a is offline
return false; return false;
break; break;
}
} }
} }
else
// Should not get here so just return something return (a.Group < b.Group);
return true;
} }
//================================================================== //==================================================================
@ -245,29 +253,54 @@ void CPeopleList::sortEx(TSortOrder order)
// remove all people from the father container // remove all people from the father container
if (!_BaseContainer) return; if (!_BaseContainer) return;
uint k; uint k;
for(k = 0; k < _Peoples.size(); ++k) for(k = 0; k < _Peoples.size(); ++k)
{ {
_BaseContainer->detachContainer(_Peoples[k].Container); CGroupContainer *parentContainer = _Peoples[k].Container->getProprietaryContainer();
parentContainer->detachContainer(_Peoples[k].Container);
}
for (k = 0; k < _GroupContainers.size(); ++k)
{
if (_GroupContainers[k].second->getProprietaryContainer() != NULL)
_BaseContainer->detachContainer(_GroupContainers[k].second);
} }
switch (order) switch (order)
{ {
default: default:
case sort_index: case sort_index:
std::sort(_Peoples.begin(), _Peoples.end(), CPeopleList::sortExByContactId); std::sort(_Peoples.begin(), _Peoples.end(), CPeopleList::sortExByContactId);
break; break;
case sort_name: case sort_name:
std::sort(_Peoples.begin(), _Peoples.end(), CPeopleList::sortExByName); std::sort(_Peoples.begin(), _Peoples.end(), CPeopleList::sortExByName);
break; break;
case sort_online: case sort_online:
std::sort(_Peoples.begin(), _Peoples.end(), CPeopleList::sortExByOnline); std::sort(_Peoples.begin(), _Peoples.end(), CPeopleList::sortExByOnline);
break; break;
} }
CGroupContainer *group = _BaseContainer;
uint groupIndex = 0;
for(k = 0; k < _Peoples.size(); ++k) for(k = 0; k < _Peoples.size(); ++k)
{ {
_BaseContainer->attachContainer(_Peoples[k].Container); bool newGroup = false;
if (k == 0)
{
newGroup = true;
}
while (groupIndex < _GroupContainers.size() && _GroupContainers[groupIndex].first != _Peoples[k].Group.toString())
{
newGroup = true;
++groupIndex;
}
if (newGroup && groupIndex < _GroupContainers.size() && _GroupContainers.size() > 1)
{
group = _GroupContainers[groupIndex].second;
_BaseContainer->attachContainer(group);
}
group->attachContainer(_Peoples[k].Container);
} }
} }
@ -299,34 +332,34 @@ bool CPeopleList::isPeopleChatVisible(uint index) const
return (_Peoples[index].Chat != NULL); return (_Peoples[index].Chat != NULL);
} }
/* /*
bool CPeopleList::isPeopleWindowVisible(uint index) const bool CPeopleList::isPeopleWindowVisible(uint index) const
{ {
if (index >= _Peoples.size()) if (index >= _Peoples.size())
{ {
nlwarning("Bad index"); nlwarning("Bad index");
return false; return false;
} }
if (!_Peoples[index].Container) return false; if (!_Peoples[index].Container) return false;
if (_Peoples[index].Container->isOpen()) if (_Peoples[index].Container->isOpen())
{ {
CInterfaceGroup *ig = _Peoples[index].Container; CInterfaceGroup *ig = _Peoples[index].Container;
do do
{ {
if (ig->isGroupContainer()) if (ig->isGroupContainer())
{ {
if (!static_cast<CGroupContainer *>(ig)->isOpen()) break; if (!static_cast<CGroupContainer *>(ig)->isOpen()) break;
} }
if (!ig->getActive()) break; if (!ig->getActive()) break;
ig = ig->getParent(); ig = ig->getParent();
} }
while(ig); while(ig);
return ig == NULL; // all parent windows must be open & visible return ig == NULL; // all parent windows must be open & visible
} }
else else
{ {
return false; return false;
} }
} }
*/ */
//================================================================== //==================================================================
@ -354,12 +387,12 @@ sint CPeopleList::addPeople(const ucstring &name, uint teamMateIndex /*= 0*/)
std::string templateName; std::string templateName;
switch (_ContactType) switch (_ContactType)
{ {
case CPeopleListDesc::Team: templateName = "mate_id"; break; case CPeopleListDesc::Team: templateName = "mate_id"; break;
case CPeopleListDesc::Contact: templateName = "contact_id_friend"; break; case CPeopleListDesc::Contact: templateName = "contact_id_friend"; break;
case CPeopleListDesc::Ignore: templateName = "contact_id_ignore"; break; case CPeopleListDesc::Ignore: templateName = "contact_id_ignore"; break;
default: default:
nlwarning("<CPeopleList::addPeople> Unknown contact type"); nlwarning("<CPeopleList::addPeople> Unknown contact type");
return -1; return -1;
break; break;
} }
@ -379,10 +412,10 @@ sint CPeopleList::addPeople(const ucstring &name, uint teamMateIndex /*= 0*/)
gc->setSavable(false); gc->setSavable(false);
// //
/*if (_ChatWindow) /*if (_ChatWindow)
{ {
_ChatWindow->getContainer()->attachContainer(gc); _ChatWindow->getContainer()->attachContainer(gc);
} }
else*/ else*/
{ {
_BaseContainer->attachContainer(gc); _BaseContainer->attachContainer(gc);
} }
@ -415,8 +448,9 @@ void CPeopleList::removePeople(uint index)
} }
else else
{ {
if (_BaseContainer) CGroupContainer *parentContainer = _Peoples[index].Container->getProprietaryContainer();
_BaseContainer->detachContainer(_Peoples[index].Container); if (parentContainer)
parentContainer->detachContainer(_Peoples[index].Container);
} }
CInterfaceManager *im = CInterfaceManager::getInstance(); CInterfaceManager *im = CInterfaceManager::getInstance();
CInterfaceGroup *pRoot = dynamic_cast<CInterfaceGroup*>(CWidgetManager::getInstance()->getElementFromId("ui:interface")); CInterfaceGroup *pRoot = dynamic_cast<CInterfaceGroup*>(CWidgetManager::getInstance()->getElementFromId("ui:interface"));
@ -447,6 +481,169 @@ void CPeopleList::setContactId(uint index, uint32 contactId)
_Peoples[index].ContactId = contactId; _Peoples[index].ContactId = contactId;
} }
//==================================================================
void CPeopleList::changeGroup(uint index, const ucstring &groupName)
{
if (index >= _Peoples.size())
{
nlwarning("<CPeopleList::changeGroup> bad index.");
return;
}
ucstring group = groupName;
if (group.toString() == "General")
group = ucstring("");
_Peoples[index].Group = group;
for (uint k = 0; k < _GroupContainers.size(); ++k)
{
if (_GroupContainers[k].first == group.toString())
return;
}
vector<pair<string, string> > properties;
properties.push_back(make_pair(string("posparent"), string("parent")));
properties.push_back(make_pair(string("id"), _ContainerID + "_group_" + toString(_GroupContainers.size())));
if (group.toString() == "")
properties.push_back(make_pair(string("title"), "General"));
else
properties.push_back(make_pair(string("title"), group.toString()));
CGroupContainer *gc = dynamic_cast<CGroupContainer *>(CWidgetManager::getInstance()->getParser()->createGroupInstance("people_list_group_header", "ui:interface", properties, false));
if (group.toString() == "")
gc->setUCTitle(ucstring("General"));
else
gc->setUCTitle(group.toString());
gc->setSavable(false);
CInterfaceGroup *pRoot = dynamic_cast<CInterfaceGroup*>(CWidgetManager::getInstance()->getElementFromId("ui:interface"));
pRoot->addGroup (gc);
_BaseContainer->attachContainer(gc);
_GroupContainers.push_back(make_pair(group.toString(), gc));
std::sort(_GroupContainers.begin(), _GroupContainers.end());
}
//==================================================================
void CPeopleList::readContactGroups()
{
_GroupContainers.clear();
// Create default group even if no groups defined
vector<pair<string, string> > properties;
properties.push_back(make_pair(string("posparent"), string("parent")));
properties.push_back(make_pair(string("id"), _ContainerID + "_group_0"));
properties.push_back(make_pair(string("title"), "General"));
CInterfaceGroup *group = CWidgetManager::getInstance()->getParser()->createGroupInstance("people_list_group_header", "ui:interface", properties, false);
CGroupContainer *gc = dynamic_cast<CGroupContainer *>(group);
gc->setUCTitle(ucstring("General"));
gc->setSavable(false);
CInterfaceGroup *pRoot = dynamic_cast<CInterfaceGroup*>(CWidgetManager::getInstance()->getElementFromId("ui:interface"));
pRoot->addGroup (gc);
_BaseContainer->attachContainer(gc);
_GroupContainers.push_back(make_pair("", gc));
const std::string filename = CInterfaceManager::getInstance()->getSaveFileName("contactgroups", "xml");
try
{
CIFile fd;
if (fd.open(CPath::lookup(filename)))
{
CIXml stream;
stream.init(fd);
xmlKeepBlanksDefault(0);
xmlNodePtr root = stream.getRootNode();
if (!root) return;
xmlNodePtr node = root->children;
uint nb = 0;
while (node)
{
CXMLAutoPtr propName;
propName = (char*) xmlGetProp(node, (xmlChar*)"name");
CXMLAutoPtr propGroup;
propGroup = (char*) xmlGetProp(node, (xmlChar*)"group");
if (propName && propGroup)
{
sint index = getIndexFromName(propName.str());
if (index < _Peoples.size())
{
_Peoples[index].Group = propGroup.str();
if (_GroupContainers.empty() || _GroupContainers.back().first != propGroup.str()) {
vector<pair<string, string> > properties;
properties.push_back(make_pair(string("posparent"), string("parent")));
properties.push_back(make_pair(string("id"), _ContainerID + "_group_" + toString(_GroupContainers.size())));
if (propGroup.str() == "")
properties.push_back(make_pair(string("title"), "General"));
else
properties.push_back(make_pair(string("title"), propGroup.str()));
CInterfaceGroup *group = CWidgetManager::getInstance()->getParser()->createGroupInstance("people_list_group_header", "ui:interface", properties, false);
CGroupContainer *gc = dynamic_cast<CGroupContainer *>(group);
if (propGroup.str() == "")
gc->setUCTitle(ucstring("General"));
else
gc->setUCTitle(propGroup.str());
gc->setSavable(false);
CInterfaceGroup *pRoot = dynamic_cast<CInterfaceGroup*>(CWidgetManager::getInstance()->getElementFromId("ui:interface"));
pRoot->addGroup (gc);
_BaseContainer->attachContainer(gc);
_GroupContainers.push_back(make_pair(propGroup.str(), gc));
}
}
}
node = node->next;
nb++;
}
fd.close();
}
std::sort(_GroupContainers.begin(), _GroupContainers.end());
}
catch (const Exception &e)
{
nlwarning("Error while parsing xml file %s : %s", filename.c_str(), e.what());
}
}
//==================================================================
void CPeopleList::saveContactGroups()
{
const std::string filename = CInterfaceManager::getInstance()->getSaveFileName("contactgroups", "xml");
try
{
COFile fd;
if (fd.open(filename, false, false, true))
{
COXml stream;
stream.init(&fd);
xmlDocPtr doc = stream.getDocument();
xmlNodePtr node = xmlNewDocNode(doc, NULL, (const xmlChar*)"contact_groups", NULL);
xmlDocSetRootElement(doc, node);
for (uint k = 0; k < _Peoples.size(); ++k)
{
xmlNodePtr newNode = xmlNewChild(node, NULL, (const xmlChar*)"contact", NULL);
xmlSetProp(newNode, (const xmlChar*)"name", (const xmlChar*)_Peoples[k].getName().toString().c_str());
xmlSetProp(newNode, (const xmlChar*)"group", (const xmlChar*)_Peoples[k].Group.toString().c_str());
}
stream.flush();
fd.close();
}
nlinfo("save %s", filename.c_str());
}
catch (const Exception &e)
{
nlwarning("Error while writing the file %s : %s", filename.c_str(), e.what());
}
}
//================================================================== //==================================================================
void CPeopleList::displayLocalPlayerTell(const ucstring &receiver, uint index, const ucstring &msg,uint numBlinks /*=0*/) void CPeopleList::displayLocalPlayerTell(const ucstring &receiver, uint index, const ucstring &msg,uint numBlinks /*=0*/)
{ {
@ -617,12 +814,12 @@ void CPeopleList::setPeopleMenu(const std::string &menuName)
} }
void CPeopleList::setPeopleMenuEx(const std::string &offlineUnblockedMenuName, void CPeopleList::setPeopleMenuEx(const std::string &offlineUnblockedMenuName,
const std::string &onlineUnblockedMenuName, const std::string &onlineUnblockedMenuName,
const std::string &onlineAbroadUnblockedMenuName, const std::string &onlineAbroadUnblockedMenuName,
const std::string &offlineBockedMenuName, const std::string &offlineBockedMenuName,
const std::string &onlineBlockedMenuName, const std::string &onlineBlockedMenuName,
const std::string &onlineAbroadBlockedMenuName const std::string &onlineAbroadBlockedMenuName
) )
{ {
_PeopleMenuOfflineUnblocked = offlineUnblockedMenuName; _PeopleMenuOfflineUnblocked = offlineUnblockedMenuName;
_PeopleMenuOnlineUnblocked = onlineUnblockedMenuName; _PeopleMenuOnlineUnblocked = onlineUnblockedMenuName;

@ -110,6 +110,11 @@ public:
void setContactId(uint index, uint32 contactId); void setContactId(uint index, uint32 contactId);
sint getIndexFromContactId(uint32 contactId); sint getIndexFromContactId(uint32 contactId);
// For Friend Groups management
void changeGroup(uint index, const ucstring &groupName);
void readContactGroups();
void saveContactGroups();
/** Display a message for the given people /** Display a message for the given people
* If the window is closed, it causes it to blink (and also the parent window) * If the window is closed, it causes it to blink (and also the parent window)
*/ */
@ -151,19 +156,21 @@ public:
private: private:
struct CPeople struct CPeople
{ {
CPeople() : Container(NULL), Chat(NULL), Online(ccs_offline), Blocked(false), ContactId(0) {} CPeople() : Container(NULL), Chat(NULL), Online(ccs_offline), Blocked(false), ContactId(0), Group("") {}
NLMISC::CRefPtr<CGroupContainer> Container; // todo : replace this with a CChatWindow one day, for consistency NLMISC::CRefPtr<CGroupContainer> Container; // todo : replace this with a CChatWindow one day, for consistency
NLMISC::CRefPtr<CGroupContainer> Chat; NLMISC::CRefPtr<CGroupContainer> Chat;
uint GlobalID; uint GlobalID;
TCharConnectionState Online; TCharConnectionState Online;
bool Blocked; bool Blocked;
uint32 ContactId; uint32 ContactId;
ucstring Group;
bool operator < (const CPeople &other) const { return getName() < other.getName(); } bool operator < (const CPeople &other) const { return getName() < other.getName(); }
ucstring getName() const { return Container->getUCTitle(); } ucstring getName() const { return Container->getUCTitle(); }
}; };
typedef std::vector<CPeople> TPeopleVect; typedef std::vector<CPeople> TPeopleVect;
private: private:
CGroupContainerPtr _BaseContainer; CGroupContainerPtr _BaseContainer;
std::vector<std::pair<std::string, NLMISC::CRefPtr<CGroupContainer> > > _GroupContainers;
NLMISC::CRefPtr<CChatWindow> _ChatWindow; NLMISC::CRefPtr<CChatWindow> _ChatWindow;
TPeopleVect _Peoples; TPeopleVect _Peoples;
CPeopleListDesc::TContactType _ContactType; CPeopleListDesc::TContactType _ContactType;

Loading…
Cancel
Save