summaryrefslogtreecommitdiff
path: root/src/modules/plugins/pluginopts.cpp
diff options
context:
space:
mode:
authorGeorge Hazan <george.hazan@gmail.com>2012-06-15 16:48:03 +0000
committerGeorge Hazan <george.hazan@gmail.com>2012-06-15 16:48:03 +0000
commit3744b5146df8530d3b43a972d58223cb3ffb533c (patch)
treea322ca4d0f8eda203cdb618071399c2d0a30e841 /src/modules/plugins/pluginopts.cpp
parentb92b010ae92db3f61a20ff2f579a5b717cfc8168 (diff)
- fixes for the plugins options' dialog;
- code cleaning git-svn-id: http://svn.miranda-ng.org/main/trunk@430 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'src/modules/plugins/pluginopts.cpp')
-rw-r--r--src/modules/plugins/pluginopts.cpp415
1 files changed, 415 insertions, 0 deletions
diff --git a/src/modules/plugins/pluginopts.cpp b/src/modules/plugins/pluginopts.cpp
new file mode 100644
index 0000000000..dc1cfb9e24
--- /dev/null
+++ b/src/modules/plugins/pluginopts.cpp
@@ -0,0 +1,415 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2010 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 "..\..\core\commonheaders.h"
+
+#include <m_version.h>
+
+#include "plugins.h"
+
+static HANDLE hevLoadModule, hevUnloadModule;
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Plugins options page dialog
+
+typedef struct
+{
+ HINSTANCE hInst;
+ int flags;
+ char* author;
+ char* authorEmail;
+ char* description;
+ char* copyright;
+ char* homepage;
+ MUUID uuid;
+ TCHAR fileName[MAX_PATH];
+}
+ PluginListItemData;
+
+static BOOL dialogListPlugins(WIN32_FIND_DATA* fd, TCHAR* path, WPARAM, LPARAM lParam)
+{
+ TCHAR buf[MAX_PATH];
+ mir_sntprintf(buf, SIZEOF(buf), _T("%s\\Plugins\\%s"), path, fd->cFileName);
+ HINSTANCE hInst = GetModuleHandle(buf);
+
+ CharLower(fd->cFileName);
+
+ BASIC_PLUGIN_INFO pi;
+ if ( checkAPI(buf, &pi, MIRANDA_VERSION_CORE, CHECKAPI_NONE) == 0 )
+ return TRUE;
+
+ int isdb = pi.pluginInfo->replacesDefaultModule == DEFMOD_DB;
+ PluginListItemData* dat = (PluginListItemData*)mir_alloc( sizeof( PluginListItemData ));
+ dat->hInst = hInst;
+ _tcsncpy(dat->fileName, fd->cFileName, SIZEOF(dat->fileName));
+ HWND hwndList = (HWND)lParam;
+
+ LVITEM it = { 0 };
+ it.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;
+ it.iImage = ( pi.pluginInfo->flags & 1 ) ? 0 : 1;
+ it.iItem = 100000; // add to the end
+ it.lParam = (LPARAM)dat;
+ int iRow = ListView_InsertItem( hwndList, &it );
+ if ( isPluginOnWhiteList(fd->cFileName) )
+ ListView_SetItemState(hwndList, iRow, !isdb ? 0x2000 : 0x3000, LVIS_STATEIMAGEMASK);
+ if ( iRow != -1 ) {
+ it.mask = LVIF_IMAGE;
+ it.iItem = iRow;
+ it.iSubItem = 1;
+ it.iImage = ( hInst != NULL ) ? 2 : 3;
+ ListView_SetItem( hwndList, &it );
+
+ ListView_SetItemText(hwndList, iRow, 2, fd->cFileName);
+
+ dat->flags = pi.pluginInfo->replacesDefaultModule;
+ dat->author = mir_strdup( pi.pluginInfo->author );
+ dat->authorEmail = mir_strdup( pi.pluginInfo->authorEmail );
+ dat->copyright = mir_strdup( pi.pluginInfo->copyright );
+ dat->description = mir_strdup( pi.pluginInfo->description );
+ dat->homepage = mir_strdup( pi.pluginInfo->homepage );
+ if ( pi.pluginInfo->cbSize == sizeof( PLUGININFOEX ))
+ dat->uuid = pi.pluginInfo->uuid;
+ else
+ memset( &dat->uuid, 0, sizeof(dat->uuid));
+
+ TCHAR *shortNameT = mir_a2t(pi.pluginInfo->shortName);
+ ListView_SetItemText(hwndList, iRow, 3, shortNameT);
+ mir_free(shortNameT);
+
+ DWORD unused, verInfoSize = GetFileVersionInfoSize(buf, &unused);
+ if ( verInfoSize != 0 ) {
+ UINT blockSize;
+ VS_FIXEDFILEINFO* fi;
+ void* pVerInfo = mir_alloc(verInfoSize);
+ GetFileVersionInfo(buf, 0, verInfoSize, pVerInfo);
+ VerQueryValue(pVerInfo, _T("\\"), (LPVOID*)&fi, &blockSize);
+ mir_sntprintf(buf, SIZEOF(buf), _T("%d.%d.%d.%d"), HIWORD(fi->dwProductVersionMS),
+ LOWORD(fi->dwProductVersionMS), HIWORD(fi->dwProductVersionLS), LOWORD(fi->dwProductVersionLS));
+ mir_free( pVerInfo );
+ }
+ else
+ mir_sntprintf(buf, SIZEOF(buf), _T("%d.%d.%d.%d"), HIBYTE(HIWORD(pi.pluginInfo->version)),
+ LOBYTE(HIWORD(pi.pluginInfo->version)), HIBYTE(LOWORD(pi.pluginInfo->version)),
+ LOBYTE(LOWORD(pi.pluginInfo->version)));
+
+ ListView_SetItemText(hwndList, iRow, 4, buf);
+ }
+ else mir_free( dat );
+ FreeLibrary(pi.hInst);
+ return TRUE;
+}
+
+static int uuidToString(const MUUID uuid, char *szStr, int cbLen)
+{
+ if (cbLen<1||!szStr) return 0;
+ mir_snprintf(szStr, cbLen, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
+ uuid.a, uuid.b, uuid.c, uuid.d[0], uuid.d[1], uuid.d[2], uuid.d[3], uuid.d[4], uuid.d[5], uuid.d[6], uuid.d[7]);
+ return 1;
+}
+
+static void RemoveAllItems( HWND hwnd )
+{
+ LVITEM lvi;
+ lvi.mask = LVIF_PARAM;
+ lvi.iItem = 0;
+ while ( ListView_GetItem( hwnd, &lvi )) {
+ PluginListItemData* dat = ( PluginListItemData* )lvi.lParam;
+ mir_free( dat->author );
+ mir_free( dat->authorEmail );
+ mir_free( dat->copyright );
+ mir_free( dat->description );
+ mir_free( dat->homepage );
+ mir_free( dat );
+ lvi.iItem ++;
+} }
+
+static int LoadPluginDynamically(PluginListItemData* dat)
+{
+ TCHAR exe[MAX_PATH];
+ GetModuleFileName(NULL, exe, SIZEOF(exe));
+ TCHAR *p = _tcsrchr(exe, '\\'); if (p) *p = 0;
+
+ pluginEntry* pPlug = OpenPlugin(dat->fileName, exe);
+ if (pPlug->pclass & PCLASS_FAILED) {
+LBL_Error:
+ Plugin_Uninit(pPlug, true);
+ return FALSE;
+ }
+
+ if ( !TryLoadPlugin(pPlug, true))
+ goto LBL_Error;
+
+ if ( CallPluginEventHook(pPlug->bpi.hInst, hModulesLoadedEvent, 0, 0) != 0)
+ goto LBL_Error;
+
+ dat->hInst = pPlug->bpi.hInst;
+ CallHookSubscribers(hevLoadModule, (WPARAM)pPlug->bpi.InfoEx, 0);
+ return TRUE;
+}
+
+static int UnloadPluginDynamically(PluginListItemData* dat)
+{
+ pluginEntry tmp;
+ _tcsncpy(tmp.pluginname, dat->fileName, SIZEOF(tmp.pluginname)-1);
+
+ int idx = pluginList.getIndex(&tmp);
+ if (idx == -1)
+ return FALSE;
+
+ pluginEntry* pPlug = pluginList[idx];
+ if ( CallPluginEventHook(pPlug->bpi.hInst, hOkToExitEvent, 0, 0) != 0)
+ return FALSE;
+
+ CallHookSubscribers(hevUnloadModule, (WPARAM)pPlug->bpi.InfoEx, 0);
+
+ dat->hInst = NULL;
+ Plugin_Uninit(pPlug, true);
+ return TRUE;
+}
+
+static LRESULT CALLBACK PluginListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ if (msg == WM_LBUTTONDOWN) {
+ LVHITTESTINFO hi;
+ hi.pt.x = LOWORD(lParam); hi.pt.y = HIWORD(lParam);
+ ListView_SubItemHitTest(hwnd, &hi);
+ if ( hi.iSubItem == 1 ) {
+ LVITEM lvi;
+ lvi.mask = LVIF_PARAM;
+ lvi.iItem = hi.iItem;
+ if ( ListView_GetItem( hwnd, &lvi )) {
+ lvi.iSubItem = 1;
+ lvi.mask = LVIF_IMAGE;
+
+ PluginListItemData* dat = ( PluginListItemData* )lvi.lParam;
+ if (dat->hInst == NULL) {
+ if ( LoadPluginDynamically(dat)) {
+ lvi.iImage = 2;
+ ListView_SetItem(hwnd, &lvi);
+ }
+ }
+ else {
+ if ( UnloadPluginDynamically(dat)) {
+ lvi.iImage = 3;
+ ListView_SetItem(hwnd, &lvi);
+ } } } } }
+
+ WNDPROC wnProc = ( WNDPROC )GetWindowLongPtr(hwnd, GWLP_USERDATA);
+ return CallWindowProc(wnProc, hwnd, msg, wParam, lParam);
+}
+
+INT_PTR CALLBACK DlgPluginOpt(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg) {
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hwndDlg);
+ {
+ HWND hwndList = GetDlgItem(hwndDlg, IDC_PLUGLIST);
+ SetWindowLongPtr(hwndList, GWLP_USERDATA, (LONG_PTR)GetWindowLongPtr(hwndList, GWLP_WNDPROC));
+ SetWindowLongPtr(hwndList, GWLP_WNDPROC, (LONG_PTR)PluginListWndProc);
+
+ HIMAGELIST hIml = ImageList_Create(16, 16, ILC_MASK | (IsWinVerXPPlus()? ILC_COLOR32 : ILC_COLOR16), 4, 0);
+ ImageList_AddIcon_IconLibLoaded( hIml, SKINICON_OTHER_UNICODE );
+ ImageList_AddIcon_IconLibLoaded( hIml, SKINICON_OTHER_ANSI );
+ ImageList_AddIcon_IconLibLoaded( hIml, SKINICON_OTHER_LOADED );
+ ImageList_AddIcon_IconLibLoaded( hIml, SKINICON_OTHER_NOTLOADED );
+ ListView_SetImageList( hwndList, hIml, LVSIL_SMALL );
+
+ LVCOLUMN col;
+ col.mask = LVCF_TEXT | LVCF_WIDTH;
+ col.pszText = _T("");
+ col.cx = 40;
+ ListView_InsertColumn(hwndList, 0, &col);
+
+ col.pszText = _T("");
+ col.cx = 20;
+ ListView_InsertColumn(hwndList, 1, &col);
+
+ col.pszText = TranslateT("Plugin");
+ col.cx = 70;
+ ListView_InsertColumn(hwndList, 2, &col);
+
+ col.pszText = TranslateT("Name");
+ col.cx = 70;//max = 220;
+ ListView_InsertColumn(hwndList, 3, &col);
+
+ col.pszText = TranslateT("Version");
+ col.cx = 70;
+ ListView_InsertColumn(hwndList, 4, &col);
+
+ // XXX: Won't work on windows 95 without IE3+ or 4.70
+ ListView_SetExtendedListViewStyleEx( hwndList, 0, LVS_EX_SUBITEMIMAGES | LVS_EX_CHECKBOXES | LVS_EX_LABELTIP | LVS_EX_FULLROWSELECT );
+ // scan the plugin dir for plugins, cos
+ enumPlugins( dialogListPlugins, ( WPARAM )hwndDlg, ( LPARAM )hwndList );
+ // sort out the headers
+
+ ListView_SetColumnWidth( hwndList, 2, LVSCW_AUTOSIZE ); // dll name
+ int w = ListView_GetColumnWidth( hwndList, 2 );
+ if (w > 110) {
+ ListView_SetColumnWidth( hwndList, 2, 110 );
+ w = 110;
+ }
+ int max = w < 110 ? 199+110-w:199;
+ ListView_SetColumnWidth( hwndList, 3, LVSCW_AUTOSIZE ); // short name
+ w = ListView_GetColumnWidth( hwndList, 3 );
+ if (w > max)
+ ListView_SetColumnWidth( hwndList, 3, max );
+ }
+ return TRUE;
+
+ case WM_NOTIFY:
+ if ( lParam ) {
+ NMLISTVIEW * hdr = (NMLISTVIEW *) lParam;
+ if ( hdr->hdr.code == LVN_ITEMCHANGED && IsWindowVisible(hdr->hdr.hwndFrom)) {
+ if (hdr->uOldState != 0 && (hdr->uNewState == 0x1000 || hdr->uNewState == 0x2000 )) {
+ HWND hwndList = GetDlgItem(hwndDlg, IDC_PLUGLIST);
+
+ LVITEM it;
+ it.mask = LVIF_PARAM | LVIF_STATE;
+ it.iItem = hdr->iItem;
+ if ( !ListView_GetItem( hwndList, &it ))
+ break;
+
+ PluginListItemData* dat = ( PluginListItemData* )it.lParam;
+ if ( dat->flags == DEFMOD_DB ) {
+ ListView_SetItemState(hwndList, hdr->iItem, 0x3000, LVIS_STATEIMAGEMASK);
+ return FALSE;
+ }
+ // if enabling and replaces, find all other replaces and toggle off
+ if (( hdr->uNewState & 0x2000) && dat->flags != 0 ) {
+ for ( int iRow=0; iRow != -1; ) {
+ if ( iRow != hdr->iItem ) {
+ LVITEM dt;
+ dt.mask = LVIF_PARAM;
+ dt.iItem = iRow;
+ if ( ListView_GetItem( hwndList, &dt )) {
+ PluginListItemData* dat2 = ( PluginListItemData* )dt.lParam;
+ if ( dat2->flags == dat->flags ) {
+ // the lParam is unset, so when the check is unset the clist block doesnt trigger
+ int lParam = dat2->flags;
+ dat2->flags = 0;
+ ListView_SetItemState(hwndList, iRow, 0x1000, LVIS_STATEIMAGEMASK );
+ dat2->flags = lParam;
+ } } }
+
+ iRow = ListView_GetNextItem( hwndList, iRow, LVNI_ALL );
+ } }
+
+ ShowWindow( GetDlgItem(hwndDlg, IDC_RESTART ), TRUE );
+ SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 );
+ break;
+ }
+
+ if ( hdr->iItem != -1 ) {
+ TCHAR buf[1024];
+ int sel = hdr->uNewState & LVIS_SELECTED;
+ HWND hwndList = GetDlgItem(hwndDlg, IDC_PLUGLIST);
+ LVITEM lvi = { 0 };
+ lvi.mask = LVIF_PARAM;
+ lvi.iItem = hdr->iItem;
+ if ( ListView_GetItem( hwndList, &lvi )) {
+ PluginListItemData* dat = ( PluginListItemData* )lvi.lParam;
+
+ ListView_GetItemText(hwndList, hdr->iItem, 1, buf, SIZEOF(buf));
+ SetWindowText(GetDlgItem(hwndDlg, IDC_PLUGININFOFRAME), sel ? buf : _T(""));
+
+ SetWindowTextA(GetDlgItem(hwndDlg, IDC_PLUGINAUTHOR), sel ? dat->author : "" );
+ SetWindowTextA(GetDlgItem(hwndDlg, IDC_PLUGINEMAIL), sel ? dat->authorEmail : "" );
+ {
+ TCHAR* p = LangPackPcharToTchar( dat->description );
+ SetWindowText(GetDlgItem(hwndDlg, IDC_PLUGINLONGINFO), sel ? p : _T(""));
+ mir_free( p );
+ }
+ SetWindowTextA(GetDlgItem(hwndDlg, IDC_PLUGINCPYR), sel ? dat->copyright : "" );
+ SetWindowTextA(GetDlgItem(hwndDlg, IDC_PLUGINURL), sel ? dat->homepage : "" );
+ if (equalUUID(miid_last, dat->uuid))
+ SetWindowText(GetDlgItem(hwndDlg, IDC_PLUGINPID), sel ? TranslateT("<none>") : _T(""));
+ else {
+ char szUID[128];
+ uuidToString( dat->uuid, szUID, sizeof(szUID));
+ SetWindowTextA(GetDlgItem(hwndDlg, IDC_PLUGINPID), sel ? szUID : "" );
+ } } } }
+
+ if ( hdr->hdr.code == PSN_APPLY ) {
+ HWND hwndList = GetDlgItem(hwndDlg, IDC_PLUGLIST);
+ TCHAR buf[1024];
+ for (int iRow=0; iRow != -1; ) {
+ ListView_GetItemText(hwndList, iRow, 2, buf, SIZEOF(buf));
+ int iState = ListView_GetItemState(hwndList, iRow, LVIS_STATEIMAGEMASK);
+ SetPluginOnWhiteList(buf, (iState & 0x2000) ? 1 : 0);
+ iRow = ListView_GetNextItem(hwndList, iRow, LVNI_ALL);
+ } } }
+ break;
+
+ case WM_COMMAND:
+ if ( HIWORD(wParam) == STN_CLICKED ) {
+ switch (LOWORD(wParam)) {
+ case IDC_PLUGINEMAIL:
+ case IDC_PLUGINURL:
+ {
+ char buf[512];
+ char *p = &buf[7];
+ lstrcpyA(buf, "mailto:");
+ if ( GetWindowTextA(GetDlgItem(hwndDlg, LOWORD(wParam)), p, SIZEOF(buf) - 7))
+ CallService(MS_UTILS_OPENURL, 0, (LPARAM) (LOWORD(wParam) == IDC_PLUGINEMAIL ? buf : p) );
+ break;
+ }
+ case IDC_GETMOREPLUGINS:
+ CallService(MS_UTILS_OPENURL, 0, (LPARAM) "http://addons.miranda-im.org/index.php?action=display&id=1" );
+ break;
+ } }
+ break;
+
+ case WM_DESTROY:
+ RemoveAllItems( GetDlgItem( hwndDlg, IDC_PLUGLIST ));
+ break;
+ }
+ return FALSE;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+int PluginOptionsInit(WPARAM wParam, LPARAM)
+{
+ OPTIONSDIALOGPAGE odp = { 0 };
+ odp.cbSize = sizeof(odp);
+ odp.hInstance = hMirandaInst;
+ odp.pfnDlgProc = DlgPluginOpt;
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_PLUGINS);
+ odp.position = 1300000000;
+ odp.pszTitle = LPGEN("Plugins");
+ odp.flags = ODPF_BOLDGROUPS;
+ CallService( MS_OPT_ADDPAGE, wParam, ( LPARAM )&odp );
+ return 0;
+}
+
+void LoadPluginOptions()
+{
+ hevLoadModule = CreateHookableEvent(ME_SYSTEM_MODULELOAD);
+ hevUnloadModule = CreateHookableEvent(ME_SYSTEM_MODULEUNLOAD);
+}
+
+void UnloadPluginOptions()
+{
+ DestroyHookableEvent(hevLoadModule);
+ DestroyHookableEvent(hevUnloadModule);
+} \ No newline at end of file