mirror of
https://github.com/JGRennison/OpenTTD-patches.git
synced 2024-11-11 13:10:45 +00:00
(svn r17708) -Feature [FS#2053]: [OSX] Implement clipboard support for OS X.
This commit is contained in:
parent
a831143f45
commit
049d62b35c
@ -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();
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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 */
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user