changeset 13201:4ebcd304709f draft

(svn r17708) -Feature [FS#2053]: [OSX] Implement clipboard support for OS X.
author michi_cc <michi_cc@openttd.org>
date Sun, 04 Oct 2009 21:08:38 +0000
parents 6ebc4e2c698e
children 1b611ed78560
files src/console_gui.cpp src/misc_gui.cpp src/os/macosx/macos.mm src/os/os2/os2.cpp src/os/unix/unix.cpp src/os/windows/win32.cpp
diffstat 6 files changed, 91 insertions(+), 74 deletions(-) [+]
line wrap: on
line diff
--- a/src/console_gui.cpp
+++ b/src/console_gui.cpp
@@ -293,6 +293,9 @@
 				MarkWholeScreenDirty();
 				break;
 
+#ifdef WITH_COCOA
+			case (WKC_META | 'V'):
+#endif
 			case (WKC_CTRL | 'V'):
 				if (InsertTextBufferClipboard(&_iconsole_cmdline)) {
 					IConsoleResetHistoryPos();
@@ -304,6 +307,9 @@
 				IConsoleCmdExec("clear");
 				break;
 
+#ifdef WITH_COCOA
+			case (WKC_META | 'U'):
+#endif
 			case (WKC_CTRL | 'U'):
 				DeleteTextBufferAll(&_iconsole_cmdline);
 				this->SetDirty();
--- a/src/misc_gui.cpp
+++ b/src/misc_gui.cpp
@@ -39,6 +39,16 @@
 
 #include "table/strings.h"
 
+
+/**
+ * Try to retrive the current clipboard contents.
+ *
+ * @note OS-specific funtion.
+ * @return True if some text could be retrived.
+ */
+bool GetClipboardContents(char *buffer, size_t buff_len);
+
+
 /* Variables to display file lists */
 SaveLoadDialogMode _saveload_mode;
 
@@ -1010,6 +1020,49 @@
 }
 
 /**
+ * Insert a chunk of text from the clipboard onto the textbuffer. Get TEXT clipboard
+ * and append this up to the maximum length (either absolute or screenlength). If maxlength
+ * is zero, we don't care about the screenlength but only about the physical length of the string
+ * @param tb Textbuf type to be changed
+ * @return true on successful change of Textbuf, or false otherwise
+ */
+bool InsertTextBufferClipboard(Textbuf *tb)
+{
+	char utf8_buf[512];
+
+	if (!GetClipboardContents(utf8_buf, lengthof(utf8_buf))) return false;
+
+	uint16 width = 0, length = 0;
+	WChar c;
+	for (const char *ptr = utf8_buf; (c = Utf8Consume(&ptr)) != '\0';) {
+		if (!IsPrintable(c)) break;
+
+		byte len = Utf8CharLen(c);
+		if (tb->size + length + len > tb->maxsize) break;
+
+		byte charwidth = GetCharacterWidth(FS_NORMAL, c);
+		if (tb->maxwidth != 0 && width + tb->width + charwidth > tb->maxwidth) break;
+
+		width += charwidth;
+		length += len;
+	}
+
+	if (length == 0) return false;
+
+	memmove(tb->buf + tb->caretpos + length, tb->buf + tb->caretpos, tb->size - tb->caretpos);
+	memcpy(tb->buf + tb->caretpos, utf8_buf, length);
+	tb->width += width;
+	tb->caretxoffs += width;
+
+	tb->size += length;
+	tb->caretpos += length;
+	assert(tb->size <= tb->maxsize);
+	tb->buf[tb->size - 1] = '\0'; // terminating zero
+
+	return true;
+}
+
+/**
  * Handle text navigation with arrow keys left/right.
  * This defines where the caret will blink and the next characer interaction will occur
  * @param tb Textbuf type where navigation occurs
@@ -1135,10 +1188,16 @@
 
 		case WKC_RETURN: case WKC_NUM_ENTER: return HEBR_CONFIRM;
 
+#ifdef WITH_COCOA
+		case (WKC_META | 'V'):
+#endif
 		case (WKC_CTRL | 'V'):
 			if (InsertTextBufferClipboard(&this->text)) w->SetWidgetDirty(wid);
 			break;
 
+#ifdef WITH_COCOA
+		case (WKC_META | 'U'):
+#endif
 		case (WKC_CTRL | 'U'):
 			DeleteTextBufferAll(&this->text);
 			w->SetWidgetDirty(wid);
--- a/src/os/macosx/macos.mm
+++ b/src/os/macosx/macos.mm
@@ -11,6 +11,7 @@
 #include "../../core/bitmath_func.hpp"
 #include "../../rev.h"
 #include "macos.h"
+#include "../../string_func.h"
 
 #define Rect  OTTDRect
 #define Point OTTDPoint
@@ -118,3 +119,19 @@
 }
 
 
+bool GetClipboardContents(char *buffer, size_t buff_len)
+{
+	NSPasteboard *pb = [ NSPasteboard generalPasteboard ];
+	NSArray *types = [ NSArray arrayWithObject:NSStringPboardType ];
+	NSString *bestType = [ pb availableTypeFromArray:types ];
+
+	/* Clipboard has no text data available. */
+	if (bestType == nil) return false;
+
+	NSString *string = [ pb stringForType:NSStringPboardType ];
+	if (string == nil || [ string length ] == 0) return false;
+
+	ttd_strlcpy(buffer, [ string UTF8String ], buff_len);
+
+	return true;
+}
--- a/src/os/os2/os2.cpp
+++ b/src/os/os2/os2.cpp
@@ -176,14 +176,7 @@
 	return ttd_main(argc, argv);
 }
 
-/**
- * Insert a chunk of text from the clipboard onto the textbuffer. Get TEXT clipboard
- * and append this up to the maximum length (either absolute or screenlength). If maxlength
- * is zero, we don't care about the screenlength but only about the physical length of the string
- * @param tb Textbuf type to be changed
- * @return Return true on successful change of Textbuf, or false otherwise
- */
-bool InsertTextBufferClipboard(Textbuf *tb)
+bool GetClipboardContents(char *buffer, size_t buff_len)
 {
 /* XXX -- Currently no clipboard support implemented with GCC */
 #ifndef __INNOTEK_LIBC__
@@ -195,30 +188,7 @@
 
 		if (text != NULL)
 		{
-			uint length = 0;
-			uint width = 0;
-			const char *i;
-
-			for (i = text; IsValidAsciiChar(*i); i++)
-			{
-				uint w;
-
-				if (tb->size + length + 1 > tb->maxsize) break;
-
-				w = GetCharacterWidth(FS_NORMAL, (byte)*i);
-				if (tb->maxwidth != 0 && width + tb->width + w > tb->maxwidth) break;
-
-				width += w;
-				length++;
-			}
-
-			memmove(tb->buf + tb->caretpos + length, tb->buf + tb->caretpos, tb->size - tb->caretpos);
-			memcpy(tb->buf + tb->caretpos, text, length);
-			tb->width += width;
-			tb->caretxoffs += width;
-			tb->size += length;
-			tb->caretpos += length;
-
+			ttd_strlcpy(buffer, text, buff_len);
 			WinCloseClipbrd(hab);
 			return true;
 		}
--- a/src/os/unix/unix.cpp
+++ b/src/os/unix/unix.cpp
@@ -262,10 +262,12 @@
 	return ret;
 }
 
-bool InsertTextBufferClipboard(Textbuf *tb)
+#ifndef WITH_COCOA
+bool GetClipboardContents(char *buffer, size_t buff_len)
 {
 	return false;
 }
+#endif
 
 
 /* multi os compatible sleep function */
--- a/src/os/windows/win32.cpp
+++ b/src/os/windows/win32.cpp
@@ -465,28 +465,18 @@
 	_searchpaths[SP_APPLICATION_BUNDLE_DIR] = NULL;
 }
 
-/**
- * Insert a chunk of text from the clipboard onto the textbuffer. Get TEXT clipboard
- * and append this up to the maximum length (either absolute or screenlength). If maxlength
- * is zero, we don't care about the screenlength but only about the physical length of the string
- * @param tb Textbuf type to be changed
- * @return true on successful change of Textbuf, or false otherwise
- */
-bool InsertTextBufferClipboard(Textbuf *tb)
+
+bool GetClipboardContents(char *buffer, size_t buff_len)
 {
 	HGLOBAL cbuf;
-	char utf8_buf[512];
 	const char *ptr;
 
-	WChar c;
-	uint16 width, length;
-
 	if (IsClipboardFormatAvailable(CF_UNICODETEXT)) {
 		OpenClipboard(NULL);
 		cbuf = GetClipboardData(CF_UNICODETEXT);
 
 		ptr = (const char*)GlobalLock(cbuf);
-		const char *ret = convert_from_fs((wchar_t*)ptr, utf8_buf, lengthof(utf8_buf));
+		const char *ret = convert_from_fs((wchar_t*)ptr, buffer, buff_len);
 		GlobalUnlock(cbuf);
 		CloseClipboard();
 
@@ -497,7 +487,7 @@
 		cbuf = GetClipboardData(CF_TEXT);
 
 		ptr = (const char*)GlobalLock(cbuf);
-		strecpy(utf8_buf, FS2OTTD(ptr), lastof(utf8_buf));
+		ttd_strlcpy(buffer, FS2OTTD(ptr), buff_len);
 
 		GlobalUnlock(cbuf);
 		CloseClipboard();
@@ -506,33 +496,6 @@
 		return false;
 	}
 
-	width = length = 0;
-
-	for (ptr = utf8_buf; (c = Utf8Consume(&ptr)) != '\0';) {
-		if (!IsPrintable(c)) break;
-
-		byte len = Utf8CharLen(c);
-		if (tb->size + length + len > tb->maxsize) break;
-
-		byte charwidth = GetCharacterWidth(FS_NORMAL, c);
-		if (tb->maxwidth != 0 && width + tb->width + charwidth > tb->maxwidth) break;
-
-		width += charwidth;
-		length += len;
-	}
-
-	if (length == 0) return false;
-
-	memmove(tb->buf + tb->caretpos + length, tb->buf + tb->caretpos, tb->size - tb->caretpos);
-	memcpy(tb->buf + tb->caretpos, utf8_buf, length);
-	tb->width += width;
-	tb->caretxoffs += width;
-
-	tb->size += length;
-	tb->caretpos += length;
-	assert(tb->size <= tb->maxsize);
-	tb->buf[tb->size - 1] = '\0'; // terminating zero
-
 	return true;
 }