(svn r17708) -Feature [FS#2053]: [OSX] Implement clipboard support for OS X.

This commit is contained in:
michi_cc 2009-10-04 21:08:38 +00:00
parent a831143f45
commit 049d62b35c
6 changed files with 91 additions and 74 deletions

View File

@ -293,6 +293,9 @@ struct IConsoleWindow : Window
MarkWholeScreenDirty(); MarkWholeScreenDirty();
break; break;
#ifdef WITH_COCOA
case (WKC_META | 'V'):
#endif
case (WKC_CTRL | 'V'): case (WKC_CTRL | 'V'):
if (InsertTextBufferClipboard(&_iconsole_cmdline)) { if (InsertTextBufferClipboard(&_iconsole_cmdline)) {
IConsoleResetHistoryPos(); IConsoleResetHistoryPos();
@ -304,6 +307,9 @@ struct IConsoleWindow : Window
IConsoleCmdExec("clear"); IConsoleCmdExec("clear");
break; break;
#ifdef WITH_COCOA
case (WKC_META | 'U'):
#endif
case (WKC_CTRL | 'U'): case (WKC_CTRL | 'U'):
DeleteTextBufferAll(&_iconsole_cmdline); DeleteTextBufferAll(&_iconsole_cmdline);
this->SetDirty(); this->SetDirty();

View File

@ -39,6 +39,16 @@
#include "table/strings.h" #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 */ /* Variables to display file lists */
SaveLoadDialogMode _saveload_mode; SaveLoadDialogMode _saveload_mode;
@ -1009,6 +1019,49 @@ bool InsertTextBufferChar(Textbuf *tb, WChar key)
return false; return false;
} }
/**
* 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. * Handle text navigation with arrow keys left/right.
* This defines where the caret will blink and the next characer interaction will occur * This defines where the caret will blink and the next characer interaction will occur
@ -1135,10 +1188,16 @@ HandleEditBoxResult QueryString::HandleEditBoxKey(Window *w, int wid, uint16 key
case WKC_RETURN: case WKC_NUM_ENTER: return HEBR_CONFIRM; case WKC_RETURN: case WKC_NUM_ENTER: return HEBR_CONFIRM;
#ifdef WITH_COCOA
case (WKC_META | 'V'):
#endif
case (WKC_CTRL | 'V'): case (WKC_CTRL | 'V'):
if (InsertTextBufferClipboard(&this->text)) w->SetWidgetDirty(wid); if (InsertTextBufferClipboard(&this->text)) w->SetWidgetDirty(wid);
break; break;
#ifdef WITH_COCOA
case (WKC_META | 'U'):
#endif
case (WKC_CTRL | 'U'): case (WKC_CTRL | 'U'):
DeleteTextBufferAll(&this->text); DeleteTextBufferAll(&this->text);
w->SetWidgetDirty(wid); w->SetWidgetDirty(wid);

View File

@ -11,6 +11,7 @@
#include "../../core/bitmath_func.hpp" #include "../../core/bitmath_func.hpp"
#include "../../rev.h" #include "../../rev.h"
#include "macos.h" #include "macos.h"
#include "../../string_func.h"
#define Rect OTTDRect #define Rect OTTDRect
#define Point OTTDPoint #define Point OTTDPoint
@ -118,3 +119,19 @@ const char *GetCurrentLocale(const char *)
} }
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;
}

View File

@ -176,14 +176,7 @@ int CDECL main(int argc, char *argv[])
return ttd_main(argc, argv); return ttd_main(argc, argv);
} }
/** bool GetClipboardContents(char *buffer, size_t buff_len)
* 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)
{ {
/* XXX -- Currently no clipboard support implemented with GCC */ /* XXX -- Currently no clipboard support implemented with GCC */
#ifndef __INNOTEK_LIBC__ #ifndef __INNOTEK_LIBC__
@ -195,30 +188,7 @@ bool InsertTextBufferClipboard(Textbuf *tb)
if (text != NULL) if (text != NULL)
{ {
uint length = 0; ttd_strlcpy(buffer, text, buff_len);
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;
WinCloseClipbrd(hab); WinCloseClipbrd(hab);
return true; return true;
} }

View File

@ -262,10 +262,12 @@ int CDECL main(int argc, char *argv[])
return ret; return ret;
} }
bool InsertTextBufferClipboard(Textbuf *tb) #ifndef WITH_COCOA
bool GetClipboardContents(char *buffer, size_t buff_len)
{ {
return false; return false;
} }
#endif
/* multi os compatible sleep function */ /* multi os compatible sleep function */

View File

@ -465,28 +465,18 @@ void DetermineBasePaths(const char *exe)
_searchpaths[SP_APPLICATION_BUNDLE_DIR] = NULL; _searchpaths[SP_APPLICATION_BUNDLE_DIR] = NULL;
} }
/**
* Insert a chunk of text from the clipboard onto the textbuffer. Get TEXT clipboard bool GetClipboardContents(char *buffer, size_t buff_len)
* 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)
{ {
HGLOBAL cbuf; HGLOBAL cbuf;
char utf8_buf[512];
const char *ptr; const char *ptr;
WChar c;
uint16 width, length;
if (IsClipboardFormatAvailable(CF_UNICODETEXT)) { if (IsClipboardFormatAvailable(CF_UNICODETEXT)) {
OpenClipboard(NULL); OpenClipboard(NULL);
cbuf = GetClipboardData(CF_UNICODETEXT); cbuf = GetClipboardData(CF_UNICODETEXT);
ptr = (const char*)GlobalLock(cbuf); 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); GlobalUnlock(cbuf);
CloseClipboard(); CloseClipboard();
@ -497,7 +487,7 @@ bool InsertTextBufferClipboard(Textbuf *tb)
cbuf = GetClipboardData(CF_TEXT); cbuf = GetClipboardData(CF_TEXT);
ptr = (const char*)GlobalLock(cbuf); ptr = (const char*)GlobalLock(cbuf);
strecpy(utf8_buf, FS2OTTD(ptr), lastof(utf8_buf)); ttd_strlcpy(buffer, FS2OTTD(ptr), buff_len);
GlobalUnlock(cbuf); GlobalUnlock(cbuf);
CloseClipboard(); CloseClipboard();
@ -506,33 +496,6 @@ bool InsertTextBufferClipboard(Textbuf *tb)
return false; 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; return true;
} }