summaryrefslogtreecommitdiff
path: root/protocols/JabberG/src/jabber_form.cpp
diff options
context:
space:
mode:
authorVadim Dashevskiy <watcherhd@gmail.com>2012-10-12 14:53:57 +0000
committerVadim Dashevskiy <watcherhd@gmail.com>2012-10-12 14:53:57 +0000
commit3b55a62fdcb1f8222de3c2c8fbed530792c419a0 (patch)
tree5b2f628e847f61bb3e16f95ecaed6e187963362f /protocols/JabberG/src/jabber_form.cpp
parent1f9c986d82657f965462d289bf94aa012cf026fc (diff)
GTalkExt, ICQ, IRC, Jabber: folders restructurization
git-svn-id: http://svn.miranda-ng.org/main/trunk@1890 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'protocols/JabberG/src/jabber_form.cpp')
-rw-r--r--protocols/JabberG/src/jabber_form.cpp905
1 files changed, 905 insertions, 0 deletions
diff --git a/protocols/JabberG/src/jabber_form.cpp b/protocols/JabberG/src/jabber_form.cpp
new file mode 100644
index 0000000000..a90dcf62fa
--- /dev/null
+++ b/protocols/JabberG/src/jabber_form.cpp
@@ -0,0 +1,905 @@
+/*
+
+Jabber Protocol Plugin for Miranda IM
+Copyright ( C ) 2002-04 Santithorn Bunchua
+Copyright ( C ) 2005-12 George Hazan
+
+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.
+
+*/
+
+#include "jabber.h"
+#include "jabber_caps.h"
+
+
+static BOOL CALLBACK JabberFormMultiLineWndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
+{
+ switch ( msg ) {
+ //case WM_GETDLGCODE:
+ // return DLGC_WANTARROWS|DLGC_WANTCHARS|DLGC_HASSETSEL|DLGC_WANTALLKEYS;
+ case WM_KEYDOWN:
+ if ( wParam == VK_TAB ) {
+ SetFocus( GetNextDlgTabItem( GetParent( GetParent( hwnd )), hwnd, GetKeyState( VK_SHIFT )<0?TRUE:FALSE ));
+ return TRUE;
+ };
+ break;
+ }
+ return CallWindowProc(( WNDPROC ) GetWindowLongPtr( hwnd, GWLP_USERDATA ), hwnd, msg, wParam, lParam );
+}
+
+struct TJabberFormControlInfo
+{
+ TJabberFormControlType type;
+ SIZE szBlock;
+ POINT ptLabel, ptCtrl;
+ HWND hLabel, hCtrl;
+};
+typedef LIST<TJabberFormControlInfo> TJabberFormControlList;
+
+struct TJabberFormLayoutInfo
+{
+ int ctrlHeight;
+ int offset, width, maxLabelWidth;
+ int y_pos, y_spacing;
+ int id;
+ bool compact;
+};
+
+void JabberFormCenterContent(HWND hwndStatic)
+{
+ RECT rcWindow;
+ int minX;
+ GetWindowRect(hwndStatic,&rcWindow);
+ minX=rcWindow.right;
+ HWND oldChild=NULL;
+ HWND hWndChild=GetWindow(hwndStatic,GW_CHILD);
+ while (hWndChild!=oldChild && hWndChild!=NULL)
+ {
+ DWORD style=GetWindowLongPtr(hWndChild, GWL_STYLE);
+ RECT rc;
+ GetWindowRect(hWndChild,&rc);
+ if ((style&SS_RIGHT) && !(style&WS_TABSTOP))
+ {
+ TCHAR * text;
+ RECT calcRect=rc;
+ int len=GetWindowTextLength(hWndChild);
+ text=(TCHAR*)malloc(sizeof(TCHAR)*(len+1));
+ GetWindowText(hWndChild,text,len+1);
+ HDC hdc=GetDC(hWndChild);
+ HFONT hfntSave = (HFONT)SelectObject(hdc, (HFONT)SendMessage(hWndChild, WM_GETFONT, 0, 0));
+ DrawText(hdc,text,-1,&calcRect,DT_CALCRECT|DT_WORDBREAK);
+ minX=min(minX, rc.right-(calcRect.right-calcRect.left));
+ SelectObject(hdc, hfntSave);
+ ReleaseDC(hWndChild,hdc);
+ }
+ else
+ {
+ minX=min(minX,rc.left);
+ }
+ oldChild=hWndChild;
+ hWndChild=GetWindow(hWndChild,GW_HWNDNEXT);
+ }
+ if (minX>rcWindow.left+5)
+ {
+ int dx=(minX-rcWindow.left)/2;
+ oldChild=NULL;
+ hWndChild=GetWindow(hwndStatic,GW_CHILD);
+ while (hWndChild!=oldChild && hWndChild!=NULL )
+ {
+ DWORD style=GetWindowLongPtr(hWndChild, GWL_STYLE);
+ RECT rc;
+ GetWindowRect(hWndChild,&rc);
+ if ((style&SS_RIGHT) && !(style&WS_TABSTOP))
+ MoveWindow(hWndChild,rc.left-rcWindow.left,rc.top-rcWindow.top, rc.right-rc.left-dx, rc.bottom-rc.top, TRUE);
+ else
+ MoveWindow(hWndChild,rc.left-dx-rcWindow.left,rc.top-rcWindow.top, rc.right-rc.left, rc.bottom-rc.top, TRUE);
+ oldChild=hWndChild;
+ hWndChild=GetWindow(hWndChild,GW_HWNDNEXT);
+ }
+ }
+}
+
+void JabberFormSetInstruction( HWND hwndForm, const TCHAR *text )
+{
+ if (!text) text = _T("");
+
+ int len = lstrlen(text);
+ int fixedLen = len;
+ for (int i = 1; i < len; ++i)
+ if ((text[i - 1] == _T('\n')) && (text[i] != _T('\r')))
+ ++fixedLen;
+ TCHAR *fixedText = NULL;
+ if (fixedLen != len) {
+ fixedText = (TCHAR *)mir_alloc(sizeof(TCHAR) * (fixedLen+1));
+ TCHAR *p = fixedText;
+ for (int i = 0; i < len; ++i) {
+ *p = text[i];
+ if (i && (text[i] == _T('\n')) && (text[i] != _T('\r'))) {
+ *p++ = _T('\r');
+ *p = _T('\n');
+ }
+ ++p;
+ }
+ *p = 0;
+ text = fixedText;
+ }
+
+ SetDlgItemText( hwndForm, IDC_INSTRUCTION, text );
+
+ RECT rcText;
+ GetWindowRect(GetDlgItem(hwndForm, IDC_INSTRUCTION), &rcText);
+ int oldWidth = rcText.right-rcText.left;
+ int deltaHeight = -(rcText.bottom-rcText.top);
+
+ SetRect(&rcText, 0, 0, rcText.right-rcText.left, 0);
+ HDC hdcEdit = GetDC(GetDlgItem(hwndForm, IDC_INSTRUCTION));
+ HFONT hfntSave = (HFONT)SelectObject(hdcEdit, (HFONT)SendDlgItemMessage(hwndForm, IDC_INSTRUCTION, WM_GETFONT, 0, 0));
+ DrawTextEx(hdcEdit, (TCHAR *)text, lstrlen(text), &rcText,
+ DT_CALCRECT|DT_EDITCONTROL|DT_TOP|DT_WORDBREAK, NULL);
+ SelectObject(hdcEdit, hfntSave);
+ ReleaseDC(GetDlgItem(hwndForm, IDC_INSTRUCTION), hdcEdit);
+
+ RECT rcWindow; GetClientRect(hwndForm, &rcWindow);
+ if (rcText.bottom-rcText.top > (rcWindow.bottom-rcWindow.top)/5) {
+ HWND hwndEdit = GetDlgItem(hwndForm, IDC_INSTRUCTION);
+ SetWindowLongPtr(hwndEdit, GWL_STYLE, WS_VSCROLL | GetWindowLongPtr(hwndEdit, GWL_STYLE));
+ rcText.bottom = rcText.top + (rcWindow.bottom-rcWindow.top)/5;
+ } else {
+ HWND hwndEdit = GetDlgItem(hwndForm, IDC_INSTRUCTION);
+ SetWindowLongPtr(hwndEdit, GWL_STYLE, ~WS_VSCROLL & GetWindowLongPtr(hwndEdit, GWL_STYLE));
+ }
+ deltaHeight += rcText.bottom-rcText.top;
+
+ SetWindowPos(GetDlgItem(hwndForm, IDC_INSTRUCTION), 0, 0, 0,
+ oldWidth,
+ rcText.bottom-rcText.top,
+ SWP_NOMOVE|SWP_NOZORDER);
+
+ GetWindowRect(GetDlgItem(hwndForm, IDC_WHITERECT), &rcText);
+ MapWindowPoints(NULL, hwndForm, (LPPOINT)&rcText, 2);
+ rcText.bottom += deltaHeight;
+ SetWindowPos(GetDlgItem(hwndForm, IDC_WHITERECT), 0, 0, 0,
+ rcText.right-rcText.left,
+ rcText.bottom-rcText.top,
+ SWP_NOMOVE|SWP_NOZORDER);
+
+ GetWindowRect(GetDlgItem(hwndForm, IDC_FRAME1), &rcText);
+ MapWindowPoints(NULL, hwndForm, (LPPOINT)&rcText, 2);
+ rcText.top += deltaHeight;
+ SetWindowPos(GetDlgItem(hwndForm, IDC_FRAME1), 0,
+ rcText.left,
+ rcText.top,
+ 0, 0,
+ SWP_NOSIZE|SWP_NOZORDER);
+
+ GetWindowRect(GetDlgItem(hwndForm, IDC_FRAME), &rcText);
+ MapWindowPoints(NULL, hwndForm, (LPPOINT)&rcText, 2);
+ rcText.top += deltaHeight;
+ SetWindowPos(GetDlgItem(hwndForm, IDC_FRAME), 0,
+ rcText.left,
+ rcText.top,
+ rcText.right-rcText.left,
+ rcText.bottom-rcText.top,
+ SWP_NOZORDER);
+
+ GetWindowRect(GetDlgItem(hwndForm, IDC_VSCROLL), &rcText);
+ MapWindowPoints(NULL, hwndForm, (LPPOINT)&rcText, 2);
+ rcText.top += deltaHeight;
+ SetWindowPos(GetDlgItem(hwndForm, IDC_VSCROLL), 0,
+ rcText.left,
+ rcText.top,
+ rcText.right-rcText.left,
+ rcText.bottom-rcText.top,
+ SWP_NOZORDER);
+
+ if (fixedText) mir_free(fixedText);
+}
+
+static TJabberFormControlType JabberFormTypeNameToId( const TCHAR *type )
+{
+ if ( !_tcscmp( type, _T("text-private")))
+ return JFORM_CTYPE_TEXT_PRIVATE;
+ if ( !_tcscmp( type, _T("text-multi")) || !_tcscmp( type, _T("jid-multi")))
+ return JFORM_CTYPE_TEXT_MULTI;
+ if ( !_tcscmp( type, _T("boolean")))
+ return JFORM_CTYPE_BOOLEAN;
+ if ( !_tcscmp( type, _T("list-single")))
+ return JFORM_CTYPE_LIST_SINGLE;
+ if ( !_tcscmp( type, _T("list-multi")))
+ return JFORM_CTYPE_LIST_MULTI;
+ if ( !_tcscmp( type, _T("fixed")))
+ return JFORM_CTYPE_FIXED;
+ if ( !_tcscmp( type, _T("hidden")))
+ return JFORM_CTYPE_HIDDEN;
+ // else
+ return JFORM_CTYPE_TEXT_SINGLE;
+}
+
+void JabberFormLayoutSingleControl(TJabberFormControlInfo *item, TJabberFormLayoutInfo *layout_info, const TCHAR *labelStr, const TCHAR *valueStr)
+{
+ RECT rcLabel = {0}, rcCtrl = {0};
+ if (item->hLabel)
+ {
+ SetRect(&rcLabel, 0, 0, layout_info->width, 0);
+ HDC hdc = GetDC( item->hLabel );
+ HFONT hfntSave = (HFONT)SelectObject(hdc, (HFONT)SendMessage(item->hLabel, WM_GETFONT, 0, 0));
+ DrawText( hdc, labelStr, -1, &rcLabel, DT_CALCRECT|DT_WORDBREAK );
+ SelectObject(hdc, hfntSave);
+ ReleaseDC(item->hLabel, hdc);
+ }
+
+ int indent = layout_info->compact ? 10 : 20;
+
+ if ((layout_info->compact && (item->type != JFORM_CTYPE_BOOLEAN) && (item->type != JFORM_CTYPE_FIXED))||
+ (rcLabel.right >= layout_info->maxLabelWidth) ||
+ (rcLabel.bottom > layout_info->ctrlHeight) ||
+ (item->type == JFORM_CTYPE_LIST_MULTI) ||
+ (item->type == JFORM_CTYPE_TEXT_MULTI))
+ {
+ int height = layout_info->ctrlHeight;
+ if ((item->type == JFORM_CTYPE_LIST_MULTI) || (item->type == JFORM_CTYPE_TEXT_MULTI)) height *= 3;
+ SetRect(&rcCtrl, indent, rcLabel.bottom, layout_info->width, rcLabel.bottom + height);
+ } else
+ if (item->type == JFORM_CTYPE_BOOLEAN)
+ {
+ SetRect(&rcCtrl, 0, 0, layout_info->width-20, 0);
+ HDC hdc = GetDC( item->hCtrl );
+ HFONT hfntSave = (HFONT)SelectObject(hdc, (HFONT)SendMessage(item->hCtrl, WM_GETFONT, 0, 0));
+ DrawText( hdc, labelStr, -1, &rcCtrl, DT_CALCRECT|DT_RIGHT|DT_WORDBREAK );
+ SelectObject(hdc, hfntSave);
+ ReleaseDC(item->hCtrl, hdc);
+ rcCtrl.right += 20;
+ } else
+ if (item->type == JFORM_CTYPE_FIXED)
+ {
+ SetRect(&rcCtrl, 0, 0, layout_info->width, 0);
+ HDC hdc = GetDC( item->hCtrl );
+ HFONT hfntSave = (HFONT)SelectObject(hdc, (HFONT)SendMessage(item->hCtrl, WM_GETFONT, 0, 0));
+ DrawText( hdc, valueStr, -1, &rcCtrl, DT_CALCRECT|DT_EDITCONTROL );
+ rcCtrl.right += 20;
+ SelectObject(hdc, hfntSave);
+ ReleaseDC(item->hCtrl, hdc);
+ } else
+ {
+ SetRect(&rcCtrl, rcLabel.right+5, 0, layout_info->width, layout_info->ctrlHeight);
+ rcLabel.bottom = rcCtrl.bottom;
+ }
+
+ if (item->hLabel)
+ SetWindowPos(item->hLabel, 0,
+ 0, 0, rcLabel.right-rcLabel.left, rcLabel.bottom-rcLabel.top,
+ SWP_NOZORDER|SWP_NOMOVE);
+ if (item->hCtrl)
+ SetWindowPos(item->hCtrl, 0,
+ 0, 0, rcCtrl.right-rcCtrl.left, rcCtrl.bottom-rcCtrl.top,
+ SWP_NOZORDER|SWP_NOMOVE);
+
+ item->ptLabel.x = rcLabel.left;
+ item->ptLabel.y = rcLabel.top;
+ item->ptCtrl.x = rcCtrl.left;
+ item->ptCtrl.y = rcCtrl.top;
+ item->szBlock.cx = layout_info->width;
+ item->szBlock.cy = max(rcLabel.bottom, rcCtrl.bottom);
+}
+
+#define JabberFormCreateLabel() \
+ CreateWindow( _T("static"), labelStr, WS_CHILD|WS_VISIBLE|SS_CENTERIMAGE, \
+ 0, 0, 0, 0, hwndStatic, ( HMENU )-1, hInst, NULL )
+
+TJabberFormControlInfo *JabberFormAppendControl(HWND hwndStatic, TJabberFormLayoutInfo *layout_info, TJabberFormControlType type, const TCHAR *labelStr, const TCHAR *valueStr)
+{
+ TJabberFormControlList *controls = (TJabberFormControlList *)GetWindowLongPtr(hwndStatic, GWLP_USERDATA);
+ if (!controls)
+ {
+ controls = new TJabberFormControlList(5);
+ SetWindowLongPtr(hwndStatic, GWLP_USERDATA, (LONG_PTR)controls);
+ }
+
+ TJabberFormControlInfo *item = (TJabberFormControlInfo *)mir_alloc(sizeof(TJabberFormControlInfo));
+ item->type = type;
+ item->hLabel = item->hCtrl = NULL;
+
+ switch (type)
+ {
+ case JFORM_CTYPE_TEXT_PRIVATE:
+ {
+ item->hLabel = JabberFormCreateLabel();
+ item->hCtrl = CreateWindowEx( WS_EX_CLIENTEDGE, _T("edit"), valueStr,
+ WS_CHILD|WS_VISIBLE|WS_TABSTOP|ES_LEFT|ES_AUTOHSCROLL|ES_PASSWORD,
+ 0, 0, 0, 0,
+ hwndStatic, ( HMENU ) layout_info->id, hInst, NULL );
+ ++layout_info->id;
+ break;
+ }
+ case JFORM_CTYPE_TEXT_MULTI:
+ {
+ item->hLabel = JabberFormCreateLabel();
+ item->hCtrl = CreateWindowEx( WS_EX_CLIENTEDGE, _T("edit"), valueStr,
+ WS_CHILD|WS_VISIBLE|WS_TABSTOP|WS_VSCROLL|ES_LEFT|ES_MULTILINE|ES_AUTOVSCROLL|ES_WANTRETURN,
+ 0, 0, 0, 0,
+ hwndStatic, ( HMENU ) layout_info->id, hInst, NULL );
+ WNDPROC oldWndProc = ( WNDPROC ) SetWindowLongPtr( item->hCtrl, GWLP_WNDPROC, ( LONG_PTR )JabberFormMultiLineWndProc );
+ SetWindowLongPtr( item->hCtrl, GWLP_USERDATA, ( LONG_PTR ) oldWndProc );
+ ++layout_info->id;
+ break;
+ }
+ case JFORM_CTYPE_BOOLEAN:
+ {
+ item->hCtrl = CreateWindowEx( 0, _T("button"), labelStr,
+ WS_CHILD|WS_VISIBLE|WS_TABSTOP|BS_AUTOCHECKBOX|BS_MULTILINE,
+ 0, 0, 0, 0,
+ hwndStatic, ( HMENU ) layout_info->id, hInst, NULL );
+ if ( valueStr && !_tcscmp( valueStr, _T("1")))
+ SendMessage( item->hCtrl, BM_SETCHECK, 1, 0 );
+ ++layout_info->id;
+ break;
+ }
+ case JFORM_CTYPE_LIST_SINGLE:
+ {
+ item->hLabel = JabberFormCreateLabel();
+ item->hCtrl = CreateWindowExA( WS_EX_CLIENTEDGE, "combobox", NULL,
+ WS_CHILD|WS_VISIBLE|WS_TABSTOP|CBS_DROPDOWNLIST,
+ 0, 0, 0, 0,
+ hwndStatic, ( HMENU ) layout_info->id, hInst, NULL );
+ ++layout_info->id;
+ break;
+ }
+ case JFORM_CTYPE_LIST_MULTI:
+ {
+ item->hLabel = JabberFormCreateLabel();
+ item->hCtrl = CreateWindowExA( WS_EX_CLIENTEDGE, "listbox",
+ NULL, WS_CHILD|WS_VISIBLE|WS_TABSTOP|LBS_MULTIPLESEL,
+ 0, 0, 0, 0,
+ hwndStatic, ( HMENU ) layout_info->id, hInst, NULL );
+ ++layout_info->id;
+ break;
+ }
+ case JFORM_CTYPE_FIXED:
+ {
+ item->hCtrl = CreateWindow( _T("edit"), valueStr,
+ WS_CHILD|WS_VISIBLE|ES_MULTILINE|ES_READONLY|ES_AUTOHSCROLL,
+ 0, 0, 0, 0,
+ hwndStatic, ( HMENU )-1, hInst, NULL );
+ break;
+ }
+ case JFORM_CTYPE_HIDDEN:
+ {
+ break;
+ }
+ case JFORM_CTYPE_TEXT_SINGLE:
+ {
+ item->hLabel = labelStr ? (JabberFormCreateLabel()) : NULL;
+ item->hCtrl = CreateWindowEx( WS_EX_CLIENTEDGE, _T("edit"), valueStr,
+ WS_CHILD|WS_VISIBLE|WS_TABSTOP|ES_LEFT|ES_AUTOHSCROLL,
+ 0, 0, 0, 0,
+ hwndStatic, ( HMENU ) layout_info->id, hInst, NULL );
+ ++layout_info->id;
+ break;
+ }
+ }
+
+ HFONT hFont = ( HFONT ) SendMessage( GetParent(hwndStatic), WM_GETFONT, 0, 0 );
+ if (item->hLabel) SendMessage( item->hLabel, WM_SETFONT, ( WPARAM ) hFont, 0 );
+ if (item->hCtrl) SendMessage( item->hCtrl, WM_SETFONT, ( WPARAM ) hFont, 0 );
+
+ JabberFormLayoutSingleControl(item, layout_info, labelStr, valueStr);
+
+ controls->insert(item);
+ return item;
+}
+
+void JabberFormAddListItem(TJabberFormControlInfo *item, TCHAR *text, bool selected)
+{
+ DWORD dwIndex;
+ switch (item->type)
+ {
+ case JFORM_CTYPE_LIST_MULTI:
+ dwIndex = SendMessage(item->hCtrl, LB_ADDSTRING, 0, (LPARAM)text);
+ if (selected) SendMessage(item->hCtrl, LB_SETSEL, TRUE, dwIndex);
+ break;
+ case JFORM_CTYPE_LIST_SINGLE:
+ dwIndex = SendMessage(item->hCtrl, CB_ADDSTRING, 0, (LPARAM)text);
+ if (selected) SendMessage(item->hCtrl, CB_SETCURSEL, dwIndex, 0);
+ break;
+ }
+}
+
+void JabberFormLayoutControls(HWND hwndStatic, TJabberFormLayoutInfo *layout_info, int *formHeight)
+{
+ TJabberFormControlList *controls = (TJabberFormControlList *)GetWindowLongPtr(hwndStatic, GWLP_USERDATA);
+ if (!controls) return;
+
+ for (int i = 0; i < controls->getCount(); ++i)
+ {
+ if ((*controls)[i]->hLabel)
+ SetWindowPos((*controls)[i]->hLabel, 0,
+ layout_info->offset+(*controls)[i]->ptLabel.x, layout_info->y_pos+(*controls)[i]->ptLabel.y, 0, 0,
+ SWP_NOZORDER|SWP_NOSIZE);
+ if ((*controls)[i]->hCtrl)
+ SetWindowPos((*controls)[i]->hCtrl, 0,
+ layout_info->offset+(*controls)[i]->ptCtrl.x, layout_info->y_pos+(*controls)[i]->ptCtrl.y, 0, 0,
+ SWP_NOZORDER|SWP_NOSIZE);
+
+ layout_info->y_pos += (*controls)[i]->szBlock.cy;
+ layout_info->y_pos += layout_info->y_spacing;
+ }
+
+ *formHeight = layout_info->y_pos + (layout_info->compact ? 0 : 9);
+}
+
+HJFORMLAYOUT JabberFormCreateLayout(HWND hwndStatic)
+{
+ RECT frameRect;
+ GetClientRect( hwndStatic, &frameRect );
+
+ TJabberFormLayoutInfo *layout_info = (TJabberFormLayoutInfo *)mir_alloc(sizeof(TJabberFormLayoutInfo));
+ layout_info->compact = false;
+ layout_info->ctrlHeight = 20;
+ layout_info->id = 0;
+ layout_info->width = frameRect.right - frameRect.left - 20 - 10;
+ layout_info->y_spacing = 5;
+ layout_info->maxLabelWidth = layout_info->width*2/5;
+ layout_info->offset = 10;
+ layout_info->y_pos = 14;
+ return layout_info;
+}
+
+void JabberFormCreateUI( HWND hwndStatic, HXML xNode, int *formHeight, BOOL bCompact )
+{
+ JabberFormDestroyUI(hwndStatic);
+
+ HXML v, o, vs;
+
+ int i, j, k;
+ const TCHAR* label, *typeName, *varStr, *str, *valueText;
+ TCHAR *labelStr, *valueStr, *p;
+ RECT frameRect;
+
+ if ( xNode==NULL || xmlGetName( xNode )==NULL || lstrcmp( xmlGetName( xNode ), _T("x")) || hwndStatic==NULL ) return;
+
+ GetClientRect( hwndStatic, &frameRect );
+
+ TJabberFormLayoutInfo layout_info;
+ layout_info.compact = bCompact ? true : false;
+ layout_info.ctrlHeight = 20;
+ layout_info.id = 0;
+ layout_info.width = frameRect.right - frameRect.left - 20;
+ if (!bCompact) layout_info.width -= 10;
+ layout_info.y_spacing = bCompact ? 1 : 5;
+ layout_info.maxLabelWidth = layout_info.width*2/5;
+ layout_info.offset = 10;
+ layout_info.y_pos = bCompact ? 0 : 14;
+ for ( i=0; ; i++ ) {
+ HXML n = xmlGetChild( xNode ,i);
+ if ( !n )
+ break;
+
+ if ( xmlGetName( n )) {
+ if ( !lstrcmp( xmlGetName( n ), _T("field"))) {
+ varStr = xmlGetAttrValue( n, _T("var"));
+ if (( typeName = xmlGetAttrValue( n, _T("type"))) != NULL ) {
+ if (( label = xmlGetAttrValue( n, _T("label"))) != NULL )
+ labelStr = mir_tstrdup( label );
+ else
+ labelStr = mir_tstrdup( varStr );
+
+ TJabberFormControlType type = JabberFormTypeNameToId(typeName);
+
+ if (( v = xmlGetChild( n , "value" )) != NULL )
+ {
+ valueText = xmlGetText( v );
+ if (type != JFORM_CTYPE_TEXT_MULTI)
+ {
+ valueStr = mir_tstrdup( valueText );
+ } else
+ {
+ size_t size = 1;
+ for ( j=0; ; j++ ) {
+ v = xmlGetChild( n ,j);
+ if ( !v )
+ break;
+ if ( xmlGetName( v ) && !lstrcmp( xmlGetName( v ), _T("value")) && xmlGetText( v ))
+ size += _tcslen( xmlGetText( v )) + 2;
+ }
+ valueStr = ( TCHAR* )mir_alloc( sizeof(TCHAR)*size );
+ valueStr[0] = '\0';
+ for ( j=0; ; j++ ) {
+ v = xmlGetChild( n ,j);
+ if ( !v )
+ break;
+ if ( xmlGetName( v ) && !lstrcmp( xmlGetName( v ), _T("value")) && xmlGetText( v )) {
+ if ( valueStr[0] )
+ _tcscat( valueStr, _T("\r\n"));
+ _tcscat( valueStr, xmlGetText( v ));
+ } }
+ }
+ } else
+ {
+ valueText = valueStr = NULL;
+ }
+
+ TJabberFormControlInfo *item = JabberFormAppendControl(hwndStatic, &layout_info, type, labelStr, valueStr);
+
+ mir_free( labelStr );
+ mir_free( valueStr );
+
+ if (type == JFORM_CTYPE_LIST_SINGLE)
+ {
+ for ( j=0; ; j++ ) {
+ o = xmlGetChild( n ,j);
+ if ( !o )
+ break;
+ if ( xmlGetName( o ) && !lstrcmp( xmlGetName( o ), _T("option"))) {
+ if (( v = xmlGetChild( o , "value" )) != NULL && xmlGetText( v )) {
+ if (( str = xmlGetAttrValue( o, _T("label"))) == NULL )
+ str = xmlGetText( v );
+ if (( p = mir_tstrdup( str )) != NULL ) {
+ bool selected = false;
+ if ( valueText != NULL && !_tcscmp( valueText, xmlGetText( v )))
+ selected = true;
+ JabberFormAddListItem(item, p, selected);
+ mir_free( p );
+ } } } }
+ } else
+ if (type == JFORM_CTYPE_LIST_MULTI)
+ {
+ for ( j=0; ; j++ ) {
+ o = xmlGetChild( n ,j);
+ if ( !o )
+ break;
+ if ( xmlGetName( o ) && !lstrcmp( xmlGetName( o ), _T("option"))) {
+ if (( v = xmlGetChild( o , "value" )) != NULL && xmlGetText( v )) {
+ if (( str = xmlGetAttrValue( o, _T("label"))) == NULL )
+ str = xmlGetText( v );
+ if (( p = mir_tstrdup( str )) != NULL ) {
+ bool selected = false;
+ for ( k=0; ; k++ ) {
+ vs = xmlGetChild( n ,k);
+ if ( !vs )
+ break;
+ if ( !lstrcmp( xmlGetName( vs ), _T("value")) && xmlGetText( vs ) && !_tcscmp( xmlGetText( vs ), xmlGetText( v )))
+ {
+ selected = true;
+ break;
+ }
+ }
+ JabberFormAddListItem( item, p, selected );
+ mir_free( p );
+ } } } } } } } } }
+
+ JabberFormLayoutControls(hwndStatic, &layout_info, formHeight);
+}
+
+void JabberFormDestroyUI(HWND hwndStatic)
+{
+ TJabberFormControlList *controls = (TJabberFormControlList *)GetWindowLongPtr(hwndStatic, GWLP_USERDATA);
+ if (controls)
+ {
+ for ( int i = 0; i < controls->getCount(); i++ )
+ mir_free((*controls)[i]);
+ controls->destroy();
+ delete controls;
+ SetWindowLongPtr(hwndStatic, GWLP_USERDATA, 0);
+ }
+}
+
+HXML JabberFormGetData( HWND hwndStatic, HXML xNode )
+{
+ HWND hFrame, hCtrl;
+ HXML n, v, o;
+ int id, j, k, len;
+ const TCHAR *varName, *type, *fieldStr, *labelText, *str2;
+ TCHAR *p, *q, *str;
+
+ if ( xNode == NULL || xmlGetName( xNode ) == NULL || lstrcmp( xmlGetName( xNode ), _T("x")) || hwndStatic == NULL )
+ return NULL;
+
+ hFrame = hwndStatic;
+ id = 0;
+ XmlNode x( _T("x"));
+ x << XATTR( _T("xmlns"), _T(JABBER_FEAT_DATA_FORMS)) << XATTR( _T("type"), _T("submit"));
+
+ for ( int i=0; ; i++ ) {
+ n = xmlGetChild( xNode ,i);
+ if ( !n )
+ break;
+
+ fieldStr = NULL;
+ if ( lstrcmp( xmlGetName( n ), _T("field")))
+ continue;
+
+ if (( varName = xmlGetAttrValue( n, _T("var"))) == NULL || ( type = xmlGetAttrValue( n, _T("type"))) == NULL )
+ continue;
+
+ hCtrl = GetDlgItem( hFrame, id );
+ HXML field = x << XCHILD( _T("field")) << XATTR( _T("var"), varName );
+
+ if ( !_tcscmp( type, _T("text-multi")) || !_tcscmp( type, _T("jid-multi"))) {
+ len = GetWindowTextLength( GetDlgItem( hFrame, id ));
+ str = ( TCHAR* )mir_alloc( sizeof(TCHAR)*( len+1 ));
+ GetDlgItemText( hFrame, id, str, len+1 );
+ p = str;
+ while ( p != NULL ) {
+ if (( q = _tcsstr( p, _T("\r\n"))) != NULL )
+ *q = '\0';
+ field << XCHILD( _T("value"), p );
+ p = q ? q+2 : NULL;
+ }
+ mir_free( str );
+ id++;
+ }
+ else if ( !_tcscmp( type, _T("boolean"))) {
+ TCHAR buf[ 10 ];
+ _itot( IsDlgButtonChecked( hFrame, id ) == BST_CHECKED ? 1 : 0, buf, 10 );
+ field << XCHILD( _T("value"), buf );
+ id++;
+ }
+ else if ( !_tcscmp( type, _T("list-single"))) {
+ len = GetWindowTextLength( GetDlgItem( hFrame, id ));
+ str = ( TCHAR* )mir_alloc( sizeof( TCHAR )*( len+1 ));
+ GetDlgItemText( hFrame, id, str, len+1 );
+ v = NULL;
+ for ( j=0; ; j++ ) {
+ o = xmlGetChild( n ,j);
+ if ( !o )
+ break;
+
+ if ( !lstrcmp( xmlGetName( o ), _T("option"))) {
+ if (( v = xmlGetChild( o , "value" )) != NULL && xmlGetText( v )) {
+ if (( str2 = xmlGetAttrValue( o, _T("label"))) == NULL )
+ str2 = xmlGetText( v );
+ if ( !lstrcmp( str2, str ))
+ break;
+ } } }
+
+ if ( o )
+ field << XCHILD( _T("value"), xmlGetText( v ));
+
+ mir_free( str );
+ id++;
+ }
+ else if ( !_tcscmp( type, _T("list-multi"))) {
+ int count = SendMessage( hCtrl, LB_GETCOUNT, 0, 0 );
+ for ( j=0; j<count; j++ ) {
+ if ( SendMessage( hCtrl, LB_GETSEL, j, 0 ) > 0 ) {
+ // an entry is selected
+ len = SendMessage( hCtrl, LB_GETTEXTLEN, j, 0 );
+ if (( str = ( TCHAR* )mir_alloc(( len+1 )*sizeof( TCHAR ))) != NULL ) {
+ SendMessage( hCtrl, LB_GETTEXT, j, ( LPARAM )str );
+ for ( k=0; ; k++ ) {
+ o = xmlGetChild( n ,k);
+ if ( !o )
+ break;
+
+ if ( xmlGetName( o ) && !lstrcmp( xmlGetName( o ), _T("option"))) {
+ if (( v = xmlGetChild( o , "value" )) != NULL && xmlGetText( v )) {
+ if (( labelText = xmlGetAttrValue( o, _T("label"))) == NULL )
+ labelText = xmlGetText( v );
+
+ if ( !lstrcmp( labelText, str ))
+ field << XCHILD( _T("value"), xmlGetText( v ));
+ } } }
+ mir_free( str );
+ } } }
+ id++;
+ }
+ else if ( !_tcscmp( type, _T("fixed")) || !_tcscmp( type, _T("hidden"))) {
+ v = xmlGetChild( n , "value" );
+ if ( v != NULL && xmlGetText( v ) != NULL )
+ field << XCHILD( _T("value"), xmlGetText( v ));
+ }
+ else { // everything else is considered "text-single" or "text-private"
+ len = GetWindowTextLength( GetDlgItem( hFrame, id ));
+ str = ( TCHAR* )mir_alloc( sizeof(TCHAR)*( len+1 ));
+ GetDlgItemText( hFrame, id, str, len+1 );
+ field << XCHILD( _T("value"), str );
+ mir_free( str );
+ id++;
+ } }
+
+ return xi.copyNode( x );
+}
+
+struct JABBER_FORM_INFO
+{
+ ~JABBER_FORM_INFO();
+
+ CJabberProto* ppro;
+ HXML xNode;
+ TCHAR defTitle[128]; // Default title if no <title/> in xNode
+ RECT frameRect; // Clipping region of the frame to scroll
+ int frameHeight; // Height of the frame ( can be eliminated, redundant to frameRect )
+ int formHeight; // Actual height of the form
+ int curPos; // Current scroll position
+ JABBER_FORM_SUBMIT_FUNC pfnSubmit;
+ void *userdata;
+};
+
+static INT_PTR CALLBACK JabberFormDlgProc( HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam )
+{
+ JABBER_FORM_INFO *jfi;
+
+ switch ( msg ) {
+ case WM_INITDIALOG:
+ {
+ HXML n;
+ LONG frameExStyle;
+
+ // lParam is ( JABBER_FORM_INFO * )
+ TranslateDialogDefault( hwndDlg );
+ ShowWindow( GetDlgItem( hwndDlg, IDC_FRAME_TEXT ), SW_HIDE );
+ jfi = ( JABBER_FORM_INFO * ) lParam;
+ if ( jfi != NULL ) {
+ // Set dialog title
+ if ( jfi->xNode!=NULL && ( n = xmlGetChild( jfi->xNode , "title" )) != NULL && xmlGetText( n ) != NULL )
+ SetWindowText( hwndDlg, xmlGetText( n ));
+ else if ( jfi->defTitle != NULL )
+ SetWindowText( hwndDlg, TranslateTS( jfi->defTitle ));
+ // Set instruction field
+ if ( jfi->xNode!=NULL && ( n = xmlGetChild( jfi->xNode , "instructions" )) != NULL && xmlGetText( n ) != NULL )
+ JabberFormSetInstruction( hwndDlg, xmlGetText( n ));
+ else
+ {
+ if ( jfi->xNode != NULL && ( n = xmlGetChild( jfi->xNode , "title" )) != NULL && xmlGetText( n ) != NULL )
+ JabberFormSetInstruction( hwndDlg, xmlGetText( n ));
+ else if ( jfi->defTitle != NULL )
+ JabberFormSetInstruction( hwndDlg, TranslateTS( jfi->defTitle ));
+ }
+
+ // Create form
+ if ( jfi->xNode != NULL ) {
+ RECT rect;
+
+ GetClientRect( GetDlgItem( hwndDlg, IDC_FRAME ), &( jfi->frameRect ));
+ GetClientRect( GetDlgItem( hwndDlg, IDC_VSCROLL ), &rect );
+ jfi->frameRect.right -= ( rect.right - rect.left );
+ GetClientRect( GetDlgItem( hwndDlg, IDC_FRAME ), &rect );
+ jfi->frameHeight = rect.bottom - rect.top;
+ JabberFormCreateUI( GetDlgItem( hwndDlg, IDC_FRAME ), jfi->xNode, &( jfi->formHeight ));
+ }
+ }
+
+ if ( jfi->formHeight > jfi->frameHeight ) {
+ HWND hwndScroll;
+
+ hwndScroll = GetDlgItem( hwndDlg, IDC_VSCROLL );
+ EnableWindow( hwndScroll, TRUE );
+ SetScrollRange( hwndScroll, SB_CTL, 0, jfi->formHeight - jfi->frameHeight, FALSE );
+ jfi->curPos = 0;
+ }
+
+ // Enable WS_EX_CONTROLPARENT on IDC_FRAME ( so tab stop goes through all its children )
+ frameExStyle = GetWindowLongPtr( GetDlgItem( hwndDlg, IDC_FRAME ), GWL_EXSTYLE );
+ frameExStyle |= WS_EX_CONTROLPARENT;
+ SetWindowLongPtr( GetDlgItem( hwndDlg, IDC_FRAME ), GWL_EXSTYLE, frameExStyle );
+
+ SetWindowLongPtr( hwndDlg, GWLP_USERDATA, ( LONG_PTR ) jfi );
+ if ( jfi->pfnSubmit != NULL )
+ EnableWindow( GetDlgItem( hwndDlg, IDC_SUBMIT ), TRUE );
+ }
+ return TRUE;
+
+ case WM_CTLCOLORSTATIC:
+ if ((GetWindowLongPtr((HWND)lParam, GWL_ID) == IDC_WHITERECT) ||
+ (GetWindowLongPtr((HWND)lParam, GWL_ID) == IDC_INSTRUCTION) ||
+ (GetWindowLongPtr((HWND)lParam, GWL_ID) == IDC_TITLE))
+ {
+ return (INT_PTR)GetStockObject(WHITE_BRUSH);
+ }
+
+ return NULL;
+
+ case WM_MOUSEWHEEL:
+ {
+ int zDelta = GET_WHEEL_DELTA_WPARAM( wParam );
+ if ( zDelta ) {
+ int nScrollLines=0;
+ SystemParametersInfo( SPI_GETWHEELSCROLLLINES, 0, (void*)&nScrollLines, 0 );
+ for (int i = 0; i < ( nScrollLines + 1 ) / 2; i++ )
+ SendMessage( hwndDlg, WM_VSCROLL, ( zDelta < 0 ) ? SB_LINEDOWN : SB_LINEUP, 0 );
+ }
+ }
+ break;
+
+ case WM_VSCROLL:
+ jfi = ( JABBER_FORM_INFO * ) GetWindowLongPtr( hwndDlg, GWLP_USERDATA );
+ if ( jfi != NULL ) {
+ int pos = jfi->curPos;
+ switch ( LOWORD( wParam )) {
+ case SB_LINEDOWN:
+ pos += 15;
+ break;
+ case SB_LINEUP:
+ pos -= 15;
+ break;
+ case SB_PAGEDOWN:
+ pos += ( jfi->frameHeight - 10 );
+ break;
+ case SB_PAGEUP:
+ pos -= ( jfi->frameHeight - 10 );
+ break;
+ case SB_THUMBTRACK:
+ pos = HIWORD( wParam );
+ break;
+ }
+ if ( pos > ( jfi->formHeight - jfi->frameHeight ))
+ pos = jfi->formHeight - jfi->frameHeight;
+ if ( pos < 0 )
+ pos = 0;
+ if ( jfi->curPos != pos ) {
+ ScrollWindow( GetDlgItem( hwndDlg, IDC_FRAME ), 0, jfi->curPos - pos, NULL, &( jfi->frameRect ));
+ SetScrollPos( GetDlgItem( hwndDlg, IDC_VSCROLL ), SB_CTL, pos, TRUE );
+ jfi->curPos = pos;
+ }
+ }
+ break;
+
+ case WM_COMMAND:
+ switch ( LOWORD( wParam )) {
+ case IDC_SUBMIT:
+ jfi = ( JABBER_FORM_INFO * ) GetWindowLongPtr( hwndDlg, GWLP_USERDATA );
+ if ( jfi != NULL ) {
+ HXML n = JabberFormGetData( GetDlgItem( hwndDlg, IDC_FRAME ), jfi->xNode );
+ ( jfi->ppro->*(jfi->pfnSubmit))( n, jfi->userdata );
+ xi.destroyNode( n );
+ }
+ // fall through
+ case IDCANCEL:
+ case IDCLOSE:
+ DestroyWindow( hwndDlg );
+ return TRUE;
+ }
+ break;
+
+ case WM_CLOSE:
+ DestroyWindow( hwndDlg );
+ break;
+
+ case WM_DESTROY:
+ JabberFormDestroyUI( GetDlgItem( hwndDlg, IDC_FRAME ));
+ jfi = ( JABBER_FORM_INFO * ) GetWindowLongPtr( hwndDlg, GWLP_USERDATA );
+ delete jfi;
+ break;
+ }
+
+ return FALSE;
+}
+
+static VOID CALLBACK JabberFormCreateDialogApcProc( void* param )
+{
+ CreateDialogParam( hInst, MAKEINTRESOURCE( IDD_FORM ), NULL, JabberFormDlgProc, ( LPARAM )param );
+}
+
+void CJabberProto::FormCreateDialog( HXML xNode, TCHAR* defTitle, JABBER_FORM_SUBMIT_FUNC pfnSubmit, void *userdata )
+{
+ JABBER_FORM_INFO *jfi = new JABBER_FORM_INFO;
+ memset( jfi, 0, sizeof( JABBER_FORM_INFO ));
+ jfi->ppro = this;
+ jfi->xNode = xi.copyNode( xNode );
+ if ( defTitle )
+ _tcsncpy( jfi->defTitle, defTitle, SIZEOF( jfi->defTitle ));
+ jfi->pfnSubmit = pfnSubmit;
+ jfi->userdata = userdata;
+
+ CallFunctionAsync( JabberFormCreateDialogApcProc, jfi );
+}
+
+//=======================================================================================
+
+JABBER_FORM_INFO::~JABBER_FORM_INFO()
+{
+ xi.destroyNode( xNode );
+ mir_free( userdata );
+} \ No newline at end of file