summaryrefslogtreecommitdiff
path: root/plugins/ModernOpt/src
diff options
context:
space:
mode:
authorVadim Dashevskiy <watcherhd@gmail.com>2012-07-20 13:13:28 +0000
committerVadim Dashevskiy <watcherhd@gmail.com>2012-07-20 13:13:28 +0000
commit8593e7594773c30b35488bb6a45fcc782ed5df0c (patch)
tree7e1e7b44b5331b419c2843f155d0e04ba6e56635 /plugins/ModernOpt/src
parent1de47a8a191ae6c607972c51ae0289e474e9f52c (diff)
ModernOpt: changed folder structure
git-svn-id: http://svn.miranda-ng.org/main/trunk@1081 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/ModernOpt/src')
-rw-r--r--plugins/ModernOpt/src/commonheaders.h79
-rw-r--r--plugins/ModernOpt/src/main.cpp54
-rw-r--r--plugins/ModernOpt/src/modernopt.cpp696
-rw-r--r--plugins/ModernOpt/src/modernopt.h53
-rw-r--r--plugins/ModernOpt/src/mopt_home.cpp80
-rw-r--r--plugins/ModernOpt/src/mopt_ignore.cpp61
-rw-r--r--plugins/ModernOpt/src/mopt_selector.cpp385
-rw-r--r--plugins/ModernOpt/src/resource.h36
8 files changed, 1444 insertions, 0 deletions
diff --git a/plugins/ModernOpt/src/commonheaders.h b/plugins/ModernOpt/src/commonheaders.h
new file mode 100644
index 0000000000..2d133a802e
--- /dev/null
+++ b/plugins/ModernOpt/src/commonheaders.h
@@ -0,0 +1,79 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2008 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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.
+*/
+
+// to enable all 0.8.0 core functions
+#define MIRANDA_VER 0x0A00
+
+#define WINVER 0x0501
+#define _WIN32_WINNT 0x0501
+#define _WIN32_IE 0x0501
+
+#define _CRT_SECURE_NO_WARNINGS
+#define CINTERFACE
+
+#include "m_stdhdr.h"
+
+#include <windows.h>
+#include <windowsx.h>
+#include <shlobj.h>
+#include <uxtheme.h>
+#include <commctrl.h>
+#include <stdio.h>
+#include <time.h>
+#include <stddef.h>
+#include <process.h>
+#include <io.h>
+#include <string.h>
+#include <locale.h>
+#include <direct.h>
+#include <win2k.h>
+
+#include <newpluginapi.h>
+#include <m_system.h>
+#include <m_system_cpp.h>
+#include <m_database.h>
+#include <m_clc.h>
+#include <m_clui.h>
+#include <m_langpack.h>
+#include <m_clist.h>
+#include <m_clistint.h>
+#include <m_button.h>
+#include <m_protosvc.h>
+#include <m_protomod.h>
+#include <m_protocols.h>
+#include <m_options.h>
+#include <m_skin.h>
+#include <m_contacts.h>
+#include <m_message.h>
+#include <m_userinfo.h>
+#include <m_history.h>
+#include <m_addcontact.h>
+#include <m_findadd.h>
+#include <m_file.h>
+#include <m_email.h>
+#include <m_awaymsg.h>
+#include <m_idle.h>
+#include <m_ignore.h>
+#include <m_icolib.h>
+
+#include "resource.h"
diff --git a/plugins/ModernOpt/src/main.cpp b/plugins/ModernOpt/src/main.cpp
new file mode 100644
index 0000000000..c11f8349f9
--- /dev/null
+++ b/plugins/ModernOpt/src/main.cpp
@@ -0,0 +1,54 @@
+#include "commonheaders.h"
+
+
+HINSTANCE hInst;
+int hLangpack;
+
+PLUGININFOEX pluginInfoEx = {
+ sizeof(PLUGININFOEX),
+ "Support for new options design",
+ PLUGIN_MAKE_VERSION(0,1,0,0),
+ "Support for new options design.",
+ "Victor Pavlychko, George Hazan",
+ "ghazan@miranda-im.org",
+ "é 2009 Victor Pavlychko, George Hazan",
+ "http://www.miranda-im.org",
+ UNICODE_AWARE,
+ { 0x621f886b, 0xa7f6, 0x457f, { 0x9d, 0x62, 0x8e, 0xe8, 0x4c, 0x27, 0x59, 0x93 }} // {621f886b-a7f6-457f-9d62-8ee84c275993}
+};
+
+BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)
+{
+ hInst = hinstDLL;
+ return TRUE;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// MirandaPluginInfoEx - returns an information about a plugin
+
+extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion)
+{
+ return &pluginInfoEx;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Performs a primary set of actions upon plugin loading
+
+int LoadModernOptsModule();
+
+extern "C" int __declspec(dllexport) Load(void)
+{
+
+ mir_getLP(&pluginInfoEx);
+
+ LoadModernOptsModule();
+ return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Unload a plugin
+
+extern "C" int __declspec(dllexport) Unload(void)
+{
+ return 0;
+}
diff --git a/plugins/ModernOpt/src/modernopt.cpp b/plugins/ModernOpt/src/modernopt.cpp
new file mode 100644
index 0000000000..1345631268
--- /dev/null
+++ b/plugins/ModernOpt/src/modernopt.cpp
@@ -0,0 +1,696 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2007 Artem Shpynov
+Copyright 2000-2007 Miranda ICQ/IM project,
+
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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 "commonheaders.h"
+#include "modernopt.h"
+#include "../../../src/resource.h"
+
+//#define MOPT_SAMPLE_PAGES
+
+extern HMODULE hInst;
+
+static HANDLE hevtModernOpt_Initialize = 0;
+
+static HWND hwndModernOpt = NULL;
+static INT_PTR CALLBACK ModernOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+
+struct ModernOptionsObject
+{
+ MODERNOPTOBJECT optObject;
+
+ HWND hwnd;
+ BOOL bChanged;
+ DWORD dwFlags;
+ int iTreeImageIndex;
+ DWORD dwIdx;
+};
+
+static DWORD g_dwIdx = 0;
+static int g_iSectionRestore = 0;
+
+static int ModernOptionsObject_Comparator(const ModernOptionsObject *ptr1, const ModernOptionsObject *ptr2);
+
+struct ModernOptionsData
+{
+ __inline void* operator new( size_t size )
+ { return calloc( 1, size );
+ }
+ __inline void operator delete( void* p )
+ { free( p );
+ }
+
+ ModernOptionsData(): pObjectList(1, ModernOptionsObject_Comparator) {}
+
+ LIST<ModernOptionsObject> pObjectList;
+ HFONT hfntBold;
+ int iPage, iSection;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// Forwards
+static INT_PTR svcModernOpt_Show(WPARAM wParam, LPARAM lParam);
+static INT_PTR svcModernOpt_Restore(WPARAM wParam, LPARAM lParam);
+static INT_PTR svcModernOpt_SelectPage(WPARAM wParam, LPARAM lParam);
+static INT_PTR svcModernOpt_AddObject(WPARAM wParam, LPARAM lParam);
+static int hookModernOpt_Initialize(WPARAM wParam, LPARAM lParam);
+
+static void ModernOptUI_ShowPage(HWND hwndDlg, struct ModernOptionsData *dat, int iPage);
+static void ModernOptUI_SelectSection(HWND hwndDlg, struct ModernOptionsData *dat, int iSection);
+
+////////////////////////////////////////////////////////////////////////////////
+// Main option pages
+struct ModernOptMainPageInfo g_ModernOptPages[MODERNOPT_PAGE_COUNT] =
+{
+ {0, FALSE, IDI_MIRANDA, _T("Home"), _T("Miranda IM configuration center")},
+ {IDC_BTN_ACCOUNTS, TRUE, IDI_BIG_NETWORK, _T("Accounts"), _T("Setup your account information to start messaging.")},
+ {IDC_BTN_SKINS, TRUE, IDI_BIG_SKINS, _T("Style"), _T("Change the look of Miranda IM according to your taste.")},
+ {IDC_BTN_CLIST, TRUE, IDI_BIG_BUDDYLIST, _T("Contacts"), _T("Configure behaviour of your contact list.")},
+ {IDC_BTN_MESSAGING, TRUE, IDI_BIG_MESSAGE, _T("Chats"), _T("Customize look&&feel of your chat windows here.")},
+ {IDC_BTN_IGNORE, TRUE, IDI_BIG_IGNORE, _T("Ignore"), _T("Ban those users and events, you are annoyed with.")},
+ {IDC_BTN_STATUS, TRUE, IDI_BIG_STATUS, _T("Status"), _T("Set your status messages and idle reporting.")},
+ {IDC_BTN_ADVANCED, TRUE, IDI_BIG_ADVANCED, _T("Advanced"), _T("")},
+ {IDC_BTN_PLUGINS, TRUE, IDI_BIG_MODULES, _T("Addons"), _T("Miranda IM is all about plugins. Manage all the plugins you have here.")},
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// Utilities
+typedef void (*ItemDestuctor)(void *);
+
+static void ModernOptionsObject_Dtor(void *ptr)
+{
+ struct ModernOptionsObject *obj = (struct ModernOptionsObject *)ptr;
+
+ mir_free(obj->optObject.lptzSubsection);
+ mir_free(obj->optObject.iBoldControls);
+ mir_free(obj->optObject.lpzClassicGroup);
+ mir_free(obj->optObject.lpzClassicPage);
+ mir_free(obj->optObject.lpzClassicTab);
+ mir_free(obj->optObject.lpzHelpUrl);
+ mir_free(obj->optObject.lpzThemeExtension);
+ mir_free(obj->optObject.lpzThemeModuleName);
+
+ switch (obj->optObject.iType)
+ {
+ case MODERNOPT_TYPE_IGNOREOBJECT:
+ mir_free(obj->optObject.lpzIgnoreModule);
+ mir_free(obj->optObject.lpzIgnoreSetting);
+ break;
+ }
+
+ if (obj->hwnd) DestroyWindow(obj->hwnd);
+ mir_free(obj);
+}
+
+static int ModernOptionsObject_Comparator(const ModernOptionsObject *ptr1, const ModernOptionsObject *ptr2)
+{
+#define obj1 ((struct ModernOptionsObject *)ptr1)
+#define obj2 ((struct ModernOptionsObject *)ptr2)
+
+ if (obj1->optObject.iSection < obj2->optObject.iSection) return -1;
+ if (obj1->optObject.iSection > obj2->optObject.iSection) return +1;
+
+ if (obj1->optObject.iType < obj2->optObject.iType) return -1;
+ if (obj1->optObject.iType > obj2->optObject.iType) return +1;
+
+ if (obj1->optObject.lptzSubsection && obj2->optObject.lptzSubsection)
+ {
+ int c = lstrcmp(obj1->optObject.lptzSubsection, obj2->optObject.lptzSubsection);
+ if (c) return c;
+ }
+
+ if (obj1->dwIdx < obj2->dwIdx) return -1;
+ if (obj1->dwIdx > obj2->dwIdx) return +1;
+ return 0;
+
+#undef obj1
+#undef obj2
+}
+
+void li_List_Destruct(LIST<ModernOptionsObject> &pList, ItemDestuctor pItemDestructor)
+{
+ int i=0;
+ for (i=0; i<pList.getCount(); i++) pItemDestructor(pList[i]);
+ pList.destroy();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Load module
+int LoadModernOptsModule()
+{
+ CreateServiceFunction(MS_MODERNOPT_SHOW, svcModernOpt_Show);
+ CreateServiceFunction(MS_MODERNOPT_RESTORE, svcModernOpt_Restore);
+ CreateServiceFunction(MS_MODERNOPT_SELECTPAGE, svcModernOpt_SelectPage);
+ CreateServiceFunction(MS_MODERNOPT_ADDOBJECT, svcModernOpt_AddObject);
+ hevtModernOpt_Initialize = CreateHookableEvent(ME_MODERNOPT_INITIALIZE);
+ HookEvent(ME_MODERNOPT_INITIALIZE, hookModernOpt_Initialize);
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Main dlgproc
+static void sttNotifyPages(struct ModernOptionsData *dat, int code)
+{
+ PSHNOTIFY pshn = {0};
+ pshn.hdr.code = code;
+ for (int i = 0; i < dat->pObjectList.getCount(); ++i)
+ {
+ struct ModernOptionsObject *obj = (struct ModernOptionsObject *)dat->pObjectList[i];
+ if (obj->hwnd && obj->bChanged)
+ {
+ obj->bChanged = FALSE;
+ pshn.hdr.hwndFrom = obj->hwnd;
+ SendMessage(obj->hwnd, WM_NOTIFY, 0, (LPARAM)&pshn);
+ }
+ }
+}
+
+static INT_PTR CALLBACK ModernOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ struct ModernOptionsData *dat = (struct ModernOptionsData *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
+
+ int i;
+ HWND hwndCtrl;
+
+ switch (msg) {
+ case WM_INITDIALOG:
+ {
+ TranslateDialogDefault(hwndDlg);
+ HIMAGELIST himl = 0;
+
+ dat = (struct ModernOptionsData *)lParam;
+ dat->iPage = -1;
+
+ LOGFONT lf;
+ dat->hfntBold = (HFONT)SendMessage(hwndDlg, WM_GETFONT, 0, 0);
+ GetObject(dat->hfntBold, sizeof(lf), &lf);
+ lf.lfWeight = FW_BOLD;
+ dat->hfntBold = CreateFontIndirect(&lf);
+
+ hwndCtrl = GetDlgItem(hwndDlg, IDC_TV_SUBSECTIONS);
+ himl = ImageList_Create(16, 16, ILC_MASK + ( IsWinVerXPPlus() ? ILC_COLOR32 : ILC_COLOR16 ), 2, 1);
+ TreeView_SetImageList(hwndCtrl, himl, TVSIL_NORMAL);
+
+ for (i = 0; i < dat->pObjectList.getCount(); ++i) {
+ struct ModernOptionsObject *obj = (struct ModernOptionsObject *)dat->pObjectList[i];
+ if ((obj->optObject.iSection >= 0) && (obj->optObject.iSection < MODERNOPT_PAGE_COUNT))
+ g_ModernOptPages[obj->optObject.iSection].bShow = TRUE;
+ if (obj->optObject.hIcon)
+ obj->iTreeImageIndex = ImageList_AddIcon(himl, obj->optObject.hIcon);
+ }
+
+ hwndCtrl = GetDlgItem(hwndDlg, IDC_ICOTABS);
+ for (i = 0; i < SIZEOF(g_ModernOptPages); ++i)
+ if (g_ModernOptPages[i].bShow && g_ModernOptPages[i].bShowTab)
+ {
+ HICON hIcon = (HICON)LoadImage(hInst, MAKEINTRESOURCE(g_ModernOptPages[i].iIcon), IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR);
+ MIcoTab_AddItem(hwndCtrl, TranslateTS(g_ModernOptPages[i].lpzTitle), hIcon, i, FALSE);
+ DestroyIcon(hIcon);
+ }
+
+ SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)dat);
+ hwndModernOpt = hwndDlg;
+
+ if (g_iSectionRestore)
+ CallService(MS_MODERNOPT_SELECTPAGE, g_iSectionRestore, 0);
+ else
+ ModernOptUI_SelectSection(hwndDlg, dat, g_iSectionRestore);
+
+ Utils_RestoreWindowPositionNoSize(hwndDlg, NULL, "Options", "");
+
+ return TRUE;
+ }
+
+ case WM_COMMAND:
+ switch (LOWORD(wParam)) {
+ case IDC_ICOTABS:
+ {
+ int iPage = MIcoTab_GetItemData(GetDlgItem(hwndDlg, IDC_ICOTABS), lParam);
+ ModernOptUI_SelectSection(hwndDlg, dat, iPage);
+ SetFocus(GetDlgItem(hwndDlg, IDC_ICOTABS));
+ }
+ break;
+
+ case IDC_BTN_HELP:
+ {
+ struct ModernOptionsObject *obj = (struct ModernOptionsObject *)dat->pObjectList[dat->iPage];
+ if (obj->optObject.lpzHelpUrl)
+ ShellExecuteA(hwndDlg, "open", obj->optObject.lpzHelpUrl, "", "", SW_SHOW);
+ }
+ break;
+
+ case IDC_BTN_EXPERT:
+ if (IsWindowEnabled(GetDlgItem(hwndDlg, IDC_BTN_APPLY)))
+ {
+ int idResult = MessageBox(hwndDlg,
+ TranslateT("You have some unsaved changes here.\n Do you wish to apply settings before switching?"),
+ _T("Miranda IM"), MB_ICONQUESTION|MB_YESNOCANCEL);
+ if (idResult == IDCANCEL) break;
+ sttNotifyPages(dat, (idResult == IDYES) ? PSN_APPLY : PSN_RESET);
+ }
+
+ { Utils_SaveWindowPosition(hwndDlg, NULL, "Options", "");
+ g_iSectionRestore = dat->iSection;
+ struct ModernOptionsObject *obj = (struct ModernOptionsObject *)dat->pObjectList[dat->iPage];
+ if (obj->optObject.lpzClassicGroup || obj->optObject.lpzClassicPage)
+ {
+ OPENOPTIONSDIALOG ood = {0};
+ ood.cbSize = sizeof(ood);
+ ood.pszGroup = obj->optObject.lpzClassicGroup;
+ ood.pszPage = obj->optObject.lpzClassicPage;
+ ood.pszTab = obj->optObject.lpzClassicTab;
+ HWND hwndOpt = (HWND)CallService(MS_OPT_OPENOPTIONSPAGE, 0, (LPARAM)&ood);
+ PostMessage(hwndDlg, WM_CLOSE, 0, 0);
+ }
+ else {
+ CallService("Options/OptionsCommand", 0, 0);
+ PostMessage(hwndDlg, WM_CLOSE, 0, 0);
+ } }
+ break;
+
+ case IDOK:
+ sttNotifyPages(dat, PSN_APPLY);
+ PostMessage(hwndDlg, WM_CLOSE, 0, 0);
+ break;
+
+ case IDCANCEL:
+ sttNotifyPages(dat, PSN_RESET);
+ PostMessage(hwndDlg, WM_CLOSE, 0, 0);
+ break;
+
+ case IDC_BTN_APPLY:
+ EnableWindow(GetDlgItem(hwndDlg,IDC_BTN_APPLY), FALSE);
+ sttNotifyPages(dat, PSN_APPLY);
+ break;
+ }
+
+ return TRUE;
+
+ case PSM_CHANGED:
+ EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_APPLY), TRUE);
+ for (i = 0; i < dat->pObjectList.getCount(); ++i) {
+ struct ModernOptionsObject *obj = (struct ModernOptionsObject *)dat->pObjectList[i];
+ if (obj->hwnd && IsWindowVisible(obj->hwnd))
+ obj->bChanged = TRUE;
+ }
+ break;
+
+ case WM_NOTIFY:
+ {
+ LPNMHDR lpnmhdr = (LPNMHDR)lParam;
+ if (lpnmhdr->idFrom == IDC_TV_SUBSECTIONS ) {
+ LPNMTREEVIEW lpnmtv = (LPNMTREEVIEW)lParam;
+ if (lpnmhdr->code == TVN_SELCHANGED ) {
+ ModernOptUI_ShowPage(hwndDlg, dat, lpnmtv->itemNew.lParam);
+ break;
+ }
+ break;
+ }
+ return TRUE;
+ }
+
+ case WM_CLOSE:
+ DestroyWindow(hwndDlg);
+ hwndModernOpt = 0;
+ return TRUE;
+
+ case WM_DESTROY:
+ if (!dat) return TRUE;
+ li_List_Destruct(dat->pObjectList, ModernOptionsObject_Dtor);
+ DeleteObject(dat->hfntBold);
+ ImageList_Destroy(TreeView_SetImageList(GetDlgItem(hwndDlg, IDC_TV_SUBSECTIONS), NULL, TVSIL_NORMAL));
+ Utils_SaveWindowPosition(hwndDlg, NULL, "Options", "");
+ delete dat;
+ }
+ return FALSE;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// UI utilities
+static HWND ModernOptUI_ShowPage_Impl(HWND hwndDlg, struct ModernOptionsData *dat, int iPage, int dx, HWND hwndInsertAfter)
+{
+ if ((iPage < 0) || (iPage >= dat->pObjectList.getCount()))
+ return NULL;
+
+ dat->iPage = iPage;
+ struct ModernOptionsObject *obj = (struct ModernOptionsObject *)dat->pObjectList[dat->iPage];
+ if (!obj->hwnd) {
+ RECT rc1, rc2;
+ GetWindowRect(GetDlgItem(hwndDlg, IDC_TV_SUBSECTIONS), &rc1);
+ GetWindowRect(GetDlgItem(hwndDlg, IDC_TXT_DUMMY), &rc2);
+ MapWindowPoints(NULL, hwndDlg, (LPPOINT)&rc1, 2);
+ MapWindowPoints(NULL, hwndDlg, (LPPOINT)&rc2, 2);
+ rc1.top += dx; rc2.top += dx;
+
+ obj->hwnd = CreateDialogParamA(obj->optObject.hInstance, obj->optObject.lpzTemplate, hwndDlg, obj->optObject.pfnDlgProc, (LPARAM)&obj->optObject);
+ if (obj->hwnd) {
+ DWORD dwShowFlags =
+ SWP_SHOWWINDOW |
+ ((obj->optObject.dwFlags & MODEROPT_FLG_NORESIZE) ? SWP_NOSIZE : 0);
+
+ int i = 0;
+
+ if (obj->optObject.iBoldControls)
+ for (i = 0; obj->optObject.iBoldControls[i]; ++i) {
+ HWND hwndChild = GetDlgItem(obj->hwnd, obj->optObject.iBoldControls[i]);
+ if (!hwndChild) continue;
+ SendMessage(hwndChild, WM_SETFONT, (WPARAM)dat->hfntBold, TRUE);
+ }
+
+ if (obj->optObject.iType == MODERNOPT_TYPE_SECTIONPAGE)
+ SetWindowPos(obj->hwnd, hwndInsertAfter, rc1.left, rc1.top, rc2.right-rc1.left, rc2.bottom-rc1.top, dwShowFlags);
+ else
+ SetWindowPos(obj->hwnd, hwndInsertAfter, rc2.left, rc2.top, rc2.right-rc2.left, rc2.bottom-rc2.top, dwShowFlags);
+
+ if (obj->optObject.iSection == MODERNOPT_PAGE_IGNORE) {
+ for (i = 0; i < dat->pObjectList.getCount(); ++i) {
+ struct ModernOptionsObject *ignoreObj = (struct ModernOptionsObject *)dat->pObjectList[i];
+ if (ignoreObj->optObject.iType == MODERNOPT_TYPE_IGNOREOBJECT)
+ ModernOptIgnore_AddItem(&ignoreObj->optObject);
+ } } }
+ }
+ else ShowWindow(obj->hwnd, SW_SHOW);
+
+ ShowWindow(GetDlgItem(hwndDlg, IDC_BTN_EXPERT), (obj->optObject.lpzClassicGroup || obj->optObject.lpzClassicPage) ? SW_SHOW : SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_BTN_HELP), obj->optObject.lpzHelpUrl ? SW_SHOW : SW_HIDE);
+
+ return obj->hwnd;
+}
+
+static int lstrcmp_null(TCHAR *p1, TCHAR *p2)
+{
+ if (!p1 && !p2) return 0;
+ if (!p1) return -1;
+ if (!p2) return 1;
+ return lstrcmp(p1, p2);
+}
+
+static void ModernOptUI_ShowPage(HWND hwndDlg, struct ModernOptionsData *dat, int iPage)
+{
+ HWND hwndInsertAfter = GetDlgItem(hwndDlg, IDC_TV_SUBSECTIONS);
+
+ int dx = 0;
+ for (int i = 0; i < dat->pObjectList.getCount(); ++i)
+ if ((dat->pObjectList[i]->optObject.iType == dat->pObjectList[iPage]->optObject.iType) &&
+ (dat->pObjectList[i]->optObject.iSection == dat->pObjectList[iPage]->optObject.iSection) &&
+ !lstrcmp_null(dat->pObjectList[i]->optObject.lptzSubsection, dat->pObjectList[iPage]->optObject.lptzSubsection))
+ {
+ hwndInsertAfter = ModernOptUI_ShowPage_Impl(hwndDlg, dat, i, dx, hwndInsertAfter);
+
+ if (dat->pObjectList[i]->hwnd) {
+ RECT rcWnd; GetWindowRect(dat->pObjectList[i]->hwnd, &rcWnd);
+ dx += rcWnd.bottom - rcWnd.top;// + 30;
+ }
+ }
+ else if (dat->pObjectList[i]->hwnd)
+ {
+ ShowWindow(dat->pObjectList[i]->hwnd, SW_HIDE);
+ }
+}
+
+static void ModernOptUI_SelectSection(HWND hwndDlg, struct ModernOptionsData *dat, int iSection)
+{
+ int i;
+ int iPageType = -1;
+
+ HWND hwndTree = GetDlgItem(hwndDlg, IDC_TV_SUBSECTIONS);
+ dat->iSection = iSection;
+
+ SendMessage(hwndTree, WM_SETREDRAW, FALSE, 0);
+ TreeView_DeleteAllItems(hwndTree);
+ for (i = 0; i < dat->pObjectList.getCount(); ++i) {
+ struct ModernOptionsObject *obj = (struct ModernOptionsObject *)dat->pObjectList[i];
+ if (obj->optObject.iSection != iSection) continue;
+
+ if ((iPageType < -1) && (iPageType != obj->optObject.iType)) continue;
+ iPageType = obj->optObject.iType;
+
+ if (obj->optObject.iType == MODERNOPT_TYPE_SECTIONPAGE) {
+ ModernOptUI_ShowPage(hwndDlg, dat, i);
+ break;
+ }
+
+ if (obj->optObject.iType == MODERNOPT_TYPE_SUBSECTIONPAGE) {
+ TVINSERTSTRUCT tvis = {0};
+ tvis.hParent = TVI_ROOT;
+ tvis.hInsertAfter = TVI_LAST;
+ tvis.item.mask = TVIF_IMAGE|TVIF_TEXT|TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIF_PARAM;
+ tvis.item.pszText = TranslateTS(obj->optObject.lptzSubsection);
+ tvis.item.cchTextMax = lstrlen(tvis.item.pszText);
+ tvis.item.iImage = tvis.item.iSelectedImage = obj->iTreeImageIndex;
+ tvis.item.lParam = i;
+ TreeView_InsertItem(hwndTree, &tvis);
+ } }
+
+ SendMessage(hwndTree, WM_SETREDRAW, TRUE, 0);
+
+ if (iPageType < 0)
+ return;
+
+ if (iPageType != MODERNOPT_TYPE_SECTIONPAGE) {
+ ShowWindow(hwndTree, SW_SHOW);
+ RedrawWindow(hwndTree, NULL, NULL, RDW_INVALIDATE);
+ TreeView_Select(hwndTree, TreeView_GetRoot(hwndTree), TVGN_CARET);
+ }
+ else ShowWindow(hwndTree, SW_HIDE);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Services
+static INT_PTR svcModernOpt_Impl(WPARAM wParam, LPARAM lParam)
+{
+ if (!hwndModernOpt) {
+ ModernOptionsData *dat = new ModernOptionsData;
+ g_dwIdx = 0;
+ NotifyEventHooks(hevtModernOpt_Initialize, (WPARAM)dat, 0);
+ hwndModernOpt = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_MODERNOPT), NULL, ModernOptDlgProc, (LPARAM)dat);
+ ShowWindow(hwndModernOpt, SW_SHOW);
+ }
+ else SetForegroundWindow(hwndModernOpt);
+
+ return 0;
+}
+
+static INT_PTR svcModernOpt_Show(WPARAM wParam, LPARAM lParam)
+{
+ g_iSectionRestore = 0;
+ return svcModernOpt_Impl(wParam, lParam);
+}
+
+static INT_PTR svcModernOpt_Restore(WPARAM wParam, LPARAM lParam)
+{
+ if (g_iSectionRestore == 0) return 0;
+ return svcModernOpt_Impl(wParam, lParam);
+}
+
+static INT_PTR svcModernOpt_SelectPage(WPARAM wParam, LPARAM lParam)
+{
+ struct ModernOptionsData *dat;
+
+ if (!hwndModernOpt)
+ return 0;
+
+ dat = (struct ModernOptionsData *)GetWindowLongPtr(hwndModernOpt, GWLP_USERDATA);
+ if (!dat)
+ return 0;
+
+ int nIdx = 0;
+ for (size_t i = 0; i < MODERNOPT_PAGE_COUNT; ++i)
+ if (g_ModernOptPages[i].bShow && g_ModernOptPages[i].bShowTab) {
+ if (i == wParam) {
+ MIcoTab_SetSel(GetDlgItem(hwndModernOpt, IDC_ICOTABS), nIdx);
+ break;
+ }
+
+ ++nIdx;
+ }
+
+// ModernOptUI_SelectSection(hwndModernOpt, dat, wParam);
+ return 0;
+}
+
+static INT_PTR svcModernOpt_AddObject(WPARAM wParam, LPARAM lParam)
+{
+ struct ModernOptionsData *dat = (struct ModernOptionsData *)wParam;
+ MODERNOPTOBJECT *obj = (MODERNOPTOBJECT *)lParam;
+ struct ModernOptionsObject *objCopy = (struct ModernOptionsObject *)mir_calloc(sizeof(struct ModernOptionsObject));
+
+ objCopy->dwIdx = ++g_dwIdx;
+
+ objCopy->optObject.cbSize = sizeof(MODERNOPTOBJECT);
+ objCopy->optObject.dwFlags = obj->dwFlags;
+ objCopy->optObject.hIcon = obj->hIcon;
+ objCopy->optObject.iSection = obj->iSection;
+ objCopy->optObject.iType = obj->iType;
+ objCopy->optObject.hInstance = obj->hInstance;
+ objCopy->optObject.lpzTemplate = obj->lpzTemplate;
+ objCopy->optObject.pfnDlgProc = obj->pfnDlgProc;
+
+ if (obj->lpzClassicGroup) objCopy->optObject.lpzClassicGroup = mir_strdup(obj->lpzClassicGroup);
+ if (obj->lpzClassicPage) objCopy->optObject.lpzClassicPage = mir_strdup(obj->lpzClassicPage);
+ if (obj->lpzClassicTab) objCopy->optObject.lpzClassicTab = mir_strdup(obj->lpzClassicTab);
+ if (obj->lpzHelpUrl) objCopy->optObject.lpzHelpUrl = mir_strdup(obj->lpzHelpUrl);
+
+ if (obj->iBoldControls) {
+ int count = 0;
+ while (obj->iBoldControls[count++]) ;
+ objCopy->optObject.iBoldControls = (int *)mir_alloc(sizeof(int) * count);
+ memcpy(objCopy->optObject.iBoldControls, obj->iBoldControls, sizeof(int) * count);
+ }
+
+ switch (obj->iType) {
+ case MODERNOPT_TYPE_SECTIONPAGE:
+ objCopy->optObject.lptzSubsection = NULL;
+ break;
+
+ case MODERNOPT_TYPE_SUBSECTIONPAGE:
+ objCopy->optObject.lptzSubsection = (objCopy->optObject.dwFlags & MODEROPT_FLG_UNICODE) ?
+ mir_u2t(obj->lpwzSubsection) :
+ mir_a2t(obj->lpzSubsection);
+ break;
+
+ case MODERNOPT_TYPE_IGNOREOBJECT:
+ objCopy->optObject.lptzSubsection = (objCopy->optObject.dwFlags & MODEROPT_FLG_UNICODE) ?
+ mir_u2t(obj->lpwzSubsection) :
+ mir_a2t(obj->lpzSubsection);
+ objCopy->optObject.lpzIgnoreModule = mir_strdup(obj->lpzIgnoreModule);
+ objCopy->optObject.lpzIgnoreSetting = mir_strdup(obj->lpzIgnoreSetting);
+ objCopy->optObject.dwIgnoreBit = obj->dwIgnoreBit;
+ break;
+
+ case MODERNOPT_TYPE_SELECTORPAGE:
+ objCopy->optObject.iType = MODERNOPT_TYPE_SUBSECTIONPAGE;
+ objCopy->optObject.hInstance = hInst;
+ objCopy->optObject.lpzTemplate = MAKEINTRESOURCEA(IDD_MODERNOPT_SKINS);
+ objCopy->optObject.pfnDlgProc = ModernOptSelector_DlgProc;
+ objCopy->optObject.lptzSubsection = (objCopy->optObject.dwFlags & MODEROPT_FLG_UNICODE) ?
+ mir_u2t(obj->lpwzSubsection) :
+ mir_a2t(obj->lpzSubsection);
+ objCopy->optObject.lpzThemeExtension = mir_strdup(obj->lpzThemeExtension);
+ objCopy->optObject.lpzThemeModuleName = mir_strdup(obj->lpzThemeModuleName);
+ break;
+ }
+
+ dat->pObjectList.insert(objCopy);
+ return 0;
+}
+
+static int hookModernOpt_Initialize(WPARAM wParam, LPARAM lParam)
+{
+ static int iBoldControls[] =
+ {
+ IDC_TXT_TITLE1, IDC_TXT_TITLE2, IDC_TXT_TITLE3, IDC_TXT_TITLE4,
+// IDC_TXT_TITLE5, IDC_TXT_TITLE6, IDC_TXT_TITLE7, IDC_TXT_TITLE8,
+ MODERNOPT_CTRL_LAST
+ };
+
+ MODERNOPTOBJECT obj = {0};
+
+ obj.cbSize = sizeof(obj);
+ obj.dwFlags = MODEROPT_FLG_TCHAR;
+
+ obj.hIcon = LoadSkinnedIcon(SKINICON_OTHER_MIRANDA);
+ obj.hInstance = hInst;
+
+ obj.iSection = MODERNOPT_PAGE_HOME;
+ obj.iType = MODERNOPT_TYPE_SECTIONPAGE;
+ obj.lpzTemplate = MAKEINTRESOURCEA(IDD_MODERNOPT_HOME);
+ obj.pfnDlgProc = ModernOptHome_DlgProc;
+ obj.lpzHelpUrl = "http://wiki.miranda-im.org/";
+ CallService(MS_MODERNOPT_ADDOBJECT, wParam, (LPARAM)&obj);
+
+ #if defined(_DEBUG) && defined(MOPT_SAMPLE_PAGES)
+ obj.iSection = MODERNOPT_PAGE_ADVANCED;
+ obj.iType = MODERNOPT_TYPE_SUBSECTIONPAGE;
+ obj.lptzSubsection = _T("Page 1");
+ CallService(MS_MODERNOPT_ADDOBJECT, wParam, (LPARAM)&obj);
+ obj.lptzSubsection = _T("Page 2");
+ CallService(MS_MODERNOPT_ADDOBJECT, wParam, (LPARAM)&obj);
+ obj.lptzSubsection = _T("Page 3");
+ CallService(MS_MODERNOPT_ADDOBJECT, wParam, (LPARAM)&obj);
+
+ obj.iType = MODERNOPT_TYPE_IGNOREOBJECT;
+ obj.hIcon = LoadSkinnedIcon(SKINICON_EVENT_FILE);
+ obj.lptzSubsection = _T("Files");
+ CallService(MS_MODERNOPT_ADDOBJECT, wParam, (LPARAM)&obj);
+ obj.hIcon = LoadSkinnedIcon(SKINICON_EVENT_MESSAGE);
+ obj.lptzSubsection = _T("Messages");
+ CallService(MS_MODERNOPT_ADDOBJECT, wParam, (LPARAM)&obj);
+ obj.hIcon = LoadSkinnedIcon(SKINICON_EVENT_URL);
+ obj.lptzSubsection = _T("URL events");
+ CallService(MS_MODERNOPT_ADDOBJECT, wParam, (LPARAM)&obj);
+ obj.hIcon = LoadSkinnedIcon(SKINICON_OTHER_TYPING);
+ obj.lptzSubsection = _T("Typing notifications");
+ CallService(MS_MODERNOPT_ADDOBJECT, wParam, (LPARAM)&obj);
+ obj.hIcon = LoadSkinnedIcon(SKINICON_OTHER_ADDCONTACT);
+ obj.lptzSubsection = _T("Added notifications");
+ CallService(MS_MODERNOPT_ADDOBJECT, wParam, (LPARAM)&obj);
+ obj.hIcon = LoadSkinnedIcon(SKINICON_OTHER_MIRANDA);
+ obj.lptzSubsection = _T("Auth requests");
+ CallService(MS_MODERNOPT_ADDOBJECT, wParam, (LPARAM)&obj);
+
+ obj.iSection = MODERNOPT_PAGE_SKINS;
+ obj.iType = MODERNOPT_TYPE_SECTIONPAGE;
+ obj.lpzTemplate = MAKEINTRESOURCEA(IDD_MODERNOPT_SKINS);
+ obj.pfnDlgProc = NULL;
+ obj.iBoldControls = iBoldControls;
+ obj.lpzHelpUrl = NULL;
+ CallService(MS_MODERNOPT_ADDOBJECT, wParam, (LPARAM)&obj);
+
+ obj.lpzTemplate = MAKEINTRESOURCEA(IDD_MODERNOPT_EMPTY);
+ obj.pfnDlgProc = NULL;
+ obj.iBoldControls = 0;
+ obj.lpzClassicGroup = 0;
+ obj.lpzClassicPage = 0;
+ obj.lpzHelpUrl = 0;
+
+ obj.iSection = MODERNOPT_PAGE_CLIST;
+ obj.iType = MODERNOPT_TYPE_SECTIONPAGE;
+ CallService(MS_MODERNOPT_ADDOBJECT, wParam, (LPARAM)&obj);
+
+ obj.iSection = MODERNOPT_PAGE_MSGS;
+ obj.iType = MODERNOPT_TYPE_SECTIONPAGE;
+ CallService(MS_MODERNOPT_ADDOBJECT, wParam, (LPARAM)&obj);
+
+ obj.iSection = MODERNOPT_PAGE_ADVANCED;
+ obj.iType = MODERNOPT_TYPE_SUBSECTIONPAGE;
+ obj.lptzSubsection = _T("Page 1");
+ CallService(MS_MODERNOPT_ADDOBJECT, wParam, (LPARAM)&obj);
+ obj.lptzSubsection = _T("Page 2");
+ CallService(MS_MODERNOPT_ADDOBJECT, wParam, (LPARAM)&obj);
+ obj.lptzSubsection = _T("Page 3");
+ CallService(MS_MODERNOPT_ADDOBJECT, wParam, (LPARAM)&obj);
+
+ obj.iSection = MODERNOPT_PAGE_MODULES;
+ obj.iType = MODERNOPT_TYPE_SUBSECTIONPAGE;
+ obj.lptzSubsection = _T("Configure");
+ CallService(MS_MODERNOPT_ADDOBJECT, wParam, (LPARAM)&obj);
+ obj.lptzSubsection = _T("Update");
+ CallService(MS_MODERNOPT_ADDOBJECT, wParam, (LPARAM)&obj);
+ obj.lptzSubsection = _T("Download");
+ CallService(MS_MODERNOPT_ADDOBJECT, wParam, (LPARAM)&obj);
+ #endif
+
+ return 0;
+}
diff --git a/plugins/ModernOpt/src/modernopt.h b/plugins/ModernOpt/src/modernopt.h
new file mode 100644
index 0000000000..728488d810
--- /dev/null
+++ b/plugins/ModernOpt/src/modernopt.h
@@ -0,0 +1,53 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2007 Artem Shpynov
+Copyright 2000-2007 Miranda ICQ/IM project,
+
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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.
+*/
+
+#ifndef MODERNOPT_H__
+#define MODERNOPT_H__ 1
+
+#include "m_descbutton.h"
+#include "m_iconheader.h"
+#include "m_modernopt.h"
+
+struct ModernOptMainPageInfo
+{
+ int idcButton;
+ BOOL bShowTab;
+ int iIcon;
+ TCHAR *lpzTitle;
+ TCHAR *lpzDescription;
+ int iPageType;
+ BOOL bShow;
+};
+
+extern struct ModernOptMainPageInfo g_ModernOptPages[MODERNOPT_PAGE_COUNT];
+
+extern HMODULE hInst;
+
+INT_PTR CALLBACK ModernOptHome_DlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+INT_PTR CALLBACK ModernOptSelector_DlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+
+void ModernOptIgnore_AddItem(MODERNOPTOBJECT *obj);
+
+#endif // MODERNOPT_H__
diff --git a/plugins/ModernOpt/src/mopt_home.cpp b/plugins/ModernOpt/src/mopt_home.cpp
new file mode 100644
index 0000000000..980f580121
--- /dev/null
+++ b/plugins/ModernOpt/src/mopt_home.cpp
@@ -0,0 +1,80 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2007 Artem Shpynov
+Copyright 2000-2007 Miranda ICQ/IM project,
+
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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 "commonheaders.h"
+#include "modernopt.h"
+
+extern HMODULE hInst;
+
+INT_PTR CALLBACK ModernOptHome_DlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ int i;
+
+ switch (msg) {
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hwndDlg);
+ for (i = 0; i < SIZEOF(g_ModernOptPages); ++i) {
+ if (g_ModernOptPages[i].idcButton) {
+ HWND hwndCtrl = GetDlgItem(hwndDlg, g_ModernOptPages[i].idcButton);
+ if (g_ModernOptPages[i].bShow) {
+ HICON hIcon = (HICON)LoadImage(hInst, MAKEINTRESOURCE(g_ModernOptPages[i].iIcon), IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR);
+ MDescButton_SetIcon(hwndCtrl, hIcon);
+ MDescButton_SetTitle(hwndCtrl, TranslateTS(g_ModernOptPages[i].lpzTitle));
+ MDescButton_SetDescription(hwndCtrl, TranslateTS(g_ModernOptPages[i].lpzDescription));
+ DestroyIcon(hIcon);
+ }
+ else ShowWindow(hwndCtrl, SW_HIDE);
+ } }
+
+ return FALSE;
+
+ case WM_COMMAND:
+ switch ( LOWORD(wParam)) {
+ case IDC_BTN_CLASSICOPT:
+ PostMessage(GetParent(hwndDlg), WM_CLOSE, 0, 0);
+ {
+ OPENOPTIONSDIALOG ood = {0};
+ ood.cbSize = sizeof(ood);
+ CallService(MS_OPT_OPENOPTIONS, 0, (LPARAM)&ood);
+ }
+ break;
+
+ case IDC_BTN_HELP:
+ ShellExecuteA(hwndDlg, "open", "http://www.miranda-im.org/", "", "", SW_SHOW);
+ break;
+
+ default:
+ for (i = 0; i < SIZEOF(g_ModernOptPages); ++i) {
+ if (g_ModernOptPages[i].idcButton == LOWORD(wParam))
+ {
+ CallService(MS_MODERNOPT_SELECTPAGE, i, 0);
+ return TRUE;
+ } } }
+
+ case WM_DESTROY:
+ return FALSE;
+ }
+ return FALSE;
+}
diff --git a/plugins/ModernOpt/src/mopt_ignore.cpp b/plugins/ModernOpt/src/mopt_ignore.cpp
new file mode 100644
index 0000000000..74f8b1524d
--- /dev/null
+++ b/plugins/ModernOpt/src/mopt_ignore.cpp
@@ -0,0 +1,61 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2007 Artem Shpynov
+Copyright 2000-2007 Miranda ICQ/IM project,
+
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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 "commonheaders.h"
+#include "modernopt.h"
+
+static HWND g_hwndModernOptIgnore = NULL;
+
+void ModernOptIgnore_AddItem(MODERNOPTOBJECT *obj)
+{
+ if ( g_hwndModernOptIgnore )
+ SendMessage(g_hwndModernOptIgnore, WM_APP, 0, (LPARAM)obj);
+}
+
+static void ResetListOptions(HWND hwndList)
+{
+ SendMessage(hwndList,CLM_SETBKBITMAP,0,(LPARAM)(HBITMAP)NULL);
+ SendMessage(hwndList,CLM_SETBKCOLOR,GetSysColor(COLOR_WINDOW),0);
+ SendMessage(hwndList,CLM_SETGREYOUTFLAGS,0,0);
+ SendMessage(hwndList,CLM_SETLEFTMARGIN,4,0);
+ SendMessage(hwndList,CLM_SETINDENT,10,0);
+ SendMessage(hwndList,CLM_SETHIDEEMPTYGROUPS,1,0);
+
+ for(int i=0;i<=FONTID_MAX;i++)
+ SendMessage(hwndList,CLM_SETTEXTCOLOR,i,GetSysColor(COLOR_WINDOWTEXT));
+}
+
+static void SetAllContactIcons(HWND hwndList, int count)
+{
+ HANDLE hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0);
+ do {
+ DWORD hItem = SendMessage(hwndList,CLM_FINDCONTACT,(WPARAM)hContact,0);
+ for (int i = 0; i < count; ++i)
+ SendMessage(hwndList,CLM_SETEXTRAIMAGE,hItem,MAKELPARAM(i, i+1));
+ if (!DBGetContactSettingByte(hContact,"CList","Hidden",0))
+ SendMessage(hwndList,CLM_SETCHECKMARK,hItem,1);
+ }
+ while(hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hContact,0));
+}
diff --git a/plugins/ModernOpt/src/mopt_selector.cpp b/plugins/ModernOpt/src/mopt_selector.cpp
new file mode 100644
index 0000000000..42b15f51bb
--- /dev/null
+++ b/plugins/ModernOpt/src/mopt_selector.cpp
@@ -0,0 +1,385 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2007 Artem Shpynov
+Copyright 2000-2007 Miranda ICQ/IM project,
+
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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 "commonheaders.h"
+#include "modernopt.h"
+
+static void sttApplySkin(MODERNOPTOBJECT *obj, TCHAR *fn)
+{
+ char svc[128];
+ mir_snprintf(svc, SIZEOF(svc), "%s%s", obj->lpzThemeModuleName, TS_SKIN_APPLY);
+ CallService(svc, NULL, (LPARAM)fn);
+}
+
+static TCHAR *sttGetActiveSkin(MODERNOPTOBJECT *obj)
+{
+ char svc[128];
+ mir_snprintf(svc, SIZEOF(svc), "%s%s", obj->lpzThemeModuleName, TS_SKIN_ACTIVE);
+ return ServiceExists(svc) ? (TCHAR *)CallService(svc, 0, 0) : 0;
+}
+
+static void sttPreviewSkin(MODERNOPTOBJECT *obj, TCHAR *fn, LPDRAWITEMSTRUCT lps)
+{
+ if (!fn) return;
+
+ char svc[128];
+ mir_snprintf(svc, SIZEOF(svc), "%s%s", obj->lpzThemeModuleName, TS_SKIN_PREVIEW);
+ if (ServiceExists(svc))
+ CallService(svc, (WPARAM)lps, (LPARAM)fn);
+ else {
+ char *afn = mir_t2a(fn);
+ char *fnpreview = (char *)mir_alloc(lstrlenA(afn) + 10);
+ lstrcpyA(fnpreview, afn);
+ lstrcatA(fnpreview, ".png");
+ HBITMAP hbmPreview = (HBITMAP)CallService(MS_UTILS_LOADBITMAP, 0, (LPARAM)fnpreview);
+ mir_free(afn);
+ mir_free(fnpreview);
+
+ if (!hbmPreview) return;
+
+ BITMAP bmp;
+ GetObject(hbmPreview, sizeof(bmp), &bmp);
+
+ SIZE szDst = { abs(bmp.bmWidth), abs(bmp.bmHeight) };
+ if ((szDst.cx > lps->rcItem.right-lps->rcItem.left) || (szDst.cy > lps->rcItem.bottom-lps->rcItem.top)) {
+ float q = min(
+ float(lps->rcItem.right-lps->rcItem.left) / szDst.cx,
+ float(lps->rcItem.bottom-lps->rcItem.top) / szDst.cy);
+ szDst.cx *= q;
+ szDst.cy *= q;
+ }
+ POINT ptDst = {
+ (lps->rcItem.left+lps->rcItem.right-szDst.cx) / 2,
+ (lps->rcItem.top+lps->rcItem.bottom-szDst.cy) / 2 };
+
+ HDC hdc = CreateCompatibleDC(lps->hDC);
+ SelectObject(hdc, hbmPreview);
+ SetStretchBltMode(hdc, HALFTONE);
+ StretchBlt(lps->hDC, ptDst.x, ptDst.y, szDst.cx, szDst.cy, hdc, 0, 0, abs(bmp.bmWidth), abs(bmp.bmHeight), SRCCOPY);
+ DeleteDC(hdc);
+ DeleteObject(hbmPreview);
+ }
+}
+
+struct TSkinListItem
+{
+ TCHAR *path;
+ TCHAR *title;
+ TCHAR *filename;
+
+ TSkinListItem(TCHAR *fn)
+ {
+ title = mir_tstrdup(fn);
+ if (TCHAR *p = _tcsrchr(title, _T('.'))) *p = 0;
+
+ TCHAR curPath[MAX_PATH];
+ GetCurrentDirectory(SIZEOF(curPath), curPath);
+
+ path = (TCHAR *)mir_alloc(MAX_PATH * sizeof(TCHAR));
+ CallService(MS_UTILS_PATHTORELATIVET, (WPARAM)curPath, (LPARAM)path);
+
+ int length = lstrlen(curPath)+lstrlen(fn)+2;
+ filename = (TCHAR *)mir_alloc(length * sizeof(TCHAR));
+ mir_sntprintf(filename, length, _T("%s\\%s"), curPath, fn);
+ }
+
+ ~TSkinListItem()
+ {
+ mir_free(path);
+ mir_free(title);
+ mir_free(filename);
+ }
+};
+
+struct TSelectorData
+{
+ MODERNOPTOBJECT *obj;
+ TCHAR *active;
+ HBITMAP hbmpPreview;
+
+ TSelectorData()
+ {
+ ZeroMemory(this, sizeof(*this));
+ }
+ ~TSelectorData()
+ {
+ mir_free(active);
+ DeleteObject(hbmpPreview);
+ }
+};
+
+static bool CheckExt(TCHAR *fn, TCHAR *ext, int n)
+{
+ int l = lstrlen(fn);
+ return (l > n) && !lstrcmp(fn + l - n, ext);
+}
+
+static void BuildSkinList(HWND hwndList, TCHAR *szExt, int nExtLength = -1, bool start = true)
+{
+ if (start) {
+ static TCHAR mirPath[MAX_PATH];
+ GetModuleFileName(NULL, mirPath, SIZEOF(mirPath));
+ if (TCHAR *p = _tcsrchr(mirPath, _T('\\'))) *p = 0;
+ SetCurrentDirectory(mirPath);
+ SendMessage(hwndList, LB_RESETCONTENT, 0, 0);
+ nExtLength = lstrlen(szExt);
+ SendMessage(hwndList, WM_SETREDRAW, FALSE, 0);
+ }
+
+ WIN32_FIND_DATA ffd = {0};
+ HANDLE h = FindFirstFile(_T("*.*"), &ffd);
+ if (h != INVALID_HANDLE_VALUE) {
+ do {
+ if (!lstrcmp(ffd.cFileName, _T("")) || !lstrcmp(ffd.cFileName, _T(".")) || !lstrcmp(ffd.cFileName, _T("..")))
+ continue;
+
+ if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+ SetCurrentDirectory(ffd.cFileName);
+ BuildSkinList(hwndList, szExt, nExtLength, false);
+ SetCurrentDirectory(_T(".."));
+ }
+ else {
+ if (CheckExt(ffd.cFileName, szExt, nExtLength)) {
+ TSkinListItem *dat = new TSkinListItem(ffd.cFileName);
+ DWORD dwItem = SendMessage(hwndList, LB_ADDSTRING, 0, (LPARAM)ffd.cFileName);
+ SendMessage(hwndList, LB_SETITEMDATA, dwItem, (LPARAM)dat);
+ } }
+ }
+ while (FindNextFile(h, &ffd));
+ FindClose(h);
+ }
+
+ if (start) {
+ SendMessage(hwndList, WM_SETREDRAW, TRUE, 0);
+ RedrawWindow(hwndList, NULL, NULL, RDW_INVALIDATE);
+ }
+}
+
+static void CreatePreview(TSelectorData *sd, TCHAR *fn, LPDRAWITEMSTRUCT lps)
+{
+ HDC hdc = CreateCompatibleDC(lps->hDC);
+ sd->hbmpPreview = CreateCompatibleBitmap(lps->hDC, lps->rcItem.right - lps->rcItem.left, lps->rcItem.bottom - lps->rcItem.top);
+ SelectObject(hdc, sd->hbmpPreview);
+
+ RECT rc;
+ HBRUSH hbr;
+
+ BITMAPINFO bi = {0};
+ bi.bmiHeader.biSize = sizeof(bi.bmiHeader);
+ bi.bmiHeader.biWidth = 8;
+ bi.bmiHeader.biHeight = -8;
+ bi.bmiHeader.biPlanes = 1;
+ bi.bmiHeader.biBitCount = 32;
+ bi.bmiHeader.biCompression = BI_RGB;
+
+ HBITMAP hBmpBrush = (HBITMAP)CreateDIBSection(0, &bi, DIB_RGB_COLORS, 0, 0, 0);
+ HDC dcBmp = CreateCompatibleDC(0);
+ HBITMAP hBmpSave = (HBITMAP)SelectObject(dcBmp, hBmpBrush);
+ hbr = CreateSolidBrush(RGB(0xcc, 0xcc, 0xcc));
+ SetRect(&rc, 0, 0, 8, 8);
+ FillRect(dcBmp, &rc, hbr);
+ DeleteObject(hbr);
+ hbr = CreateSolidBrush(RGB(0xff, 0xff, 0xff));
+ SetRect(&rc, 4, 0, 8, 4);
+ FillRect(dcBmp, &rc, hbr);
+ SetRect(&rc, 0, 4, 4, 8);
+ FillRect(dcBmp, &rc, hbr);
+ DeleteObject(hbr);
+ SelectObject(dcBmp, hBmpSave);
+ DeleteDC(dcBmp);
+
+ rc = lps->rcItem;
+ OffsetRect(&rc, -rc.left, -rc.top);
+ hbr = CreatePatternBrush(hBmpBrush);
+ SetBrushOrgEx(hdc, 1, 1, 0);
+ FillRect(hdc, &rc, hbr);
+ DeleteObject(hbr);
+ DeleteObject(hBmpBrush);
+
+ HDC hdcSave = lps->hDC;
+ lps->hDC = hdc;
+ sttPreviewSkin(sd->obj, fn, lps);
+ lps->hDC = hdcSave;
+
+ FrameRect(hdc, &rc, GetStockBrush(LTGRAY_BRUSH));
+ DeleteDC(hdc);
+}
+
+INT_PTR CALLBACK ModernOptSelector_DlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ TSelectorData *sd = (TSelectorData *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
+ MODERNOPTOBJECT *&obj = sd->obj;
+
+ switch (msg) {
+ case WM_INITDIALOG:
+ {
+ sd = new TSelectorData;
+ MODERNOPTOBJECT *&obj = sd->obj;
+
+ sd->obj = (MODERNOPTOBJECT *)lParam;
+ sd->active = sttGetActiveSkin(obj);
+ SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)sd);
+
+ TCHAR *s = mir_a2t(obj->lpzThemeExtension);
+ BuildSkinList(GetDlgItem(hwndDlg, IDC_SKINLIST), s);
+ mir_free(s);
+ }
+ return FALSE;
+
+ case WM_COMMAND:
+ if (LOWORD(wParam) == IDC_SKINLIST) {
+ switch (HIWORD(wParam)) {
+ case LBN_SELCHANGE:
+ DeleteObject(sd->hbmpPreview);
+ sd->hbmpPreview = 0;
+ RedrawWindow(GetDlgItem(hwndDlg, IDC_PREVIEW1), NULL, NULL, RDW_INVALIDATE);
+ break;
+
+ case LBN_DBLCLK:
+ {
+ int idx = SendDlgItemMessage(hwndDlg, IDC_SKINLIST, LB_GETCURSEL, 0, 0);
+ if (idx >= 0)
+ {
+ TSkinListItem *dat = (TSkinListItem *)SendDlgItemMessage(hwndDlg, IDC_SKINLIST, LB_GETITEMDATA, idx, 0);
+ sttApplySkin(obj, dat->filename);
+ mir_free(sd->active);
+ sd->active = sttGetActiveSkin(obj);
+ RedrawWindow(GetDlgItem(hwndDlg, IDC_SKINLIST), NULL, NULL, RDW_INVALIDATE);
+ }
+ break;
+ } }
+ break;
+ }
+ return FALSE;
+
+ case WM_MEASUREITEM:
+ {
+ LPMEASUREITEMSTRUCT lps = (LPMEASUREITEMSTRUCT)lParam;
+ if (lps->CtlID != IDC_SKINLIST)
+ break;
+ TSkinListItem *dat = (TSkinListItem *)lps->itemData;
+ if (!dat) break;
+
+ lps->itemWidth = 10;
+ lps->itemHeight = 30;
+
+ return FALSE;
+ }
+
+ case WM_DRAWITEM:
+ {
+ LPDRAWITEMSTRUCT lps = (LPDRAWITEMSTRUCT)lParam;
+ if (lps->CtlID == IDC_SKINLIST) {
+ TSkinListItem *dat = (TSkinListItem *)lps->itemData;
+ if (!dat) break;
+
+ SetBkMode(lps->hDC, TRANSPARENT);
+ COLORREF clLine1, clLine2, clBack;
+ if (lps->itemState & ODS_SELECTED) {
+ FillRect(lps->hDC, &lps->rcItem, GetSysColorBrush(COLOR_HIGHLIGHT));
+ clBack = GetSysColor(COLOR_HIGHLIGHT);
+ clLine1 = GetSysColor(COLOR_HIGHLIGHTTEXT);
+ }
+ else {
+ FillRect(lps->hDC, &lps->rcItem, GetSysColorBrush(COLOR_WINDOW));
+ clBack = GetSysColor(COLOR_WINDOW);
+ clLine1 = GetSysColor(COLOR_WINDOWTEXT);
+ }
+ clLine2 = RGB(
+ GetRValue(clLine1) * 0.66 + GetRValue(clBack) * 0.34,
+ GetGValue(clLine1) * 0.66 + GetGValue(clBack) * 0.34,
+ GetBValue(clLine1) * 0.66 + GetBValue(clBack) * 0.34
+ );
+
+ lps->rcItem.left += 2;
+ lps->rcItem.top += 2;
+ lps->rcItem.bottom -= 2;
+ lps->rcItem.right -= 5;
+
+ int cxIcon = GetSystemMetrics(SM_CXSMICON);
+ int cyIcon = GetSystemMetrics(SM_CYSMICON);
+
+ if (sd->active && !lstrcmp(sd->active, dat->filename)) {
+ DrawIconEx(lps->hDC, lps->rcItem.left, (lps->rcItem.top+lps->rcItem.bottom-cyIcon)/2,
+ LoadSkinnedIcon(SKINICON_OTHER_EMPTYBLOB),
+ cxIcon, cyIcon, 0, NULL, DI_NORMAL);
+ }
+ else {
+ DrawIconEx(lps->hDC, lps->rcItem.left, (lps->rcItem.top+lps->rcItem.bottom-cyIcon)/2,
+ LoadSkinnedIcon(SKINICON_OTHER_SMALLDOT),
+ cxIcon, cyIcon, 0, NULL, DI_NORMAL);
+ }
+ lps->rcItem.left += cxIcon;
+ lps->rcItem.left += 5;
+
+// SelectObject(lps->hDC, dat->hfntTitle);
+ SetTextColor(lps->hDC, clLine1);
+ DrawText(lps->hDC, dat->title, -1, &lps->rcItem, DT_LEFT|DT_NOPREFIX|DT_SINGLELINE|DT_END_ELLIPSIS|DT_TOP);
+ lps->rcItem.left += cxIcon;
+
+ SetTextColor(lps->hDC, clLine2);
+ DrawText(lps->hDC, dat->path, -1, &lps->rcItem, DT_LEFT|DT_NOPREFIX|DT_SINGLELINE|DT_PATH_ELLIPSIS|DT_BOTTOM);
+ }
+ else if (lps->CtlID == IDC_PREVIEW1) {
+ int idx = SendDlgItemMessage(hwndDlg, IDC_SKINLIST, LB_GETCURSEL, 0, 0);
+
+ if (!sd->hbmpPreview) {
+ if (idx >= 0) {
+ TSkinListItem *dat = (TSkinListItem *)SendDlgItemMessage(hwndDlg, IDC_SKINLIST, LB_GETITEMDATA, idx, 0);
+ CreatePreview(sd, dat->filename, lps);
+ //sttPreviewSkin(obj, dat->filename, lps);
+ }
+ else CreatePreview(sd, NULL, lps);
+ }
+
+ if (sd->hbmpPreview) {
+ HDC hdc = CreateCompatibleDC(lps->hDC);
+ SelectObject(hdc, sd->hbmpPreview);
+ BitBlt(lps->hDC,
+ lps->rcItem.left, lps->rcItem.top,
+ lps->rcItem.right - lps->rcItem.left, lps->rcItem.bottom - lps->rcItem.top,
+ hdc, 0, 0, SRCCOPY);
+ DeleteDC(hdc);
+ }
+ }
+
+ return TRUE;
+ }
+
+ case WM_DELETEITEM:
+ {
+ LPDELETEITEMSTRUCT lps = (LPDELETEITEMSTRUCT)lParam;
+ if (lps->CtlID != IDC_SKINLIST) break;
+ TSkinListItem *dat = (TSkinListItem *)lps->itemData;
+ if (dat) delete dat;
+ return FALSE;
+ }
+
+ case WM_DESTROY:
+ delete sd;
+ return FALSE;
+ }
+ return FALSE;
+}
diff --git a/plugins/ModernOpt/src/resource.h b/plugins/ModernOpt/src/resource.h
new file mode 100644
index 0000000000..de4fbab2e0
--- /dev/null
+++ b/plugins/ModernOpt/src/resource.h
@@ -0,0 +1,36 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by resource.rc
+//
+
+#define IDD_MODERNOPT_EMPTY 206
+#define IDD_MODERNOPT 216
+#define IDD_MODERNOPT_HOME 219
+#define IDD_MODERNOPT_SKINS 220
+
+#define IDI_BIG_ADVANCED 308
+#define IDI_BIG_BUDDYLIST 309
+#define IDI_BIG_IGNORE 310
+#define IDI_BIG_MESSAGE 311
+#define IDI_BIG_MODULES 312
+#define IDI_BIG_NETWORK 313
+#define IDI_BIG_SKINS 314
+#define IDI_BIG_STATUS 315
+
+#define IDC_BTN_HELP 1001
+#define IDC_BTN_CLASSICOPT 1002
+#define IDC_BTN_ACCOUNTS 1004
+#define IDC_BTN_SKINS 1005
+#define IDC_BTN_CLIST 1006
+#define IDC_BTN_MESSAGING 1007
+#define IDC_BTN_IGNORE 1008
+#define IDC_BTN_STATUS 1009
+#define IDC_BTN_ADVANCED 1010
+#define IDC_BTN_PLUGINS 1011
+#define IDC_TV_SUBSECTIONS 1012
+#define IDC_ICOTABS 1013
+#define IDC_BTN_EXPERT 1015
+#define IDC_BTN_APPLY 1016
+#define IDC_TXT_DUMMY 1017
+#define IDC_SKINLIST 1029
+#define IDC_PREVIEW1 1030