Sign in to follow this  
Followers 0
jkollss

Short magnet links [patch solution]

5 posts in this topic

I don't know what the mess about the subject.

Here is the source patch to enable "short" human readable magnet links in the chat.

Part of the code was taken from FlyLinDC++. It's distributed with source and I found nothing about copyright restrictions, in particular they based on ApexDC++ code. And there is nothing hard to implement such feature anyway.

diff --git a/client/Util.h b/client/Util.h

index 71bce1e..1181ece 100644

--- a/client/Util.h

+++ b/client/Util.h

@@ -544,6 +544,24 @@ struct noCaseStringEq {

 	}

 };


+template<typename T>

+class AutoArray {

+	typedef T* TPtr;

+public:

+	explicit AutoArray(TPtr t) : p(t) { }

+	explicit AutoArray(size_t size) : p(new T[size]) { }

+	~AutoArray() { delete[] p; }

+	operator TPtr() { return p; }

+	TPtr get() { return p; }

+	AutoArray& operator=(TPtr t) { delete[] p; p = t; return *this; }

+private:

+	AutoArray(const AutoArray&);

+	AutoArray& operator=(const AutoArray&);

+

+	TPtr p;

+};

+

+

 } // namespace dcpp


 #endif // !defined(UTIL_H)

diff --git a/windows/ChatCtrl.cpp b/windows/ChatCtrl.cpp

index fb8cb15..6284423 100644

--- a/windows/ChatCtrl.cpp

+++ b/windows/ChatCtrl.cpp

@@ -59,8 +59,19 @@ ChatCtrl::~ChatCtrl() {


 void ChatCtrl::AdjustTextSize() {

 	if(GetWindowTextLength() > SETTING(CHATBUFFERSIZE)) {

-		// After 25000 charecters, w95 becomes sad...

+		// After 25000 characters, w95 becomes sad...

 		SetRedraw(FALSE);

+		// [jkollss]

+		int g = LineIndex(LineFromChar(2000));

+		for (TURLMap::iterator i = lURLMap.begin(); i != lURLMap.end();)

+		{

+			i->first -= g;

+			if (i->first < 0)

+				lURLMap.erase(i++);

+			else

+				i++;

+		}

+		//

 		SetSel(0, LineIndex(LineFromChar(2000)));

 		ReplaceSel(_T(""));

 		SetRedraw(TRUE);

@@ -267,6 +278,7 @@ void ChatCtrl::AppendTextOnly(const tstring& sMyNick, const TCHAR* sText, CHARFO


 	// Zvyrazneni vsech URL a nastaveni "klikatelnosti"

 	long lSearchFrom = 0;

+	tstring ls;

 	for(size_t i = 0; i < (sizeof(Links) / sizeof(Links[0])); i++) {

 		long linkStart = sMsgLower.Find(Links[i], lSearchFrom);

 		while(linkStart > 0) {

@@ -281,6 +293,32 @@ void ChatCtrl::AppendTextOnly(const tstring& sMyNick, const TCHAR* sText, CHARFO

 				linkEnd = _tcslen(sMsgLower);

 			}

 			SetSel(lSelBegin + linkStart, lSelBegin + linkEnd);

+			// [jkolls] Shorten magnet link

+			AutoArray<TCHAR> cURL(linkEnd - linkStart + 1);

+			GetTextRange(lSelBegin + linkStart, lSelBegin + linkEnd, cURL);

+			ls = cURL;

+			if (_strnicmp(Text::fromT(cURL.get()).c_str(), "magnet:?", 8) == 0)

+			{

+				string sFileName = Text::fromT(cURL.get());

+				int dn = sFileName.find("dn=");

+				if (dn == string::npos)

+					sFileName = "Unnamed magnet-link";

+				else

+					sFileName = sFileName.substr(dn + 3);

+				sFileName = Util::encodeURI(sFileName, true);

+				tstring sFileSize = cURL;

+				int64_t filesize = Util::toInt64(Text::fromT(sFileSize.substr(sFileSize.find(_T("xl=")) + 3, sFileSize.find(_T("&")) - sFileSize.find(_T("xl=")))));

+				ls = Text::toT(sFileName) + _T(" (") + Util::formatBytesW(filesize) + _T(")");

+				ReplaceSel(ls.c_str());

+				tstring tmp = sMsgLower.Left(linkStart);

+				tmp += ls;

+				tmp += sMsgLower.Mid(linkEnd);

+				sMsgLower = tmp.c_str();

+				linkEnd = linkStart + ls.length();

+				SetSel(lSelBegin + linkStart, lSelBegin + linkEnd);

+				lURLMap.push_back(make_pair(lSelBegin + linkStart, cURL.get()));

+			}

+			// 

 			SetSelectionCharFormat(WinUtil::m_TextStyleURL);

 			linkStart = sMsgLower.Find(Links[i], linkEnd);

 		}

diff --git a/windows/ChatCtrl.h b/windows/ChatCtrl.h

index 14951ad..680b2f8 100644

--- a/windows/ChatCtrl.h

+++ b/windows/ChatCtrl.h

@@ -34,6 +34,7 @@

 #endif


 class UserInfo;

+typedef list<pair<int, tstring>> TURLMap;


 class ChatCtrl: public CRichEditCtrl, public CMessageMap, public UCHandler<ChatCtrl>

 {

@@ -129,6 +130,22 @@ public:

 		// We wanna control the scrolling...

 	}


+	// [jkollss]

+	TURLMap lURLMap;

+	tstring get_URL(ENLINK* p_EL) const

+	{

+		const long lBegin = p_EL->chrg.cpMin, lEnd = p_EL->chrg.cpMax;

+		for (TURLMap::const_iterator i = lURLMap.begin(); i != lURLMap.end(); ++i)

+			if (i->first == lBegin)

+				return i->second;

+		AutoArray<TCHAR> sURLTemp(lEnd - lBegin+1);

+		sURLTemp[0] = 0;

+		GetTextRange(lBegin, lEnd, sURLTemp);

+		return tstring(sURLTemp);

+	}

+	//

+	static tstring sSelectedURL;

+

 private:

 	bool HitNick(const POINT& p, tstring& sNick, int& iBegin , int& iEnd);

 	bool HitIP(const POINT& p, tstring& sIP, int& iBegin, int& iEnd);

@@ -147,7 +164,6 @@ private:

 	static tstring sSelectedLine;

 	static tstring sSelectedIP;

 	static tstring sSelectedUser;

-	static tstring sSelectedURL;

 };



diff --git a/windows/HubFrame.cpp b/windows/HubFrame.cpp

index 449ad9c..b8d8960 100644

--- a/windows/HubFrame.cpp

+++ b/windows/HubFrame.cpp

@@ -55,6 +55,7 @@ ResourceManager::Strings HubFrame::columnNames[] = { ResourceManager::NICK, Reso

 	ResourceManager::VERSION, ResourceManager::MODE, ResourceManager::HUBS, ResourceManager::SLOTS };


 extern CAGEmotionSetup* g_pEmotionsSetup;

+//tstring sSelectedURL = Util::emptyStringT;


 LRESULT HubFrame::OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)

 {

@@ -2438,6 +2439,57 @@ LRESULT HubFrame::onEmoPackChange(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl

 	return 0;

 }


+// [jkollss]

+LRESULT HubFrame::onClientEnLink(int idCtrl, LPNMHDR pnmh, BOOL& bHandled)

+{

+	ENLINK* pEL = (ENLINK*)pnmh;

+

+	if (pEL->msg == WM_LBUTTONUP)

+	{

+		tstring sURL = ctrlClient.get_URL(pEL);

+		WinUtil::openLink(sURL);

+	}

+	else if(pEL->msg == WM_RBUTTONUP)

+	{

+		ctrlClient.sSelectedURL = ctrlClient.get_URL(pEL);

+		ctrlClient.SetSel(pEL->chrg.cpMin, pEL->chrg.cpMax);

+		ctrlClient.InvalidateRect(NULL);

+		return 0;

+	}

+	return 0;

+}

+

+LRESULT HubFrame::onMouseMove(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)

+{

+	RECT rc;

+	POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };		// location of mouse click

+	// Get the bounding rectangle of the client area. 

+	ctrlClient.GetClientRect(&rc);

+	ctrlClient.ScreenToClient(&pt); 

+	if (PtInRect(&rc, pt))

+	{

+		ctrlClient.sSelectedURL = _T("");

+		return TRUE;

+	}

+	return 1;

+}

+

+LRESULT HubFrame::onRButtonUp(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)

+{

+	RECT rc;

+	POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };		// location of mouse click

+

+	// Get the bounding rectangle of the client area. 

+	ctrlClient.GetClientRect(&rc);

+	ctrlClient.ScreenToClient(&pt); 

+	if (PtInRect(&rc, pt))

+	{

+		ctrlClient.sSelectedURL = _T("");

+	}

+	return 1;

+}

+

+

 /**

  * @file

  * $Id: HubFrame.cpp 382 2008-03-09 10:40:22Z BigMuscle $

diff --git a/windows/HubFrame.h b/windows/HubFrame.h

index 7da4749..be816f3 100644

--- a/windows/HubFrame.h

+++ b/windows/HubFrame.h

@@ -136,7 +136,9 @@ public:

 	LRESULT onSelChange(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/);

 	LRESULT onCtlColor(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/);

 	LRESULT onFileReconnect(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/);

-	LRESULT onClientEnLink(int idCtrl, LPNMHDR pnmh, BOOL& bHandled) { return ctrlClient.onClientEnLink(idCtrl, pnmh, bHandled); }

+	LRESULT onRButtonUp(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled);

+	LRESULT onMouseMove(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled);

+	LRESULT onClientEnLink(int idCtrl, LPNMHDR pnmh, BOOL& bHandled); // [jkollss] { return ctrlClient.onClientEnLink(idCtrl, pnmh, bHandled); }

 	LRESULT onSelectUser(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/);

 	LRESULT onPrivateMessage(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/);

 	LRESULT onPublicMessage(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/);

diff --git a/windows/PrivateFrame.cpp b/windows/PrivateFrame.cpp

index 2dfaa29..f78a7cd 100644

--- a/windows/PrivateFrame.cpp

+++ b/windows/PrivateFrame.cpp

@@ -809,6 +809,24 @@ LRESULT PrivateFrame::onEmoticons(WORD /*wNotifyCode*/, WORD /*wID*/, HWND hWndC

 	return 0;

 }


+LRESULT PrivateFrame::onClientEnLink(int idCtrl, LPNMHDR pnmh, BOOL& bHandled)

+{

+	//return ctrlClient.onClientEnLink(idCtrl, pnmh, bHandled);

+	ENLINK* pEL = (ENLINK*)pnmh;

+

+	if ( pEL->msg == WM_LBUTTONUP ) {

+		tstring sURL = ctrlClient.get_URL(pEL);

+		WinUtil::openLink(sURL);

+

+	} else if(pEL->msg == WM_RBUTTONUP) {

+		pSelectedURL = ctrlClient.get_URL(pEL);

+		ctrlClient.SetSel(pEL->chrg.cpMin, pEL->chrg.cpMax);

+		ctrlClient.InvalidateRect(NULL);

+		return 0;

+	}

+	return 0;

+}

+

 /**

  * @file

  * $Id: PrivateFrame.cpp 382 2008-03-09 10:40:22Z BigMuscle $

diff --git a/windows/PrivateFrame.h b/windows/PrivateFrame.h

index 57635f8..6fc98aa 100644

--- a/windows/PrivateFrame.h

+++ b/windows/PrivateFrame.h

@@ -98,7 +98,7 @@ public:

 	LRESULT onAddToFavorites(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/);

 	LRESULT onTabContextMenu(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/);

 	LRESULT onContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);

-	LRESULT onClientEnLink(int idCtrl, LPNMHDR pnmh, BOOL& bHandled) { return ctrlClient.onClientEnLink(idCtrl, pnmh, bHandled); }

+	LRESULT onClientEnLink(int idCtrl, LPNMHDR pnmh, BOOL& bHandled);// { return ctrlClient.onClientEnLink(idCtrl, pnmh, bHandled); }

 	LRESULT onOpenUserLog(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/);

 	LRESULT onEmoPackChange(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/);

   	LRESULT onEmoticons(WORD /*wNotifyCode*/, WORD /*wID*/, HWND hWndCtl, BOOL& bHandled);

Share this post


Link to post
Share on other sites

has already been fixed in the beta so no need to post about or post link to a leech client

Share this post


Link to post
Share on other sites

Yes indeed I made my own version some time ago... but I'll look through this in case I can spot some ideas from it...

Share this post


Link to post
Share on other sites

has already been fixed in the beta so no need to post about or post link to a leech client

I dunno about leech that client or not. I don't care. I just take useful idea and adapted it to Apex. I have no relations to flylink group. I pointed to their website only it because I took some code from their client. That's it.

So, please get your paranoia back and just look at the code.

Thanks.

Share this post


Link to post
Share on other sites
Sign in to follow this  
Followers 0