← Back to team overview

linuxdcpp-team team mailing list archive

[Branch ~dcplusplus-team/dcplusplus/trunk] Rev 2904: rich edit fixes

 

------------------------------------------------------------
revno: 2904
committer: poy <poy@xxxxxxxxxx>
branch nick: trunk
timestamp: Tue 2012-04-17 19:32:56 +0200
message:
  rich edit fixes
modified:
  changelog.txt
  dwt/include/dwt/aspects/Scrollable.h
  dwt/include/dwt/widgets/RichTextBox.h
  dwt/src/widgets/RichTextBox.cpp
  win32/AspectChat.h
  win32/RichTextBox.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 'changelog.txt'
--- changelog.txt	2012-04-07 18:05:24 +0000
+++ changelog.txt	2012-04-17 17:32:56 +0000
@@ -27,6 +27,7 @@
 * [L#947895] Move the "follow redirect" command to inline chat links (poy)
 * Format chat links (poy)
 * Improve threaded file list loading (poy)
+* [L#981733] Prevent the keyboard language from switching
 
 -- 0.791 2012-01-14 --
 * Update translations

=== modified file 'dwt/include/dwt/aspects/Scrollable.h'
--- dwt/include/dwt/aspects/Scrollable.h	2012-01-13 20:55:20 +0000
+++ dwt/include/dwt/aspects/Scrollable.h	2012-04-17 17:32:56 +0000
@@ -36,18 +36,13 @@
 #ifndef DWT_aspects_Scrollable_h
 #define DWT_aspects_Scrollable_h
 
-#include "../Dispatchers.h"
 #include "../DWTException.h"
 #include "../Message.h"
 
 namespace dwt { namespace aspects {
 
 /// Aspect class used by Widgets that have the possibility of scrolling
-/** \ingroup aspects::Classes
-  * E.g. the Slider have a scroll Aspect to it therefore Slider realize
-  * the aspects::Scrollable through inheritance.
-  */
-template< class WidgetType >
+template<typename WidgetType>
 class Scrollable
 {
 	const WidgetType& W() const { return *static_cast<const WidgetType*>(this); }
@@ -55,33 +50,23 @@
 
 	HWND H() const { return W().handle(); }
 
-	typedef Dispatchers::VoidVoid<> ScrollableDispatcher;
+	typedef std::function<void ()> F;
 
 public:
 	/// @ refer to the ::GetScrollInfo doc for information on the params.
 	SCROLLINFO getScrollInfo(int fnBar, int mask = SIF_ALL) const;
 	bool scrollIsAtEnd() const;
 
-	/// \ingroup EventHandlersaspects::Scrollable
-	/// Setting the event handler for the "scrolling horizontally" event
-	/** A scrolling event occurs when for instance a Sliders value is being
-	  * manipulated through user interaction. Such an action would raise this event.
-	  * <br>
-	  * No parameters are passed.
-	  */
-	void onScrollHorz(const ScrollableDispatcher::F& f) {
-		W().addCallback(Message( WM_HSCROLL ), ScrollableDispatcher(f));
+	/** catch horizontal scrolling events.
+	@param sbFlag one of the SB_ flags defined in the WM_HSCROLL doc, or -1 as a catch-all. */
+	void onScrollHorz(F f, int sbFlag = -1) {
+		onScroll(WM_HSCROLL, f, sbFlag);
 	}
 
-	/// \ingroup EventHandlersaspects::Scrollable
-	/// Setting the event handler for the "scrolling vertically" event
-	/** A scrolling event occurs when for instance a Sliders value is being
-	  * manipulated through user interaction. Such an action would raise this event.
-	  * <br>
-	  * No parameters are passed.
-	  */
-	void onScrollVert(const ScrollableDispatcher::F& f) {
-		W().addCallback(Message( WM_VSCROLL ), ScrollableDispatcher(f));
+	/** catch vertical scrolling events.
+	@param sbFlag one of the SB_ flags defined in the WM_VSCROLL doc, or -1 as a catch-all. */
+	void onScrollVert(F f, int sbFlag = -1) {
+		onScroll(WM_VSCROLL, f, sbFlag);
 	}
 
 private:
@@ -89,9 +74,18 @@
 	virtual int scrollOffsetImpl() const {
 		return 0;
 	}
+
+	void onScroll(UINT message, F f, int sbFlag) {
+		W().addCallback(Message(message), [f, sbFlag](const MSG& msg, LRESULT&) -> bool {
+			if(sbFlag == -1 || LOWORD(msg.wParam) == sbFlag) {
+				f();
+			}
+			return false;
+		});
+	}
 };
 
-template<class WidgetType>
+template<typename WidgetType>
 SCROLLINFO Scrollable<WidgetType>::getScrollInfo(int fnBar, int mask) const {
 	SCROLLINFO info = { sizeof(SCROLLINFO), mask };
 	if(!::GetScrollInfo(H(), fnBar, &info)) {
@@ -100,7 +94,7 @@
 	return info;
 }
 
-template<class WidgetType>
+template<typename WidgetType>
 bool Scrollable<WidgetType>::scrollIsAtEnd() const {
 	SCROLLINFO scrollInfo = getScrollInfo(SB_VERT, SIF_RANGE | SIF_PAGE | SIF_POS);
 	return !scrollInfo.nPage || scrollInfo.nPos >= static_cast<int>(scrollInfo.nMax - scrollInfo.nPage) + scrollOffsetImpl();

=== modified file 'dwt/include/dwt/widgets/RichTextBox.h'
--- dwt/include/dwt/widgets/RichTextBox.h	2012-04-16 16:31:28 +0000
+++ dwt/include/dwt/widgets/RichTextBox.h	2012-04-17 17:32:56 +0000
@@ -128,6 +128,8 @@
 	COLORREF getTextColor() const { return textColor; }
 	COLORREF getBgColor() const { return bgColor; }
 
+	virtual bool handleMessage(const MSG& msg, LRESULT& retVal);
+
 protected:
 	tstring currentNeedle;		// search in chat window
 	int currentNeedlePos;		// search in chat window

=== modified file 'dwt/src/widgets/RichTextBox.cpp'
--- dwt/src/widgets/RichTextBox.cpp	2012-04-16 16:31:28 +0000
+++ dwt/src/widgets/RichTextBox.cpp	2012-04-17 17:32:56 +0000
@@ -49,6 +49,15 @@
 #ifndef CFM_BACKCOLOR
 #define CFM_BACKCOLOR 0x04000000
 #endif
+#ifndef EM_SETLANGOPTIONS
+#define EM_SETLANGOPTIONS (WM_USER + 120)
+#endif
+#ifndef EM_GETLANGOPTIONS
+#define EM_GETLANGOPTIONS (WM_USER + 121)
+#endif
+#ifndef IMF_AUTOKEYBOARD
+#define IMF_AUTOKEYBOARD 0x0001
+#endif
 
 namespace dwt {
 
@@ -80,6 +89,15 @@
 	sendMessage(EM_SETEVENTMASK, 0, cs.events);
 	sendMessage(EM_AUTOURLDETECT, FALSE);
 
+	/* after special chars are added to the control, it sets the IMF_AUTOKEYBOARD flag which
+	results in the Win keyboard language switching. the fix is to remove that flag when the control
+	gains focus (which is when the presence of the flag actually matters). */
+	onFocus([this] {
+		auto opts = sendMessage(EM_GETLANGOPTIONS);
+		if((opts & IMF_AUTOKEYBOARD) == IMF_AUTOKEYBOARD)
+			sendMessage(EM_SETLANGOPTIONS, 0, opts & ~IMF_AUTOKEYBOARD);
+	});
+
 	/* unlike other common controls, Rich Edits ignore WM_PRINTCLIENT messages. as per
 	<http://msdn.microsoft.com/en-us/library/bb787875(VS.85).aspx>, we have to handle the printing
 	by ourselves. this is crucial for taskbar thumbnails and "Aero Peek" previews. */
@@ -399,4 +417,19 @@
 	redraw();
 }
 
+bool RichTextBox::handleMessage(const MSG& msg, LRESULT& retVal) {
+	bool handled = BaseType::handleMessage(msg, retVal);
+
+	/* when scrolling downwards, the content of the box sometimes scrolls up too far, leaving blank
+	space below the last line. this behavior seems to be specific to Rich Edit 4.1. */
+	if(msg.message == WM_VSCROLL && msg.wParam == SB_PAGEDOWN) {
+		retVal = getDispatcher().chain(msg);
+		if(scrollIsAtEnd())
+			scrollToBottom();
+		return true;
+	}
+
+	return handled;
+}
+
 }

=== modified file 'win32/AspectChat.h'
--- win32/AspectChat.h	2012-04-16 16:31:28 +0000
+++ win32/AspectChat.h	2012-04-17 17:32:56 +0000
@@ -220,9 +220,6 @@
 		case VK_NEXT: // page down
 			{
 				chat->sendMessage(WM_VSCROLL, SB_PAGEDOWN);
-				// sometimes scrolls too far, so add the following:
-				if(chat->scrollIsAtEnd())
-					chat->scrollToBottom();
 				return true;
 			} break;
 		case VK_HOME:

=== modified file 'win32/RichTextBox.cpp'
--- win32/RichTextBox.cpp	2012-04-16 19:46:18 +0000
+++ win32/RichTextBox.cpp	2012-04-17 17:32:56 +0000
@@ -162,7 +162,7 @@
 			auto text = getLinkText(link);
 
 			auto menu = dwt::WidgetCreator<dwt::Menu>::create(this, dwt::Menu::Seed());
-			menu->setTitle(text, WinUtil::menuIcon(IDI_LINKS));
+			menu->setTitle(dwt::util::escapeMenu(text), WinUtil::menuIcon(IDI_LINKS));
 			menu->appendItem(T_("&Open"), [text] { WinUtil::parseLink(text); }, WinUtil::menuIcon(IDI_RIGHT), true, true);
 			menu->open(dwt::ClientCoordinate(dwt::Point::fromLParam(clickPos), this));
 			return 1;