← Back to team overview

linuxdcpp-team team mailing list archive

[Branch ~dcplusplus-team/dcplusplus/trunk] Rev 2715: allow for more user matching customization

 

------------------------------------------------------------
revno: 2715
committer: poy <poy@xxxxxxxxxx>
branch nick: trunk
timestamp: Sun 2011-12-11 19:36:51 +0100
message:
  allow for more user matching customization
modified:
  dcpp/OnlineUser.h
  dcpp/User.cpp
  dcpp/UserMatch.h
  dcpp/UserMatchManager.cpp
  dcpp/UserMatchManager.h
  dcpp/forward.h
  win32/HubFrame.cpp
  win32/StylesPage.cpp
  win32/StylesPage.h
  win32/UserInfoBase.h
  win32/UserMatchDlg.cpp
  win32/UserMatchDlg.h
  win32/WinUtil.cpp


--
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 'dcpp/OnlineUser.h'
--- dcpp/OnlineUser.h	2011-12-04 14:56:09 +0000
+++ dcpp/OnlineUser.h	2011-12-11 18:36:51 +0000
@@ -53,32 +53,29 @@
 		CT_HIDDEN = 64
 	};
 
-	Identity() : sid(0) { }
-	Identity(const UserPtr& ptr, uint32_t aSID) : user(ptr), sid(aSID) { }
+	Identity() : sid(0), ignoreChat(false) { }
+	Identity(const UserPtr& ptr, uint32_t aSID) : user(ptr), sid(aSID), ignoreChat(false) { }
 	Identity(const Identity& rhs) : Flags(), sid(0) { *this = rhs; } // Use operator= since we have to lock before reading...
 	Identity& operator=(const Identity& rhs) {
 		FastLock l(cs);
 		*static_cast<Flags*>(this) = rhs;
 		user = rhs.user;
 		sid = rhs.sid;
-		match = rhs.match;
+		ignoreChat = rhs.ignoreChat;
+		style = rhs.style;
 		info = rhs.info;
 		return *this;
 	}
 
-// GS is already defined on some systems (e.g. OpenSolaris)
-#ifdef GS
-#undef GS
-#endif
-
-#define GS(n, x) string get##n() const { return get(x); } void set##n(const string& v) { set(x, v); }
-	GS(Nick, "NI")
-	GS(Description, "DE")
-	GS(Ip4, "I4")
-	GS(Ip6, "I6")
-	GS(Udp4Port, "U4")
-	GS(Udp6Port, "U6")
-	GS(Email, "EM")
+#define GETSET_FIELD(n, x) string get##n() const { return get(x); } void set##n(const string& v) { set(x, v); }
+	GETSET_FIELD(Nick, "NI")
+	GETSET_FIELD(Description, "DE")
+	GETSET_FIELD(Ip4, "I4")
+	GETSET_FIELD(Ip6, "I6")
+	GETSET_FIELD(Udp4Port, "U4")
+	GETSET_FIELD(Udp6Port, "U6")
+	GETSET_FIELD(Email, "EM")
+#undef GETSET_FIELD
 
 	void setBytesShared(const string& bs) { set("SS", bs); }
 	int64_t getBytesShared() const { return Util::toInt64(get("SS")); }
@@ -113,23 +110,30 @@
 	bool isSet(const char* name) const;
 	string getSIDString() const { return string((const char*)&sid, 4); }
 
-	UserMatchPropsPtr getMatch() const;
-	void setMatch(UserMatchPropsPtr match);
-	bool noChat() const;
-
 	bool isClientType(ClientType ct) const;
 
 	void getParams(ParamMap& params, const string& prefix, bool compatibility) const;
+
+	const UserPtr& getUser() const { return user; }
 	UserPtr& getUser() { return user; }
-	GETSET(UserPtr, user, User);
-	GETSET(uint32_t, sid, SID);
+	uint32_t getSID() const { return sid; }
+
+	bool noChat() const;
+	void setNoChat(bool ignoreChat);
+
+	Style getStyle() const;
+	void setStyle(Style&& style);
 
 private:
+	UserPtr user;
+	uint32_t sid;
+
 	typedef std::unordered_map<short, string> InfMap;
 	typedef InfMap::iterator InfIter;
 	InfMap info;
 
-	UserMatchPropsPtr match;
+	bool ignoreChat;
+	Style style;
 
 	static FastCriticalSection cs;
 };

=== modified file 'dcpp/User.cpp'
--- dcpp/User.cpp	2011-12-04 14:56:09 +0000
+++ dcpp/User.cpp	2011-12-11 18:36:51 +0000
@@ -190,19 +190,24 @@
 	return ret;
 }
 
-UserMatchPropsPtr Identity::getMatch() const {
-	FastLock l(cs);
-	return match;
-}
-
-void Identity::setMatch(UserMatchPropsPtr match) {
-	FastLock l(cs);
-	this->match = match;
-}
-
 bool Identity::noChat() const {
 	FastLock l(cs);
-	return match && match->noChat;
+	return ignoreChat;
+}
+
+void Identity::setNoChat(bool ignoreChat) {
+	FastLock l(cs);
+	this->ignoreChat = ignoreChat;
+}
+
+Style Identity::getStyle() const {
+	FastLock l(cs);
+	return style;
+}
+
+void Identity::setStyle(Style&& style) {
+	FastLock l(cs);
+	this->style = std::forward<Style>(style);
 }
 
 void FavoriteUser::update(const OnlineUser& info) {

=== modified file 'dcpp/UserMatch.h'
--- dcpp/UserMatch.h	2011-12-10 18:51:47 +0000
+++ dcpp/UserMatch.h	2011-12-11 18:36:51 +0000
@@ -35,15 +35,36 @@
 using std::string;
 using std::vector;
 
+struct Style {
+	string font;
+	int textColor;
+	int bgColor;
+
+	Style() : textColor(-1), bgColor(-1) { }
+};
+
 /** Defines rules to match users. */
 struct UserMatch : public Flags {
 	enum {
-		GENERATED = 1 << 1, /** Generated by DC++. Matchers that the user touches become precious
-							and cannot be modified anymore by DC++ when automating actions. */
-
-		FAVS = 1 << 2,
-		OPS = 1 << 3,
-		BOTS = 1 << 4
+		GENERATED_BIT,
+		FAVS_BIT,
+		OPS_BIT,
+		BOTS_BIT,
+		FORCE_CHAT_BIT,
+		IGNORE_CHAT_BIT
+	};
+
+	enum {
+		GENERATED = 1 << GENERATED_BIT, /** Generated by DC++. Matchers that the user touches
+										become precious and cannot be modified anymore by DC++ when
+										automating actions. */
+
+		FAVS = 1 << FAVS_BIT,
+		OPS = 1 << OPS_BIT,
+		BOTS = 1 << BOTS_BIT,
+
+		FORCE_CHAT = 1 << FORCE_CHAT_BIT,
+		IGNORE_CHAT = 1 << IGNORE_CHAT_BIT
 	};
 
 	string name;
@@ -82,7 +103,7 @@
 
 	vector<Rule> rules;
 
-	UserMatchPropsPtr props;
+	Style style;
 
 	void addRule(Rule&& rule);
 	bool empty() const;
@@ -90,15 +111,6 @@
 	bool match(OnlineUser& user) const;
 };
 
-/** Stores properties to be applied to matched users. */
-struct UserMatchProps : public intrusive_ptr_base<UserMatchProps> {
-	bool noChat;
-
-	string font;
-	int textColor;
-	int bgColor;
-};
-
 } // namespace dcpp
 
 #endif

=== modified file 'dcpp/UserMatchManager.cpp'
--- dcpp/UserMatchManager.cpp	2011-12-10 18:51:47 +0000
+++ dcpp/UserMatchManager.cpp	2011-12-11 18:36:51 +0000
@@ -59,13 +59,35 @@
 }
 
 void UserMatchManager::match(OnlineUser& user) const {
+	auto& identity = user.getIdentity();
+
+	bool chatSet = false;
+	Style style;
+
 	for(auto i = list.cbegin(), iend = list.cend(); i != iend; ++i) {
 		if(i->match(user)) {
-			user.getIdentity().setMatch(i->props);
-			return;
+
+			if(!chatSet && (i->isSet(UserMatch::FORCE_CHAT) || i->isSet(UserMatch::IGNORE_CHAT))) {
+				identity.setNoChat(i->isSet(UserMatch::IGNORE_CHAT));
+				chatSet = true;
+			}
+
+			if(style.font.empty() && !i->style.font.empty()) {
+				style.font = i->style.font;
+			}
+
+			if(style.textColor < 0 && i->style.textColor >= 0) {
+				style.textColor = i->style.textColor;
+			}
+
+			if(style.bgColor < 0 && i->style.bgColor >= 0) {
+				style.bgColor = i->style.bgColor;
+			}
 		}
 	}
-	user.getIdentity().setMatch(nullptr);
+
+	if(!chatSet) { identity.setNoChat(false); }
+	identity.setStyle(std::move(style));
 }
 
 void UserMatchManager::ignoreChat(const HintedUser& user, bool ignore) {
@@ -73,6 +95,7 @@
 
 	UserMatch matcher;
 	matcher.setFlag(UserMatch::GENERATED);
+	matcher.setFlag(ignore ? UserMatch::IGNORE_CHAT : UserMatch::FORCE_CHAT);
 
 	matcher.name = str(F_("Match %1% (added by %2%)") % nick % APPNAME);
 
@@ -106,20 +129,14 @@
 		setList(std::move(newList));
 	}));
 
-	// first, see if an automatic matcher with these rules already exists.
+	// see if an automatic matcher with these rules already exists.
 	for(auto i = newList.begin(), iend = newList.end(); i != iend; ++i) {
 		if(i->isSet(UserMatch::GENERATED) && i->rules == matcher.rules) {
-			matcher.props = i->props;
-			matcher.props->noChat = ignore;
+			matcher.style = i->style;
 			newList.erase(i);
 			return;
 		}
 	}
-
-	matcher.props = new UserMatchProps();
-	matcher.props->noChat = ignore;
-	matcher.props->textColor = -1;
-	matcher.props->bgColor = -1;
 }
 
 void UserMatchManager::on(SettingsManagerListener::Load, SimpleXML& xml) noexcept {
@@ -139,12 +156,12 @@
 			if(xml.getBoolChildAttrib("Favs")) { match.setFlag(UserMatch::FAVS); }
 			if(xml.getBoolChildAttrib("Ops")) { match.setFlag(UserMatch::OPS); }
 			if(xml.getBoolChildAttrib("Bots")) { match.setFlag(UserMatch::BOTS); }
+			if(xml.getBoolChildAttrib("ForceChat")) { match.setFlag(UserMatch::FORCE_CHAT); }
+			if(xml.getBoolChildAttrib("IgnoreChat")) { match.setFlag(UserMatch::IGNORE_CHAT); }
 
-			match.props = new UserMatchProps();
-			match.props->noChat = xml.getBoolChildAttrib("NoChat");
-			match.props->font = xml.getChildAttrib("Font");
-			match.props->textColor = xml.getIntChildAttrib("TextColor");
-			match.props->bgColor = xml.getIntChildAttrib("BgColor");
+			match.style.font = xml.getChildAttrib("Font");
+			match.style.textColor = xml.getIntChildAttrib("TextColor");
+			match.style.bgColor = xml.getIntChildAttrib("BgColor");
 
 			xml.stepIn();
 
@@ -181,11 +198,12 @@
 		if(i->isSet(UserMatch::FAVS)) { xml.addChildAttrib("Favs", true); }
 		if(i->isSet(UserMatch::OPS)) { xml.addChildAttrib("Ops", true); }
 		if(i->isSet(UserMatch::BOTS)) { xml.addChildAttrib("Bots", true); }
+		if(i->isSet(UserMatch::FORCE_CHAT)) { xml.addChildAttrib("ForceChat", true); }
+		if(i->isSet(UserMatch::IGNORE_CHAT)) { xml.addChildAttrib("IgnoreChat", true); }
 
-		if(i->props->noChat) { xml.addChildAttrib("NoChat", true); }
-		xml.addChildAttrib("Font", i->props->font);
-		xml.addChildAttrib("TextColor", i->props->textColor);
-		xml.addChildAttrib("BgColor", i->props->bgColor);
+		xml.addChildAttrib("Font", i->style.font);
+		xml.addChildAttrib("TextColor", i->style.textColor);
+		xml.addChildAttrib("BgColor", i->style.bgColor);
 
 		xml.stepIn();
 		for(auto rule = i->rules.cbegin(), rule_end = i->rules.cend(); rule != rule_end; ++rule) {

=== modified file 'dcpp/UserMatchManager.h'
--- dcpp/UserMatchManager.h	2011-12-10 18:51:47 +0000
+++ dcpp/UserMatchManager.h	2011-12-11 18:36:51 +0000
@@ -39,8 +39,8 @@
 	/// Assign a new list of user matching definitions. All current users will be re-matched.
 	void setList(UserMatches&& newList);
 
-	/** Match the given user against current user matching definitions. The "match" member of the
-	user's identity object will point to the properties of the matched definition on success. */
+	/** Match the given user against current user matching definitions. The user's identity object
+	will be modified accordingly. */
 	void match(OnlineUser& user) const;
 
 	void ignoreChat(const HintedUser& user, bool ignore);

=== modified file 'dcpp/forward.h'
--- dcpp/forward.h	2011-12-03 21:53:57 +0000
+++ dcpp/forward.h	2011-12-11 18:36:51 +0000
@@ -120,9 +120,6 @@
 
 struct UserMatch;
 
-struct UserMatchProps;
-typedef boost::intrusive_ptr<UserMatchProps> UserMatchPropsPtr;
-
 class WindowInfo;
 
 } // namespace dcpp

=== modified file 'win32/HubFrame.cpp'
--- win32/HubFrame.cpp	2011-12-11 14:45:53 +0000
+++ win32/HubFrame.cpp	2011-12-11 18:36:51 +0000
@@ -789,25 +789,22 @@
 }
 
 int HubFrame::UserInfo::getStyle(HFONT& font, COLORREF& textColor, COLORREF& bgColor, int) const {
-	auto match = identity.getMatch();
-	if(!match) {
-		return CDRF_DODEFAULT;
-	}
+	auto style = identity.getStyle();
 
-	if(!match->font.empty()) {
+	if(!style.font.empty()) {
 		// cache lookup might fail when refreshing the list of user matching defs...
-		auto cached = WinUtil::userMatchFonts.find(match->font);
+		auto cached = WinUtil::userMatchFonts.find(style.font);
 		if(cached != WinUtil::userMatchFonts.end()) {
 			font = cached->second->handle();
 		}
 	}
 
-	if(match->textColor != -1) {
-		textColor = match->textColor;
+	if(style.textColor != -1) {
+		textColor = style.textColor;
 	}
 
-	if(match->bgColor != -1) {
-		bgColor = match->bgColor;
+	if(style.bgColor != -1) {
+		bgColor = style.bgColor;
 	}
 
 	return CDRF_NEWFONT;

=== modified file 'win32/StylesPage.cpp'
--- win32/StylesPage.cpp	2011-12-10 18:51:47 +0000
+++ win32/StylesPage.cpp	2011-12-11 18:36:51 +0000
@@ -310,16 +310,16 @@
 
 StylesPage::UserMatchData::UserMatchData(UserMatch& matcher) :
 Data(Text::toT(matcher.name), IDH_SETTINGS_STYLES_USER_MATCH),
-props(matcher.props)
+matcher(matcher)
 {
-	customFont = !props->font.empty();
-	makeFont(font, props->font);
-
-	customTextColor = props->textColor >= 0;
-	textColor = props->textColor;
-
-	customBgColor = props->bgColor >= 0;
-	bgColor = props->bgColor;
+	customFont = !matcher.style.font.empty();
+	makeFont(font, matcher.style.font);
+
+	customTextColor = matcher.style.textColor >= 0;
+	textColor = matcher.style.textColor;
+
+	customBgColor = matcher.style.bgColor >= 0;
+	bgColor = matcher.style.bgColor;
 }
 
 const StylesPage::Data::Font& StylesPage::UserMatchData::getFont() const {
@@ -335,9 +335,10 @@
 }
 
 void StylesPage::UserMatchData::update() {
-	props->font = customFont ? Text::fromT(WinUtil::encodeFont(font.second)) : Util::emptyString;
-	props->textColor = customTextColor ? textColor : -1;
-	props->bgColor = customBgColor ? bgColor : -1;
+	matcher.style.font = customFont ? Text::fromT(WinUtil::encodeFont(font.second)) : Util::emptyString;
+	matcher.style.textColor = customTextColor ? textColor : -1;
+	matcher.style.bgColor = customBgColor ? bgColor : -1;
+	matcher.unsetFlag(UserMatch::GENERATED);
 }
 
 void StylesPage::handleSelectionChanged() {

=== modified file 'win32/StylesPage.h'
--- win32/StylesPage.h	2011-12-10 18:51:47 +0000
+++ win32/StylesPage.h	2011-12-11 18:36:51 +0000
@@ -111,7 +111,7 @@
 		void update();
 
 	private:
-		UserMatchPropsPtr props;
+		UserMatch& matcher;
 	};
 
 	Data* globalData;

=== modified file 'win32/UserInfoBase.h'
--- win32/UserInfoBase.h	2011-12-10 18:51:47 +0000
+++ win32/UserInfoBase.h	2011-12-11 18:36:51 +0000
@@ -68,8 +68,6 @@
 		chatNotIgnoredOnly = 1 << 5
 	};
 
-	UserMatchPropsPtr match;
-
 	UserTraits();
 
 	void parse(const UserInfoBase* ui);

=== modified file 'win32/UserMatchDlg.cpp'
--- win32/UserMatchDlg.cpp	2011-12-05 19:20:06 +0000
+++ win32/UserMatchDlg.cpp	2011-12-11 18:36:51 +0000
@@ -44,7 +44,8 @@
 ops(0),
 bots(0),
 rules(0),
-noChat(0)
+forceChat(0),
+ignoreChat(0)
 {
 	onInitDialog([this, initialMatcher] { return handleInitDialog(initialMatcher); });
 	onHelp(&WinUtil::help);
@@ -83,10 +84,13 @@
 	}
 
 	{
-		auto cur = grid->addChild(GroupBox::Seed())->addChild(Grid::Seed(1, 1));
+		auto cur = grid->addChild(GroupBox::Seed())->addChild(Grid::Seed(1, 2));
 		cur->setSpacing(grid->getSpacing());
 
-		noChat = cur->addChild(CheckBox::Seed(T_("Ignore chat messages")));
+		forceChat = cur->addChild(CheckBox::Seed(T_("Always show chat messages")));
+		forceChat->onClicked([this] { if(forceChat->getChecked()) ignoreChat->setChecked(false); });
+		ignoreChat = cur->addChild(CheckBox::Seed(T_("Ignore chat messages")));
+		ignoreChat->onClicked([this] { if(ignoreChat->getChecked()) forceChat->setChecked(false); });
 	}
 
 	{
@@ -113,9 +117,10 @@
 			addRow(&*i);
 		}
 
-		if(initialMatcher->props->noChat) { noChat->setChecked(true); }
+		if(initialMatcher->isSet(UserMatch::FORCE_CHAT)) { forceChat->setChecked(true); }
+		else if(initialMatcher->isSet(UserMatch::IGNORE_CHAT)) { ignoreChat->setChecked(true); }
 
-		result.props = initialMatcher->props;
+		result.style = initialMatcher->style;
 	}
 
 	setText(T_("User matching definition"));
@@ -176,12 +181,8 @@
 		return;
 	}
 
-	if(!result.props) {
-		result.props = new UserMatchProps();
-		result.props->textColor = -1;
-		result.props->bgColor = -1;
-	}
-	result.props->noChat = noChat->getChecked();
+	if(forceChat->getChecked()) { result.setFlag(UserMatch::FORCE_CHAT); }
+	else if(ignoreChat->getChecked()) { result.setFlag(UserMatch::IGNORE_CHAT); }
 
 	endDialog(IDOK);
 }

=== modified file 'win32/UserMatchDlg.h'
--- win32/UserMatchDlg.h	2011-12-03 21:53:57 +0000
+++ win32/UserMatchDlg.h	2011-12-11 18:36:51 +0000
@@ -35,7 +35,7 @@
 	TextBoxPtr name;
 	CheckBoxPtr favs, ops, bots;
 	GridPtr rules;
-	CheckBoxPtr noChat;
+	CheckBoxPtr forceChat, ignoreChat;
 
 	UserMatch result;
 

=== modified file 'win32/WinUtil.cpp'
--- win32/WinUtil.cpp	2011-12-10 18:51:47 +0000
+++ win32/WinUtil.cpp	2011-12-11 18:36:51 +0000
@@ -414,10 +414,10 @@
 
 	const auto& list = UserMatchManager::getInstance()->getList();
 	for(auto i = list.cbegin(), iend = list.cend(); i != iend; ++i) {
-		if(!i->props->font.empty()) {
+		if(!i->style.font.empty()) {
 			LOGFONT lf;
-			decodeFont(Text::toT(i->props->font), lf);
-			userMatchFonts[i->props->font] = new dwt::Font(lf);
+			decodeFont(Text::toT(i->style.font), lf);
+			userMatchFonts[i->style.font] = new dwt::Font(lf);
 		}
 	}
 }