From 4b0b7853103435d005c2013b925c6e3fc60402a6 Mon Sep 17 00:00:00 2001 From: Kirill Volinsky Date: Sat, 26 May 2012 23:01:52 +0000 Subject: projects cleanup git-svn-id: http://svn.miranda-ng.org/main/trunk@191 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/ExtraIcons/.cproject | 993 +++++++++++++++++++++++ plugins/ExtraIcons/.project | 70 ++ plugins/ExtraIcons/BaseExtraIcon.cpp | 79 ++ plugins/ExtraIcons/BaseExtraIcon.h | 52 ++ plugins/ExtraIcons/CallbackExtraIcon.cpp | 72 ++ plugins/ExtraIcons/CallbackExtraIcon.h | 47 ++ plugins/ExtraIcons/DefaultExtraIcons.cpp | 390 +++++++++ plugins/ExtraIcons/DefaultExtraIcons.h | 26 + plugins/ExtraIcons/Docs/extraicons.png | Bin 0 -> 36754 bytes plugins/ExtraIcons/Docs/extraicons_changelog.txt | 26 + plugins/ExtraIcons/Docs/extraicons_readme.txt | 26 + plugins/ExtraIcons/Docs/extraicons_version.txt | 1 + plugins/ExtraIcons/Docs/langpack_extraicons.txt | 15 + plugins/ExtraIcons/ExtraIcon.cpp | 130 +++ plugins/ExtraIcons/ExtraIcon.h | 73 ++ plugins/ExtraIcons/ExtraIconGroup.cpp | 213 +++++ plugins/ExtraIcons/ExtraIconGroup.h | 62 ++ plugins/ExtraIcons/IcolibExtraIcon.cpp | 109 +++ plugins/ExtraIcons/IcolibExtraIcon.h | 41 + plugins/ExtraIcons/ZIP/doit.bat | 97 +++ plugins/ExtraIcons/commons.h | 119 +++ plugins/ExtraIcons/extraicons.cpp | 540 ++++++++++++ plugins/ExtraIcons/extraicons.sln | 26 + plugins/ExtraIcons/extraicons.vcxproj | 239 ++++++ plugins/ExtraIcons/extraicons.vcxproj.filters | 124 +++ plugins/ExtraIcons/options.cpp | 866 ++++++++++++++++++++ plugins/ExtraIcons/options.h | 32 + plugins/ExtraIcons/res/AlwaysVis.ico | Bin 0 -> 2038 bytes plugins/ExtraIcons/res/Chatchannel.ico | Bin 0 -> 2038 bytes plugins/ExtraIcons/res/NeverVis.ico | Bin 0 -> 2038 bytes plugins/ExtraIcons/res/empty.ico | Bin 0 -> 766 bytes plugins/ExtraIcons/res/female.ico | Bin 0 -> 2550 bytes plugins/ExtraIcons/res/male.ico | Bin 0 -> 2550 bytes plugins/ExtraIcons/resource.h | 33 + plugins/ExtraIcons/resource.rc | 150 ++++ plugins/ExtraIcons/usedIcons.cpp | 110 +++ plugins/ExtraIcons/usedIcons.h | 29 + 37 files changed, 4790 insertions(+) create mode 100644 plugins/ExtraIcons/.cproject create mode 100644 plugins/ExtraIcons/.project create mode 100644 plugins/ExtraIcons/BaseExtraIcon.cpp create mode 100644 plugins/ExtraIcons/BaseExtraIcon.h create mode 100644 plugins/ExtraIcons/CallbackExtraIcon.cpp create mode 100644 plugins/ExtraIcons/CallbackExtraIcon.h create mode 100644 plugins/ExtraIcons/DefaultExtraIcons.cpp create mode 100644 plugins/ExtraIcons/DefaultExtraIcons.h create mode 100644 plugins/ExtraIcons/Docs/extraicons.png create mode 100644 plugins/ExtraIcons/Docs/extraicons_changelog.txt create mode 100644 plugins/ExtraIcons/Docs/extraicons_readme.txt create mode 100644 plugins/ExtraIcons/Docs/extraicons_version.txt create mode 100644 plugins/ExtraIcons/Docs/langpack_extraicons.txt create mode 100644 plugins/ExtraIcons/ExtraIcon.cpp create mode 100644 plugins/ExtraIcons/ExtraIcon.h create mode 100644 plugins/ExtraIcons/ExtraIconGroup.cpp create mode 100644 plugins/ExtraIcons/ExtraIconGroup.h create mode 100644 plugins/ExtraIcons/IcolibExtraIcon.cpp create mode 100644 plugins/ExtraIcons/IcolibExtraIcon.h create mode 100644 plugins/ExtraIcons/ZIP/doit.bat create mode 100644 plugins/ExtraIcons/commons.h create mode 100644 plugins/ExtraIcons/extraicons.cpp create mode 100644 plugins/ExtraIcons/extraicons.sln create mode 100644 plugins/ExtraIcons/extraicons.vcxproj create mode 100644 plugins/ExtraIcons/extraicons.vcxproj.filters create mode 100644 plugins/ExtraIcons/options.cpp create mode 100644 plugins/ExtraIcons/options.h create mode 100644 plugins/ExtraIcons/res/AlwaysVis.ico create mode 100644 plugins/ExtraIcons/res/Chatchannel.ico create mode 100644 plugins/ExtraIcons/res/NeverVis.ico create mode 100644 plugins/ExtraIcons/res/empty.ico create mode 100644 plugins/ExtraIcons/res/female.ico create mode 100644 plugins/ExtraIcons/res/male.ico create mode 100644 plugins/ExtraIcons/resource.h create mode 100644 plugins/ExtraIcons/resource.rc create mode 100644 plugins/ExtraIcons/usedIcons.cpp create mode 100644 plugins/ExtraIcons/usedIcons.h (limited to 'plugins/ExtraIcons') diff --git a/plugins/ExtraIcons/.cproject b/plugins/ExtraIcons/.cproject new file mode 100644 index 0000000000..39d4b46fc7 --- /dev/null +++ b/plugins/ExtraIcons/.cproject @@ -0,0 +1,993 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +make + +build +true +true +true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +make + +build +true +true +true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/ExtraIcons/.project b/plugins/ExtraIcons/.project new file mode 100644 index 0000000000..f451e2b4bc --- /dev/null +++ b/plugins/ExtraIcons/.project @@ -0,0 +1,70 @@ + + + extraicons + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + ?name? + + + + org.eclipse.cdt.make.core.append_environment + true + + + org.eclipse.cdt.make.core.buildArguments + + + + org.eclipse.cdt.make.core.buildCommand + make + + + org.eclipse.cdt.make.core.buildLocation + ${workspace_loc:/extraicons/Debug} + + + org.eclipse.cdt.make.core.contents + org.eclipse.cdt.make.core.activeConfigSettings + + + org.eclipse.cdt.make.core.enableAutoBuild + false + + + org.eclipse.cdt.make.core.enableCleanBuild + true + + + org.eclipse.cdt.make.core.enableFullBuild + true + + + org.eclipse.cdt.make.core.stopOnError + true + + + org.eclipse.cdt.make.core.useDefaultBuildCmd + true + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + + + + + + org.eclipse.cdt.core.ccnature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.core.cnature + + diff --git a/plugins/ExtraIcons/BaseExtraIcon.cpp b/plugins/ExtraIcons/BaseExtraIcon.cpp new file mode 100644 index 0000000000..f1aea5438c --- /dev/null +++ b/plugins/ExtraIcons/BaseExtraIcon.cpp @@ -0,0 +1,79 @@ +/* + Copyright (C) 2009 Ricardo Pescuma Domenecci + + This is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this file; see the file license.txt. If + not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +#include "commons.h" + +BaseExtraIcon::BaseExtraIcon(int id, const char *name, const char *description, const char *descIcon, + MIRANDAHOOKPARAM OnClick, LPARAM param) : + ExtraIcon(name), id(id), description(description), descIcon(descIcon), OnClick(OnClick), onClickParam(param) +{ +} + +BaseExtraIcon::~BaseExtraIcon() +{ +} + +void BaseExtraIcon::setOnClick(MIRANDAHOOKPARAM OnClick, LPARAM param) +{ + this->OnClick = OnClick; + this->onClickParam = param; +} + +int BaseExtraIcon::getID() const +{ + return id; +} + +const char *BaseExtraIcon::getDescription() const +{ + return description.c_str(); +} + +void BaseExtraIcon::setDescription(const char *desc) +{ + description = desc; +} + +const char *BaseExtraIcon::getDescIcon() const +{ + return descIcon.c_str(); +} + +void BaseExtraIcon::setDescIcon(const char *icon) +{ + descIcon = icon; +} + +void BaseExtraIcon::onClick(HANDLE hContact) +{ + if (OnClick == NULL) + return; + + OnClick((WPARAM) hContact, (LPARAM) ConvertToClistSlot(slot), onClickParam); +} + +int BaseExtraIcon::ClistSetExtraIcon(HANDLE hContact, HANDLE hImage) +{ + ExtraIcon *tmp = extraIconsByHandle[id - 1]; + if (tmp != this) + return tmp->ClistSetExtraIcon(hContact, hImage); + else + return Clist_SetExtraIcon(hContact, slot, hImage); +} + diff --git a/plugins/ExtraIcons/BaseExtraIcon.h b/plugins/ExtraIcons/BaseExtraIcon.h new file mode 100644 index 0000000000..e484dd2e4b --- /dev/null +++ b/plugins/ExtraIcons/BaseExtraIcon.h @@ -0,0 +1,52 @@ +/* + Copyright (C) 2009 Ricardo Pescuma Domenecci + + This is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this file; see the file license.txt. If + not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +#ifndef __BASEEXTRAICON_H__ +#define __BASEEXTRAICON_H__ + +#include "ExtraIcon.h" + +class BaseExtraIcon : public ExtraIcon +{ +public: + BaseExtraIcon(int id, const char *name, const char *description, const char *descIcon, MIRANDAHOOKPARAM OnClick, + LPARAM param); + virtual ~BaseExtraIcon(); + + virtual int getID() const; + virtual const char *getDescription() const; + virtual void setDescription(const char *desc); + virtual const char *getDescIcon() const; + virtual void setDescIcon(const char *icon); + virtual int getType() const =0; + + virtual void onClick(HANDLE hContact); + virtual void setOnClick(MIRANDAHOOKPARAM OnClick, LPARAM param); + + virtual int ClistSetExtraIcon(HANDLE hContact, HANDLE hImage); + +protected: + int id; + std::string description; + std::string descIcon; + MIRANDAHOOKPARAM OnClick; + LPARAM onClickParam; +}; + +#endif // __BASEEXTRAICON_H__ diff --git a/plugins/ExtraIcons/CallbackExtraIcon.cpp b/plugins/ExtraIcons/CallbackExtraIcon.cpp new file mode 100644 index 0000000000..3f4d368f75 --- /dev/null +++ b/plugins/ExtraIcons/CallbackExtraIcon.cpp @@ -0,0 +1,72 @@ +/* + Copyright (C) 2009 Ricardo Pescuma Domenecci + + This is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this file; see the file license.txt. If + not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +#include "commons.h" + +CallbackExtraIcon::CallbackExtraIcon(int id, const char *name, const char *description, const char *descIcon, + MIRANDAHOOK RebuildIcons, MIRANDAHOOK ApplyIcon, MIRANDAHOOKPARAM OnClick, LPARAM param) : + BaseExtraIcon(id, name, description, descIcon, OnClick, param), RebuildIcons(RebuildIcons), ApplyIcon(ApplyIcon), + needToRebuild(true) +{ +} + +CallbackExtraIcon::~CallbackExtraIcon() +{ +} + +int CallbackExtraIcon::getType() const +{ + return EXTRAICON_TYPE_CALLBACK; +} + +void CallbackExtraIcon::rebuildIcons() +{ + if (!isEnabled()) + { + needToRebuild = true; + return; + } + needToRebuild = false; + + RebuildIcons(0, 0); +} + +void CallbackExtraIcon::applyIcon(HANDLE hContact) +{ + if (!isEnabled() || hContact == NULL) + return; + + if (needToRebuild) + rebuildIcons(); + + ApplyIcon((WPARAM) hContact, 0); +} + +int CallbackExtraIcon::setIcon(int id, HANDLE hContact, void *icon) +{ + if (!isEnabled() || hContact == NULL || id != this->id) + return -1; + + return ClistSetExtraIcon(hContact, (HANDLE) icon); +} + +void CallbackExtraIcon::storeIcon(HANDLE hContact, void *icon) +{ +} + diff --git a/plugins/ExtraIcons/CallbackExtraIcon.h b/plugins/ExtraIcons/CallbackExtraIcon.h new file mode 100644 index 0000000000..7b46c88da9 --- /dev/null +++ b/plugins/ExtraIcons/CallbackExtraIcon.h @@ -0,0 +1,47 @@ +/* + Copyright (C) 2009 Ricardo Pescuma Domenecci + + This is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this file; see the file license.txt. If + not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +#ifndef __CALLBACKEXTRAICON_H__ +#define __CALLBACKEXTRAICON_H__ + +#include "BaseExtraIcon.h" + +class CallbackExtraIcon : public BaseExtraIcon +{ +public: + CallbackExtraIcon(int id, const char *name, const char *description, const char *descIcon, + MIRANDAHOOK RebuildIcons, MIRANDAHOOK ApplyIcon, MIRANDAHOOKPARAM OnClick, LPARAM param); + virtual ~CallbackExtraIcon(); + + virtual int getType() const; + + virtual void rebuildIcons(); + virtual void applyIcon(HANDLE hContact); + + virtual int setIcon(int id, HANDLE hContact, void *icon); + virtual void storeIcon(HANDLE hContact, void *icon); + +private: + int(*RebuildIcons)(WPARAM wParam, LPARAM lParam); + int(*ApplyIcon)(WPARAM wParam, LPARAM lParam); + + bool needToRebuild; +}; + +#endif // __CALLBACKEXTRAICON_H__ diff --git a/plugins/ExtraIcons/DefaultExtraIcons.cpp b/plugins/ExtraIcons/DefaultExtraIcons.cpp new file mode 100644 index 0000000000..ebdaddff8a --- /dev/null +++ b/plugins/ExtraIcons/DefaultExtraIcons.cpp @@ -0,0 +1,390 @@ +/* + Copyright (C) 2009 Ricardo Pescuma Domenecci + + This is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this file; see the file license.txt. If + not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +#include "commons.h" + +/* + 0, // EXTRA_ICON_VISMODE + 1, // EXTRA_ICON_EMAIL + 2, // EXTRA_ICON_PROTO + 3, // EXTRA_ICON_SMS + 4, // EXTRA_ICON_ADV1 + 5, // EXTRA_ICON_ADV2 + 6, // EXTRA_ICON_WEB + 7, // EXTRA_ICON_CLIENT + 8, // EXTRA_ICON_ADV3 + 9, // EXTRA_ICON_ADV4 + */ + +static void ProtocolInit(); +static void DBExtraIconsInit(); + +void DefaultExtraIcons_Load() +{ + DBExtraIconsInit(); + ProtocolInit(); +} + +void DefaultExtraIcons_Unload() +{ +} + +// DB extra icons /////////////////////////////////////////////////////////////////////// + +struct Info; + +HANDLE hExtraVisibility = NULL; +HANDLE hExtraChat = NULL; +HANDLE hExtraGender = NULL; + +static void SetVisibility(HANDLE hContact, int apparentMode, BOOL clear) +{ + if (hContact == NULL) + return; + + char *proto = (char*) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0); + if (IsEmpty(proto)) + return; + + if (apparentMode <= 0) + apparentMode = DBGetContactSettingWord(hContact, proto, "ApparentMode", 0); + + const char *ico = NULL; + + if (DBGetContactSettingByte(hContact, proto, "ChatRoom", 0)) + { + // Is chat + if (apparentMode == ID_STATUS_OFFLINE) + ico = "ChatActivity"; + + if (ico == NULL && !clear) + return; + + ExtraIcon_SetIcon(hExtraChat, hContact, ico); + } + else + { + // Not chat + if (apparentMode == ID_STATUS_OFFLINE) + ico = "NeverVis"; + + else if (apparentMode == ID_STATUS_ONLINE) + ico = "AlwaysVis"; + + if (ico == NULL && !clear) + return; + + ExtraIcon_SetIcon(hExtraVisibility, hContact, ico); + } +} + +static void SetGender(HANDLE hContact, int gender, BOOL clear) +{ + if (hContact == NULL) + return; + + char *proto = (char*) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0); + if (IsEmpty(proto)) + return; + + if (gender <= 0) + gender = DBGetContactSettingByte(hContact, proto, "Gender", 0); + if (gender <= 0) + gender = DBGetContactSettingByte(hContact, "UserInfo", "Gender", 0); + + const char *ico = NULL; + if (gender == 'M') + ico = "gender_male"; + else if (gender == 'F') + ico = "gender_female"; + else + ico = NULL; + + if (ico == NULL && !clear) + return; + + ExtraIcon_SetIcon(hExtraGender, hContact, ico); +} + +static void EmailOnClick(Info *info, const char *text); +static void HomepageOnClick(Info *info, const char *text); +static void DefaultSetIcon(HANDLE hContact, Info *info, const char *text); + +struct Info +{ + const char *name; + const char *desc; + const char *icon; + const char *db[8]; + void (*SetIcon)(HANDLE hContact, Info *info, const char *text); + void (*OnClick)(Info *info, const char *text); + HANDLE hExtraIcon; +} infos[] = { + { "homepage", "Homepage", "core_main_2", { NULL, "Homepage", + "UserInfo", "Homepage" }, DefaultSetIcon, &HomepageOnClick, NULL }, + { "sms", "Phone/SMS", "core_main_17", { NULL, "Cellular", + "UserInfo", "Cellular", + "UserInfo", "Phone", + "UserInfo", "MyPhone0" }, DefaultSetIcon, NULL, NULL }, + { "email", "E-mail", "core_main_14", { NULL, "e-mail", + "UserInfo", "e-mail", + "UserInfo", "Mye-mail0" }, DefaultSetIcon, &EmailOnClick, NULL }, +}; + +static void EmailOnClick(Info *info, const char *text) +{ + char cmd[1024]; + mir_snprintf(cmd, MAX_REGS(cmd), "mailto:%s", text); + ShellExecute(NULL, "open", cmd, NULL, NULL, SW_SHOW); +} + +static void HomepageOnClick(Info *info, const char *text) +{ + ShellExecute(NULL, "open", text, NULL, NULL, SW_SHOW); +} + +static void DefaultSetIcon(HANDLE hContact, Info *info, const char *text) +{ + ExtraIcon_SetIcon(info->hExtraIcon, hContact, text ? info->icon : NULL); +} + +static void SetExtraIcons(HANDLE hContact) +{ + if (hContact == NULL) + return; + + char *proto = (char*) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0); + if (IsEmpty(proto)) + return; + + for (unsigned int i = 0; i < MAX_REGS(infos); ++i) + { + Info &info = infos[i]; + + bool show = false; + for (unsigned int j = 0; !show && j < MAX_REGS(info.db); j += 2) + { + if (info.db[j + 1] == NULL) + break; + + DBVARIANT dbv = { 0 }; + if (!DBGetContactSettingString(hContact, info.db[j] == NULL ? proto : info.db[j], info.db[j+1], &dbv)) + { + if (!IsEmpty(dbv.pszVal)) + { + info.SetIcon(hContact, &info, dbv.pszVal); + show = true; + } + DBFreeVariant(&dbv); + } + } + } +} + +static int SettingChanged(WPARAM wParam, LPARAM lParam) +{ + HANDLE hContact = (HANDLE) wParam; + DBCONTACTWRITESETTING *cws = (DBCONTACTWRITESETTING*) lParam; + + if (hContact == NULL) + return 0; + + char *proto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0); + if (IsEmpty(proto)) + return 0; + + bool isProto = (strcmp(cws->szModule, proto) == 0); + + if (isProto && strcmp(cws->szSetting, "ApparentMode") == 0) + { + SetVisibility(hContact, cws->value.type == DBVT_DELETED ? 0 : cws->value.wVal, TRUE); + return 0; + } + + if (strcmp(cws->szSetting, "Gender") == 0 && (isProto || strcmp(cws->szModule, "UserInfo") == 0)) + { + SetGender(hContact, cws->value.type == DBVT_DELETED ? 0 : cws->value.bVal, TRUE); + return 0; + } + + for (unsigned int i = 0; i < MAX_REGS(infos); ++i) + { + Info &info = infos[i]; + + for (unsigned int j = 0; j < MAX_REGS(info.db); j += 2) + { + if (info.db[j + 1] == NULL) + break; + if (info.db[j] == NULL && !isProto) + continue; + if (info.db[j] != NULL && strcmp(cws->szModule, info.db[j])) + continue; + if (strcmp(cws->szSetting, info.db[j + 1])) + continue; + + bool show = (cws->value.type != DBVT_DELETED && !IsEmpty(cws->value.pszVal)); + info.SetIcon(hContact, &info, show ? cws->value.pszVal : NULL); + + break; + } + } + + return 0; +} + +static int DefaultOnClick(WPARAM wParam, LPARAM lParam, LPARAM param) +{ + Info *info = (Info *) param; + if (info == NULL) + return 0; + + HANDLE hContact = (HANDLE) wParam; + if (hContact == NULL) + return 0; + + char *proto = (char*) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0); + if (IsEmpty(proto)) + return 0; + + bool found = false; + for (unsigned int j = 0; !found && j < MAX_REGS(info->db); j += 2) + { + if (info->db[j + 1] == NULL) + break; + + DBVARIANT dbv = { 0 }; + if (!DBGetContactSettingString(hContact, info->db[j] == NULL ? proto : info->db[j], info->db[j+1], &dbv)) + { + if (!IsEmpty(dbv.ptszVal)) + { + info->OnClick(info, dbv.ptszVal); + found = true; + } + + DBFreeVariant(&dbv); + } + } + + return 0; +} + +static void DBExtraIconsInit() +{ + hExtraChat = ExtraIcon_Register("chat_activity", "Chat activity", "ChatActivity"); + hExtraVisibility = ExtraIcon_Register("visibility", "Visibility", "AlwaysVis"); + hExtraGender = ExtraIcon_Register("gender", "Gender", "gender_male"); + for (unsigned int i = 0; i < MAX_REGS(infos); ++i) + { + Info &info = infos[i]; + if (info.OnClick) + info.hExtraIcon = ExtraIcon_Register(info.name, info.desc, info.icon, DefaultOnClick, (LPARAM) &info); + else + info.hExtraIcon = ExtraIcon_Register(info.name, info.desc, info.icon); + } + + HANDLE hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + while (hContact != NULL) + { + SetExtraIcons(hContact); + SetVisibility(hContact, -1, FALSE); + SetGender(hContact, -1, FALSE); + + hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0); + } + + hHooks.push_back(HookEvent(ME_DB_CONTACT_SETTINGCHANGED, SettingChanged)); +} + +// Protocol ///////////////////////////////////////////////////////////////////////////// + +struct ProtoInfo +{ + string proto; + HANDLE hImage; +}; + +vector protos; + +HANDLE hExtraProto = NULL; + +static int ProtocolRebuildIcons(WPARAM wParam, LPARAM lParam) +{ + protos.clear(); + return 0; +} + +static ProtoInfo *FindProto(const char * proto) +{ + for (unsigned int i = 0; i < protos.size(); ++i) + { + ProtoInfo *pi = &protos[i]; + if (strcmp(pi->proto.c_str(), proto) == 0) + return pi; + } + + HICON hIcon = LoadSkinnedProtoIcon(proto, ID_STATUS_ONLINE); + if (hIcon == NULL) + return NULL; + + HANDLE hImage = (HANDLE) CallService(MS_CLIST_EXTRA_ADD_ICON, (WPARAM) hIcon, 0); + if (hImage == NULL) + return NULL; + + ProtoInfo tmp; + tmp.proto = proto; + tmp.hImage = hImage; + protos.push_back(tmp); + + return &protos[protos.size() - 1]; +} + +static int ProtocolApplyIcon(WPARAM wParam, LPARAM lParam) +{ + HANDLE hContact = (HANDLE) wParam; + + char *proto = (char*) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0); + if (IsEmpty(proto)) + return 0; + + ProtoInfo *pi = FindProto(proto); + + HANDLE hImage = NULL; + if (pi != NULL) + hImage = pi->hImage; + + ExtraIcon_SetIcon(hExtraProto, hContact, hImage); + + return 0; +} + +static int ProtocolOnClick(WPARAM wParam, LPARAM lParam, LPARAM param) +{ + HANDLE hContact = (HANDLE) wParam; + if (hContact == NULL) + return 0; + + CallService(MS_USERINFO_SHOWDIALOG, (WPARAM) hContact, 0); + return 0; +} + +static void ProtocolInit() +{ + hExtraProto = ExtraIcon_Register("protocol", "Account", "core_main_34", &ProtocolRebuildIcons, &ProtocolApplyIcon, + &ProtocolOnClick); +} diff --git a/plugins/ExtraIcons/DefaultExtraIcons.h b/plugins/ExtraIcons/DefaultExtraIcons.h new file mode 100644 index 0000000000..fba4602d41 --- /dev/null +++ b/plugins/ExtraIcons/DefaultExtraIcons.h @@ -0,0 +1,26 @@ +/* + Copyright (C) 2009 Ricardo Pescuma Domenecci + + This is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this file; see the file license.txt. If + not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +#ifndef __DEFAULTEXTRAICONS_H__ +#define __DEFAULTEXTRAICONS_H__ + +void DefaultExtraIcons_Load(); +void DefaultExtraIcons_Unload(); + +#endif // __DEFAULTEXTRAICONS_H__ diff --git a/plugins/ExtraIcons/Docs/extraicons.png b/plugins/ExtraIcons/Docs/extraicons.png new file mode 100644 index 0000000000..9710ef5c1b Binary files /dev/null and b/plugins/ExtraIcons/Docs/extraicons.png differ diff --git a/plugins/ExtraIcons/Docs/extraicons_changelog.txt b/plugins/ExtraIcons/Docs/extraicons_changelog.txt new file mode 100644 index 0000000000..984bb20614 --- /dev/null +++ b/plugins/ExtraIcons/Docs/extraicons_changelog.txt @@ -0,0 +1,26 @@ +Extra Icons Service + +Changelog: + +. 0.2.5.0 + * Fix for crash on reseting icons + +. 0.2.4.0 + * Fix for removing grouped icon + +. 0.2.3.0 + * Fix for initial position of icons + +. 0.2.2.0 + * Fix for external plugins overriding internal icons + +. 0.2.1.0 + * Fix for multi selection in Windows Vista + + CTRL now deselects too + +. 0.2.0.0 + + Allows group/ungroup of icons + + New options dialog + +. 0.1.0.0 + + Initial version \ No newline at end of file diff --git a/plugins/ExtraIcons/Docs/extraicons_readme.txt b/plugins/ExtraIcons/Docs/extraicons_readme.txt new file mode 100644 index 0000000000..56ae4c9f72 --- /dev/null +++ b/plugins/ExtraIcons/Docs/extraicons_readme.txt @@ -0,0 +1,26 @@ +Extra Icons Service plugin +-------------------------- + +CAUTION: THIS IS A BETA STAGE PLUGIN. IT CAN DO VERY BAD THINGS. USE AT YOUR OWN RISK. + + +This is a simple plugin to allow the user to select which extra icons he wants to see. + +It is based on the idea that plugins register icons, the contact list shows them, and this plugin is the glue. By default it supports: + - Account + - E-mail + - Phone/SMS + - Homepage + - Visibility + - Chat activity + - Gender + +By now it is supported my clist_modern and clist_mw from 0.8#29. I intend to add clist_nicer next. + +Thanks to FYR for some code that I copied from clist_modern and to Angeli-Ka for the nice icons. + + +To report bugs/make suggestions, go to the forum thread: http://forums.miranda-im.org/showthread.php?t=178318 + + + diff --git a/plugins/ExtraIcons/Docs/extraicons_version.txt b/plugins/ExtraIcons/Docs/extraicons_version.txt new file mode 100644 index 0000000000..ffcd6fde96 --- /dev/null +++ b/plugins/ExtraIcons/Docs/extraicons_version.txt @@ -0,0 +1 @@ +Extra Icons Service 0.2.5.0 \ No newline at end of file diff --git a/plugins/ExtraIcons/Docs/langpack_extraicons.txt b/plugins/ExtraIcons/Docs/langpack_extraicons.txt new file mode 100644 index 0000000000..037ad6a249 --- /dev/null +++ b/plugins/ExtraIcons/Docs/langpack_extraicons.txt @@ -0,0 +1,15 @@ +; Extra Icons Service +; Author: Pescuma + +[Select the extra icons to be shown in the contact list:] + +[Account] +[E-mail] +[Phone/SMS] +[Homepage] +[Visibility] +[Chat activity] +[Gender] + +[* only the first %d icons will be shown] +[You can group/ungroup icons by selecting then (CTRL+left click) and using the popup menu (right click)] diff --git a/plugins/ExtraIcons/ExtraIcon.cpp b/plugins/ExtraIcons/ExtraIcon.cpp new file mode 100644 index 0000000000..1aaab01e2a --- /dev/null +++ b/plugins/ExtraIcons/ExtraIcon.cpp @@ -0,0 +1,130 @@ +/* + Copyright (C) 2009 Ricardo Pescuma Domenecci + + This is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this file; see the file license.txt. If + not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +#include "commons.h" + +ExtraIcon::ExtraIcon(const char *name) : + name(name), slot(-1), position(1000) +{ +} + +ExtraIcon::~ExtraIcon() +{ +} + +const char *ExtraIcon::getName() const +{ + return name.c_str(); +} + +int ExtraIcon::getSlot() const +{ + return slot; +} + +void ExtraIcon::setSlot(int slot) +{ + this->slot = slot; +} + +int ExtraIcon::getPosition() const +{ + return position; +} + +void ExtraIcon::setPosition(int position) +{ + this->position = position; +} + +bool ExtraIcon::isEnabled() const +{ + return slot >= 0; +} + +void ExtraIcon::applyIcons() +{ + if (!isEnabled()) + return; + + HANDLE hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + while (hContact != NULL) + { + // Clear to assert that it will be cleared + Clist_SetExtraIcon(hContact, slot, NULL); + + applyIcon(hContact); + + hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0); + } +} + +int ExtraIcon::compare(const ExtraIcon *other) const +{ + if (this == other) + return 0; + + int ret = getPosition() - other->getPosition(); + if (ret != 0) + return ret; + + int id = 0; + if (getType() != EXTRAICON_TYPE_GROUP) + id = ((BaseExtraIcon*) this)->getID(); + int otherId = 0; + if (other->getType() != EXTRAICON_TYPE_GROUP) + otherId = ((BaseExtraIcon*) other)->getID(); + return id - otherId; +} + +bool ExtraIcon::operator==(const ExtraIcon & other) const +{ + int c = compare(&other); + return c == 0; +} + +bool ExtraIcon::operator!=(const ExtraIcon & other) const +{ + int c = compare(&other); + return c != 0; +} + +bool ExtraIcon::operator<(const ExtraIcon & other) const +{ + int c = compare(&other); + return c < 0; +} + +bool ExtraIcon::operator<=(const ExtraIcon & other) const +{ + int c = compare(&other); + return c <= 0; +} + +bool ExtraIcon::operator>(const ExtraIcon & other) const +{ + int c = compare(&other); + return c > 0; +} + +bool ExtraIcon::operator>=(const ExtraIcon & other) const +{ + int c = compare(&other); + return c >= 0; +} diff --git a/plugins/ExtraIcons/ExtraIcon.h b/plugins/ExtraIcons/ExtraIcon.h new file mode 100644 index 0000000000..03b0177a08 --- /dev/null +++ b/plugins/ExtraIcons/ExtraIcon.h @@ -0,0 +1,73 @@ +/* + Copyright (C) 2009 Ricardo Pescuma Domenecci + + This is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this file; see the file license.txt. If + not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +#ifndef __EXTRAICON_H__ +#define __EXTRAICON_H__ + +#include + +#define EXTRAICON_TYPE_GROUP -1 + +class ExtraIcon +{ +public: + ExtraIcon(const char *name); + virtual ~ExtraIcon(); + + virtual void rebuildIcons() =0; + virtual void applyIcons(); + virtual void applyIcon(HANDLE hContact) =0; + virtual void onClick(HANDLE hContact) =0; + + virtual int setIcon(int id, HANDLE hContact, void *icon) =0; + virtual void storeIcon(HANDLE hContact, void *icon) =0; + + virtual const char *getName() const; + virtual const char *getDescription() const =0; + virtual const char *getDescIcon() const =0; + virtual int getType() const =0; + + virtual int getSlot() const; + virtual void setSlot(int slot); + + virtual int getPosition() const; + virtual void setPosition(int position); + + virtual bool isEnabled() const; + + /// @retun <0 if this < other, 0 if this == other, >0 if this > other + virtual int compare(const ExtraIcon *other) const; + + bool operator==(const ExtraIcon &other) const; + bool operator!=(const ExtraIcon &other) const; + bool operator<(const ExtraIcon &other) const; + bool operator<=(const ExtraIcon &other) const; + bool operator>(const ExtraIcon &other) const; + bool operator>=(const ExtraIcon &other) const; + + virtual int ClistSetExtraIcon(HANDLE hContact, HANDLE hImage) =0; + +protected: + std::string name; + + int slot; + int position; +}; + +#endif // __EXTRAICON_H__ diff --git a/plugins/ExtraIcons/ExtraIconGroup.cpp b/plugins/ExtraIcons/ExtraIconGroup.cpp new file mode 100644 index 0000000000..b7862e0375 --- /dev/null +++ b/plugins/ExtraIcons/ExtraIconGroup.cpp @@ -0,0 +1,213 @@ +/* + Copyright (C) 2009 Ricardo Pescuma Domenecci + + This is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this file; see the file license.txt. If + not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +#include "commons.h" + +ExtraIconGroup::ExtraIconGroup(const char *name) : + ExtraIcon(name), setValidExtraIcon(false), insideApply(false) +{ + char setting[512]; + mir_snprintf(setting, MAX_REGS(setting), "%s/%s", MODULE_NAME, name); + CallService(MS_DB_SETSETTINGRESIDENT, TRUE, (WPARAM) setting); +} + +ExtraIconGroup::~ExtraIconGroup() +{ + items.clear(); +} + +void ExtraIconGroup::addExtraIcon(BaseExtraIcon *extra) +{ + items.push_back(extra); + + description = ""; + for (unsigned int i = 0; i < items.size(); ++i) + { + if (i > 0) + description += " / "; + description += items[i]->getDescription(); + } +} + +void ExtraIconGroup::rebuildIcons() +{ + for (unsigned int i = 0; i < items.size(); ++i) + items[i]->rebuildIcons(); +} + +void ExtraIconGroup::applyIcon(HANDLE hContact) +{ + if (!isEnabled() || hContact == NULL) + return; + + setValidExtraIcon = false; + + insideApply = true; + + unsigned int i; + for (i = 0; i < items.size(); ++i) + { + items[i]->applyIcon(hContact); + + if (setValidExtraIcon) + break; + } + + insideApply = false; + + DBWriteContactSettingDword(hContact, MODULE_NAME, name.c_str(), setValidExtraIcon ? items[i]->getID() : 0); +} + +int ExtraIconGroup::getPosition() const +{ + int pos = INT_MAX; + for (unsigned int i = 0; i < items.size(); ++i) + pos = MIN(pos, items[i]->getPosition()); + return pos; +} + +void ExtraIconGroup::setSlot(int slot) +{ + ExtraIcon::setSlot(slot); + + for (unsigned int i = 0; i < items.size(); ++i) + items[i]->setSlot(slot); +} + +ExtraIcon * ExtraIconGroup::getCurrentItem(HANDLE hContact) const +{ + int id = (int) DBGetContactSettingDword(hContact, MODULE_NAME, name.c_str(), 0); + if (id < 1) + return NULL; + + for (unsigned int i = 0; i < items.size(); ++i) + if (id == items[i]->getID()) + return items[i]; + + return NULL; +} + +void ExtraIconGroup::onClick(HANDLE hContact) +{ + ExtraIcon *extra = getCurrentItem(hContact); + if (extra != NULL) + extra->onClick(hContact); +} + +int ExtraIconGroup::setIcon(int id, HANDLE hContact, void *icon) +{ + if (insideApply) + { + for (unsigned int i = 0; i < items.size(); ++i) + if (items[i]->getID() == id) + return items[i]->setIcon(id, hContact, icon); + + return -1; + } + + ExtraIcon *current = getCurrentItem(hContact); + int currentPos = items.size(); + int storePos = items.size(); + for (unsigned int i = 0; i < items.size(); ++i) + { + if (items[i]->getID() == id) + storePos = i; + + if (items[i] == current) + currentPos = i; + } + + if (storePos == items.size()) + { + return -1; + } + else if (storePos > currentPos) + { + items[storePos]->storeIcon(hContact, icon); + return 0; + } + + // Ok, we have to set the icon, but we have to assert it is a valid icon + + setValidExtraIcon = false; + + int ret = items[storePos]->setIcon(id, hContact, icon); + + if (storePos < currentPos) + { + if (setValidExtraIcon) + DBWriteContactSettingDword(hContact, MODULE_NAME, name.c_str(), items[storePos]->getID()); + } + else if (storePos == currentPos) + { + if (!setValidExtraIcon) + { + DBWriteContactSettingDword(hContact, MODULE_NAME, name.c_str(), 0); + + insideApply = true; + + for (++storePos; storePos < items.size(); ++storePos) + { + items[storePos]->applyIcon(hContact); + + if (setValidExtraIcon) + break; + } + + insideApply = false; + + if (setValidExtraIcon) + DBWriteContactSettingDword(hContact, MODULE_NAME, name.c_str(), items[storePos]->getID()); + } + } + + return ret; +} + +void ExtraIconGroup::storeIcon(HANDLE hContact, void *icon) +{ +} + +const char *ExtraIconGroup::getDescription() const +{ + return description.c_str(); +} + +const char *ExtraIconGroup::getDescIcon() const +{ + for (unsigned int i = 0; i < items.size(); ++i) + if (!IsEmpty(items[i]->getDescIcon())) + return items[i]->getDescIcon(); + + return ""; +} + +int ExtraIconGroup::getType() const +{ + return EXTRAICON_TYPE_GROUP; +} + +int ExtraIconGroup::ClistSetExtraIcon(HANDLE hContact, HANDLE hImage) +{ + if (hImage != NULL && hImage != (HANDLE) -1) + setValidExtraIcon = true; + + return Clist_SetExtraIcon(hContact, slot, hImage); +} + diff --git a/plugins/ExtraIcons/ExtraIconGroup.h b/plugins/ExtraIcons/ExtraIconGroup.h new file mode 100644 index 0000000000..906509962d --- /dev/null +++ b/plugins/ExtraIcons/ExtraIconGroup.h @@ -0,0 +1,62 @@ +/* + Copyright (C) 2009 Ricardo Pescuma Domenecci + + This is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this file; see the file license.txt. If + not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +#ifndef __EXTRAICONGROUP_H__ +#define __EXTRAICONGROUP_H__ + +#include +#include "ExtraIcon.h" + +class BaseExtraIcon; + +class ExtraIconGroup : public ExtraIcon +{ +public: + ExtraIconGroup(const char *name); + virtual ~ExtraIconGroup(); + + virtual void addExtraIcon(BaseExtraIcon *extra); + + virtual void rebuildIcons(); + virtual void applyIcon(HANDLE hContact); + virtual void onClick(HANDLE hContact); + + virtual int setIcon(int id, HANDLE hContact, void *icon); + virtual void storeIcon(HANDLE hContact, void *icon); + + virtual const char *getDescription() const; + virtual const char *getDescIcon() const; + virtual int getType() const; + + virtual int getPosition() const; + virtual void setSlot(int slot); + + std::vector items; + + virtual int ClistSetExtraIcon(HANDLE hContact, HANDLE hImage); + +protected: + std::string description; + bool setValidExtraIcon; + bool insideApply; + + virtual ExtraIcon * getCurrentItem(HANDLE hContact) const; +}; + +#endif // __EXTRAICONGROUP_H__ diff --git a/plugins/ExtraIcons/IcolibExtraIcon.cpp b/plugins/ExtraIcons/IcolibExtraIcon.cpp new file mode 100644 index 0000000000..f7dc03ca24 --- /dev/null +++ b/plugins/ExtraIcons/IcolibExtraIcon.cpp @@ -0,0 +1,109 @@ +/* + Copyright (C) 2009 Ricardo Pescuma Domenecci + + This is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this file; see the file license.txt. If + not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +#include "commons.h" + +IcolibExtraIcon::IcolibExtraIcon(int id, const char *name, const char *description, const char *descIcon, + MIRANDAHOOKPARAM OnClick, LPARAM param) : + BaseExtraIcon(id, name, description, descIcon, OnClick, param) +{ + char setting[512]; + mir_snprintf(setting, MAX_REGS(setting), "%s/%s", MODULE_NAME, name); + CallService(MS_DB_SETSETTINGRESIDENT, TRUE, (WPARAM) setting); +} + +IcolibExtraIcon::~IcolibExtraIcon() +{ +} + +int IcolibExtraIcon::getType() const +{ + return EXTRAICON_TYPE_ICOLIB; +} + +void IcolibExtraIcon::rebuildIcons() +{ +} + +void IcolibExtraIcon::applyIcon(HANDLE hContact) +{ + if (!isEnabled() || hContact == NULL) + return; + + HANDLE hImage = NULL; + + DBVARIANT dbv = { 0 }; + if (!DBGetContactSettingString(hContact, MODULE_NAME, name.c_str(), &dbv)) + { + if (!IsEmpty(dbv.pszVal)) + hImage = GetIcon(dbv.pszVal); + + DBFreeVariant(&dbv); + } + + ClistSetExtraIcon(hContact, hImage); +} + +int IcolibExtraIcon::setIcon(int id, HANDLE hContact, void *icon) +{ + if (hContact == NULL || id != this->id) + return -1; + + if (isEnabled()) + { + DBVARIANT dbv = { 0 }; + if (!DBGetContactSettingString(hContact, MODULE_NAME, name.c_str(), &dbv)) + { + if (!IsEmpty(dbv.pszVal)) + RemoveIcon(dbv.pszVal); + + DBFreeVariant(&dbv); + } + } + + storeIcon(hContact, icon); + + if (isEnabled()) + { + const char *icolibName = (const char *) icon; + + HANDLE hImage; + if (IsEmpty(icolibName)) + hImage = NULL; + else + hImage = AddIcon(icolibName); + + return ClistSetExtraIcon(hContact, hImage); + } + + return 0; +} + +void IcolibExtraIcon::storeIcon(HANDLE hContact, void *icon) +{ + if (hContact == NULL) + return; + + const char *icolibName = (const char *) icon; + if (IsEmpty(icolibName)) + icolibName = ""; // Delete don't work and I don't know why + + DBWriteContactSettingString(hContact, MODULE_NAME, name.c_str(), icolibName); +} + diff --git a/plugins/ExtraIcons/IcolibExtraIcon.h b/plugins/ExtraIcons/IcolibExtraIcon.h new file mode 100644 index 0000000000..2f142f2607 --- /dev/null +++ b/plugins/ExtraIcons/IcolibExtraIcon.h @@ -0,0 +1,41 @@ +/* + Copyright (C) 2009 Ricardo Pescuma Domenecci + + This is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this file; see the file license.txt. If + not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +#ifndef __ICOLIBEXTRAICON_H__ +#define __ICOLIBEXTRAICON_H__ + +#include "BaseExtraIcon.h" + +class IcolibExtraIcon : public BaseExtraIcon +{ +public: + IcolibExtraIcon(int id, const char *name, const char *description, const char *descIcon, MIRANDAHOOKPARAM OnClick, + LPARAM param); + virtual ~IcolibExtraIcon(); + + virtual int getType() const; + + virtual void rebuildIcons(); + virtual void applyIcon(HANDLE hContact); + + virtual int setIcon(int id, HANDLE hContact, void *icon); + virtual void storeIcon(HANDLE hContact, void *icon); +}; + +#endif // __ICOLIBEXTRAICON_H__ diff --git a/plugins/ExtraIcons/ZIP/doit.bat b/plugins/ExtraIcons/ZIP/doit.bat new file mode 100644 index 0000000000..2f5615d126 --- /dev/null +++ b/plugins/ExtraIcons/ZIP/doit.bat @@ -0,0 +1,97 @@ +@echo off + +rem Batch file to build and upload files +rem +rem TODO: Integration with FL + +set name=extraicons + +rem To upload, this var must be set here or in other batch +rem set ftp=ftp://:@/ + +echo Building %name% ... + +msdev ..\%name%.dsp /MAKE "%name% - Win32 Release" /REBUILD + +echo Generating files for %name% ... + +del *.zip +del *.dll +copy ..\Docs\%name%_changelog.txt +copy ..\Docs\%name%_version.txt +copy ..\Docs\%name%_readme.txt +copy ..\Docs\%name%.png +mkdir Docs +cd Docs +del /Q *.* +copy ..\..\Docs\langpack_%name%.txt +copy ..\..\m_%name%.h +cd .. +mkdir Plugins +cd Plugins +cd .. +mkdir src +cd src +del /Q *.* +copy ..\..\*.h +copy ..\..\*.cpp +copy ..\..\*. +copy ..\..\*.rc +copy ..\..\*.dsp +copy ..\..\*.dsw +mkdir Docs +cd Docs +del /Q *.* +copy ..\..\..\Docs\*.* +cd .. +mkdir sdk +cd sdk +del /Q *.* +copy ..\..\..\sdk\*.* +cd .. +cd .. + +cd Plugins +copy "..\..\..\..\bin\release\Plugins\%name%.dll" +cd .. + +"C:\Program Files\Filzip\Filzip.exe" -a -rp %name%.zip %name%.dll Docs Plugins + +"C:\Program Files\Filzip\Filzip.exe" -a -rp %name%_src.zip src + +del *.dll +cd Docs +del /Q *.* +cd .. +rmdir Docs +cd Plugins +del /Q *.* +cd .. +rmdir Plugins +cd src +del /Q *.* +cd Docs +del /Q *.* +cd .. +rmdir Docs +cd sdk +del /Q *.* +cd .. +rmdir sdk +cd .. +rmdir src + +if "%ftp%"=="" GOTO END + +echo Going to upload files... +pause + +"C:\Program Files\FileZilla\FileZilla.exe" -u .\%name%.zip %ftp% -overwrite -close +"C:\Program Files\FileZilla\FileZilla.exe" -u .\%name%_changelog.txt %ftp% -overwrite -close +"C:\Program Files\FileZilla\FileZilla.exe" -u .\%name%_version.txt %ftp% -overwrite -close +"C:\Program Files\FileZilla\FileZilla.exe" -u .\%name%_readme.txt %ftp% -overwrite -close +"C:\Program Files\FileZilla\FileZilla.exe" -u .\%name%.png %ftp% -overwrite -close + +:END + +echo Done. diff --git a/plugins/ExtraIcons/commons.h b/plugins/ExtraIcons/commons.h new file mode 100644 index 0000000000..296d7ae04e --- /dev/null +++ b/plugins/ExtraIcons/commons.h @@ -0,0 +1,119 @@ +/* + Copyright (C) 2009 Ricardo Pescuma Domenecci + + This is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this file; see the file license.txt. If + not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +#ifndef __COMMONS_H__ +# define __COMMONS_H__ + +#define _CRT_SECURE_NO_WARNINGS + +#ifdef UNICODE +#error "Unicode not needed by this plugin" +#endif + +#define _WIN32_IE 0x500 +#include +#include +#include +#include +#include + +#include +#include +#include +#include +using namespace std; + +// Miranda headers +#define MIRANDA_VER 0x0A00 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "..\utils\mir_icons.h" + +#include "resource.h" +#include "m_extraicons.h" + +#include "ExtraIcon.h" +#include "ExtraIconGroup.h" +#include "CallbackExtraIcon.h" +#include "IcolibExtraIcon.h" +#include "usedIcons.h" +#include "DefaultExtraIcons.h" +#include "options.h" + +#define MODULE_NAME "ExtraIcons" + +// Global Variables +extern HINSTANCE hInst; +extern PLUGINLINK *pluginLink; + +#define MAX_REGS(_A_) ( sizeof(_A_) / sizeof(_A_[0]) ) +#define FREE(_m_) if (_m_ != NULL) { free(_m_); _m_ = NULL; } + +#define ICON_SIZE 16 + +extern vector hHooks; + +extern vector registeredExtraIcons; +extern vector extraIconsByHandle; +extern vector extraIconsBySlot; +void RebuildListsBasedOnGroups(vector &groups); +ExtraIcon * GetExtraIconBySlot(int slot); + +int GetNumberOfSlots(); +int ConvertToClistSlot(int slot); + +int Clist_SetExtraIcon(HANDLE hContact, int slot, HANDLE hImage); + +static inline BOOL IsEmpty(const char *str) +{ + return str == NULL || str[0] == 0; +} + +static inline int MIN(int a, int b) +{ + if (a <= b) + return a; + return b; +} + +static inline int MAX(int a, int b) +{ + if (a >= b) + return a; + return b; +} + +#endif // __COMMONS_H__ diff --git a/plugins/ExtraIcons/extraicons.cpp b/plugins/ExtraIcons/extraicons.cpp new file mode 100644 index 0000000000..e71086bad1 --- /dev/null +++ b/plugins/ExtraIcons/extraicons.cpp @@ -0,0 +1,540 @@ +/* + Copyright (C) 2009 Ricardo Pescuma Domenecci + + This is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this file; see the file license.txt. If + not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +#include "commons.h" + +// Prototypes /////////////////////////////////////////////////////////////////////////// + +PLUGININFOEX pluginInfo = { + sizeof(PLUGININFOEX), + "Extra Icons Service", + PLUGIN_MAKE_VERSION(0,2,5,0), + "Extra Icons Service", + "Ricardo Pescuma Domenecci", + "", + "© 2009 Ricardo Pescuma Domenecci", + "http://pescuma.org/miranda/extraicons", + 0, + 0, //doesn't replace anything built-in + { 0x112f7d30, 0xcd19, 0x4c74, { 0xa0, 0x3b, 0xbf, 0xbb, 0x76, 0xb7, 0x5b, 0xc4 } } // {112F7D30-CD19-4c74-A03BBFBB76B75BC4} +}; + +HINSTANCE hInst; +PLUGINLINK *pluginLink; +MM_INTERFACE mmi; +UTF8_INTERFACE utfi; +int hLangpack; + +vector hHooks; +vector hServices; +vector registeredExtraIcons; +vector extraIconsByHandle; +vector extraIconsBySlot; + +char *metacontacts_proto = NULL; +BOOL clistRebuildAlreadyCalled = FALSE; +BOOL clistApplyAlreadyCalled = FALSE; + +int clistFirstSlot = 0; +int clistSlotCount = 0; + +int ModulesLoaded(WPARAM wParam, LPARAM lParam); +int PreShutdown(WPARAM wParam, LPARAM lParam); +int IconsChanged(WPARAM wParam, LPARAM lParam); +int ClistExtraListRebuild(WPARAM wParam, LPARAM lParam); +int ClistExtraImageApply(WPARAM wParam, LPARAM lParam); +int ClistExtraClick(WPARAM wParam, LPARAM lParam); + +INT_PTR ExtraIcon_Register(WPARAM wParam, LPARAM lParam); +INT_PTR ExtraIcon_SetIcon(WPARAM wParam, LPARAM lParam); + +// Functions //////////////////////////////////////////////////////////////////////////// + +extern "C" BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +{ + hInst = hinstDLL; + return TRUE; +} + +extern "C" __declspec(dllexport) PLUGININFO* MirandaPluginInfo(DWORD mirandaVersion) +{ + pluginInfo.cbSize = sizeof(PLUGININFO); + return (PLUGININFO*) &pluginInfo; +} + +extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) +{ + pluginInfo.cbSize = sizeof(PLUGININFOEX); + return &pluginInfo; +} + +static const MUUID interfaces[] = { MIID_EXTRAICONSSERVICE, MIID_LAST }; +extern "C" __declspec(dllexport) const MUUID* MirandaPluginInterfaces(void) +{ + return interfaces; +} + +extern "C" int __declspec(dllexport) Load(PLUGINLINK *link) +{ + pluginLink = link; + + mir_getMMI(&mmi); + mir_getUTFI(&utfi); + mir_getLP(&pluginInfo); + + DWORD ret = CallService(MS_CLUI_GETCAPS, CLUICAPS_FLAGS2, 0); + clistFirstSlot = HIWORD(ret); + clistSlotCount = LOWORD(ret); + + + // Icons + IcoLib_Register("AlwaysVis", "Contact List", "Always Visible", IDI_ALWAYSVIS); + IcoLib_Register("NeverVis", "Contact List", "Never Visible", IDI_NEVERVIS); + IcoLib_Register("ChatActivity", "Contact List", "Chat Activity", IDI_CHAT); + IcoLib_Register("gender_male", "Contact List", "Male", IDI_MALE); + IcoLib_Register("gender_female", "Contact List", "Female", IDI_FEMALE); + + + // Hooks + hHooks.push_back(HookEvent(ME_SYSTEM_MODULESLOADED, &ModulesLoaded)); + hHooks.push_back(HookEvent(ME_SYSTEM_PRESHUTDOWN, &PreShutdown)); + hHooks.push_back(HookEvent(ME_CLIST_EXTRA_LIST_REBUILD, &ClistExtraListRebuild)); + hHooks.push_back(HookEvent(ME_CLIST_EXTRA_IMAGE_APPLY, &ClistExtraImageApply)); + hHooks.push_back(HookEvent(ME_CLIST_EXTRA_CLICK, &ClistExtraClick)); + + + // Services + hServices.push_back(CreateServiceFunction(MS_EXTRAICON_REGISTER, &ExtraIcon_Register)); + hServices.push_back(CreateServiceFunction(MS_EXTRAICON_SET_ICON, &ExtraIcon_SetIcon)); + + DefaultExtraIcons_Load(); + + return 0; +} + +extern "C" int __declspec(dllexport) Unload(void) +{ + return 0; +} + +// Called when all the modules are loaded +int ModulesLoaded(WPARAM wParam, LPARAM lParam) +{ + if (ServiceExists(MS_MC_GETPROTOCOLNAME)) + metacontacts_proto = (char *) CallService(MS_MC_GETPROTOCOLNAME, 0, 0); + + + // add our modules to the KnownModules list + CallService("DBEditorpp/RegisterSingleModule", (WPARAM) MODULE_NAME, 0); + CallService("DBEditorpp/RegisterSingleModule", (WPARAM) MODULE_NAME "Groups", 0); + + + // updater plugin support + if (ServiceExists(MS_UPDATE_REGISTER)) + { + Update upd = { 0 }; + char szCurrentVersion[30]; + + upd.cbSize = sizeof(upd); + upd.szComponentName = pluginInfo.shortName; + + upd.szUpdateURL = UPDATER_AUTOREGISTER; + + upd.szBetaVersionURL = "http://pescuma.org/miranda/extraicons_version.txt"; + upd.szBetaChangelogURL = "http://pescuma.org/miranda/extraicons#Changelog"; + upd.pbBetaVersionPrefix = (BYTE *) "Extra Icons Service "; + upd.cpbBetaVersionPrefix = strlen((char *) upd.pbBetaVersionPrefix); + upd.szBetaUpdateURL = "http://pescuma.org/miranda/extraicons.zip"; + + upd.pbVersion = (BYTE *) CreateVersionStringPlugin((PLUGININFO*) &pluginInfo, szCurrentVersion); + upd.cpbVersion = strlen((char *) upd.pbVersion); + + CallService(MS_UPDATE_REGISTER, 0, (LPARAM)&upd); + } + + hHooks.push_back(HookEvent(ME_SKIN2_ICONSCHANGED, &IconsChanged)); + + InitOptions(); + + return 0; +} + +int IconsChanged(WPARAM wParam, LPARAM lParam) +{ + return 0; +} + +int PreShutdown(WPARAM wParam, LPARAM lParam) +{ + DefaultExtraIcons_Unload(); + + unsigned int i; + for (i = 0; i < hServices.size(); i++) + DestroyServiceFunction(hServices[i]); + + for (i = 0; i < hHooks.size(); i++) + UnhookEvent(hHooks[i]); + + DeInitOptions(); + + return 0; +} + +int GetNumberOfSlots() +{ + return clistSlotCount; +} + +int ConvertToClistSlot(int slot) +{ + if (slot < 0) + return slot; + + return clistFirstSlot + slot; +} + +int Clist_SetExtraIcon(HANDLE hContact, int slot, HANDLE hImage) +{ + IconExtraColumn iec = { 0 }; + iec.cbSize = sizeof(iec); + iec.ColumnType = ConvertToClistSlot(slot); + iec.hImage = (hImage == NULL ? (HANDLE) -1 : hImage); + + return CallService(MS_CLIST_EXTRA_SET_ICON, (WPARAM) hContact, (LPARAM) &iec); +} + +ExtraIcon * GetExtraIcon(HANDLE id) +{ + unsigned int i = (int) id; + + if (i < 1 || i > extraIconsByHandle.size()) + return NULL; + + return extraIconsByHandle[i - 1]; +} + +ExtraIcon * GetExtraIconBySlot(int slot) +{ + for (unsigned int i = 0; i < extraIconsBySlot.size(); ++i) + { + ExtraIcon *extra = extraIconsBySlot[i]; + if (extra->getSlot() == slot) + return extra; + } + return NULL; +} + +BaseExtraIcon * GetExtraIconByName(const char *name) +{ + for (unsigned int i = 0; i < registeredExtraIcons.size(); ++i) + { + BaseExtraIcon *extra = registeredExtraIcons[i]; + if (strcmp(name, extra->getName()) == 0) + return extra; + } + return NULL; +} + +static void LoadGroups(vector &groups) +{ + unsigned int count = DBGetContactSettingWord(NULL, MODULE_NAME "Groups", "Count", 0); + for (unsigned int i = 0; i < count; ++i) + { + char setting[512]; + mir_snprintf(setting, MAX_REGS(setting), "%d_count", i); + unsigned int items = DBGetContactSettingWord(NULL, MODULE_NAME "Groups", setting, 0); + if (items < 1) + continue; + + mir_snprintf(setting, MAX_REGS(setting), "__group_%d", i); + ExtraIconGroup *group = new ExtraIconGroup(setting); + + for (unsigned int j = 0; j < items; ++j) + { + mir_snprintf(setting, MAX_REGS(setting), "%d_%d", i, j); + + DBVARIANT dbv = { 0 }; + if (!DBGetContactSettingString(NULL, MODULE_NAME "Groups", setting, &dbv)) + { + if (!IsEmpty(dbv.pszVal)) + { + BaseExtraIcon *extra = GetExtraIconByName(dbv.pszVal); + if (extra != NULL) + { + group->items.push_back(extra); + + if (extra->getSlot() >= 0) + group->setSlot(extra->getSlot()); + } + } + DBFreeVariant(&dbv); + } + } + + if (group->items.size() < 2) + { + delete group; + continue; + } + + groups.push_back(group); + } +} + +static ExtraIconGroup * IsInGroup(vector &groups, BaseExtraIcon *extra) +{ + for (unsigned int i = 0; i < groups.size(); ++i) + { + ExtraIconGroup *group = groups[i]; + for (unsigned int j = 0; j < group->items.size(); ++j) + { + if (extra == group->items[j]) + return group; + } + } + return NULL; +} + +struct compareFunc : std::binary_function +{ + bool operator()(const ExtraIcon * one, const ExtraIcon * two) const + { + return *one < *two; + } +}; + +void RebuildListsBasedOnGroups(vector &groups) +{ + unsigned int i; + for (i = 0; i < extraIconsByHandle.size(); ++i) + extraIconsByHandle[i] = registeredExtraIcons[i]; + + for (i = 0; i < extraIconsBySlot.size(); ++i) + { + ExtraIcon *extra = extraIconsBySlot[i]; + if (extra->getType() != EXTRAICON_TYPE_GROUP) + continue; + + delete extra; + } + extraIconsBySlot.clear(); + + for (i = 0; i < groups.size(); ++i) + { + ExtraIconGroup *group = groups[i]; + + for (unsigned int j = 0; j < group->items.size(); ++j) + extraIconsByHandle[group->items[j]->getID() - 1] = group; + + extraIconsBySlot.push_back(group); + } + + for (i = 0; i < extraIconsByHandle.size(); ++i) + { + ExtraIcon *extra = extraIconsByHandle[i]; + if (extra->getType() != EXTRAICON_TYPE_GROUP) + extraIconsBySlot.push_back(extra); + } + + std::sort(extraIconsBySlot.begin(), extraIconsBySlot.end(), compareFunc()); +} + +INT_PTR ExtraIcon_Register(WPARAM wParam, LPARAM lParam) +{ + if (wParam == 0) + return 0; + + EXTRAICON_INFO *ei = (EXTRAICON_INFO *) wParam; + if (ei->cbSize < (int) sizeof(EXTRAICON_INFO)) + return 0; + if (ei->type != EXTRAICON_TYPE_CALLBACK && ei->type != EXTRAICON_TYPE_ICOLIB) + return 0; + if (IsEmpty(ei->name) || IsEmpty(ei->description)) + return 0; + if (ei->type == EXTRAICON_TYPE_CALLBACK && (ei->ApplyIcon == NULL || ei->RebuildIcons == NULL)) + return 0; + + const char *desc = Translate(ei->description); + + BaseExtraIcon *extra = GetExtraIconByName(ei->name); + if (extra != NULL) + { + if (ei->type != extra->getType() || ei->type != EXTRAICON_TYPE_ICOLIB) + return 0; + + // Found one, now merge it + + if (_stricmp(extra->getDescription(), desc)) + { + string newDesc = extra->getDescription(); + newDesc += " / "; + newDesc += desc; + extra->setDescription(newDesc.c_str()); + } + + if (!IsEmpty(ei->descIcon)) + extra->setDescIcon(ei->descIcon); + + if (ei->OnClick != NULL) + extra->setOnClick(ei->OnClick, ei->onClickParam); + + if (extra->getSlot() > 0) + { + if (clistRebuildAlreadyCalled) + extra->rebuildIcons(); + if (clistApplyAlreadyCalled) + extraIconsByHandle[extra->getID() - 1]->applyIcons(); + } + + return extra->getID(); + } + + size_t id = registeredExtraIcons.size() + 1; + + switch (ei->type) + { + case EXTRAICON_TYPE_CALLBACK: + extra = new CallbackExtraIcon(id, ei->name, desc, ei->descIcon == NULL ? "" : ei->descIcon, + ei->RebuildIcons, ei->ApplyIcon, ei->OnClick, ei->onClickParam); + break; + case EXTRAICON_TYPE_ICOLIB: + extra = new IcolibExtraIcon(id, ei->name, desc, ei->descIcon == NULL ? "" : ei->descIcon, ei->OnClick, + ei->onClickParam); + break; + default: + return 0; + } + + char setting[512]; + mir_snprintf(setting, MAX_REGS(setting), "Position_%s", ei->name); + extra->setPosition(DBGetContactSettingWord(NULL, MODULE_NAME, setting, 1000)); + + mir_snprintf(setting, MAX_REGS(setting), "Slot_%s", ei->name); + int slot = DBGetContactSettingWord(NULL, MODULE_NAME, setting, 1); + if (slot == (WORD) -1) + slot = -1; + extra->setSlot(slot); + + registeredExtraIcons.push_back(extra); + extraIconsByHandle.push_back(extra); + + vector groups; + LoadGroups(groups); + + ExtraIconGroup *group = IsInGroup(groups, extra); + if (group != NULL) + { + RebuildListsBasedOnGroups(groups); + } + else + { + for (unsigned int i = 0; i < groups.size(); ++i) + delete groups[i]; + + extraIconsBySlot.push_back(extra); + std::sort(extraIconsBySlot.begin(), extraIconsBySlot.end(), compareFunc()); + } + + if (slot >= 0 || group != NULL) + { + if (clistRebuildAlreadyCalled) + extra->rebuildIcons(); + + slot = 0; + for (unsigned int i = 0; i < extraIconsBySlot.size(); ++i) + { + ExtraIcon *ex = extraIconsBySlot[i]; + if (ex->getSlot() < 0) + continue; + + int oldSlot = ex->getSlot(); + ex->setSlot(slot++); + + if (clistApplyAlreadyCalled && (ex == group || ex == extra || oldSlot != slot)) + extra->applyIcons(); + } + } + + return id; +} + +INT_PTR ExtraIcon_SetIcon(WPARAM wParam, LPARAM lParam) +{ + if (wParam == 0) + return -1; + + EXTRAICON *ei = (EXTRAICON *) wParam; + if (ei->cbSize < (int) sizeof(EXTRAICON)) + return -1; + if (ei->hExtraIcon == NULL || ei->hContact == NULL) + return -1; + + ExtraIcon *extra = GetExtraIcon(ei->hExtraIcon); + if (extra == NULL) + return -1; + + return extra->setIcon((int) ei->hExtraIcon, ei->hContact, ei->hImage); +} + +int ClistExtraListRebuild(WPARAM wParam, LPARAM lParam) +{ + clistRebuildAlreadyCalled = TRUE; + + ResetIcons(); + + for (unsigned int i = 0; i < extraIconsBySlot.size(); ++i) + extraIconsBySlot[i]->rebuildIcons(); + + return 0; +} + +int ClistExtraImageApply(WPARAM wParam, LPARAM lParam) +{ + HANDLE hContact = (HANDLE) wParam; + if (hContact == NULL) + return 0; + + clistApplyAlreadyCalled = TRUE; + + for (unsigned int i = 0; i < extraIconsBySlot.size(); ++i) + extraIconsBySlot[i]->applyIcon(hContact); + + return 0; +} + +int ClistExtraClick(WPARAM wParam, LPARAM lParam) +{ + HANDLE hContact = (HANDLE) wParam; + if (hContact == NULL) + return 0; + + int clistSlot = (int) lParam; + + for (unsigned int i = 0; i < extraIconsBySlot.size(); ++i) + { + ExtraIcon *extra = extraIconsBySlot[i]; + if (ConvertToClistSlot(extra->getSlot()) == clistSlot) + { + extra->onClick(hContact); + break; + } + } + + return 0; +} diff --git a/plugins/ExtraIcons/extraicons.sln b/plugins/ExtraIcons/extraicons.sln new file mode 100644 index 0000000000..2a93959cce --- /dev/null +++ b/plugins/ExtraIcons/extraicons.sln @@ -0,0 +1,26 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "extraicons", "extraicons.vcxproj", "{778D0DEB-C798-45D3-98E0-ABAB242573C8}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {778D0DEB-C798-45D3-98E0-ABAB242573C8}.Debug|Win32.ActiveCfg = Debug|Win32 + {778D0DEB-C798-45D3-98E0-ABAB242573C8}.Debug|Win32.Build.0 = Debug|Win32 + {778D0DEB-C798-45D3-98E0-ABAB242573C8}.Debug|x64.ActiveCfg = Debug|x64 + {778D0DEB-C798-45D3-98E0-ABAB242573C8}.Debug|x64.Build.0 = Debug|x64 + {778D0DEB-C798-45D3-98E0-ABAB242573C8}.Release|Win32.ActiveCfg = Release|Win32 + {778D0DEB-C798-45D3-98E0-ABAB242573C8}.Release|Win32.Build.0 = Release|Win32 + {778D0DEB-C798-45D3-98E0-ABAB242573C8}.Release|x64.ActiveCfg = Release|x64 + {778D0DEB-C798-45D3-98E0-ABAB242573C8}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/plugins/ExtraIcons/extraicons.vcxproj b/plugins/ExtraIcons/extraicons.vcxproj new file mode 100644 index 0000000000..bee809844b --- /dev/null +++ b/plugins/ExtraIcons/extraicons.vcxproj @@ -0,0 +1,239 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {778D0DEB-C798-45D3-98E0-ABAB242573C8} + ExtraIcons + + + + DynamicLibrary + MultiByte + + + DynamicLibrary + MultiByte + + + DynamicLibrary + MultiByte + true + + + DynamicLibrary + MultiByte + true + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(SolutionDir)$(Configuration)\Plugins\ + $(SolutionDir)$(Configuration)64\Plugins\ + $(SolutionDir)$(Configuration)\Obj\$(ProjectName)\ + $(SolutionDir)$(Configuration)64\Obj\$(ProjectName)\ + $(SolutionDir)$(Configuration)\Plugins\ + $(SolutionDir)$(Configuration)64\Plugins\ + $(SolutionDir)$(Configuration)\Obj\$(ProjectName)\ + $(SolutionDir)$(Configuration)64\Obj\$(ProjectName)\ + true + true + true + true + + + + Full + Size + ..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level3 + Use + commons.h + + + NDEBUG;%(PreprocessorDefinitions) + ..\..\include\msapi + + + /ALIGN:4096 /filealign:0x200 /ignore:4108 %(AdditionalOptions) + comctl32.lib;%(AdditionalDependencies) + true + true + 0x3EC20000 + true + $(IntDir)$(TargetName).lib + Windows + false + + + + + Full + Size + ..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories) + WIN64;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level3 + Use + commons.h + + + NDEBUG;%(PreprocessorDefinitions) + ..\..\include\msapi + + + /ALIGN:4096 /filealign:0x200 /ignore:4108 %(AdditionalOptions) + comctl32.lib;%(AdditionalDependencies) + true + true + 0x3EC20000 + true + $(IntDir)$(TargetName).lib + Windows + false + + + + + Disabled + ..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + Level3 + EditAndContinue + Use + commons.h + + + NDEBUG;%(PreprocessorDefinitions) + ..\..\include\msapi + + + /ALIGN:4096 /filealign:0x200 /ignore:4108 %(AdditionalOptions) + comctl32.lib;%(AdditionalDependencies) + true + 0x3EC20000 + $(IntDir)$(TargetName).lib + Windows + false + + + + + Disabled + ..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories) + WIN64;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + Level3 + Use + commons.h + + + NDEBUG;%(PreprocessorDefinitions) + ..\..\include\msapi + + + /ALIGN:4096 /filealign:0x200 /ignore:4108 %(AdditionalOptions) + comctl32.lib;%(AdditionalDependencies) + true + 0x3EC20000 + $(IntDir)$(TargetName).lib + Windows + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Create + Create + Create + Create + + + + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + + + \ No newline at end of file diff --git a/plugins/ExtraIcons/extraicons.vcxproj.filters b/plugins/ExtraIcons/extraicons.vcxproj.filters new file mode 100644 index 0000000000..9ea3a1ae86 --- /dev/null +++ b/plugins/ExtraIcons/extraicons.vcxproj.filters @@ -0,0 +1,124 @@ + + + + + {d1b17c52-ce87-4ebe-ab2d-69eab89a32a1} + h;hpp;hxx;hm;inl + + + {65beea6e-8646-427b-8827-1f1e70d835db} + ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe + + + {d6b93e43-b221-4629-bb6e-19f9fa9373a0} + cpp;c;cxx;rc;def;r;odl;idl;hpj;bat + + + {d7ab53c3-5a13-4c10-bd27-60f5549a39cd} + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Docs + + + Docs + + + Docs + + + Docs + + + + + Resource Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/plugins/ExtraIcons/options.cpp b/plugins/ExtraIcons/options.cpp new file mode 100644 index 0000000000..bbfc82629c --- /dev/null +++ b/plugins/ExtraIcons/options.cpp @@ -0,0 +1,866 @@ +/* + Copyright (C) 2009 Ricardo Pescuma Domenecci + + This is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this file; see the file license.txt. If + not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +#include "commons.h" + +#define ICON_SIZE 16 + +// Prototypes ///////////////////////////////////////////////////////////////////////////////////// + +HANDLE hOptHook = NULL; + +static INT_PTR CALLBACK OptionsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); + +// Functions ////////////////////////////////////////////////////////////////////////////////////// + + +int InitOptionsCallback(WPARAM wParam, LPARAM lParam) +{ + if (GetNumberOfSlots() < 1) + return 0; + + OPTIONSDIALOGPAGE odp = { 0 }; + odp.cbSize = sizeof(odp); + odp.hInstance = hInst; + odp.pszGroup = LPGENT("Contact List"); + odp.pszTitle = LPGENT("Extra icons"); + odp.pszTab = LPGENT("General"); + odp.pfnDlgProc = OptionsDlgProc; + odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPTIONS); + odp.flags = ODPF_BOLDGROUPS | ODPF_EXPERTONLY; + CallService(MS_OPT_ADDPAGE,wParam,(LPARAM)&odp); + + return 0; +} + +void InitOptions() +{ + hOptHook = HookEvent(ME_OPT_INITIALISE, InitOptionsCallback); +} + +void DeInitOptions() +{ + UnhookEvent(hOptHook); +} + +BOOL ScreenToClient(HWND hWnd, LPRECT lpRect) +{ + BOOL ret; + POINT pt; + + pt.x = lpRect->left; + pt.y = lpRect->top; + + ret = ScreenToClient(hWnd, &pt); + + if (!ret) + return ret; + + lpRect->left = pt.x; + lpRect->top = pt.y; + + pt.x = lpRect->right; + pt.y = lpRect->bottom; + + ret = ScreenToClient(hWnd, &pt); + + lpRect->right = pt.x; + lpRect->bottom = pt.y; + + return ret; +} + +static void RemoveExtraIcons(int slot) +{ + HANDLE hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + while (hContact != NULL) + { + Clist_SetExtraIcon(hContact, slot, NULL); + + hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0); + } +} + +#ifndef TVIS_FOCUSED +#define TVIS_FOCUSED 1 +#endif + +WNDPROC origTreeProc; + +static bool IsSelected(HWND tree, HTREEITEM hItem) +{ + return (TVIS_SELECTED & TreeView_GetItemState(tree, hItem, TVIS_SELECTED)) == TVIS_SELECTED; +} + +static void Tree_Select(HWND tree, HTREEITEM hItem) +{ + TreeView_SetItemState(tree, hItem, TVIS_SELECTED, TVIS_SELECTED); +} + +static void Tree_Unselect(HWND tree, HTREEITEM hItem) +{ + TreeView_SetItemState(tree, hItem, 0, TVIS_SELECTED); +} + +static void Tree_DropHilite(HWND tree, HTREEITEM hItem) +{ + TreeView_SetItemState(tree, hItem, TVIS_DROPHILITED, TVIS_DROPHILITED); +} + +static void Tree_DropUnhilite(HWND tree, HTREEITEM hItem) +{ + TreeView_SetItemState(tree, hItem, 0, TVIS_DROPHILITED); +} + +static void UnselectAll(HWND tree) +{ + TreeView_SelectItem(tree, NULL); + + HTREEITEM hItem = TreeView_GetRoot(tree); + while (hItem) + { + Tree_Unselect(tree, hItem); + hItem = TreeView_GetNextSibling(tree, hItem); + } +} + +static void Tree_SelectRange(HWND tree, HTREEITEM hStart, HTREEITEM hEnd) +{ + int start = 0; + int end = 0; + int i = 0; + HTREEITEM hItem = TreeView_GetRoot(tree); + while (hItem) + { + if (hItem == hStart) + start = i; + if (hItem == hEnd) + end = i; + + i++; + hItem = TreeView_GetNextSibling(tree, hItem); + } + + if (end < start) + { + int tmp = start; + start = end; + end = tmp; + } + + i = 0; + hItem = TreeView_GetRoot(tree); + while (hItem) + { + if (i >= start) + Tree_Select(tree, hItem); + if (i == end) + break; + + i++; + hItem = TreeView_GetNextSibling(tree, hItem); + } +} + +static int GetNumSelected(HWND tree) +{ + int ret = 0; + HTREEITEM hItem = TreeView_GetRoot(tree); + while (hItem) + { + if (IsSelected(tree, hItem)) + ret++; + hItem = TreeView_GetNextSibling(tree, hItem); + } + return ret; +} + +static void Tree_GetSelected(HWND tree, vector &selected) +{ + HTREEITEM hItem = TreeView_GetRoot(tree); + while (hItem) + { + if (IsSelected(tree, hItem)) + selected.push_back(hItem); + hItem = TreeView_GetNextSibling(tree, hItem); + } +} + +static void Tree_Select(HWND tree, vector &selected) +{ + for (unsigned int i = 0; i < selected.size(); i++) + if (selected[i] != NULL) + Tree_Select(tree, selected[i]); +} + +LRESULT CALLBACK TreeProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) + { + case WM_LBUTTONDOWN: + { + DWORD pos = (DWORD) lParam; + + TVHITTESTINFO hti; + hti.pt.x = (short) LOWORD(pos); + hti.pt.y = (short) HIWORD(pos); + if (!TreeView_HitTest(hwndDlg, &hti)) + { + UnselectAll(hwndDlg); + break; + } + + if (!(wParam & (MK_CONTROL | MK_SHIFT)) || !(hti.flags & (TVHT_ONITEMICON | TVHT_ONITEMLABEL + | TVHT_ONITEMRIGHT))) + { + UnselectAll(hwndDlg); + TreeView_SelectItem(hwndDlg, hti.hItem); + break; + } + + if (wParam & MK_CONTROL) + { + vector selected; + Tree_GetSelected(hwndDlg, selected); + + + // Check if have to deselect it + for (unsigned int i = 0; i < selected.size(); i++) + { + if (selected[i] == hti.hItem) + { + // Deselect it + UnselectAll(hwndDlg); + selected[i] = NULL; + + if (i > 0) + hti.hItem = selected[0]; + + else if (i + 1 < selected.size()) + hti.hItem = selected[i + 1]; + + else + hti.hItem = NULL; + + break; + } + } + + TreeView_SelectItem(hwndDlg, hti.hItem); + Tree_Select(hwndDlg, selected); + } + else if (wParam & MK_SHIFT) + { + HTREEITEM hItem = TreeView_GetSelection(hwndDlg); + if (hItem == NULL) + break; + + vector selected; + Tree_GetSelected(hwndDlg, selected); + + TreeView_SelectItem(hwndDlg, hti.hItem); + Tree_Select(hwndDlg, selected); + Tree_SelectRange(hwndDlg, hItem, hti.hItem); + } + + return 0; + } + } + + return CallWindowProc(origTreeProc, hwndDlg, msg, wParam, lParam); +} + +static vector * Tree_GetIDs(HWND tree, HTREEITEM hItem) +{ + TVITEM tvi = { 0 }; + tvi.mask = TVIF_HANDLE | TVIF_PARAM; + tvi.hItem = hItem; + TreeView_GetItem(tree, &tvi); + + return (vector *) tvi.lParam; +} + +static HTREEITEM Tree_AddExtraIcon(HWND tree, BaseExtraIcon *extra, bool selected, HTREEITEM hAfter = TVI_LAST) +{ + vector *ids = new vector ; + ids->push_back(extra->getID()); + + TVINSERTSTRUCT tvis = { 0 }; + tvis.hParent = NULL; + tvis.hInsertAfter = hAfter; + tvis.item.mask = TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_STATE; + tvis.item.stateMask = TVIS_STATEIMAGEMASK; + tvis.item.iSelectedImage = tvis.item.iImage = extra->getID(); + tvis.item.lParam = (LPARAM) ids; + tvis.item.pszText = (char *) extra->getDescription(); + tvis.item.state = INDEXTOSTATEIMAGEMASK(selected ? 2 : 1); + return TreeView_InsertItem(tree, &tvis); +} + +static HTREEITEM Tree_AddExtraIconGroup(HWND tree, vector &group, bool selected, HTREEITEM hAfter = TVI_LAST) +{ + vector *ids = new vector ; + string desc; + int img = 0; + for (unsigned int i = 0; i < group.size(); ++i) + { + BaseExtraIcon *extra = registeredExtraIcons[group[i] - 1]; + ids->push_back(extra->getID()); + + if (img == 0 && !IsEmpty(extra->getDescIcon())) + img = extra->getID(); + + if (i > 0) + desc += " / "; + desc += extra->getDescription(); + } + + TVINSERTSTRUCT tvis = { 0 }; + tvis.hParent = NULL; + tvis.hInsertAfter = hAfter; + tvis.item.mask = TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_STATE; + tvis.item.stateMask = TVIS_STATEIMAGEMASK; + tvis.item.iSelectedImage = tvis.item.iImage = img; + tvis.item.lParam = (LPARAM) ids; + tvis.item.pszText = (char *) desc.c_str(); + tvis.item.state = INDEXTOSTATEIMAGEMASK(selected ? 2 : 1); + return TreeView_InsertItem(tree, &tvis); +} + +static void GroupSelectedItems(HWND tree) +{ + vector toRemove; + vector ids; + bool selected = false; + HTREEITEM hPlace = NULL; + + + // Find items + + HTREEITEM hItem = TreeView_GetRoot(tree); + TVITEM tvi = { 0 }; + tvi.mask = TVIF_HANDLE | TVIF_PARAM | TVIF_TEXT | TVIF_STATE; + while (hItem) + { + if (IsSelected(tree, hItem)) + { + if (hPlace == NULL) + hPlace = hItem; + + tvi.hItem = hItem; + TreeView_GetItem(tree, &tvi); + + vector *iids = (vector *) tvi.lParam; + ids.insert(ids.end(), iids->begin(), iids->end()); + + if ((tvi.state & INDEXTOSTATEIMAGEMASK(3)) == INDEXTOSTATEIMAGEMASK(2)) + selected = true; + + toRemove.push_back(hItem); + } + + hItem = TreeView_GetNextSibling(tree, hItem); + } + + if (hPlace == NULL) + return; // None selected + + // Add new + int ii = ids.at(0); + ii = ids.at(1); + HTREEITEM hNew = Tree_AddExtraIconGroup(tree, ids, selected, hPlace); + + + // Remove old + for (unsigned int i = 0; i < toRemove.size(); ++i) + { + delete Tree_GetIDs(tree, toRemove[i]); + TreeView_DeleteItem(tree, toRemove[i]); + } + + // Select + UnselectAll(tree); + TreeView_SelectItem(tree, hNew); +} + +static void UngroupSelectedItems(HWND tree) +{ + HTREEITEM hItem = TreeView_GetSelection(tree); + if (hItem == NULL) + return; + vector *ids = Tree_GetIDs(tree, hItem); + if (ids->size() < 2) + return; + + bool selected = IsSelected(tree, hItem); + + for (size_t i = ids->size(); i > 0; --i) + { + BaseExtraIcon *extra = registeredExtraIcons[ids->at(i - 1) - 1]; + Tree_AddExtraIcon(tree, extra, selected, hItem); + } + + delete Tree_GetIDs(tree, hItem); + TreeView_DeleteItem(tree, hItem); + + UnselectAll(tree); +} + +static int ShowPopup(HWND hwndDlg, int popup) +{ + // Fix selection + HWND tree = GetDlgItem(hwndDlg, IDC_EXTRAORDER); + HTREEITEM hSelected = (HTREEITEM) SendMessage(tree, TVM_GETNEXTITEM, TVGN_DROPHILITE, 0); + HTREEITEM hItem = TreeView_GetRoot(tree); + while (hItem) + { + if (hItem != hSelected && IsSelected(tree, hItem)) + Tree_DropHilite(tree, hItem); + hItem = TreeView_GetNextSibling(tree, hItem); + } + // InvalidateRect(tree, NULL, FALSE); + + HMENU menu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_OPT_POPUP)); + HMENU submenu = GetSubMenu(menu, popup); + CallService(MS_LANGPACK_TRANSLATEMENU, (WPARAM) submenu, 0); + + DWORD pos = GetMessagePos(); + int ret = TrackPopupMenu(submenu, TPM_TOPALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD | TPM_LEFTALIGN, LOWORD(pos), + HIWORD(pos), 0, hwndDlg, NULL); + + DestroyMenu(menu); + + + // Revert selection + hItem = TreeView_GetRoot(tree); + while (hItem) + { + if (hItem != hSelected && IsSelected(tree, hItem)) + Tree_DropUnhilite(tree, hItem); + hItem = TreeView_GetNextSibling(tree, hItem); + } + + return ret; +} + +static int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) +{ + vector *a = (vector *) lParam1; + vector *b = (vector *) lParam2; + return registeredExtraIcons[a->at(0) - 1]->compare(registeredExtraIcons[b->at(0) - 1]); +} + +static INT_PTR CALLBACK OptionsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + static int dragging = 0; + static HANDLE hDragItem = NULL; + + switch (msg) + { + case WM_INITDIALOG: + { + TranslateDialogDefault(hwndDlg); + + int numSlots = GetNumberOfSlots(); + if (numSlots < (int) registeredExtraIcons.size()) + { + char txt[512]; + mir_snprintf(txt, MAX_REGS(txt), Translate("* only the first %d icons will be shown"), numSlots); + + HWND label = GetDlgItem(hwndDlg, IDC_MAX_ICONS_L); + SetWindowText(label, txt); + ShowWindow(label, SW_SHOW); + } + + HWND tree = GetDlgItem(hwndDlg, IDC_EXTRAORDER); + SetWindowLongPtr(tree, GWL_STYLE, GetWindowLong(tree, GWL_STYLE) | TVS_NOHSCROLL); + + int cx = GetSystemMetrics(SM_CXSMICON); + HIMAGELIST hImageList = ImageList_Create(cx, cx, ILC_COLOR32 | ILC_MASK, 2, 2); + + HICON hDefaultIcon = (HICON) LoadImage(hInst, MAKEINTRESOURCE(IDI_EMPTY), IMAGE_ICON, cx, cx, + LR_DEFAULTCOLOR | LR_SHARED); + ImageList_AddIcon(hImageList, hDefaultIcon); + DestroyIcon(hDefaultIcon); + + unsigned int i; + for (i = 0; i < registeredExtraIcons.size(); ++i) + { + ExtraIcon *extra = registeredExtraIcons[i]; + + HICON hIcon = IcoLib_LoadIcon(extra->getDescIcon()); + + if (hIcon == NULL) + { + HICON hDefaultIcon = (HICON) LoadImage(hInst, MAKEINTRESOURCE(IDI_EMPTY), IMAGE_ICON, cx, cx, + LR_DEFAULTCOLOR | LR_SHARED); + ImageList_AddIcon(hImageList, hDefaultIcon); + DestroyIcon(hDefaultIcon); + } + else + { + ImageList_AddIcon(hImageList, hIcon); + IcoLib_ReleaseIcon(hIcon); + } + } + TreeView_SetImageList(tree, hImageList, TVSIL_NORMAL); + + for (i = 0; i < extraIconsBySlot.size(); ++i) + { + ExtraIcon *extra = extraIconsBySlot[i]; + + if (extra->getType() == EXTRAICON_TYPE_GROUP) + { + ExtraIconGroup *group = (ExtraIconGroup *) extra; + vector ids; + for (unsigned int j = 0; j < group->items.size(); ++j) + ids.push_back(group->items[j]->getID()); + Tree_AddExtraIconGroup(tree, ids, extra->isEnabled()); + } + else + { + Tree_AddExtraIcon(tree, (BaseExtraIcon *) extra, extra->isEnabled()); + } + } + + TVSORTCB sort = { 0 }; + sort.hParent = NULL; + sort.lParam = 0; + sort.lpfnCompare = CompareFunc; + TreeView_SortChildrenCB(tree, &sort, 0); + + origTreeProc = (WNDPROC) SetWindowLongPtr(tree, -4, (INT_PTR)TreeProc); + + return TRUE; + } + case WM_NOTIFY: + { + LPNMHDR lpnmhdr = (LPNMHDR) lParam; + if (lpnmhdr->idFrom == 0) + { + if (lpnmhdr->code == (UINT) PSN_APPLY) + { + unsigned int i; + + HWND tree = GetDlgItem(hwndDlg, IDC_EXTRAORDER); + + + // Store old slots + int *oldSlots = new int[registeredExtraIcons.size()]; + int lastUsedSlot = -1; + for (i = 0; i < registeredExtraIcons.size(); ++i) + { + if (extraIconsByHandle[i] == registeredExtraIcons[i]) + oldSlots[i] = registeredExtraIcons[i]->getSlot(); + else + // Remove old slot for groups to re-set images + oldSlots[i] = -1; + lastUsedSlot = MAX(lastUsedSlot, registeredExtraIcons[i]->getSlot()); + } + lastUsedSlot = MIN(lastUsedSlot, GetNumberOfSlots()); + + + // Get user data and create new groups + vector groups; + + BYTE pos = 0; + int firstEmptySlot = 0; + HTREEITEM ht = TreeView_GetRoot(tree); + TVITEM tvi = { 0 }; + tvi.mask = TVIF_HANDLE | TVIF_PARAM | TVIF_STATE; + tvi.stateMask = TVIS_STATEIMAGEMASK; + while (ht) + { + tvi.hItem = ht; + TreeView_GetItem(tree, &tvi); + + vector *ids = (vector *) tvi.lParam; + if (ids == NULL || ids->size() < 1) + continue; // ??? + + bool enabled = ((tvi.state & INDEXTOSTATEIMAGEMASK(3)) == INDEXTOSTATEIMAGEMASK(2)); + int slot = (enabled ? firstEmptySlot++ : -1); + if (slot >= GetNumberOfSlots()) + slot = -1; + + if (ids->size() == 1) + { + BaseExtraIcon *extra = registeredExtraIcons[ids->at(0) - 1]; + extra->setPosition(pos++); + extra->setSlot(slot); + } + else + { + char name[128]; + mir_snprintf(name, MAX_REGS(name), "__group_%d", groups.size()); + + ExtraIconGroup *group = new ExtraIconGroup(name); + + for (i = 0; i < ids->size(); ++i) + { + BaseExtraIcon *extra = registeredExtraIcons[ids->at(i) - 1]; + extra->setPosition(pos++); + + group->addExtraIcon(extra); + } + + group->setSlot(slot); + + groups.push_back(group); + } + + ht = TreeView_GetNextSibling(tree, ht); + } + + // Store data + for (i = 0; i < registeredExtraIcons.size(); ++i) + { + BaseExtraIcon *extra = registeredExtraIcons[i]; + + char setting[512]; + mir_snprintf(setting, MAX_REGS(setting), "Position_%s", extra->getName()); + DBWriteContactSettingWord(NULL, MODULE_NAME, setting, extra->getPosition()); + + mir_snprintf(setting, MAX_REGS(setting), "Slot_%s", extra->getName()); + DBWriteContactSettingWord(NULL, MODULE_NAME, setting, extra->getSlot()); + } + + CallService(MS_DB_MODULE_DELETE, 0, (LPARAM) MODULE_NAME "Groups"); + DBWriteContactSettingWord(NULL, MODULE_NAME "Groups", "Count", groups.size()); + for (i = 0; i < groups.size(); ++i) + { + ExtraIconGroup *group = groups[i]; + + char setting[512]; + mir_snprintf(setting, MAX_REGS(setting), "%d_count", i); + DBWriteContactSettingWord(NULL, MODULE_NAME "Groups", setting, group->items.size()); + + for (unsigned int j = 0; j < group->items.size(); ++j) + { + BaseExtraIcon *extra = group->items[j]; + + mir_snprintf(setting, MAX_REGS(setting), "%d_%d", i, j); + DBWriteContactSettingString(NULL, MODULE_NAME "Groups", setting, extra->getName()); + } + } + + // Clean removed slots + for (int j = firstEmptySlot; j <= lastUsedSlot; ++j) + RemoveExtraIcons(j); + + + // Apply icons to new slots + RebuildListsBasedOnGroups(groups); + for (i = 0; i < extraIconsBySlot.size(); ++i) + { + ExtraIcon *extra = extraIconsBySlot[i]; + + if (extra->getType() != EXTRAICON_TYPE_GROUP) + { + if (oldSlots[((BaseExtraIcon *) extra)->getID() - 1] == extra->getSlot()) + continue; + } + + extra->applyIcons(); + } + + delete[] oldSlots; + + return TRUE; + } + } + else if (lpnmhdr->idFrom == IDC_EXTRAORDER) + { + HWND tree = GetDlgItem(hwndDlg, IDC_EXTRAORDER); + + switch (lpnmhdr->code) + { + case TVN_BEGINDRAG: + { + SetCapture(hwndDlg); + dragging = 1; + hDragItem = ((LPNMTREEVIEWA) lParam)->itemNew.hItem; + TreeView_SelectItem(tree, hDragItem); + break; + } + case NM_CLICK: + { + DWORD pos = GetMessagePos(); + + TVHITTESTINFO hti; + hti.pt.x = (short) LOWORD(pos); + hti.pt.y = (short) HIWORD(pos); + ScreenToClient(lpnmhdr->hwndFrom, &hti.pt); + if (TreeView_HitTest(lpnmhdr->hwndFrom, &hti)) + { + if (hti.flags & TVHT_ONITEMSTATEICON) + { + TreeView_SelectItem(tree, hti.hItem); + SendMessage(GetParent(hwndDlg), PSM_CHANGED, (WPARAM) hwndDlg, 0); + } + } + break; + } + case TVN_KEYDOWN: + { + TV_KEYDOWN *nmkd = (TV_KEYDOWN *) lpnmhdr; + if (nmkd->wVKey == VK_SPACE) + { + // Determine the selected tree item. + HTREEITEM hItem = TreeView_GetSelection(tree); + if (hItem != NULL) + SendMessage(GetParent(hwndDlg), PSM_CHANGED, (WPARAM) hwndDlg, 0); + } + break; + } + case NM_RCLICK: + { + HTREEITEM hSelected = (HTREEITEM) SendMessage(tree, TVM_GETNEXTITEM, TVGN_DROPHILITE, 0); + if (hSelected != NULL && !IsSelected(tree, hSelected)) + { + UnselectAll(tree); + TreeView_SelectItem(tree, hSelected); + } + + int sels = GetNumSelected(tree); + if (sels > 1) + { + if (ShowPopup(hwndDlg, 0) == ID_GROUP) + { + GroupSelectedItems(tree); + SendMessage(GetParent(hwndDlg), PSM_CHANGED, (WPARAM) hwndDlg, 0); + } + } + else if (sels == 1) + { + HTREEITEM hItem = TreeView_GetSelection(tree); + vector *ids = Tree_GetIDs(tree, hItem); + if (ids->size() > 1) + { + if (ShowPopup(hwndDlg, 1) == ID_UNGROUP) + { + UngroupSelectedItems(tree); + SendMessage(GetParent(hwndDlg), PSM_CHANGED, (WPARAM) hwndDlg, 0); + } + } + } + break; + } + } + } + + break; + } + case WM_MOUSEMOVE: + { + if (!dragging) + break; + + HWND tree = GetDlgItem(hwndDlg, IDC_EXTRAORDER); + + TVHITTESTINFO hti; + hti.pt.x = (short) LOWORD(lParam); + hti.pt.y = (short) HIWORD(lParam); + ClientToScreen(hwndDlg, &hti.pt); + ScreenToClient(tree, &hti.pt); + TreeView_HitTest(tree, &hti); + if (hti.flags & (TVHT_ONITEM | TVHT_ONITEMRIGHT)) + { + HTREEITEM it = hti.hItem; + hti.pt.y -= TreeView_GetItemHeight(tree) / 2; + TreeView_HitTest(tree, &hti); + if (!(hti.flags & TVHT_ABOVE)) + TreeView_SetInsertMark(tree, hti.hItem, 1); + else + TreeView_SetInsertMark(tree, it, 0); + } + else + { + if (hti.flags & TVHT_ABOVE) + SendDlgItemMessage(hwndDlg, IDC_EXTRAORDER, WM_VSCROLL, MAKEWPARAM(SB_LINEUP,0), 0); + if (hti.flags & TVHT_BELOW) + SendDlgItemMessage(hwndDlg, IDC_EXTRAORDER, WM_VSCROLL, MAKEWPARAM(SB_LINEDOWN,0), 0); + TreeView_SetInsertMark(tree, NULL, 0); + } + break; + } + case WM_LBUTTONUP: + { + if (!dragging) + break; + + HWND tree = GetDlgItem(hwndDlg, IDC_EXTRAORDER); + + TreeView_SetInsertMark(tree, NULL, 0); + dragging = 0; + ReleaseCapture(); + + TVHITTESTINFO hti; + hti.pt.x = (short) LOWORD(lParam); + hti.pt.y = (short) HIWORD(lParam); + ClientToScreen(hwndDlg, &hti.pt); + ScreenToClient(tree, &hti.pt); + hti.pt.y -= TreeView_GetItemHeight(tree) / 2; + TreeView_HitTest(tree,&hti); + if (hDragItem == hti.hItem) + break; + + if (!(hti.flags & (TVHT_ONITEM | TVHT_ONITEMRIGHT | TVHT_ABOVE | TVHT_BELOW))) + break; + + if (hti.flags & TVHT_ABOVE) + hti.hItem = TVI_FIRST; + else if (hti.flags & TVHT_BELOW) + hti.hItem = TVI_LAST; + + TVINSERTSTRUCT tvis; + TCHAR name[512]; + tvis.item.mask = TVIF_HANDLE | TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_STATE; + tvis.item.stateMask = 0xFFFFFFFF; + tvis.item.pszText = name; + tvis.item.cchTextMax = MAX_REGS(name); + tvis.item.hItem = (HTREEITEM) hDragItem; + TreeView_GetItem(tree, &tvis.item); + + TreeView_DeleteItem(tree, hDragItem); + + tvis.hParent = NULL; + tvis.hInsertAfter = hti.hItem; + TreeView_SelectItem(tree, TreeView_InsertItem(tree, &tvis)); + + SendMessage(GetParent(hwndDlg), PSM_CHANGED, (WPARAM) hwndDlg, 0); + + break; + } + case WM_DESTROY: + { + HWND tree = GetDlgItem(hwndDlg, IDC_EXTRAORDER); + HTREEITEM hItem = TreeView_GetRoot(tree); + while (hItem) + { + delete Tree_GetIDs(tree, hItem); + hItem = TreeView_GetNextSibling(tree, hItem); + } + + break; + } + } + + return 0; +} diff --git a/plugins/ExtraIcons/options.h b/plugins/ExtraIcons/options.h new file mode 100644 index 0000000000..5d50348c0e --- /dev/null +++ b/plugins/ExtraIcons/options.h @@ -0,0 +1,32 @@ +/* + Copyright (C) 2009 Ricardo Pescuma Domenecci + + This is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this file; see the file license.txt. If + not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +#ifndef __OPTIONS_H__ +# define __OPTIONS_H__ + + +// Initializations needed by options +void InitOptions(); + +// Deinitializations needed by options +void DeInitOptions(); + + + +#endif // __OPTIONS_H__ diff --git a/plugins/ExtraIcons/res/AlwaysVis.ico b/plugins/ExtraIcons/res/AlwaysVis.ico new file mode 100644 index 0000000000..05013a077d Binary files /dev/null and b/plugins/ExtraIcons/res/AlwaysVis.ico differ diff --git a/plugins/ExtraIcons/res/Chatchannel.ico b/plugins/ExtraIcons/res/Chatchannel.ico new file mode 100644 index 0000000000..2e48365971 Binary files /dev/null and b/plugins/ExtraIcons/res/Chatchannel.ico differ diff --git a/plugins/ExtraIcons/res/NeverVis.ico b/plugins/ExtraIcons/res/NeverVis.ico new file mode 100644 index 0000000000..6aebec2acc Binary files /dev/null and b/plugins/ExtraIcons/res/NeverVis.ico differ diff --git a/plugins/ExtraIcons/res/empty.ico b/plugins/ExtraIcons/res/empty.ico new file mode 100644 index 0000000000..8ba93283ac Binary files /dev/null and b/plugins/ExtraIcons/res/empty.ico differ diff --git a/plugins/ExtraIcons/res/female.ico b/plugins/ExtraIcons/res/female.ico new file mode 100644 index 0000000000..faa08fc6c0 Binary files /dev/null and b/plugins/ExtraIcons/res/female.ico differ diff --git a/plugins/ExtraIcons/res/male.ico b/plugins/ExtraIcons/res/male.ico new file mode 100644 index 0000000000..5bee53143a Binary files /dev/null and b/plugins/ExtraIcons/res/male.ico differ diff --git a/plugins/ExtraIcons/resource.h b/plugins/ExtraIcons/resource.h new file mode 100644 index 0000000000..42525157f8 --- /dev/null +++ b/plugins/ExtraIcons/resource.h @@ -0,0 +1,33 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by resource.rc +// +#define IDD_OPTIONS_OLD 119 +#define IDI_ALWAYSVIS 120 +#define IDD_OPTIONS 120 +#define IDI_NEVERVIS 121 +#define IDI_CHAT 122 +#define IDI_MALE 123 +#define IDI_FEMALE 124 +#define IDI_EMPTY 125 +#define IDR_OPT_POPUP 126 +#define IDC_SLOT_L 1075 +#define IDC_SLOT 1076 +#define IDC_MAX_ICONS_L 1077 +#define IDC_EXTRAORDER 1889 +#define ID_GROUP 40006 +#define ID_UNGROUP 40007 +#define IDC_STATIC -1 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NO_MFC 1 +#define _APS_3D_CONTROLS 1 +#define _APS_NEXT_RESOURCE_VALUE 127 +#define _APS_NEXT_COMMAND_VALUE 40008 +#define _APS_NEXT_CONTROL_VALUE 1078 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/plugins/ExtraIcons/resource.rc b/plugins/ExtraIcons/resource.rc new file mode 100644 index 0000000000..22cbf020df --- /dev/null +++ b/plugins/ExtraIcons/resource.rc @@ -0,0 +1,150 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "resource.h" +#include "winresrc.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Neutral resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU) +#ifdef _WIN32 +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_OPTIONS DIALOGEX 0, 0, 276, 229 +STYLE DS_FIXEDSYS | WS_CHILD | WS_VISIBLE +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg" +BEGIN + LTEXT "Select the extra icons to be shown in the contact list:", + IDC_STATIC,1,9,274,13 + CONTROL "",IDC_EXTRAORDER,"SysTreeView32",TVS_NOTOOLTIPS | + TVS_CHECKBOXES | TVS_FULLROWSELECT | WS_BORDER | + WS_TABSTOP,1,24,274,160 + LTEXT "* only the first %d icons will be shown", + IDC_MAX_ICONS_L,1,190,274,13,NOT WS_VISIBLE + LTEXT "You can group/ungroup icons by selecting then (CTRL+left click) and using the popup menu (right click)", + IDC_STATIC,1,208,274,20 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + IDD_OPTIONS, DIALOG + BEGIN + LEFTMARGIN, 1 + RIGHTMARGIN, 275 + TOPMARGIN, 1 + BOTTOMMARGIN, 228 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_ALWAYSVIS ICON DISCARDABLE "res\\AlwaysVis.ico" +IDI_NEVERVIS ICON DISCARDABLE "res\\NeverVis.ico" +IDI_CHAT ICON DISCARDABLE "res\\Chatchannel.ico" +IDI_MALE ICON DISCARDABLE "res\\male.ico" +IDI_FEMALE ICON DISCARDABLE "res\\female.ico" +IDI_EMPTY ICON DISCARDABLE "res\\empty.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IDR_OPT_POPUP MENU DISCARDABLE +BEGIN + POPUP "Group" + BEGIN + MENUITEM "Group", ID_GROUP + END + POPUP "Ungroup" + BEGIN + MENUITEM "Ungroup", ID_UNGROUP + END +END + +#endif // Neutral resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// English (Canada) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENC) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_CAN +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""resource.h""\r\n" + "#include ""winresrc.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // English (Canada) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/plugins/ExtraIcons/usedIcons.cpp b/plugins/ExtraIcons/usedIcons.cpp new file mode 100644 index 0000000000..de58069293 --- /dev/null +++ b/plugins/ExtraIcons/usedIcons.cpp @@ -0,0 +1,110 @@ +/* + Copyright (C) 2009 Ricardo Pescuma Domenecci + + This is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this file; see the file license.txt. If + not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +#include "commons.h" + +struct Icon +{ + string name; + int refCount; + HANDLE hImage; + + Icon(const char *icolibName) : + name(icolibName), refCount(0), hImage(NULL) + { + } +}; + +static vector usedIcons; + +static Icon * FindIcon(const char *icolibName) +{ + Icon *icon = NULL; + + for (unsigned int i = 0; i < usedIcons.size(); ++i) + { + Icon *tmp = &usedIcons[i]; + if (tmp->name != icolibName) + continue; + + icon = tmp; + break; + } + + if (icon == NULL) + { + usedIcons.push_back(Icon(icolibName)); + icon = &usedIcons[usedIcons.size() - 1]; + } + + if (icon->hImage == NULL) + { + HICON hIcon = IcoLib_LoadIcon(icon->name.c_str()); + if (hIcon != NULL) + { + icon->hImage = (HANDLE) CallService(MS_CLIST_EXTRA_ADD_ICON, (WPARAM) hIcon, 0); + if (icon->hImage == (HANDLE) -1) + icon->hImage = NULL; + + IcoLib_ReleaseIcon(hIcon); + } + } + + return icon; +} + +HANDLE GetIcon(const char *icolibName) +{ + return FindIcon(icolibName)->hImage; +} + +HANDLE AddIcon(const char *icolibName) +{ + Icon *icon = FindIcon(icolibName); + icon->refCount++; + return icon->hImage; +} + +void RemoveIcon(const char *icolibName) +{ + for (unsigned int i = 0; i < usedIcons.size(); ++i) + { + Icon *icon = &usedIcons[i]; + + if (icon->name != icolibName) + continue; + + icon->refCount--; + break; + } +} + +static bool NotUsedIcon(const Icon &icon) +{ + return icon.refCount <= 0; +} + +void ResetIcons() +{ + usedIcons.erase(std::remove_if(usedIcons.begin(), usedIcons.end(), NotUsedIcon), usedIcons.end()); + + for (unsigned int i = 0; i < usedIcons.size(); ++i) + usedIcons[i].hImage = NULL; +} + diff --git a/plugins/ExtraIcons/usedIcons.h b/plugins/ExtraIcons/usedIcons.h new file mode 100644 index 0000000000..ef3a0f0200 --- /dev/null +++ b/plugins/ExtraIcons/usedIcons.h @@ -0,0 +1,29 @@ +/* + Copyright (C) 2009 Ricardo Pescuma Domenecci + + This is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this file; see the file license.txt. If + not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +#ifndef __USEDICONS_H__ +#define __USEDICONS_H__ + +HANDLE GetIcon(const char *icolibName); +HANDLE AddIcon(const char *icolibName); +void RemoveIcon(const char *icolibName); +void ResetIcons(); + + +#endif // __USEDICONS_H__ -- cgit v1.2.3