summaryrefslogtreecommitdiff
path: root/Plugins/utils
diff options
context:
space:
mode:
Diffstat (limited to 'Plugins/utils')
-rw-r--r--Plugins/utils/ContactAsyncQueue.cpp222
-rw-r--r--Plugins/utils/ContactAsyncQueue.h93
-rw-r--r--Plugins/utils/mir_buffer.h452
-rw-r--r--Plugins/utils/mir_icons.cpp49
-rw-r--r--Plugins/utils/mir_icons.h33
-rw-r--r--Plugins/utils/mir_log.cpp133
-rw-r--r--Plugins/utils/mir_log.h41
-rw-r--r--Plugins/utils/mir_memory.cpp70
-rw-r--r--Plugins/utils/mir_memory.h68
-rw-r--r--Plugins/utils/mir_options.cpp541
-rw-r--r--Plugins/utils/mir_options.h68
11 files changed, 1770 insertions, 0 deletions
diff --git a/Plugins/utils/ContactAsyncQueue.cpp b/Plugins/utils/ContactAsyncQueue.cpp
new file mode 100644
index 0000000..7be4cfe
--- /dev/null
+++ b/Plugins/utils/ContactAsyncQueue.cpp
@@ -0,0 +1,222 @@
+/*
+Copyright (C) 2006 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 "ContactAsyncQueue.h"
+#include <process.h>
+
+
+// Itens with higher time at end
+static int QueueSortItems(const QueueItem *i1, const QueueItem *i2)
+{
+ return i1->check_time - i2->check_time;
+}
+
+// Itens with higher time at end
+static void ContactAsyncQueueThread(void *obj)
+{
+ ((ContactAsyncQueue *)obj)->Thread();
+}
+
+ContactAsyncQueue::ContactAsyncQueue(pfContactAsyncQueueCallback fContactAsyncQueueCallback, int initialSize)
+ : queue(30, QueueSortItems)
+{
+ hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+ finished = 0;
+ callback = fContactAsyncQueueCallback;
+
+ InitializeCriticalSection(&cs);
+
+ _beginthread(ContactAsyncQueueThread, 0, this);
+ //mir_forkthread(ContactAsyncQueueThread, this);
+}
+
+ContactAsyncQueue::~ContactAsyncQueue()
+{
+ if (finished == 0)
+ finished = 1;
+ SetEvent(hEvent);
+ int count = 0;
+ while(finished != 2 && ++count < 50)
+ Sleep(10);
+
+ for (int i = 0; i < queue.getCount(); i++)
+ if (queue[i] != NULL)
+ mir_free(queue[i]);
+
+ DeleteCriticalSection(&cs);
+}
+
+void ContactAsyncQueue::Lock()
+{
+ EnterCriticalSection(&cs);
+}
+
+void ContactAsyncQueue::Release()
+{
+ LeaveCriticalSection(&cs);
+}
+
+void ContactAsyncQueue::RemoveAll(HANDLE hContact)
+{
+ Lock();
+
+ for (int i = queue.getCount() - 1; i >= 0; --i)
+ {
+ QueueItem *item = queue[i];
+
+ if (item->hContact == hContact)
+ {
+ queue.remove(i);
+ mir_free(item);
+ }
+ }
+
+ Release();
+}
+
+void ContactAsyncQueue::RemoveAllConsiderParam(HANDLE hContact, void *param)
+{
+ Lock();
+
+ for (int i = queue.getCount() - 1; i >= 0; --i)
+ {
+ QueueItem *item = queue[i];
+
+ if (item->hContact == hContact && item->param == param)
+ {
+ queue.remove(i);
+ mir_free(item);
+ }
+ }
+
+ Release();
+}
+
+void ContactAsyncQueue::Add(int waitTime, HANDLE hContact, void *param)
+{
+ Lock();
+
+ InternalAdd(waitTime, hContact, param);
+
+ Release();
+}
+
+void ContactAsyncQueue::AddIfDontHave(int waitTime, HANDLE hContact, void *param)
+{
+ Lock();
+
+ int i;
+ for (i = queue.getCount() - 1; i >= 0; --i)
+ if (queue[i]->hContact == hContact)
+ break;
+
+ if (i < 0)
+ InternalAdd(waitTime, hContact, param);
+
+ Release();
+}
+
+void ContactAsyncQueue::AddAndRemovePrevious(int waitTime, HANDLE hContact, void *param)
+{
+ Lock();
+
+ RemoveAll(hContact);
+ InternalAdd(waitTime, hContact, param);
+
+ Release();
+}
+
+void ContactAsyncQueue::AddAndRemovePreviousConsiderParam(int waitTime, HANDLE hContact, void *param)
+{
+ Lock();
+
+ RemoveAllConsiderParam(hContact, param);
+ InternalAdd(waitTime, hContact, param);
+
+ Release();
+}
+
+void ContactAsyncQueue::InternalAdd(int waitTime, HANDLE hContact, void *param)
+{
+ QueueItem *item = (QueueItem *) mir_alloc(sizeof(QueueItem));
+ item->hContact = hContact;
+ item->check_time = GetTickCount() + waitTime;
+ item->param = param;
+
+ queue.insert(item);
+
+ SetEvent(hEvent);
+}
+
+void ContactAsyncQueue::Thread()
+{
+ while (!finished)
+ {
+ ResetEvent(hEvent);
+
+ Lock();
+
+ if (queue.getCount() <= 0)
+ {
+ // No items, so supend thread
+ Release();
+
+ wait(/*INFINITE*/ 2 * 60 * 1000);
+ }
+ else
+ {
+ // Take a look at first item
+ QueueItem *qi = queue[0];
+
+ int dt = qi->check_time - GetTickCount();
+ if (dt > 0)
+ {
+ // Not time to request yet, wait...
+ Release();
+
+ wait(dt);
+ }
+ else
+ {
+ // Will request this item
+ queue.remove(0);
+
+ Release();
+
+ callback(qi->hContact, qi->param);
+
+ mir_free(qi);
+ }
+ }
+ }
+
+ finished = 2;
+}
+
+void ContactAsyncQueue::wait(int time)
+{
+ if (!finished)
+ WaitForSingleObject(hEvent, time);
+}
+
+
+
+
+
+
diff --git a/Plugins/utils/ContactAsyncQueue.h b/Plugins/utils/ContactAsyncQueue.h
new file mode 100644
index 0000000..a19ba04
--- /dev/null
+++ b/Plugins/utils/ContactAsyncQueue.h
@@ -0,0 +1,93 @@
+/*
+Copyright (C) 2006 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.
+*/
+
+
+#ifndef __CONTACTASYNCQUEUE_H__
+# define __CONTACTASYNCQUEUE_H__
+
+#ifndef MIRANDA_VER
+#define MIRANDA_VER 0x0700
+#endif
+
+#include <windows.h>
+#include <newpluginapi.h>
+#include <m_system_cpp.h>
+
+
+typedef void (*pfContactAsyncQueueCallback) (HANDLE hContact, void *param);
+
+
+struct QueueItem
+{
+ DWORD check_time;
+ HANDLE hContact;
+ void *param;
+};
+
+
+class ContactAsyncQueue
+{
+public:
+
+ ContactAsyncQueue(pfContactAsyncQueueCallback fContactAsyncQueueCallback, int initialSize = 10);
+ ~ContactAsyncQueue();
+
+ inline int Size() const { return queue.getCount(); }
+ inline int Remove(int idx) { mir_free(queue[idx]); return queue.remove(idx); }
+ inline QueueItem* Get(int idx) const { return queue[idx]; }
+
+
+ void RemoveAll(HANDLE hContact);
+ void RemoveAllConsiderParam(HANDLE hContact, void *param);
+ void Add(int waitTime, HANDLE hContact, void *param = NULL);
+ void AddIfDontHave(int waitTime, HANDLE hContact, void *param = NULL);
+ void AddAndRemovePrevious(int waitTime, HANDLE hContact, void *param = NULL);
+ void AddAndRemovePreviousConsiderParam(int waitTime, HANDLE hContact, void *param = NULL);
+
+ void Lock();
+ void Release();
+
+
+ void Thread();
+
+private:
+
+ LIST<QueueItem> queue;
+
+ CRITICAL_SECTION cs;
+ pfContactAsyncQueueCallback callback;
+ HANDLE hEvent;
+ int finished;
+
+
+ void InternalAdd(int waitTime, HANDLE hContact, void *param);
+ void wait(int time);
+};
+
+
+
+
+
+
+
+
+
+
+
+#endif // __CONTACTASYNCQUEUE_H__
diff --git a/Plugins/utils/mir_buffer.h b/Plugins/utils/mir_buffer.h
new file mode 100644
index 0000000..f72da9e
--- /dev/null
+++ b/Plugins/utils/mir_buffer.h
@@ -0,0 +1,452 @@
+/*
+Copyright (C) 2005 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.
+*/
+
+
+#ifndef __MIR_BUFFER_H__
+# define __MIR_BUFFER_H__
+
+#include <windows.h>
+
+#include "mir_memory.h"
+#include <m_variables.h>
+
+
+template<class T>
+static int __bvsnprintf(T *str, size_t size, const T *fmt, va_list args)
+{
+ return 0;
+}
+
+template<>
+static inline int __bvsnprintf<char>(char *str, size_t size, const char *fmt, va_list args)
+{
+ return _vsnprintf(str, size, fmt, args);
+}
+
+template<>
+static inline int __bvsnprintf<wchar_t>(wchar_t *str, size_t size, const wchar_t *fmt, va_list args)
+{
+ return _vsnwprintf(str, size, fmt, args);
+}
+
+template<class T>
+static inline int __blen(const T *str)
+{
+ return 0;
+}
+
+template<>
+static inline int __blen<char>(const char *str)
+{
+ return strlen(str);
+}
+
+template<>
+static inline int __blen<wchar_t>(const wchar_t *str)
+{
+ return lstrlenW(str);
+}
+
+template<class T>
+static inline T * __bTranslate(const T *str)
+{
+ return 0;
+}
+
+template<>
+static inline char * __bTranslate<char>(const char *str)
+{
+ return Translate(str);
+}
+
+template<>
+static inline wchar_t * __bTranslate<wchar_t>(const wchar_t *str)
+{
+ return TranslateW(str);
+}
+
+
+template<class O, class D>
+static void __bcopy(D *dest, const O *orig, size_t len)
+{
+}
+
+template<>
+static void __bcopy(char *dest, const char *orig, size_t len)
+{
+ strncpy(dest, orig, len);
+}
+
+template<>
+static void __bcopy(WCHAR *dest, const WCHAR *orig, size_t len)
+{
+ wcsncpy(dest, orig, len);
+}
+
+template<>
+static void __bcopy(WCHAR *dest, const char *orig, size_t len)
+{
+ MultiByteToWideChar(CallService("LangPack/GetCodePage", 0, 0), 0, orig, len, dest, len);
+}
+
+template<>
+static void __bcopy(char *dest, const WCHAR *orig, size_t len)
+{
+ WideCharToMultiByte(CallService("LangPack/GetCodePage", 0, 0), 0, orig, len, dest, len, NULL, NULL);
+}
+
+
+
+template<class T>
+class Buffer
+{
+ public:
+ size_t len;
+ T *str;
+
+ Buffer() : len(0), str(NULL), size(0) {}
+
+ Buffer(T in)
+ {
+ str = in;
+ size = len = __blen(in);
+ }
+
+ ~Buffer()
+ {
+ free();
+ }
+
+ void pack()
+ {
+ if (str != NULL)
+ str[len] = 0;
+ }
+
+ void alloc(size_t total)
+ {
+ if (total > size)
+ {
+ size = total + 256 - total % 256;
+ if (str == NULL)
+ str = (T *) mir_alloc(size * sizeof(T));
+ else
+ str = (T *) mir_realloc(str, size * sizeof(T));
+ }
+ }
+
+ void free()
+ {
+ if (str != NULL)
+ {
+ mir_free(str);
+ str = NULL;
+ len = size = 0;
+ }
+ }
+
+ void clear()
+ {
+ len = 0;
+ }
+
+ void append(T app)
+ {
+ alloc(len + 1);
+
+ str[len] = app;
+ len++;
+ }
+
+ void append(const char *app, size_t appLen = -1)
+ {
+ if (appLen == -1)
+ appLen = __blen(app);
+
+ size_t total = len + appLen + 1;
+ alloc(total);
+
+ __bcopy(&str[len], app, appLen);
+ len += appLen;
+ }
+
+ void append(const WCHAR *app, size_t appLen = -1)
+ {
+ if (appLen == -1)
+ appLen = __blen(app);
+
+ size_t total = len + appLen + 1;
+ alloc(total);
+
+ __bcopy(&str[len], app, appLen);
+ len += appLen;
+ }
+
+ void appendPrintf(const T *app, ...)
+ {
+ size_t total = len + 512;
+ alloc(total);
+
+ va_list arg;
+ va_start(arg, app);
+ total = __bvsnprintf<T>(&str[len], size - len - 1, app, arg);
+ if (total < 0)
+ total = size - len - 1;
+ len += total;
+ }
+
+ void insert(size_t pos, T *app, size_t appLen = -1)
+ {
+ if (pos > len)
+ pos = len;
+ if (pos < 0)
+ pos = 0;
+
+ if (appLen == -1)
+ appLen = __blen(app);
+
+ alloc(len + appLen + 1);
+
+ if (pos < len)
+ memmove(&str[pos + appLen], &str[pos], (len - pos) * sizeof(T));
+ memmove(&str[pos], app, appLen * sizeof(T));
+
+ len += appLen;
+ }
+
+ void replace(size_t start, size_t end, T *app, size_t appLen = -1)
+ {
+ if (start > len)
+ start = len;
+ if (start < 0)
+ start = 0;
+
+ if (end > len)
+ end = len;
+ if (end < start)
+ end = start;
+
+ if (appLen == -1)
+ appLen = __blen(app);
+
+ size_t oldLen = end - start;
+ if (oldLen < appLen)
+ alloc(len + appLen - oldLen + 1);
+
+ if (end < len && oldLen != appLen)
+ memmove(&str[start + appLen], &str[end], (len - end) * sizeof(T));
+ memmove(&str[start], app, appLen * sizeof(T));
+
+ len += appLen - oldLen;
+ }
+
+ void translate()
+ {
+ if (str == NULL || len == 0)
+ return;
+
+ str[len] = 0;
+ T *tmp = __bTranslate(str);
+ len = __blen(tmp);
+ alloc(len + 1);
+ memmove(str, tmp, len * sizeof(T));
+ }
+
+ T *appender(size_t appLen)
+ {
+ alloc(len + appLen + 1);
+ T *ret = &str[len];
+ len += appLen;
+ return ret;
+ }
+
+ T *lock(size_t maxSize)
+ {
+ alloc(len + maxSize + 1);
+ return &str[len];
+ }
+
+ void release()
+ {
+ len += max(__blen(&str[len]), size - len - 1);
+ }
+
+ T *detach()
+ {
+ T *ret = str;
+ str = NULL;
+ len = 0;
+ return ret;
+ }
+
+ void trimRight()
+ {
+ if (str == NULL)
+ return;
+
+ int e;
+ for(e = len-1; e >= 0 && (str[e] == (T)' '
+ || str[e] == (T)'\t'
+ || str[e] == (T)'\r'
+ || str[e] == (T)'\n'); e--) ;
+ len = e+1;
+ }
+
+ void trimLeft()
+ {
+ if (str == NULL)
+ return;
+
+ int s;
+ for(s = 0; str[s] == (T)' '
+ || str[s] == (T)'\t'
+ || str[s] == (T)'\r'
+ || str[s] == (T)'\n'; s++) ;
+ if (s > 0)
+ {
+ memmove(str, &str[s], (len - s) * sizeof(T));
+ len -= s;
+ }
+ }
+
+ void trim()
+ {
+ trimRight();
+ trimLeft();
+ }
+
+ Buffer<T>& operator+=(const char *txt)
+ {
+ append(txt);
+ return *this;
+ }
+
+ Buffer<T>& operator+=(const WCHAR *txt)
+ {
+ append(txt);
+ return *this;
+ }
+
+
+ private:
+ size_t size;
+};
+
+
+static void ReplaceVars(Buffer<TCHAR> *buffer, HANDLE hContact, TCHAR **variables, int numVariables)
+{
+ if (buffer->len < 3)
+ return;
+
+ if (numVariables <= 0)
+ return;
+
+ for(size_t i = buffer->len - 1; i > 0; i--)
+ {
+ if (buffer->str[i] == _T('%'))
+ {
+ // Find previous
+ size_t j;
+ for(j = i - 1; j > 0 && ((buffer->str[j] >= _T('a') && buffer->str[j] <= _T('z'))
+ || (buffer->str[j] >= _T('A') && buffer->str[j] <= _T('Z'))
+ || buffer->str[j] == _T('-')
+ || buffer->str[j] == _T('_')); j--) ;
+
+ if (buffer->str[j] == _T('%'))
+ {
+ size_t foundLen = i - j + 1;
+ if (foundLen == 9 && _tcsncmp(&buffer->str[j], _T("%contact%"), 9) == 0)
+ {
+ buffer->replace(j, i + 1, (TCHAR *) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM) hContact, GCDNF_TCHAR));
+ }
+ else if (foundLen == 6 && _tcsncmp(&buffer->str[j], _T("%date%"), 6) == 0)
+ {
+ TCHAR tmp[128];
+ DBTIMETOSTRINGT tst = {0};
+ tst.szFormat = _T("d s");
+ tst.szDest = tmp;
+ tst.cbDest = 128;
+ CallService(MS_DB_TIME_TIMESTAMPTOSTRINGT, (WPARAM) time(NULL), (LPARAM) &tst);
+ buffer->replace(j, i + 1, tmp);
+ }
+ else
+ {
+ for(int k = 0; k < numVariables; k += 2)
+ {
+ size_t len = lstrlen(variables[k]);
+ if (foundLen == len + 2 && _tcsncmp(&buffer->str[j]+1, variables[k], len) == 0)
+ {
+ buffer->replace(j, i + 1, variables[k + 1]);
+ break;
+ }
+ }
+ }
+ }
+
+ i = j;
+ if (i == 0)
+ break;
+ }
+ else if (buffer->str[i] == _T('\\') && i+1 <= buffer->len-1 && buffer->str[i+1] == _T('n'))
+ {
+ buffer->str[i] = _T('\r');
+ buffer->str[i+1] = _T('\n');
+ }
+ }
+}
+
+
+static void ReplaceTemplate(Buffer<TCHAR> *out, HANDLE hContact, TCHAR *templ, TCHAR **vars, int numVars)
+{
+ if (ServiceExists(MS_VARS_FORMATSTRING_EX))
+ {
+ TCHAR *tmp = variables_parse_ex(templ, NULL, hContact, vars, numVars);
+ if (tmp != NULL)
+ {
+ out->append(tmp);
+ variables_free(tmp);
+ out->pack();
+ return;
+ }
+ }
+
+ if (ServiceExists(MS_VARS_FORMATSTRING))
+ {
+ out->append(templ);
+ ReplaceVars(out, hContact, vars, numVars);
+ out->pack();
+
+ TCHAR *tmp = variables_parse(out->str, NULL, hContact);
+ if (tmp != NULL)
+ {
+ out->clear();
+ out->append(tmp);
+ variables_free(tmp);
+ out->pack();
+ return;
+ }
+ }
+
+ out->append(templ);
+ ReplaceVars(out, hContact, vars, numVars);
+ out->pack();
+}
+
+
+#endif // __MIR_BUFFER_H__
diff --git a/Plugins/utils/mir_icons.cpp b/Plugins/utils/mir_icons.cpp
new file mode 100644
index 0000000..1ee7999
--- /dev/null
+++ b/Plugins/utils/mir_icons.cpp
@@ -0,0 +1,49 @@
+/*
+Copyright (C) 2007 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 "mir_icons.h"
+
+#include <newpluginapi.h>
+#include <m_system.h>
+#include <m_icolib.h>
+
+
+HICON LoadIconEx(const char *iconName, BOOL copy)
+{
+ if (!ServiceExists(MS_SKIN2_GETICON))
+ return NULL;
+
+ HICON hIcon = (HICON) CallService(MS_SKIN2_GETICON, 0, (LPARAM) iconName);
+ if (copy)
+ {
+ hIcon = CopyIcon(hIcon);
+ CallService(MS_SKIN2_RELEASEICON, 0, (LPARAM) iconName);
+ }
+ return hIcon;
+}
+
+
+void ReleaseIconEx(HICON hIcon)
+{
+ if (ServiceExists(MS_SKIN2_RELEASEICON))
+ CallService(MS_SKIN2_RELEASEICON, (WPARAM) hIcon, 0);
+ else
+ DestroyIcon(hIcon);
+}
diff --git a/Plugins/utils/mir_icons.h b/Plugins/utils/mir_icons.h
new file mode 100644
index 0000000..c61c7c6
--- /dev/null
+++ b/Plugins/utils/mir_icons.h
@@ -0,0 +1,33 @@
+/*
+Copyright (C) 2005 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.
+*/
+
+
+#ifndef __MIR_ICONS_H__
+# define __MIR_ICONS_H__
+
+#include <windows.h>
+
+
+HICON LoadIconEx(const char *iconName, BOOL copy = FALSE);
+void ReleaseIconEx(HICON hIcon);
+
+
+
+
+#endif // __MIR_MEMORY_H__
diff --git a/Plugins/utils/mir_log.cpp b/Plugins/utils/mir_log.cpp
new file mode 100644
index 0000000..b842bb1
--- /dev/null
+++ b/Plugins/utils/mir_log.cpp
@@ -0,0 +1,133 @@
+/*
+Copyright (C) 2005 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 "mir_log.h"
+
+#include <stdio.h>
+
+extern "C"
+{
+#include <newpluginapi.h>
+#include <m_netlib.h>
+#include <m_protocols.h>
+#include <m_clist.h>
+}
+
+
+int mlog(const char *module, const char *function, const char *fmt, ...)
+{
+#ifdef ENABLE_LOG
+
+ va_list va;
+ char text[1024];
+ size_t len;
+
+ mir_snprintf(text, sizeof(text) - 10, "[%08u - %08u] [%s] [%s] ",
+ GetCurrentThreadId(), GetTickCount(), module, function);
+ len = strlen(text);
+
+ va_start(va, fmt);
+ mir_vsnprintf(&text[len], sizeof(text) - len, fmt, va);
+ va_end(va);
+
+#ifdef LOG_TO_NETLIB
+
+ return CallService(MS_NETLIB_LOG, NULL, (LPARAM) text);
+
+#else
+ char file[256];
+ _snprintf(file, sizeof(file), "c:\\miranda_%s.log.txt", module);
+
+ FILE *fp = fopen(file,"at");
+
+ if (fp != NULL)
+ {
+ fprintf(fp, "%s\n", text);
+ fclose(fp);
+ return 0;
+ }
+ else
+ {
+ return -1;
+ }
+
+#endif
+
+#else
+
+ return 0;
+
+#endif
+}
+
+int mlogC(const char *module, const char *function, HANDLE hContact, const char *fmt, ...)
+{
+#ifdef ENABLE_LOG
+
+ va_list va;
+ char text[1024];
+ size_t len;
+
+ char *name = NULL;
+ char *proto = NULL;
+ if (hContact != NULL)
+ {
+ name = (char*) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, 0);
+ proto = (char*) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
+ }
+
+ mir_snprintf(text, sizeof(text) - 10, "[%08u - %08u] [%s] [%s] [%08d - %s - %s] ",
+ GetCurrentThreadId(), GetTickCount(), module, function,
+ hContact, proto == NULL ? "" : proto, name == NULL ? "" : name);
+ len = strlen(text);
+
+ va_start(va, fmt);
+ mir_vsnprintf(&text[len], sizeof(text) - len, fmt, va);
+ va_end(va);
+
+#ifdef LOG_TO_NETLIB
+
+ return CallService(MS_NETLIB_LOG, NULL, (LPARAM) text);
+
+#else
+ char file[256];
+ _snprintf(file, sizeof(file), "c:\\miranda_%s.log.txt", module);
+
+ FILE *fp = fopen(file,"at");
+
+ if (fp != NULL)
+ {
+ fprintf(fp, "%s\n", text);
+ fclose(fp);
+ return 0;
+ }
+ else
+ {
+ return -1;
+ }
+
+#endif
+
+#else
+
+ return 0;
+
+#endif
+}
diff --git a/Plugins/utils/mir_log.h b/Plugins/utils/mir_log.h
new file mode 100644
index 0000000..395c7e1
--- /dev/null
+++ b/Plugins/utils/mir_log.h
@@ -0,0 +1,41 @@
+/*
+Copyright (C) 2005 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.
+*/
+
+
+#ifndef __LOG_H__
+# define __LOG_H__
+
+#include <windows.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+int mlog(const char *module, const char *function, const char *fmt, ...);
+int mlogC(const char *module, const char *function, HANDLE hContact, const char *fmt, ...);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __LOG_H__
diff --git a/Plugins/utils/mir_memory.cpp b/Plugins/utils/mir_memory.cpp
new file mode 100644
index 0000000..cea960b
--- /dev/null
+++ b/Plugins/utils/mir_memory.cpp
@@ -0,0 +1,70 @@
+/*
+Copyright (C) 2005 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 "mir_memory.h"
+
+#define MIRANDA_VER 0x0700
+#include <newpluginapi.h>
+#include <m_system.h>
+
+
+struct MM_INTERFACE mmi;
+struct UTF8_INTERFACE utfi;
+
+void init_mir_malloc()
+{
+ mir_getMMI(&mmi);
+ mir_getUTFI(&utfi);
+}
+
+
+void * mir_alloc0(size_t size)
+{
+ void * ptr = mir_alloc(size);
+
+ if (ptr != NULL)
+ memset(ptr, 0, size);
+
+ return ptr;
+}
+
+int strcmpnull(char *str1, char *str2)
+{
+ if ( str1 == NULL && str2 == NULL )
+ return 0;
+ if ( str1 != NULL && str2 == NULL )
+ return 1;
+ if ( str1 == NULL && str2 != NULL )
+ return -1;
+
+ return strcmp(str1, str2);
+}
+
+int strcmpnullW(WCHAR *str1, WCHAR *str2)
+{
+ if ( str1 == NULL && str2 == NULL )
+ return 0;
+ if ( str1 != NULL && str2 == NULL )
+ return 1;
+ if ( str1 == NULL && str2 != NULL )
+ return -1;
+
+ return lstrcmpW(str1, str2);
+}
diff --git a/Plugins/utils/mir_memory.h b/Plugins/utils/mir_memory.h
new file mode 100644
index 0000000..ef2a0d4
--- /dev/null
+++ b/Plugins/utils/mir_memory.h
@@ -0,0 +1,68 @@
+/*
+Copyright (C) 2005 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.
+*/
+
+
+#ifndef __MIR_MEMORY_H__
+# define __MIR_MEMORY_H__
+
+#include <windows.h>
+
+
+// Need to be called on ME_SYSTEM_MODULESLOADED or Load
+void init_mir_malloc();
+
+
+void * mir_alloc0(size_t size);
+int strcmpnull(char *str1, char *str2);
+int strcmpnullW(WCHAR *str1, WCHAR *str2);
+
+
+#ifdef _UNICODE
+
+# define lstrcmpnull strcmpnullW
+
+#define INPLACE_CHAR_TO_TCHAR(_new_var_, _size_, _old_var_) \
+ TCHAR _new_var_[_size_]; \
+ MultiByteToWideChar(CP_ACP, 0, _old_var_, -1, _new_var_, _size_)
+
+
+#define INPLACE_TCHAR_TO_CHAR(_new_var_, _size_, _old_var_) \
+ char _new_var_[_size_]; \
+ WideCharToMultiByte(CP_ACP, 0, _old_var_, -1, _new_var_, _size_, NULL, NULL);
+
+#else
+
+# define lstrcmpnull strcmpnull
+
+#define INPLACE_CHAR_TO_TCHAR(_new_var_, _size_, _old_var_) \
+ TCHAR *_new_var_ = _old_var_
+
+#define INPLACE_TCHAR_TO_CHAR(_new_var_, _size_, _old_var_) \
+ char *_new_var_ = _old_var_;
+
+#endif
+
+
+
+// Free memory and set to NULL
+//#define MIR_FREE(_x_) if (_x_ != NULL) { mir_free(_x_); _x_ = NULL; }
+
+
+
+#endif // __MIR_MEMORY_H__
diff --git a/Plugins/utils/mir_options.cpp b/Plugins/utils/mir_options.cpp
new file mode 100644
index 0000000..bf4e3f0
--- /dev/null
+++ b/Plugins/utils/mir_options.cpp
@@ -0,0 +1,541 @@
+/*
+Copyright (C) 2005 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 "mir_options.h"
+#include "mir_memory.h"
+
+#include <commctrl.h>
+#include <stdio.h>
+#include <tchar.h>
+
+#define MIRANDA_VER 0x0600
+#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>
+
+
+#define MAX_REGS(_A_) ( sizeof(_A_) / sizeof(_A_[0]) )
+
+
+static TCHAR* MyDBGetContactSettingTString(HANDLE hContact, char* module, char* setting, TCHAR* out, size_t len, TCHAR *def)
+{
+ DBVARIANT dbv;
+
+ out[0] = _T('\0');
+
+ if (!DBGetContactSettingTString(hContact, module, setting, &dbv))
+ {
+#ifdef UNICODE
+ if (dbv.type == DBVT_ASCIIZ)
+ {
+ MultiByteToWideChar(CP_ACP, 0, dbv.pszVal, -1, out, len);
+ }
+ else if (dbv.type == DBVT_UTF8)
+ {
+ MultiByteToWideChar(CP_UTF8, 0, dbv.pszVal, -1, out, len);
+ }
+ else if (dbv.type == DBVT_WCHAR)
+ {
+ lstrcpyn(out, dbv.pwszVal, len);
+ }
+#else
+ if (dbv.type == DBVT_ASCIIZ)
+ {
+ lstrcpyn(out, dbv.pszVal, len);
+ }
+#endif
+ else
+ {
+ if (def != NULL)
+ lstrcpyn(out, def, len);
+ }
+
+ DBFreeVariant(&dbv);
+ }
+ else
+ {
+ if (def != NULL)
+ lstrcpyn(out, def, len);
+ }
+
+ return out;
+}
+
+
+static TCHAR dbPath[MAX_PATH] = {0}; // database profile path (read at startup only)
+
+
+static int PathIsAbsolute(const TCHAR *path)
+{
+ if (!path || !(lstrlen(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))
+ {
+ lstrcpyn(pOut, pSrc, outSize);
+ }
+ else
+ {
+ if (dbPath[0] == _T('\0'))
+ {
+ char tmp[1024];
+ CallService(MS_DB_GETPROFILEPATH, MAX_REGS(tmp), (LPARAM) tmp);
+ mir_sntprintf(dbPath, MAX_REGS(dbPath), _T(TCHAR_STR_PARAM) _T("\\"), tmp);
+ }
+
+ size_t len = lstrlen(dbPath);
+ if (_tcsnicmp(pSrc, dbPath, len))
+ {
+ mir_sntprintf(pOut, outSize, _T("%s"), pSrc + len);
+ }
+ else
+ {
+ lstrcpyn(pOut, pSrc, outSize);
+ }
+ }
+}
+
+static void PathToAbsolute(TCHAR *pOut, size_t outSize, const TCHAR *pSrc)
+{
+ if (PathIsAbsolute(pSrc) || !isalnum(pSrc[0]))
+ {
+ lstrcpyn(pOut, pSrc, outSize);
+ }
+ else
+ {
+ if (dbPath[0] == _T('\0'))
+ {
+ char tmp[1024];
+ CallService(MS_DB_GETPROFILEPATH, MAX_REGS(tmp), (LPARAM) tmp);
+ mir_sntprintf(dbPath, MAX_REGS(dbPath), _T(TCHAR_STR_PARAM) _T("\\"), tmp);
+ }
+
+ mir_sntprintf(pOut, outSize, _T("%s%s"), dbPath, pSrc);
+ }
+}
+
+
+void LoadOpts(OptPageControl *controls, int controlsSize, char *module)
+{
+ for (int i = 0 ; i < controlsSize ; i++)
+ {
+ OptPageControl *ctrl = &controls[i];
+
+ if (ctrl->var != NULL)
+ {
+ switch(ctrl->type)
+ {
+ case CONTROL_CHECKBOX:
+ {
+ *((BYTE *) ctrl->var) = DBGetContactSettingByte(NULL, module, ctrl->setting, ctrl->dwDefValue);
+ break;
+ }
+ case CONTROL_SPIN:
+ {
+ *((WORD *) ctrl->var) = DBGetContactSettingWord(NULL, module, ctrl->setting, ctrl->dwDefValue);
+ break;
+ }
+ case CONTROL_COLOR:
+ {
+ *((COLORREF *) ctrl->var) = (COLORREF) DBGetContactSettingDword(NULL, module, ctrl->setting, ctrl->dwDefValue);
+ break;
+ }
+ case CONTROL_RADIO:
+ {
+ *((WORD *) ctrl->var) = DBGetContactSettingWord(NULL, module, ctrl->setting, ctrl->dwDefValue);
+ break;
+ }
+ case CONTROL_COMBO:
+ {
+ *((WORD *) ctrl->var) = DBGetContactSettingWord(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_FILE:
+ {
+ TCHAR tmp[1024];
+ 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;
+ }
+ }
+ }
+ }
+}
+
+
+
+BOOL CALLBACK SaveOptsDlgProc(OptPageControl *controls, int controlsSize, char *module, HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ 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, DBGetContactSettingByte(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(DBGetContactSettingWord(NULL, module, ctrl->setting, ctrl->dwDefValue), 0));
+ break;
+ }
+ case CONTROL_COLOR:
+ {
+ SendDlgItemMessage(hwndDlg, ctrl->nID, CPM_SETCOLOUR, 0, (COLORREF) DBGetContactSettingDword(NULL, module, ctrl->setting, ctrl->dwDefValue));
+ break;
+ }
+ case CONTROL_RADIO:
+ {
+ CheckDlgButton(hwndDlg, ctrl->nID, DBGetContactSettingWord(NULL, module, ctrl->setting, ctrl->dwDefValue) == ctrl->value ? BST_CHECKED : BST_UNCHECKED);
+ break;
+ }
+ case CONTROL_COMBO:
+ {
+ SendDlgItemMessage(hwndDlg, ctrl->nID, CB_SETCURSEL, DBGetContactSettingWord(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;
+ PROTOCOLDESCRIPTOR **protos;
+ int i,count;
+ char szName[128];
+
+ ListView_SetExtendedListViewStyle(hwndProtocols, LVS_EX_CHECKBOXES);
+
+ ZeroMemory(&lvc, sizeof(lvc));
+ lvc.mask = LVCF_FMT;
+ lvc.fmt = LVCFMT_IMAGE | LVCFMT_LEFT;
+ ListView_InsertColumn(hwndProtocols, 0, &lvc);
+
+ ZeroMemory(&lvi, sizeof(lvi));
+ lvi.mask = LVIF_TEXT | LVIF_PARAM;
+ lvi.iSubItem = 0;
+ lvi.iItem = 1000;
+
+ CallService(MS_PROTO_ENUMPROTOCOLS, (WPARAM)&count, (LPARAM)&protos);
+
+ for (i = 0; i < count; i++)
+ {
+ if (protos[i]->type != PROTOTYPE_PROTOCOL)
+ continue;
+
+ if (protos[i]->szName == NULL || protos[i]->szName[0] == '\0')
+ continue;
+
+ if (ctrl->allowProtocol != NULL && !ctrl->allowProtocol(protos[i]->szName))
+ continue;
+
+ CallProtoService(protos[i]->szName, PS_GETNAME, sizeof(szName), (LPARAM)szName);
+
+ char *setting = (char *) mir_alloc0(128 * sizeof(char));
+ mir_snprintf(setting, 128, ctrl->setting, protos[i]->szName);
+
+ BOOL show = (BOOL)DBGetContactSettingByte(NULL, module, setting, ctrl->dwDefValue);
+
+ lvi.lParam = (LPARAM)setting;
+#ifdef UNICODE
+ WCHAR szwName[128];
+ MultiByteToWideChar(CP_ACP, 0, szName, -1, szwName, 128);
+ lvi.pszText = TranslateTS(szwName);
+#else
+ lvi.pszText = TranslateTS(szName);
+#endif
+ 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:
+ {
+ TCHAR tmp[1024];
+ 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_FILE:
+ {
+ TCHAR tmp[1024];
+ 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:
+ {
+ TCHAR tmp[1024];
+ 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:
+ {
+ TCHAR tmp[1024];
+ 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 i;
+ for(i = 0; i < count; i++)
+ {
+ TCHAR *id = (TCHAR *) SendDlgItemMessage(hwndDlg, ctrl->nID, CB_GETITEMDATA, (WPARAM) i, 0);
+ if (lstrcmp(id, tmp) == 0)
+ break;
+ }
+ if (i < count)
+ SendDlgItemMessage(hwndDlg, ctrl->nID, CB_SETCURSEL, i, 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:
+ {
+ // 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:
+ {
+ DBWriteContactSettingByte(NULL, module, ctrl->setting, (BYTE) IsDlgButtonChecked(hwndDlg, ctrl->nID));
+ break;
+ }
+ case CONTROL_SPIN:
+ {
+ DBWriteContactSettingWord(NULL, module, ctrl->setting, (WORD) SendDlgItemMessage(hwndDlg, ctrl->nIDSpin, UDM_GETPOS, 0, 0));
+ break;
+ }
+ case CONTROL_COLOR:
+ {
+ DBWriteContactSettingDword(NULL, module, ctrl->setting, (DWORD) SendDlgItemMessage(hwndDlg, ctrl->nID, CPM_GETCOLOUR, 0, 0));
+ break;
+ }
+ case CONTROL_RADIO:
+ {
+ if (IsDlgButtonChecked(hwndDlg, ctrl->nID))
+ DBWriteContactSettingWord(NULL, module, ctrl->setting, (BYTE) ctrl->value);
+ break;
+ }
+ case CONTROL_COMBO:
+ {
+ DBWriteContactSettingWord(NULL, module, ctrl->setting, (WORD) SendDlgItemMessage(hwndDlg, ctrl->nID, CB_GETCURSEL, 0, 0));
+ break;
+ }
+ case CONTROL_PROTOCOL_LIST:
+ {
+ LVITEM lvi = {0};
+ HWND hwndProtocols = GetDlgItem(hwndDlg, ctrl->nID);
+ int i;
+
+ lvi.mask = (UINT) LVIF_PARAM;
+
+ for (i = 0; i < ListView_GetItemCount(hwndProtocols); i++)
+ {
+ lvi.iItem = i;
+ ListView_GetItem(hwndProtocols, &lvi);
+
+ char *setting = (char *)lvi.lParam;
+ DBWriteContactSettingByte(NULL, module, setting, (BYTE)ListView_GetCheckState(hwndProtocols, i));
+ }
+ break;
+ }
+ case CONTROL_TEXT:
+ {
+ TCHAR tmp[1024];
+ GetDlgItemText(hwndDlg, ctrl->nID, tmp, 1024);
+ DBWriteContactSettingTString(NULL, module, ctrl->setting, tmp);
+ break;
+ }
+ case CONTROL_FILE:
+ {
+ TCHAR tmp[1024];
+ GetDlgItemText(hwndDlg, ctrl->nID, tmp, 1024);
+ TCHAR rel[1024];
+ PathToRelative(rel, 1024, tmp);
+ DBWriteContactSettingTString(NULL, module, ctrl->setting, rel);
+ break;
+ }
+ case CONTROL_COMBO_TEXT:
+ {
+ TCHAR tmp[1024];
+ GetDlgItemText(hwndDlg, ctrl->nID, tmp, 1024);
+ DBWriteContactSettingTString(NULL, module, ctrl->setting, tmp);
+ break;
+ }
+ case CONTROL_COMBO_ITEMDATA:
+ {
+ int sel = SendDlgItemMessage(hwndDlg, ctrl->nID, CB_GETCURSEL, 0, 0);
+ DBWriteContactSettingTString(NULL, module, ctrl->setting, (TCHAR *) SendDlgItemMessage(hwndDlg, ctrl->nID, CB_GETITEMDATA, (WPARAM) sel, 0));
+ break;
+ }
+ }
+ }
+
+ LoadOpts(controls, controlsSize, 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};
+ HWND hwndProtocols = GetDlgItem(hwndDlg, ctrl->nID);
+ int i;
+
+ lvi.mask = (UINT) LVIF_PARAM;
+
+ for (i = 0; i < ListView_GetItemCount(hwndProtocols); i++)
+ {
+ lvi.iItem = i;
+ ListView_GetItem(hwndProtocols, &lvi);
+ mir_free((char *) lvi.lParam);
+ }
+ break;
+ }
+ }
+ }
+ break;
+ }
+ }
+
+ return 0;
+}
diff --git a/Plugins/utils/mir_options.h b/Plugins/utils/mir_options.h
new file mode 100644
index 0000000..2c433df
--- /dev/null
+++ b/Plugins/utils/mir_options.h
@@ -0,0 +1,68 @@
+/*
+Copyright (C) 2005 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.
+*/
+
+
+#ifndef __MIR_OPTIONS_H__
+# define __MIR_OPTIONS_H__
+
+#include <windows.h>
+
+
+#define CONTROL_CHECKBOX 0 // Stored as BYTE
+#define CONTROL_SPIN 1 // Stored as WORD
+#define CONTROL_COLOR 2 // Stored as DWORD
+#define CONTROL_RADIO 3 // Stored as WORD
+#define CONTROL_COMBO 4 // Stored as WORD
+#define CONTROL_PROTOCOL_LIST 5 // Stored as BYTEs
+#define CONTROL_TEXT 6 // Stored as TCHARs, max len 1024
+#define CONTROL_COMBO_TEXT 7 // Stored as TCHARs, max len 1024
+#define CONTROL_COMBO_ITEMDATA 8 // Stored as TCHARs, max len 1024
+#define CONTROL_FILE 9 // Stored as TCHARs, max len 1024
+
+
+typedef BOOL (* FPAllowProtocol) (const char *proto);
+
+typedef struct {
+ void *var;
+ int type;
+ unsigned int nID;
+ char *setting;
+ union {
+ DWORD dwDefValue;
+ TCHAR *tszDefValue;
+ };
+ union {
+ int nIDSpin;
+ int value;
+ FPAllowProtocol allowProtocol;
+ };
+ WORD min;
+ WORD max;
+} OptPageControl;
+
+BOOL CALLBACK SaveOptsDlgProc(OptPageControl *controls, int controlsSize, char *module, HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+
+void LoadOpts(OptPageControl *controls, int controlsSize, char *module);
+
+
+
+
+
+
+#endif // __MIR_OPTIONS_H__