summaryrefslogtreecommitdiff
path: root/utils/mir_options.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'utils/mir_options.cpp')
-rw-r--r--utils/mir_options.cpp447
1 files changed, 447 insertions, 0 deletions
diff --git a/utils/mir_options.cpp b/utils/mir_options.cpp
new file mode 100644
index 0000000000..acf9ff9531
--- /dev/null
+++ b/utils/mir_options.cpp
@@ -0,0 +1,447 @@
+/*
+Copyright (C) 2005-2009 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+#include <windows.h>
+#include <commctrl.h>
+#include <stdio.h>
+#include <tchar.h>
+
+#include <newpluginapi.h>
+#include <m_database.h>
+#include <m_utils.h>
+#include <m_langpack.h>
+#include <m_protocols.h>
+#include <m_protosvc.h>
+#include <m_system.h>
+
+#include "mir_options.h"
+
+static TCHAR* MyDBGetContactSettingTString(MCONTACT hContact, char* module, char* setting, TCHAR* out, size_t len, TCHAR *def)
+{
+ DBVARIANT dbv = { 0 };
+
+ out[0] = _T('\0');
+
+ if (!db_get_ts(hContact, module, setting, &dbv)) {
+ mir_tstrncpy(out, dbv.ptszVal, (int)len);
+ db_free(&dbv);
+ }
+ else {
+ if (def != NULL)
+ mir_tstrncpy(out, def, (int)len);
+ }
+
+ return out;
+}
+
+
+static TCHAR dbPath[MAX_PATH] = { 0 }; // database profile path (read at startup only)
+
+
+static int PathIsAbsolute(const TCHAR *path)
+{
+ if (!path || !(mir_tstrlen(path) > 2))
+ return 0;
+ if ((path[1] == _T(':') && path[2] == _T('\\')) || (path[0] == _T('\\') && path[1] == _T('\\')))
+ return 1;
+ return 0;
+}
+
+static void PathToRelative(TCHAR *pOut, size_t outSize, const TCHAR *pSrc)
+{
+ if (!PathIsAbsolute(pSrc))
+ mir_tstrncpy(pOut, pSrc, (int)outSize);
+ else {
+ if (dbPath[0] == _T('\0')) {
+ char tmp[1024];
+ CallService(MS_DB_GETPROFILEPATH, _countof(tmp), (LPARAM)tmp);
+ mir_sntprintf(dbPath, _T("%S\\"), tmp);
+ }
+
+ size_t len = mir_tstrlen(dbPath);
+ if (!_tcsnicmp(pSrc, dbPath, len))
+ len = 0;
+ mir_tstrncpy(pOut, pSrc + len, outSize);
+ }
+}
+
+static void PathToAbsolute(TCHAR *pOut, size_t outSize, const TCHAR *pSrc)
+{
+ if (PathIsAbsolute(pSrc) || !isalnum(pSrc[0]))
+ mir_tstrncpy(pOut, pSrc, (int)outSize);
+ else {
+ if (dbPath[0] == _T('\0')) {
+ char tmp[1024];
+ CallService(MS_DB_GETPROFILEPATH, _countof(tmp), (LPARAM)tmp);
+ mir_sntprintf(dbPath, _T("%S\\"), tmp);
+ }
+
+ mir_sntprintf(pOut, outSize, _T("%s%s"), dbPath, pSrc);
+ }
+}
+
+static void LoadOpt(OptPageControl *ctrl, char *module)
+{
+ if (ctrl->var == NULL)
+ return;
+
+ TCHAR tmp[1024];
+ switch (ctrl->type) {
+ case CONTROL_CHECKBOX:
+ *((BYTE *)ctrl->var) = db_get_b(NULL, module, ctrl->setting, ctrl->dwDefValue);
+ break;
+
+ case CONTROL_SPIN:
+ *((WORD *)ctrl->var) = db_get_w(NULL, module, ctrl->setting, ctrl->dwDefValue);
+ break;
+
+ case CONTROL_COLOR:
+ *((COLORREF *)ctrl->var) = (COLORREF)db_get_dw(NULL, module, ctrl->setting, ctrl->dwDefValue);
+ break;
+
+ case CONTROL_RADIO:
+ *((WORD *)ctrl->var) = db_get_w(NULL, module, ctrl->setting, ctrl->dwDefValue);
+ break;
+
+ case CONTROL_COMBO:
+ *((WORD *)ctrl->var) = db_get_w(NULL, module, ctrl->setting, ctrl->dwDefValue);
+ break;
+
+ case CONTROL_PROTOCOL_LIST:
+ break;
+
+ case CONTROL_TEXT:
+ MyDBGetContactSettingTString(NULL, module, ctrl->setting, ((TCHAR *)ctrl->var), min(ctrl->max <= 0 ? 1024 : ctrl->max, 1024), ctrl->tszDefValue == NULL ? NULL : TranslateTS(ctrl->tszDefValue));
+ break;
+
+ case CONTROL_INT:
+ *((int *)ctrl->var) = (int)db_get_dw(NULL, module, ctrl->setting, ctrl->dwDefValue);
+ break;
+
+ case CONTROL_FILE:
+ MyDBGetContactSettingTString(NULL, module, ctrl->setting, tmp, 1024, ctrl->tszDefValue == NULL ? NULL : ctrl->tszDefValue);
+ PathToAbsolute(((TCHAR *)ctrl->var), min(ctrl->max <= 0 ? 1024 : ctrl->max, 1024), tmp);
+ break;
+
+ case CONTROL_COMBO_TEXT:
+ case CONTROL_COMBO_ITEMDATA:
+ MyDBGetContactSettingTString(NULL, module, ctrl->setting, ((TCHAR *)ctrl->var), min(ctrl->max <= 0 ? 1024 : ctrl->max, 1024), ctrl->tszDefValue == NULL ? NULL : TranslateTS(ctrl->tszDefValue));
+ break;
+ }
+}
+
+void LoadOpts(OptPageControl *controls, int controlsSize, char *module)
+{
+ for (int i = 0; i < controlsSize; i++)
+ LoadOpt(&controls[i], module);
+}
+
+INT_PTR CALLBACK SaveOptsDlgProc(OptPageControl *controls, int controlsSize, char *module, HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ TCHAR tmp[1024];
+
+ switch (msg) {
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hwndDlg);
+
+ for (int i = 0; i < controlsSize; i++) {
+ OptPageControl *ctrl = &controls[i];
+
+ if (GetDlgItem(hwndDlg, ctrl->nID) == NULL)
+ continue;
+
+ switch (ctrl->type) {
+ case CONTROL_CHECKBOX:
+ CheckDlgButton(hwndDlg, ctrl->nID, db_get_b(NULL, module, ctrl->setting, ctrl->dwDefValue) == 1 ? BST_CHECKED : BST_UNCHECKED);
+ break;
+
+ case CONTROL_SPIN:
+ SendDlgItemMessage(hwndDlg, ctrl->nIDSpin, UDM_SETBUDDY, (WPARAM)GetDlgItem(hwndDlg, ctrl->nID), 0);
+ SendDlgItemMessage(hwndDlg, ctrl->nIDSpin, UDM_SETRANGE, 0, MAKELONG(ctrl->max, ctrl->min));
+ SendDlgItemMessage(hwndDlg, ctrl->nIDSpin, UDM_SETPOS, 0, MAKELONG(db_get_w(NULL, module, ctrl->setting, ctrl->dwDefValue), 0));
+ break;
+
+ case CONTROL_COLOR:
+ SendDlgItemMessage(hwndDlg, ctrl->nID, CPM_SETCOLOUR, 0, (COLORREF)db_get_dw(NULL, module, ctrl->setting, ctrl->dwDefValue));
+ break;
+
+ case CONTROL_RADIO:
+ CheckDlgButton(hwndDlg, ctrl->nID, db_get_w(NULL, module, ctrl->setting, ctrl->dwDefValue) == ctrl->value ? BST_CHECKED : BST_UNCHECKED);
+ break;
+
+ case CONTROL_COMBO:
+ SendDlgItemMessage(hwndDlg, ctrl->nID, CB_SETCURSEL, db_get_w(NULL, module, ctrl->setting, ctrl->dwDefValue), 0);
+ break;
+
+ case CONTROL_PROTOCOL_LIST:
+ {
+ // Fill list view
+ HWND hwndProtocols = GetDlgItem(hwndDlg, ctrl->nID);
+ LVCOLUMN lvc;
+ LVITEM lvi;
+
+ ListView_SetExtendedListViewStyle(hwndProtocols, LVS_EX_CHECKBOXES);
+
+ memset(&lvc, 0, sizeof(lvc));
+ lvc.mask = LVCF_FMT;
+ lvc.fmt = LVCFMT_IMAGE | LVCFMT_LEFT;
+ ListView_InsertColumn(hwndProtocols, 0, &lvc);
+
+ memset(&lvi, 0, sizeof(lvi));
+ lvi.mask = LVIF_TEXT | LVIF_PARAM;
+ lvi.iSubItem = 0;
+ lvi.iItem = 1000;
+
+ int count;
+ PROTOACCOUNT **protos;
+ Proto_EnumAccounts(&count, &protos);
+
+ for (int k = 0; k < count; k++) {
+ PROTOACCOUNT *p = protos[k];
+ if (p->szModuleName == NULL || p->szModuleName[0] == '\0')
+ continue;
+
+ if (ctrl->allowProtocol != NULL && !ctrl->allowProtocol(p->szModuleName))
+ continue;
+
+ char *setting = (char *)mir_alloc(128 * sizeof(char));
+ mir_snprintf(setting, 128, ctrl->setting, p->szModuleName);
+
+ BOOL show = (BOOL)db_get_b(NULL, module, setting, ctrl->dwDefValue);
+
+ lvi.lParam = (LPARAM)setting;
+ lvi.pszText = p->tszAccountName;
+ lvi.iItem = ListView_InsertItem(hwndProtocols, &lvi);
+ ListView_SetItemState(hwndProtocols, lvi.iItem, INDEXTOSTATEIMAGEMASK(show ? 2 : 1), LVIS_STATEIMAGEMASK);
+ }
+
+ ListView_SetColumnWidth(hwndProtocols, 0, LVSCW_AUTOSIZE);
+ ListView_Arrange(hwndProtocols, LVA_ALIGNLEFT | LVA_ALIGNTOP);
+ }
+ break;
+
+ case CONTROL_TEXT:
+ SetDlgItemText(hwndDlg, ctrl->nID, MyDBGetContactSettingTString(NULL, module, ctrl->setting, tmp, 1024, ctrl->tszDefValue == NULL ? NULL : TranslateTS(ctrl->tszDefValue)));
+ SendDlgItemMessage(hwndDlg, ctrl->nID, EM_LIMITTEXT, min(ctrl->max <= 0 ? 1024 : ctrl->max, 1024), 0);
+ break;
+
+ case CONTROL_INT:
+ SetDlgItemInt(hwndDlg, ctrl->nID, db_get_dw(NULL, module, ctrl->setting, ctrl->dwDefValue), ctrl->min <= 0);
+ SendDlgItemMessage(hwndDlg, ctrl->nID, EM_LIMITTEXT, 9, 0);
+ break;
+
+ case CONTROL_FILE:
+ MyDBGetContactSettingTString(NULL, module, ctrl->setting, tmp, 1024, ctrl->tszDefValue == NULL ? NULL : ctrl->tszDefValue);
+ {
+ TCHAR abs[1024];
+ PathToAbsolute(abs, 1024, tmp);
+ SetDlgItemText(hwndDlg, ctrl->nID, abs);
+ }
+ SendDlgItemMessage(hwndDlg, ctrl->nID, EM_LIMITTEXT, min(ctrl->max <= 0 ? 1024 : ctrl->max, 1024), 0);
+ break;
+
+ case CONTROL_COMBO_TEXT:
+ MyDBGetContactSettingTString(NULL, module, ctrl->setting, tmp, 1024, ctrl->tszDefValue == NULL ? NULL : TranslateTS(ctrl->tszDefValue));
+ SendDlgItemMessage(hwndDlg, ctrl->nID, CB_SELECTSTRING, 0, (WPARAM)tmp);
+ break;
+
+ case CONTROL_COMBO_ITEMDATA:
+ MyDBGetContactSettingTString(NULL, module, ctrl->setting, tmp, 1024, ctrl->tszDefValue == NULL ? NULL : TranslateTS(ctrl->tszDefValue));
+ {
+ int count = SendDlgItemMessage(hwndDlg, ctrl->nID, CB_GETCOUNT, 0, 0);
+ int k;
+ for (k = 0; k < count; k++) {
+ TCHAR *id = (TCHAR *)SendDlgItemMessage(hwndDlg, ctrl->nID, CB_GETITEMDATA, (WPARAM)k, 0);
+ if (mir_tstrcmp(id, tmp) == 0)
+ break;
+ }
+ if (k < count)
+ SendDlgItemMessage(hwndDlg, ctrl->nID, CB_SETCURSEL, k, 0);
+ }
+ break;
+ }
+ }
+ break;
+
+ case WM_COMMAND:
+ for (int i = 0; i < controlsSize; i++) {
+ OptPageControl *ctrl = &controls[i];
+
+ if (LOWORD(wParam) == ctrl->nID) {
+ switch (ctrl->type) {
+ case CONTROL_TEXT:
+ case CONTROL_SPIN:
+ case CONTROL_INT:
+ // Don't make apply enabled during buddy set
+ if (HIWORD(wParam) != EN_CHANGE || (HWND)lParam != GetFocus())
+ return 0;
+
+ break;
+
+ case CONTROL_COMBO_ITEMDATA:
+ case CONTROL_COMBO_TEXT:
+ case CONTROL_COMBO:
+ if (HIWORD(wParam) != CBN_SELCHANGE || (HWND)lParam != GetFocus())
+ return 0;
+ break;
+ }
+
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ }
+ }
+ break;
+
+ case WM_NOTIFY:
+ {
+ LPNMHDR lpnmhdr = (LPNMHDR)lParam;
+ if (lpnmhdr->idFrom == 0 && lpnmhdr->code == PSN_APPLY) {
+ for (int i = 0; i < controlsSize; i++) {
+ OptPageControl *ctrl = &controls[i];
+
+ if (GetDlgItem(hwndDlg, ctrl->nID) == NULL)
+ continue;
+
+ switch (ctrl->type) {
+ case CONTROL_CHECKBOX:
+ db_set_b(NULL, module, ctrl->setting, (BYTE)IsDlgButtonChecked(hwndDlg, ctrl->nID));
+ break;
+
+ case CONTROL_SPIN:
+ db_set_w(NULL, module, ctrl->setting, (WORD)SendDlgItemMessage(hwndDlg, ctrl->nIDSpin, UDM_GETPOS, 0, 0));
+ break;
+
+ case CONTROL_COLOR:
+ db_set_dw(NULL, module, ctrl->setting, (DWORD)SendDlgItemMessage(hwndDlg, ctrl->nID, CPM_GETCOLOUR, 0, 0));
+ break;
+
+ case CONTROL_RADIO:
+ if (IsDlgButtonChecked(hwndDlg, ctrl->nID))
+ db_set_w(NULL, module, ctrl->setting, (BYTE)ctrl->value);
+ break;
+
+ case CONTROL_COMBO:
+ db_set_w(NULL, module, ctrl->setting, (WORD)SendDlgItemMessage(hwndDlg, ctrl->nID, CB_GETCURSEL, 0, 0));
+ break;
+
+ case CONTROL_PROTOCOL_LIST:
+ {
+ LVITEM lvi = { 0 };
+ lvi.mask = (UINT)LVIF_PARAM;
+
+ HWND hwndProtocols = GetDlgItem(hwndDlg, ctrl->nID);
+ int count = ListView_GetItemCount(hwndProtocols);
+ for (int k = 0; k < count; k++) {
+ lvi.iItem = k;
+ ListView_GetItem(hwndProtocols, &lvi);
+
+ char *setting = (char *)lvi.lParam;
+ db_set_b(NULL, module, setting, (BYTE)ListView_GetCheckState(hwndProtocols, k));
+ }
+ }
+ break;
+
+ case CONTROL_TEXT:
+ GetDlgItemText(hwndDlg, ctrl->nID, tmp, _countof(tmp));
+ db_set_ts(NULL, module, ctrl->setting, tmp);
+ break;
+
+ case CONTROL_INT:
+ BOOL trans;
+ {
+ int val = GetDlgItemInt(hwndDlg, ctrl->nID, &trans, ctrl->min <= 0);
+ if (!trans)
+ val = ctrl->dwDefValue;
+ if (ctrl->max != 0)
+ val = min(val, ctrl->max);
+ if (ctrl->min != 0)
+ val = max(val, ctrl->min);
+ db_set_dw(NULL, module, ctrl->setting, val);
+ }
+ break;
+
+ case CONTROL_FILE:
+ GetDlgItemText(hwndDlg, ctrl->nID, tmp, _countof(tmp));
+ {
+ TCHAR rel[1024];
+ PathToRelative(rel, 1024, tmp);
+ db_set_ts(NULL, module, ctrl->setting, rel);
+ }
+ break;
+
+ case CONTROL_COMBO_TEXT:
+ GetDlgItemText(hwndDlg, ctrl->nID, tmp, _countof(tmp));
+ db_set_ts(NULL, module, ctrl->setting, tmp);
+ break;
+
+ case CONTROL_COMBO_ITEMDATA:
+ int sel = SendDlgItemMessage(hwndDlg, ctrl->nID, CB_GETCURSEL, 0, 0);
+ db_set_ts(NULL, module, ctrl->setting, (TCHAR *)SendDlgItemMessage(hwndDlg, ctrl->nID, CB_GETITEMDATA, (WPARAM)sel, 0));
+ break;
+ }
+
+ LoadOpt(ctrl, module);
+ }
+
+ return TRUE;
+ }
+ else if (lpnmhdr->idFrom != 0 && lpnmhdr->code == LVN_ITEMCHANGED) {
+ // Changed for protocols
+ for (int i = 0; i < controlsSize; i++) {
+ OptPageControl *ctrl = &controls[i];
+
+ if (ctrl->type == CONTROL_PROTOCOL_LIST && ctrl->nID == lpnmhdr->idFrom) {
+ NMLISTVIEW *nmlv = (NMLISTVIEW *)lParam;
+
+ if (IsWindowVisible(GetDlgItem(hwndDlg, ctrl->nID)) && ((nmlv->uNewState ^ nmlv->uOldState) & LVIS_STATEIMAGEMASK))
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+
+ break;
+ }
+ }
+ }
+ }
+ break;
+
+ case WM_DESTROY:
+ for (int i = 0; i < controlsSize; i++) {
+ OptPageControl *ctrl = &controls[i];
+
+ if (GetDlgItem(hwndDlg, ctrl->nID) == NULL)
+ continue;
+
+ switch (ctrl->type) {
+ case CONTROL_PROTOCOL_LIST:
+ LVITEM lvi = { 0 };
+ lvi.mask = (UINT)LVIF_PARAM;
+
+ HWND hwndProtocols = GetDlgItem(hwndDlg, ctrl->nID);
+ int count = ListView_GetItemCount(hwndProtocols);
+ for (i = 0; i < count; i++) {
+ lvi.iItem = i;
+ ListView_GetItem(hwndProtocols, &lvi);
+ mir_free((char *)lvi.lParam);
+ }
+ break;
+ }
+ }
+ break;
+ }
+
+ return 0;
+}