summaryrefslogtreecommitdiff
path: root/src/mir_app/src/FontOptions.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mir_app/src/FontOptions.cpp')
-rw-r--r--src/mir_app/src/FontOptions.cpp1389
1 files changed, 1389 insertions, 0 deletions
diff --git a/src/mir_app/src/FontOptions.cpp b/src/mir_app/src/FontOptions.cpp
new file mode 100644
index 0000000000..982fb25e2e
--- /dev/null
+++ b/src/mir_app/src/FontOptions.cpp
@@ -0,0 +1,1389 @@
+/*
+
+Miranda NG: the free IM client for Microsoft* Windows*
+
+Copyright (ñ) 2012-15 Miranda NG project (http://miranda-ng.org),
+Copyright (c) 2000-12 Miranda IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "stdafx.h"
+#include "FontService.h"
+
+// *_w2 is working copy of list
+// *_w3 is stores initial configuration
+
+static int sttCompareFont(const FontInternal* p1, const FontInternal* p2)
+{
+ int result = mir_tstrcmp(p1->group, p2->group);
+ if (result != 0)
+ return result;
+
+ result = p1->order - p2->order;
+ if (result != 0)
+ return result;
+
+ return mir_tstrcmp(p1->getName(), p2->getName());
+}
+
+OBJLIST<FontInternal> font_id_list(20, sttCompareFont), font_id_list_w2(20, sttCompareFont), font_id_list_w3(20, sttCompareFont);
+
+static int sttCompareColour(const ColourInternal* p1, const ColourInternal* p2)
+{
+ int result = mir_tstrcmp(p1->group, p2->group);
+ if (result != 0)
+ return result;
+
+ result = p1->order - p2->order;
+ if (result != 0)
+ return result;
+
+ return mir_tstrcmp(p1->getName(), p2->getName());
+}
+
+OBJLIST<ColourInternal> colour_id_list(10, sttCompareColour), colour_id_list_w2(10, sttCompareColour), colour_id_list_w3(10, sttCompareColour);
+
+static int sttCompareEffect(const EffectInternal* p1, const EffectInternal* p2)
+{
+ int result = mir_tstrcmp(p1->group, p2->group);
+ if (result != 0)
+ return result;
+
+ result = p1->order - p2->order;
+ if (result != 0)
+ return result;
+
+ return mir_tstrcmp(p1->getName(), p2->getName());
+}
+
+OBJLIST<EffectInternal> effect_id_list(10, sttCompareEffect), effect_id_list_w2(10, sttCompareEffect), effect_id_list_w3(10, sttCompareEffect);
+
+struct DrawTextWithEffectParam
+{
+ int cbSize;
+ HDC hdc; // handle to DC
+ LPCTSTR lpchText; // text to draw
+ int cchText; // length of text to draw
+ LPRECT lprc; // rectangle coordinates
+ UINT dwDTFormat; // formatting options
+ FONTEFFECT * pEffect; // effect to be drawn on
+};
+
+#define MS_DRAW_TEXT_WITH_EFFECTA "Modern/SkinEngine/DrawTextWithEffectA"
+#define MS_DRAW_TEXT_WITH_EFFECTW "Modern/SkinEngine/DrawTextWithEffectW"
+
+#define MS_DRAW_TEXT_WITH_EFFECT MS_DRAW_TEXT_WITH_EFFECTW
+
+// Helper
+int __inline DrawTextWithEffect(HDC hdc, LPCTSTR lpchText, int cchText, RECT * lprc, UINT dwDTFormat, FONTEFFECT * pEffect)
+{
+ DrawTextWithEffectParam params;
+ static BYTE bIfServiceExists = ServiceExists(MS_DRAW_TEXT_WITH_EFFECT) ? 1 : 0;
+
+ if (pEffect == NULL || pEffect->effectIndex == 0)
+ return DrawText(hdc, lpchText, cchText, lprc, dwDTFormat); // If no effect specified draw by GDI it just more careful with ClearType
+
+ if (bIfServiceExists == 0)
+ return DrawText(hdc, lpchText, cchText, lprc, dwDTFormat);
+
+ // else
+ params.cbSize = sizeof(DrawTextWithEffectParam);
+ params.hdc = hdc;
+ params.lpchText = lpchText;
+ params.cchText = cchText;
+ params.lprc = lprc;
+ params.dwDTFormat = dwDTFormat;
+ params.pEffect = pEffect;
+ return CallService(MS_DRAW_TEXT_WITH_EFFECT, (WPARAM)&params, 0);
+}
+
+#define UM_SETFONTGROUP (WM_USER + 101)
+#define TIMER_ID 11015
+
+#define FSUI_COLORBOXWIDTH 50
+#define FSUI_COLORBOXLEFT 5
+#define FSUI_FONTFRAMEHORZ 5
+#define FSUI_FONTFRAMEVERT 4
+#define FSUI_FONTLEFT (FSUI_COLORBOXLEFT+FSUI_COLORBOXWIDTH+5)
+
+void UpdateFontSettings(FontIDW *font_id, FontSettingsT *fontsettings);
+void UpdateColourSettings(ColourIDW *colour_id, COLORREF *colour);
+void UpdateEffectSettings(EffectIDW *effect_id, FONTEFFECT* effectsettings);
+
+static void WriteLine(FILE *out, const char pszText[])
+{
+ fputs(pszText, out);
+ fputc('\n', out);
+}
+
+static BOOL ExportSettings(HWND hwndDlg, const TCHAR *filename, OBJLIST<FontInternal>& flist, OBJLIST<ColourInternal>& clist, OBJLIST<EffectInternal>& elist)
+{
+ FILE *out = _tfopen(filename, _T("w"));
+ if (out == NULL) {
+ MessageBox(hwndDlg, filename, TranslateT("Failed to create file"), MB_ICONWARNING | MB_OK);
+ return FALSE;
+ }
+
+ char header[512], buff[1024];
+ header[0] = 0;
+
+ fputs("SETTINGS:\n\n", out);
+
+ for (int i = 0; i < flist.getCount(); i++) {
+ FontInternal& F = flist[i];
+
+ mir_snprintf(buff, "\n[%s]", F.dbSettingsGroup);
+ if (mir_strcmp(buff, header) != 0) {
+ strncpy(header, buff, SIZEOF(header));
+ WriteLine(out, buff);
+ }
+
+ fprintf(out, (F.flags & FIDF_APPENDNAME) ? "%sName=s%S\n" : "%s=s%S\n", F.prefix, F.value.szFace);
+
+ int iFontSize;
+ if (F.flags & FIDF_SAVEACTUALHEIGHT) {
+ SIZE size;
+ LOGFONT lf;
+ CreateFromFontSettings(&F.value, &lf);
+ HFONT hFont = CreateFontIndirect(&lf);
+
+ HDC hdc = GetDC(hwndDlg);
+ HFONT hOldFont = (HFONT)SelectObject(hdc, hFont);
+ GetTextExtentPoint32(hdc, _T("_W"), 2, &size);
+ ReleaseDC(hwndDlg, hdc);
+ SelectObject(hdc, hOldFont);
+ DeleteObject(hFont);
+
+ iFontSize = size.cy;
+ }
+ else if (F.flags & FIDF_SAVEPOINTSIZE) {
+ HDC hdc = GetDC(hwndDlg);
+ iFontSize = (BYTE)-MulDiv(F.value.size, 72, GetDeviceCaps(hdc, LOGPIXELSY));
+ ReleaseDC(hwndDlg, hdc);
+ }
+ else iFontSize = F.value.size;
+ fprintf(out, "%sSize=b%d\n", F.prefix, iFontSize);
+
+ fprintf(out, "%sSty=b%d\n", F.prefix, F.value.style);
+ fprintf(out, "%sSet=b%d\n", F.prefix, F.value.charset);
+ fprintf(out, "%sCol=d%d\n", F.prefix, F.value.colour);
+
+ if (F.flags & FIDF_NOAS)
+ fprintf(out, "%sAs=w%d\n", F.prefix, 0x00FF);
+
+ fprintf(out, "%sFlags=w%d\n", F.prefix, F.flags);
+ }
+
+ header[0] = 0;
+ for (int i = 0; i < clist.getCount(); i++) {
+ ColourInternal& C = clist[i];
+
+ mir_snprintf(buff, "\n[%s]", C.dbSettingsGroup);
+ if (mir_strcmp(buff, header) != 0) {
+ strncpy_s(header, buff, _TRUNCATE);
+ WriteLine(out, buff);
+ }
+ fprintf(out, "%s=d%d\n", C.setting, (DWORD)C.value);
+ }
+
+ header[0] = 0;
+ for (int i = 0; i < elist.getCount(); i++) {
+ EffectInternal& E = elist[i];
+
+ mir_snprintf(buff, "\n[%s]", E.dbSettingsGroup);
+ if (mir_strcmp(buff, header) != 0) {
+ strncpy_s(header, buff, _TRUNCATE);
+ WriteLine(out, buff);
+ }
+ fprintf(out, "%sEffect=b%d\n", E.setting, E.value.effectIndex);
+ fprintf(out, "%sEffectCol1=d%d\n", E.setting, E.value.baseColour);
+ fprintf(out, "%sEffectCol2=d%d\n", E.setting, E.value.secondaryColour);
+ }
+
+ fclose(out);
+ return TRUE;
+}
+
+void OptionsChanged()
+{
+ NotifyEventHooks(hFontReloadEvent, 0, 0);
+ NotifyEventHooks(hColourReloadEvent, 0, 0);
+}
+
+TOOLINFO ti;
+int x, y;
+
+UINT_PTR CALLBACK CFHookProc(HWND hdlg, UINT uiMsg, WPARAM, LPARAM lParam)
+{
+ if (uiMsg == WM_INITDIALOG) {
+ CHOOSEFONT* cf = (CHOOSEFONT *)lParam;
+ if (cf != NULL) {
+ if (cf->lCustData & FIDF_DISABLESTYLES) {
+ EnableWindow(GetDlgItem(hdlg, 1137), FALSE);
+ ShowWindow(GetDlgItem(hdlg, 1137), SW_HIDE);
+ ShowWindow(GetDlgItem(hdlg, 1095), SW_SHOW);
+ }
+ else if (cf->lCustData & FIDF_ALLOWEFFECTS) {
+ EnableWindow(GetDlgItem(hdlg, 1139), FALSE);
+ ShowWindow(GetDlgItem(hdlg, 1139), SW_HIDE);
+ ShowWindow(GetDlgItem(hdlg, 1091), SW_HIDE);
+ }
+ }
+ }
+
+ return 0;
+}
+
+struct FSUIListItemData
+{
+ int font_id;
+ int colour_id;
+ int effect_id;
+};
+
+static BOOL sttFsuiBindColourIdToFonts(HWND hwndList, const TCHAR *name, const TCHAR *backgroundGroup, const TCHAR *backgroundName, int colourId)
+{
+ BOOL res = FALSE;
+ for (int i = SendMessage(hwndList, LB_GETCOUNT, 0, 0); i--;) {
+ FSUIListItemData *itemData = (FSUIListItemData *)SendMessage(hwndList, LB_GETITEMDATA, i, 0);
+ if (itemData && itemData->font_id >= 0) {
+ FontInternal& F = font_id_list_w2[itemData->font_id];
+
+ if (name && !mir_tstrcmp(F.name, name)) {
+ itemData->colour_id = colourId;
+ res = TRUE;
+ }
+
+ if (backgroundGroup && backgroundName && !mir_tstrcmp(F.backgroundGroup, backgroundGroup) && !mir_tstrcmp(F.backgroundName, backgroundName)) {
+ itemData->colour_id = colourId;
+ res = TRUE;
+ }
+ }
+ }
+
+ return res;
+}
+
+static bool sttFsuiBindEffectIdToFonts(HWND hwndList, const TCHAR *name, int effectId)
+{
+ for (int i = SendMessage(hwndList, LB_GETCOUNT, 0, 0); i--;) {
+ FSUIListItemData *itemData = (FSUIListItemData *)SendMessage(hwndList, LB_GETITEMDATA, i, 0);
+ if (itemData && itemData->font_id >= 0) {
+ FontInternal& F = font_id_list_w2[itemData->font_id];
+
+ if (name && !mir_tstrcmp(F.name, name)) {
+ itemData->effect_id = effectId;
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+static HTREEITEM sttFindNamedTreeItemAt(HWND hwndTree, HTREEITEM hItem, const TCHAR *name)
+{
+ TVITEM tvi = { 0 };
+ TCHAR str[MAX_PATH];
+
+ if (hItem)
+ tvi.hItem = TreeView_GetChild(hwndTree, hItem);
+ else
+ tvi.hItem = TreeView_GetRoot(hwndTree);
+
+ if (!name)
+ return tvi.hItem;
+
+ tvi.mask = TVIF_TEXT;
+ tvi.pszText = str;
+ tvi.cchTextMax = SIZEOF(str);
+
+ while (tvi.hItem) {
+ TreeView_GetItem(hwndTree, &tvi);
+
+ if (!mir_tstrcmp(tvi.pszText, name))
+ return tvi.hItem;
+
+ tvi.hItem = TreeView_GetNextSibling(hwndTree, tvi.hItem);
+ }
+ return NULL;
+}
+
+static void sttFsuiCreateSettingsTreeNode(HWND hwndTree, const TCHAR *groupName, int hLangpack)
+{
+ TCHAR itemName[1024];
+ TCHAR* sectionName;
+ int sectionLevel = 0;
+
+ HTREEITEM hSection = NULL;
+ mir_tstrcpy(itemName, groupName);
+ sectionName = itemName;
+
+ while (sectionName) {
+ // allow multi-level tree
+ TCHAR* pItemName = sectionName;
+ HTREEITEM hItem;
+
+ // one level deeper
+ if (sectionName = _tcschr(sectionName, '/'))
+ *sectionName = 0;
+
+ pItemName = TranslateTH(hLangpack, pItemName);
+
+ hItem = sttFindNamedTreeItemAt(hwndTree, hSection, pItemName);
+ if (!sectionName || !hItem) {
+ if (!hItem) {
+ TVINSERTSTRUCT tvis = { 0 };
+ TreeItem *treeItem = (TreeItem *)mir_alloc(sizeof(TreeItem));
+ treeItem->groupName = sectionName ? NULL : mir_tstrdup(groupName);
+ treeItem->paramName = mir_t2a(itemName);
+
+ tvis.hParent = hSection;
+ tvis.hInsertAfter = TVI_SORT;//TVI_LAST;
+ tvis.item.mask = TVIF_TEXT | TVIF_PARAM;
+ tvis.item.pszText = pItemName;
+ tvis.item.lParam = (LPARAM)treeItem;
+
+ hItem = TreeView_InsertItem(hwndTree, &tvis);
+
+ memset(&tvis.item, 0, sizeof(tvis.item));
+ tvis.item.hItem = hItem;
+ tvis.item.mask = TVIF_HANDLE | TVIF_STATE;
+ tvis.item.state = tvis.item.stateMask = db_get_b(NULL, "FontServiceUI", treeItem->paramName, TVIS_EXPANDED);
+ TreeView_SetItem(hwndTree, &tvis.item);
+ }
+ }
+
+ if (sectionName) {
+ *sectionName = '/';
+ sectionName++;
+ }
+
+ sectionLevel++;
+
+ hSection = hItem;
+ }
+}
+
+static void sttSaveCollapseState(HWND hwndTree)
+{
+ HTREEITEM hti;
+ TVITEM tvi;
+
+ hti = TreeView_GetRoot(hwndTree);
+ while (hti != NULL) {
+ HTREEITEM ht;
+ TreeItem *treeItem;
+
+ tvi.mask = TVIF_STATE | TVIF_HANDLE | TVIF_CHILDREN | TVIF_PARAM;
+ tvi.hItem = hti;
+ tvi.stateMask = (DWORD)-1;
+ TreeView_GetItem(hwndTree, &tvi);
+
+ if (tvi.cChildren > 0) {
+ treeItem = (TreeItem *)tvi.lParam;
+ if (tvi.state & TVIS_EXPANDED)
+ db_set_b(NULL, "FontServiceUI", treeItem->paramName, TVIS_EXPANDED);
+ else
+ db_set_b(NULL, "FontServiceUI", treeItem->paramName, 0);
+ }
+
+ ht = TreeView_GetChild(hwndTree, hti);
+ if (ht == NULL) {
+ ht = TreeView_GetNextSibling(hwndTree, hti);
+ while (ht == NULL) {
+ hti = TreeView_GetParent(hwndTree, hti);
+ if (hti == NULL) break;
+ ht = TreeView_GetNextSibling(hwndTree, hti);
+ }
+ }
+
+ hti = ht;
+ }
+}
+
+static void sttFreeListItems(HWND hList)
+{
+ int count = SendMessage(hList, LB_GETCOUNT, 0, 0);
+ if (count > 0) {
+ for (int idx = 0; idx < count; idx++) {
+ LRESULT res = SendMessage(hList, LB_GETITEMDATA, idx, 0);
+ FSUIListItemData *itemData = (FSUIListItemData *)res;
+ if (itemData && res != LB_ERR)
+ mir_free(itemData);
+ }
+ }
+}
+
+static void ShowEffectButton(HWND hwndDlg, BOOL bShow)
+{
+ ShowWindow(GetDlgItem(hwndDlg, IDC_BKGCOLOUR), bShow ? SW_HIDE : SW_SHOW);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_BKGCOLOUR_STATIC), bShow ? SW_HIDE : SW_SHOW);
+
+ ShowWindow(GetDlgItem(hwndDlg, IDC_EFFECT), bShow ? SW_SHOW : SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_EFFECT_STATIC), bShow ? SW_SHOW : SW_HIDE);
+}
+
+TCHAR* ModernEffectNames[] = { LPGENT("<none>"), LPGENT("Shadow at left"), LPGENT("Shadow at right"), LPGENT("Outline"), LPGENT("Outline smooth"), LPGENT("Smooth bump"), LPGENT("Contour thin"), LPGENT("Contour heavy") };
+
+static INT_PTR CALLBACK ChooseEffectDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ static FONTEFFECT * pEffect = NULL;
+
+ switch (uMsg) {
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hwndDlg);
+ pEffect = (FONTEFFECT*)lParam;
+ {
+ for (int i = 0; i < SIZEOF(ModernEffectNames); i++) {
+ int itemid = SendDlgItemMessage(hwndDlg, IDC_EFFECT_COMBO, CB_ADDSTRING, 0, (LPARAM)TranslateTS(ModernEffectNames[i]));
+ SendDlgItemMessage(hwndDlg, IDC_EFFECT_COMBO, CB_SETITEMDATA, itemid, i);
+ SendDlgItemMessage(hwndDlg, IDC_EFFECT_COMBO, CB_SETCURSEL, 0, 0);
+ }
+
+ int cnt = SendDlgItemMessage(hwndDlg, IDC_EFFECT_COMBO, CB_GETCOUNT, 0, 0);
+ for (int i = 0; i < cnt; i++) {
+ if (SendDlgItemMessage(hwndDlg, IDC_EFFECT_COMBO, CB_GETITEMDATA, i, 0) == pEffect->effectIndex) {
+ SendDlgItemMessage(hwndDlg, IDC_EFFECT_COMBO, CB_SETCURSEL, i, 0);
+ break;
+ }
+ }
+ }
+
+ SendDlgItemMessage(hwndDlg, IDC_EFFECT_COLOUR1, CPM_SETCOLOUR, 0, pEffect->baseColour & 0x00FFFFFF);
+ SendDlgItemMessage(hwndDlg, IDC_EFFECT_COLOUR2, CPM_SETCOLOUR, 0, pEffect->secondaryColour & 0x00FFFFFF);
+
+ SendDlgItemMessage(hwndDlg, IDC_EFFECT_COLOUR_SPIN1, UDM_SETRANGE, 0, MAKELONG(255, 0));
+ SendDlgItemMessage(hwndDlg, IDC_EFFECT_COLOUR_SPIN2, UDM_SETRANGE, 0, MAKELONG(255, 0));
+ SendDlgItemMessage(hwndDlg, IDC_EFFECT_COLOUR_SPIN1, UDM_SETPOS, 0, MAKELONG((BYTE)~((BYTE)((pEffect->baseColour & 0xFF000000) >> 24)), 0));
+ SendDlgItemMessage(hwndDlg, IDC_EFFECT_COLOUR_SPIN2, UDM_SETPOS, 0, MAKELONG((BYTE)~((BYTE)((pEffect->secondaryColour & 0xFF000000) >> 24)), 0));
+ return TRUE;
+
+ case WM_COMMAND:
+ switch (LOWORD(wParam)) {
+ case IDOK:
+ {
+ int i = SendDlgItemMessage(hwndDlg, IDC_EFFECT_COMBO, CB_GETCURSEL, 0, 0);
+ pEffect->effectIndex = (BYTE)SendDlgItemMessage(hwndDlg, IDC_EFFECT_COMBO, CB_GETITEMDATA, i, 0);
+ pEffect->baseColour = SendDlgItemMessage(hwndDlg, IDC_EFFECT_COLOUR1, CPM_GETCOLOUR, 0, 0) | ((~(BYTE)SendDlgItemMessage(hwndDlg, IDC_EFFECT_COLOUR_SPIN1, UDM_GETPOS, 0, 0)) << 24);
+ pEffect->secondaryColour = SendDlgItemMessage(hwndDlg, IDC_EFFECT_COLOUR2, CPM_GETCOLOUR, 0, 0) | ((~(BYTE)SendDlgItemMessage(hwndDlg, IDC_EFFECT_COLOUR_SPIN2, UDM_GETPOS, 0, 0)) << 24);
+ }
+ EndDialog(hwndDlg, IDOK);
+ return TRUE;
+
+ case IDCANCEL:
+ EndDialog(hwndDlg, IDCANCEL);
+ return TRUE;
+ }
+ break;
+ case WM_DESTROY:
+ pEffect = NULL;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void sttSaveFontData(HWND hwndDlg, FontInternal &F)
+{
+ LOGFONT lf;
+ char str[128];
+
+ if (F.flags & FIDF_APPENDNAME)
+ mir_snprintf(str, "%sName", F.prefix);
+ else
+ strncpy_s(str, F.prefix, _TRUNCATE);
+
+ if (db_set_ts(NULL, F.dbSettingsGroup, str, F.value.szFace)) {
+ char buff[1024];
+ WideCharToMultiByte(code_page, 0, F.value.szFace, -1, buff, 1024, 0, 0);
+ db_set_s(NULL, F.dbSettingsGroup, str, buff);
+ }
+
+ mir_snprintf(str, "%sSize", F.prefix);
+ if (F.flags & FIDF_SAVEACTUALHEIGHT) {
+ SIZE size;
+ CreateFromFontSettings(&F.value, &lf);
+ HFONT hFont = CreateFontIndirect(&lf);
+ HDC hdc = GetDC(hwndDlg);
+ HFONT hOldFont = (HFONT)SelectObject(hdc, hFont);
+ GetTextExtentPoint32(hdc, _T("_W"), 2, &size);
+ ReleaseDC(hwndDlg, hdc);
+ SelectObject(hdc, hOldFont);
+ DeleteObject(hFont);
+
+ db_set_b(NULL, F.dbSettingsGroup, str, (char)size.cy);
+ }
+ else if (F.flags & FIDF_SAVEPOINTSIZE) {
+ HDC hdc = GetDC(hwndDlg);
+ db_set_b(NULL, F.dbSettingsGroup, str, (BYTE)-MulDiv(F.value.size, 72, GetDeviceCaps(hdc, LOGPIXELSY)));
+ ReleaseDC(hwndDlg, hdc);
+ }
+ else db_set_b(NULL, F.dbSettingsGroup, str, F.value.size);
+
+ mir_snprintf(str, "%sSty", F.prefix);
+ db_set_b(NULL, F.dbSettingsGroup, str, F.value.style);
+ mir_snprintf(str, "%sSet", F.prefix);
+ db_set_b(NULL, F.dbSettingsGroup, str, F.value.charset);
+ mir_snprintf(str, "%sCol", F.prefix);
+ db_set_dw(NULL, F.dbSettingsGroup, str, F.value.colour);
+ if (F.flags & FIDF_NOAS) {
+ mir_snprintf(str, "%sAs", F.prefix);
+ db_set_w(NULL, F.dbSettingsGroup, str, (WORD)0x00FF);
+ }
+ mir_snprintf(str, "%sFlags", F.prefix);
+ db_set_w(NULL, F.dbSettingsGroup, str, (WORD)F.flags);
+}
+
+static INT_PTR CALLBACK DlgProcLogOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ int i, selCount;
+ LOGFONT lf;
+
+ static HBRUSH hBkgColourBrush = 0;
+
+ switch (msg) {
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hwndDlg);
+
+ font_id_list_w2 = font_id_list;
+ font_id_list_w3 = font_id_list;
+
+ colour_id_list_w2 = colour_id_list;
+ colour_id_list_w3 = colour_id_list;
+
+ effect_id_list_w2 = effect_id_list;
+ effect_id_list_w3 = effect_id_list;
+
+ for (i = 0; i < font_id_list_w2.getCount(); i++) {
+ FontInternal& F = font_id_list_w2[i];
+ // sync settings with database
+ UpdateFontSettings(&F, &F.value);
+ sttFsuiCreateSettingsTreeNode(GetDlgItem(hwndDlg, IDC_FONTGROUP), F.group, F.hLangpack);
+ }
+
+ for (i = 0; i < colour_id_list_w2.getCount(); i++) {
+ ColourInternal& C = colour_id_list_w2[i];
+
+ // sync settings with database
+ UpdateColourSettings(&C, &C.value);
+ sttFsuiCreateSettingsTreeNode(GetDlgItem(hwndDlg, IDC_FONTGROUP), C.group, C.hLangpack);
+ }
+
+ for (i = 0; i < effect_id_list_w2.getCount(); i++) {
+ EffectInternal& E = effect_id_list_w2[i];
+
+ // sync settings with database
+ UpdateEffectSettings(&E, &E.value);
+ sttFsuiCreateSettingsTreeNode(GetDlgItem(hwndDlg, IDC_FONTGROUP), E.group, E.hLangpack);
+ }
+
+ SendDlgItemMessage(hwndDlg, IDC_BKGCOLOUR, CPM_SETDEFAULTCOLOUR, 0, (LPARAM)GetSysColor(COLOR_WINDOW));
+ return TRUE;
+
+ case UM_SETFONTGROUP:
+ TreeItem *treeItem;
+ {
+ TVITEM tvi = { 0 };
+ tvi.hItem = TreeView_GetSelection(GetDlgItem(hwndDlg, IDC_FONTGROUP));
+ tvi.mask = TVIF_HANDLE | TVIF_PARAM;
+ TreeView_GetItem(GetDlgItem(hwndDlg, IDC_FONTGROUP), &tvi);
+ treeItem = (TreeItem *)tvi.lParam;
+ TCHAR *group_buff = treeItem->groupName;
+
+ sttFreeListItems(GetDlgItem(hwndDlg, IDC_FONTLIST));
+ SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_RESETCONTENT, 0, 0);
+
+ if (group_buff) {
+ BOOL need_restart = FALSE;
+
+ SendDlgItemMessage(hwndDlg, IDC_FONTLIST, WM_SETREDRAW, FALSE, 0);
+
+ for (int fontId = 0; fontId < font_id_list_w2.getCount(); fontId++) {
+ FontInternal &F = font_id_list_w2[fontId];
+ if (!_tcsncmp(F.group, group_buff, 64)) {
+ FSUIListItemData *itemData = (FSUIListItemData*)mir_alloc(sizeof(FSUIListItemData));
+ itemData->colour_id = -1;
+ itemData->effect_id = -1;
+ itemData->font_id = fontId;
+ SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_ADDSTRING, (WPARAM)-1, (LPARAM)itemData);
+ need_restart |= (F.flags & FIDF_NEEDRESTART);
+ }
+ }
+
+ if (hBkgColourBrush) {
+ DeleteObject(hBkgColourBrush);
+ hBkgColourBrush = 0;
+ }
+
+ for (int colourId = 0; colourId < colour_id_list_w2.getCount(); colourId++) {
+ ColourInternal &C = colour_id_list_w2[colourId];
+ if (!_tcsncmp(C.group, group_buff, 64)) {
+ if (!sttFsuiBindColourIdToFonts(GetDlgItem(hwndDlg, IDC_FONTLIST), C.name, C.group, C.name, colourId)) {
+ FSUIListItemData *itemData = (FSUIListItemData*)mir_alloc(sizeof(FSUIListItemData));
+ itemData->colour_id = colourId;
+ itemData->font_id = -1;
+ itemData->effect_id = -1;
+
+ SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_ADDSTRING, (WPARAM)-1, (LPARAM)itemData);
+ }
+
+ if (mir_tstrcmp(C.name, _T("Background")) == 0)
+ hBkgColourBrush = CreateSolidBrush(C.value);
+ }
+ }
+
+ if (!hBkgColourBrush)
+ hBkgColourBrush = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
+
+ for (int effectId = 0; effectId < effect_id_list_w2.getCount(); effectId++) {
+ EffectInternal& E = effect_id_list_w2[effectId];
+ if (!_tcsncmp(E.group, group_buff, 64)) {
+ if (!sttFsuiBindEffectIdToFonts(GetDlgItem(hwndDlg, IDC_FONTLIST), E.name, effectId)) {
+ FSUIListItemData *itemData = (FSUIListItemData*)mir_alloc(sizeof(FSUIListItemData));
+ itemData->effect_id = effectId;
+ itemData->font_id = -1;
+ itemData->colour_id = -1;
+
+ SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_ADDSTRING, (WPARAM)-1, (LPARAM)itemData);
+ }
+ }
+ }
+
+ SendDlgItemMessage(hwndDlg, IDC_FONTLIST, WM_SETREDRAW, TRUE, 0);
+ UpdateWindow(GetDlgItem(hwndDlg, IDC_FONTLIST));
+
+ SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_SETSEL, TRUE, 0);
+ SendMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(IDC_FONTLIST, LBN_SELCHANGE), 0);
+ }
+ else {
+ EnableWindow(GetDlgItem(hwndDlg, IDC_BKGCOLOUR), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_FONTCOLOUR), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CHOOSEFONT), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_RESET), FALSE);
+ ShowEffectButton(hwndDlg, FALSE);
+ }
+ }
+ return TRUE;
+
+ case WM_MEASUREITEM:
+ {
+ MEASUREITEMSTRUCT *mis = (MEASUREITEMSTRUCT *)lParam;
+ if ((mis->CtlID != IDC_FONTLIST) || (mis->itemID == -1))
+ break;
+
+ FSUIListItemData *itemData = (FSUIListItemData *)mis->itemData;
+ if (!itemData)
+ return FALSE;
+
+ HFONT hFont = NULL, hoFont = NULL;
+ BOOL bIsFont = FALSE;
+ TCHAR *itemName = NULL;
+ if (itemData->font_id >= 0) {
+ int iItem = itemData->font_id;
+ bIsFont = TRUE;
+ CreateFromFontSettings(&font_id_list_w2[iItem].value, &lf);
+ hFont = CreateFontIndirect(&lf);
+ itemName = font_id_list_w2[iItem].getName();
+ }
+
+ if (itemData->colour_id >= 0) {
+ int iItem = itemData->colour_id;
+ if (!itemName)
+ itemName = colour_id_list_w2[iItem].getName();
+ }
+
+ HDC hdc = GetDC(GetDlgItem(hwndDlg, mis->CtlID));
+ if (hFont)
+ hoFont = (HFONT)SelectObject(hdc, hFont);
+ else
+ hoFont = (HFONT)SelectObject(hdc, (HFONT)SendDlgItemMessage(hwndDlg, mis->CtlID, WM_GETFONT, 0, 0));
+
+ SIZE fontSize;
+ GetTextExtentPoint32(hdc, itemName, (int)mir_tstrlen(itemName), &fontSize);
+ if (hoFont) SelectObject(hdc, hoFont);
+ if (hFont) DeleteObject(hFont);
+ ReleaseDC(GetDlgItem(hwndDlg, mis->CtlID), hdc);
+ mis->itemWidth = fontSize.cx + 2 * FSUI_FONTFRAMEHORZ + 4;
+ mis->itemHeight = fontSize.cy + 2 * FSUI_FONTFRAMEVERT + 4;
+ }
+ return TRUE;
+
+ case WM_DRAWITEM:
+ FONTEFFECT Effect;
+ {
+ DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT *)lParam;
+ HFONT hFont = NULL, hoFont = NULL;
+ COLORREF clBack = (COLORREF)-1;
+ COLORREF clText = GetSysColor(COLOR_WINDOWTEXT);
+ BOOL bIsFont = FALSE;
+ TCHAR *itemName = NULL;
+
+ FSUIListItemData *itemData = (FSUIListItemData *)dis->itemData;
+ FONTEFFECT * pEffect = NULL;
+
+ if (dis->CtlID != IDC_FONTLIST)
+ break;
+
+ if (!itemData) return FALSE;
+
+ if (itemData->font_id >= 0) {
+ int iItem = itemData->font_id;
+ bIsFont = TRUE;
+ CreateFromFontSettings(&font_id_list_w2[iItem].value, &lf);
+ hFont = CreateFontIndirect(&lf);
+ itemName = font_id_list_w2[iItem].getName();
+ clText = font_id_list_w2[iItem].value.colour;
+ }
+
+ if (itemData->colour_id >= 0) {
+ int iItem = itemData->colour_id;
+ if (bIsFont)
+ clBack = colour_id_list_w2[iItem].value;
+ else {
+ clText = colour_id_list_w2[iItem].value;
+ itemName = colour_id_list_w2[iItem].getName();
+ }
+ }
+
+ if (itemData->effect_id >= 0) {
+ int iItem = itemData->effect_id;
+
+ Effect.effectIndex = effect_id_list_w2[iItem].value.effectIndex;
+ Effect.baseColour = effect_id_list_w2[iItem].value.baseColour;
+ Effect.secondaryColour = effect_id_list_w2[iItem].value.secondaryColour;
+ pEffect = &Effect;
+
+ if (!bIsFont)
+ itemName = effect_id_list_w2[iItem].getName();
+ }
+
+ if (hFont)
+ hoFont = (HFONT)SelectObject(dis->hDC, hFont);
+ else
+ hoFont = (HFONT)SelectObject(dis->hDC, (HFONT)SendDlgItemMessage(hwndDlg, dis->CtlID, WM_GETFONT, 0, 0));
+
+ SetBkMode(dis->hDC, TRANSPARENT);
+
+ if (dis->itemState & ODS_SELECTED) {
+ SetTextColor(dis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
+ FillRect(dis->hDC, &dis->rcItem, GetSysColorBrush(COLOR_HIGHLIGHT));
+ }
+ else {
+ SetTextColor(dis->hDC, bIsFont ? clText : GetSysColor(COLOR_WINDOWTEXT));
+ if (bIsFont && (clBack != (COLORREF)-1)) {
+ HBRUSH hbrTmp = CreateSolidBrush(clBack);
+ FillRect(dis->hDC, &dis->rcItem, hbrTmp);
+ DeleteObject(hbrTmp);
+ }
+ else FillRect(dis->hDC, &dis->rcItem, bIsFont ? hBkgColourBrush : GetSysColorBrush(COLOR_WINDOW));
+ }
+
+ if (bIsFont) {
+ HBRUSH hbrBack;
+ RECT rc;
+
+ if (clBack != (COLORREF)-1)
+ hbrBack = CreateSolidBrush(clBack);
+ else {
+ LOGBRUSH lb;
+ GetObject(hBkgColourBrush, sizeof(lf), &lb);
+ hbrBack = CreateBrushIndirect(&lb);
+ }
+
+ SetRect(&rc,
+ dis->rcItem.left + FSUI_COLORBOXLEFT,
+ dis->rcItem.top + FSUI_FONTFRAMEVERT,
+ dis->rcItem.left + FSUI_COLORBOXLEFT + FSUI_COLORBOXWIDTH,
+ dis->rcItem.bottom - FSUI_FONTFRAMEVERT);
+
+ FillRect(dis->hDC, &rc, hbrBack);
+ DeleteObject(hbrBack);
+
+ FrameRect(dis->hDC, &rc, GetSysColorBrush(COLOR_HIGHLIGHT));
+ rc.left += 1;
+ rc.top += 1;
+ rc.right -= 1;
+ rc.bottom -= 1;
+ FrameRect(dis->hDC, &rc, GetSysColorBrush(COLOR_HIGHLIGHTTEXT));
+
+ SetTextColor(dis->hDC, clText);
+
+ DrawTextWithEffect(dis->hDC, _T("abc"), 3, &rc, DT_CENTER | DT_NOPREFIX | DT_SINGLELINE | DT_VCENTER | DT_WORD_ELLIPSIS, pEffect);
+
+ if (dis->itemState & ODS_SELECTED) {
+ SetTextColor(dis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
+ pEffect = NULL; // Do not draw effect on selected item name text
+ }
+ rc = dis->rcItem;
+ rc.left += FSUI_FONTLEFT;
+ DrawTextWithEffect(dis->hDC, itemName, (int)mir_tstrlen(itemName), &rc, DT_LEFT | DT_NOPREFIX | DT_SINGLELINE | DT_VCENTER | DT_WORD_ELLIPSIS, pEffect);
+ }
+ else {
+ RECT rc;
+ HBRUSH hbrTmp;
+ SetRect(&rc,
+ dis->rcItem.left + FSUI_COLORBOXLEFT,
+ dis->rcItem.top + FSUI_FONTFRAMEVERT,
+ dis->rcItem.left + FSUI_COLORBOXLEFT + FSUI_COLORBOXWIDTH,
+ dis->rcItem.bottom - FSUI_FONTFRAMEVERT);
+
+ hbrTmp = CreateSolidBrush(clText);
+ FillRect(dis->hDC, &rc, hbrTmp);
+ DeleteObject(hbrTmp);
+
+ FrameRect(dis->hDC, &rc, GetSysColorBrush(COLOR_HIGHLIGHT));
+ rc.left += 1;
+ rc.top += 1;
+ rc.right -= 1;
+ rc.bottom -= 1;
+ FrameRect(dis->hDC, &rc, GetSysColorBrush(COLOR_HIGHLIGHTTEXT));
+
+ rc = dis->rcItem;
+ rc.left += FSUI_FONTLEFT;
+
+ DrawTextWithEffect(dis->hDC, itemName, (int)mir_tstrlen(itemName), &rc, DT_LEFT | DT_NOPREFIX | DT_SINGLELINE | DT_VCENTER | DT_WORD_ELLIPSIS, pEffect);
+ }
+ if (hoFont) SelectObject(dis->hDC, hoFont);
+ if (hFont) DeleteObject(hFont);
+ }
+ return TRUE;
+
+ case WM_COMMAND:
+ switch (LOWORD(wParam)) {
+ case IDC_FONTLIST:
+ if (HIWORD(wParam) == LBN_SELCHANGE) {
+ char bEnableFont = 1;
+ char bEnableClText = 1;
+ char bEnableClBack = 1;
+ char bEnableEffect = 1;
+ char bEnableReset = 1;
+
+ COLORREF clBack = 0xffffffff;
+ COLORREF clText = 0xffffffff;
+
+ if (selCount = SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETSELCOUNT, 0, 0)) {
+ int *selItems = (int *)mir_alloc(font_id_list_w2.getCount() * sizeof(int));
+ SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETSELITEMS, (WPARAM)selCount, (LPARAM)selItems);
+ for (i = 0; i < selCount; i++) {
+ FSUIListItemData *itemData = (FSUIListItemData *)SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETITEMDATA, selItems[i], 0);
+ if (IsBadReadPtr(itemData, sizeof(FSUIListItemData))) continue; // prevent possible problems with corrupted itemData
+
+ if (bEnableClBack && (itemData->colour_id < 0))
+ bEnableClBack = 0;
+ if (bEnableEffect && (itemData->effect_id < 0))
+ bEnableEffect = 0;
+ if (bEnableFont && (itemData->font_id < 0))
+ bEnableFont = 0;
+ if (!bEnableFont || bEnableClText && (itemData->font_id < 0))
+ bEnableClText = 0;
+ if (bEnableReset && (itemData->font_id >= 0) && !(font_id_list_w2[itemData->font_id].flags&FIDF_DEFAULTVALID))
+ bEnableReset = 0;
+
+ if (bEnableClBack && (itemData->colour_id >= 0) && (clBack == 0xffffffff))
+ clBack = colour_id_list_w2[itemData->colour_id].value;
+ if (bEnableClText && (itemData->font_id >= 0) && (clText == 0xffffffff))
+ clText = font_id_list_w2[itemData->font_id].value.colour;
+ }
+ mir_free(selItems);
+ }
+ else bEnableFont = bEnableClText = bEnableClBack = bEnableReset = bEnableEffect = 0;
+
+ EnableWindow(GetDlgItem(hwndDlg, IDC_BKGCOLOUR), bEnableClBack);
+ ShowEffectButton(hwndDlg, bEnableEffect && !bEnableClBack);
+
+ EnableWindow(GetDlgItem(hwndDlg, IDC_FONTCOLOUR), bEnableClText);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CHOOSEFONT), bEnableFont);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_RESET), bEnableReset);
+
+ if (bEnableClBack) SendDlgItemMessage(hwndDlg, IDC_BKGCOLOUR, CPM_SETCOLOUR, 0, clBack);
+ if (bEnableClText) SendDlgItemMessage(hwndDlg, IDC_FONTCOLOUR, CPM_SETCOLOUR, 0, clText);
+
+ return TRUE;
+ }
+
+ if (HIWORD(wParam) != LBN_DBLCLK)
+ return TRUE;
+
+ //fall through
+
+ case IDC_CHOOSEFONT:
+ if (selCount = SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETSELCOUNT, 0, 0)) {
+ int *selItems = (int *)mir_alloc(selCount * sizeof(int));
+ SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETSELITEMS, (WPARAM)selCount, (LPARAM)selItems);
+
+ FSUIListItemData *itemData = (FSUIListItemData *)SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETITEMDATA, selItems[0], 0);
+ if (itemData->font_id < 0) {
+ mir_free(selItems);
+ if (itemData->colour_id >= 0)
+ SendDlgItemMessage(hwndDlg, IDC_BKGCOLOUR, WM_LBUTTONUP, 0, 0);
+ return TRUE;
+ }
+
+ FontInternal& F = font_id_list_w2[itemData->font_id];
+ CreateFromFontSettings(&F.value, &lf);
+
+ CHOOSEFONT cf = { 0 };
+ cf.lStructSize = sizeof(cf);
+ cf.hwndOwner = hwndDlg;
+ cf.lpLogFont = &lf;
+ cf.lCustData = F.flags;
+ cf.Flags = CF_FORCEFONTEXIST | CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS | CF_ENABLEHOOK;
+ cf.lpfnHook = CFHookProc;
+
+ if (F.flags & FIDF_ALLOWEFFECTS) // enable effects section
+ cf.Flags |= CF_EFFECTS;
+ else if (F.flags & FIDF_DISABLESTYLES) { // mutually exclusive with FIDF_ALLOWEFFECTS
+ cf.Flags |= CF_TTONLY | CF_NOOEMFONTS;
+ lf.lfWeight = FW_NORMAL;
+ lf.lfItalic = lf.lfUnderline = lf.lfStrikeOut = FALSE;
+ }
+
+ if (ChooseFont(&cf)) {
+ for (i = 0; i < selCount; i++) {
+ FSUIListItemData *itemData = (FSUIListItemData *)SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETITEMDATA, selItems[i], 0);
+ if (itemData->font_id < 0)
+ continue;
+
+ FontInternal& F1 = font_id_list_w2[itemData->font_id];
+ F1.value.size = (char)lf.lfHeight;
+ F1.value.style = (lf.lfWeight >= FW_BOLD ? DBFONTF_BOLD : 0) | (lf.lfItalic ? DBFONTF_ITALIC : 0) | (lf.lfUnderline ? DBFONTF_UNDERLINE : 0) | (lf.lfStrikeOut ? DBFONTF_STRIKEOUT : 0);
+ F1.value.charset = lf.lfCharSet;
+ _tcsncpy_s(F1.value.szFace, lf.lfFaceName, _TRUNCATE);
+
+ MEASUREITEMSTRUCT mis = { 0 };
+ mis.CtlID = IDC_FONTLIST;
+ mis.itemID = selItems[i];
+ mis.itemData = SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETITEMDATA, selItems[i], 0);
+ SendMessage(hwndDlg, WM_MEASUREITEM, 0, (LPARAM)& mis);
+ SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_SETITEMHEIGHT, selItems[i], mis.itemHeight);
+ }
+ InvalidateRect(GetDlgItem(hwndDlg, IDC_FONTLIST), NULL, TRUE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_UNDO), TRUE);
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ }
+
+ mir_free(selItems);
+ }
+ return TRUE;
+
+ case IDC_EFFECT:
+ if (selCount = SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETSELCOUNT, 0, 0)) {
+ int *selItems = (int *)mir_alloc(selCount * sizeof(int));
+ SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETSELITEMS, (WPARAM)selCount, (LPARAM)selItems);
+ FSUIListItemData *itemData = (FSUIListItemData *)SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETITEMDATA, selItems[0], 0);
+ EffectInternal& E = effect_id_list_w2[itemData->effect_id];
+
+ FONTEFFECT es = E.value;
+ if (IDOK == DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_CHOOSE_FONT_EFFECT), hwndDlg, ChooseEffectDlgProc, (LPARAM)&es)) {
+ for (int i = 0; i < selCount; i++) {
+ FSUIListItemData *itemData = (FSUIListItemData *)SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETITEMDATA, selItems[i], 0);
+ if (itemData->effect_id < 0)
+ continue;
+
+ EffectInternal& E1 = effect_id_list_w2[itemData->effect_id];
+ E1.value = es;
+ }
+ InvalidateRect(GetDlgItem(hwndDlg, IDC_FONTLIST), NULL, TRUE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_UNDO), TRUE);
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ }
+
+ mir_free(selItems);
+ }
+ return TRUE;
+
+ case IDC_FONTCOLOUR:
+ if (selCount = SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETSELCOUNT, 0, 0)) {
+ int *selItems = (int *)mir_alloc(selCount * sizeof(int));
+ SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETSELITEMS, (WPARAM)selCount, (LPARAM)selItems);
+ for (int i = 0; i < selCount; i++) {
+ FSUIListItemData *itemData = (FSUIListItemData *)SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETITEMDATA, selItems[i], 0);
+ if (itemData->font_id < 0) continue;
+ font_id_list_w2[itemData->font_id].value.colour = SendDlgItemMessage(hwndDlg, IDC_FONTCOLOUR, CPM_GETCOLOUR, 0, 0);
+ }
+ mir_free(selItems);
+ InvalidateRect(GetDlgItem(hwndDlg, IDC_FONTLIST), NULL, FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_UNDO), TRUE);
+ }
+ break;
+
+ case IDC_BKGCOLOUR:
+ if (selCount = SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETSELCOUNT, 0, 0)) {
+ int *selItems = (int *)mir_alloc(selCount * sizeof(int));
+ SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETSELITEMS, (WPARAM)selCount, (LPARAM)selItems);
+ for (i = 0; i < selCount; i++) {
+ FSUIListItemData *itemData = (FSUIListItemData *)SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETITEMDATA, selItems[i], 0);
+ if (itemData->colour_id < 0) continue;
+ colour_id_list_w2[itemData->colour_id].value = SendDlgItemMessage(hwndDlg, IDC_BKGCOLOUR, CPM_GETCOLOUR, 0, 0);
+
+ if (mir_tstrcmp(colour_id_list_w2[itemData->colour_id].name, _T("Background")) == 0) {
+ if (hBkgColourBrush) DeleteObject(hBkgColourBrush);
+ hBkgColourBrush = CreateSolidBrush(colour_id_list_w2[itemData->colour_id].value);
+ }
+ }
+ mir_free(selItems);
+ InvalidateRect(GetDlgItem(hwndDlg, IDC_FONTLIST), NULL, FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_UNDO), TRUE);
+ }
+ break;
+
+ case IDC_BTN_RESET:
+ if (font_id_list_w2.getCount() && (selCount = SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETSELCOUNT, 0, 0))) {
+ int *selItems = (int *)mir_alloc(font_id_list_w2.getCount() * sizeof(int));
+ SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETSELITEMS, (WPARAM)selCount, (LPARAM)selItems);
+ for (i = 0; i < selCount; i++) {
+ FSUIListItemData *itemData = (FSUIListItemData *)SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETITEMDATA, selItems[i], 0);
+ if (IsBadReadPtr(itemData, sizeof(FSUIListItemData))) continue; // prevent possible problems with corrupted itemData
+
+ if ((itemData->font_id >= 0) && (font_id_list_w2[itemData->font_id].flags & FIDF_DEFAULTVALID)) {
+ font_id_list_w2[itemData->font_id].value = font_id_list_w2[itemData->font_id].deffontsettings;
+
+ MEASUREITEMSTRUCT mis = { 0 };
+ mis.CtlID = IDC_FONTLIST;
+ mis.itemID = selItems[i];
+ mis.itemData = SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETITEMDATA, selItems[i], 0);
+ SendMessage(hwndDlg, WM_MEASUREITEM, 0, (LPARAM)& mis);
+ SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_SETITEMHEIGHT, selItems[i], mis.itemHeight);
+ }
+
+ if (itemData->colour_id >= 0)
+ colour_id_list_w2[itemData->colour_id].value = colour_id_list_w2[itemData->colour_id].defcolour;
+
+ if (itemData->effect_id >= 0)
+ effect_id_list_w2[itemData->effect_id].value = effect_id_list_w2[itemData->effect_id].defeffect;
+
+ }
+ mir_free(selItems);
+ InvalidateRect(GetDlgItem(hwndDlg, IDC_FONTLIST), NULL, TRUE);
+ SendMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(IDC_FONTLIST, LBN_SELCHANGE), 0);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_UNDO), TRUE);
+ }
+ break;
+
+ case IDC_BTN_EXPORT:
+ {
+ TCHAR fname_buff[MAX_PATH], filter[MAX_PATH];
+ mir_sntprintf(filter, SIZEOF(filter), _T("%s (*.ini)%c*.ini%c%s (*.txt)%c*.TXT%c%s (*.*)%c*.*%c"), TranslateT("Configuration files"), 0, 0, TranslateT("Text files"), 0, 0, TranslateT("All files"), 0, 0);
+
+ OPENFILENAME ofn = { 0 };
+ ofn.lStructSize = sizeof(ofn);
+ ofn.lpstrFile = fname_buff;
+ ofn.lpstrFile[0] = '\0';
+ ofn.nMaxFile = MAX_PATH;
+ ofn.hwndOwner = hwndDlg;
+ ofn.Flags = OFN_NOREADONLYRETURN | OFN_CREATEPROMPT | OFN_OVERWRITEPROMPT;
+ ofn.lpstrFilter = filter;
+ ofn.nFilterIndex = 1;
+
+ ofn.lpstrDefExt = _T("ini");
+
+ if (GetSaveFileName(&ofn) == TRUE)
+ if (!ExportSettings(hwndDlg, ofn.lpstrFile, font_id_list, colour_id_list, effect_id_list))
+ MessageBox(hwndDlg, TranslateT("Error writing file"), TranslateT("Error"), MB_ICONWARNING | MB_OK);
+ }
+ return TRUE;
+
+ case IDC_BTN_UNDO:
+ font_id_list_w2 = font_id_list_w3;
+ colour_id_list_w2 = colour_id_list_w3;
+ effect_id_list_w2 = effect_id_list_w3;
+ EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_UNDO), FALSE);
+
+ SendMessage(hwndDlg, UM_SETFONTGROUP, 0, 0);
+ break;
+ }
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ break;
+
+ case WM_NOTIFY:
+ if (((LPNMHDR)lParam)->idFrom == 0 && ((LPNMHDR)lParam)->code == PSN_APPLY) {
+ char str[32];
+
+ font_id_list_w3 = font_id_list;
+ colour_id_list_w3 = colour_id_list;
+ effect_id_list_w3 = effect_id_list;
+
+ EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_UNDO), TRUE);
+
+ font_id_list = font_id_list_w2;
+ colour_id_list = colour_id_list_w2;
+ effect_id_list = effect_id_list_w2;
+
+ for (i = 0; i < font_id_list_w2.getCount(); i++) {
+ FontInternal& F = font_id_list_w2[i];
+ sttSaveFontData(hwndDlg, F);
+ }
+
+ for (i = 0; i < colour_id_list_w2.getCount(); i++) {
+ ColourInternal& C = colour_id_list_w2[i];
+
+ strncpy_s(str, C.setting, _TRUNCATE);
+ db_set_dw(NULL, C.dbSettingsGroup, str, C.value);
+ }
+
+ for (i = 0; i < effect_id_list_w2.getCount(); i++) {
+ EffectInternal& E = effect_id_list_w2[i];
+
+ mir_snprintf(str, "%sEffect", E.setting);
+ db_set_b(NULL, E.dbSettingsGroup, str, E.value.effectIndex);
+
+ mir_snprintf(str, "%sEffectCol1", E.setting);
+ db_set_dw(NULL, E.dbSettingsGroup, str, E.value.baseColour);
+
+ mir_snprintf(str, "%sEffectCol2", E.setting);
+ db_set_dw(NULL, E.dbSettingsGroup, str, E.value.secondaryColour);
+ }
+
+ OptionsChanged();
+ return TRUE;
+ }
+
+ if (((LPNMHDR)lParam)->idFrom == IDC_FONTGROUP) {
+ switch (((NMHDR*)lParam)->code) {
+ case TVN_SELCHANGED:
+ SendMessage(hwndDlg, UM_SETFONTGROUP, 0, 0);
+ break;
+
+ case TVN_DELETEITEM:
+ TreeItem *treeItem = (TreeItem *)(((LPNMTREEVIEW)lParam)->itemOld.lParam);
+ if (treeItem) {
+ mir_free(treeItem->groupName);
+ mir_free(treeItem->paramName);
+ mir_free(treeItem);
+ }
+ break;
+ }
+ }
+ break;
+
+ case WM_DESTROY:
+ KillTimer(hwndDlg, TIMER_ID);
+ sttSaveCollapseState(GetDlgItem(hwndDlg, IDC_FONTGROUP));
+ DeleteObject(hBkgColourBrush);
+ font_id_list_w2.destroy();
+ font_id_list_w3.destroy();
+ colour_id_list_w2.destroy();
+ colour_id_list_w3.destroy();
+ effect_id_list_w2.destroy();
+ effect_id_list_w3.destroy();
+ sttFreeListItems(GetDlgItem(hwndDlg, IDC_FONTLIST));
+ break;
+ }
+ return FALSE;
+}
+
+int OptInit(WPARAM wParam, LPARAM)
+{
+ OPTIONSDIALOGPAGE odp = { 0 };
+ odp.position = -790000000;
+ odp.hInstance = g_hInst;
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_FONTS);
+ odp.pszTitle = LPGEN("Fonts and colors");
+ odp.pszGroup = LPGEN("Customize");
+ odp.flags = ODPF_BOLDGROUPS;
+ odp.pfnDlgProc = DlgProcLogOptions;
+ Options_AddPage(wParam, &odp);
+ return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+static FontInternal* sttFindFont(OBJLIST<FontInternal> &fonts, char *module, char *prefix)
+{
+ for (int i = 0; i < fonts.getCount(); i++) {
+ FontInternal& F = fonts[i];
+ if (!mir_strcmp(F.dbSettingsGroup, module) && !mir_strcmp(F.prefix, prefix))
+ return &F;
+ }
+
+ return 0;
+}
+
+static FontInternal fntHeader, fntGeneral, fntSmall;
+
+static INT_PTR CALLBACK DlgProcModernOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ int i;
+ LOGFONT lf;
+
+ switch (msg) {
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hwndDlg);
+
+ fntHeader = *sttFindFont(font_id_list, "Fonts", "Header");
+ UpdateFontSettings(&fntHeader, &fntHeader.value);
+ fntGeneral = *sttFindFont(font_id_list, "Fonts", "Generic");
+ UpdateFontSettings(&fntGeneral, &fntGeneral.value);
+ fntSmall = *sttFindFont(font_id_list, "Fonts", "Small");
+ UpdateFontSettings(&fntSmall, &fntSmall.value);
+ return TRUE;
+
+ case WM_DRAWITEM:
+ {
+ FontInternal *pf = 0;
+ DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT *)lParam;
+ switch (dis->CtlID) {
+ case IDC_PREVIEWHEADER:
+ pf = &fntHeader;
+ break;
+ case IDC_PREVIEWGENERAL:
+ pf = &fntGeneral;
+ break;
+ case IDC_PREVIEWSMALL:
+ pf = &fntSmall;
+ break;
+ }
+
+ if (!pf)
+ break;
+
+ HFONT hFont = NULL, hoFont = NULL;
+ CreateFromFontSettings(&pf->value, &lf);
+ hFont = CreateFontIndirect(&lf);
+ hoFont = (HFONT)SelectObject(dis->hDC, hFont);
+ SetBkMode(dis->hDC, TRANSPARENT);
+ SetTextColor(dis->hDC, GetSysColor(COLOR_BTNTEXT));
+ FillRect(dis->hDC, &dis->rcItem, GetSysColorBrush(COLOR_BTNFACE));
+ DrawText(dis->hDC, TranslateT("Sample text"), -1, &dis->rcItem, DT_LEFT | DT_NOPREFIX | DT_SINGLELINE | DT_VCENTER | DT_WORD_ELLIPSIS | DT_CENTER);
+ if (hoFont)
+ SelectObject(dis->hDC, hoFont);
+ return TRUE;
+ }
+
+ case WM_COMMAND:
+ switch (LOWORD(wParam)) {
+ case IDC_CHOOSEFONTHEADER:
+ case IDC_CHOOSEFONTGENERAL:
+ case IDC_CHOOSEFONTSMALL:
+ {
+ FontInternal *pf = NULL;
+ switch (LOWORD(wParam)) {
+ case IDC_CHOOSEFONTHEADER:
+ pf = &fntHeader;
+ break;
+ case IDC_CHOOSEFONTGENERAL:
+ pf = &fntGeneral;
+ break;
+ case IDC_CHOOSEFONTSMALL:
+ pf = &fntSmall;
+ break;
+ };
+
+ CreateFromFontSettings(&pf->value, &lf);
+
+ CHOOSEFONT cf = { 0 };
+ cf.lStructSize = sizeof(cf);
+ cf.hwndOwner = hwndDlg;
+ cf.lpLogFont = &lf;
+ cf.lCustData = pf->flags;
+ cf.Flags = CF_FORCEFONTEXIST | CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
+ if (pf->flags & FIDF_ALLOWEFFECTS) {
+ cf.Flags |= CF_EFFECTS | CF_ENABLEHOOK;
+ cf.lpfnHook = CFHookProc;
+ }
+
+ if (ChooseFont(&cf)) {
+ pf->value.size = (char)lf.lfHeight;
+ pf->value.style = (lf.lfWeight >= FW_BOLD ? DBFONTF_BOLD : 0) | (lf.lfItalic ? DBFONTF_ITALIC : 0) | (lf.lfUnderline ? DBFONTF_UNDERLINE : 0) | (lf.lfStrikeOut ? DBFONTF_STRIKEOUT : 0);
+ pf->value.charset = lf.lfCharSet;
+ _tcsncpy_s(pf->value.szFace, lf.lfFaceName, _TRUNCATE);
+
+ InvalidateRect(GetDlgItem(hwndDlg, IDC_PREVIEWHEADER), NULL, TRUE);
+ InvalidateRect(GetDlgItem(hwndDlg, IDC_PREVIEWGENERAL), NULL, TRUE);
+ InvalidateRect(GetDlgItem(hwndDlg, IDC_PREVIEWSMALL), NULL, TRUE);
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ }
+ }
+ return TRUE;
+ }
+ break;
+
+ case WM_NOTIFY:
+ if (((LPNMHDR)lParam)->idFrom == 0 && ((LPNMHDR)lParam)->code == PSN_APPLY) {
+ for (i = 0; i < font_id_list.getCount(); i++) {
+ FontInternal &F = font_id_list[i];
+ if (F.deffontsettings.charset == SYMBOL_CHARSET)
+ continue;
+
+ COLORREF cl = F.value.colour;
+ if (F.isHeader())
+ F.value = fntHeader.value;
+ else if ((F.flags & FIDF_CLASSMASK) == FIDF_CLASSSMALL)
+ F.value = fntSmall.value;
+ else
+ F.value = fntGeneral.value;
+
+ F.value.colour = cl;
+ sttSaveFontData(hwndDlg, F);
+ }
+
+ OptionsChanged();
+ }
+ break;
+ }
+ return FALSE;
+}
+
+INT_PTR CALLBACK AccMgrDlgProc(HWND, UINT, WPARAM, LPARAM);
+INT_PTR CALLBACK DlgPluginOpt(HWND, UINT, WPARAM, LPARAM);
+
+int FontsModernOptInit(WPARAM wParam, LPARAM)
+{
+ static int iBoldControls[] =
+ {
+ IDC_TXT_TITLE1, IDC_TXT_TITLE2, IDC_TXT_TITLE3,
+ MODERNOPT_CTRL_LAST
+ };
+
+ MODERNOPTOBJECT obj = {0};
+ obj.cbSize = sizeof(obj);
+ obj.dwFlags = MODEROPT_FLG_TCHAR|MODEROPT_FLG_NORESIZE;
+ obj.hIcon = LoadSkinnedIcon(SKINICON_OTHER_MIRANDA);
+ obj.hInstance = g_hInst;
+ obj.iSection = MODERNOPT_PAGE_SKINS;
+ obj.iType = MODERNOPT_TYPE_SUBSECTIONPAGE;
+ obj.iBoldControls = iBoldControls;
+ obj.lptzSubsection = LPGENT("Fonts");
+ obj.lpzClassicGroup = "Customize";
+ obj.lpzClassicPage = "Fonts";
+ obj.lpzHelpUrl = "http://wiki.miranda-ng.org/";
+
+ obj.lpzTemplate = MAKEINTRESOURCEA(IDD_MODERNOPT_FONTS);
+ obj.pfnDlgProc = DlgProcModernOptions;
+ CallService(MS_MODERNOPT_ADDOBJECT, wParam, (LPARAM)&obj);
+
+ obj.iSection = MODERNOPT_PAGE_ACCOUNTS;
+ obj.iType = MODERNOPT_TYPE_SECTIONPAGE;
+ obj.lpzTemplate = MAKEINTRESOURCEA(IDD_MODERNOPT_ACCOUNTS);
+ obj.pfnDlgProc = AccMgrDlgProc;
+ obj.lpzClassicGroup = NULL;
+ obj.lpzClassicPage = "Network";
+ obj.lpzHelpUrl = "http://wiki.miranda-ng.org/";
+ CallService(MS_MODERNOPT_ADDOBJECT, wParam, (LPARAM)&obj);
+
+ obj.iSection = MODERNOPT_PAGE_MODULES;
+ obj.iType = MODERNOPT_TYPE_SECTIONPAGE;
+ obj.lpzTemplate = MAKEINTRESOURCEA(IDD_MODERNOPT_MODULES);
+ obj.pfnDlgProc = DlgPluginOpt;
+ obj.iBoldControls = iBoldControls;
+ obj.lpzClassicGroup = NULL;
+ obj.lpzClassicPage = NULL;
+ obj.lpzHelpUrl = "http://wiki.miranda-ng.org/";
+ CallService(MS_MODERNOPT_ADDOBJECT, wParam, (LPARAM)&obj);
+ return 0;
+}