linuxdcpp-team team mailing list archive
-
linuxdcpp-team team
-
Mailing list archive
-
Message #02695
[Branch ~dcplusplus-team/dcplusplus/trunk] Rev 2333: Add user information tooltips
------------------------------------------------------------
revno: 2333
committer: poy <poy@xxxxxxxxxx>
branch nick: trunk
timestamp: Wed 2010-12-08 17:54:29 +0100
message:
Add user information tooltips
modified:
changelog.txt
dcpp/ClientManager.cpp
dcpp/ClientManager.h
dcpp/User.cpp
dcpp/User.h
dcpp/Util.cpp
dcpp/Util.h
dwt/include/dwt/util/StringUtils.h
dwt/include/dwt/widgets/Table.h
dwt/src/util/StringUtils.cpp
dwt/src/widgets/TabView.cpp
dwt/src/widgets/Table.cpp
win32/HubFrame.cpp
win32/TransferView.cpp
win32/UserInfoBase.cpp
win32/UserInfoBase.h
win32/UsersFrame.cpp
win32/WinUtil.h
--
lp:dcplusplus
https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk
Your team Dcplusplus-team is subscribed to branch lp:dcplusplus.
To unsubscribe from this branch go to https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk/+edit-subscription
=== modified file 'changelog.txt'
--- changelog.txt 2010-12-05 18:59:52 +0000
+++ changelog.txt 2010-12-08 16:54:29 +0000
@@ -51,6 +51,7 @@
* [L#534242] Better looking settings dialog (fleetcommand, poy)
* Allow regular expressions in ADL searches (poy)
* [L#395464] [ADC] Send "000" as the STA success code
+* Add user information tooltips (poy)
-- 0.770 2010-07-05 --
* [L#550300] Catch more potential file corruptions (thanks bigmuscle)
=== modified file 'dcpp/ClientManager.cpp'
--- dcpp/ClientManager.cpp 2010-08-27 13:47:33 +0000
+++ dcpp/ClientManager.cpp 2010-12-08 16:54:29 +0000
@@ -324,7 +324,7 @@
}
}
-OnlineUser* ClientManager::findOnlineUser_hint(const CID& cid, const string& hintUrl, OnlinePair& p) throw() {
+OnlineUser* ClientManager::findOnlineUser_hint(const CID& cid, const string& hintUrl, OnlinePair& p) {
p = onlineUsers.equal_range(cid);
if(p.first == p.second) // no user found with the given CID.
return 0;
@@ -341,7 +341,11 @@
return 0;
}
-OnlineUser* ClientManager::findOnlineUser(const CID& cid, const string& hintUrl, bool priv) throw() {
+OnlineUser* ClientManager::findOnlineUser(const HintedUser& user, bool priv) {
+ return findOnlineUser(user.user->getCID(), user.hint, priv);
+}
+
+OnlineUser* ClientManager::findOnlineUser(const CID& cid, const string& hintUrl, bool priv) {
OnlinePair p;
OnlineUser* u = findOnlineUser_hint(cid, hintUrl, p);
if(u) // found an exact match (CID + hint).
@@ -362,7 +366,7 @@
bool priv = FavoriteManager::getInstance()->isPrivate(user.hint);
Lock l(cs);
- OnlineUser* u = findOnlineUser(user.user->getCID(), user.hint, priv);
+ OnlineUser* u = findOnlineUser(user, priv);
if(u) {
u->getClient().connect(*u, token);
@@ -373,7 +377,7 @@
bool priv = FavoriteManager::getInstance()->isPrivate(user.hint);
Lock l(cs);
- OnlineUser* u = findOnlineUser(user.user->getCID(), user.hint, priv);
+ OnlineUser* u = findOnlineUser(user, priv);
if(u) {
u->getClient().privateMessage(*u, msg, thirdPerson);
=== modified file 'dcpp/ClientManager.h'
--- dcpp/ClientManager.h 2010-08-27 13:47:33 +0000
+++ dcpp/ClientManager.h 2010-12-08 16:54:29 +0000
@@ -73,7 +73,8 @@
* @param priv discard any user that doesn't match the hint.
* @return OnlineUser* found by CID and hint; might be only by CID if priv is false.
*/
- OnlineUser* findOnlineUser(const CID& cid, const string& hintUrl, bool priv) throw();
+ OnlineUser* findOnlineUser(const HintedUser& user, bool priv);
+ OnlineUser* findOnlineUser(const CID& cid, const string& hintUrl, bool priv);
UserPtr findUser(const string& aNick, const string& aHubUrl) const throw() { return findUser(makeCid(aNick, aHubUrl)); }
UserPtr findUser(const CID& cid) const throw();
@@ -156,7 +157,7 @@
void updateNick(const OnlineUser& user) throw();
/// @return OnlineUser* found by CID and hint; discard any user that doesn't match the hint.
- OnlineUser* findOnlineUser_hint(const CID& cid, const string& hintUrl) throw() {
+ OnlineUser* findOnlineUser_hint(const CID& cid, const string& hintUrl) {
OnlinePair p;
return findOnlineUser_hint(cid, hintUrl, p);
}
@@ -164,7 +165,7 @@
* @param p OnlinePair of all the users found by CID, even those who don't match the hint.
* @return OnlineUser* found by CID and hint; discard any user that doesn't match the hint.
*/
- OnlineUser* findOnlineUser_hint(const CID& cid, const string& hintUrl, OnlinePair& p) throw();
+ OnlineUser* findOnlineUser_hint(const CID& cid, const string& hintUrl, OnlinePair& p);
string getUsersFile() const { return Util::getPath(Util::PATH_USER_LOCAL) + "Users.xml"; }
=== modified file 'dcpp/User.cpp'
--- dcpp/User.cpp 2010-02-11 21:44:13 +0000
+++ dcpp/User.cpp 2010-12-08 16:54:29 +0000
@@ -90,6 +90,10 @@
get("HR") + "/" + get("HO") + ",S:" + get("SL") + ">";
}
+string Identity::getCountry() const {
+ return Util::getIpCountry(getIp());
+}
+
string Identity::get(const char* name) const {
FastLock l(cs);
InfMap::const_iterator i = info.find(*(short*)name);
=== modified file 'dcpp/User.h'
--- dcpp/User.h 2010-12-03 17:26:12 +0000
+++ dcpp/User.h 2010-12-08 16:54:29 +0000
@@ -139,6 +139,7 @@
void setBot(bool bot) { set("BO", bot ? "1" : Util::emptyString); }
void setHidden(bool hidden) { set("HI", hidden ? "1" : Util::emptyString); }
string getTag() const;
+ string getCountry() const;
bool supports(const string& name) const;
bool isHub() const { return isClientType(CT_HUB) || isSet("HU"); }
bool isOp() const { return isClientType(CT_OP) || isClientType(CT_SU) || isClientType(CT_OWNER) || isSet("OP"); }
=== modified file 'dcpp/Util.cpp'
--- dcpp/Util.cpp 2010-12-01 16:03:18 +0000
+++ dcpp/Util.cpp 2010-12-08 16:54:29 +0000
@@ -899,9 +899,10 @@
for exemple: it returns "PT", whitch standards for "Portugal"
more info: http://www.maxmind.com/app/csv
*/
-string Util::getIpCountry (string IP) {
- if (BOOLSETTING(GET_USER_COUNTRY)) {
- dcassert(count(IP.begin(), IP.end(), '.') == 3);
+string Util::getIpCountry(const string& IP) {
+ if(BOOLSETTING(GET_USER_COUNTRY)) {
+ if(count(IP.begin(), IP.end(), '.') != 3)
+ return Util::emptyString;
//e.g IP 23.24.25.26 : w=23, x=24, y=25, z=26
string::size_type a = IP.find('.');
@@ -920,7 +921,7 @@
}
}
- return Util::emptyString; //if doesn't returned anything already, something is wrong...
+ return Util::emptyString;
}
string Util::getTimeString() {
=== modified file 'dcpp/Util.h'
--- dcpp/Util.h 2010-12-01 16:03:18 +0000
+++ dcpp/Util.h 2010-12-08 16:54:29 +0000
@@ -412,7 +412,7 @@
static int stricmp(const wstring& a, const wstring& b) { return stricmp(a.c_str(), b.c_str()); }
static int strnicmp(const wstring& a, const wstring& b, size_t n) { return strnicmp(a.c_str(), b.c_str(), n); }
- static string getIpCountry (string IP);
+ static string getIpCountry(const string& IP);
static bool getAway() { return away; }
static void setAway(bool aAway) {
=== modified file 'dwt/include/dwt/util/StringUtils.h'
--- dwt/include/dwt/util/StringUtils.h 2010-02-11 21:44:13 +0000
+++ dwt/include/dwt/util/StringUtils.h 2010-12-08 16:54:29 +0000
@@ -38,6 +38,8 @@
tstring escapeMenu(tstring str);
+void cutStr(tstring& str, size_t n);
+
} }
#endif /*STRINGUTILS_H_*/
=== modified file 'dwt/include/dwt/widgets/Table.h'
--- dwt/include/dwt/widgets/Table.h 2010-07-10 14:36:48 +0000
+++ dwt/include/dwt/widgets/Table.h 2010-12-08 16:54:29 +0000
@@ -79,18 +79,26 @@
{
typedef CommonControl BaseType;
- struct HeaderDispatcher {
- typedef std::function<void (int)> F;
-
- HeaderDispatcher(const F& f_) : f(f_) { }
-
- bool operator()(const MSG& msg, LRESULT& ret) const {
- LPNMLISTVIEW p = (LPNMLISTVIEW) msg.lParam;
- f(p->iSubItem);
- return true;
- }
-
- F f;
+ struct HeaderDispatcher : Dispatchers::Base<void (int)> {
+ typedef Dispatchers::Base<void (int)> BaseType;
+ HeaderDispatcher(const F& f_) : BaseType(f_) { }
+
+ bool operator()(const MSG& msg, LRESULT& ret) const {
+ f(reinterpret_cast<LPNMLISTVIEW>(msg.lParam)->iSubItem);
+ return true;
+ }
+ };
+
+ struct TooltipDispatcher : Dispatchers::Base<tstring (int)> {
+ typedef Dispatchers::Base<tstring (int)> BaseType;
+ TooltipDispatcher(const F& f_) : BaseType(f_) { }
+
+ bool operator()(const MSG& msg, LRESULT& ret) const {
+ NMLVGETINFOTIP& tip = *reinterpret_cast<LPNMLVGETINFOTIP>(msg.lParam);
+ tstring text(f(tip.iItem));
+ _tcscpy_s(tip.pszText, tip.cchTextMax, text.c_str());
+ return true;
+ }
};
// Need to be friend to access private data...
@@ -353,6 +361,8 @@
*/
void setSingleRowSelection( bool value = true );
+ void setTooltips(const TooltipDispatcher::F& f);
+
/// Adds (or removes) grid lines.
/** A grid with grid lines will have lines surrounding every cell in it. <br>
* value defines if we're supposed to add grid lines or remove them. <br>
=== modified file 'dwt/src/util/StringUtils.cpp'
--- dwt/src/util/StringUtils.cpp 2010-02-11 21:44:13 +0000
+++ dwt/src/util/StringUtils.cpp 2010-12-08 16:54:29 +0000
@@ -43,4 +43,9 @@
return str;
}
+void cutStr(tstring& str, size_t n) {
+ if(str.size() > n)
+ str = str.substr(0, n - 3) + _T("...");
+}
+
} }
=== modified file 'dwt/src/widgets/TabView.cpp'
--- dwt/src/widgets/TabView.cpp 2010-10-28 22:43:23 +0000
+++ dwt/src/widgets/TabView.cpp 2010-12-08 16:54:29 +0000
@@ -387,8 +387,8 @@
}
tstring TabView::formatTitle(tstring title) {
- if(widthConfig && title.length() > widthConfig)
- title = title.substr(0, widthConfig - 3) + _T("...");
+ if(widthConfig)
+ util::cutStr(title, widthConfig);
return util::escapeMenu(title);
}
=== modified file 'dwt/src/widgets/Table.cpp'
--- dwt/src/widgets/Table.cpp 2010-07-10 14:36:48 +0000
+++ dwt/src/widgets/Table.cpp 2010-12-08 16:54:29 +0000
@@ -149,8 +149,8 @@
ListView_SetItemState(handle(), item, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
}
-void Table::selectAll() {
- for(size_t i = 0, n = size(); i < n; ++i)
+void Table::selectAll() {
+ for(size_t i = 0, n = size(); i < n; ++i)
setSelected(i);
}
@@ -554,4 +554,9 @@
return ListView_HitTest(handle(), &lvi);
}
+void Table::setTooltips(const TooltipDispatcher::F& f) {
+ addRemoveTableExtendedStyle(LVS_EX_INFOTIP, true);
+ addCallback(Message(WM_NOTIFY, LVN_GETINFOTIP), TooltipDispatcher(f));
+}
+
}
=== modified file 'win32/HubFrame.cpp'
--- win32/HubFrame.cpp 2010-12-03 18:27:30 +0000
+++ win32/HubFrame.cpp 2010-12-08 16:54:29 +0000
@@ -162,6 +162,8 @@
users->onKeyDown(std::bind(&HubFrame::handleUsersKeyDown, this, _1));
users->onContextMenu(std::bind(&HubFrame::handleUsersContextMenu, this, _1));
+ prepareUserList(users, true);
+
TextBox::Seed cs = WinUtil::Seeds::textBox;
cs.style |= ES_AUTOHSCROLL;
filter = userGrid->addChild(cs);
@@ -639,10 +641,8 @@
columns[COLUMN_DESCRIPTION] = Text::toT(identity.getDescription());
columns[COLUMN_TAG] = Text::toT(identity.getTag());
columns[COLUMN_CONNECTION] = Text::toT(identity.getConnection());
- string ip = identity.getIp();
- string country = ip.empty()?Util::emptyString:Util::getIpCountry(ip);
- columns[COLUMN_IP] = Text::toT(ip);
- columns[COLUMN_COUNTRY] = Text::toT(country);
+ columns[COLUMN_IP] = Text::toT(identity.getIp());
+ columns[COLUMN_COUNTRY] = Text::toT(identity.getCountry());
columns[COLUMN_EMAIL] = Text::toT(identity.getEmail());
columns[COLUMN_CID] = Text::toT(identity.getUser()->getCID().toBase32());
=== modified file 'win32/TransferView.cpp'
--- win32/TransferView.cpp 2010-12-03 13:59:16 +0000
+++ win32/TransferView.cpp 2010-12-08 16:54:29 +0000
@@ -125,6 +125,8 @@
connections->onKeyDown(std::bind(&TransferView::handleKeyDown, this, _1));
connections->onDblClicked(std::bind(&TransferView::handleDblClicked, this));
connections->onRaw(std::bind(&TransferView::handleCustomDraw, this, _1, _2), dwt::Message(WM_NOTIFY, NM_CUSTOMDRAW));
+
+ prepareUserList(connections);
}
{
=== modified file 'win32/UserInfoBase.cpp'
--- win32/UserInfoBase.cpp 2010-02-11 21:44:13 +0000
+++ win32/UserInfoBase.cpp 2010-12-08 16:54:29 +0000
@@ -20,12 +20,15 @@
#include "UserInfoBase.h"
+#include <dcpp/ClientManager.h>
+#include <dcpp/FavoriteManager.h>
+#include <dcpp/LogManager.h>
#include <dcpp/QueueManager.h>
-#include <dcpp/LogManager.h>
-#include <dcpp/FavoriteManager.h>
#include <dcpp/UploadManager.h>
#include <dcpp/User.h>
+#include <dwt/util/StringUtils.h>
+
#include "PrivateFrame.h"
#include "HubFrame.h"
@@ -78,6 +81,57 @@
}
}
+const size_t maxChars = 100; // max chars per tooltip line
+
+tstring UserInfoBase::getTooltip(bool priv) const {
+ bool hubSet = priv;
+ if(!priv)
+ priv = FavoriteManager::getInstance()->isPrivate(user.hint);
+
+ tstring ret(WinUtil::getNicks(user, priv));
+ dwt::util::cutStr(ret, maxChars);
+
+ auto addLine = [&ret](tstring line) {
+ dwt::util::cutStr(line, maxChars);
+ ret += _T("\r\n") + line;
+ };
+
+ if(!hubSet)
+ addLine(str(TF_("Hubs: %1%") % WinUtil::getHubNames(user, priv).first));
+
+ OnlineUser* ou = ClientManager::getInstance()->findOnlineUser(user, priv);
+ if(!ou)
+ return ret;
+ const Identity& id = ou->getIdentity();
+
+ auto getField = [&id](const char* code) -> tstring {
+ string field = id.get(code);
+ return field.empty() ? _T("?") : Text::toT(field);
+ };
+
+ if(id.isHidden())
+ addLine(T_("Hidden user"));
+ if(id.isBot())
+ addLine(T_("Bot"));
+ if(id.isOp())
+ addLine(T_("Hub operator"));
+ if(id.isAway())
+ addLine(T_("In away mode"));
+
+ addLine(str(TF_("Shared: %1%") % Text::toT(Util::formatBytes(id.getBytesShared()))));
+ addLine(str(TF_("Description: %1%") % Text::toT(id.getDescription())));
+ addLine(str(TF_("Tag: %1%") % Text::toT(id.getTag())));
+ addLine(str(TF_("Connection: %1%") % Text::toT(id.getConnection())));
+ addLine(str(TF_("IP: %1%") % getField("I4")));
+ const string country = id.getCountry();
+ if(!country.empty())
+ addLine(str(TF_("Country: %1%") % Text::toT(country)));
+ addLine(str(TF_("E-mail: %1%") % Text::toT(id.getEmail())));
+ addLine(str(TF_("Slots: %1%/%2%") % getField("FS") % getField("SL")));
+
+ return ret;
+}
+
void UserInfoBase::UserTraits::parse(UserInfoBase* ui) {
if(ui->getUser().user->isSet(User::NMDC))
adcOnly = false;
=== modified file 'win32/UserInfoBase.h'
--- win32/UserInfoBase.h 2010-07-10 14:36:48 +0000
+++ win32/UserInfoBase.h 2010-12-08 16:54:29 +0000
@@ -41,6 +41,8 @@
void removeFromQueue();
void connectFav(dwt::TabViewPtr);
+ tstring getTooltip(bool priv) const;
+
const HintedUser& getUser() const { return user; }
struct UserTraits {
@@ -140,6 +142,11 @@
menu->appendSeparator();
menu->appendItem(T_("Remove user from queue"), std::bind(&ThisType::handleRemoveFromQueue, this));
}
+
+ template<typename TableType>
+ void prepareUserList(TableType* table, bool priv = false) {
+ table->setTooltips([table, priv](int i) -> tstring { return table->getData(i)->getTooltip(priv); });
+ }
};
#endif /*USERINFOBASE_H_*/
=== modified file 'win32/UsersFrame.cpp'
--- win32/UsersFrame.cpp 2010-11-30 18:21:53 +0000
+++ win32/UsersFrame.cpp 2010-12-08 16:54:29 +0000
@@ -55,6 +55,8 @@
users->onKeyDown(std::bind(&UsersFrame::handleKeyDown, this, _1));
users->onRaw(std::bind(&UsersFrame::handleItemChanged, this, _2), dwt::Message(WM_NOTIFY, LVN_ITEMCHANGED));
users->onContextMenu(std::bind(&UsersFrame::handleContextMenu, this, _1));
+
+ prepareUserList(users);
}
{
=== modified file 'win32/WinUtil.h'
--- win32/WinUtil.h 2010-11-24 22:14:02 +0000
+++ win32/WinUtil.h 2010-12-08 16:54:29 +0000
@@ -167,12 +167,14 @@
static tstring getNicks(const UserPtr& u, const string& hintUrl);
static tstring getNicks(const CID& cid, const string& hintUrl, bool priv);
static tstring getNicks(const HintedUser& user) { return getNicks(user.user->getCID(), user.hint); }
+ static tstring getNicks(const HintedUser& user, bool priv) { return getNicks(user.user->getCID(), user.hint, priv); }
/** @return Pair of hubnames as a string and a bool representing the user's online status */
static pair<tstring, bool> getHubNames(const CID& cid, const string& hintUrl);
static pair<tstring, bool> getHubNames(const UserPtr& u, const string& hintUrl);
static pair<tstring, bool> getHubNames(const CID& cid, const string& hintUrl, bool priv);
static pair<tstring, bool> getHubNames(const HintedUser& user) { return getHubNames(user.user->getCID(), user.hint); }
+ static pair<tstring, bool> getHubNames(const HintedUser& user, bool priv) { return getHubNames(user.user->getCID(), user.hint, priv); }
static void reducePaths(string& message);