summaryrefslogtreecommitdiff
path: root/plugins/Folders/src
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/Folders/src')
-rw-r--r--plugins/Folders/src/commonheaders.h63
-rw-r--r--plugins/Folders/src/dlg_handlers.cpp411
-rw-r--r--plugins/Folders/src/dlg_handlers.h28
-rw-r--r--plugins/Folders/src/events.cpp41
-rw-r--r--plugins/Folders/src/events.h36
-rw-r--r--plugins/Folders/src/folderItem.cpp250
-rw-r--r--plugins/Folders/src/folderItem.h80
-rw-r--r--plugins/Folders/src/folders.cpp231
-rw-r--r--plugins/Folders/src/foldersList.cpp232
-rw-r--r--plugins/Folders/src/foldersList.h69
-rw-r--r--plugins/Folders/src/hooked_events.cpp64
-rw-r--r--plugins/Folders/src/hooked_events.h34
-rw-r--r--plugins/Folders/src/resource.h27
-rw-r--r--plugins/Folders/src/services.cpp250
-rw-r--r--plugins/Folders/src/services.h50
-rw-r--r--plugins/Folders/src/utils.cpp357
-rw-r--r--plugins/Folders/src/utils.h62
-rw-r--r--plugins/Folders/src/version.h45
18 files changed, 2330 insertions, 0 deletions
diff --git a/plugins/Folders/src/commonheaders.h b/plugins/Folders/src/commonheaders.h
new file mode 100644
index 0000000000..52ab262421
--- /dev/null
+++ b/plugins/Folders/src/commonheaders.h
@@ -0,0 +1,63 @@
+/*
+Custom profile folders plugin for Miranda IM
+
+Copyright © 2005 Cristian Libotean
+
+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.
+*/
+
+#define _CRT_SECURE_NO_WARNINGS
+
+#ifndef M_FOLDERS_COMMONHEADERS_H
+#define M_FOLDERS_COMMONHEADERS_H
+
+#define MAX_FOLDER_SIZE 2048
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <windows.h>
+
+#include "newpluginapi.h"
+#include "m_utils.h"
+#include "m_folders.h"
+
+#include "version.h"
+#include "utils.h"
+#include "resource.h"
+#include "foldersList.h"
+#include "dlg_handlers.h"
+
+#include "m_database.h"
+#include "m_system.h"
+#include "m_skin.h"
+#include "m_options.h"
+#include "m_clist.h"
+#include "m_langpack.h"
+#include "m_history.h"
+#include "m_contacts.h"
+#include "m_popup.h"
+#include "m_fontservice.h"
+#include "m_variables.h"
+
+#ifndef MS_DB_GETPROFILEPATH_BASIC //db3xSA
+#define MS_DB_GETPROFILEPATH_BASIC "DB/GetProfilePathBasic"
+#endif
+
+extern char ModuleName[];
+extern HINSTANCE hInstance;
+extern CFoldersList &lstRegisteredFolders;
+
+#endif //FOLDERS_COMMONHEADERS_H \ No newline at end of file
diff --git a/plugins/Folders/src/dlg_handlers.cpp b/plugins/Folders/src/dlg_handlers.cpp
new file mode 100644
index 0000000000..cb11566363
--- /dev/null
+++ b/plugins/Folders/src/dlg_handlers.cpp
@@ -0,0 +1,411 @@
+#include "dlg_handlers.h"
+
+PFolderItem lastItem = NULL;
+
+static int bInitializing = 0;
+
+int GetCurrentItemSelection(HWND hWnd)
+{
+ return SendDlgItemMessageW(hWnd, IDC_FOLDERS_ITEMS_LIST, LB_GETCURSEL, 0, 0);
+}
+
+int GetCurrentSectionSelection(HWND hWnd)
+{
+ return SendDlgItemMessageW(hWnd, IDC_FOLDERS_SECTIONS_LIST, LB_GETCURSEL, 0, 0);
+}
+
+PFolderItem GetSelectedItem(HWND hWnd)
+{
+ WCHAR section[MAX_FOLDER_SIZE];
+ WCHAR item[MAX_FOLDER_SIZE];
+ GetCurrentItemText(hWnd, item, MAX_FOLDER_SIZE);
+ GetCurrentSectionText(hWnd, section, MAX_FOLDER_SIZE);
+ return lstRegisteredFolders.GetTranslated(section, item);
+}
+
+int GetCurrentItemText(HWND hWnd, WCHAR *buffer, int count)
+{
+ int index = GetCurrentItemSelection(hWnd);
+ if (index != LB_ERR)
+ {
+ SendDlgItemMessageW(hWnd, IDC_FOLDERS_ITEMS_LIST, LB_GETTEXT, index, (LPARAM) buffer);
+ return 1;
+ }
+ else{
+ buffer[0] = L'\0';
+ return 0;
+ }
+}
+
+int GetCurrentSectionText(HWND hWnd, WCHAR *buffer, int count)
+{
+ int index = GetCurrentSectionSelection(hWnd);
+ if (index != LB_ERR)
+ {
+ SendDlgItemMessageW(hWnd, IDC_FOLDERS_SECTIONS_LIST, LB_GETTEXT, index, (LPARAM) buffer);
+ return 1;
+ }
+ else{
+ buffer[0] = L'0';
+ return 0;
+ }
+}
+
+//void GetEditText(HWND hWnd, char *buffer, int size)
+//{
+// GetWindowText(GetDlgItem(hWnd, IDC_FOLDER_EDIT), buffer, size);
+// StrTrim(buffer, "\\\t \n");
+//}
+
+void GetEditTextW(HWND hWnd, wchar_t *buffer, int size)
+{
+ GetWindowTextW(GetDlgItem(hWnd, IDC_FOLDER_EDIT), buffer, size);
+}
+
+//void SetEditText(HWND hWnd, const char *buffer)
+//{
+// bInitializing = 1;
+// SetWindowText(GetDlgItem(hWnd, IDC_FOLDER_EDIT), buffer);
+// bInitializing = 0;
+//// SendDlgItemMessage(hWnd, IDC_FOLDER_EDIT, WM_SETTEXT, 0, (LPARAM) buffer);
+//}
+
+void SetEditTextW(HWND hWnd, const wchar_t *buffer)
+{
+ bInitializing = 1;
+ SetWindowTextW(GetDlgItem(hWnd, IDC_FOLDER_EDIT), buffer);
+ bInitializing = 0;
+}
+
+int ContainsSection(HWND hWnd, const WCHAR *section)
+{
+ int index = SendDlgItemMessageW(hWnd, IDC_FOLDERS_SECTIONS_LIST, LB_FINDSTRINGEXACT, -1, (LPARAM) section);
+ return (index != LB_ERR);
+}
+
+void LoadRegisteredFolderSections(HWND hWnd)
+{
+ for (int i = 0; i < lstRegisteredFolders.Count(); i++)
+ {
+ PFolderItem tmp = lstRegisteredFolders.Get(i + 1);
+ WCHAR *translated = mir_a2u(Translate(tmp->GetSection()));
+ if (!ContainsSection(hWnd, translated))
+ {
+ SendDlgItemMessageW(hWnd, IDC_FOLDERS_SECTIONS_LIST, LB_ADDSTRING, 0, (LPARAM) translated);
+ }
+ mir_free(translated);
+ }
+}
+
+void LoadRegisteredFolderItems(HWND hWnd)
+{
+ WCHAR buffer[MAX_FOLDER_SIZE];
+ GetCurrentSectionText(hWnd, buffer, MAX_FOLDER_SIZE);
+ SendDlgItemMessageW(hWnd, IDC_FOLDERS_ITEMS_LIST, LB_RESETCONTENT, 0, 0);
+ for (int i = 0; i < lstRegisteredFolders.Count(); i++)
+ {
+ PFolderItem item = lstRegisteredFolders.Get(i + 1);
+ WCHAR *wide = mir_a2u(Translate(item->GetSection()));
+ if (wcscmp(buffer, wide) == 0)
+ {
+ mir_free(wide);
+ wide = mir_a2u(Translate(item->GetName()));
+ SendDlgItemMessageW(hWnd, IDC_FOLDERS_ITEMS_LIST, LB_ADDSTRING, 0, (LPARAM) wide);
+ }
+ mir_free(wide);
+ }
+ SendDlgItemMessageW(hWnd, IDC_FOLDERS_ITEMS_LIST, LB_SETCURSEL, 0, 0); //select the first item
+ PostMessage(hWnd, WM_COMMAND, MAKEWPARAM(IDC_FOLDERS_ITEMS_LIST, LBN_SELCHANGE), 0); //tell the dialog to refresh the preview
+}
+
+void LoadItem(HWND hWnd, PFolderItem item)
+{
+ if (item)
+ {
+ if (item->IsUnicode())
+ {
+ SetEditTextW(hWnd, item->GetFormatW());
+ }
+ else{
+ WCHAR *buffer = mir_a2u(item->GetFormat());
+ SetEditTextW(hWnd, buffer);
+ mir_free(buffer);
+ }
+ RefreshPreview(hWnd);
+ }
+}
+
+void SaveItem(HWND hWnd, PFolderItem item, int bEnableApply)
+{
+ if (item)
+ {
+ if (item->IsUnicode())
+ {
+ wchar_t buffer[MAX_FOLDER_SIZE];
+ GetEditTextW(hWnd, buffer, MAX_FOLDER_SIZE);
+ item->SetFormatW(buffer);
+ }
+ else{
+ WCHAR buffer[MAX_FOLDER_SIZE];
+ char ansi[MAX_FOLDER_SIZE];
+ GetEditTextW(hWnd, buffer, MAX_FOLDER_SIZE);
+ WideCharToMultiByte(CallService(MS_LANGPACK_GETCODEPAGE, 0, 0), 0, buffer, -1, ansi, MAX_FOLDER_SIZE, NULL, NULL);
+ item->SetFormat(ansi);
+ }
+ if (bEnableApply)
+ {
+ SendMessage(GetParent(hWnd), PSM_CHANGED, 0, 0);
+ }
+ }
+}
+
+int ChangesNotSaved(HWND hWnd, PFolderItem item)
+{
+ int res = 0;
+ if (item)
+ {
+ if (item->IsUnicode())
+ {
+ wchar_t buffer[MAX_FOLDER_SIZE];
+ GetEditTextW(hWnd, buffer, MAX_FOLDER_SIZE);
+ res = (wcscmp(item->GetFormatW(), buffer) != 0);
+ }
+ else{
+ WCHAR buffer[MAX_FOLDER_SIZE];
+ GetEditTextW(hWnd, buffer, MAX_FOLDER_SIZE);
+ char *ansi = mir_u2a(buffer);
+
+ res = (strcmp(item->GetFormat(), ansi) != 0);
+ mir_free(ansi);
+ }
+ }
+
+ return res;
+}
+
+void CheckForChanges(HWND hWnd, int bNeedConfirmation = 1)
+{
+ if (ChangesNotSaved(hWnd, lastItem))
+ {
+ if ((!bNeedConfirmation) || MessageBoxW(hWnd, TranslateW(L"Some changes weren't saved. Apply the changes now ?"), TranslateW(L"Changes not saved"), MB_YESNO | MB_ICONINFORMATION) == IDYES)
+ {
+ SaveItem(hWnd, lastItem);
+ }
+ }
+}
+
+void RefreshPreview(HWND hWnd)
+{
+ wchar_t tmp[MAX_FOLDER_SIZE];
+ wchar_t res[MAX_FOLDER_SIZE];
+ GetEditTextW(hWnd, tmp, MAX_FOLDER_SIZE);
+ ExpandPathW(res, tmp, MAX_FOLDER_SIZE);
+ SetWindowTextW(GetDlgItem(hWnd, IDC_PREVIEW_EDIT), res);
+ //SendDlgItemMessage(hWnd, IDC_PREVIEW_EDIT, WM_SETTEXT, 0, (LPARAM) res);
+}
+
+
+/************************************** DIALOG HANDLERS *************************************/
+#include "commctrl.h"
+
+INT_PTR CALLBACK DlgProcOpts(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ {
+ bInitializing = 1;
+ lastItem = NULL;
+ TranslateDialogDefault(hWnd);
+ LoadRegisteredFolderSections(hWnd);
+ bInitializing = 0;
+
+ break;
+ }
+
+ case WM_COMMAND:
+ {
+ switch (LOWORD(wParam))
+ {
+ case IDC_FOLDER_EDIT:
+ {
+ switch (HIWORD(wParam))
+ {
+ case EN_CHANGE:
+ {
+ RefreshPreview(hWnd);
+ if (!bInitializing)
+ {
+ SendMessage(GetParent(hWnd), PSM_CHANGED, 0, 0); //show the apply button.
+ }
+
+ break;
+ }
+ }
+
+ break;
+ }
+
+ case IDC_REFRESH_BUTTON:
+ {
+ RefreshPreview(hWnd);
+
+ break;
+ }
+
+ case IDC_HELP_BUTTON:
+ {
+ HWND helpDlg = CreateDialogW(hInstance, MAKEINTRESOURCEW(IDD_VARIABLES_HELP), hWnd, DlgProcVariables);
+ ShowWindow(helpDlg, SW_SHOW);
+
+ break;
+ }
+
+ case IDC_FOLDERS_SECTIONS_LIST:
+ {
+ switch (HIWORD(wParam))
+ {
+ case LBN_SELCHANGE:
+ {
+ CheckForChanges(hWnd);
+ LoadRegisteredFolderItems(hWnd);
+ lastItem = NULL;
+ SetEditTextW(hWnd, L"");
+ RefreshPreview(hWnd);
+
+ break;
+ }
+ }
+
+ break;
+ }
+
+ case IDC_FOLDERS_ITEMS_LIST:
+ {
+ switch (HIWORD(wParam))
+ {
+ case LBN_SELCHANGE:
+ {
+ PFolderItem item = GetSelectedItem(hWnd);
+ if (item != NULL)
+ {
+ CheckForChanges(hWnd);
+ LoadItem(hWnd, item);
+ }
+ lastItem = item;
+
+ break;
+ }
+ }
+
+ break;
+ }
+ }
+
+ break;
+ }
+
+ case WM_NOTIFY:
+ {
+// Log("WM_NOTIFY %d %d", wParam, lParam);
+ switch(((LPNMHDR)lParam)->idFrom)
+ {
+ case 0:
+ switch (((LPNMHDR)lParam)->code)
+ {
+ case PSN_APPLY:
+ {
+ PFolderItem item = GetSelectedItem(hWnd);
+ if (item)
+ {
+ SaveItem(hWnd, item, FALSE);
+ LoadItem(hWnd, item);
+ }
+
+ lstRegisteredFolders.Save();
+ CallPathChangedEvents();
+
+ break;
+ }
+ }
+
+ break;
+ }
+ }
+
+ break;
+
+ default:
+ {
+
+ break;
+ }
+ }
+
+ return 0;
+}
+
+INT_PTR CALLBACK DlgProcVariables(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ {
+ SetDlgItemText(hWnd, IDC_HELP_RICHEDIT, _T("\
+Don't forget to click on Apply to save the changes. If you don't then the changes won\'t\r\n\
+be saved to the database, they will only be valid for this session.\r\n\r\n\
+Variable string\t\tWhat it expands to:\r\n\
+%miranda_path%\tExpands to your miranda path (e.g: c:\program files\miranda im).\r\n\
+%profile_path%\t\tExpands to your profile path - the value found in mirandaboot.ini,\r\n\
+\t\t\tProfileDir section (usually inside miranda's folder).\r\n\
+%current_profile%\tExpands to your current profile name without the extenstion.\r\n\
+\t\t\t(e.g.default if your your profile is default.dat).\r\n\r\n\r\n\
+Environment variables\r\n\
+The plugin can also expand environment variables; the variables are specified like in any other\r\n\
+program that can use environment variables, i.e. %<env variable>%.\r\n\
+Note: Environment variables are expanded before any Miranda variables. So if you have, for\r\n\
+example, %profile_path% defined as a system variable then it will be expanded to that value\r\n\
+instead of expanding to Miranda\’s profile path.\r\n\r\n\
+Examples:\r\n\
+If the value for the ProfileDir inside mirandaboot.ini, ProfileDir section is \'.\profiles\', current\r\n\
+profile is \'default.dat\' and miranda\'s path is \'c:\program files\miranda im\' then:\r\n\
+%miranda_path%\t\t\twill expand to \'c:\program files\miranda im\'\r\n\
+%profile_path%\t\t\twill expand to \'c:\program files\miranda im\profiles\'\r\n\
+%current_profile%\t\t\twill expand to \'default\'\r\n\
+%temp%\t\t\t\twill expand to the temp folder of the current user.\r\n\
+%profile_path%\%current_profile%\twill expand to \'c:\program files\miranda im\profiles\default\'\r\n\
+%miranda_path%\plugins\config\twill expand to \'c:\program files\miranda im\plugins\config\'\r\n\
+\' %miranda_path%\\\\\\\\ \'\t\twill expand to \'c:\program files\miranda im\'\r\n\
+notice that the spaces at the beginning and the end of the string are trimmed, as well as the last \\\
+"));
+
+ TranslateDialogDefault(hWnd);
+
+ break;
+ }
+
+ case WM_CLOSE:
+ {
+ DestroyWindow(hWnd);
+
+ break;
+ }
+
+ case WM_COMMAND:
+ {
+ switch (LOWORD(wParam))
+ {
+ case IDCLOSE:
+ {
+ DestroyWindow(hWnd);
+
+ break;
+ }
+ }
+
+ break;
+ }
+ }
+
+ return 0;
+} \ No newline at end of file
diff --git a/plugins/Folders/src/dlg_handlers.h b/plugins/Folders/src/dlg_handlers.h
new file mode 100644
index 0000000000..4f3a4f15ca
--- /dev/null
+++ b/plugins/Folders/src/dlg_handlers.h
@@ -0,0 +1,28 @@
+#ifndef M_FOLDERS_DLG_HANDLERS_H
+#define M_FOLDERS_DLG_HANDLERS_H
+
+//#include "commonheaders.h"
+#include "services.h"
+#include "events.h"
+#include <richedit.h>
+
+INT_PTR CALLBACK DlgProcOpts(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
+INT_PTR CALLBACK DlgProcVariables(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
+
+int GetCurrentItemSelection(HWND hWnd);
+int GetCurrentSectionSelection(HWND hWnd);
+PFolderItem GetSelectedItem(HWND hWnd);
+int GetCurrentSectionText(HWND hWnd, WCHAR *buffer, int count);
+int GetCurrentItemText(HWND hWnd, WCHAR *buffer, int count);
+//void GetEditText(HWND hWnd, char *buffer, int size);
+void GetEditTextW(HWND hWnd, wchar_t *buffer, int size);
+//void SetEditText(HWND hWnd, const char *buffer);
+void SetEditTextW(HWND hWnd, const wchar_t *buffer);
+void LoadRegisteredFolderSections(HWND hWnd);
+void LoadRegisteredFolderItems(HWND hWnd);
+void LoadItem(HWND hWnd, PFolderItem item);
+void SaveItem(HWND hWnd, PFolderItem item, int bEnableApply = TRUE);
+int ChangesNotSaved(HWND hWnd);
+void RefreshPreview(HWND hWnd);
+
+#endif //M_FOLDERS_DLG_HANDLERS_H \ No newline at end of file
diff --git a/plugins/Folders/src/events.cpp b/plugins/Folders/src/events.cpp
new file mode 100644
index 0000000000..359ac81bf4
--- /dev/null
+++ b/plugins/Folders/src/events.cpp
@@ -0,0 +1,41 @@
+/*
+Custom profile folders plugin for Miranda IM
+
+Copyright © 2005 Cristian Libotean
+
+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 "events.h"
+
+HANDLE hPathChanged;
+
+int InitEvents()
+{
+ hPathChanged = CreateHookableEvent(ME_FOLDERS_PATH_CHANGED);
+ return 0;
+}
+
+int DestroyEvents()
+{
+ DestroyHookableEvent(hPathChanged);
+ hPathChanged = 0;
+ return 0;
+}
+
+int CallPathChangedEvents()
+{
+ return NotifyEventHooks(hPathChanged, 0, 0);
+} \ No newline at end of file
diff --git a/plugins/Folders/src/events.h b/plugins/Folders/src/events.h
new file mode 100644
index 0000000000..8f73ee7cfe
--- /dev/null
+++ b/plugins/Folders/src/events.h
@@ -0,0 +1,36 @@
+/*
+Custom profile folders plugin for Miranda IM
+
+Copyright © 2005 Cristian Libotean
+
+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 M_FOLDERS_EVENTS_H
+#define M_FOLDERS_EVENTS_H
+
+#include "commonheaders.h"
+#include "m_folders.h"
+
+extern HANDLE hPathChanged;
+
+int InitEvents();
+int DestroyEvents();
+
+int CallPathChangedEvents();
+
+
+
+#endif //M_FOLDERS_EVENTS_H \ No newline at end of file
diff --git a/plugins/Folders/src/folderItem.cpp b/plugins/Folders/src/folderItem.cpp
new file mode 100644
index 0000000000..cf58e5feac
--- /dev/null
+++ b/plugins/Folders/src/folderItem.cpp
@@ -0,0 +1,250 @@
+/*
+Custom profile folders plugin for Miranda IM
+
+Copyright © 2005 Cristian Libotean
+
+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 "folderItem.h"
+#include "commonheaders.h"
+#include "services.h"
+
+CFolderItem::CFolderItem(const char *sectionName, const char *name, const char *format, const DWORD flags)
+{
+ strncpy(szSection, sectionName, sizeof(szSection));
+ szFormat = NULL;
+ szOldFormat = NULL;
+ szFormatW = NULL;
+ szOldFormatW = NULL;
+ strncpy(szName, name, sizeof(szName));
+ this->flags = flags;
+ GetDataFromDatabase(format);
+ FolderCreateDirectory();
+}
+
+void MyFree(void *data)
+{
+ if (data)
+ {
+ free(data);
+ }
+}
+
+CFolderItem::~CFolderItem()
+{
+// WriteDataToDatabase();
+ if (IsUnicode())
+ {
+ MyFree(szFormatW);
+ MyFree(szOldFormatW);
+ }
+ else{
+ MyFree(szFormat);
+ MyFree(szOldFormat);
+ }
+}
+
+const char *CFolderItem::GetSection() const
+{
+ return szSection;
+}
+
+const char *CFolderItem::GetName() const
+{
+ return szName;
+}
+
+const char *CFolderItem::GetFormat() const
+{
+ return szFormat;
+}
+
+const wchar_t *CFolderItem::GetFormatW() const
+{
+ return szFormatW;
+}
+
+void CFolderItem::SetFormat(const char *newFormat)
+{
+ MyFree(szOldFormat);
+ szOldFormat = szFormat;
+ szFormat = _strdup((strlen(newFormat) > 0) ? newFormat : MIRANDA_PATH);
+}
+
+void CFolderItem::SetFormatW(const wchar_t *newFormat)
+{
+ MyFree(szOldFormatW);
+ szOldFormatW = szFormatW;
+ szFormatW = _wcsdup((wcslen(newFormat) > 0) ? newFormat : MIRANDA_PATHW);
+}
+
+int CFolderItem::IsUnicode() const
+{
+ return (flags & FF_UNICODE);
+}
+
+int CFolderItem::IsEqual(const CFolderItem *other)
+{
+ return (IsEqual(other->GetSection(), other->GetName()));
+}
+
+int CFolderItem::IsEqual(const char *section, const char *name)
+{
+ return ((strcmp(szName, name) == 0) && (strcmp(szSection, section) == 0));
+}
+
+int CFolderItem::IsEqualTranslated(const char *trSection, const char *trName)
+{
+ return ((strcmp(Translate(szName), trName) == 0) && (strcmp(Translate(szSection), trSection) == 0));
+}
+
+int CFolderItem::operator ==(const CFolderItem *other)
+{
+ return IsEqual(other);
+}
+
+void CFolderItem::Expand(char *buffer, int size)
+{
+ if (IsUnicode())
+ {
+ ExpandPathW((wchar_t *) buffer, szFormatW, size);
+ }
+ else{
+ ExpandPath(buffer, szFormat, size);
+ }
+}
+
+void CFolderItem::Save()
+{
+ int res = FolderDeleteOldDirectory(FALSE);
+ //FolderCreateDirectory(!res);
+ FolderCreateDirectory(FALSE);
+ WriteDataToDatabase();
+}
+
+int CFolderItem::FolderCreateDirectory(int showFolder)
+{
+ int res = FOLDER_SUCCESS;
+ if (IsUnicode())
+ {
+ wchar_t buffer[MAX_FOLDER_SIZE];
+ if (szFormatW)
+ {
+ ExpandPathW(buffer, szFormatW, MAX_FOLDER_SIZE);
+ CreateDirectories(buffer);
+ if (showFolder)
+ {
+ ShellExecuteW(NULL, L"explore", buffer, NULL, NULL, SW_SHOW);
+ }
+ res = (DirectoryExists(buffer)) ? FOLDER_SUCCESS : FOLDER_FAILURE;
+ }
+ }
+ else{
+ char buffer[MAX_FOLDER_SIZE];
+ if (szFormat)
+ {
+ ExpandPath(buffer, szFormat, MAX_FOLDER_SIZE);
+ CreateDirectories(buffer);
+ if (showFolder)
+ {
+ ShellExecuteA(NULL, "explore", buffer, NULL, NULL, SW_SHOW);
+ }
+ res = (DirectoryExists(buffer)) ? FOLDER_SUCCESS : FOLDER_FAILURE;
+ }
+ }
+ return res;
+}
+
+int CFolderItem::FolderDeleteOldDirectory(int showFolder)
+{
+ int res = FOLDER_SUCCESS;
+ if (IsUnicode())
+ {
+ wchar_t buffer[MAX_FOLDER_SIZE];
+ if (szOldFormatW)
+ {
+ if (wcscmp(szFormatW, szOldFormatW) == 0) //format wasn't changed
+ {
+ return res;
+ }
+ ExpandPathW(buffer, szOldFormatW, MAX_FOLDER_SIZE);
+ RemoveDirectories(buffer);
+ res = (DirectoryExists(buffer)) ? FOLDER_FAILURE : FOLDER_SUCCESS;
+ if ((res == FOLDER_FAILURE) && (showFolder))
+ {
+ ShellExecuteW(NULL, L"explore", buffer, NULL, NULL, SW_SHOW);
+ }
+ }
+ }
+ else{
+ char buffer[MAX_FOLDER_SIZE];
+ if (szOldFormat)
+ {
+ if (strcmp(szFormat, szOldFormat) == 0) //format wasn't changed
+ {
+ return res;
+ }
+ ExpandPath(buffer, szOldFormat, MAX_FOLDER_SIZE);
+ RemoveDirectories(buffer);
+ res = (DirectoryExists(buffer)) ? FOLDER_FAILURE : FOLDER_SUCCESS;
+ if ((res == FOLDER_FAILURE) && (showFolder))
+ {
+ ShellExecuteA(NULL, "explore", buffer, NULL, NULL, SW_SHOW);
+ }
+ }
+ }
+ return res;
+}
+
+void CFolderItem::GetDataFromDatabase(const char *szNotFound)
+{
+ char name[256];
+ strcpy(name, szSection);
+ strcat(name, szName);
+
+ if (IsUnicode())
+ {
+ wchar_t buffer[MAX_FOLDER_SIZE];
+ GetStringFromDatabase(name, (const wchar_t *) szNotFound, buffer, MAX_FOLDER_SIZE);
+ SetFormatW(buffer);
+ }
+ else{
+ char buffer[MAX_FOLDER_SIZE];
+ GetStringFromDatabase(name, szNotFound, buffer, MAX_FOLDER_SIZE);
+ SetFormat(buffer);
+ }
+}
+
+void CFolderItem::WriteDataToDatabase()
+{
+ char name[256];
+ strcpy(name, szSection);
+ strcat(name, szName);
+
+ if (IsUnicode())
+ {
+ if (szFormatW)
+ {
+ WriteStringToDatabase(name, szFormatW);
+ }
+ }
+ else{
+ if (szFormat)
+ {
+ WriteStringToDatabase(name, szFormat);
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/Folders/src/folderItem.h b/plugins/Folders/src/folderItem.h
new file mode 100644
index 0000000000..ab2c1bbd38
--- /dev/null
+++ b/plugins/Folders/src/folderItem.h
@@ -0,0 +1,80 @@
+/*
+Custom profile folders plugin for Miranda IM
+
+Copyright © 2005 Cristian Libotean
+
+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.
+*/
+
+#define _CRT_SECURE_NO_WARNINGS
+
+#ifndef M_FOLDERS_FOLDER_ITEM_H
+#define M_FOLDERS_FOLDER_ITEM_H
+
+#include <string.h>
+#include <malloc.h>
+#include <windows.h>
+
+#define FOLDERS_NO_HELPER_FUNCTIONS
+#include "m_folders.h"
+#undef FOLDERS_NO_HELPER_FUNCTIONS
+
+
+#define FOLDER_SUCCESS 1
+#define FOLDER_FAILURE 0
+
+class CFolderItem{
+ protected:
+ char szSection[FOLDERS_NAME_MAX_SIZE];
+ char szName[FOLDERS_NAME_MAX_SIZE]; //don't forget to modify in m_folders.h
+ union{
+ char *szFormat;
+ wchar_t *szFormatW;
+ };
+ union{
+ char *szOldFormat;
+ wchar_t *szOldFormatW;
+ };
+ DWORD flags;
+
+ void GetDataFromDatabase(const char *szNotFound);
+ void WriteDataToDatabase();
+
+ int FolderCreateDirectory(int showFolder = 0);
+ int FolderDeleteOldDirectory(int showFolder = 0);
+
+ public:
+ CFolderItem(const char *sectionName, const char *name, const char *format, const DWORD flags);
+ virtual ~CFolderItem();
+ void Expand(char *buffer, int size);
+ void Save();
+
+ int IsUnicode() const;
+ int IsEqual(const CFolderItem *other);
+ int IsEqual(const char *section, const char *name);
+ int IsEqualTranslated(const char *trSection, const char *trName);
+ int operator ==(const CFolderItem *other);
+
+ const char *GetSection() const;
+ const char *GetName() const;
+ const char *GetFormat() const;
+ const wchar_t *GetFormatW() const;
+ void SetFormat(const char *newFormat);
+ void SetFormatW(const wchar_t *newFormat);
+};
+
+typedef CFolderItem *PFolderItem;
+
+#endif //M_FOLDERS_FOLDER_ITEM_H \ No newline at end of file
diff --git a/plugins/Folders/src/folders.cpp b/plugins/Folders/src/folders.cpp
new file mode 100644
index 0000000000..721c43ee5f
--- /dev/null
+++ b/plugins/Folders/src/folders.cpp
@@ -0,0 +1,231 @@
+/*
+Custom profile folders plugin for Miranda IM
+
+Copyright © 2005 Cristian Libotean
+
+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 "hooked_events.h"
+#include "services.h"
+#include "events.h"
+
+#include "m_folders.h"
+
+#define MS_FOLDERS_TEST_PLUGIN "Folders/Test/Plugin"
+
+char ModuleName[] = "Folders";
+HINSTANCE hInstance;
+int hLangpack;
+
+CFoldersList &lstRegisteredFolders = CFoldersList(10); //the list
+
+
+
+PLUGININFOEX pluginInfo = {
+ sizeof(PLUGININFOEX),
+ __PLUGIN_DISPLAY_NAME,
+ VERSION,
+ __DESC,
+ __AUTHOR,
+ __AUTHOREMAIL,
+ __COPYRIGHT,
+ __AUTHORWEB,
+ UNICODE_AWARE,
+ {0x2f129563, 0x2c7d, 0x4a9a, {0xb9, 0x48, 0x97, 0xdf, 0xcc, 0x0a, 0xfd, 0xd7}} //{2f129563-2c7d-4a9a-b948-97dfcc0afdd7}
+}; //not used
+
+#ifdef _DEBUG
+
+typedef struct{
+ int cbSize; //size of struct
+ int nUniqueID; //unique id for this path. This ID should be unique for your plugin.
+ char szName[FOLDERS_NAME_MAX_SIZE]; //name to show in options
+} FOLDERSDATA_OLD;
+
+INT_PTR TestPlugin(WPARAM wParam, LPARAM lParam)
+{
+ char temp[MAX_PATH];
+ const int MAX = 20;
+ int i;
+ HANDLE handles[MAX][2];
+/* FOLDERSDATA caca;
+ caca.cbSize = sizeof(caca);
+ caca.szFormat = FOLDER_LOGS;*/
+ char *section;
+ for (i = 0; i < MAX; i++)
+ {
+ switch (i % 4)
+ {
+ case 0:
+ section = "Section 1";
+ break;
+ case 1:
+ section = "Section 2";
+ break;
+ case 2:
+ section = "Yet another section";
+ break;
+ case 3:
+ section = "Section no 4";
+ break;
+ default:
+ section = "Uhh ohh";
+ break;
+ }
+ //strcpy(caca.szSection, section);
+ _itoa(i, temp, 10);
+ //strcpy(caca.szName, temp);
+
+ handles[i][0] = FoldersRegisterCustomPathT(section, temp, FOLDER_LOGS); //CallService(MS_FOLDERS_REGISTER_PATH, 0, (LPARAM) &caca);
+ }
+ //caca.szFormatW = L"%profile_path%\\%current_profile%\\Ø";
+ //caca.flags = FF_UNICODE;
+ FoldersRegisterCustomPath("Unicode stuff", "non unicode", " %profile_path%\\%current_profile%\\Ø\\\\\\");
+ for (i = 0; i < MAX; i++)
+ {
+ //strcpy(caca.szSection, "Unicode stuff");
+ sprintf(temp, "Value %d", i);
+ //strcpy(caca.szName, temp);
+ handles[i][1] = FoldersRegisterCustomPathW("Unicode stuff", temp, L"%profile_path%\\%current_profile%\\\u1FA6"); //CallService(MS_FOLDERS_REGISTER_PATH, 0, (LPARAM) &caca);
+ }
+/*
+ FOLDERSAPPENDDATA data;
+ data.hRegisteredPath = handles[0];
+ data.szAppendData = "just an appended string";
+ char *cacat;
+ CallService(MS_FOLDERS_GET_PATH_ALLOC_APPEND, (WPARAM) &data, (LPARAM) &cacat);
+ Log("Append function returned : %s", cacat); */
+ /*FOLDERSGETDATA data = {0};
+ data.cbSize = sizeof(data);
+ data.nMaxPathSize = sizeof(temp);
+ data.szPath = temp; */
+ for (i = 0; i < MAX; i++)
+ {
+ //CallService(MS_FOLDERS_GET_PATH, handles[i][0], (LPARAM) &data);
+ FoldersGetCustomPath((HANDLE) handles[i][0], temp, sizeof(temp), "<not found>");
+ Log("Path function[%d] returned : %s", i, temp);
+ }
+ wchar_t buffer[MAX_PATH];
+ //data.szPathW = buffer;
+ for (i = 0; i < MAX; i++)
+ {
+ //CallService(MS_FOLDERS_GET_PATH, handles[i][0], (LPARAM) &data);
+ FoldersGetCustomPathW((HANDLE) handles[i][1], buffer, MAX_PATH, L"<not found>");
+ Log("Unicode path function[%d] returned: %S", i, buffer);
+ }
+// GetPathService(CONFIGURATION_PATH, (LPARAM) temp);
+// GetPathAllocService(AVATARS_PATH, (LPARAM) &caca);
+
+
+ for (i = 0; i < MAX; i++)
+ {
+ FoldersGetCustomPathEx((HANDLE) handles[i][0], temp, sizeof(temp), "<not found>", "test");
+ Log("Path function Ex (test) [%d] returned : %s", i, temp);
+ FoldersGetCustomPathEx((HANDLE) handles[i][0], temp, sizeof(temp), "<not found>", "");
+ Log("Path function Ex () [%d] returned : %s", i, temp);
+ FoldersGetCustomPathEx((HANDLE) handles[i][0], temp, sizeof(temp), "<not found>", NULL);
+ Log("Path function Ex (NULL) [%d] returned : %s", i, temp);
+ }
+
+ for (i = 0; i < MAX; i++)
+ {
+ FoldersGetCustomPathExW((HANDLE) handles[i][1], buffer, MAX_PATH, L"<not found>", L"test");
+ Log("Unicode path function Ex (test) [%d] returned : %S", i, buffer);
+ FoldersGetCustomPathExW((HANDLE) handles[i][1], buffer, MAX_PATH, L"<not found>", L"");
+ Log("Unicode path function Ex () [%d] returned : %S", i, buffer);
+ FoldersGetCustomPathExW((HANDLE) handles[i][1], buffer, MAX_PATH, L"<not found>", NULL);
+ Log("Unicode path function Ex (NULL) [%d] returned : %S", i, buffer);
+ }
+
+ return 0;
+}
+
+HANDLE hTestPlugin;
+#endif
+
+extern "C" __declspec(dllexport) PLUGININFOEX *MirandaPluginInfoEx(DWORD mirandaVersion)
+{
+ return &pluginInfo;
+}
+
+extern "C" __declspec(dllexport) const MUUID MirandaInterfaces[] = {MIID_FOLDERS, MIID_LAST};
+
+extern "C" int __declspec(dllexport) Load(void)
+{
+#if _MSC_VER >= 1300
+ Log("%s", "Entering function " __FUNCTION__);
+#endif
+
+ mir_getLP(&pluginInfo);
+
+ Log("%s", "Creating service functions ...");
+ InitServices();
+ InitEvents();
+
+#ifdef _DEBUG
+ hTestPlugin = CreateServiceFunction(MS_FOLDERS_TEST_PLUGIN, TestPlugin);
+ CLISTMENUITEM mi = {0};
+
+ mi.cbSize=sizeof(mi);
+ mi.position=300050000;
+ mi.flags=0;
+ mi.hIcon=0;
+ mi.pszName=Translate("Test folders");
+ mi.pszService=MS_FOLDERS_TEST_PLUGIN;
+ Menu_AddMainMenuItem(&mi);
+#endif
+#if _MSC_VER >= 1300
+ Log("%s", "Hooking events ...");
+#endif
+ HookEvents();
+#if _MSC_VER >= 1300
+ Log("%s", "Leaving function " __FUNCTION__);
+#endif
+ return 0;
+}
+
+extern "C" int __declspec(dllexport) Unload()
+{
+#if _MSC_VER >= 1300
+ Log("%s", "Entering function " __FUNCTION__);
+ Log("%s", "Unhooking events ...");
+
+ Log("%s", "Destroying service functions ...");
+#endif
+// DestroyServiceFunction(MS_HISTORY_SHOWCONTACTHISTORY);
+ DestroyServices();
+ DestroyEvents();
+ UnhookEvents();
+#ifdef _DEBUG
+ DestroyServiceFunction(hTestPlugin);
+#endif
+
+#if _MSC_VER >= 1300
+ Log("%s", "Leaving function " __FUNCTION__);
+#endif
+ return 0;
+}
+
+bool WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)
+{
+ hInstance = hinstDLL;
+ if (fdwReason == DLL_PROCESS_ATTACH)
+ {
+ DisableThreadLibraryCalls(hinstDLL);
+ }
+ return TRUE;
+} \ No newline at end of file
diff --git a/plugins/Folders/src/foldersList.cpp b/plugins/Folders/src/foldersList.cpp
new file mode 100644
index 0000000000..b13620fe71
--- /dev/null
+++ b/plugins/Folders/src/foldersList.cpp
@@ -0,0 +1,232 @@
+/*
+Custom profile folders plugin for Miranda IM
+
+Copyright © 2005 Cristian Libotean
+
+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 "foldersList.h"
+
+CFoldersList::CFoldersList(int initialSize)
+{
+ capacity = 0;
+ count = 0;
+ list = NULL;
+ Enlarge(initialSize);
+}
+
+CFoldersList::~CFoldersList()
+{
+ Clear();
+ free(list);
+}
+
+void CFoldersList::Clear()
+{
+ int i;
+ for (i = 0; i < count; i++)
+ {
+ delete (list[i]);
+ }
+
+ count = 0;
+}
+
+int CFoldersList::Count()
+{
+ return count;
+}
+
+int CFoldersList::Capacity()
+{
+ return capacity;
+}
+
+void CFoldersList::Save()
+{
+ int i;
+ for (i = 0; i < count; i++)
+ {
+ list[i]->Save();
+ }
+}
+
+PFolderItem CFoldersList::Get(int index)
+{
+ index--;
+ if ((index < 0) || (index >= count))
+ {
+ return NULL;
+ }
+ return list[index];
+}
+
+PFolderItem CFoldersList::Get(const char *section, const char *name)
+{
+ int i;
+ for (i = 0; i < count; i++)
+ {
+ if (list[i]->IsEqual(section, name))
+ {
+ return list[i];
+ }
+ }
+ return NULL;
+}
+
+PFolderItem CFoldersList::Get(const WCHAR *section, const WCHAR *name)
+{
+ const int MAX_SIZE = 2048;
+ char aSection[MAX_SIZE];
+ char aName[MAX_SIZE];
+ UINT cp = static_cast<UINT>(CallService(MS_LANGPACK_GETCODEPAGE, 0, 0));
+
+ WideCharToMultiByte(cp, 0, section, -1, aSection, MAX_SIZE, NULL, NULL);
+ WideCharToMultiByte(cp, 0, name, -1, aName, MAX_SIZE, NULL, NULL);
+
+ return Get(aSection, aName);
+}
+
+PFolderItem CFoldersList::GetTranslated(const char *trSection, const char *trName)
+{
+ int i;
+ for (i = 0; i < count; i++)
+ {
+ if (list[i]->IsEqualTranslated(trSection, trName))
+ {
+ return list[i];
+ }
+ }
+
+ return NULL;
+}
+
+PFolderItem CFoldersList::GetTranslated(WCHAR *trSection, const WCHAR *trName)
+{
+ const int MAX_SIZE = 2048;
+ char aSection[MAX_SIZE];
+ char aName[MAX_SIZE];
+ UINT cp = static_cast<UINT>(CallService(MS_LANGPACK_GETCODEPAGE, 0, 0));
+
+ WideCharToMultiByte(cp, 0, trSection, -1, aSection, MAX_SIZE, NULL, NULL);
+ WideCharToMultiByte(cp, 0, trName, -1, aName, MAX_SIZE, NULL, NULL);
+
+ return GetTranslated(aSection, aName);
+}
+
+
+int CFoldersList::Expand(int index, char *szResult, int size)
+{
+ PFolderItem tmp = Get(index);
+ int res = 1;
+ if (tmp)
+ {
+ tmp->Expand(szResult, size);
+ res = 0;
+ }
+ else{
+ memset(szResult, 0, size);
+ }
+ return res;
+}
+
+int CFoldersList::Add(CFolderItem *item)
+{
+ EnsureCapacity();
+ int pos = Contains(item);
+ if (!pos)
+ {
+ list[count++] = item;
+ return count;
+ }
+ else{
+ delete item;
+ return pos;
+ }
+ return 0;
+}
+
+int CFoldersList::Add(FOLDERSDATA data)
+{
+ CFolderItem *item;
+ if (data.flags & FF_UNICODE)
+ {
+ item = new CFolderItem(data.szSection, data.szName, (char *) data.szFormatW, data.flags);
+ }
+ else{
+ item = new CFolderItem(data.szSection, data.szName, data.szFormat, data.flags);
+ }
+ return Add(item);
+}
+
+void CFoldersList::Remove(CFolderItem *item)
+{
+// Remove(item->GetUniqueID());
+}
+
+void CFoldersList::Remove(int uniqueID)
+{
+/* int i, j;
+ CFolderItem *tmp;
+ for (i = 0; i < count; i++)
+ {
+ if (list[i]->GetUniqueID() == uniqueID)
+ {
+ tmp = list[i];
+ for (j = i; j < count - 1; j++)
+ {
+ list[j] = list[j + 1];
+ }
+ count--;
+ delete tmp;
+ return;
+ }
+ }
+*/
+}
+
+int CFoldersList::Contains(CFolderItem *item)
+{
+ return Contains(item->GetSection(), item->GetName());
+}
+
+int CFoldersList::Contains(const char *section, const char *name)
+{
+ int i;
+ for (i = 0; i < count; i++)
+ {
+ if (list[i]->IsEqual(section, name))
+ {
+ return i + 1;
+ }
+ }
+ return 0;
+}
+
+void CFoldersList::EnsureCapacity()
+{
+ if (count >= capacity)
+ {
+ Enlarge(capacity / 2);
+ }
+}
+
+void CFoldersList::Enlarge(int increaseAmount)
+{
+ int newSize = capacity + increaseAmount;
+ list = (PFolderItem *) realloc(list, newSize * sizeof(PFolderItem));
+ capacity = newSize;
+} \ No newline at end of file
diff --git a/plugins/Folders/src/foldersList.h b/plugins/Folders/src/foldersList.h
new file mode 100644
index 0000000000..854249b3a3
--- /dev/null
+++ b/plugins/Folders/src/foldersList.h
@@ -0,0 +1,69 @@
+/*
+Custom profile folders plugin for Miranda IM
+
+Copyright © 2005 Cristian Libotean
+
+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 M_FOLDERS_LIST_H
+#define M_FOLDERS_LIST_H
+
+#include <string.h>
+#include <malloc.h>
+
+#include "folderItem.h"
+
+#define FOLDERS_NO_HELPER_FUNCTIONS
+#include "m_folders.h"
+#undef FOLDERS_NO_HELPER_FUNCTIONS
+#include "newpluginapi.h"
+#include "m_langpack.h"
+
+class CFoldersList{
+ protected:
+ PFolderItem *list; //the list
+ int count;
+ int capacity;
+
+ void Enlarge(int increaseAmount);
+ void EnsureCapacity();
+
+ public:
+ CFoldersList(int initialSize = 10);
+ virtual ~CFoldersList();
+
+ void Clear();
+ int Add(CFolderItem *item);
+ int Add(FOLDERSDATA data);
+ void Remove(CFolderItem *item);
+ void Remove(int uniqueID);
+ int Contains(CFolderItem *item);
+ int Contains(const char *section, const char *name);
+
+ int Count();
+ int Capacity();
+
+ PFolderItem Get(int index);
+ PFolderItem Get(const char *section, const char *name);
+ PFolderItem Get(const WCHAR *section, const WCHAR *name);
+ PFolderItem GetTranslated(const char *trSection, const char *trName);
+ PFolderItem GetTranslated(WCHAR *trSection, const WCHAR *trName);
+ int Expand(int index, char *szResult, int size);
+ void Save();
+};
+
+
+#endif \ No newline at end of file
diff --git a/plugins/Folders/src/hooked_events.cpp b/plugins/Folders/src/hooked_events.cpp
new file mode 100644
index 0000000000..77042f2879
--- /dev/null
+++ b/plugins/Folders/src/hooked_events.cpp
@@ -0,0 +1,64 @@
+/*
+Custom profile folders plugin for Miranda IM
+
+Copyright © 2005 Cristian Libotean
+
+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 "hooked_events.h"
+#include "events.h"
+
+#define HOST "http://eblis.tla.ro/projects"
+
+#if defined(WIN64) || defined(_WIN64)
+#define FOLDERS_VERSION_URL HOST "/miranda/Folders/updater/x64/Folders.html"
+#define FOLDERS_UPDATE_URL HOST "/miranda/Folders/updater/x64/Folders.zip"
+#else
+#define FOLDERS_VERSION_URL HOST "/miranda/Folders/updater/Folders.html"
+#define FOLDERS_UPDATE_URL HOST "/miranda/Folders/updater/Folders.zip"
+#endif
+#define FOLDERS_VERSION_PREFIX "Custom profile folders version "
+
+HANDLE hOptionsInitialize;
+
+int HookEvents()
+{
+ hOptionsInitialize = HookEvent(ME_OPT_INITIALISE, OnOptionsInitialize);
+ return 0;
+}
+
+int UnhookEvents()
+{
+ UnhookEvent(hOptionsInitialize);
+ return 0;
+}
+
+int OnOptionsInitialize(WPARAM wParam, LPARAM lParam)
+{
+ OPTIONSDIALOGPAGE odp = { 0 };
+ odp.cbSize = sizeof(odp);
+ odp.position = 100000000;
+ odp.hInstance = hInstance;
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_FOLDERS);
+ odp.pszTitle = LPGEN("Folders");
+ odp.pszGroup = LPGEN("Customize");
+ odp.groupPosition = 910000000;
+ odp.flags = ODPF_BOLDGROUPS;
+ odp.pfnDlgProc = DlgProcOpts;
+ Options_AddPage(wParam, &odp);
+
+ return 0;
+} \ No newline at end of file
diff --git a/plugins/Folders/src/hooked_events.h b/plugins/Folders/src/hooked_events.h
new file mode 100644
index 0000000000..7a2d427e18
--- /dev/null
+++ b/plugins/Folders/src/hooked_events.h
@@ -0,0 +1,34 @@
+/*
+Custom profile folders plugin for Miranda IM
+
+Copyright © 2005 Cristian Libotean
+
+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 M_FOLDERS_HOOKED_EVENTS_H
+#define M_FOLDERS_HOOKED_EVENTS_H
+
+#include "commonheaders.h"
+#include "services.h"
+
+extern HANDLE hOptionsInitialize;
+
+int UnhookEvents();
+int HookEvents();
+
+int OnOptionsInitialize(WPARAM wParam, LPARAM lParam);
+
+#endif \ No newline at end of file
diff --git a/plugins/Folders/src/resource.h b/plugins/Folders/src/resource.h
new file mode 100644
index 0000000000..e8ff0247cf
--- /dev/null
+++ b/plugins/Folders/src/resource.h
@@ -0,0 +1,27 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by folders.rc
+//
+#define IDD_OPT_FOLDERS 101
+#define IDD_VARIABLES_HELP 102
+#define IDC_FOLDERS_ITEMS_LIST 1002
+#define IDC_FOLDERS_GROUPBOX 1003
+#define IDC_EDIT_FOLDER_GROUPBOX 1004
+#define IDC_FOLDER_EDIT 1005
+#define IDC_REFRESH_BUTTON 1008
+#define IDC_PREVIEW_GROUPBOX 1009
+#define IDC_PREVIEW_EDIT 1010
+#define IDC_HELP_BUTTON 1011
+#define IDC_HELP_RICHEDIT 1012
+#define IDC_FOLDERS_SECTIONS_LIST 1013
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 105
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1014
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/plugins/Folders/src/services.cpp b/plugins/Folders/src/services.cpp
new file mode 100644
index 0000000000..f811bf2246
--- /dev/null
+++ b/plugins/Folders/src/services.cpp
@@ -0,0 +1,250 @@
+/*
+Custom profile folders plugin for Miranda IM
+
+Copyright © 2005 Cristian Libotean
+
+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 "services.h"
+
+#define DEFAULT_SECTION "Unknown"
+
+char szCurrentProfilePath[MAX_FOLDERS_PATH] = {0};
+char szCurrentProfile[MAX_FOLDERS_PATH] = {0};
+char szMirandaPath[MAX_FOLDERS_PATH] = {0};
+char szUserDataPath[MAX_FOLDERS_PATH] = {0};
+
+wchar_t szCurrentProfilePathW[MAX_FOLDERS_PATH] = {0};
+wchar_t szCurrentProfileW[MAX_FOLDERS_PATH] = {0};
+wchar_t szMirandaPathW[MAX_FOLDERS_PATH] = {0};
+wchar_t szUserDataPathW[MAX_FOLDERS_PATH] = {0};
+
+HANDLE hsFoldersGetPath;
+HANDLE hsFoldersGetSize;
+HANDLE hsFoldersGetPathAlloc;
+HANDLE hsFoldersRegisterPath;
+
+int InitServices()
+{
+ ServiceExists(MS_DB_GETPROFILEPATH_BASIC) ? CallService(MS_DB_GETPROFILEPATH_BASIC, sizeof(szCurrentProfilePath), (LPARAM) szCurrentProfilePath) : CallService(MS_DB_GETPROFILEPATH, sizeof(szCurrentProfilePath), (LPARAM) szCurrentProfilePath);
+ CallService(MS_DB_GETPROFILENAME, sizeof(szCurrentProfile), (LPARAM) szCurrentProfile);
+ char *pos = strrchr(szCurrentProfile, '.');
+ szCurrentProfile[pos - szCurrentProfile] = '\0'; //remove the extension (.dat)
+ GetModuleFileNameA(GetModuleHandleA(NULL), szMirandaPath, sizeof(szMirandaPath));
+ pos = strrchr(szMirandaPath, '\\');
+ szMirandaPath[pos - szMirandaPath] = '\0'; //remove '\miranda32.exe'
+
+ char *szTemp = Utils_ReplaceVars("%miranda_userdata%");
+ mir_snprintf(szUserDataPath, MAX_FOLDERS_PATH, szTemp);
+ mir_free(szTemp);
+
+ MultiByteToWideChar(CP_ACP, 0, szCurrentProfilePath, -1, szCurrentProfilePathW, MAX_FOLDERS_PATH);
+ MultiByteToWideChar(CP_ACP, 0, szCurrentProfile, -1, szCurrentProfileW, MAX_FOLDERS_PATH);
+ MultiByteToWideChar(CP_ACP, 0, szMirandaPath, -1, szMirandaPathW, MAX_FOLDERS_PATH);
+ MultiByteToWideChar(CP_ACP, 0, szUserDataPath, -1, szUserDataPathW, MAX_FOLDERS_PATH);
+
+ hsFoldersGetPath = CreateServiceFunction(MS_FOLDERS_GET_PATH, GetPathService);
+// CreateServiceFunction(MS_FOLDERS_GET_PATH_APPEND, GetPathAppendService);
+ hsFoldersGetSize = CreateServiceFunction(MS_FOLDERS_GET_SIZE, GetPathSizeService);
+ hsFoldersGetPathAlloc = CreateServiceFunction(MS_FOLDERS_GET_PATH_ALLOC, GetPathAllocService);
+// CreateServiceFunction(MS_FOLDERS_GET_PATH_ALLOC_APPEND, GetPathAllocAppendService);
+ hsFoldersRegisterPath = CreateServiceFunction(MS_FOLDERS_REGISTER_PATH, RegisterPathService);
+
+ return 0;
+}
+
+int DestroyServices()
+{
+ DestroyServiceFunction(hsFoldersGetPath);
+// DestroyServiceFunction(MS_FOLDERS_GET_PATH_APPEND);
+ DestroyServiceFunction(hsFoldersGetSize);
+ DestroyServiceFunction(hsFoldersGetPathAlloc);
+// DestroyServiceFunction(MS_FOLDERS_GET_PATH_ALLOC_APPEND);
+ DestroyServiceFunction(hsFoldersRegisterPath);
+ return 0;
+}
+
+INT_PTR ExpandPath(char *szResult, char *format, int size)
+{
+ szResult[0] = '\0';
+ char *input = NULL;
+
+ if (ServiceExists(MS_VARS_FORMATSTRING))
+ {
+ TCHAR* tmp_format = mir_a2t(format);
+ TCHAR *vars_result_tmp = variables_parse(tmp_format, NULL, NULL);
+ mir_free(tmp_format);
+ char *vars_result = mir_t2a(vars_result_tmp);
+
+ if (vars_result != NULL)
+ {
+ input = mir_strdup(vars_result);
+
+ variables_free(vars_result_tmp);
+ }
+ mir_free(vars_result);
+ }
+
+ if (input == NULL)
+ {
+ input = mir_strdup(format);
+ }
+
+ char *core_result = Utils_ReplaceVars(input);
+ strncpy(szResult, core_result, size);
+
+ mir_free(core_result);
+
+ StrReplace(szResult, PROFILE_PATH, szCurrentProfilePath);
+ StrReplace(szResult, CURRENT_PROFILE, szCurrentProfile);
+ StrReplace(szResult, MIRANDA_PATH, szMirandaPath);
+ StrReplace(szResult, MIRANDA_USERDATA, szUserDataPath);
+
+ StrTrim(szResult, "\t \\");
+
+ mir_free(input);
+
+ return strlen(szResult);
+}
+
+INT_PTR ExpandPathW(wchar_t *szResult, wchar_t *format, int size)
+{
+ szResult[0] = '\0';
+ wchar_t *input = NULL;
+
+ if (ServiceExists(MS_VARS_FORMATSTRING))
+ {
+ TCHAR* tmp_format = mir_u2t(format);
+ TCHAR *vars_result_tmp = variables_parse(tmp_format, NULL, NULL);
+ mir_free(tmp_format);
+ wchar_t *vars_result = mir_t2u(vars_result_tmp);
+
+ if (vars_result != NULL)
+ {
+ input = mir_wstrdup(vars_result);
+
+ variables_free(vars_result_tmp);
+ }
+ mir_free(vars_result);
+ }
+
+ if (input == NULL)
+ {
+ input = mir_wstrdup(format);
+ }
+
+ wchar_t *core_result = Utils_ReplaceVarsW(input);
+ if (core_result)
+ {
+ wcsncpy(szResult, core_result, size);
+ }
+ else {
+ wcsncpy(szResult, input, size);
+ }
+
+ mir_free(core_result);
+
+ StrReplace(szResult, PROFILE_PATHW, szCurrentProfilePathW);
+ StrReplace(szResult, CURRENT_PROFILEW, szCurrentProfileW);
+ StrReplace(szResult, MIRANDA_PATHW, szMirandaPathW);
+ StrReplace(szResult, MIRANDA_USERDATAW, szUserDataPathW);
+
+ StrTrim(szResult, L"\t \\");
+
+ mir_free(input);
+
+ return wcslen(szResult);
+}
+
+INT_PTR GetPath(int hRegisteredFolder, char *szResult, int size)
+{
+ return lstRegisteredFolders.Expand(hRegisteredFolder, szResult, size);
+ //return 0;
+}
+
+INT_PTR RegisterPathService(WPARAM wParam, LPARAM lParam)
+{
+ FOLDERSDATA tmp = *(FOLDERSDATA *) lParam;
+ int res = 0;
+ if (tmp.cbSize == sizeof(FOLDERSDATA))
+ {
+ res = lstRegisteredFolders.Add(tmp); //returns 1..n or 0 on error
+ }
+ return res;
+}
+
+INT_PTR GetPathSizeService(WPARAM wParam, LPARAM lParam)
+{
+ char tmp[MAX_FOLDER_SIZE * 4]; //dumb
+ int res = lstRegisteredFolders.Expand(wParam, tmp, sizeof(tmp));
+ size_t len = 0;
+ if ((lstRegisteredFolders.Get(wParam)) && (lstRegisteredFolders.Get(wParam)->IsUnicode()))
+ {
+ len = wcslen((wchar_t *)tmp);
+ }
+ else{
+ len = strlen(tmp);
+ }
+ if (lParam != NULL)
+ {
+ *((size_t *) lParam) = len;
+ }
+ return len;
+}
+
+INT_PTR GetPathService(WPARAM wParam, LPARAM lParam)
+{
+ FOLDERSGETDATA data = *(FOLDERSGETDATA *) lParam;
+ size_t res = 1;
+ if (data.cbSize == sizeof(FOLDERSGETDATA))
+ {
+ res = GetPath(wParam, data.szPath, data.nMaxPathSize); //dumb ...
+ }
+ return res;
+}
+
+INT_PTR GetPathAllocService(WPARAM wParam, LPARAM lParam)
+{
+ int size;
+ int res = 1;
+ FOLDERSGETALLOCDATA data = *(FOLDERSGETALLOCDATA *) lParam;
+ if (data.cbSize == sizeof(FOLDERSGETALLOCDATA))
+ {
+ size = GetPathSizeService(wParam, (LPARAM) &size);
+ char **buffer = data.szPath;
+ *buffer = (char *) mir_alloc(size + 1);
+ res = GetPath(wParam, *buffer, size);
+ }
+ return res;
+}
+/*
+int GetPathAppendService(WPARAM wParam, LPARAM lParam)
+{
+ FOLDERSAPPENDDATA data = *(FOLDERSAPPENDDATA *) wParam;
+ int res = GetPathService(data.hRegisteredPath, lParam);
+ strcat((char *) lParam, data.szAppendData);
+ return res;
+}
+*/
+/*
+int GetPathAllocAppendService(WPARAM wParam, LPARAM lParam)
+{
+ FOLDERSAPPENDDATA data = *(FOLDERSAPPENDDATA *) wParam;
+ int res = GetPathAllocService(data.hRegisteredPath, lParam);
+ strcat(*(char **) lParam, data.szAppendData);
+ return res;
+}
+*/ \ No newline at end of file
diff --git a/plugins/Folders/src/services.h b/plugins/Folders/src/services.h
new file mode 100644
index 0000000000..3a2ee1aa9f
--- /dev/null
+++ b/plugins/Folders/src/services.h
@@ -0,0 +1,50 @@
+/*
+Custom profile folders plugin for Miranda IM
+
+Copyright © 2005 Cristian Libotean
+
+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 M_FOLDERS_PROVIDED_SERVICES_H
+#define M_FOLDERS_PROVIDED_SERVICES_H
+
+#include "commonheaders.h"
+#include "m_folders.h"
+
+#define MAX_FOLDERS_PATH 512
+
+extern char szCurrentProfilePath[MAX_FOLDERS_PATH];
+extern char szCurrentProfile[MAX_FOLDERS_PATH];
+extern char szMirandaPath[MAX_FOLDERS_PATH];
+
+extern wchar_t szCurrentProfilePathW[MAX_FOLDERS_PATH];
+extern wchar_t szCurrentProfileW[MAX_FOLDERS_PATH];
+extern wchar_t szMirandaPathW[MAX_FOLDERS_PATH];
+
+int InitServices();
+int DestroyServices();
+INT_PTR ExpandPath(char *szResult, char *format, int size);
+INT_PTR ExpandPathW(wchar_t *szResult, wchar_t *format, int size);
+INT_PTR GetPath(int hRegisteredFolder, char *szResult, int size);
+
+INT_PTR RegisterPathService(WPARAM wParam, LPARAM lParam);
+INT_PTR GetPathSizeService(WPARAM wParam, LPARAM lParam);
+INT_PTR GetPathService(WPARAM wParam, LPARAM lParam);
+INT_PTR GetPathAllocService(WPARAM wParam, LPARAM lParam);
+//int GetPathAppendService(WPARAM wParam, LPARAM lParam);
+//int GetPathAllocAppendService(WPARAM wParam, LPARAM lParam);
+
+#endif //M_FOLDERS_PROVIDED_SERVICES_H \ No newline at end of file
diff --git a/plugins/Folders/src/utils.cpp b/plugins/Folders/src/utils.cpp
new file mode 100644
index 0000000000..64623b63f1
--- /dev/null
+++ b/plugins/Folders/src/utils.cpp
@@ -0,0 +1,357 @@
+/*
+Custom profile folders plugin for Miranda IM
+
+Copyright © 2005 Cristian Libotean
+
+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 "utils.h"
+
+int Log(char *format, ...)
+{
+#ifdef _DEBUG
+ char str[4096];
+ va_list vararg;
+ int tBytes;
+ FILE *fout = fopen("folders.log", "at");
+
+ va_start(vararg, format);
+
+ tBytes = _vsnprintf(str, sizeof(str), format, vararg);
+ if (tBytes > 0)
+ {
+ str[tBytes] = 0;
+ }
+
+ va_end(vararg);
+ if (str[strlen(str) - 1] != '\n')
+ {
+ strcat(str, "\n");
+ }
+ fputs(str, fout);
+ fclose(fout);
+#endif
+ return 0;
+}
+
+char *StrCopy(char *source, size_t index, const char *what, size_t count)
+{
+ size_t i;
+ for (i = 0; i < count; i++)
+ {
+ source[index + i] = what[i];
+ }
+ return source;
+}
+
+wchar_t *StrCopy(wchar_t *source, size_t index, const wchar_t *what, size_t count)
+{
+ size_t i;
+ for (i = 0; i < count; i++)
+ {
+ source[index + i] = what[i];
+ }
+ return source;
+}
+
+char *StrDelete(char *source, size_t index, size_t count)
+{
+ size_t len = strlen(source);
+ size_t i;
+ count = (count + index > len) ? len - index : count;
+ for (i = index; i + count <= len; i++)
+ {
+ source[i] = source[i + count];
+ }
+ return source;
+}
+
+wchar_t *StrDelete(wchar_t *source, size_t index, size_t count)
+{
+ size_t len = wcslen(source);
+ size_t i;
+ count = (count + index > len) ? len - index : count;
+ for (i = index; i + count <= len; i++)
+ {
+ source[i] = source[i + count];
+ }
+ return source;
+}
+
+
+char *StrInsert(char *source, size_t index, const char *what)
+{
+ size_t whatLen = strlen(what);
+ size_t sourceLen = strlen(source);
+ size_t i;
+ for (i = sourceLen; i >= index; i--)
+ {
+ source[i + whatLen] = source[i];
+ }
+ for (i = 0; i < whatLen; i++)
+ {
+ source[index + i] = what[i];
+ }
+ return source;
+}
+
+wchar_t *StrInsert(wchar_t *source, size_t index, const wchar_t *what)
+{
+ size_t whatLen = wcslen(what);
+ size_t sourceLen = wcslen(source);
+ size_t i;
+ for (i = sourceLen; i >= index; i--)
+ {
+ source[i + whatLen] = source[i];
+ }
+ for (i = 0; i < whatLen; i++)
+ {
+ source[index + i] = what[i];
+ }
+ return source;
+}
+
+
+char *StrReplace(char *source, const char *what, const char *withWhat)
+{
+ char *pos;
+ size_t whatLen = strlen(what);
+ size_t withWhatLen = strlen(withWhat);
+ size_t minLen;
+ size_t index;
+
+ while ((pos = strstr(source, what)))
+ {
+ minLen = min(whatLen, withWhatLen);
+ StrCopy(source, pos - source, withWhat, minLen);
+ index = pos - source + minLen;
+ if (whatLen > withWhatLen)
+ {
+ StrDelete(source, index, whatLen - withWhatLen);
+ }
+ else{
+ if (whatLen < withWhatLen)
+ {
+ StrInsert(source, index, withWhat + minLen);
+ }
+ }
+ }
+ return source;
+}
+
+wchar_t *StrReplace(wchar_t *source, const wchar_t *what, const wchar_t *withWhat)
+{
+ wchar_t *pos;
+ size_t whatLen = wcslen(what);
+ size_t withWhatLen = wcslen(withWhat);
+ size_t minLen;
+ size_t index;
+
+ while ((pos = wcsstr(source, what)))
+ {
+ minLen = min(whatLen, withWhatLen);
+ StrCopy(source, pos - source, withWhat, minLen);
+ index = pos - source + minLen;
+ if (whatLen > withWhatLen)
+ {
+ StrDelete(source, index, whatLen - withWhatLen);
+ }
+ else{
+ if (whatLen < withWhatLen)
+ {
+ StrInsert(source, index, withWhat + minLen);
+ }
+ }
+ }
+ return source;
+}
+
+char *StrTrim(char *szText, const char *szTrimChars)
+{
+ size_t i = strlen(szText) - 1;
+ while ((i >= 0) && (strchr(szTrimChars, szText[i])))
+ {
+ szText[i--] = '\0';
+ }
+ i = 0;
+ while ((i < strlen(szText)) && (strchr(szTrimChars, szText[i])))
+ {
+ i++;
+ }
+ if (i)
+ {
+ StrDelete(szText, 0, i);
+ }
+ return szText;
+}
+
+wchar_t *StrTrim(wchar_t *szText, const wchar_t *szTrimChars)
+{
+ size_t i = wcslen(szText) - 1;
+ while ((i >= 0) && (wcschr(szTrimChars, szText[i])))
+ {
+ szText[i--] = '\0';
+ }
+ i = 0;
+ while ((i < wcslen(szText)) && (wcschr(szTrimChars, szText[i])))
+ {
+ i++;
+ }
+ if (i)
+ {
+ StrDelete(szText, 0, i);
+ }
+ return szText;
+}
+
+void CreateDirectories(char *path)
+{
+ char *pos = path;
+ char tmp;
+ while (pos = strchr(pos, '\\'))
+ {
+ tmp = pos[0];
+ pos[0] = '\0';
+ CreateDirectoryA(path, NULL);
+ pos[0] = tmp;
+ pos++;
+ }
+ CreateDirectoryA(path, NULL);
+ GetLastError();
+}
+
+void CreateDirectories(wchar_t *path)
+{
+ wchar_t *pos = path;
+ wchar_t tmp;
+ while (pos = wcschr(pos, '\\'))
+ {
+ tmp = pos[0];
+ pos[0] = '\0';
+ CreateDirectoryW(path, NULL);
+ pos[0] = tmp;
+ pos++;
+ }
+ CreateDirectoryW(path, NULL);
+ GetLastError();
+}
+
+void RemoveDirectories(char *path)
+{
+ char *pos;
+ char *buffer = _strdup(path);
+ if (!(GetFileAttributesA(buffer) & FILE_ATTRIBUTE_REPARSE_POINT)) { RemoveDirectoryA(buffer); }
+ while (pos = strrchr(buffer, '\\'))
+ {
+ pos[0] = '\0';
+ if (!(GetFileAttributesA(buffer) & FILE_ATTRIBUTE_REPARSE_POINT)) { RemoveDirectoryA(buffer); }
+ }
+ free(buffer);
+}
+
+void RemoveDirectories(wchar_t *path)
+{
+ wchar_t *pos;
+ wchar_t *buffer = _wcsdup(path);
+ if (!(GetFileAttributesW(buffer) & FILE_ATTRIBUTE_REPARSE_POINT)) { RemoveDirectoryW(buffer); }
+ while (pos = wcsrchr(buffer, '\\'))
+ {
+ pos[0] = '\0';
+ if (!(GetFileAttributesW(buffer) & FILE_ATTRIBUTE_REPARSE_POINT)) { RemoveDirectoryW(buffer); }
+ }
+ free(buffer);
+}
+
+int DirectoryExists(char *path)
+{
+ char buffer[4096];
+ GetCurrentDirectoryA(sizeof(buffer), buffer);
+ int res = SetCurrentDirectoryA(path);
+ SetCurrentDirectoryA(buffer);
+ return res;
+}
+
+int DirectoryExists(wchar_t *path)
+{
+ wchar_t buffer[4096];
+ GetCurrentDirectoryW(sizeof(buffer), buffer);
+ int res = SetCurrentDirectoryW(path);
+ SetCurrentDirectoryW(buffer);
+ return res;
+}
+
+
+int GetStringFromDatabase(char *szSettingName, const char *szError, char *szResult, size_t size)
+{
+ DBVARIANT dbv = {0};
+ int res = 1;
+ size_t len;
+ dbv.type = DBVT_ASCIIZ;
+ if (DBGetContactSetting(NULL, ModuleName, szSettingName, &dbv) == 0)
+ {
+ res = 0;
+ size_t tmp = strlen(dbv.pszVal);
+ len = (tmp < size - 1) ? tmp : size - 1;
+ strncpy(szResult, dbv.pszVal, len);
+ szResult[len] = '\0';
+ mir_free(dbv.pszVal);
+ }
+ else{
+ res = 1;
+ size_t tmp = strlen(szError);
+ len = (tmp < size - 1) ? tmp : size - 1;
+ strncpy(szResult, szError, len);
+ szResult[len] = '\0';
+ }
+ return res;
+}
+
+int GetStringFromDatabase(char *szSettingName, const wchar_t *szError, wchar_t *szResult, size_t size)
+{
+ DBVARIANT dbv = {0};
+ int res = 1;
+ size_t len;
+ dbv.type = DBVT_WCHAR;
+ if (DBGetContactSettingWString(NULL, ModuleName, szSettingName, &dbv) == 0)
+ //if (DBGetContactSetting(NULL, ModuleName, szSettingName, &dbv) == 0)
+ {
+ res = 0;
+ size_t tmp = wcslen(dbv.pwszVal);
+ len = (tmp < size - 1) ? tmp : size - 1;
+ wcsncpy(szResult, dbv.pwszVal, len);
+ szResult[len] = '\0';
+ mir_free(dbv.pwszVal);
+ }
+ else{
+ res = 1;
+ size_t tmp = wcslen(szError);
+ len = (tmp < size - 1) ? tmp : size - 1;
+ wcsncpy(szResult, szError, len);
+ szResult[len] = '\0';
+ }
+ return res;
+}
+
+
+int WriteStringToDatabase(char *szSettingName, const char *szValue)
+{
+ return DBWriteContactSettingString(NULL, ModuleName, szSettingName, szValue);
+}
+
+int WriteStringToDatabase(char *szSettingName, const wchar_t *szValue)
+{
+ return DBWriteContactSettingWString(NULL, ModuleName, szSettingName, szValue);
+} \ No newline at end of file
diff --git a/plugins/Folders/src/utils.h b/plugins/Folders/src/utils.h
new file mode 100644
index 0000000000..066c822900
--- /dev/null
+++ b/plugins/Folders/src/utils.h
@@ -0,0 +1,62 @@
+/*
+Custom profile folders plugin for Miranda IM
+
+Copyright © 2005 Cristian Libotean
+
+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 M_FOLDERS_UTILS_H
+#define M_FOLDERS_UTILS_H
+
+#include <stdarg.h>
+#include "commonheaders.h"
+
+int Log(char *format, ...);
+
+char *StrReplace(char *source, const char *what, const char *withWhat);
+char *StrCopy(char *source, size_t index, const char *what, size_t count);
+char *StrDelete(char *source, size_t index, size_t count);
+char *StrInsert(char *source, size_t index, const char *what);
+char *StrTrim(char *szText, const char *szTrimChars);
+
+wchar_t *StrReplace(wchar_t *source, const wchar_t *what, const wchar_t *withWhat);
+wchar_t *StrCopy(wchar_t *source, size_t index, const wchar_t *what, size_t count);
+wchar_t *StrDelete(wchar_t *source, size_t index, size_t count);
+wchar_t *StrInsert(wchar_t *source, size_t index, const wchar_t *what);
+wchar_t *StrTrim(wchar_t *szText, const wchar_t *szTrimChars);
+
+void CreateDirectories(char *szPath);
+void RemoveDirectories(char *szPath);
+int DirectoryExists(char *szPath);
+
+void CreateDirectories(wchar_t *szPath);
+void RemoveDirectories(wchar_t *szPath);
+int DirectoryExists(wchar_t *szPath);
+
+int GetStringFromDatabase(char *szSettingName, const char *szError, char *szResult, size_t size);
+int WriteStringToDatabase(char *szSettingName, const char *szValue);
+
+int GetStringFromDatabase(char *szSettingName, const wchar_t *szError, wchar_t *szResult, size_t size);
+int WriteStringToDatabase(char *szSettingName, const wchar_t *szValue);
+
+__inline static wchar_t *Utils_ReplaceVarsW(wchar_t *szData) {
+ REPLACEVARSDATA dat = {0};
+ dat.cbSize = sizeof(dat);
+ dat.dwFlags = RVF_UNICODE;
+ return (wchar_t *) CallService(MS_UTILS_REPLACEVARS, (WPARAM) szData, (LPARAM) &dat);
+}
+
+#endif \ No newline at end of file
diff --git a/plugins/Folders/src/version.h b/plugins/Folders/src/version.h
new file mode 100644
index 0000000000..5aff03dd5a
--- /dev/null
+++ b/plugins/Folders/src/version.h
@@ -0,0 +1,45 @@
+/*
+Custom profile folders plugin for Miranda IM
+
+Copyright © 2005-2012 Cristian Libotean
+
+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 M_FOLDERS_VERSION_H
+#define M_FOLDERS_VERSION_H
+
+#define __MAJOR_VERSION 0
+#define __MINOR_VERSION 1
+#define __RELEASE_NUM 6
+#define __BUILD_NUM 1
+
+#define VERSION PLUGIN_MAKE_VERSION(__MAJOR_VERSION, __MINOR_VERSION, __RELEASE_NUM, __BUILD_NUM)
+
+#define __PLUGINVERSION_STRING __MAJOR_VERSION,__MINOR_VERSION,__RELEASE_NUM,__BUILD_NUM
+#define __PLUGINVERSION_STRING_DOTS __MAJOR_VERSION.__MINOR_VERSION.__RELEASE_NUM.__BUILD_NUM
+#define __STRINGIFY_(x) #x
+#define __STRINGIFY(x) __STRINGIFY_(x)
+#define __VERSION_STRING __STRINGIFY(__PLUGINVERSION_STRING_DOTS)
+
+#define __DESC "Service plugin. Allows plugins to save their data to user selected folders; supports variables."
+#define __AUTHOR "Cristian Libotean"
+#define __AUTHOREMAIL "eblis102@yahoo.com"
+#define __COPYRIGHT "© 2005-2012 Cristian Libotean"
+#define __AUTHORWEB "http://www.miranda-im.org/"
+#define __PLUGIN_DISPLAY_NAME "Custom profile folders"
+
+
+#endif //M_FOLDERS_VERSION_H