summaryrefslogtreecommitdiff
path: root/protocols/IcqOscarJ/src/changeinfo/editstring.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'protocols/IcqOscarJ/src/changeinfo/editstring.cpp')
-rw-r--r--protocols/IcqOscarJ/src/changeinfo/editstring.cpp367
1 files changed, 367 insertions, 0 deletions
diff --git a/protocols/IcqOscarJ/src/changeinfo/editstring.cpp b/protocols/IcqOscarJ/src/changeinfo/editstring.cpp
new file mode 100644
index 0000000000..288351e8d3
--- /dev/null
+++ b/protocols/IcqOscarJ/src/changeinfo/editstring.cpp
@@ -0,0 +1,367 @@
+// ---------------------------------------------------------------------------80
+// ICQ plugin for Miranda Instant Messenger
+// ________________________________________
+//
+// Copyright © 2001-2004 Richard Hughes, Martin Öberg
+// Copyright © 2004-2009 Joe Kucera, Bio
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// -----------------------------------------------------------------------------
+// DESCRIPTION:
+//
+// ChangeInfo Plugin stuff
+//
+// -----------------------------------------------------------------------------
+#include "icqoscar.h"
+
+
+static ChangeInfoData *dataStringEdit = NULL;
+static WNDPROC OldStringEditProc, OldExpandButtonProc;
+static HWND hwndEdit = NULL, hwndExpandButton = NULL, hwndUpDown = NULL;
+
+static const char escapes[]={'a','\a',
+'b','\b',
+'e',27,
+'f','\f',
+'r','\r',
+'t','\t',
+'v','\v',
+'\\','\\'};
+
+static void EscapesToMultiline(WCHAR *str,PDWORD selStart,PDWORD selEnd)
+{ //converts "\\n" and "\\t" to "\r\n" and "\t" because a multi-line edit box can show them properly
+ DWORD i;
+
+ for(i=0; *str; str++, i++)
+ {
+ if (*str != '\\') continue;
+ if (str[1] == 'n')
+ {
+ *str++ = '\r';
+ i++;
+ *str = '\n';
+ }
+ else if (str[1] == 't')
+ {
+ *str = '\t';
+ memmove(str+1, str+2, sizeof(WCHAR)*(strlennull(str)-1));
+
+ if (*selStart>i) --*selStart;
+ if (*selEnd>i) --*selEnd;
+ }
+ }
+}
+
+
+
+static void EscapesToBinary(char *str)
+{
+ for (;*str;str++)
+ {
+ if (*str!='\\') continue;
+ if(str[1]=='n') {*str++='\r'; *str='\n'; continue;}
+ if(str[1]=='0')
+ {
+ char *codeend;
+ *str=(char)strtol(str+1,&codeend,8);
+ if (*str==0) {*str='\\'; continue;}
+ memmove(str+1,codeend,strlennull(codeend)+1);
+ continue;
+ }
+ for(int i=0;i<SIZEOF(escapes);i+=2)
+ if(str[1]==escapes[i])
+ {
+ *str=escapes[i+1];
+ memmove(str+1,str+2,strlennull(str)-1);
+ break;
+ }
+ }
+}
+
+
+
+char *BinaryToEscapes(char *str)
+{
+ int extra=10,len=strlennull(str)+11,i;
+ char *out,*pout;
+
+ out=pout=(char*)SAFE_MALLOC(len);
+ for (;*str;str++)
+ {
+ if ((unsigned char)*str>=' ')
+ {
+ *pout++=*str;
+ continue;
+ }
+ if(str[0]=='\r' && str[1]=='\n')
+ {
+ *pout++='\\';
+ *pout++='n';
+ str++;
+ continue;
+ }
+ if(extra<3)
+ {
+ extra+=8; len+=8;
+ pout=out=(char*)SAFE_REALLOC(out,len);
+ }
+ *pout++='\\';
+ for(i = 0; i < SIZEOF(escapes); i += 2)
+ if (*str==escapes[i+1])
+ {
+ *pout++=escapes[i];
+ extra--;
+ break;
+ }
+ if(i < SIZEOF(escapes)) continue;
+ *pout++='0'; extra--;
+ if (*str>=8)
+ {
+ *pout++=(*str>>3)+'0';
+ extra--;
+ }
+ *pout++=(*str&7)+'0'; extra--;
+ }
+ *pout='\0';
+ return out;
+}
+
+
+
+static LRESULT CALLBACK StringEditSubclassProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
+{
+ switch(msg)
+ {
+ case WM_KEYDOWN:
+ if (wParam==VK_ESCAPE)
+ {
+ if (dataStringEdit)
+ dataStringEdit->EndStringEdit(0);
+ return 0;
+ }
+ if (wParam==VK_RETURN)
+ {
+ if (GetWindowLongPtr(hwnd, GWL_STYLE) & ES_MULTILINE && !(GetKeyState(VK_CONTROL) & 0x8000)) break;
+ if (dataStringEdit)
+ dataStringEdit->EndStringEdit(1);
+ return 0;
+ }
+ break;
+
+ case WM_GETDLGCODE:
+ return DLGC_WANTALLKEYS|CallWindowProc(OldStringEditProc, hwnd, msg, wParam, lParam);
+
+ case WM_KILLFOCUS:
+ if ((HWND)wParam == hwndExpandButton) break;
+ if (dataStringEdit)
+ dataStringEdit->EndStringEdit(1);
+ return 0;
+ }
+ return CallWindowProc(OldStringEditProc, hwnd, msg, wParam, lParam);
+}
+
+
+
+static LRESULT CALLBACK ExpandButtonSubclassProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
+{
+ switch(msg)
+ {
+ case WM_LBUTTONUP:
+ if(GetCapture()==hwnd)
+ {
+ //do expand
+ RECT rcStart,rcEnd;
+ DWORD selStart,selEnd;
+ WCHAR *text;
+ BOOL animEnabled=TRUE;
+
+ GetWindowRect(hwndEdit,&rcStart);
+ InflateRect(&rcStart,2,2);
+
+ text = GetWindowTextUcs(hwndEdit);
+ SendMessage(hwndEdit,EM_GETSEL,(WPARAM)&selStart,(LPARAM)&selEnd);
+ DestroyWindow(hwndEdit);
+ EscapesToMultiline(text,&selStart,&selEnd);
+ hwndEdit=CreateWindowExA(WS_EX_TOOLWINDOW,"EDIT","",WS_POPUP|WS_BORDER|WS_VISIBLE|ES_WANTRETURN|ES_AUTOVSCROLL|WS_VSCROLL|ES_MULTILINE,rcStart.left,rcStart.top,rcStart.right-rcStart.left,rcStart.bottom-rcStart.top,NULL,NULL,hInst,NULL);
+ SetWindowTextUcs(hwndEdit, text);
+ OldStringEditProc=(WNDPROC)SetWindowLongPtr(hwndEdit,GWLP_WNDPROC,(LONG_PTR)StringEditSubclassProc);
+ SendMessage(hwndEdit,WM_SETFONT,(WPARAM)dataStringEdit->hListFont,0);
+ SendMessage(hwndEdit,EM_SETSEL,selStart,selEnd);
+ SetFocus(hwndEdit);
+
+ rcEnd.left=rcStart.left; rcEnd.top=rcStart.top;
+ rcEnd.right=rcEnd.left+350;
+ rcEnd.bottom=rcEnd.top+150;
+ if (LOBYTE(LOWORD(GetVersion()))>4 || HIBYTE(LOWORD(GetVersion()))>0)
+ SystemParametersInfo(SPI_GETCOMBOBOXANIMATION,0,&animEnabled,FALSE);
+ if(animEnabled)
+ {
+ DWORD startTime,timeNow;
+ startTime=GetTickCount();
+ for (;;)
+ {
+ UpdateWindow(hwndEdit);
+ timeNow=GetTickCount();
+ if(timeNow>startTime+200) break;
+ SetWindowPos(hwndEdit,0,rcEnd.left,rcEnd.top,(rcEnd.right-rcStart.right)*(timeNow-startTime)/200+rcStart.right-rcEnd.left,(rcEnd.bottom-rcStart.bottom)*(timeNow-startTime)/200+rcStart.bottom-rcEnd.top,SWP_NOZORDER);
+ }
+ }
+ SetWindowPos(hwndEdit,0,rcEnd.left,rcEnd.top,rcEnd.right-rcEnd.left,rcEnd.bottom-rcEnd.top,SWP_NOZORDER);
+
+ DestroyWindow(hwnd);
+ hwndExpandButton=NULL;
+
+ SAFE_FREE((void**)&text);
+ }
+ break;
+ }
+ return CallWindowProc(OldExpandButtonProc,hwnd,msg,wParam,lParam);
+}
+
+
+void ChangeInfoData::BeginStringEdit(int iItem, RECT *rc, int i, WORD wVKey)
+{
+ char *szValue;
+ char str[80];
+ int alloced=0;
+
+ EndStringEdit(0);
+ InflateRect(rc,-2,-2);
+ rc->left-=2;
+ if (setting[i].displayType & LIF_PASSWORD && !settingData[i].changed)
+ szValue = " ";
+ else if ((setting[i].displayType & LIM_TYPE) == LI_NUMBER)
+ {
+ szValue = str;
+ null_snprintf(str, sizeof(str), "%d", settingData[i].value );
+ }
+ else if (settingData[i].value)
+ {
+ szValue = BinaryToEscapes((char*)settingData[i].value);
+ alloced = 1;
+ }
+ else szValue = "";
+
+ iEditItem = iItem;
+
+ if ((setting[i].displayType & LIM_TYPE)==LI_LONGSTRING)
+ {
+ rc->right-=rc->bottom-rc->top;
+ hwndExpandButton=CreateWindowA("BUTTON","",WS_VISIBLE|WS_CHILD|BS_PUSHBUTTON|BS_ICON,rc->right,rc->top,rc->bottom-rc->top,rc->bottom-rc->top,hwndList,NULL,hInst,NULL);
+ SendMessage(hwndExpandButton,BM_SETIMAGE,IMAGE_ICON,(LPARAM)LoadImage(hInst,MAKEINTRESOURCE(IDI_EXPANDSTRINGEDIT),IMAGE_ICON,0,0,LR_SHARED));
+ OldExpandButtonProc=(WNDPROC)SetWindowLongPtr(hwndExpandButton,GWLP_WNDPROC,(LONG_PTR)ExpandButtonSubclassProc);
+ }
+
+ dataStringEdit = this;
+ hwndEdit = CreateWindow(_T("EDIT"),_T(""),WS_VISIBLE|WS_CHILD|ES_AUTOHSCROLL|((setting[i].displayType&LIM_TYPE)==LI_NUMBER?ES_NUMBER:0)|(setting[i].displayType&LIF_PASSWORD?ES_PASSWORD:0),rc->left,rc->top,rc->right-rc->left,rc->bottom-rc->top,hwndList,NULL,hInst,NULL);
+ SetWindowTextUtf(hwndEdit, szValue);
+ if (alloced) SAFE_FREE(&szValue);
+ OldStringEditProc=(WNDPROC)SetWindowLongPtr(hwndEdit,GWLP_WNDPROC,(LONG_PTR)StringEditSubclassProc);
+ SendMessage(hwndEdit,WM_SETFONT,(WPARAM)hListFont,0);
+ if ((setting[i].displayType & LIM_TYPE) == LI_NUMBER)
+ {
+ int *range= (int*)setting[i].pList;
+ RECT rcUpDown;
+ hwndUpDown=CreateWindow(UPDOWN_CLASS,_T(""),WS_VISIBLE|WS_CHILD|UDS_AUTOBUDDY|UDS_ALIGNRIGHT|UDS_HOTTRACK|UDS_NOTHOUSANDS|UDS_SETBUDDYINT,0,0,0,0,hwndList,NULL,hInst,NULL);
+ SendMessage(hwndUpDown, UDM_SETRANGE32, range[0], range[1]);
+ SendMessage(hwndUpDown, UDM_SETPOS32, 0, settingData[i].value);
+ if (!(setting[i].displayType & LIF_ZEROISVALID) && settingData[i].value==0)
+ SetWindowTextA(hwndEdit, "");
+ GetClientRect(hwndUpDown, &rcUpDown);
+ rc->right -= rcUpDown.right;
+ SetWindowPos(hwndEdit,0,0,0,rc->right-rc->left,rc->bottom-rc->top,SWP_NOZORDER|SWP_NOMOVE);
+ }
+ SendMessage(hwndEdit,EM_SETSEL,0,(LPARAM)-1);
+ SetFocus(hwndEdit);
+ PostMessage(hwndEdit,WM_KEYDOWN,wVKey,0);
+}
+
+
+void ChangeInfoData::EndStringEdit(int save)
+{
+ if (hwndEdit == NULL || iEditItem == -1 || this != dataStringEdit) return;
+ if (save)
+ {
+ char *text = (char*)SAFE_MALLOC(GetWindowTextLength(hwndEdit)+1);
+
+ GetWindowTextA(hwndEdit,(char*)text,GetWindowTextLength(hwndEdit)+1);
+ EscapesToBinary(text);
+ if ((setting[iEditItem].displayType&LIM_TYPE)==LI_NUMBER)
+ {
+ LPARAM newValue;
+ int *range=(int*)setting[iEditItem].pList;
+ newValue = atoi(text);
+ if (newValue)
+ {
+ if (newValue<range[0]) newValue=range[0];
+ if (newValue>range[1]) newValue=range[1];
+ }
+ settingData[iEditItem].changed = settingData[iEditItem].value != newValue;
+ settingData[iEditItem].value = newValue;
+ SAFE_FREE(&text);
+ }
+ else
+ {
+ if (!(setting[iEditItem].displayType & LIF_PASSWORD))
+ {
+ SAFE_FREE(&text);
+ text = GetWindowTextUtf(hwndEdit);
+ EscapesToBinary(text);
+ }
+ if ((setting[iEditItem].displayType & LIF_PASSWORD && strcmpnull(text," ")) ||
+ (!(setting[iEditItem].displayType & LIF_PASSWORD) && strcmpnull(text, (char*)settingData[iEditItem].value) && (strlennull(text) + strlennull((char*)settingData[iEditItem].value))))
+ {
+ SAFE_FREE((void**)&settingData[iEditItem].value);
+ if (strlennull(text))
+ settingData[iEditItem].value = (LPARAM)text;
+ else
+ {
+ settingData[iEditItem].value = 0;
+ SAFE_FREE(&text);
+ }
+ settingData[iEditItem].changed = 1;
+ }
+ }
+ if (settingData[iEditItem].changed)
+ {
+ TCHAR tbuf[MAX_PATH];
+
+ GetWindowText(hwndEdit, tbuf, SIZEOF(tbuf));
+ ListView_SetItemText(hwndList, iEditItem, 1, tbuf);
+
+ EnableDlgItem(hwndDlg, IDC_SAVE, TRUE);
+ }
+ }
+ ListView_RedrawItems(hwndList, iEditItem, iEditItem);
+ iEditItem = -1;
+ dataStringEdit = NULL;
+ DestroyWindow(hwndEdit);
+ hwndEdit = NULL;
+ if (hwndExpandButton) DestroyWindow(hwndExpandButton);
+ hwndExpandButton = NULL;
+ if (hwndUpDown) DestroyWindow(hwndUpDown);
+ hwndUpDown = NULL;
+}
+
+
+
+int IsStringEditWindow(HWND hwnd)
+{
+ if (hwnd == hwndEdit) return 1;
+ if (hwnd == hwndExpandButton) return 1;
+ if (hwnd == hwndUpDown) return 1;
+ return 0;
+}