# HG changeset patch # User nemo # Date 1426450483 14400 # Node ID 1af1a54d740b413ce125bc0d64af943db87dc963 # Parent 231d3e3d32675cbb0b5066bef3b7839470153cfe# Parent 4925438f5ab722fafd7f8c2d1f2f139d0589ec7a merge ☹ diff -r 231d3e3d3267 -r 1af1a54d740b QTfrontend/game.cpp --- a/QTfrontend/game.cpp Sun Mar 15 16:14:13 2015 -0400 +++ b/QTfrontend/game.cpp Sun Mar 15 16:14:43 2015 -0400 @@ -16,6 +16,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include +#include + #include #include #include @@ -258,6 +261,18 @@ .arg(QString::fromUtf8(msg.mid(2).left(size - 4)))); return; } + case 'y': + { + // copy string to clipboard + QApplication::clipboard()->setText(QString::fromUtf8(msg.mid(2))); + break; + } + case 'Y': + { + // paste clipboard to game + SendIPC(QString("Y").toAscii() + QApplication::clipboard()->text().toUtf8().left(250).replace('\n', ' ')); + break; + } case 'i': { emit GameStats(msg.at(2), QString::fromUtf8(msg.mid(3))); diff -r 231d3e3d3267 -r 1af1a54d740b hedgewars/SDLh.pas --- a/hedgewars/SDLh.pas Sun Mar 15 16:14:13 2015 -0400 +++ b/hedgewars/SDLh.pas Sun Mar 15 16:14:43 2015 -0400 @@ -307,8 +307,11 @@ SDLK_RETURN = 13; SDLK_ESCAPE = 27; SDLK_a = 97; + SDLK_c = 99; SDLK_q = 113; + SDLK_v = 118; SDLK_w = 119; + SDLK_x = 120; SDLK_DELETE = 127; SDLK_KP_ENTER = 271; SDLK_UP = 273; diff -r 231d3e3d3267 -r 1af1a54d740b hedgewars/uChat.pas --- a/hedgewars/uChat.pas Sun Mar 15 16:14:13 2015 -0400 +++ b/hedgewars/uChat.pas Sun Mar 15 16:14:43 2015 -0400 @@ -30,11 +30,13 @@ procedure DrawChat; procedure KeyPressChat(Key, Sym: Longword; Modifier: Word); procedure SendHogSpeech(s: shortstring); +procedure CopyToClipboard(var newContent: shortstring); implementation uses SDLh, uInputHandler, uTypes, uVariables, uCommands, uUtils, uTextures, uRender, uIO, uScript, uRenderUtils; const MaxStrIndex = 27; + MaxInputStrLen = 240; type TChatLine = record Tex: PTexture; @@ -63,11 +65,12 @@ liveLua: boolean; ChatHidden: boolean; firstDraw: boolean; - InputLinePrefix: shortstring; + InputLinePrefix: TChatLine; // cursor cursorPos, cursorX, selectedPos, selectionDx: LongInt; LastKeyPressTick: LongWord; + const InputStrLNoPred: byte = 255; @@ -110,12 +113,12 @@ // calculate cursor offset - str:= InputLinePrefix + InputStr.s; + str:= InputStr.s; font:= CheckCJKFont(ansistring(str), fnt16); // get only substring before cursor to determine length - // SetLength(str, Length(InputLinePrefix) + cursorPos); // makes pas2c unhappy - str[0]:= char(Length(InputLinePrefix) + cursorPos); + // SetLength(str, cursorPos); // makes pas2c unhappy + str[0]:= char(cursorPos); // get render size of text TTF_SizeUTF8(Fontz[font].Handle, Str2PChar(str), @coff, nil); @@ -125,9 +128,9 @@ if selectedPos >= 0 then begin if selectedPos > cursorPos then - str:= InputLinePrefix + InputStr.s; - // SetLength(str, Length(InputLinePrefix) + selectedPos); // makes pas2c unhappy - str[0]:= char(Length(InputLinePrefix) + selectedPos); + str:= InputStr.s; + // SetLength(str, selectedPos); // makes pas2c unhappy + str[0]:= char(selectedPos); TTF_SizeUTF8(Fontz[font].Handle, Str2PChar(str), @soff, nil); selectionDx:= soff - coff; end @@ -197,7 +200,7 @@ begin cl.s:= str; color:= colors[#6]; - str:= InputLinePrefix + str + ' '; + str:= str + ' '; end else begin @@ -248,6 +251,24 @@ inc(visibleCount) end; +procedure CheckPasteBuffer(); forward; + +procedure UpdateInputLinePrefix(); +begin +if liveLua then + begin + InputLinePrefix.color:= colors[#1]; + InputLinePrefix.s:= '[Lua] >'; + end +else + begin + InputLinePrefix.color:= colors[#6]; + InputLinePrefix.s:= UserNick + '>'; + end; + +FreeAndNilTexture(InputLinePrefix.Tex); +end; + procedure DrawChat; var i, t, left, top, cnt: LongInt; selRect: TSDL_Rect; @@ -264,13 +285,21 @@ // draw chat input line first and under all other lines if (GameState = gsChat) and (InputStr.Tex <> nil) then begin + CheckPasteBuffer(); + + if InputLinePrefix.Tex = nil then + RenderChatLineTex(InputLinePrefix, InputLinePrefix.s); + + DrawTexture(left, top, InputLinePrefix.Tex); + inc(left, InputLinePrefix.Width); + DrawTexture(left, top, InputStr.Tex); + if firstDraw then begin UpdateCursorCoords(); firstDraw:= false; end; - DrawTexture(left, top, InputStr.Tex); if selectedPos < 0 then begin // draw cursor @@ -294,9 +323,10 @@ DrawRect(selRect, $FF, $FF, $FF, $40, true); end; + + dec(left, InputLinePrefix.Width); end; - // draw chat lines if ((not ChatHidden) or showAll) and (UIDisplay <> uiNone) then begin @@ -458,6 +488,7 @@ AddFileLog('[Lua] chat input string parsing disabled'); AddChatString(#3 + 'Lua parsing: OFF'); end; + UpdateInputLinePrefix(); end; exit end; @@ -565,6 +596,7 @@ cursorPos:= min(cursorPos, selectedPos); ResetSelection(); end; + UpdateCursorCoords(); end; procedure HandleSelection(enabled: boolean); @@ -660,6 +692,73 @@ end; end; +procedure CopyToClipboard(var newContent: shortstring); +begin + SendIPC(_S'y' + copy(newContent, 1, 253) + #0); +end; + +procedure CopySelectionToClipboard(); +var selection: shortstring; +begin + if selectedPos >= 0 then + begin + selection:= copy(InputStr.s, min(CursorPos, selectedPos) + 1, abs(CursorPos - selectedPos)); + CopyToClipboard(selection); + end; +end; + +// TODO: honor utf8, don't break utf8 chars when shifting chars beyond limit +procedure InsertIntoInputStr(s: shortstring); +var i, l, il, lastc: integer; +begin + // safe length for string + l:= min(MaxInputStrLen-cursorPos, Length(s)); + s:= copy(s,1,l); + + // if we insert rather than append, shift info in InputStrL accordingly + if cursorPos < Length(InputStr.s) then + begin + for i:= Length(InputStr.s) downto cursorPos + 1 do + begin + if InputStrL[i] <> InputStrLNoPred then + begin + il:= i + l; + // only shift if not overflowing + if il <= MaxInputStrLen then + InputStrL[il]:= InputStrL[i] + l; + InputStrL[i]:= InputStrLNoPred; + end; + end; + end; + + InputStrL[cursorPos + l]:= cursorPos; + // insert string truncated to safe length + Insert(s, InputStr.s, cursorPos + 1); + if Length(InputStr.s) > MaxInputStrLen then + InputStr.s[0]:= char(MaxInputStrLen); + + SetLine(InputStr, InputStr.s, true); + + // move cursor to end of inserted string + lastc:= MaxInputStrLen; + cursorPos:= min(lastc, cursorPos + l); + UpdateCursorCoords(); +end; + +procedure PasteFromClipboard(); +begin + SendIPC(_S'Y'); +end; + +procedure CheckPasteBuffer(); +begin + if Length(ChatPasteBuffer) > 0 then + begin + InsertIntoInputStr(ChatPasteBuffer); + ChatPasteBuffer:= ''; + end; +end; + procedure KeyPressChat(Key, Sym: Longword; Modifier: Word); const firstByteMark: array[0..3] of byte = (0, $C0, $E0, $F0); var i, btw, index: integer; @@ -670,6 +769,8 @@ LastKeyPressTick:= RealTicks; action:= true; + CheckPasteBuffer(); + selMode:= (modifier and (KMOD_LSHIFT or KMOD_RSHIFT)) <> 0; ctrl:= (modifier and (KMOD_LCTRL or KMOD_RCTRL)) <> 0; skip:= none; @@ -691,11 +792,13 @@ HandleSelection(true); SkipInputChars(skip, true); DeleteSelected(); - end; + end + else + UpdateCursorCoords(); + end else DeleteSelected(); - UpdateCursorCoords(); end; SDLK_DELETE: begin @@ -718,12 +821,12 @@ SkipInputChars(skip, false); DeleteSelected(); end; - end; + end + else + UpdateCursorCoords(); end else DeleteSelected(); - - UpdateCursorCoords(); end; SDLK_ESCAPE: begin @@ -862,6 +965,33 @@ else action:= false; end; + SDLK_c: + begin + // copy + if ctrl then + CopySelectionToClipboard() + else + action:= false; + end; + SDLK_v: + begin + // paste + if ctrl then + PasteFromClipboard() + else + action:= false; + end; + SDLK_x: + begin + // cut + if ctrl then + begin + CopySelectionToClipboard(); + DeleteSelected(); + end + else + action:= false; + end; else action:= false; end; @@ -888,28 +1018,10 @@ utf8:= char(Key or firstByteMark[Pred(btw)]) + utf8; - if Length(InputStr.s) + btw > 240 then + if Length(InputStr.s) + btw > MaxInputStrLen then exit; - // if we insert rather than append, shift info in InputStrL accordingly - if cursorPos < Length(InputStr.s) then - begin - for i:= Length(InputStr.s) downto cursorPos + 1 do - begin - if InputStrL[i] <> InputStrLNoPred then - begin - InputStrL[i+btw]:= InputStrL[i] + btw; - InputStrL[i]:= InputStrLNoPred; - end; - end; - end; - - InputStrL[cursorPos + btw]:= cursorPos; - Insert(utf8, InputStr.s, cursorPos + 1); - SetLine(InputStr, InputStr.s, true); - - cursorPos:= cursorPos + btw; - UpdateCursorCoords(); + InsertIntoInputStr(utf8); end end; @@ -994,7 +1106,8 @@ ChatHidden:= false; firstDraw:= true; - InputLinePrefix:= UserNick + '> '; + InputLinePrefix.Tex:= nil; + UpdateInputLinePrefix(); inputStr.s:= ''; inputStr.Tex := nil; for i:= 0 to MaxStrIndex do @@ -1009,6 +1122,7 @@ procedure freeModule; var i: ShortInt; begin + FreeAndNilTexture(InputLinePrefix.Tex); FreeAndNilTexture(InputStr.Tex); for i:= 0 to MaxStrIndex do FreeAndNilTexture(Strs[i].Tex); diff -r 231d3e3d3267 -r 1af1a54d740b hedgewars/uIO.pas --- a/hedgewars/uIO.pas Sun Mar 15 16:14:13 2015 -0400 +++ b/hedgewars/uIO.pas Sun Mar 15 16:14:43 2015 -0400 @@ -163,6 +163,7 @@ ParseChatCommand('chatmsg ' + #4, s, 2) else isProcessed:= false; + 'Y': ChatPasteBuffer:= copy(s, 2, Length(s) - 1); else isProcessed:= false; end; diff -r 231d3e3d3267 -r 1af1a54d740b hedgewars/uVariables.pas --- a/hedgewars/uVariables.pas Sun Mar 15 16:14:13 2015 -0400 +++ b/hedgewars/uVariables.pas Sun Mar 15 16:14:43 2015 -0400 @@ -237,6 +237,8 @@ MaxTextureSize: LongInt; + ChatPasteBuffer: shortstring; + ///////////////////////////////////// //Buttons {$IFDEF USE_TOUCH_INTERFACE} @@ -2685,6 +2687,8 @@ cStereoDepth:= 0; cViewLimitsDebug:= false; AprilOne := false; + + ChatPasteBuffer:= ''; end; procedure freeModule; diff -r 231d3e3d3267 -r 1af1a54d740b misc/OfficialChallenges/racer_#15.hwmap --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/misc/OfficialChallenges/racer_#15.hwmap Sun Mar 15 16:14:43 2015 -0400 @@ -0,0 +1,1 @@ +AAACYnicFc9NSJRRFAbgc3/PfP8lqGGLIlpIJVktlHAgXaSRLTLMQIQGwwhJF8UIUs7umHExvCn5CcWgiSFo0SBGUrjJjSAIFZWgQdmiggqjdd9sHs7qfc/rZ2UWwnasg6hS1IMzy7ZBn9BbAEfwEXAu6kBl2FNgGTZbcMpFZSEo5+0F+VLfKMiIbczrMbk2H7RpM8+kXs3zEdlR5BLoa6w77/TqK3nvuuzPh1/lmbxXxarzsCCHYr6i0zEe1Cux14k1RY4nHyRX0CLvx3Jc/IxTa6wpxlL+KQ4n4FsctfLGmLWIVstfiArL38GCVS3wzKppPmJTOXXYukdVifWW9CHr1fAd6+dg0uIyzFj+CmOry3DUph7iPevuxT7r7sc+iPZp3zKr7hjxRlUniE4jf8sfJnVA3zb4Tx4z6peIDS6xdeNe5OkiteB8hxnjZOSkcR/rdJFa8HNi0/hZ1WXCniQvNKLC+DmcMmIR75Ju1OeJN6sBYnk5TJAVVQQd0E+8DK4S32LTxFf5ZRLPYZzkEAyR/CAYiY8yR3BBPSD2Gp8UmQKOqEmcTVDncIpwFy4TliY7cRNHCf+oDCGpbUoNq8/kDKguwlviLekGUUp6B3LknCyyzrrJbU96vXqeJl+J0+ROiD5yG+Qe8rS6Sd4X1UthMy5SsJGkBF1ijsLdRQa5obCH/aXgPSsh/xTLUNCWjInmRCdFpJooWtZjFE7oQfoP92i1IA== \ No newline at end of file diff -r 231d3e3d3267 -r 1af1a54d740b share/hedgewars/Data/Scripts/OfficialChallenges.lua --- a/share/hedgewars/Data/Scripts/OfficialChallenges.lua Sun Mar 15 16:14:13 2015 -0400 +++ b/share/hedgewars/Data/Scripts/OfficialChallenges.lua Sun Mar 15 16:14:43 2015 -0400 @@ -32,6 +32,8 @@ return("Racer Challenge #5") elseif LandDigest == "M479034891Scripts/Multiplayer/Racer.lua" then return("Racer Challenge #6") + elseif LandDigest == "M256715557Scripts/Multiplayer/Racer.lua" then + return("Racer Challenge #15") end end end