summaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'plugins')
-rw-r--r--plugins/StatusPlugins/KeepStatus/action_keepstatus.cpp2
-rw-r--r--plugins/StatusPlugins/StartupStatus/StartupStatus_10.vcxproj16
-rw-r--r--plugins/VersionInfo/AggressiveOptimize.h58
-rw-r--r--plugins/VersionInfo/CPlugin.cpp143
-rw-r--r--plugins/VersionInfo/CPlugin.h69
-rw-r--r--plugins/VersionInfo/CVersionInfo.cpp1588
-rw-r--r--plugins/VersionInfo/CVersionInfo.h116
-rw-r--r--plugins/VersionInfo/VersionInfo.html11
-rw-r--r--plugins/VersionInfo/VersionInfo.icobin0 -> 2550 bytes
-rw-r--r--plugins/VersionInfo/VersionInfo_10.vcxproj382
-rw-r--r--plugins/VersionInfo/VersionInfo_10.vcxproj.filters61
-rw-r--r--plugins/VersionInfo/common.h120
-rw-r--r--plugins/VersionInfo/dlgHandlers.cpp700
-rw-r--r--plugins/VersionInfo/dlgHandlers.h44
-rw-r--r--plugins/VersionInfo/docs/Pack files/files_release.txt1
-rw-r--r--plugins/VersionInfo/docs/Pack files/files_releasex64.txt1
-rw-r--r--plugins/VersionInfo/docs/Pack files/files_source.txt4
-rw-r--r--plugins/VersionInfo/docs/Pack files/files_source_ignore.txt4
-rw-r--r--plugins/VersionInfo/docs/pack source.bat8
-rw-r--r--plugins/VersionInfo/docs/pack symbols.bat9
-rw-r--r--plugins/VersionInfo/docs/pack x64.bat10
-rw-r--r--plugins/VersionInfo/docs/pack.bat10
-rw-r--r--plugins/VersionInfo/docs/readme_versioninfo.txt433
-rw-r--r--plugins/VersionInfo/docs/rebase_versioninfo.txt33
-rw-r--r--plugins/VersionInfo/docs/symbols_exclude.txt1
-rw-r--r--plugins/VersionInfo/docs/versioninfo.gifbin0 -> 100803 bytes
-rw-r--r--plugins/VersionInfo/hooked_events.cpp97
-rw-r--r--plugins/VersionInfo/hooked_events.h35
-rw-r--r--plugins/VersionInfo/m_versioninfo.h48
-rw-r--r--plugins/VersionInfo/main.cpp175
-rw-r--r--plugins/VersionInfo/resource.h71
-rw-r--r--plugins/VersionInfo/resource.rc225
-rw-r--r--plugins/VersionInfo/sdk/m_folders.h284
-rw-r--r--plugins/VersionInfo/sdk/m_updater.h146
-rw-r--r--plugins/VersionInfo/services.cpp80
-rw-r--r--plugins/VersionInfo/services.h33
-rw-r--r--plugins/VersionInfo/utils.cpp606
-rw-r--r--plugins/VersionInfo/utils.h54
-rw-r--r--plugins/VersionInfo/version.h49
-rw-r--r--plugins/VersionInfo/version.rc100
-rw-r--r--plugins/dbeditorpp/Res/Contacts.icobin0 -> 1406 bytes
-rw-r--r--plugins/dbeditorpp/Res/Icon_1.icobin0 -> 1078 bytes
-rw-r--r--plugins/dbeditorpp/Res/Icon_14.icobin0 -> 318 bytes
-rw-r--r--plugins/dbeditorpp/Res/Icon_15.icobin0 -> 318 bytes
-rw-r--r--plugins/dbeditorpp/Res/Icon_16.icobin0 -> 318 bytes
-rw-r--r--plugins/dbeditorpp/Res/Icon_17.icobin0 -> 318 bytes
-rw-r--r--plugins/dbeditorpp/Res/Icon_18.icobin0 -> 318 bytes
-rw-r--r--plugins/dbeditorpp/Res/Icon_4.icobin0 -> 1406 bytes
-rw-r--r--plugins/dbeditorpp/Res/Red.icobin0 -> 1406 bytes
-rw-r--r--plugins/dbeditorpp/Res/Red_open.icobin0 -> 1406 bytes
-rw-r--r--plugins/dbeditorpp/Res/UserMenu.icobin0 -> 1406 bytes
-rw-r--r--plugins/dbeditorpp/Res/Yellow.icobin0 -> 1406 bytes
-rw-r--r--plugins/dbeditorpp/Res/Yellow_open.icobin0 -> 1406 bytes
-rw-r--r--plugins/dbeditorpp/Res/dbepp.icobin0 -> 318 bytes
-rw-r--r--plugins/dbeditorpp/Res/handle.icobin0 -> 318 bytes
-rw-r--r--plugins/dbeditorpp/Res/handle1.icobin0 -> 318 bytes
-rw-r--r--plugins/dbeditorpp/Res/ico_RegEdit.icobin0 -> 2550 bytes
-rw-r--r--plugins/dbeditorpp/Res/offline2.icobin0 -> 1406 bytes
-rw-r--r--plugins/dbeditorpp/Res/online2.icobin0 -> 1406 bytes
-rw-r--r--plugins/dbeditorpp/Res/unicode.icobin0 -> 318 bytes
-rw-r--r--plugins/dbeditorpp/Version.h28
-rw-r--r--plugins/dbeditorpp/Version.rc38
-rw-r--r--plugins/dbeditorpp/addeditsettingsdlg.cpp458
-rw-r--r--plugins/dbeditorpp/copymodule.cpp197
-rw-r--r--plugins/dbeditorpp/dbeditorpp.dep51
-rw-r--r--plugins/dbeditorpp/dbeditorpp.dsp293
-rw-r--r--plugins/dbeditorpp/dbeditorpp.dsw29
-rw-r--r--plugins/dbeditorpp/dbeditorpp.mak737
-rw-r--r--plugins/dbeditorpp/dbeditorpp.ncbbin0 -> 91136 bytes
-rw-r--r--plugins/dbeditorpp/dbeditorpp.optbin0 -> 49664 bytes
-rw-r--r--plugins/dbeditorpp/dbeditorpp.sln21
-rw-r--r--plugins/dbeditorpp/dbeditorpp_10.vcxproj519
-rw-r--r--plugins/dbeditorpp/dbeditorpp_10.vcxproj.filters145
-rw-r--r--plugins/dbeditorpp/dbeditorpp_readme.txt143
-rw-r--r--plugins/dbeditorpp/dbeditorpp_translation.txt38
-rw-r--r--plugins/dbeditorpp/deletemodule.cpp148
-rw-r--r--plugins/dbeditorpp/exportimport.cpp758
-rw-r--r--plugins/dbeditorpp/findwindow.cpp725
-rw-r--r--plugins/dbeditorpp/headers.h267
-rw-r--r--plugins/dbeditorpp/icons.cpp176
-rw-r--r--plugins/dbeditorpp/knownmodules.cpp84
-rw-r--r--plugins/dbeditorpp/main.cpp715
-rw-r--r--plugins/dbeditorpp/main_window.cpp665
-rw-r--r--plugins/dbeditorpp/modsettingenum.cpp88
-rw-r--r--plugins/dbeditorpp/modsettingenum.h17
-rw-r--r--plugins/dbeditorpp/modules.cpp109
-rw-r--r--plugins/dbeditorpp/moduletree.cpp1135
-rw-r--r--plugins/dbeditorpp/options.cpp98
-rw-r--r--plugins/dbeditorpp/resource.h156
-rw-r--r--plugins/dbeditorpp/resource.rc515
-rw-r--r--plugins/dbeditorpp/settinglist.cpp1261
-rw-r--r--plugins/dbeditorpp/threads.cpp48
-rw-r--r--plugins/dbeditorpp/watchedvars.cpp391
-rw-r--r--plugins/extraicons/.cproject993
-rw-r--r--plugins/extraicons/.project70
-rw-r--r--plugins/extraicons/BaseExtraIcon.cpp79
-rw-r--r--plugins/extraicons/BaseExtraIcon.h52
-rw-r--r--plugins/extraicons/CallbackExtraIcon.cpp72
-rw-r--r--plugins/extraicons/CallbackExtraIcon.h47
-rw-r--r--plugins/extraicons/DefaultExtraIcons.cpp390
-rw-r--r--plugins/extraicons/DefaultExtraIcons.h26
-rw-r--r--plugins/extraicons/Docs/extraicons.pngbin0 -> 36754 bytes
-rw-r--r--plugins/extraicons/Docs/extraicons_changelog.txt26
-rw-r--r--plugins/extraicons/Docs/extraicons_readme.txt26
-rw-r--r--plugins/extraicons/Docs/extraicons_version.txt1
-rw-r--r--plugins/extraicons/Docs/langpack_extraicons.txt15
-rw-r--r--plugins/extraicons/ExtraIcon.cpp130
-rw-r--r--plugins/extraicons/ExtraIcon.h73
-rw-r--r--plugins/extraicons/ExtraIconGroup.cpp213
-rw-r--r--plugins/extraicons/ExtraIconGroup.h62
-rw-r--r--plugins/extraicons/IcolibExtraIcon.cpp109
-rw-r--r--plugins/extraicons/IcolibExtraIcon.h41
-rw-r--r--plugins/extraicons/ZIP/doit.bat97
-rw-r--r--plugins/extraicons/commons.h120
-rw-r--r--plugins/extraicons/extraicons.cpp540
-rw-r--r--plugins/extraicons/extraicons.vcxproj720
-rw-r--r--plugins/extraicons/extraicons.vcxproj.filters127
-rw-r--r--plugins/extraicons/m_extraicons.h182
-rw-r--r--plugins/extraicons/options.cpp866
-rw-r--r--plugins/extraicons/options.h32
-rw-r--r--plugins/extraicons/res/AlwaysVis.icobin0 -> 2038 bytes
-rw-r--r--plugins/extraicons/res/Chatchannel.icobin0 -> 2038 bytes
-rw-r--r--plugins/extraicons/res/NeverVis.icobin0 -> 2038 bytes
-rw-r--r--plugins/extraicons/res/empty.icobin0 -> 766 bytes
-rw-r--r--plugins/extraicons/res/female.icobin0 -> 2550 bytes
-rw-r--r--plugins/extraicons/res/male.icobin0 -> 2550 bytes
-rw-r--r--plugins/extraicons/resource.h33
-rw-r--r--plugins/extraicons/resource.rc150
-rw-r--r--plugins/extraicons/sdk/m_metacontacts.h162
-rw-r--r--plugins/extraicons/sdk/m_updater.h146
-rw-r--r--plugins/extraicons/usedIcons.cpp110
-rw-r--r--plugins/extraicons/usedIcons.h29
-rw-r--r--plugins/modernb/icons_pack/ICONS_10.vcxproj93
-rw-r--r--plugins/utils/ContactAsyncQueue.cpp234
-rw-r--r--plugins/utils/ContactAsyncQueue.h95
-rw-r--r--plugins/utils/MemoryModule.c540
-rw-r--r--plugins/utils/MemoryModule.h48
-rw-r--r--plugins/utils/mir_buffer.h545
-rw-r--r--plugins/utils/mir_dblists.cpp149
-rw-r--r--plugins/utils/mir_dblists.h62
-rw-r--r--plugins/utils/mir_dbutils.h70
-rw-r--r--plugins/utils/mir_icons.cpp86
-rw-r--r--plugins/utils/mir_icons.h38
-rw-r--r--plugins/utils/mir_log.cpp220
-rw-r--r--plugins/utils/mir_log.h63
-rw-r--r--plugins/utils/mir_memory.h124
-rw-r--r--plugins/utils/mir_options.cpp650
-rw-r--r--plugins/utils/mir_options.h72
-rw-r--r--plugins/utils/mir_options_notify.cpp199
-rw-r--r--plugins/utils/mir_options_notify.h69
-rw-r--r--plugins/utils/mir_profiler.cpp178
-rw-r--r--plugins/utils/mir_profiler.h77
-rw-r--r--plugins/utils/mir_scope.h35
-rw-r--r--plugins/utils/mir_smileys.cpp521
-rw-r--r--plugins/utils/mir_smileys.h69
-rw-r--r--plugins/utils/scope.h106
-rw-r--r--plugins/utils/templates.cpp476
-rw-r--r--plugins/utils/templates.h102
-rw-r--r--plugins/utils/tstring.h14
-rw-r--r--plugins/utils/utf8_helpers.h587
-rw-r--r--plugins/variables/Variables_10.vcxproj16
-rw-r--r--plugins/variables/action_variables.cpp2
-rw-r--r--plugins/variables/condition_variables.cpp2
-rw-r--r--plugins/variables/trigger_variables.cpp2
-rw-r--r--plugins/weather/langpack_defweather.txt126
-rw-r--r--plugins/weather/license.txt340
-rw-r--r--plugins/weather/m_cluiframes.h275
-rw-r--r--plugins/weather/m_weather.h161
-rw-r--r--plugins/weather/mingw-comp.bat2
-rw-r--r--plugins/weather/proto_weather/mingw-comp.bat2
-rw-r--r--plugins/weather/proto_weather/proto_weather.dsp118
-rw-r--r--plugins/weather/proto_weather/proto_weather.vcproj173
-rw-r--r--plugins/weather/proto_weather/proto_weather_8.vcproj254
-rw-r--r--plugins/weather/proto_weather/proto_weather_9.vcproj421
-rw-r--r--plugins/weather/proto_weather/resource.h26
-rw-r--r--plugins/weather/proto_weather/resource.rc81
-rw-r--r--plugins/weather/proto_weather/wicons/Cloud.icobin0 -> 6830 bytes
-rw-r--r--plugins/weather/proto_weather/wicons/FOG.icobin0 -> 6830 bytes
-rw-r--r--plugins/weather/proto_weather/wicons/LIGHT.ICObin0 -> 6830 bytes
-rw-r--r--plugins/weather/proto_weather/wicons/NA.icobin0 -> 6830 bytes
-rw-r--r--plugins/weather/proto_weather/wicons/PCLOUDY.icobin0 -> 6830 bytes
-rw-r--r--plugins/weather/proto_weather/wicons/RAIN.icobin0 -> 6830 bytes
-rw-r--r--plugins/weather/proto_weather/wicons/RSHOWER.icobin0 -> 6830 bytes
-rw-r--r--plugins/weather/proto_weather/wicons/SNOW.ICObin0 -> 6830 bytes
-rw-r--r--plugins/weather/proto_weather/wicons/SSHOWER.icobin0 -> 6830 bytes
-rw-r--r--plugins/weather/proto_weather/wicons/SUN.ICObin0 -> 6830 bytes
-rw-r--r--plugins/weather/res/brief.icobin0 -> 2550 bytes
-rw-r--r--plugins/weather/res/disabled.icobin0 -> 2550 bytes
-rw-r--r--plugins/weather/res/edit.icobin0 -> 2550 bytes
-rw-r--r--plugins/weather/res/icon.icobin0 -> 6830 bytes
-rw-r--r--plugins/weather/res/info.icobin0 -> 2550 bytes
-rw-r--r--plugins/weather/res/infologo.icobin0 -> 2238 bytes
-rw-r--r--plugins/weather/res/log.icobin0 -> 2550 bytes
-rw-r--r--plugins/weather/res/map.icobin0 -> 2550 bytes
-rw-r--r--plugins/weather/res/more.icobin0 -> 2550 bytes
-rw-r--r--plugins/weather/res/popup.icobin0 -> 2550 bytes
-rw-r--r--plugins/weather/res/popup_no.icobin0 -> 2550 bytes
-rw-r--r--plugins/weather/res/reload.icobin0 -> 2550 bytes
-rw-r--r--plugins/weather/res/update.icobin0 -> 2550 bytes
-rw-r--r--plugins/weather/res/update2.icobin0 -> 2550 bytes
-rw-r--r--plugins/weather/resource.h174
-rw-r--r--plugins/weather/resource.rc464
-rw-r--r--plugins/weather/sample_ini.ini421
-rw-r--r--plugins/weather/version.h6
-rw-r--r--plugins/weather/weather-history.txt930
-rw-r--r--plugins/weather/weather-readme.html230
-rw-r--r--plugins/weather/weather-translation.txt798
-rw-r--r--plugins/weather/weather.c308
-rw-r--r--plugins/weather/weather.dsp241
-rw-r--r--plugins/weather/weather.h547
-rw-r--r--plugins/weather/weather_10.vcxproj485
-rw-r--r--plugins/weather/weather_10.vcxproj.filters136
-rw-r--r--plugins/weather/weather_addstn.c438
-rw-r--r--plugins/weather/weather_contacts.c515
-rw-r--r--plugins/weather/weather_conv.c809
-rw-r--r--plugins/weather/weather_data.c493
-rw-r--r--plugins/weather/weather_http.c226
-rw-r--r--plugins/weather/weather_icons.c90
-rw-r--r--plugins/weather/weather_info.c253
-rw-r--r--plugins/weather/weather_ini.c628
-rw-r--r--plugins/weather/weather_mwin.c449
-rw-r--r--plugins/weather/weather_opt.c648
-rw-r--r--plugins/weather/weather_popup.c454
-rw-r--r--plugins/weather/weather_svcs.c452
-rw-r--r--plugins/weather/weather_update.c678
-rw-r--r--plugins/weather/weather_userinfo.c418
226 files changed, 40413 insertions, 20 deletions
diff --git a/plugins/StatusPlugins/KeepStatus/action_keepstatus.cpp b/plugins/StatusPlugins/KeepStatus/action_keepstatus.cpp
index ac5368dff9..a321ecfcc9 100644
--- a/plugins/StatusPlugins/KeepStatus/action_keepstatus.cpp
+++ b/plugins/StatusPlugins/KeepStatus/action_keepstatus.cpp
@@ -1,7 +1,7 @@
#include "../commonstatus.h"
#include "keepstatus.h"
#include "../resource.h"
-#include "../../NewTriggerPlugin/m_trigger.h"
+#include "m_trigger.h"
#include "../../helpers/db_helpers.h"
extern HINSTANCE hInst;
diff --git a/plugins/StatusPlugins/StartupStatus/StartupStatus_10.vcxproj b/plugins/StatusPlugins/StartupStatus/StartupStatus_10.vcxproj
index 755883644b..fc395a4469 100644
--- a/plugins/StatusPlugins/StartupStatus/StartupStatus_10.vcxproj
+++ b/plugins/StatusPlugins/StartupStatus/StartupStatus_10.vcxproj
@@ -142,7 +142,7 @@
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <AdditionalIncludeDirectories>../../../include;../includes</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>../../../include;../../ExternalAPI;../includes;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;STARTUPSTATUS_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
@@ -188,7 +188,7 @@
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
- <AdditionalIncludeDirectories>../../../include;../includes</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>../../../include;../../ExternalAPI;../includes;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;STARTUPSTATUS_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
@@ -225,7 +225,7 @@
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
- <AdditionalIncludeDirectories>../../../include;../includes</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>../../../include;../../ExternalAPI;../includes;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;STARTUPSTATUS_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
@@ -264,7 +264,7 @@
<Optimization>Full</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
- <AdditionalIncludeDirectories>../../../include;../includes</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>../../../include;../../ExternalAPI;../includes;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;STARTUPSTATUS_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<ExceptionHandling>false</ExceptionHandling>
@@ -330,7 +330,7 @@
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>../commonstatus.h</PrecompiledHeaderFile>
- <AdditionalIncludeDirectories>../../../include;../includes;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>../../../include;../../ExternalAPI;../includes;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link />
<Link>
@@ -349,7 +349,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">
<ClCompile>
<PrecompiledHeaderFile>../commonstatus.h</PrecompiledHeaderFile>
- <AdditionalIncludeDirectories>../../../include;../includes;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>../../../include;../../ExternalAPI;../includes;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<AdditionalDependencies>wininet.lib;Delayimp.lib;%(AdditionalDependencies)</AdditionalDependencies>
@@ -365,7 +365,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeaderFile>../commonstatus.h</PrecompiledHeaderFile>
- <AdditionalIncludeDirectories>../../../include;../includes;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>../../../include;../../ExternalAPI;../includes;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<AdditionalDependencies>wininet.lib;Delayimp.lib;%(AdditionalDependencies)</AdditionalDependencies>
@@ -392,7 +392,7 @@
<BufferSecurityCheck>false</BufferSecurityCheck>
<FloatingPointModel>Fast</FloatingPointModel>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
- <AdditionalIncludeDirectories>../../../include;../includes;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>../../../include;../../ExternalAPI;../includes;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link />
<Link>
diff --git a/plugins/VersionInfo/AggressiveOptimize.h b/plugins/VersionInfo/AggressiveOptimize.h
new file mode 100644
index 0000000000..1b646c301c
--- /dev/null
+++ b/plugins/VersionInfo/AggressiveOptimize.h
@@ -0,0 +1,58 @@
+
+//////////////////////////////
+// Version 1.10
+// Jan 23rd, 2000
+// Version 1.00
+// May 20th, 1999
+// Todd C. Wilson, Fresh Ground Software
+// (todd@nopcode.com)
+// This header file will kick in settings for Visual C++ 5 and 6 that will (usually)
+// result in smaller exe's.
+// The "trick" is to tell the compiler to not pad out the function calls; this is done
+// by not using the /O1 or /O2 option - if you do, you implicitly use /Gy, which pads
+// out each and every function call. In one single 500k dll, I managed to cut out 120k
+// by this alone!
+// The other two "tricks" are telling the Linker to merge all data-type segments together
+// in the exe file. The relocation, read-only (constants) data, and code section (.text)
+// sections can almost always be merged. Each section merged can save 4k in exe space,
+// since each section is padded out to 4k chunks. This is very noticable with smaller
+// exes, since you could have only 700 bytes of data, 300 bytes of code, 94 bytes of
+// strings - padded out, this could be 12k of runtime, for 1094 bytes of stuff!
+// Note that if you're using MFC static or some other 3rd party libs, you may get poor
+// results with merging the readonly (.rdata) section - the exe may grow larger.
+// To use this feature, define _MERGE_DATA_ in your project or before this header is used.
+// With Visual C++ 5, the program uses a file alignement of 512 bytes, which results
+// in a small exe. Under VC6, the program instead uses 4k, which is the same as the
+// section size. The reason (from what I understand) is that 4k is the chunk size of
+// the virtual memory manager, and that WinAlign (an end-user tuning tool for Win98)
+// will re-align the programs on this boundary. The problem with this is that all of
+// Microsoft's system exes and dlls are not tuned like this, and using 4k causes serious
+// exe bloat. Very noticable for smaller programs.
+// The "trick" for this is to use the undocumented FILEALIGN linker parm to change the
+// padding from 4k to 1/2k, which results in a much smaller exe - anywhere from 20%-75%
+// depending on the size.
+
+
+#ifdef NDEBUG
+// /Og (global optimizations), /Os (favor small code), /Oy (no frame pointers)
+#pragma optimize("gsy",on)
+
+#pragma comment(linker,"/RELEASE")
+
+// Note that merging the .rdata section will result in LARGER exe's if you using
+// MFC (esp. static link). If this is desirable, define _MERGE_RDATA_ in your project.
+#ifdef _MERGE_RDATA_
+#pragma comment(linker,"/merge:.rdata=.data")
+#endif // _MERGE_RDATA_
+
+#pragma comment(linker,"/merge:.text=.data")
+#pragma comment(linker,"/merge:.reloc=.data")
+
+#if _MSC_VER >= 1000
+// Only supported/needed with VC6; VC5 already does 0x200 for release builds.
+// Totally undocumented! And if you set it lower than 512 bytes, the program crashes.
+// Either leave at 0x200 or 0x1000
+#pragma comment(linker,"/FILEALIGN:0x200")
+#endif // _MSC_VER >= 1000
+
+#endif // NDEBUG
diff --git a/plugins/VersionInfo/CPlugin.cpp b/plugins/VersionInfo/CPlugin.cpp
new file mode 100644
index 0000000000..8d87457cf1
--- /dev/null
+++ b/plugins/VersionInfo/CPlugin.cpp
@@ -0,0 +1,143 @@
+/*
+Version information plugin for Miranda IM
+
+Copyright © 2002-2006 Luca Santarelli, Cristian Libotean
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "CPlugin.h"
+//#include "AggressiveOptimize.h"
+
+#include "common.h"
+
+const int cPLUGIN_UUID_MARK = 4;
+char PLUGIN_UUID_MARK[cPLUGIN_UUID_MARK];
+
+#define PLUGIN_UNCERTAIN_MARK "?"
+
+#define RJUST 70
+
+CPlugin::CPlugin() {
+ lpzFileName = "";
+ lpzShortName = "";
+ lpzVersion = "";
+ lpzTimestamp = "";
+ lpzLinkedModules = "";
+ pluginID = UUID_NULL;
+};
+
+CPlugin::CPlugin(std::string eFileName, std::string eShortName, MUUID pluginID, std::string eUnicodeInfo, DWORD eVersion, std::string eTimestamp, std::string eLinkedModules) {
+ lpzFileName = std::string(eFileName);
+ lpzShortName = std::string(eShortName);
+ lpzUnicodeInfo = std::string(eUnicodeInfo);
+ lpzTimestamp = std::string(eTimestamp);
+ lpzLinkedModules = std::string(eLinkedModules);
+
+ char aux[128];
+ wsprintf(aux,"%d.%d.%d.%d", (eVersion>>24)&0xFF, (eVersion>>16)&0xFF, (eVersion>>8)&0xFF, (eVersion)&0xFF);
+ lpzVersion = std::string(aux);
+
+ this->pluginID = pluginID;
+};
+
+CPlugin::CPlugin(const CPlugin& other) {
+ lpzFileName = other.lpzFileName;
+ lpzShortName = other.lpzShortName;
+ lpzUnicodeInfo = other.lpzUnicodeInfo;
+ lpzVersion = other.lpzVersion;
+ lpzTimestamp = other.lpzTimestamp;
+ lpzLinkedModules = other.lpzLinkedModules;
+ pluginID = other.pluginID;
+}
+
+CPlugin::~CPlugin() {
+ //Debug information
+// char str[64]; wsprintf(str, "~CPlugin(): %s", lpzFileName.c_str());
+// MB(str);
+ //
+ lpzFileName.~basic_string();
+ lpzShortName.~basic_string();
+ lpzVersion.~basic_string();
+ lpzUnicodeInfo.~basic_string();
+ lpzTimestamp.~basic_string();
+ lpzLinkedModules.~basic_string();
+}
+
+void CPlugin::SetErrorMessage(std::string error)
+{
+ lpzLinkedModules = error;
+}
+
+bool CPlugin::operator<(CPlugin &anotherPlugin) {
+ std::string anotherFileName = anotherPlugin.getFileName();
+
+ char szThis[MAX_PATH]; lstrcpy(szThis, lpzFileName.c_str());
+ char szThat[MAX_PATH]; lstrcpy(szThat, anotherFileName.c_str());
+
+ if (lstrcmpi(szThis, szThat) < 0)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool CPlugin::operator>(CPlugin &anotherPlugin) {
+ return !((*this) < anotherPlugin);
+}
+bool CPlugin::operator==(CPlugin &anotherPlugin) {
+ return !((*this) < anotherPlugin || (*this) > anotherPlugin);
+}
+
+std::string CPlugin::getFileName() {
+ return this->lpzFileName;
+}
+
+std::string CPlugin::getInformations(DWORD flags, char *szHighlightHeader, char *szHighlightFooter) {
+// std::string lpzInformations = std::string(lpzFileName + "\t\t" + lpzVersion + "\r\n");
+// std::string lpzInformations = std::string(lpzFileName + " - " + lpzShortName + " [" + lpzTimestamp + "], version: " + lpzVersion +"\r\n");
+// std::string lpzInformations = std::string(lpzShortName + " [" + lpzFileName + " · " + lpzTimestamp + "] - version " + lpzVersion + "\r\n");
+// std::string lpzInformations = std::string(lpzFileName + " [" + lpzShortName + " · " + lpzTimestamp + "] - version: " + lpzVersion +"\r\n");
+ std::string lpzInformations;
+ if (flags & VISF_SHOWUUID)
+ {
+ char aux[128];
+ UUIDToString(pluginID, aux, sizeof(aux));
+ lpzInformations = std::string(aux);
+ }
+ else{
+ lpzInformations = (IsUUIDNull(pluginID)) ? " " : PLUGIN_UUID_MARK;
+ }
+ lpzInformations += std::string(" " + lpzFileName + " v." + szHighlightHeader + lpzVersion + szHighlightFooter + " [" + lpzTimestamp + "] - " + lpzShortName);
+ if (lpzUnicodeInfo.size() > 0)
+ {
+ char *lwr = _strlwr(_strdup(lpzShortName.c_str()));
+ if ((strstr(lwr, "unicode") == NULL) && (strstr(lwr, "2in1") == NULL))
+ {
+ lpzInformations.append(" |" + lpzUnicodeInfo + "|");
+ }
+ free(lwr);
+ }
+ //lpzInformations.append("\t");
+ //lpzInformations.append(lpzPluginID);
+ lpzInformations.append("\r\n");
+
+ if (lpzLinkedModules.size() > 0)
+ {
+ lpzInformations.append(lpzLinkedModules);
+ lpzInformations.append("\r\n");
+ }
+// std::string lpzInformations = std::string(lpzFileName + " - " + lpzShortName + " [" + lpzTimestamp + " · " + lpzVersion +"]\r\n");
+ return lpzInformations;
+}; \ No newline at end of file
diff --git a/plugins/VersionInfo/CPlugin.h b/plugins/VersionInfo/CPlugin.h
new file mode 100644
index 0000000000..4eb1adc69a
--- /dev/null
+++ b/plugins/VersionInfo/CPlugin.h
@@ -0,0 +1,69 @@
+/*
+Version information plugin for Miranda IM
+
+Copyright © 2002-2006 Luca Santarelli, Cristian Libotean
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef CPLUGIN_H
+#define CPLUGIN_H
+
+//#define STRICT
+#define WIN32_LEAN_AND_MEAN
+
+#define _CRT_SECURE_NO_DEPRECATE
+
+#include <windows.h>
+#include <string>
+
+#ifndef M_NEWPLUGINAPI_H__
+#include "../../include/newpluginapi.h"
+#endif
+
+#define DEF_UUID_CHARMARK "¤"
+
+extern const int cPLUGIN_UUID_MARK;
+extern char PLUGIN_UUID_MARK[];
+
+//using namespace std;
+
+class CPlugin {
+ private:
+ std::string lpzFileName;
+ std::string lpzShortName;
+ std::string lpzVersion;
+ std::string lpzUnicodeInfo; //aditional info, Unicode aware ...
+ std::string lpzTimestamp; //to show the last modified timestamp
+ std::string lpzLinkedModules; //to show linked modules that aren't found
+ MUUID pluginID;
+
+ public:
+ CPlugin();
+ CPlugin(std::string fileName, std::string shortName, MUUID pluginID, std::string unicodeInfo, DWORD version, std::string timestamp, std::string linkedModules);
+ CPlugin(const CPlugin&);
+ ~CPlugin();
+ std::string getFileName();
+ std::string getInformations(DWORD, char *, char *);
+
+ void SetErrorMessage(std::string error);
+
+ //Operators
+ bool operator<(CPlugin&);
+ bool operator>(CPlugin&);
+ bool operator==(CPlugin&);
+};
+#endif \ No newline at end of file
diff --git a/plugins/VersionInfo/CVersionInfo.cpp b/plugins/VersionInfo/CVersionInfo.cpp
new file mode 100644
index 0000000000..43087c3837
--- /dev/null
+++ b/plugins/VersionInfo/CVersionInfo.cpp
@@ -0,0 +1,1588 @@
+/*
+Version information plugin for Miranda IM
+
+Copyright © 2002-2006 Luca Santarelli, Cristian Libotean
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#include "CVersionInfo.h"
+//#include "AggressiveOptimize.h"
+
+#include "common.h"
+
+//using namespace std;
+
+BOOL (WINAPI *MyGetDiskFreeSpaceEx)(LPCTSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER);
+BOOL (WINAPI *MyIsWow64Process)(HANDLE, PBOOL);
+void (WINAPI *MyGetSystemInfo)(LPSYSTEM_INFO);
+BOOL (WINAPI *MyGlobalMemoryStatusEx)(LPMEMORYSTATUSEX lpBuffer) = NULL;
+
+LANGID (WINAPI *MyGetUserDefaultUILanguage)() = NULL;
+LANGID (WINAPI *MyGetSystemDefaultUILanguage)() = NULL;
+
+static int ValidExtension(char *fileName, char *extension)
+{
+ char *dot = strrchr(fileName, '.');
+ if ((dot != NULL) && (lstrcmpiA(dot + 1, extension) == 0))
+ {
+ if (dot[strlen(extension) + 1] == 0)
+ {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+/*
+int EnumSettings(const char *setting, LPARAM lParam)
+{
+ char *name = (char *) lParam;
+ char *tmp = _strdup(setting);
+ _strlwr(tmp);
+
+ int res = 0;
+
+ if (strcmp(tmp, name) == 0)
+ {
+ strcpy((char *) lParam, setting);
+ res = 1;
+ }
+
+ free(tmp);
+
+ return res;
+}
+
+int IsPluginDisabled(char *fileName)
+{
+ char *name = _strdup(fileName);
+ _strlwr(name);
+ DBCONTACTENUMSETTINGS dbEnum = {0};
+ dbEnum.pfnEnumProc = EnumSettings;
+ dbEnum.lParam = (LPARAM) name;
+ dbEnum.szModule = "PluginDisable";
+
+ int res = -1;
+
+ CallService(MS_DB_CONTACT_ENUMSETTINGS, NULL, (LPARAM) &dbEnum);
+ DBVARIANT dbv = {0};
+ dbv.type = DBVT_BYTE;
+
+ int exists = !(DBGetContactSetting(NULL, "PluginDisable", name, &dbv));
+ if (exists)
+ {
+ res = dbv.bVal;
+ }
+ free(name);
+
+ return res;
+}
+*/
+
+void FillLocalTime(std::string &output, FILETIME *fileTime)
+{
+ TIME_ZONE_INFORMATION tzInfo = {0};
+ FILETIME local = {0};
+ SYSTEMTIME sysTime;
+ char date[1024];
+ char time[256];
+
+ FileTimeToLocalFileTime(fileTime, &local);
+ FileTimeToSystemTime(&local, &sysTime);
+
+ GetDateFormat(EnglishLocale, 0, &sysTime, "dd' 'MMM' 'yyyy", date, sizeof(date));
+ GetTimeFormat(NULL, TIME_FORCE24HOURFORMAT, &sysTime, "HH':'mm':'ss", time, sizeof(time)); //americans love 24hour format ;)
+ output = std::string(date) + " at " + std::string(time);
+
+ int res = GetTimeZoneInformation(&tzInfo);
+ char tzName[32] = {0};
+ char tzOffset[64] = {0};
+ int offset = 0;
+ switch (res)
+ {
+ case TIME_ZONE_ID_DAYLIGHT:
+ {
+ offset = -(tzInfo.Bias + tzInfo.DaylightBias);
+ WideCharToMultiByte(CP_ACP, 0, tzInfo.DaylightName, -1, tzName, sizeof(tzName), NULL, NULL);
+
+ break;
+ }
+
+ case TIME_ZONE_ID_STANDARD:
+ {
+ WideCharToMultiByte(CP_ACP, 0, tzInfo.StandardName, -1, tzName, sizeof(tzName), NULL, NULL);
+ offset = -(tzInfo.Bias + tzInfo.StandardBias);
+
+ break;
+ }
+
+ case TIME_ZONE_ID_UNKNOWN:
+ {
+ WideCharToMultiByte(CP_ACP, 0, tzInfo.StandardName, -1, tzName, sizeof(tzName), NULL, NULL);
+ offset = -tzInfo.Bias;
+
+ break;
+ }
+ }
+
+ sprintf(tzOffset, "UTC %+02d:%02d", offset / 60, offset % 60);
+ output += " (" /*+ std::string(tzName) + ", " */ + std::string(tzOffset) + ")";
+}
+
+CVersionInfo::CVersionInfo() {
+ luiFreeDiskSpace = 0;
+ bDEPEnabled = 0;
+};
+
+CVersionInfo::~CVersionInfo() {
+
+ listInactivePlugins.clear();
+ listActivePlugins.clear();
+ listUnloadablePlugins.clear();
+
+ lpzMirandaVersion.~basic_string();
+ lpzNightly.~basic_string();
+ lpzUnicodeBuild.~basic_string();
+ lpzBuildTime.~basic_string();
+ lpzOSVersion.~basic_string();
+ lpzMirandaPath.~basic_string();
+ lpzCPUName.~basic_string();
+ lpzCPUIdentifier.~basic_string();
+};
+
+void CVersionInfo::Initialize() {
+#ifdef _DEBUG
+ if (verbose) PUShowMessage("Before GetMirandaVersion().", SM_NOTIFY);
+#endif
+ GetMirandaVersion();
+
+#ifdef _DEBUG
+ if (verbose) PUShowMessage("Before GetProfileSettings().", SM_NOTIFY);
+#endif
+ GetProfileSettings();
+
+#ifdef _DEBUG
+ if (verbose) PUShowMessage("Before GetLangpackInfo().", SM_NOTIFY);
+#endif
+ GetOSLanguages();
+ GetLangpackInfo();
+
+#ifdef _DEBUG
+ if (verbose) PUShowMessage("Before GetPluginLists().", SM_NOTIFY);
+#endif
+ GetPluginLists();
+
+#ifdef _DEBUG
+ if (verbose) PUShowMessage("Before GetOSVersion().", SM_NOTIFY);
+#endif
+ GetOSVersion();
+
+#ifdef _DEBUG
+ if (verbose) PUShowMessage("Before GetHWSettings().", SM_NOTIFY);
+#endif
+ GetHWSettings();
+
+#ifdef _DEBUG
+ if (verbose) PUShowMessage("Done with GetHWSettings().", SM_NOTIFY);
+#endif
+}
+
+bool CVersionInfo::GetMirandaVersion() {
+ const BYTE str_size = 64;
+ char str[str_size];
+ //Miranda version
+
+ CallService(MS_SYSTEM_GETVERSIONTEXT, (WPARAM)str_size, (LPARAM)(char*)str);
+ this->lpzMirandaVersion = std::string(str);
+ //Is it a nightly?
+ if (lpzMirandaVersion.find("alpha",0) != std::string::npos)
+ lpzNightly = "Yes";
+ else
+ lpzNightly = "No";
+ if (lpzMirandaVersion.find("Unicode", 0) != std::string::npos)
+ {
+ lpzUnicodeBuild = "Yes";
+ }
+ else{
+ lpzUnicodeBuild = "No";
+ }
+ char time[128], date[128];
+ GetModuleTimeStamp(date, time);
+ lpzBuildTime = std::string(time) + " on " + std::string(date);
+ return TRUE;
+}
+
+bool CVersionInfo::GetOSVersion() {
+ //Operating system informations
+ OSVERSIONINFO osvi;
+ ZeroMemory(&osvi, sizeof(osvi));
+ osvi.dwOSVersionInfoSize = sizeof(osvi);
+ GetVersionEx(&osvi);
+ //Now fill the private members.
+ char aux[256];
+ wsprintf(aux, "%d.%d.%d %s", osvi.dwMajorVersion, osvi.dwMinorVersion, LOWORD(osvi.dwBuildNumber), osvi.szCSDVersion);
+ lpzOSVersion = std::string(aux);
+ //OSName
+ //Let's read the registry.
+ HKEY hKey;
+ char szKey[MAX_PATH], szValue[MAX_PATH];
+
+
+ lstrcpyn(szKey, "Hardware\\Description\\System\\CentralProcessor\\0", MAX_PATH);
+ if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, szKey, 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
+ {
+ DWORD type, size, result;
+
+ lstrcpyn(szValue, "Identifier", MAX_PATH);
+ result = RegQueryValueEx(hKey, szValue, 0, &type, NULL, &size);
+ if (result == ERROR_SUCCESS)
+ {
+ char *aux = (char *) malloc(size);
+ result = RegQueryValueEx(hKey, szValue, 0, &type, (LPBYTE) aux, &size);
+ lpzCPUIdentifier = std::string(aux);
+ free(aux);
+ }
+ else{
+ NotifyError(GetLastError(), "RegQueryValueEx()", __LINE__);
+ lpzCPUIdentifier = "<Error in RegQueryValueEx()>";
+ }
+ lstrcpyn(szValue, "ProcessorNameString", MAX_PATH);
+ result = RegQueryValueEx(hKey, szValue, 0, &type, NULL, &size); //get the size
+ if (result == ERROR_SUCCESS)
+ {
+// MessageBox(0, "ProcessorNameString available in the registry", "Info", 0);
+ char *aux = (char *) malloc(size);
+ result = RegQueryValueEx(hKey, szValue, 0, &type, (LPBYTE) aux, &size);
+ lpzCPUName = std::string(aux);
+ free(aux);
+ }
+ else{ //else try to use cpuid instruction to get the proc name
+ char szName[49] = "<cpuid extension N/A>";
+ #if (!defined(WIN64) && !defined(_WIN64))
+ __asm
+ {
+ push eax //save the registers
+ push ebx
+ push ecx
+ push edx
+
+ xor eax, eax //get simple name
+ cpuid
+ mov DWORD PTR szName[0], ebx
+ mov DWORD PTR szName[4], edx
+ mov DWORD PTR szName[8], ecx
+ mov DWORD PTR szName[12], 0
+
+ mov eax, 0x80000000 //try to get pretty name
+ cpuid
+
+ cmp eax, 0x80000004
+ jb end //if we don't have the extension end the check
+
+ mov DWORD PTR szName[0], 0 //make the string null
+
+ mov eax, 0x80000002 //first part of the string
+ cpuid
+ mov DWORD PTR szName[0], eax
+ mov DWORD PTR szName[4], ebx
+ mov DWORD PTR szName[8], ecx
+ mov DWORD PTR szName[12], edx
+
+ mov eax, 0x80000003 //second part of the string
+ cpuid
+ mov DWORD PTR szName[16], eax
+ mov DWORD PTR szName[20], ebx
+ mov DWORD PTR szName[24], ecx
+ mov DWORD PTR szName[28], edx
+
+ mov eax, 0x80000004 //third part of the string
+ cpuid
+ mov DWORD PTR szName[32], eax
+ mov DWORD PTR szName[36], ebx
+ mov DWORD PTR szName[40], ecx
+ mov DWORD PTR szName[44], edx
+
+ end:
+ pop edx //load them back
+ pop ecx
+ pop ebx
+ pop eax
+ }
+ szName[sizeof(szName) - 1] = '\0';
+ #endif
+ if (strlen(szName) == 0)
+ {
+ lpzCPUName = "<name N/A>";
+ }
+ else{
+ lpzCPUName = std::string(szName);
+ }
+ }
+ }
+
+ bDEPEnabled = IsProcessorFeaturePresent(PF_NX_ENABLED);
+ /*
+ if (!bDEPEnabled)
+ {
+ int x = 0;
+ __asm
+ {
+ push eax
+ push ebx
+ push ecx
+ push edx
+
+ mov eax, 0x80000001
+ cpuid
+ mov eax, 1
+ shl eax, 20
+ xor edx, eax
+ cmp edx, 0
+ je end_DEP
+ mov x, 1
+
+ end_DEP:
+ pop edx
+ pop ecx
+ pop ebx
+ pop eax
+ }
+ bDEPEnabled = x;
+ }
+ */
+ switch (osvi.dwPlatformId) {
+ case VER_PLATFORM_WIN32_WINDOWS:
+ lstrcpyn(szKey, "Software\\Microsoft\\Windows\\CurrentVersion", MAX_PATH);
+ lstrcpyn(szValue, "Version", MAX_PATH);
+ break;
+ case VER_PLATFORM_WIN32_NT:
+
+ lstrcpyn(szKey, "Software\\Microsoft\\Windows NT\\CurrentVersion", MAX_PATH);
+ lstrcpyn(szValue, "ProductName", MAX_PATH);
+ break;
+ }
+
+ RegCloseKey(hKey);
+ if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,szKey,0,KEY_QUERY_VALUE,&hKey) == ERROR_SUCCESS) {
+ DWORD type, size, result;
+ //Get the size of the value we'll read.
+ result = RegQueryValueEx((HKEY)hKey,szValue,(LPDWORD)NULL, (LPDWORD)&type,(LPBYTE)NULL,
+ (LPDWORD)&size);
+ if (result == ERROR_SUCCESS) {
+ //Read it.
+ char *aux = (char*)malloc(size);
+ result = RegQueryValueEx((HKEY)hKey,szValue,(LPDWORD)NULL, (LPDWORD)&type,(LPBYTE)aux,(LPDWORD)&size);
+ lpzOSName = std::string(aux);
+ free(aux);
+ }
+ else {
+ NotifyError(GetLastError(), "RegQueryValueEx()", __LINE__);
+ lpzOSName = "<Error in RegQueryValueEx()>";
+ }
+ }
+ else {
+ NotifyError(GetLastError(), "RegOpenKeyEx()", __LINE__);
+ lpzOSName = "<Error in RegOpenKeyEx()>";
+ }
+
+ //Now we can improve it if we can.
+ switch (LOWORD(osvi.dwBuildNumber)) {
+ case 950: lpzOSName = "Microsoft Windows 95"; break;
+ case 1111: lpzOSName = "Microsoft Windows 95 OSR2"; break;
+ case 1998: lpzOSName = "Microsoft Windows 98"; break;
+ case 2222: lpzOSName = "Microsoft Windows 98 SE"; break;
+ case 3000: lpzOSName = "Microsoft Windows ME"; break; //Even if this is wrong, we have already read it in the registry.
+ case 1381: lpzOSName = "Microsoft Windows NT"; break; //What about service packs?
+ case 2195: lpzOSName = "Microsoft Windows 2000"; break; //What about service packs?
+ case 2600: lpzOSName = "Microsoft Windows XP"; break;
+ case 3790:
+ {
+ if (GetSystemMetrics(89)) { //R2 ?
+ lpzOSName = "Microsoft Windows 2003 R2";
+ }
+ else{
+ lpzOSName = "Microsoft Windows 2003";
+ }
+
+ break; //added windows 2003 info
+ }
+ }
+
+ return TRUE;
+}
+
+bool CVersionInfo::GetHWSettings() {
+ //Free space on Miranda Partition.
+ char szMirandaPath[MAX_PATH] = { 0 };
+ { char *str2;
+ GetModuleFileName(GetModuleHandle(NULL),szMirandaPath,sizeof(szMirandaPath));
+ str2=strrchr(szMirandaPath,'\\');
+ if(str2!=NULL) *str2=0;
+ }
+ HMODULE hKernel32;
+ hKernel32 = LoadLibrary("kernel32.dll");
+ if (hKernel32) {
+ MyGetDiskFreeSpaceEx = (BOOL (WINAPI *)(LPCTSTR,PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER))GetProcAddress(hKernel32, "GetDiskFreeSpaceExA");
+ MyIsWow64Process = (BOOL (WINAPI *) (HANDLE, PBOOL)) GetProcAddress(hKernel32, "IsWow64Process");
+ MyGetSystemInfo = (void (WINAPI *) (LPSYSTEM_INFO)) GetProcAddress(hKernel32, "GetNativeSystemInfo");
+ MyGlobalMemoryStatusEx = (BOOL (WINAPI *) (LPMEMORYSTATUSEX)) GetProcAddress(hKernel32, "GlobalMemoryStatusEx");
+ if (!MyGetSystemInfo)
+ {
+ MyGetSystemInfo = GetSystemInfo;
+ }
+
+ FreeLibrary(hKernel32);
+ }
+ if (MyGetDiskFreeSpaceEx) {
+ ULARGE_INTEGER FreeBytes, a, b;
+ MyGetDiskFreeSpaceEx(szMirandaPath, &FreeBytes, &a, &b);
+ //Now we need to convert it.
+ __int64 aux = FreeBytes.QuadPart;
+ aux /= (1024*1024);
+ luiFreeDiskSpace = (unsigned long int)aux;
+ }
+ else {
+ luiFreeDiskSpace = 0;
+ }
+
+ char szInfo[1024];
+ GetWindowsShell(szInfo, sizeof(szInfo));
+ lpzShell = szInfo;
+ GetInternetExplorerVersion(szInfo, sizeof(szInfo));
+ lpzIEVersion = szInfo;
+
+
+ lpzAdministratorPrivileges = (IsCurrentUserLocalAdministrator()) ? "Yes" : "No";
+
+ bIsWOW64 = 0;
+ if (MyIsWow64Process)
+ {
+ if (!MyIsWow64Process(GetCurrentProcess(), &bIsWOW64))
+ {
+ bIsWOW64 = 0;
+ }
+ }
+
+ SYSTEM_INFO sysInfo = {0};
+ GetSystemInfo(&sysInfo);
+ luiProcessors = sysInfo.dwNumberOfProcessors;
+
+ //Installed RAM
+ if (MyGlobalMemoryStatusEx) //windows 2000+
+ {
+ MEMORYSTATUSEX ms = {0};
+ ms.dwLength = sizeof(ms);
+ MyGlobalMemoryStatusEx(&ms);
+ luiRAM = (unsigned int) ((ms.ullTotalPhys / (1024 * 1024)) + 1);
+ }
+ else{
+ MEMORYSTATUS ms = {0};
+ ZeroMemory(&ms, sizeof(ms));
+ ms.dwLength = sizeof(ms);
+ GlobalMemoryStatus(&ms);
+ luiRAM = (ms.dwTotalPhys/(1024*1024))+1; //Ugly hack!!!!
+ }
+
+ return TRUE;
+}
+
+bool CVersionInfo::GetProfileSettings()
+{
+ char profileName[MAX_PATH] = {0};
+ char profilePath[MAX_PATH] = {0};
+ ServiceExists(MS_DB_GETPROFILEPATH_BASIC) ? CallService(MS_DB_GETPROFILEPATH_BASIC, MAX_PATH, (LPARAM) profilePath) : CallService(MS_DB_GETPROFILEPATH, MAX_PATH, (LPARAM) profilePath); //get the profile path
+ CallService(MS_DB_GETPROFILENAME, MAX_PATH, (LPARAM) profileName); //get the profile name
+// strcat(profileName, ".dat"); //add the .dat extension to the profile name
+ lpzProfilePath = std::string(profilePath); //save the profile path
+
+ strcat(profilePath, "\\"); //add the last \\ to the path
+ strcat(profilePath, profileName); //now profilePath is drive:\path\profilename.dat
+ HANDLE fin = CreateFile(profilePath, FILE_READ_ATTRIBUTES | FILE_READ_EA | STANDARD_RIGHTS_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (fin == INVALID_HANDLE_VALUE) { fin = CreateFile(profilePath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); }
+ if (fin != INVALID_HANDLE_VALUE)
+ {
+ DWORD size;
+ FILETIME creation, modified, accessed;
+ size = GetFileSize(fin, NULL);
+ TCHAR number[1024];
+ char tmp[1024];
+ double fileSize = (double) size / 1024;
+
+ sprintf(tmp, "%f", fileSize);
+ GetNumberFormat(EnglishLocale, NULL, tmp, NULL, number, 1024);
+
+ lpzProfileSize = std::string(number) + " KBytes";
+ GetFileTime(fin, &creation, &accessed, &modified);
+ FillLocalTime(lpzProfileCreationDate, &creation);
+
+ CloseHandle(fin);
+ }
+ else{
+ DWORD error = GetLastError();
+ char tmp[1024];
+ sprintf(tmp, "%d", error);
+ lpzProfileCreationDate = "<error " + std::string(tmp) + " at FileOpen>" + std::string(profilePath);
+ lpzProfileSize = "<error " + std::string(tmp) + " at FileOpen>" + std::string(profilePath);
+ }
+
+ return true;
+}
+
+static char szSystemLocales[4096] = {0};
+static WORD systemLangID;
+#define US_LANG_ID 0x00000409
+
+BOOL CALLBACK EnumSystemLocalesProc(char *szLocale)
+{
+ DWORD locale = atoi(szLocale);
+ char *name = GetLanguageName(locale);
+ if (!strstr(szSystemLocales, name))
+ {
+ strcat(szSystemLocales, name);
+ strcat(szSystemLocales, ", ");
+ }
+
+ return TRUE;
+}
+
+BOOL CALLBACK EnumResLangProc(HMODULE hModule, LPCTSTR lpszType, LPCTSTR lpszName, WORD wIDLanguage, LONG_PTR lParam)
+{
+ if (!lpszName)
+ return FALSE;
+
+ if (wIDLanguage != US_LANG_ID)
+ systemLangID = wIDLanguage;
+
+ return TRUE;
+}
+
+bool CVersionInfo::GetOSLanguages()
+{
+ lpzOSLanguages = "(UI | Locale (User/System)) : ";
+
+ LANGID UILang;
+
+ OSVERSIONINFO os = {0};
+ os.dwOSVersionInfoSize = sizeof(os);
+ GetVersionEx(&os);
+ switch (os.dwMajorVersion)
+ {
+ case 4: //Win 95-Me, NT
+ {
+ if (os.dwPlatformId == VER_PLATFORM_WIN32_NT) //Win NT
+ {
+ HMODULE hLib = LoadLibrary("ntdll.dll");
+
+ if (hLib)
+ {
+ EnumResourceLanguages(hLib, RT_VERSION, MAKEINTRESOURCE(1), EnumResLangProc, NULL);
+
+ FreeLibrary(hLib);
+
+ if (systemLangID == US_LANG_ID)
+ {
+ UINT uiACP;
+
+ uiACP = GetACP();
+ switch (uiACP)
+ {
+ case 874: // Thai code page activated, it's a Thai enabled system
+ systemLangID = MAKELANGID(LANG_THAI, SUBLANG_DEFAULT);
+ break;
+
+ case 1255: // Hebrew code page activated, it's a Hebrew enabled system
+ systemLangID = MAKELANGID(LANG_HEBREW, SUBLANG_DEFAULT);
+ break;
+
+ case 1256: // Arabic code page activated, it's a Arabic enabled system
+ systemLangID = MAKELANGID(LANG_ARABIC, SUBLANG_ARABIC_SAUDI_ARABIA);
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+ }
+ else{ //Win 95-Me
+ HKEY hKey = NULL;
+ char szLangID[128] = "0x";
+ DWORD size = sizeof(szLangID) - 2;
+ char err[512];
+
+ if (RegOpenKeyEx(HKEY_CURRENT_USER, "Control Panel\\Desktop\\ResourceLocale", 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
+ {
+ if (RegQueryValueEx(hKey, "", 0, NULL, (LPBYTE) &szLangID + 2, &size) == ERROR_SUCCESS)
+ {
+ sscanf(szLangID, "%lx", &systemLangID);
+ }
+ else{
+ FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, GetLastError(), LANG_SYSTEM_DEFAULT, err, size, NULL);
+ MessageBox(0, err, "Error at RegQueryValueEx()", MB_OK);
+ }
+ RegCloseKey(hKey);
+ }
+ else{
+ FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, GetLastError(), LANG_SYSTEM_DEFAULT, err, size, NULL);
+ MessageBox(0, err, "Error at RegOpenKeyEx()", MB_OK);
+ }
+ }
+
+ lpzOSLanguages += GetLanguageName(systemLangID);
+
+ break;
+ }
+
+ case 5: //Win 2000, XP
+ default:
+ {
+ HMODULE hKernel32 = LoadLibrary("kernel32.dll");
+ if (hKernel32)
+ {
+ MyGetUserDefaultUILanguage = (LANGID (WINAPI *)()) GetProcAddress(hKernel32, "GetUserDefaultUILanguage");
+ MyGetSystemDefaultUILanguage = (LANGID (WINAPI *)()) GetProcAddress(hKernel32, "GetSystemDefaultUILanguage");
+
+ FreeLibrary(hKernel32);
+ }
+
+ if ((MyGetUserDefaultUILanguage) && (MyGetSystemDefaultUILanguage))
+ {
+ UILang = MyGetUserDefaultUILanguage();
+ lpzOSLanguages += GetLanguageName(UILang);
+ lpzOSLanguages += "/";
+ UILang = MyGetSystemDefaultUILanguage();
+ lpzOSLanguages += GetLanguageName(UILang);
+ }
+ else{
+ lpzOSLanguages += "Missing functions in kernel32.dll (GetUserDefaultUILanguage, GetSystemDefaultUILanguage)";
+ }
+
+ break;
+ }
+ }
+
+ lpzOSLanguages += " | ";
+ lpzOSLanguages += GetLanguageName(LOCALE_USER_DEFAULT);
+ lpzOSLanguages += "/";
+ lpzOSLanguages += GetLanguageName(LOCALE_SYSTEM_DEFAULT);
+
+ if (DBGetContactSettingByte(NULL, ModuleName, "ShowInstalledLanguages", 0))
+ {
+ szSystemLocales[0] = '\0';
+ lpzOSLanguages += " [";
+ EnumSystemLocales(EnumSystemLocalesProc, LCID_INSTALLED);
+ if (strlen(szSystemLocales) > 2)
+ {
+ szSystemLocales[strlen(szSystemLocales) - 2] = '\0';
+ }
+ lpzOSLanguages += szSystemLocales;
+ lpzOSLanguages += "]";
+ }
+
+ return true;
+}
+
+int SaveInfo(const char *data, const char *lwrData, const char *search, char *dest, int size)
+{
+ const char *pos = strstr(lwrData, search);
+ int res = 1;
+ if (pos == lwrData)
+ {
+ strncpy(dest, &data[strlen(search)], size);
+ res = 0;
+ }
+
+ return res;
+}
+
+bool CVersionInfo::GetLangpackInfo()
+{
+ char langpackPath[MAX_PATH] = {0};
+ char search[MAX_PATH] = {0};
+ char *p;
+ lpzLangpackModifiedDate = "";
+ GetModuleFileName(GetModuleHandle(NULL), langpackPath, sizeof(langpackPath));
+ p = strrchr(langpackPath, '\\');
+ if (p)
+ {
+ WIN32_FIND_DATA data = {0};
+ HANDLE hLangpack;
+
+ p[1] = '\0';
+ strcpy(search, langpackPath);
+ strcat(search, "langpack_*.txt");
+ hLangpack = FindFirstFile(search, &data);
+ if (hLangpack != INVALID_HANDLE_VALUE)
+ {
+ char buffer[1024];
+ char temp[1024];
+ //FILETIME localWriteTime;
+ //SYSTEMTIME sysTime;
+ FillLocalTime(lpzLangpackModifiedDate, &data.ftLastWriteTime);
+
+ char locale[128] = {0};
+ char language[128] = {0};
+ char version[128] = {0};
+ strcpy(version, "N/A");
+ char *p;
+ strncpy(temp, data.cFileName, sizeof(temp));
+ p = strrchr(temp, '.');
+ p[0] = '\0';
+ strncpy(language, strchr(temp, '_') + 1, sizeof(language));
+
+ strcat(langpackPath, data.cFileName);
+ FILE *fin = fopen(langpackPath, "rt");
+
+ if (fin)
+ {
+ size_t len;
+ while (!feof(fin))
+ {
+ fgets(buffer, sizeof(buffer), fin);
+ len = strlen(buffer);
+ if (buffer[len - 1] == '\n') buffer[len - 1] = '\0';
+ strncpy(temp, buffer, sizeof(temp));
+ _strlwr(temp);
+ if (SaveInfo(buffer, temp, "language: ", language, sizeof(language)))
+ {
+ if (SaveInfo(buffer, temp, "locale: ", locale, sizeof(locale)))
+ {
+ p = strstr(buffer, "; FLID: ");
+ if (p)
+ {
+ int ok = 1;
+ int i;
+ for (i = 0; ((i < 3) && (ok)); i++)
+ {
+ p = strrchr(temp, '.');
+ if (p)
+ {
+ p[0] = '\0';
+ }
+ else{
+ ok = 0;
+ }
+ }
+ p = strrchr(temp, ' ');
+ if ((ok) && (p))
+ {
+ strncpy(version, &buffer[p - temp + 1], sizeof(version));
+ }
+ else{
+ strncpy(version, "<unknown>", sizeof(version));
+ }
+ }
+ }
+ }
+ }
+
+ lpzLangpackInfo = std::string(language) + " [" + std::string(locale) + "]";
+ if (strlen(version) > 0)
+ {
+ lpzLangpackInfo += " v. " + std::string(version);
+ }
+ fclose(fin);
+ }
+ else{
+ int err = GetLastError();
+ lpzLangpackInfo = "<error> Could not open file " + std::string(data.cFileName);
+ }
+ FindClose(hLangpack);
+ }
+ else{
+ lpzLangpackInfo = "No language pack installed";
+ }
+ }
+
+ return true;
+}
+
+std::string GetPluginTimestamp(FILETIME *fileTime)
+{
+ SYSTEMTIME sysTime;
+ FileTimeToSystemTime(fileTime, &sysTime); //convert the file tyme to system time
+ //char time[256];
+ char date[256]; //lovely
+ GetDateFormat(EnglishLocale, 0, &sysTime, "dd' 'MMM' 'yyyy", date, sizeof(date));
+ //GetTimeFormat(NULL, TIME_FORCE24HOURFORMAT, &sysTime, "HH':'mm':'ss", time, sizeof(time)); //americans love 24hour format :)
+ std::string timedate(date);
+ return timedate;
+}
+
+bool CVersionInfo::GetPluginLists() {
+
+ HANDLE hFind;
+ char szMirandaPath[MAX_PATH] = { 0 }, szSearchPath[MAX_PATH] = { 0 }; //For search purpose
+ WIN32_FIND_DATA fd;
+ char szMirandaPluginsPath[MAX_PATH] = { 0 }, szPluginPath[MAX_PATH] = { 0 }; //For info reading purpose
+ BYTE PluginIsEnabled = 0;
+ HINSTANCE hInstPlugin = NULL;
+ PLUGININFOEX *(*MirandaPluginInfo)(DWORD); //These two are used to get informations from the plugin.
+ PLUGININFOEX *pluginInfo = NULL; //Read above.
+ DWORD mirandaVersion = 0;
+ BOOL asmCheckOK = FALSE;
+ DWORD loadError;
+// SYSTEMTIME sysTime; //for timestamp
+
+ mirandaVersion=(DWORD)CallService(MS_SYSTEM_GETVERSION,0,0);
+
+ { char *str2;
+ GetModuleFileName(GetModuleHandle(NULL),szMirandaPath,sizeof(szMirandaPath));
+ str2=strrchr(szMirandaPath,'\\');
+ if(str2!=NULL) *str2=0;
+ }
+ lpzMirandaPath = std::string(szMirandaPath);
+ //We got Miranda path, now we'll use it for two different purposes.
+ //1) finding plugins.
+ //2) Reading plugin infos
+ lstrcpyn(szSearchPath,szMirandaPath, MAX_PATH); //We got the path, now we copy it into szSearchPath. We'll use szSearchPath as am auxiliary variable, while szMirandaPath will keep a "fixed" value.
+ lstrcat(szSearchPath,"\\Plugins\\*.dll");
+
+ lstrcpyn(szMirandaPluginsPath, szMirandaPath, MAX_PATH);
+ lstrcat(szMirandaPluginsPath,"\\Plugins\\");
+
+ hFind=FindFirstFile(szSearchPath,&fd);
+ LogToFile("Starting to load plugins");
+ if(hFind != INVALID_HANDLE_VALUE) {
+ do {
+ if (verbose) PUShowMessage(fd.cFileName, SM_NOTIFY);
+ if (!ValidExtension(fd.cFileName, "dll"))
+ {
+ continue; //do not report plugins that do not have extension .dll
+ }
+
+ hInstPlugin = GetModuleHandle(fd.cFileName); //try to get the handle of the module
+
+ if (hInstPlugin) //if we got it then the dll is loaded (enabled)
+ {
+ PluginIsEnabled = 1;
+ LogToFile("Plugin '%s' is enabled and loaded", fd.cFileName);
+ }
+ else{
+ PluginIsEnabled = 0;
+ LogToFile("Plugin '%s' is not loaded, going to load it", fd.cFileName);
+ lstrcpyn(szPluginPath, szMirandaPluginsPath, MAX_PATH); // szPluginPath becomes "drive:\path\Miranda\Plugins\"
+ lstrcat(szPluginPath, fd.cFileName); // szPluginPath becomes "drive:\path\Miranda\Plugins\popup.dll"
+ hInstPlugin = LoadLibrary(szPluginPath);
+/*
+ PluginIsEnabled = !(
+ DBGetContactSettingByte(NULL, "PluginDisable", fd.cFileName, FALSE)
+ || DBGetContactSettingByte(NULL, "PluginDisable", CharUpper(fd.cFileName), FALSE)
+ || DBGetContactSettingByte(NULL, "PluginDisable", CharLower(fd.cFileName), FALSE)
+
+ }; //If the DB does not contain that value, the plugin is enabled => default: FALSE; action: !read
+*/
+ //Let's read the informations.
+/*
+ }
+ if (PluginIsEnabled) {
+ hInstPlugin = GetModuleHandle(fd.cFileName);
+ }
+ else{
+ lstrcpyn(szPluginPath, szMirandaPluginsPath, MAX_PATH); // szPluginPath becomes "drive:\path\Miranda\Plugins\"
+ lstrcat(szPluginPath, fd.cFileName); // szPluginPath becomes "drive:\path\Miranda\Plugins\popup.dll"
+ hInstPlugin = LoadLibrary(szPluginPath);
+ }
+*/
+ }
+ if (!hInstPlugin) { //It wasn't loaded.
+ loadError = GetLastError();
+ int bUnknownError = 1; //assume plugin didn't load because of unknown error
+ //Some error messages.
+ //get the dlls the plugin statically links to
+ if (DBGetContactSettingByte(NULL, ModuleName, "CheckForDependencies", TRUE))
+ {
+ std::string linkedModules = "";
+
+ lstrcpyn(szPluginPath, szMirandaPluginsPath, MAX_PATH); // szPluginPath becomes "drive:\path\Miranda\Plugins\"
+ lstrcat(szPluginPath, fd.cFileName); // szPluginPath becomes "drive:\path\Miranda\Plugins\popup.dll"
+ if (GetLinkedModulesInfo(szPluginPath, linkedModules))
+ {
+ LogToFile("Plugin %s has unresolved dependencies, adding to unloadable list", szPluginPath);
+ std::string time = GetPluginTimestamp(&fd.ftLastWriteTime);
+ CPlugin thePlugin = CPlugin(std::string(fd.cFileName), "<unknown>", UUID_NULL, "", 0, time, linkedModules);
+ AddPlugin(thePlugin, listUnloadablePlugins);
+ bUnknownError = 0; //we know why the plugin didn't load
+ }
+ }
+ if (bUnknownError) //if cause is unknown then report it
+ {
+ LogToFile("Plugin %s doesn't load", szPluginPath);
+ std::string time = GetPluginTimestamp(&fd.ftLastWriteTime);
+ char buffer[4096];
+ char error[2048];
+ //DWORD_PTR arguments[2] = {loadError, 0};
+ FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY, NULL, loadError, 0, error, sizeof(error), NULL);
+ sprintf(buffer, " Error %ld - %s", loadError, error);
+ CPlugin thePlugin = CPlugin(std::string(fd.cFileName), "<unknown>", UUID_NULL, "", 0, time, buffer);
+ AddPlugin(thePlugin, listUnloadablePlugins);
+ }
+ }
+ else { //It was successfully loaded.
+ LogToFile("Plugin '%s' was loaded successfully", fd.cFileName);
+ MirandaPluginInfo = (PLUGININFOEX *(*)(DWORD))GetProcAddress(hInstPlugin, "MirandaPluginInfoEx");
+ if (!MirandaPluginInfo)
+ {
+ MirandaPluginInfo = (PLUGININFOEX *(*)(DWORD))GetProcAddress(hInstPlugin, "MirandaPluginInfo");
+ }
+ if (!MirandaPluginInfo) { //There is no function: it's not a valid plugin. Let's move on to the next file.
+ continue;
+ }
+ else {
+ //It's a valid plugin, since we could find MirandaPluginInfo
+ #if (!defined(WIN64) && !defined(_WIN64))
+ asmCheckOK = FALSE;
+ __asm {
+ push mirandaVersion
+ push mirandaVersion
+ call MirandaPluginInfo
+ pop eax
+ pop eax
+ cmp eax, mirandaVersion
+ jne a1
+ mov asmCheckOK, 0xffffffff
+ // jmp a2
+ a1:
+ // a2:
+ }
+ #else
+ asmCheckOK = TRUE;
+ #endif
+ if (asmCheckOK)
+ pluginInfo = CopyPluginInfo(MirandaPluginInfo(mirandaVersion));
+ else {
+ ZeroMemory(&pluginInfo, sizeof(pluginInfo));
+ MessageBox(NULL, fd.cFileName, "Invalid plugin", MB_OK);
+ }
+ }
+ }
+ //Let's get the info.
+ if (MirandaPluginInfo != NULL) {//a valid miranda plugin
+ if (pluginInfo != NULL) {
+ LogToFile("Plugin '%s' is a miranda plugin", fd.cFileName);
+ //We have loaded the informations into pluginInfo.
+ std::string timedate = GetPluginTimestamp(&fd.ftLastWriteTime);
+ CPlugin thePlugin = CPlugin(std::string(fd.cFileName),std::string(pluginInfo->shortName), pluginInfo->uuid, std::string((pluginInfo->flags & 1) ? "Unicode aware" : ""), (DWORD) pluginInfo->version, timedate, "");
+
+ if (PluginIsEnabled)
+ {
+ AddPlugin(thePlugin, listActivePlugins);
+ }
+ else {
+ if ((IsUUIDNull(pluginInfo->uuid)) && (mirandaVersion >= PLUGIN_MAKE_VERSION(0,8,0,9)))
+ {
+ thePlugin.SetErrorMessage(" Plugin does not have an UUID and will not work with Miranda 0.8.\r\n");
+ AddPlugin(thePlugin, listUnloadablePlugins);
+ }
+ else{
+ AddPlugin(thePlugin, listInactivePlugins);
+ }
+ FreeLibrary(hInstPlugin); //We don't need it anymore.
+ }
+ FreePluginInfo(pluginInfo);
+ MirandaPluginInfo = NULL;
+#ifdef _DEBUG
+ if (verbose)
+ {
+ char szMsg[4096] = { 0 };
+ wsprintf(szMsg, "Done with: %s", fd.cFileName);
+ PUShowMessage(szMsg, SM_NOTIFY);
+ }
+#endif
+ }
+ else{//pluginINFO == NULL
+ LogToFile("Plugin '%s' refuses to load", fd.cFileName);
+ pluginInfo = CopyPluginInfo(MirandaPluginInfo(PLUGIN_MAKE_VERSION(9, 9, 9, 9))); //let's see if the plugin likes this miranda version
+ char *szShortName = "<unknown>";
+ std::string time = GetPluginTimestamp(&fd.ftLastWriteTime); //get the plugin timestamp;
+ DWORD version = 0;
+ if (pluginInfo)
+ {
+ szShortName = pluginInfo->shortName;
+ version = pluginInfo->version;
+ }
+
+ CPlugin thePlugin = CPlugin(std::string(fd.cFileName), std::string(szShortName), (pluginInfo) ? (pluginInfo->uuid) : UUID_NULL, std::string(((pluginInfo) && (pluginInfo->flags & 1)) ? "Unicode aware" : ""), version, time, " Plugin refuses to load. Miranda version too old.");
+
+ AddPlugin(thePlugin, listUnloadablePlugins);
+ if (pluginInfo)
+ {
+ FreePluginInfo(pluginInfo);
+ }
+ }
+ }
+ } while (FindNextFile(hFind,&fd));
+ FindClose(hFind);
+ }
+ LogToFile("Done loading plugins");
+ return TRUE;
+}
+
+bool CVersionInfo::AddPlugin(CPlugin &aPlugin, std::list<CPlugin> &aList) {
+ std::list<CPlugin>::iterator pos = aList.begin();
+ bool inserted = FALSE;
+
+ if (aList.begin() == aList.end()) { //It's empty
+ aList.push_back(aPlugin);
+ return TRUE;
+ }
+ else { //It's not empty
+ while (pos != aList.end()) {
+ //It can be either < or >, not equal.
+ if (aPlugin < (*pos)) {
+ aList.insert(pos, aPlugin);
+ return TRUE;
+ }
+ else { //It's greater: we need to insert it.
+ pos++;
+ }
+ }
+ }
+ if (inserted == FALSE) {
+ aList.push_back(aPlugin);
+ return TRUE;
+ }
+ return TRUE;
+};
+
+static char *GetStringFromRVA(DWORD RVA, const LOADED_IMAGE *image)
+{
+ char *moduleName;
+ moduleName = (char *) ImageRvaToVa(image->FileHeader, image->MappedAddress, RVA, NULL);
+ return moduleName;
+}
+
+bool CVersionInfo::GetLinkedModulesInfo(char *moduleName, std::string &linkedModules)
+{
+ LogToFile("Checking dll %s for unresolved dll dependencies ...", moduleName);
+ LOADED_IMAGE image;
+ ULONG importTableSize;
+ IMAGE_IMPORT_DESCRIPTOR *importData;
+ //HMODULE dllModule;
+ linkedModules = "";
+ bool result = false;
+// LogToFile(" Before LoadLibraryEx", moduleName);
+// dllModule = LoadLibraryEx(moduleName, NULL, DONT_RESOLVE_DLL_REFERENCES);
+ //dllModule = 0;
+ //LogToFile(" Before MapAndLoad (dll handle %ld)", moduleName, dllModule);
+ if (MapAndLoad(moduleName, NULL, &image, TRUE, TRUE) == FALSE)
+ {
+ char tmp[20];
+ sprintf(tmp, "%d", GetLastError());
+ LogToFile(" MapAndLoad failed with error %s", tmp);
+ linkedModules = "<error " + std::string(tmp) + " at MapAndLoad()>\r\n";
+// FreeLibrary(dllModule);
+ return result;
+ }
+ LogToFile(" Before ImageDirectoryEntryToData (base address %ld)", image.MappedAddress);
+ importData = (IMAGE_IMPORT_DESCRIPTOR *) ImageDirectoryEntryToData(image.MappedAddress, FALSE, IMAGE_DIRECTORY_ENTRY_IMPORT, &importTableSize);
+ if (!importData)
+ {
+ char tmp[20];
+ sprintf(tmp, "%d", GetLastError());
+ LogToFile(" ImageDirectoryEntryToData failed with error %s", tmp);
+ linkedModules = "<error " + std::string(tmp) + " at ImageDirectoryEntryToDataEx()>\r\n";
+ }
+ else{
+ LogToFile(" Checking dll dependencies");
+ while (importData->Name)
+ {
+ char *moduleName;
+ moduleName = GetStringFromRVA(importData->Name, &image);
+ LogToFile(" Checking link to dll %s", moduleName);
+ if (!DoesDllExist(moduleName))
+ {
+ LogToFile(" Dll %s not found, adding to list", moduleName);
+ linkedModules.append(" Plugin statically links to missing dll file: " + std::string(moduleName) + "\r\n");
+ result = true;
+ }
+ else{
+ LogToFile(" Dll %s found", moduleName);
+ }
+ LogToFile(" Moving to next import entry");
+ importData++; //go to next record
+ }
+ }
+ LogToFile(" Done checking dependencies");
+ LogToFile(" Cleaning up; before {FreeLibrary()} and UnMapAndLoad");
+// FreeLibrary(dllModule);
+ UnMapAndLoad(&image); //unload the image
+ return result;
+}
+
+std::string CVersionInfo::GetListAsString(std::list<CPlugin> &aList, DWORD flags, int beautify) {
+ std::list<CPlugin>::iterator pos = aList.begin();
+ std::string out = "";
+#ifdef _DEBUG
+ if (verbose) PUShowMessage("CVersionInfo::GetListAsString, begin.", SM_NOTIFY);
+#endif
+
+ char szHeader[32] = {0};
+ char szFooter[32] = {0};
+ if ((((flags & VISF_FORUMSTYLE) == VISF_FORUMSTYLE) || beautify) && (DBGetContactSettingByte(NULL, ModuleName, "BoldVersionNumber", TRUE)))
+ {
+ GetStringFromDatabase("BoldBegin", "[b]", szHeader, sizeof(szHeader));
+ GetStringFromDatabase("BoldEnd", "[/b]", szFooter, sizeof(szFooter));
+ }
+
+ while (pos != aList.end()) {
+ out.append(std::string((*pos).getInformations(flags, szHeader, szFooter)));
+ pos++;
+ }
+#ifdef _DEBUG
+ if (verbose) PUShowMessage("CVersionInfo::GetListAsString, end.", SM_NOTIFY);
+#endif
+ return out;
+};
+
+void CVersionInfo::BeautifyReport(int beautify, char *szBeautifyText, char *szNonBeautifyText, std::string &out)
+{
+ if (beautify)
+ {
+ out.append(szBeautifyText);
+ }
+ else{
+ out.append(szNonBeautifyText);
+ }
+}
+
+void CVersionInfo::AddInfoHeader(int suppressHeader, int forumStyle, int beautify, std::string &out)
+{
+ if (forumStyle) //forum style
+ {
+ char szSize[256];
+ char szQuote[256];
+
+ GetStringFromDatabase("SizeBegin", "[size=1]", szSize, sizeof(szSize));
+ GetStringFromDatabase("QuoteBegin", "[quote]", szQuote, sizeof(szQuote));
+ out.append(szQuote);
+ out.append(szSize);
+ }
+ else{
+ out = "";
+ }
+ if (!suppressHeader)
+ {
+ out.append("Miranda IM - VersionInformation plugin by Hrk, modified by Eblis\r\n");
+ if (!forumStyle)
+ {
+ out.append("Miranda's homepage: http://www.miranda-im.org/\r\n"); //changed homepage
+ out.append("Miranda tools: http://miranda-im.org/download/\r\n\r\n"); //was missing a / before download
+ }
+ }
+ char buffer[1024]; //for beautification
+ GetStringFromDatabase("BeautifyHorizLine", "<hr />", buffer, sizeof(buffer));
+ BeautifyReport(beautify, buffer, "", out);
+ GetStringFromDatabase("BeautifyBlockStart", "<blockquote>", buffer, sizeof(buffer));
+ BeautifyReport(beautify, buffer, "", out);
+ if (!suppressHeader)
+ {
+ //Time of report:
+ char lpzTime[12]; GetTimeFormat(LOCALE_USER_DEFAULT, 0, NULL,"HH':'mm':'ss",lpzTime, sizeof(lpzTime));
+ char lpzDate[32]; GetDateFormat(EnglishLocale, 0, NULL,"dd' 'MMMM' 'yyyy",lpzDate, sizeof(lpzDate));
+ out.append("Report generated at: " + std::string(lpzTime) + " on " + std::string(lpzDate) + "\r\n\r\n");
+ }
+ //Operating system
+ out.append("CPU: " + lpzCPUName + " [" + lpzCPUIdentifier + "]");
+ if (bDEPEnabled)
+ {
+ out.append(" [DEP enabled]");
+ }
+ if (luiProcessors > 1)
+ {
+ char noProcs[128];
+ sprintf(noProcs, " [%d CPUs]", luiProcessors);
+ out.append(noProcs);
+ }
+ out.append("\r\n");
+
+ //RAM
+ char szRAM[64]; wsprintf(szRAM, "%d", luiRAM);
+ out.append("Installed RAM: " + std::string(szRAM) + " MBytes\r\n");
+
+ //operating system
+ out.append("Operating System: " + lpzOSName + " [version: " + lpzOSVersion + "]\r\n");
+
+ //shell, IE, administrator
+ out.append("Shell: " + lpzShell + ", Internet Explorer " + lpzIEVersion + "\r\n");
+ out.append("Administrator privileges: " + lpzAdministratorPrivileges + "\r\n");
+
+ //languages
+ out.append("OS Languages: " + lpzOSLanguages + "\r\n");
+
+
+ //FreeDiskSpace
+ if (luiFreeDiskSpace) {
+ char szDiskSpace[64]; wsprintf(szDiskSpace, "%d", luiFreeDiskSpace);
+ out.append("Free disk space on Miranda partition: " + std::string(szDiskSpace) + " MBytes\r\n");
+ }
+
+ //Miranda
+ out.append("Miranda path: " + lpzMirandaPath + "\r\n");
+
+ out.append("Miranda IM version: " + lpzMirandaVersion);
+ if (bIsWOW64)
+ {
+ out.append(" [running inside WOW64]");
+ }
+ if (bServiceMode)
+ {
+ out.append(" [service mode]");
+ }
+ out.append("\r\nBuild time: " + lpzBuildTime + "\r\n");
+ out.append("Profile path: " + lpzProfilePath + "\r\n");
+ //if (lpzProfileSize.find("error", 0) == std::string::npos) //only show the profile size of no error occured
+ //{
+ out.append("Profile size: " + lpzProfileSize + "\r\n");
+ out.append("Profile creation date: " + lpzProfileCreationDate + "\r\n");
+ //}
+ out.append("Language pack: " + lpzLangpackInfo);
+ out.append((lpzLangpackModifiedDate.size() > 0) ? ", modified: " + lpzLangpackModifiedDate : "");
+ out.append("\r\n");
+
+ out.append("Nightly: " + lpzNightly + "\r\n");
+ out.append("Unicode core: " + lpzUnicodeBuild);
+
+ GetStringFromDatabase("BeautifyBlockEnd", "</blockquote>", buffer, sizeof(buffer));
+ BeautifyReport(beautify, buffer, "\r\n", out);
+ //out.append("\r\n");
+}
+
+void CVersionInfo::AddInfoFooter(int suppressFooter, int forumStyle, int beautify, std::string &out)
+{
+ //End of report
+ char buffer[1024]; //for beautification purposes
+ GetStringFromDatabase("BeautifyHorizLine", "<hr />", buffer, sizeof(buffer));
+ if (!suppressFooter)
+ {
+ BeautifyReport(beautify, buffer, "\r\n", out);
+ out.append("\r\nEnd of report.\r\n");
+ }
+ if (!forumStyle)
+ {
+ if (!suppressFooter)
+ {
+ out.append(Translate("If you are going to use this report to submit a bug, remember to check the website for questions or help the developers may need.\r\nIf you don't check your bug report and give feedback, it will not be fixed!"));
+ }
+ }
+ else{
+ char szSize[256];
+ char szQuote[256];
+
+ GetStringFromDatabase("SizeEnd", "[/size]", szSize, sizeof(szSize));
+ GetStringFromDatabase("QuoteEnd", "[/quote]", szQuote, sizeof(szQuote));
+ out.append(szSize);
+ out.append(szQuote);
+ }
+}
+
+static void AddSectionAndCount(std::list<CPlugin> list, char *listText, std::string &out)
+{
+ char tmp[64];
+ sprintf(tmp, " (%u)", list.size());
+ out.append(listText);
+ out.append(tmp);
+ out.append(":");
+}
+
+std::string CVersionInfo::GetInformationsAsString(int bDisableForumStyle) {
+ //Begin of report
+ std::string out;
+ int forumStyle = (bDisableForumStyle) ? 0 : DBGetContactSettingByte(NULL, ModuleName, "ForumStyle", TRUE);
+ int showUUID = DBGetContactSettingByte(NULL, ModuleName, "ShowUUIDs", FALSE);
+ int beautify = DBGetContactSettingByte(NULL, ModuleName, "Beautify", 0) & (!forumStyle);
+ int suppressHeader = DBGetContactSettingByte(NULL, ModuleName, "SuppressHeader", TRUE);
+
+ DWORD flags = (forumStyle) | (showUUID << 1);
+
+ AddInfoHeader(suppressHeader, forumStyle, beautify, out);
+ char normalPluginsStart[1024]; //for beautification purposes, for normal plugins text (start)
+ char normalPluginsEnd[1024]; //for beautification purposes, for normal plugins text (end)
+ char horizLine[1024]; //for beautification purposes
+ char buffer[1024]; //for beautification purposes
+
+ char headerHighlightStart[10] = "";
+ char headerHighlightEnd[10] = "";
+ if (forumStyle)
+ {
+ char start[128], end[128];
+ GetStringFromDatabase("BoldBegin", "[b]", start, sizeof(start));
+ GetStringFromDatabase("BoldEnd", "[/b]", end, sizeof(end));
+ strncpy(headerHighlightStart, start, sizeof(headerHighlightStart));
+ strncpy(headerHighlightEnd, end, sizeof(headerHighlightEnd));
+ }
+
+ //Plugins: list of active (enabled) plugins.
+ GetStringFromDatabase("BeautifyHorizLine", "<hr />", horizLine, sizeof(horizLine));
+ BeautifyReport(beautify, horizLine, "\r\n", out);
+ GetStringFromDatabase("BeautifyActiveHeaderBegin", "<b><font size=\"-1\" color=\"DarkGreen\">", buffer, sizeof(buffer));
+ BeautifyReport(beautify, buffer, headerHighlightStart, out);
+ AddSectionAndCount(listActivePlugins, "Active Plugins", out);
+ GetStringFromDatabase("BeautifyActiveHeaderEnd", "</font></b>", buffer, sizeof(buffer));
+ BeautifyReport(beautify, buffer, headerHighlightEnd, out);
+ out.append("\r\n");
+
+ GetStringFromDatabase("BeautifyPluginsBegin", "<font size=\"-2\" color=\"black\">", normalPluginsStart, sizeof(normalPluginsStart));
+ BeautifyReport(beautify, normalPluginsStart, "", out);
+ out.append(GetListAsString(listActivePlugins, flags, beautify));
+ GetStringFromDatabase("BeautifyPluginsEnd", "</font>", normalPluginsEnd, sizeof(normalPluginsEnd));
+ BeautifyReport(beautify, normalPluginsEnd, "", out);
+ //Plugins: list of inactive (disabled) plugins.
+ if ((!forumStyle) && ((DBGetContactSettingByte(NULL, ModuleName, "ShowInactive", TRUE)) || (bServiceMode))) {
+ BeautifyReport(beautify, horizLine, "\r\n", out);
+ GetStringFromDatabase("BeautifyInactiveHeaderBegin", "<b><font size=\"-1\" color=\"DarkRed\">", buffer, sizeof(buffer));
+ BeautifyReport(beautify, buffer, headerHighlightStart, out);
+ AddSectionAndCount(listInactivePlugins, "Inactive Plugins", out);
+ GetStringFromDatabase("BeautifyInactiveHeaderEnd", "</font></b>", buffer, sizeof(buffer));
+ BeautifyReport(beautify, buffer, headerHighlightEnd, out);
+ out.append("\r\n");
+ BeautifyReport(beautify, normalPluginsStart, "", out);
+ out.append(GetListAsString(listInactivePlugins, flags, beautify));
+ BeautifyReport(beautify, normalPluginsEnd, "", out);
+ }
+ if (listUnloadablePlugins.size() > 0)
+ {
+ //out.append("\r\n");
+ BeautifyReport(beautify, horizLine, "\r\n", out);
+ GetStringFromDatabase("BeautifyUnloadableHeaderBegin", "<b><font size=\"-1\"><font color=\"Red\">", buffer, sizeof(buffer));
+ BeautifyReport(beautify, buffer, headerHighlightStart, out);
+ AddSectionAndCount(listUnloadablePlugins, "Unloadable Plugins", out);
+ GetStringFromDatabase("BeautifyUnloadableHeaderEnd", "</font></b>", buffer, sizeof(buffer));
+ BeautifyReport(beautify, buffer, headerHighlightEnd, out);
+ out.append("\r\n");
+ BeautifyReport(beautify, normalPluginsStart, "", out);
+ out.append(GetListAsString(listUnloadablePlugins, flags, beautify));
+ BeautifyReport(beautify, normalPluginsEnd, "", out);
+ }
+ AddInfoFooter(suppressHeader, forumStyle, beautify, out);
+ return out;
+}
+
+//========== Print functions =====
+
+void CVersionInfo::PrintInformationsToFile(const char *info)
+{
+ char buffer[MAX_PATH];
+ char outputFileName[MAX_PATH];
+ if (bFoldersAvailable)
+ {
+ FoldersGetCustomPath(hOutputLocation, buffer, sizeof(buffer), "%miranda_path%");
+ strcat(buffer, "\\VersionInfo.txt");
+ }
+ else{
+ GetStringFromDatabase("OutputFile", "VersionInfo.txt", buffer, sizeof(buffer));
+ }
+
+ RelativePathToAbsolute(buffer, outputFileName, sizeof(buffer));
+
+ FILE *fp = fopen(outputFileName, "wb");
+ if (fp != NULL) {
+ fprintf(fp, info);
+ fclose(fp);
+ char mex[512];
+ mir_snprintf(mex, sizeof(mex), Translate("Information successfully written to file: \"%s\"."), outputFileName);
+ Log(mex);
+ }
+ else {
+ char mex[512];
+ mir_snprintf(mex, sizeof(mex), Translate("Error during the creation of file \"%s\". Disk may be full or write protected."), outputFileName);
+ Log(mex);
+ }
+}
+
+void CVersionInfo::PrintInformationsToFile() {
+ PrintInformationsToFile((*this).GetInformationsAsString().c_str());
+}
+
+void CVersionInfo::PrintInformationsToMessageBox() {
+ MessageBox(NULL, (*this).GetInformationsAsString().c_str(), ModuleName, MB_OK);
+ return;
+}
+
+void CVersionInfo::PrintInformationsToOutputDebugString() {
+ OutputDebugString((*this).GetInformationsAsString().c_str());
+ return;
+}
+
+#include "resource.h"
+//extern HINSTANCE hInst;
+
+void CVersionInfo::PrintInformationsToDialogBox() {
+// HWND parent = DBGetContactSettingByte(NULL, ModuleName, "ShowInTaskbar", TRUE)?GetDesktopWindow():NULL;
+ HWND parent = NULL;
+ HWND DialogBox = CreateDialogParam(hInst,
+ MAKEINTRESOURCE(IDD_DIALOGINFO),
+ parent, DialogBoxProc, (LPARAM) this);
+
+ SetDlgItemText(DialogBox, IDC_TEXT, (*this).GetInformationsAsString().c_str());
+ return;
+}
+
+void CVersionInfo::PrintInformationsToClipboard(bool showLog) {
+
+ if (GetOpenClipboardWindow()) {
+ Log(Translate("The clipboard is not available, retry."));
+ }
+ else {
+ OpenClipboard(NULL);
+ //Ok, let's begin, then.
+ EmptyClipboard();
+ //Storage data we'll use.
+ LPTSTR lptstrCopy;
+ std::string aux = (*this).GetInformationsAsString();
+ size_t length = aux.length() + 1;
+ HANDLE hData = GlobalAlloc(GMEM_MOVEABLE, length + 5);
+ //Lock memory, copy it, release it.
+ lptstrCopy = (LPTSTR)GlobalLock(hData);
+ memcpy(lptstrCopy, aux.c_str(), length);
+ lptstrCopy[length] = '\0';
+ GlobalUnlock(hData);
+ //Now set the clipboard data.
+ SetClipboardData(CF_TEXT, hData);
+ //Remove the lock on the clipboard.
+ CloseClipboard();
+ if (showLog)
+ {
+ Log(Translate("Information successfully copied into clipboard."));
+ }
+ }
+ return;
+}
+
+/*int MyReceive(SOCKET sClient, char *message, int size, int bShow)
+{
+ int len = recv(sClient, message, size - 1, 0);
+ int success = 0;
+ if (len != SOCKET_ERROR)
+ {
+ message[len] = '\0';
+ if (bShow)
+ {
+ PUShowMessage(message, SM_NOTIFY);
+ }
+ char *pos = message;
+ while ((pos = strchr(pos + 1, '\n')))
+ {
+ success++;
+ }
+ if (success <= 0) success = 1; //make sure success is at least 1
+ }
+ else{
+ success = 0;
+ closesocket(sClient);
+ }
+ return success;
+}*/
+
+#define UPLOAD_ERROR() {PUShowMessage("Error while trying to upload data", SM_WARNING); return 1;}
+
+DWORD WINAPI UploadWorkerTread(LPVOID param)
+{
+ //PUShowMessage("Uploading to site", SM_NOTIFY);
+ /*
+ char *text = (char *) param;
+ char message[2048];
+
+ char server[1024];
+ int port;
+ char user[512];
+ char password[512];
+
+ GetStringFromDatabase("UploadServer", "vi.cass.cz", server, sizeof(server));
+ port = DBGetContactSettingWord(NULL, ModuleName, "UploadPort", DEFAULT_UPLOAD_PORT);
+ GetStringFromDatabase("UploadUser", "", user, sizeof(user));
+ GetStringFromDatabase("UploadPassword", "", password, sizeof(password));
+ CallService(MS_DB_CRYPT_DECODESTRING, sizeof(password), (LPARAM) password);
+
+ SOCKET sClient = socket(AF_INET, SOCK_STREAM, 0);
+ if (!sClient)
+ {
+ MB("Could not create connection socket ...");
+ return 1;
+ }
+
+ sockaddr_in addr = {0};
+ hostent *localHost = gethostbyname(server);
+ char *localIP = (localHost) ? inet_ntoa(*(struct in_addr *) *localHost->h_addr_list) : server;
+
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = inet_addr(localIP);
+ addr.sin_port = htons(port);
+
+ int res = connect(sClient, (sockaddr *) &addr, sizeof(addr));
+ if (res)
+ {
+ char buffer[1024];
+ mir_snprintf(buffer, sizeof(buffer), "Could not connect to server '%s' on port %d", server, port);
+ MB(buffer);
+ return 1;
+ }
+ res = MyReceive(sClient, message, sizeof(message), TRUE); //get the welcome message
+ switch (res)
+ {
+ case 1:
+ if (!MyReceive(sClient, message, sizeof(message), 0)) UPLOAD_ERROR(); //get the enter username message
+ break;
+
+ case 2: //the enter user message was received already
+ break;
+
+ default: //assume error by default
+ UPLOAD_ERROR();
+ }
+
+ send(sClient, user, strlen(user), 0);
+ if (!MyReceive(sClient, message, sizeof(message), FALSE)) UPLOAD_ERROR(); //get the enter password message
+ send(sClient, password, strlen(password), 0);
+ if (!MyReceive(sClient, message, sizeof(message), FALSE)) UPLOAD_ERROR(); //get the upload data message
+ send(sClient, text, strlen(text) + 1, 0); //data message needs to send \0 so the server knows when to stop.
+ if (!MyReceive(sClient, message, sizeof(message), TRUE)) UPLOAD_ERROR();
+ closesocket(sClient);
+ //PUShowMessage("Done uploading to site", SM_NOTIFY);
+
+ if (text)
+ {
+ free(text);
+ }
+ */
+ return 0;
+}
+
+void CVersionInfo::UploadToSite(char *text){
+
+ DWORD threadID;
+ HANDLE thread;
+ char *data = NULL;
+ if (!text)
+ {
+ data = _strdup(GetInformationsAsString().c_str());
+ }
+ else{
+ data = _strdup(text);
+ }
+
+ thread = CreateThread(NULL, NULL, UploadWorkerTread, data, 0, &threadID); //the thread will free the buffer
+ if (!thread)
+ {
+ MB("Upload worker thread could not be created");
+ }
+ if ((thread != NULL) && (thread != INVALID_HANDLE_VALUE))
+ {
+ CloseHandle(thread);
+ }
+} \ No newline at end of file
diff --git a/plugins/VersionInfo/CVersionInfo.h b/plugins/VersionInfo/CVersionInfo.h
new file mode 100644
index 0000000000..e97eee09cb
--- /dev/null
+++ b/plugins/VersionInfo/CVersionInfo.h
@@ -0,0 +1,116 @@
+/*
+Version information plugin for Miranda IM
+
+Copyright © 2002-2006 Luca Santarelli, Cristian Libotean
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef CVERSIONINFO_H
+#define CVERSIONINFO_H
+
+//#define STRICT
+#define WIN32_LEAN_AND_MEAN
+//#include "AggressiveOptimize.h"
+
+#define _CRT_SECURE_NO_DEPRECATE
+
+#ifndef PF_NX_ENABLED
+ #define PF_NX_ENABLED 12
+#endif
+
+#include <list>
+#include <string>
+//using namespace std;
+
+#include "CPlugin.h"
+
+class CVersionInfo
+{
+ private:
+ //Informations related to Miranda: main informations.
+ std::string lpzMirandaVersion;
+ std::string lpzMirandaPath;
+ std::string lpzProfilePath;
+ std::string lpzProfileSize;
+ std::string lpzProfileCreationDate;
+ std::string lpzNightly;
+ std::string lpzUnicodeBuild;
+ std::string lpzCPUName;
+ std::string lpzCPUIdentifier;
+ std::string lpzBuildTime;
+ std::string lpzShell;
+ std::string lpzIEVersion;
+ std::string lpzAdministratorPrivileges;
+ std::string lpzOSLanguages;
+ std::string lpzLangpackInfo;
+ std::string lpzLangpackModifiedDate;
+ //Informations related to plugins
+ std::list<CPlugin> listActivePlugins;
+ std::list<CPlugin> listInactivePlugins;
+ std::list<CPlugin> listUnloadablePlugins;
+ //OS and hardware informations.
+ std::string lpzOSVersion;
+ std::string lpzOSName;
+ unsigned int luiProcessors;
+ unsigned int luiRAM;
+ unsigned int luiFreeDiskSpace;
+ int bDEPEnabled;
+ BOOL bIsWOW64;
+ //Additional Miranda informations.
+ unsigned int luiContacts;
+ unsigned int luiEvents;
+ unsigned int luiUnreadEvents;
+ unsigned int luiDBSize;
+ bool bExpertSettingsOn;
+ //Configuration
+
+ bool GetLinkedModulesInfo(char *moduleName, std::string &linkedModules);
+
+ public:
+ //Constructor/Destructor
+ CVersionInfo();
+ ~CVersionInfo();
+ void Initialize();
+ //Miranda informations
+ bool GetMirandaVersion();
+ bool GetProfileSettings();
+ bool GetOSLanguages();
+ bool GetLangpackInfo();
+ bool GetPluginLists();
+ bool GetEventCount(); //TODO
+ //OSInformations
+ bool GetOSVersion();
+ bool GetHWSettings();
+ //Plugins
+ bool AddPlugin(CPlugin&, std::list<CPlugin>&);
+ //Prints
+
+ void PrintInformationsToFile();
+ void PrintInformationsToFile(const char *info);
+ void PrintInformationsToDialogBox();
+ void PrintInformationsToMessageBox();
+ void PrintInformationsToOutputDebugString();
+ void PrintInformationsToClipboard(bool);
+ void UploadToSite(char *text = NULL);
+
+ std::string GetListAsString(std::list<CPlugin>&, DWORD flags, int beautify);
+ std::string GetInformationsAsString(int bDisableForumStyle = 0);
+ void BeautifyReport(int, char *, char *, std::string &);
+ void AddInfoHeader(int, int, int, std::string &);
+ void AddInfoFooter(int, int, int, std::string &);
+};
+
+#endif \ No newline at end of file
diff --git a/plugins/VersionInfo/VersionInfo.html b/plugins/VersionInfo/VersionInfo.html
new file mode 100644
index 0000000000..a955874979
--- /dev/null
+++ b/plugins/VersionInfo/VersionInfo.html
@@ -0,0 +1,11 @@
+<html>
+ <head></head>
+ <body>
+ <center>
+ <h1>Version Information Test Page</h1>
+
+ <p>Version Information version 1.4.3.2</p>
+ <p><a href="VersionInfo.zip">VersionInfo.zip</a></p>
+ </center>
+ </body>
+</html>
diff --git a/plugins/VersionInfo/VersionInfo.ico b/plugins/VersionInfo/VersionInfo.ico
new file mode 100644
index 0000000000..b026d584c2
--- /dev/null
+++ b/plugins/VersionInfo/VersionInfo.ico
Binary files differ
diff --git a/plugins/VersionInfo/VersionInfo_10.vcxproj b/plugins/VersionInfo/VersionInfo_10.vcxproj
new file mode 100644
index 0000000000..65d6bed2a0
--- /dev/null
+++ b/plugins/VersionInfo/VersionInfo_10.vcxproj
@@ -0,0 +1,382 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug Unicode|Win32">
+ <Configuration>Debug Unicode</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug Unicode|x64">
+ <Configuration>Debug Unicode</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release Unicode|Win32">
+ <Configuration>Release Unicode</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release Unicode|x64">
+ <Configuration>Release Unicode</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectName>VersionInfo</ProjectName>
+ <ProjectGuid>{3CE5572B-B7B0-4D1C-9D10-4622FBA6198E}</ProjectGuid>
+ <RootNamespace>VersionInfo</RootNamespace>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\Plugins\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)/Obj/$(ProjectName)\</IntDir>
+ <IgnoreImportLibrary Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</IgnoreImportLibrary>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\Plugins\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)/Obj/$(ProjectName)\</IntDir>
+ <IgnoreImportLibrary Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</IgnoreImportLibrary>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">$(SolutionDir)$(Configuration)\Plugins\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">$(SolutionDir)$(Configuration)/Obj/$(ProjectName)\</IntDir>
+ <IgnoreImportLibrary Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">true</IgnoreImportLibrary>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">$(SolutionDir)$(Configuration)\Plugins\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">$(SolutionDir)$(Configuration)/Obj/$(ProjectName)\</IntDir>
+ <IgnoreImportLibrary Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">true</IgnoreImportLibrary>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">svc_vi</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">svc_vi</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">svc_vi</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">svc_vi</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Midl>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ <TypeLibraryName>C:\Programmi\Miranda\Plugins/VersionInfo.tlb</TypeLibraryName>
+ <HeaderFileName>
+ </HeaderFileName>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;VERSIONINFO_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <RuntimeTypeInfo>true</RuntimeTypeInfo>
+ <AssemblerOutput>All</AssemblerOutput>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0410</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>comctl32.lib;imagehlp.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <BaseAddress>0x25040000</BaseAddress>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ <TypeLibraryName>.\Release/VersionInfo.tlb</TypeLibraryName>
+ <HeaderFileName>
+ </HeaderFileName>
+ </Midl>
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;VERSIONINFO_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <RuntimeTypeInfo>true</RuntimeTypeInfo>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <BrowseInformationFile>$(IntDir)</BrowseInformationFile>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0410</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>comctl32.lib;imagehlp.lib;odbc32.lib;odbccp32.lib;delayimp.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <AdditionalManifestDependencies>type=%27Win32%27 name=%27Microsoft.Windows.Common-Controls%27 version=%276.0.0.0%27 processorArchitecture=%27X86%27 publicKeyToken=%276595b64144ccf1df%27 language=%27*%27;%(AdditionalManifestDependencies)</AdditionalManifestDependencies>
+ <DelayLoadDLLs>imagehlp.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <GenerateMapFile>true</GenerateMapFile>
+ <MapFileName>$(OutDir)$(ProjectName).map</MapFileName>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+ <BaseAddress>0x25040000</BaseAddress>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">
+ <Midl>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ <TypeLibraryName>C:\Programmi\Miranda\Plugins/VersionInfo.tlb</TypeLibraryName>
+ <HeaderFileName>
+ </HeaderFileName>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;VERSIONINFO_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <RuntimeTypeInfo>true</RuntimeTypeInfo>
+ <AssemblerOutput>All</AssemblerOutput>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0410</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>comctl32.lib;imagehlp.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <BaseAddress>0x25040000</BaseAddress>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ <TypeLibraryName>.\Release/VersionInfo.tlb</TypeLibraryName>
+ <HeaderFileName>
+ </HeaderFileName>
+ </Midl>
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;VERSIONINFO_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <RuntimeTypeInfo>true</RuntimeTypeInfo>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <BrowseInformationFile>$(IntDir)</BrowseInformationFile>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0410</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>comctl32.lib;imagehlp.lib;odbc32.lib;odbccp32.lib;delayimp.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalManifestDependencies>type=%27Win32%27 name=%27Microsoft.Windows.Common-Controls%27 version=%276.0.0.0%27 processorArchitecture=%27X86%27 publicKeyToken=%276595b64144ccf1df%27 language=%27*%27;%(AdditionalManifestDependencies)</AdditionalManifestDependencies>
+ <DelayLoadDLLs>imagehlp.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+ <BaseAddress>0x25040000</BaseAddress>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="CPlugin.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">Disabled</Optimization>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;VERSIONINFO_EXPORTS</PreprocessorDefinitions>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;VERSIONINFO_EXPORTS</PreprocessorDefinitions>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">MinSpace</Optimization>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;VERSIONINFO_EXPORTS</PreprocessorDefinitions>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MinSpace</Optimization>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;VERSIONINFO_EXPORTS</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="CVersionInfo.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">Disabled</Optimization>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;VERSIONINFO_EXPORTS</PreprocessorDefinitions>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;VERSIONINFO_EXPORTS</PreprocessorDefinitions>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">MinSpace</Optimization>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;VERSIONINFO_EXPORTS</PreprocessorDefinitions>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MinSpace</Optimization>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;VERSIONINFO_EXPORTS</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="dlgHandlers.cpp" />
+ <ClCompile Include="hooked_events.cpp" />
+ <ClCompile Include="main.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">Disabled</Optimization>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;VERSIONINFO_EXPORTS</PreprocessorDefinitions>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;VERSIONINFO_EXPORTS</PreprocessorDefinitions>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">MinSpace</Optimization>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;VERSIONINFO_EXPORTS</PreprocessorDefinitions>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MinSpace</Optimization>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;VERSIONINFO_EXPORTS</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="services.cpp" />
+ <ClCompile Include="utils.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">Disabled</Optimization>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;VERSIONINFO_EXPORTS</PreprocessorDefinitions>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;VERSIONINFO_EXPORTS</PreprocessorDefinitions>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">MinSpace</Optimization>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;VERSIONINFO_EXPORTS</PreprocessorDefinitions>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MinSpace</Optimization>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;VERSIONINFO_EXPORTS</PreprocessorDefinitions>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="CPlugin.h" />
+ <ClInclude Include="CVersionInfo.h" />
+ <ClInclude Include="hooked_events.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="resource.rc" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="VersionInfo.ico" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/plugins/VersionInfo/VersionInfo_10.vcxproj.filters b/plugins/VersionInfo/VersionInfo_10.vcxproj.filters
new file mode 100644
index 0000000000..46d44f7f4e
--- /dev/null
+++ b/plugins/VersionInfo/VersionInfo_10.vcxproj.filters
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{0740347a-255e-4fb6-9e9a-14397010e8ad}</UniqueIdentifier>
+ <Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{691f667c-7c8a-4c3e-8990-a9b456b12230}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{b90941c8-389b-4c91-9298-f201b8740872}</UniqueIdentifier>
+ <Extensions>ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="CPlugin.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="CVersionInfo.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="dlgHandlers.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="hooked_events.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="main.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="services.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="utils.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="CPlugin.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="CVersionInfo.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="hooked_events.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="resource.rc">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="VersionInfo.ico">
+ <Filter>Resource Files</Filter>
+ </None>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/plugins/VersionInfo/common.h b/plugins/VersionInfo/common.h
new file mode 100644
index 0000000000..9f2abfb8f3
--- /dev/null
+++ b/plugins/VersionInfo/common.h
@@ -0,0 +1,120 @@
+/*
+Version information plugin for Miranda IM
+
+Copyright © 2002-2006 Luca Santarelli, Cristian Libotean
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef M_VERSIONINFO_COMMON_H
+#define M_VERSIONINFO_COMMON_H
+
+#pragma warning(disable:4005)
+#define _CRT_SECURE_NO_DEPRECATE
+#pragma warning(default:4005)
+
+#define VIPF_NONE 0x0000
+#define VIPF_UNCERTAIN 0x0010
+
+#define VISF_FORUMSTYLE 0x0001
+#define VISF_SHOWUUID 0x0002
+#define VISF_SHOWFLAGS 0x0004
+
+#include <windows.h>
+#include <time.h>
+
+#include <commctrl.h>
+#include <list>
+#include <imagehlp.h>
+#include <winsock.h>
+
+#include <String>
+//using namespace std;
+
+#include "version.h"
+
+#include "m_versioninfo.h"
+#include "hooked_events.h"
+#include "services.h"
+#include "dlgHandlers.h"
+
+#include "../../include/newpluginapi.h"
+#include "../../include/m_system.h"
+#include "../../include/m_langpack.h"
+#include "../../include/m_database.h"
+#include "../../include/m_skin.h"
+#include "../../include/m_clist.h"
+#include "../../include/m_options.h"
+#include "../../include/m_popup.h"
+
+#include "../../include/m_utils.h"
+#include "sdk/m_updater.h"
+#include "sdk/m_folders.h"
+
+#include "utils.h"
+
+#ifndef MS_DB_GETPROFILEPATH_BASIC //db3xSA
+#define MS_DB_GETPROFILEPATH_BASIC "DB/GetProfilePathBasic"
+#endif
+
+//main.cpp
+extern HINSTANCE hInst;
+
+//main.cpp
+extern HICON hiVIIcon;
+
+//main.cpp
+extern DWORD EnglishLocale;
+
+//for folders support
+extern BOOL bFoldersAvailable;
+extern HANDLE hOutputLocation;
+
+//services.cpp
+extern int bServiceMode;
+
+//main.cpp
+extern char ModuleName[];
+extern BOOL verbose;
+
+#define DEFAULT_UPLOAD_PORT 51234
+
+const MUUID UUID_NULL = {0x00000000, 0x0000, 0x0000, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }};
+
+//miranda [re]alloc and free functions
+//main.cpp
+extern void * (* MirandaMalloc)(size_t);
+extern void * (* MirandaRealloc)(void *, size_t);
+extern void (* MirandaFree)(void *);
+
+#define OLD_MIRANDAPLUGININFO_SUPPORT PLUGININFO oldPluginInfo = { \
+ sizeof(PLUGININFO), \
+ pluginInfo.shortName, \
+ pluginInfo.version, \
+ pluginInfo.description, \
+ pluginInfo.author, \
+ pluginInfo.authorEmail, \
+ pluginInfo.copyright, \
+ pluginInfo.homepage, \
+ pluginInfo.flags, \
+ pluginInfo.replacesDefaultModule \
+}; \
+\
+extern "C" __declspec(dllexport) PLUGININFO *MirandaPluginInfo(DWORD mirandaVersion) \
+{ \
+ return &oldPluginInfo; \
+}
+
+#endif \ No newline at end of file
diff --git a/plugins/VersionInfo/dlgHandlers.cpp b/plugins/VersionInfo/dlgHandlers.cpp
new file mode 100644
index 0000000000..d7f36d3f83
--- /dev/null
+++ b/plugins/VersionInfo/dlgHandlers.cpp
@@ -0,0 +1,700 @@
+/*
+Version information plugin for Miranda IM
+
+Copyright © 2002-2006 Luca Santarelli, Cristian Libotean
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "dlgHandlers.h"
+
+const char *szQuoteStrings[] = {"[quote] | [/quote]", "[code] | [/code]", ""};
+const char *szSizeStrings[] = {"[size=1] | [/size]", "[size=1px] | [/size]", "[size=12] | [/size]", "[size=80] | [/size]", ""};
+const char *szBoldStrings[] = {"[b] | [/b]", "[u] | [/u]", "[b][u] | [/u][/b]", "<b> | </b>", "<u> | </u>", "<b><u> | </u></b>"};
+const int nQuoteCount = sizeof(szQuoteStrings) / sizeof(szQuoteStrings[0]); //get the number of quote strings
+const int nSizeCount = sizeof(szSizeStrings) / sizeof(szSizeStrings[0]); //get the number of size strings
+const int nBoldCount = sizeof(szBoldStrings) / sizeof(szBoldStrings[0]); //get the number of bold strings
+
+#define MAX_TEXT 4096*4
+
+int AddInfoToComboboxes(HWND hWnd, int nQuotesComboBox, int nSizesComboBox, int nBoldComboBox)
+{
+ int i;
+ for (i = 0; i < nQuoteCount; i++)
+ {
+ SendDlgItemMessage(hWnd, nQuotesComboBox, CB_ADDSTRING, 0, (LPARAM) szQuoteStrings[i]);
+ }
+ for (i = 0; i < nSizeCount; i++)
+ {
+ SendDlgItemMessage(hWnd, nSizesComboBox, CB_ADDSTRING, 0, (LPARAM) szSizeStrings[i]);
+ }
+ for (i = 0; i < nBoldCount; i++)
+ {
+ SendDlgItemMessage(hWnd, nBoldComboBox, CB_ADDSTRING, 0, (LPARAM) szBoldStrings[i]);
+ }
+ return 0;
+}
+
+void EnableAskComboboxes(HWND hWnd, int bEnable)
+{
+ EnableWindow(GetDlgItem(hWnd, IDC_ASK_BOLDCOMBOBOX), bEnable);
+ EnableWindow(GetDlgItem(hWnd, IDC_ASK_QUOTECOMBOBOX), bEnable);
+ EnableWindow(GetDlgItem(hWnd, IDC_ASK_SIZECOMBOBOX), bEnable);
+}
+
+INT_PTR CALLBACK AskDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ const int MAX_SIZE = 128;
+ static int oldFSFValue;
+ static char oldQuoteBegin[MAX_SIZE], oldQuoteEnd[MAX_SIZE];
+ static char oldSizeBegin[MAX_SIZE], oldSizeEnd[MAX_SIZE];
+ static char oldBoldBegin[MAX_SIZE], oldBoldEnd[MAX_SIZE];
+
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ char buffer[1024];
+
+ SendMessage(hWnd, WM_SETICON, ICON_BIG, (LPARAM) hiVIIcon);
+
+ TranslateDialogDefault(hWnd);
+
+ oldFSFValue = DBGetContactSettingByte(NULL, ModuleName, "ForumStyle", 1);
+
+ AddInfoToComboboxes(hWnd, IDC_ASK_QUOTECOMBOBOX, IDC_ASK_SIZECOMBOBOX, IDC_ASK_BOLDCOMBOBOX);
+
+ CheckDlgButton(hWnd, IDC_ASK_TODIALOGBOX, BST_CHECKED);
+
+ CheckDlgButton(hWnd, IDC_ASK_FORUMSTYLE, (oldFSFValue) ? BST_CHECKED : BST_UNCHECKED);
+ EnableAskComboboxes(hWnd, oldFSFValue);
+
+ GetStringFromDatabase("QuoteBegin", "[quote]", oldQuoteBegin, MAX_SIZE);
+ GetStringFromDatabase("QuoteEnd", "[/quote]", oldQuoteEnd, MAX_SIZE);
+ sprintf(buffer, "%s | %s", oldQuoteBegin, oldQuoteEnd);
+ SendDlgItemMessage(hWnd, IDC_ASK_QUOTECOMBOBOX, CB_SELECTSTRING, -1, (LPARAM) buffer);
+
+ GetStringFromDatabase("SizeBegin", "[size=1]", oldSizeBegin, MAX_SIZE);
+ GetStringFromDatabase("SizeEnd", "[/size]", oldSizeEnd, MAX_SIZE);
+ sprintf(buffer, "%s | %s", oldSizeBegin, oldSizeEnd);
+ SendDlgItemMessage(hWnd, IDC_ASK_SIZECOMBOBOX, CB_SELECTSTRING, -1, (LPARAM) buffer);
+
+ GetStringFromDatabase("BoldBegin", "[b]", oldBoldBegin, MAX_SIZE);
+ GetStringFromDatabase("BoldEnd", "[/b]", oldBoldEnd, MAX_SIZE);
+ sprintf(buffer, "%s | %s", oldBoldBegin, oldBoldEnd);
+ SendDlgItemMessage(hWnd, IDC_ASK_BOLDCOMBOBOX, CB_SELECTSTRING, -1, (LPARAM) buffer);
+
+ return TRUE;
+ break;
+
+ case WM_CLOSE:
+ DestroyWindow(hWnd);
+
+ break;
+
+ case WM_COMMAND:
+ switch (LOWORD(wParam))
+ {
+ case IDC_ASK_FORUMSTYLE:
+ EnableAskComboboxes(hWnd, IsDlgButtonChecked(hWnd, IDC_ASK_FORUMSTYLE));
+
+ break;
+
+ case IDC_ASK_CANCEL:
+ DestroyWindow(hWnd);
+
+ break;
+
+ case IDC_ASK_OK:
+ int debugTo = TO_DIALOGBOX; //just to be safe
+ int newFSFValue = IsDlgButtonChecked(hWnd, IDC_ASK_FORUMSTYLE);
+ char quoteBegin[MAX_SIZE], quoteEnd[MAX_SIZE];
+ char sizeBegin[MAX_SIZE], sizeEnd[MAX_SIZE];
+ char boldBegin[MAX_SIZE], boldEnd[MAX_SIZE];
+ char buffer[1024];
+
+ SendDlgItemMessage(hWnd, IDC_ASK_QUOTECOMBOBOX, WM_GETTEXT, sizeof(buffer), (LPARAM) buffer);
+ SplitStringInfo(buffer, quoteBegin, quoteEnd);
+ SendDlgItemMessage(hWnd, IDC_ASK_SIZECOMBOBOX, WM_GETTEXT, sizeof(buffer), (LPARAM) buffer);
+ SplitStringInfo(buffer, sizeBegin, sizeEnd);
+ SendDlgItemMessage(hWnd, IDC_ASK_BOLDCOMBOBOX, WM_GETTEXT, sizeof(buffer), (LPARAM) buffer);
+ SplitStringInfo(buffer, boldBegin, boldEnd);
+
+ if (newFSFValue != oldFSFValue)
+ {
+ DBWriteContactSettingByte(NULL, ModuleName, "ForumStyle", newFSFValue); //temporary store the new value
+ }
+ if (newFSFValue)
+ {
+ DBWriteContactSettingString(NULL, ModuleName, "QuoteBegin", quoteBegin);
+ DBWriteContactSettingString(NULL, ModuleName, "QuoteEnd", quoteEnd);
+
+ DBWriteContactSettingString(NULL, ModuleName, "SizeBegin", sizeBegin);
+ DBWriteContactSettingString(NULL, ModuleName, "SizeEnd", sizeEnd);
+
+ DBWriteContactSettingString(NULL, ModuleName, "BoldBegin", boldBegin);
+ DBWriteContactSettingString(NULL, ModuleName, "BoldEnd", boldEnd);
+ }
+
+ if (IsDlgButtonChecked(hWnd, IDC_ASK_TOFILE))
+ debugTo = TO_FILE;
+ if (IsDlgButtonChecked(hWnd, IDC_ASK_TOMESSAGEBOX))
+ debugTo = TO_MESSAGEBOX;
+ if (IsDlgButtonChecked(hWnd, IDC_ASK_TODIALOGBOX))
+ debugTo = TO_DIALOGBOX;
+ if (IsDlgButtonChecked(hWnd, IDC_ASK_TOOUTPUTDEBUGSTRING))
+ debugTo = TO_DEBUGSTRING;
+ if (IsDlgButtonChecked(hWnd, IDC_ASK_TOCLIPBOARD))
+ debugTo = TO_CLIPBOARD;
+ if (IsDlgButtonChecked(hWnd, IDC_ASK_TOUPLOAD))
+ debugTo = TO_UPLOAD;
+
+ DoDebugTo(debugTo);
+
+ if (newFSFValue != oldFSFValue)
+ {
+ DBWriteContactSettingByte(NULL, ModuleName, "ForumStyle", oldFSFValue);
+ }
+ if (newFSFValue)
+ {
+ DBWriteContactSettingString(NULL, ModuleName, "QuoteBegin", oldQuoteBegin);
+ DBWriteContactSettingString(NULL, ModuleName, "QuoteEnd", oldQuoteEnd);
+
+ DBWriteContactSettingString(NULL, ModuleName, "SizeBegin", oldSizeBegin);
+ DBWriteContactSettingString(NULL, ModuleName, "SizeEnd", oldSizeEnd);
+
+ DBWriteContactSettingString(NULL, ModuleName, "BoldBegin", oldBoldBegin);
+ DBWriteContactSettingString(NULL, ModuleName, "BoldEnd", oldBoldEnd);
+ }
+
+ DestroyWindow(hWnd);
+
+ break;
+ }
+
+ break;
+
+ default:
+
+ break;
+ }
+ return 0;
+}
+
+int DoDebugTo(int debugTo)
+{
+ HWND parent = NULL;
+ HWND askDialog;
+ CVersionInfo myInfo;// = CVersionInfo();
+ if (verbose) PUShowMessage("I am going to read the information.", SM_NOTIFY);
+ if (debugTo != TO_ASK)
+ {
+ myInfo.Initialize();
+ }
+ if (verbose) PUShowMessage("I have read the information, I will now print them.", SM_NOTIFY);
+
+ switch(debugTo) {
+ case TO_ASK:
+ askDialog = CreateDialog(hInst, MAKEINTRESOURCE(IDD_ASKDIALOG), parent, AskDlgProc);
+ ShowWindow(askDialog, SW_SHOW);
+
+ break;
+
+ case TO_FILE:
+ myInfo.PrintInformationsToFile();
+
+ break;
+
+ case TO_MESSAGEBOX:
+ myInfo.PrintInformationsToMessageBox();
+
+ break;
+
+ case TO_DIALOGBOX:
+ myInfo.PrintInformationsToDialogBox();
+
+ break;
+
+ case TO_DEBUGSTRING:
+ myInfo.PrintInformationsToOutputDebugString();
+
+ break;
+
+ case TO_CLIPBOARD:
+ myInfo.PrintInformationsToClipboard(true);
+
+ break;
+
+ case TO_UPLOAD:
+ myInfo.UploadToSite();
+
+ break;
+
+ default:
+ myInfo.PrintInformationsToFile();
+
+ break;
+
+ }
+ if ((debugTo != TO_CLIPBOARD) && (DBGetContactSettingByte(NULL, ModuleName, "ClipboardAlways", FALSE)))
+ {
+ myInfo.PrintInformationsToClipboard(false);
+ }
+
+ if ((bServiceMode) && (debugTo != TO_DIALOGBOX) && (debugTo != TO_ASK)) //close miranda if in service mode and no dialog was shown
+ {
+ PostQuitMessage(0);
+ }
+
+ return 0;
+}
+
+void EnableUploadSettings(HWND hWnd, int bEnable)
+{
+ EnableWindow(GetDlgItem(hWnd, IDC_UPLOAD_SERVER), bEnable);
+ EnableWindow(GetDlgItem(hWnd, IDC_UPLOAD_PORT), bEnable);
+ EnableWindow(GetDlgItem(hWnd, IDC_UPLOAD_USERNAME), bEnable);
+ EnableWindow(GetDlgItem(hWnd, IDC_UPLOAD_PASSWORD), bEnable);
+}
+
+INT_PTR CALLBACK DlgProcOpts(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ static int bOptionsInitializing = 0;
+ switch(msg) {
+ case WM_INITDIALOG:
+ {
+ bOptionsInitializing = 1;
+ TranslateDialogDefault(hWnd);
+ AddInfoToComboboxes(hWnd, IDC_QUOTECOMBOBOX, IDC_SIZECOMBOBOX, IDC_BOLDCOMBOBOX);
+
+ CheckDlgButton(hWnd, IDC_FORUMSTYLE, (BOOL) DBGetContactSettingByte(NULL, ModuleName, "ForumStyle", TRUE) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hWnd, IDC_DISABLEDTOO, (BOOL) DBGetContactSettingByte(NULL, ModuleName, "ShowInactive", TRUE) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hWnd, IDC_SHOWUUIDS, (BOOL) DBGetContactSettingByte(NULL, ModuleName, "ShowUUIDs", FALSE) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hWnd, IDC_SHOWINSTALLEDLANGUAGES, (BOOL) DBGetContactSettingByte(NULL, ModuleName, "ShowInstalledLanguages", FALSE) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hWnd, IDC_SUPPRESSHEADER, (BOOL) DBGetContactSettingByte(NULL, ModuleName, "SuppressHeader", TRUE) ? BST_CHECKED : BST_UNCHECKED);
+
+ CheckDlgButton(hWnd, IDC_SHOWINTASKBAR, (BOOL) DBGetContactSettingByte(NULL, ModuleName, "ShowInTaskbar", TRUE) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hWnd, IDC_CLIPBOARDALSO, (BOOL) DBGetContactSettingByte(NULL, ModuleName, "ClipboardAlways", FALSE) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hWnd, IDC_BOLDVERSION, (BOOL) DBGetContactSettingByte(NULL, ModuleName, "BoldVersionNumber", TRUE) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hWnd, IDC_CHECKUNLOADABLE, (BOOL) DBGetContactSettingByte(NULL, ModuleName, "CheckForDependencies", TRUE) ? BST_CHECKED : BST_UNCHECKED);
+ SetFocus(GetDlgItem(hWnd, IDC_FORUMSTYLE));
+ {
+ DBVARIANT dbv = { 0 };
+ dbv.type = DBVT_ASCIIZ;
+ bOptionsInitializing = 1;
+ char buffer[1024];
+ char notFound[1024];
+
+ if (DBGetContactSetting(NULL, ModuleName, "OutputFile", &dbv) == 0)
+ {
+ RelativePathToAbsolute(dbv.pszVal, notFound, sizeof(notFound));
+ }
+ else{
+ RelativePathToAbsolute("VersionInfo.txt", notFound, sizeof(notFound));
+ }
+
+ if (bFoldersAvailable)
+ {
+ //FoldersGetCustomPath(hOutputLocation, buffer, sizeof(buffer), "%miranda_path%");
+ //strcat(buffer, "\\VersionInfo.txt");
+ strcpy(buffer, TranslateTS("Customize using folders plugin"));
+ }
+ else{
+ strncpy(buffer, notFound, sizeof(notFound));
+ }
+
+ SetDlgItemText(hWnd, IDC_FILENAME, buffer);
+
+ char start[256], end[256];
+ GetStringFromDatabase("QuoteBegin", "[quote]", start, sizeof(start));
+ GetStringFromDatabase("QuoteEnd", "[/quote]", end, sizeof(end));
+ sprintf(buffer, "%s | %s", start, end);
+ SendDlgItemMessage(hWnd, IDC_QUOTECOMBOBOX, CB_SELECTSTRING, -1, (LPARAM) buffer);
+
+ GetStringFromDatabase("SizeBegin", "[size=1]", start, sizeof(start));
+ GetStringFromDatabase("SizeEnd", "[/size]", end, sizeof(end));
+ sprintf(buffer, "%s | %s", start, end);
+ SendDlgItemMessage(hWnd, IDC_SIZECOMBOBOX, CB_SELECTSTRING, -1, (LPARAM) buffer);
+
+ GetStringFromDatabase("BoldBegin", "[b]", start, sizeof(start));
+ GetStringFromDatabase("BoldEnd", "[/b]", end, sizeof(end));
+ sprintf(buffer, "%s | %s", start, end);
+ SendDlgItemMessage(hWnd, IDC_BOLDCOMBOBOX, CB_SELECTSTRING, -1, (LPARAM) buffer);
+ //to add stuff
+
+ //upload server settings
+ GetStringFromDatabase("UploadServer", "vi.cass.cz", buffer, sizeof(buffer));
+ SetWindowText(GetDlgItem(hWnd, IDC_UPLOAD_SERVER), buffer);
+
+ int port = DBGetContactSettingWord(NULL, ModuleName, "UploadPort", DEFAULT_UPLOAD_PORT);
+ _itoa(port, buffer, 10);
+ SetWindowText(GetDlgItem(hWnd, IDC_UPLOAD_PORT), buffer);
+
+ GetStringFromDatabase("UploadUser", "", buffer, sizeof(buffer));
+ SetWindowText(GetDlgItem(hWnd, IDC_UPLOAD_USERNAME), buffer);
+
+ GetStringFromDatabase("UploadPassword", "", buffer, sizeof(buffer));
+ CallService(MS_DB_CRYPT_DECODESTRING, sizeof(buffer), (LPARAM) buffer);
+ SetWindowText(GetDlgItem(hWnd, IDC_UPLOAD_PASSWORD), buffer);
+ }
+
+ switch(DBGetContactSettingByte(NULL, ModuleName, "DebugTo", TO_DIALOGBOX)) {
+ case TO_FILE:
+ CheckDlgButton(hWnd, IDC_TOFILE, BST_CHECKED);
+
+ break;
+
+ case TO_MESSAGEBOX:
+ CheckDlgButton(hWnd, IDC_TOMESSAGEBOX, BST_CHECKED);
+
+ break;
+
+ case TO_DIALOGBOX:
+ CheckDlgButton(hWnd, IDC_TODIALOGBOX, BST_CHECKED);
+
+ break;
+
+ case TO_DEBUGSTRING:
+ CheckDlgButton(hWnd, IDC_TODEBUGSTRING, BST_CHECKED);
+
+ break;
+
+ case TO_CLIPBOARD:
+ CheckDlgButton(hWnd, IDC_TOCLIPBOARD, BST_CHECKED);
+
+ break;
+
+ case TO_UPLOAD:
+ CheckDlgButton(hWnd, IDC_TOUPLOAD, BST_CHECKED);
+ break;
+
+ case TO_ASK:
+ CheckDlgButton(hWnd, IDC_ASKEVERYTIME, BST_CHECKED);
+
+ break;
+
+ default:
+ CheckDlgButton(hWnd, IDC_TODIALOGBOX, BST_CHECKED);
+
+ break;
+ }
+
+ EnableWindow(GetDlgItem(hWnd, IDC_QUOTECOMBOBOX), IsDlgButtonChecked(hWnd, IDC_FORUMSTYLE) ? TRUE : FALSE); //forum style only
+ EnableWindow(GetDlgItem(hWnd, IDC_SIZECOMBOBOX), IsDlgButtonChecked(hWnd, IDC_FORUMSTYLE) ? TRUE : FALSE); //forum style only
+ EnableWindow(GetDlgItem(hWnd, IDC_BOLDVERSION), IsDlgButtonChecked(hWnd, IDC_FORUMSTYLE) ? TRUE : FALSE); //forum style only
+ EnableWindow(GetDlgItem(hWnd, IDC_BOLDCOMBOBOX), (IsDlgButtonChecked(hWnd, IDC_BOLDVERSION) & IsDlgButtonChecked(hWnd, IDC_FORUMSTYLE)) ? TRUE : FALSE);//both forum style and bold version checked
+ EnableWindow(GetDlgItem(hWnd, IDC_SHOWINTASKBAR), IsDlgButtonChecked(hWnd, IDC_TODIALOGBOX) ? TRUE : FALSE); //only enable for to dialog box
+ EnableWindow(GetDlgItem(hWnd, IDC_DISABLEDTOO), IsDlgButtonChecked(hWnd, IDC_FORUMSTYLE) ? FALSE : TRUE); //if forum style disable show disabled plugins
+ EnableWindow(GetDlgItem(hWnd, IDC_CLIPBOARDALSO), IsDlgButtonChecked(hWnd, IDC_TOCLIPBOARD) ? FALSE : TRUE); //don't enable always clipboard if we're printing to clipboard
+ EnableWindow(GetDlgItem(hWnd, IDC_FILENAME), ((IsDlgButtonChecked(hWnd, IDC_TOFILE)) && (!bFoldersAvailable)) ? TRUE : FALSE);
+ EnableUploadSettings(hWnd, IsDlgButtonChecked(hWnd, IDC_TOUPLOAD) ? TRUE : FALSE);
+
+ OSVERSIONINFO osvi;
+ ZeroMemory(&osvi, sizeof(osvi));
+ osvi.dwOSVersionInfoSize = sizeof(osvi);
+ GetVersionEx(&osvi);
+
+ if (osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) {
+ EnableWindow(GetDlgItem(hWnd, IDC_CHECKUNLOADABLE), FALSE);
+ }
+
+ CheckDlgButton(hWnd, IDC_DEBUG, (BOOL) verbose == TRUE ? BST_CHECKED : BST_UNCHECKED);
+
+ SetFocus(GetDlgItem(hWnd, IDC_GETINFONOW));
+
+ bOptionsInitializing = 0;
+
+ break;
+ }
+
+ case WM_COMMAND:
+ switch(LOWORD(wParam)) {
+ case IDC_ASKEVERYTIME:
+ case IDC_TOFILE:
+ case IDC_TOMESSAGEBOX:
+ case IDC_TODIALOGBOX:
+ case IDC_TODEBUGSTRING:
+ case IDC_TOCLIPBOARD:
+ case IDC_TOUPLOAD:
+ case IDC_FORUMSTYLE:
+ case IDC_BOLDVERSION:
+ EnableWindow(GetDlgItem(hWnd, IDC_QUOTECOMBOBOX), IsDlgButtonChecked(hWnd, IDC_FORUMSTYLE) ? TRUE : FALSE); //forum style only
+ EnableWindow(GetDlgItem(hWnd, IDC_SIZECOMBOBOX), IsDlgButtonChecked(hWnd, IDC_FORUMSTYLE) ? TRUE : FALSE); //forum style only
+ EnableWindow(GetDlgItem(hWnd, IDC_BOLDVERSION), IsDlgButtonChecked(hWnd, IDC_FORUMSTYLE) ? TRUE : FALSE); //forum style only
+ EnableWindow(GetDlgItem(hWnd, IDC_BOLDCOMBOBOX), (IsDlgButtonChecked(hWnd, IDC_BOLDVERSION) & IsDlgButtonChecked(hWnd, IDC_FORUMSTYLE)) ? TRUE : FALSE); //both forum style and bold version checked
+ EnableWindow(GetDlgItem(hWnd, IDC_FILENAME), ((IsDlgButtonChecked(hWnd, IDC_TOFILE)) && (!bFoldersAvailable)) ? TRUE : FALSE);
+ EnableWindow(GetDlgItem(hWnd, IDC_SHOWINTASKBAR), IsDlgButtonChecked(hWnd, IDC_TODIALOGBOX) ? TRUE : FALSE); //only enable for to dialog box
+ EnableWindow(GetDlgItem(hWnd, IDC_DISABLEDTOO), IsDlgButtonChecked(hWnd, IDC_FORUMSTYLE) ? FALSE : TRUE); //if forum style disable show disabled plugins
+ EnableWindow(GetDlgItem(hWnd, IDC_CLIPBOARDALSO), IsDlgButtonChecked(hWnd, IDC_TOCLIPBOARD) ? FALSE : TRUE); //don't enable always clipboard if we're printing to clipboard
+ EnableUploadSettings(hWnd, IsDlgButtonChecked(hWnd, IDC_TOUPLOAD) ? TRUE : FALSE);
+
+ case IDC_SHOWUUIDS:
+ if (IsDlgButtonChecked(hWnd, IDC_SHOWUUIDS) && MessageBox(hWnd, Translate("Are you sure you want to enable this option ?\nPlease only enable this option if you really know what you're doing and what the option is for or if someone asked you to do it."), Translate("Show plugin UUIDs ?"), MB_YESNO | MB_ICONWARNING) == IDNO)
+ {
+ CheckDlgButton(hWnd, IDC_SHOWUUIDS, FALSE);
+
+ break;
+ }//else fallthrough
+ case IDC_DISABLEDTOO:
+ case IDC_SHOWINTASKBAR:
+ case IDC_CLIPBOARDALSO:
+ case IDC_CHECKUNLOADABLE:
+ case IDC_SUPPRESSHEADER:
+ case IDC_SHOWINSTALLEDLANGUAGES:
+ EnableWindow(GetDlgItem(hWnd, IDC_GETINFONOW), FALSE);
+
+ case IDC_QUOTECOMBOBOX:
+ case IDC_SIZECOMBOBOX:
+ case IDC_BOLDCOMBOBOX:
+ if (!bOptionsInitializing)
+ {
+ SendMessage(GetParent(hWnd), PSM_CHANGED,0,0);
+ }
+
+ break;
+
+ case IDC_FILENAME:
+ case IDC_UPLOAD_USERNAME:
+ case IDC_UPLOAD_PASSWORD:
+ case IDC_UPLOAD_PORT:
+ case IDC_UPLOAD_SERVER:
+ {
+ if ((HIWORD(wParam) == EN_CHANGE))// || (HIWORD(wParam) == CBN_SELENDOK)) //CBN_EDITCHANGE
+ {
+ if (!bOptionsInitializing)
+ {
+ SendMessage(GetParent(hWnd), PSM_CHANGED, 0, 0);
+ EnableWindow(GetDlgItem(hWnd, IDC_GETINFONOW), FALSE);
+ }
+ }
+
+ break;
+ }
+
+ case IDC_GETINFONOW:
+ //Call the plugin menu command routine.
+ PluginMenuCommand(0,0);
+
+ break;
+
+ case IDC_DEBUG:
+ verbose = !verbose;
+
+ break;
+ }
+
+ break;
+
+ case WM_NOTIFY:
+ switch(((LPNMHDR)lParam)->idFrom)
+ {
+ case 0:
+ switch (((LPNMHDR)lParam)->code)
+ {
+ case PSN_APPLY:
+ {
+ {
+ char buffer[1024];
+ char start[256], end[256];
+ SendDlgItemMessage(hWnd, IDC_QUOTECOMBOBOX, WM_GETTEXT, sizeof(buffer), (LPARAM) buffer);
+ SplitStringInfo(buffer, start, end);
+ DBWriteContactSettingString(NULL, ModuleName, "QuoteBegin", start);
+ DBWriteContactSettingString(NULL, ModuleName, "QuoteEnd", end);
+ SendDlgItemMessage(hWnd, IDC_SIZECOMBOBOX, WM_GETTEXT, sizeof(buffer), (LPARAM) buffer);
+ SplitStringInfo(buffer, start, end);
+ DBWriteContactSettingString(NULL, ModuleName, "SizeBegin", start);
+ DBWriteContactSettingString(NULL, ModuleName, "SizeEnd", end);
+ SendDlgItemMessage(hWnd, IDC_BOLDCOMBOBOX, WM_GETTEXT, sizeof(buffer), (LPARAM) buffer);
+ SplitStringInfo(buffer, start, end);
+ DBWriteContactSettingString(NULL, ModuleName, "BoldBegin", start);
+ DBWriteContactSettingString(NULL, ModuleName, "BoldEnd", end);
+
+ /*//upload server settings
+ SendDlgItemMessage(hWnd, IDC_UPLOAD_SERVER, WM_GETTEXT, sizeof(buffer), (LPARAM) buffer);
+ DBWriteContactSettingString(NULL, ModuleName, "UploadServer", buffer);
+
+ SendDlgItemMessage(hWnd, IDC_UPLOAD_PORT, WM_GETTEXT, sizeof(buffer), (LPARAM) buffer);
+ int port = atoi(buffer);
+ DBWriteContactSettingWord(NULL, ModuleName, "UploadPort", port);
+
+ SendDlgItemMessage(hWnd, IDC_UPLOAD_USERNAME, WM_GETTEXT, sizeof(buffer), (LPARAM) buffer);
+ DBWriteContactSettingString(NULL, ModuleName, "UploadUser", buffer);
+
+ SendDlgItemMessage(hWnd, IDC_UPLOAD_PASSWORD, WM_GETTEXT, sizeof(buffer), (LPARAM) buffer);
+ CallService(MS_DB_CRYPT_ENCODESTRING, sizeof(buffer), (LPARAM) buffer);
+ DBWriteContactSettingString(NULL, ModuleName, "UploadPassword", buffer);*/
+ }
+ DBWriteContactSettingByte(NULL, ModuleName, "CheckForDependencies", IsDlgButtonChecked(hWnd, IDC_CHECKUNLOADABLE) ? TRUE : FALSE);
+ DBWriteContactSettingByte(NULL, ModuleName, "BoldVersionNumber", IsDlgButtonChecked(hWnd, IDC_BOLDVERSION) ? TRUE : FALSE);
+ DBWriteContactSettingByte(NULL, ModuleName, "ForumStyle", IsDlgButtonChecked(hWnd, IDC_FORUMSTYLE) ? TRUE : FALSE);
+ DBWriteContactSettingByte(NULL, ModuleName, "ClipboardAlways", IsDlgButtonChecked(hWnd, IDC_CLIPBOARDALSO) ? TRUE : FALSE);
+ DBWriteContactSettingByte(NULL, ModuleName, "SuppressHeader", IsDlgButtonChecked(hWnd, IDC_SUPPRESSHEADER) ? TRUE : FALSE);
+ DBWriteContactSettingByte(NULL, ModuleName, "ShowUUIDs", IsDlgButtonChecked(hWnd, IDC_SHOWUUIDS) ? TRUE : FALSE);
+ DBWriteContactSettingByte(NULL, ModuleName, "ShowInstalledLanguages", IsDlgButtonChecked(hWnd, IDC_SHOWINSTALLEDLANGUAGES) ? TRUE : FALSE);
+
+ char fileName[MAX_PATH]; //absolute
+ char filePath[MAX_PATH]; //relative
+ if (!bFoldersAvailable)
+ {
+ GetDlgItemText(hWnd, IDC_FILENAME, fileName, MAX_PATH);
+ AbsolutePathToRelative(fileName, filePath, sizeof(filePath));
+
+ DBWriteContactSettingString(NULL, ModuleName, "OutputFile", filePath); //store relative path
+ }
+ DBWriteContactSettingByte(NULL, ModuleName, "ShowInTaskbar", IsDlgButtonChecked(hWnd, IDC_SHOWINTASKBAR) ? TRUE : FALSE);
+ //Debug to:
+ if (IsDlgButtonChecked(hWnd, IDC_TOFILE))
+ DBWriteContactSettingByte(NULL, ModuleName, "DebugTo", TO_FILE);
+ else if (IsDlgButtonChecked(hWnd, IDC_TOMESSAGEBOX))
+ DBWriteContactSettingByte(NULL, ModuleName, "DebugTo", TO_MESSAGEBOX);
+ else if (IsDlgButtonChecked(hWnd, IDC_TODIALOGBOX))
+ DBWriteContactSettingByte(NULL, ModuleName, "DebugTo", TO_DIALOGBOX);
+ else if (IsDlgButtonChecked(hWnd, IDC_TODEBUGSTRING))
+ DBWriteContactSettingByte(NULL, ModuleName, "DebugTo", TO_DEBUGSTRING);
+ else if (IsDlgButtonChecked(hWnd, IDC_TOCLIPBOARD))
+ DBWriteContactSettingByte(NULL, ModuleName, "DebugTo", TO_CLIPBOARD);
+ else if (IsDlgButtonChecked(hWnd, IDC_TOUPLOAD))
+ DBWriteContactSettingByte(NULL, ModuleName, "DebugTo", TO_UPLOAD);
+ else if (IsDlgButtonChecked(hWnd, IDC_ASKEVERYTIME))
+ DBWriteContactSettingByte(NULL, ModuleName, "DebugTo", TO_ASK);
+
+ EnableWindow(GetDlgItem(hWnd, IDC_GETINFONOW), TRUE);
+ //Disabled plugins too?
+ DBWriteContactSettingByte(NULL, ModuleName, "ShowInactive", IsDlgButtonChecked(hWnd, IDC_DISABLEDTOO)?TRUE:FALSE);
+
+ GetStringFromDatabase("UUIDCharMark", DEF_UUID_CHARMARK, PLUGIN_UUID_MARK, cPLUGIN_UUID_MARK);
+ }
+ }
+ }
+
+ break;
+
+ default:
+
+ break;
+ }
+ return 0;
+}
+
+INT_PTR CALLBACK DialogBoxProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
+ static CVersionInfo *myInfo = NULL;
+ switch(msg) {
+ case WM_INITDIALOG:
+ SendMessage(hWnd, WM_SETICON, ICON_BIG, (LPARAM) hiVIIcon);
+
+ myInfo = (CVersionInfo *) lParam;
+ if (DBGetContactSettingByte(NULL, ModuleName, "ShowInTaskbar", TRUE))
+ {
+ DWORD ws;
+ ws = GetWindowLong(hWnd, GWL_EXSTYLE);
+ SetWindowLong(hWnd, GWL_EXSTYLE, ws | WS_EX_APPWINDOW);
+ //SetWindowLong(hWnd, GWL_STYLE, ws | WS_DLGFRAME | WS_POPUPWINDOW);
+ }
+
+ TranslateDialogDefault(hWnd);
+ {
+ DBVARIANT dbv = { 0 };
+ LOGFONT lf = { 0 };
+
+ dbv.type = DBVT_BLOB;
+ if (DBGetContactSetting(NULL, "OptionFont", "Font", &dbv) == 0) {
+ lf=*(LOGFONT*)dbv.pbVal;
+ }
+ else {
+ HFONT hFont;
+ hFont=(HFONT)SendDlgItemMessage(hWnd,IDC_CLOSE,WM_GETFONT,0,0);
+ GetObject(hFont,sizeof(lf),&lf);
+ }
+ SendDlgItemMessage(hWnd,IDC_TEXT,WM_SETFONT,(WPARAM)CreateFontIndirect(&lf),0);
+ }
+
+ return TRUE;
+
+ case WM_CLOSE:
+ DestroyWindow(hWnd);
+
+ break;
+
+ case WM_COMMAND: {
+ switch(LOWORD(wParam)) {
+ case IDC_CLOSE:
+ DestroyWindow(hWnd);
+
+ break;
+
+ case IDC_COPYTEXT:
+ SetLastError(0);
+ if (GetOpenClipboardWindow()) {
+ Log(Translate("The clipboard is not available, retry."));
+ }
+ else {
+ OpenClipboard(hWnd);
+ //Ok, let's begin, then.
+ EmptyClipboard();
+ //Storage data we'll use.
+ char text[MAX_TEXT];
+ LPTSTR lptstrCopy;
+ GetDlgItemText(hWnd, IDC_TEXT, text, MAX_TEXT);
+ int length = lstrlen(text) + 1;
+ HANDLE hData = GlobalAlloc(GMEM_MOVEABLE, length + 5);
+ //Lock memory, copy it, release it.
+ lptstrCopy = (LPTSTR)GlobalLock(hData);
+ memmove(lptstrCopy, text, length);
+ lptstrCopy[length] = '\0';
+ GlobalUnlock(hData);
+ //Now set the clipboard data.
+ SetClipboardData(CF_TEXT, hData);
+ //Remove the lock on the clipboard.
+ CloseClipboard();
+ }
+
+ break;
+
+ case IDC_SAVETOFILE:
+ char text[MAX_TEXT];
+ GetDlgItemText(hWnd, IDC_TEXT, text, MAX_TEXT);
+
+ myInfo->PrintInformationsToFile(text);
+
+ break;
+
+ case IDC_UPLOAD:
+ if (myInfo)
+ {
+ char text[MAX_TEXT];
+ GetDlgItemText(hWnd, IDC_TEXT, text, MAX_TEXT);
+ myInfo->UploadToSite(text);
+ }
+
+ break;
+ }
+
+ break;
+ }
+ case WM_DESTROY:
+ DeleteObject((HFONT)SendDlgItemMessage(hWnd,IDC_TEXT,WM_GETFONT,0,0));
+ myInfo = NULL;
+ if (bServiceMode) //close miranda if in service mode
+ {
+ PostQuitMessage(0);
+ }
+
+ break;
+
+ default:
+
+ break;
+ }
+ return 0;
+} \ No newline at end of file
diff --git a/plugins/VersionInfo/dlgHandlers.h b/plugins/VersionInfo/dlgHandlers.h
new file mode 100644
index 0000000000..1c531c231a
--- /dev/null
+++ b/plugins/VersionInfo/dlgHandlers.h
@@ -0,0 +1,44 @@
+/*
+Version information plugin for Miranda IM
+
+Copyright © 2002-2006 Luca Santarelli, Cristian Libotean
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef M_VERSIONINFO_DLGHEADERS_H
+#define M_VERSIONINFO_DLGHEADERS_H
+
+#include "common.h"
+#include "resource.h"
+#include "CVersionInfo.h"
+
+#define TO_ASK 0
+#define TO_FILE 1
+#define TO_MESSAGEBOX 2
+#define TO_DIALOGBOX 3
+#define TO_DEBUGSTRING 4
+#define TO_CLIPBOARD 5
+#define TO_UPLOAD 6
+
+extern INT_PTR PluginMenuCommand(WPARAM, LPARAM);
+extern INT_PTR OptionsInitialise(WPARAM, LPARAM);
+
+
+int DoDebugTo(int debugTo);
+INT_PTR CALLBACK AskDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
+INT_PTR CALLBACK DlgProcOpts(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
+INT_PTR CALLBACK DialogBoxProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
+#endif \ No newline at end of file
diff --git a/plugins/VersionInfo/docs/Pack files/files_release.txt b/plugins/VersionInfo/docs/Pack files/files_release.txt
new file mode 100644
index 0000000000..f70bd504e3
--- /dev/null
+++ b/plugins/VersionInfo/docs/Pack files/files_release.txt
@@ -0,0 +1 @@
+..\win32\Release\svc_vi.dll \ No newline at end of file
diff --git a/plugins/VersionInfo/docs/Pack files/files_releasex64.txt b/plugins/VersionInfo/docs/Pack files/files_releasex64.txt
new file mode 100644
index 0000000000..67f2eb50a6
--- /dev/null
+++ b/plugins/VersionInfo/docs/Pack files/files_releasex64.txt
@@ -0,0 +1 @@
+..\x64\Release\svc_vi.dll \ No newline at end of file
diff --git a/plugins/VersionInfo/docs/Pack files/files_source.txt b/plugins/VersionInfo/docs/Pack files/files_source.txt
new file mode 100644
index 0000000000..ec3390726a
--- /dev/null
+++ b/plugins/VersionInfo/docs/Pack files/files_source.txt
@@ -0,0 +1,4 @@
+..\docs\pack files\*.*
+..\docs\*.*
+..\*.*
+..\sdk\*.* \ No newline at end of file
diff --git a/plugins/VersionInfo/docs/Pack files/files_source_ignore.txt b/plugins/VersionInfo/docs/Pack files/files_source_ignore.txt
new file mode 100644
index 0000000000..fcc9f161ac
--- /dev/null
+++ b/plugins/VersionInfo/docs/Pack files/files_source_ignore.txt
@@ -0,0 +1,4 @@
+pack files\*.*
+..\~backup\*.*
+..\Debug\*.*
+..\Release\*.* \ No newline at end of file
diff --git a/plugins/VersionInfo/docs/pack source.bat b/plugins/VersionInfo/docs/pack source.bat
new file mode 100644
index 0000000000..0906f97cb9
--- /dev/null
+++ b/plugins/VersionInfo/docs/pack source.bat
@@ -0,0 +1,8 @@
+for /F "tokens=3-7* delims=. " %%i in (readme_versioninfo.txt) do (call :Pack %%i %%j %%k %%l; exit)
+
+:Pack
+d:\usr\PowerArchiver\pacl\pacomp.exe -p -a -c2 "VersionInfo src %1.%2.%3.%4.zip" @"pack files\files_source.txt" -x*.zip -x*.ncb -x*.user
+exit
+
+error:
+echo "Error packing Versioninfo"
diff --git a/plugins/VersionInfo/docs/pack symbols.bat b/plugins/VersionInfo/docs/pack symbols.bat
new file mode 100644
index 0000000000..73c4fe8efe
--- /dev/null
+++ b/plugins/VersionInfo/docs/pack symbols.bat
@@ -0,0 +1,9 @@
+@echo off
+if NOT EXIST "symbols\%1 - %3" (
+ mkdir "symbols\%1 - %3"
+)
+xcopy "..\%2\win32\Release\*.pdb" "symbols\%1 - %3\win32\*" /EXCLUDE:symbols_exclude.txt /Y
+xcopy "..\%2\x64\Release\*.pdb" "symbols\%1 - %3\x64\*" /EXCLUDE:symbols_exclude.txt /Y
+
+d:\usr\PowerArchiver\pacl\pacomp.exe -p -a -r -c2 "symbols - %1.zip" "symbols\*.*"
+rmdir "symbols\" /Q /S \ No newline at end of file
diff --git a/plugins/VersionInfo/docs/pack x64.bat b/plugins/VersionInfo/docs/pack x64.bat
new file mode 100644
index 0000000000..ae61abb3d3
--- /dev/null
+++ b/plugins/VersionInfo/docs/pack x64.bat
@@ -0,0 +1,10 @@
+for /F "tokens=3-7* delims=. " %%i in (readme_versioninfo.txt) do (call :Pack %%i %%j %%k %%l; exit)
+
+:Pack
+d:\usr\PowerArchiver\pacl\pacomp.exe -a -c2 "VersionInfo %1.%2.%3.%4 x64.zip" @"Pack files\files_releasex64.txt"
+d:\usr\PowerArchiver\pacl\pacomp.exe -p -a -c2 "VersionInfo %1.%2.%3.%4 x64.zip" ..\docs\*.txt ..\*.caca -xsymbols_exclude.txt
+call "pack symbols.bat" VersionInfo "" %1.%2.%3.%4
+exit
+
+error:
+echo "Error packing Versioninfo"
diff --git a/plugins/VersionInfo/docs/pack.bat b/plugins/VersionInfo/docs/pack.bat
new file mode 100644
index 0000000000..4366326474
--- /dev/null
+++ b/plugins/VersionInfo/docs/pack.bat
@@ -0,0 +1,10 @@
+for /F "tokens=3-7* delims=. " %%i in (readme_versioninfo.txt) do (call :Pack %%i %%j %%k %%l; exit)
+
+:Pack
+d:\usr\PowerArchiver\pacl\pacomp.exe -a -c2 "VersionInfo %1.%2.%3.%4 x32.zip" @"Pack files\files_release.txt"
+d:\usr\PowerArchiver\pacl\pacomp.exe -p -a -c2 "VersionInfo %1.%2.%3.%4 x32.zip" ..\docs\*.txt ..\*.caca -xsymbols_exclude.txt
+call "pack symbols.bat" VersionInfo "" %1.%2.%3.%4
+exit
+
+error:
+echo "Error packing Versioninfo"
diff --git a/plugins/VersionInfo/docs/readme_versioninfo.txt b/plugins/VersionInfo/docs/readme_versioninfo.txt
new file mode 100644
index 0000000000..8a7d49fe7a
--- /dev/null
+++ b/plugins/VersionInfo/docs/readme_versioninfo.txt
@@ -0,0 +1,433 @@
+VersionInfo, v.1.4.3.4
+ by Luca "Hrk" Santarelli, Cristian Libotean
+ hrk@users.sf.net, eblis102@yahoo.com
+ Thanks go to: StormLord, Cyreve, Strickz, Wintime98
+ All of them helped me somehow.
+
+- INFO -
+
+Hi :-)
+
+This plugin is born from a feature request on the Open Discussion forum.
+Its purpose is to display some informations related to Miranda and to the OS
+so that you can copy/paste them in a bug report.
+
+Remember: submitting a bug report DOES NOT mean that it will be fixed.
+You need to check the bug report because developers may need your cooperation,
+testing debug builds or making other tests.
+
+The displayed informations are:
+§ Date/Time of report
+§ System cpu type
+§ OS name and version (major, minor, build, additional data)
+§ Installed RAM
+§ Miranda version, being it or not a nightly and/or unicode.
+§ List of enabled plugins (filename, short name, version and last modified date)
+§ List of disabled plugins (filename, short name, version and last modified date). Optional.
+
+
+- USE -
+
+!!! For bugs and/or suggestions please email me, eblis102@yahoo.com (please don't spam hrk as
+he's not working on this anymore).
+
+Click on the button in the main menu or the one in the options... and you're done.
+You can choose where to debug: text file, message box (no copy/paste), dialog
+box (copy/paste), OutputDebugString(), Clipboard directly. You can also check to print
+to clipboard while printing to any of the other options (except clipboard, of course :) )
+
+
+- CHANGES -
+
++ : new feature
+* : changed
+! : bufgix
+- : feature removed or disabled because of pending bugs
+
+v. 1.4.3.4 - 2009/11/13
+ + x64 support (not tested !!)
+
+v.1.4.3.3 - 2008/02/15
+ ! Plugins that do not have the extension .dll will not be listed anymore
+
+v.1.4.3.2 - 2008/01/31
+ * Report plugins without UUIDs in Miranda 0.8 #9 or later as Unloadable instead of Inactive
+
+v.1.4.3.1 - 2008/01/30
+ * When in service mode enable showing of disabled plugins if 'forum style formatting' is disabled, regardless if the option to show disabled plugins in the options is checked or not.
+ ! Ignore case when checking dll name.
+
+v.1.4.3.0 - 2008/01/29
+ * Show messages using a popup if a popup plugin is available
+ + Added service mode functionality - requires miranda 0.8 #9 or later.
+ WARNING: Please rename the plugin back to svc_vi.dll if you're using Updater to update your plugins.
+
+v.1.4.2.7 - 2008/01/25
+ ! Fixed crash when displaying information for unloadable plugins
+
+v.1.4.2.6 - 2008/01/24
+ * Changed beta versions server.
+
+v.1.4.2.5 - 2007/10/24
+ + Added profile path to VersionInfo report.
+
+v.1.4.2.4 - 2007/09/26
+ * Show warning message when user tries to activate 'Show plugin UUIDs' option.
+
+v.1.4.2.3 - 2007/07/25
+ ! Fixed time zone offset calculation.
+ ! Fixed negative time zones display.
+
+v.1.4.2.2 - 2007/07/24
+ + Added time zone information for profile creation date and language pack modified date.
+
+v.1.4.2.1 - 2007/06/22
+ * Show menu item is always checked (to disable use the menu editor).
+ * Enabled unicode flag since plugin is 2in1.
+
+v.1.4.2.0 - 2007/06/22
+ * Show UUIDs checkbox is now visible only when 'show expert options' is checked.
+ * Added checkbox to enable/disable showing installed languages - visible only when 'show expert options' is checked.
+
+v.1.4.1.5 - 2007/06/21
+ * Removed installed languages info from report (still available using the hidden setting 'ShowInstalledLanguages')
+
+v 1.4.1.4 - 2007/05/11
+ ! Show more than 2g of memory if available.
+
+v. 1.4.1.3 - 2007/03/27
+ * Fix for database plugins returning non standard profile path (dbxSA).
+
+v. 1.4.1.2 - 2007/03/22
+ ! Fix Unicode plugin detection.
+
+v. 1.4.1.1 - 2007/03/07
+ + Added icon to output dialog window.
+ * Make 'Customize using folders plugin' translatable.
+
+v. 1.4.1.0 - 2007/03/07
+ * Changed plugin UUID ( {2f174488-489c-4fe1-940d-596cf0f35e65} ).
+ + Added VERSIONINFO interface.
+
+v. 1.4.0.4 - 2007/03/06
+ + Option to show UUID info.
+ + Added VI UUID.
+ + Added hidden setting to change the character shown if plugin has a UUID defined (UUIDCharMark).
+ ! Do not enable Apply when first entering the options.
+
+v. 1.4.0.3 - 2007/02/12
+ + Read plugin Unicode aware flag. Only shown if plugin name doesn't contain 'unicode' or '2in1'.
+
+v. 1.4.0.2 - 2007/01/31
+ * Changed beta URL.
+
+v. 1.4.0.1 - 2007/01/28
+ + Added InternetExplorer version
+
+v. 1.4.0.0 - 2007/01/28
+ + Added Windows shell information.
+ ! Fix for profile creation date and size on Windows 98
+
+v. 1.3.2.2 - 2007/01/07
+ + New version resource file.
+ + Added OS languages info: {User UI language/}System UI language | Current user locale/System locale [available system languages]. User UI language is not available for Windows 95, 98, Me and NT.
+ + Folders support.
+ ! Close thread handle.
+
+v. 1.3.2.1 - 2006/12/07
+ * Changed controls tab order.
+
+v. 1.3.2.0 - 2006/11/26
+ * Reorganised the post a bit.
+ + Added empty blockquote style.
+ ! Fixed <u><b> version number highlighting.
+ + Added dll version info.
+
+v. 1.3.1.1 - 2006/11/15
+ * "Ask every time", not "Ask everytime" :)
+ + Added administrator privileges information.
+ + Added "Save to file" button to dialog.
+ * Disabled the "Upload" button.
+
+v. 1.3.1.0 - 2006/11/1
+ + Added multiple CPUs info.
+ + Added WOW64 info.
+ ! Don't get plugin information twice.
+ * Moved main menu entry near Help.
+ * Default output location changed to dialog.
+
+v. 1.3.0.4 - 2006/10/16
+ * Made langpack retrieval more robust.
+ + Show langpack info.
+ * No more dependency on winsock2 (removed upload feature for now, support isn't available anyway)
+
+v. 1.3.0.1 - 2006/09/25
+ + Updater support (beta versions)
+ ! Enable the Apply button when combobox items are changed.
+ + Added quote, size and bold comboboxes to ask dialog.
+ * Sections now use the same highlighting method as the plugins.
+ * Changed text displayed when plugins don't want to load with current Miranda version.
+
+v. 1.3.0.0 - 2006/08/08
+ * Use relative paths. The file path in the options will show as absolute but it's saved in the database as relative - uses the services in m_utils.h.
+ + New versioninfo icon - thanks Faith Healer.
+ + Option to automatically upload VI post to vi.cass.cz :) - currently there's no support on the site for it
+ + Show plugins that fail to load for unknown reasons.
+ * Use mir_snprintf where possible.
+ + Added checkbox for forum style formatting in ask dialog.
+ * Changed plugin section to "Services"
+
+v. 1.2.0.4 - 2006/07/26
+ * 'Attempt to find unloadable plugins' is checked by default now and is grayed out on Win 98.
+ + Added check for Windows 2003 R2.
+
+v. 1.2.0.3 - 2006/06/01
+ + Added a service to get the VersionInfo post as a string.
+
+v. 1.2.0.2 - 2006/05/20
+ ! Fixed a bug when notifing of errors - thanks for the patch Peter (UnregistereD).
+
+v. 1.2.0.1 - 2006/05/17
+ * People reported they don't have PF_NX_ENABLED defined so i created a workaround for those who want to build VI from sources.
+ ! Destroy services the proper way.
+
+v. 1.2.0.0 - 2006/05/01
+ + Added DEP information.
+ * Show message if CPU doesn't recognize cpuid extension.
+
+v. 1.0.1.19 - 2006/03/23
+ ! Fixed "Do it now" being disabled when first entering the options window.
+
+v. 1.0.1.18 - 2006/03/09
+ + Added a new size option for phpBB forums.
+ + Added a new highlight option (bold and underline).
+ + Added a new option to suppress header and footer information - will make the post a bit smaller.
+ ! Fixed a bug when information was copied to clipboard.
+
+v. 1.0.1.17 - 2006/01/01
+ + Added check to find out plugin information for plugins that refuse to load.
+ ! Fixed a new line issue (happened when Unloadable plugins entry was visible).
+
+v. 1.0.1.16 - 2006/01/31
+ * Removed the static edge from the dialog buttons.
+ + Added check for plugins that refuse to load.
+ * Updated the translation strings.
+
+v. 1.0.1.15 - 2005/10/17
+ + Added some hidden beautification settings. You need to use dbeditor to add these settings to
+ VersionInfo. All settings are strings and they should either be bbcodes or html codes. (do a default
+ output for an example). Check the changes in version 1.0.1.14 to see how you can activate this output.
+ ~ BeautifyHorizLine - code for a horizontal line
+ (default: <hr />)
+ ~ BeautifyBlockStart - code for a blockquote (start code) that separates the hw and miranda settings from the plugins
+ (default: <blockquote>)
+ ~ BeautifyBlockEnd - code for a blockquote (end code) that separates the hw and miranda settings from the plugins
+ (default: </blockquote>)
+ ~ BeautifyActiveHeaderBegin - code for the font and size of the active header text (start code)
+ (default: <b><font size="-1" color="DarkGreen">)
+ ~ BeautifyActiveHeaderEnd - code for the font and size of the active header text (end code)
+ (default: </font></b>)
+ ~ BeautifyInactiveHeaderBegin - code for the font and size of the inactive header text (start code)
+ (default: <b><font size="-1" color="DarkRed">)
+ ~ BeautifyInactiveHeaderEnd - code for the font and size of the inactive header text (end code)
+ (default: </font></b>)
+ ~ BeautifyUnloadableHeaderBegin - code for the font and size of the unloadable header text (start code)
+ (default: <b><font size="-1"><font color="Red">)
+ ~ BeautifyUnloadableHeaderEnd - code for the font and size of the unloadable header text (end code)
+ (default: </font></b>)
+ ~ BeautifyPluginsBegin - code for the font and size of plugins (start code)
+ (default: <font size="-2" color="black">)
+ ~ BeautifyPluginsEnd - code for the font and size of plugins (end code)
+ (default: </font>)
+ How it works:
+ $starting info [Miranda IM ... Miranda's homepage ... Miranda tools]
+ {Horizontal line}{block start}Report generated at: $date
+ $hardware, os and miranda settings
+ {block end}{horizontal line}{active header start}Active Plugins (#):{active header end}
+ {plugins start}
+ $plugins
+ {plugins end}{horizontal line}{inactive header start}Inactive Plugins (#):{inactive header end}
+ {plugins start}
+ $plugins
+ {plugins end}{horizontal line}{unloadable header start}Unloadable Plugins (#):{unloadable header end}
+ {plugins start}
+ $plugins
+ {plugins end}{horizontal line}
+ $end info [End of report ...]
+
+v. 1.0.1.14 - 2005/10/16
+ - Removed the logging functions used when attempting to find an unloadable plugin.
+ + Added hidden option to beautify the output. You need to use dbeditor and add a new
+ byte value to VersionInfo called Beautify and set it to 1 for the setting to take effect.
+ Forum style formatting must be OFF; although forum style is unchecked it will get the
+ highlighting information from the appropriate checkbox so be sure to set it
+ accordingly (usually to <b /> or <u />. The formatting is hardcoded at the moment
+ (it's set to html tags), i might add some strings in the database for it later on.
+ + Added option to select how to highlight version number; currently you can
+ select from bold or underline.
+
+v. 1.0.1.13 - 2005/10/14
+ + Added option to ask where to print the output.
+
+v. 1.0.1.12 - 2005/10/06
+ * Changed the way versioninfo scans for enabled/disabled plugins.
+ Now it should be able to detect even plugin that were reported as inactive before (like aim toc2 and clist_nicerW+)
+ + Added profile size and creation date.
+ + Added information about missing statically linked dll files. Use with care, might crash miranda on some systems.
+ This function might not work (correctly) on windows 98 and below. If you check this option a file named
+ 'versioninfo.log' will appear in miranda's folder; in case of a crash please post this info in the forums
+ (thread Plugins->Versioninfo format style) using [code][/code] bbcodes.
+
+v. 1.0.1.11 - 2005/09/24
+ + Added option to print version number in bold or not.
+ + Added [code] bbcode and empty size field (if the forum doesn't strip other bbcodes from inside a [code])
+
+v. 1.0.1.10 - 2005/09/25
+ ! Fixed issue that prevented the apply button to be enabled when changing the filename.
+ + Added options to select forum bbcodes.
+
+v. 1.0.1.9 - 2005/09/22 :)
+ + Added a new CPU check. Might be unstable and can't detect very old processors (like pentium mmx)
+ * Changed hidden settings strings to QuoteBegin, QuoteEnd, SizeBegin, SizeEnd.
+ ! Fixed updater issue - older versions should be detected as well (thanks sje). Plugin should
+ comply with updater rules from now on.
+
+v. 1.0.1.8 - 2005/09/22
+ * Changed month number to month short name (english locale)
+ + Added "hidden" settings for 'quote' and 'size' strings (only valid when using forum style formatting).
+ You need to use dbeditor++ to add these.
+ "QuoteHeader" - String value containing the starting quote string.
+ You can use this if you want to change the "[quote]" string to "[code]" for example.
+ If the setting is not present it reverts to "[quote]"
+ "SizeHeader" - String value containing the starting size string.
+ You should use this if the forum software doesn't recognize "[size=1]" and needs
+ something like "[size=1px]". If the setting is not present it reverts to "[size=1]".
+ "QuoteFooter" - String value containing the ending quote string. If the setting is not present it reverts to "[/quote]"
+ "SizeFooter" - String value containing the ending size string. If the setting is not present it reverts to "[/size]"
+ !If you change the header for one of these don't forget to change the footer as well (and vice versa).
+ + When using forum style formatting the version number will be bold.
+ + Added active and inactive plugins count (it can't hurt :) )
+
+v. 1.0.1.7 - 2005/09/21
+ ! Fixed double enter issue
+ ! Fixed unicode detection problem
+
+
+1.0.1.6 - 2005/09/11
+ * Changed miranda's homepage from 'http://miranda-icq.sourceforge.net/' to 'miranda-im.org'
+ * Changed miranda tools link.
+ * Changed some strings (date and time related).
+ + Added check for unicode core.
+ + Added miranda path to versioninfo output.
+ + Added plugin's last modified date to versioninfo output.
+ + Added plugin's short name to versioninfo output.
+ + Added os check for windows 2003.
+ + Added option to show information window in taskbar
+ + Added option to always copy to clipboard
+ + Added CPU info
+ Should still work with amd 64 (unsure)
+
+1.0.1.5 * Works on AMD64 now.
+ * Fixed some typos in the text and URLs.
+ * Changed some default settings.
+
+1.0.1.4 * Fixed the crashes when a .dll file was found but was not a plugin.
+ * Filesize somehow increased to 80KB... don't ask me why.
+ + Added support for MirandaInstaller/Wassup by Tornado.
+
+1.0.1.3 * No change at all, but it now works for everyone. Don't ask me how.
+
+1.0.1.2 * Fixed NT detection.
+ * Fixed click on X button in dialogbox.
+
+1.0.1.1 * Changed the option page UI to reflect Miranda's one and to have a
+ more intuitive usage.
+ * Size has increased, but there's not anymore the need for that
+ external DLL. :-)
+
+1.0.1.0 + Added "DialogBox" as output (Cyreve, Stormlord, myself)
+ + Added "OutputDebugString()" as output
+ + Added "Clipboard" as output
+ + Added the missing button in the options
+ + Added a cool icon
+ + Added OS name (Wintime98, myself)
+ + Added Miranda build time (Wintime98)
+ + Added free disk space on Miranda partition (Stormlord, myself)
+ * Changed "Debug to:" to "Output to:" because of its meaning
+
+1.0.0.0 First release.
+ DialogBox is not yet selectable.
+ Developers, read the REBASE information.
+
+
+- TRANSLATION -
+
+The strings you can translate are these:
+
+for version 1.4.2.4
+;Plugin description:
+;[Collects and prints information related to Miranda, the plugins and the OS.]
+;
+;Option dialog
+;[Plugins]
+;[Version Information]
+;[Output to:]
+;[Text file]
+;[MessageBox()]
+;[DialogBox]
+;[Show window in taskbar]
+;[OutputDebugString()]
+;[Clipboard]
+;[Upload to site]
+;[Ask every time]
+;[Also copy info to clipboard]
+;[Forum style formatting]
+;[Highlight version number using]
+;[Show disabled plugins too]
+;[Show plugin UUIDs]
+;[Attempt to find unloadable plugins (doesn't work on Windows 98)]
+;[Suppress header information]
+;[Add a menu item to the main Miranda Menu]
+;[You will need to restart Miranda to add/remove the menu item.]
+;[Do it now]
+;[Upload site settings]
+;[Username]
+;[Password]
+;[Customize using folders plugin]
+;[Are you sure you want to enable this option ?\nPlease only enable this option if you really know what you're doing and what the option is for or if someone asked you to do it.]
+;[Show plugin UUIDs ?]
+;
+;Dialog box
+;[Upload]
+;[Close]
+;[Copy text]
+;
+;Miscellanea
+;[If you are going to use this report to submit a bug, remember to check the website for questions or help the developers may need.\r\nIf you don't check your bug report and give feedback, it will not be fixed!]
+;[Information successfully written to file: \"%s\".]
+;[Error during the creation of file \"%s\". Disk may be full or write protected.]
+
+;[Ok, something went wrong in the \"%s\" setting. Report back the following values:\nFacility: %X\nError code: %X\nLine number: %d]
+
+;[The clipboard is not available, retry.]
+;[Information successfully copied into clipboard.]
+;[Miranda Version Information]
+
+- DISCLAIMER -
+
+This plugin works just fine on my machine, it should work just fine on yours
+without conflicting with other plugins. Should you have any trouble, write me
+at hrk@users.sf.net where "sf" must be changed to "sourceforge".
+Anyway, if you are a smart programmer, give a look at the code and tell me
+the changes you'd make. If I like them, I'll put them inside. :-)
+
+This plugin is released under the GPL license, I'm too lazy to copy it, though.
+Anyway, if you do have Miranda (and you should, otherwise this plugin is
+pretty useless) you already have a file called GPL.txt with tis license.
+Being GPLed you are free to modify or change the source code (you can find it
+here: http://nortiq.com/miranda/ and look for the source section) but you
+cannot sell it.
+As I already wrote: if you do modify it, notify me, I don't see a good reason
+not to share the improvements with the Miranda community. :-)
+
+Yes, I have made a quite long disclaimer, I can save the file now. :-)
diff --git a/plugins/VersionInfo/docs/rebase_versioninfo.txt b/plugins/VersionInfo/docs/rebase_versioninfo.txt
new file mode 100644
index 0000000000..fd71ab0526
--- /dev/null
+++ b/plugins/VersionInfo/docs/rebase_versioninfo.txt
@@ -0,0 +1,33 @@
+=§= TO PLUGIN DEVELOPERS =§=
+
+This plugin has its Base Address set to:
+0x25040000
+
+Please, avoid using this BaseAddress for your plugins: using the same addresses
+will slow Miranda.
+Read "pluginguidelines.txt" under miranda0100/miranda32/doc/ in the CVS.
+
+This Base Address is built this way:
+
+0x25 040000
+^^^^ ^^^^^^
+My radix Incremental value related to my plugins.
+
+Range for base address is 0x10000000 to 0x50000000, so 0x25040000 fits well there.
+
+040000 is an incremental value which represents VersionInfo.
+[Note: 000000 is used for RePosition, 010000 for NewStatusNotify, 030000 for PicPlugin and so on.]
+
+Why do I call 0x25 "My radix"?
+
+HRK = H + R + K
+H = 8th letter in the english alphabet.
+R = 18th letter in the english alphabet.
+K = 11th letter in the english alphabet.
+
+8 + 18 + 11 = 37.
+37(dec) = 25(Hex)
+
+Base Address can be found/configured:
+§ MSVC++ 6.0
+ Project->Settings->Link->Output->Base Address \ No newline at end of file
diff --git a/plugins/VersionInfo/docs/symbols_exclude.txt b/plugins/VersionInfo/docs/symbols_exclude.txt
new file mode 100644
index 0000000000..361cf2448b
--- /dev/null
+++ b/plugins/VersionInfo/docs/symbols_exclude.txt
@@ -0,0 +1 @@
+vc80.pdb \ No newline at end of file
diff --git a/plugins/VersionInfo/docs/versioninfo.gif b/plugins/VersionInfo/docs/versioninfo.gif
new file mode 100644
index 0000000000..a0e1f8eadb
--- /dev/null
+++ b/plugins/VersionInfo/docs/versioninfo.gif
Binary files differ
diff --git a/plugins/VersionInfo/hooked_events.cpp b/plugins/VersionInfo/hooked_events.cpp
new file mode 100644
index 0000000000..b87fa355df
--- /dev/null
+++ b/plugins/VersionInfo/hooked_events.cpp
@@ -0,0 +1,97 @@
+/*
+Version information plugin for Miranda IM
+
+Copyright © 2002-2006 Luca Santarelli, Cristian Libotean
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "hooked_events.h"
+
+HANDLE hModulesLoaded;
+HANDLE hOptionsInitialize;
+
+const int nExpertOnlyControls = 10;
+UINT uiExpertOnlyControls[nExpertOnlyControls] = {0};
+
+#define HOST "http://eblis.tla.ro/projects"
+
+#define VERSIONINFO_VERSION_URL HOST "/miranda/VersionInfo/updater/VersionInfo.html"
+#define VERSIONINFO_UPDATE_URL HOST "/miranda/VersionInfo/updater/VersionInfo.zip"
+#define VERSIONINFO_VERSION_PREFIX "Version Information version "
+
+int HookEvents()
+{
+ hModulesLoaded = HookEvent(ME_SYSTEM_MODULESLOADED, OnModulesLoaded);
+ hOptionsInitialize = HookEvent(ME_OPT_INITIALISE, OnOptionsInitialise);
+ //hPreShutdown = HookEvent(ME_SYSTEM_PRESHUTDOWN, OnPreShutdown);
+
+ return 0;
+}
+
+int UnhookEvents()
+{
+ UnhookEvent(hModulesLoaded);
+ UnhookEvent(hOptionsInitialize);
+
+ return 0;
+}
+
+int OnModulesLoaded(WPARAM wParam, LPARAM lParam)
+{
+ char buffer[1024];
+ Update update = {0};
+ update.cbSize = sizeof(Update);
+ update.szComponentName = __PLUGIN_DISPLAY_NAME;
+ update.pbVersion = (BYTE *) CreateVersionString(VERSION, buffer);
+ update.cpbVersion = (int) strlen((char *) update.pbVersion);
+ update.szUpdateURL = UPDATER_AUTOREGISTER;
+ update.szBetaVersionURL = VERSIONINFO_VERSION_URL;
+ update.szBetaUpdateURL = VERSIONINFO_UPDATE_URL;
+ update.pbBetaVersionPrefix = (BYTE *) VERSIONINFO_VERSION_PREFIX;
+ update.cpbBetaVersionPrefix = (int) strlen(VERSIONINFO_VERSION_PREFIX);
+ CallService(MS_UPDATE_REGISTER, 0, (LPARAM) &update);
+
+ bFoldersAvailable = ServiceExists(MS_FOLDERS_REGISTER_PATH);
+ hOutputLocation = FoldersRegisterCustomPath("VersionInfo", "Output folder", "%miranda_path%");
+
+ GetStringFromDatabase("UUIDCharMark", DEF_UUID_CHARMARK, PLUGIN_UUID_MARK, cPLUGIN_UUID_MARK);
+
+ return 0;
+}
+
+int OnOptionsInitialise(WPARAM wParam, LPARAM lParam)
+{
+ OPTIONSDIALOGPAGE odp = { 0 };
+
+ uiExpertOnlyControls[0] = IDC_SHOWUUIDS;
+ uiExpertOnlyControls[1] = IDC_SHOWINSTALLEDLANGUAGES;
+
+ odp.cbSize = sizeof(odp);
+ odp.position = 100000000;
+ odp.hInstance = hInst;
+ odp.pszTemplate = MAKEINTRESOURCE(IDD_OPT_VERSIONINFO);
+ odp.pszTitle = Translate("Version Information");
+ odp.pszGroup = Translate("Services");
+ odp.groupPosition = 910000000;
+ odp.flags=ODPF_BOLDGROUPS;
+ odp.pfnDlgProc = DlgProcOpts;
+ odp.expertOnlyControls = uiExpertOnlyControls;
+ odp.nExpertOnlyControls = 2;
+
+ CallService(MS_OPT_ADDPAGE,wParam,(LPARAM)&odp);
+
+ return 0;
+} \ No newline at end of file
diff --git a/plugins/VersionInfo/hooked_events.h b/plugins/VersionInfo/hooked_events.h
new file mode 100644
index 0000000000..3c972fe014
--- /dev/null
+++ b/plugins/VersionInfo/hooked_events.h
@@ -0,0 +1,35 @@
+/*
+Version information plugin for Miranda IM
+
+Copyright © 2002-2006 Luca Santarelli, Cristian Libotean
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef M_VERSIONINFO_HOOKED_EVENTS_H
+#define M_VERSIONINFO_HOOKED_EVENTS_H
+
+#include "common.h"
+
+extern HANDLE hModulesLoaded;
+extern HANDLE hOptionsInitialise;
+
+int HookEvents();
+int UnhookEvents();
+
+int OnModulesLoaded(WPARAM wParam, LPARAM lParam);
+int OnOptionsInitialise(WPARAM wParam, LPARAM lParam);
+
+#endif \ No newline at end of file
diff --git a/plugins/VersionInfo/m_versioninfo.h b/plugins/VersionInfo/m_versioninfo.h
new file mode 100644
index 0000000000..3c5ffddcc0
--- /dev/null
+++ b/plugins/VersionInfo/m_versioninfo.h
@@ -0,0 +1,48 @@
+/*
+Version information plugin for Miranda IM
+
+Copyright © 2002-2006 Luca Santarelli, Cristian Libotean
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef M_VERSIONINFO_H
+#define M_VERSIONINFO_H
+
+/*Brings up the versioninfo post as configured in the options
+wParam - not used
+lParam - not used
+*/
+#define MS_VERSIONINFO_MENU_COMMAND "VersionInfo/MenuCommand"
+
+/*Returns a string containing the versioninfo post
+wParam - (BOOL) suppress forum style formatting. If true the post won't have forum style formatting even if the option is checked in miranda's options.
+lParam - (char **) Pointer to a string that receives the info. Memory is allocated using miranda's version of malloc() and you need to use miranda's version of free() on it.
+Returns 0 on success.
+
+how to use:
+{
+//...
+ char *data;
+ if (GetInfoService(TRUE, (LPARAM) &data) == 0)
+ {//success
+ }
+ return 0;
+}
+
+*/
+#define MS_VERSIONINFO_GETINFO "Versioninfo/GetInfo"
+
+#endif //M_VERSIONINFO_H
diff --git a/plugins/VersionInfo/main.cpp b/plugins/VersionInfo/main.cpp
new file mode 100644
index 0000000000..13784e8c03
--- /dev/null
+++ b/plugins/VersionInfo/main.cpp
@@ -0,0 +1,175 @@
+/*
+Version information plugin for Miranda IM
+
+Copyright © 2002-2006 Luca Santarelli, Cristian Libotean
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#define STRICT
+#define WIN32_LEAN_AND_MEAN
+
+#define _CRT_SECURE_NO_DEPRECATE
+
+#include "common.h"
+
+#include "CVersionInfo.h"
+
+HINSTANCE hInst;
+PLUGINLINK *pluginLink;
+
+HICON hiVIIcon;
+
+DWORD EnglishLocale;
+
+BOOL bFoldersAvailable = FALSE;
+HANDLE hOutputLocation = NULL; //for folders plugin
+
+void * (* MirandaMalloc)(size_t);
+void * (* MirandaRealloc)(void *, size_t);
+void (* MirandaFree)(void *);
+
+char ModuleName[] = "VersionInfo";
+
+#ifdef _DEBUG
+ BOOL verbose = FALSE;//TRUE;
+#else
+ BOOL verbose = FALSE;
+#endif
+
+PLUGININFOEX pluginInfo={
+ sizeof(PLUGININFOEX),
+ __PLUGIN_DISPLAY_NAME,
+ VERSION,
+ __DESC,
+ __AUTHOR,
+ __AUTHOREMAIL,
+ __COPYRIGHT,
+ __AUTHORWEB,
+ 1, //not transient
+ 0,
+ {0x2f174488, 0x489c, 0x4fe1, {0x94, 0x0d, 0x59, 0x6c, 0xf0, 0xf3, 0x5e, 0x65}} //{2f174488-489c-4fe1-940d-596cf0f35e65}
+};
+
+OLD_MIRANDAPLUGININFO_SUPPORT;
+
+static const MUUID interfaces[] = {MIID_VERSIONINFO, MIID_SERVICEMODE, MIID_LAST};
+
+extern "C" __declspec(dllexport) const MUUID *MirandaPluginInterfaces()
+{
+ return interfaces;
+}
+
+bool WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)
+{
+ LogToFileInit();
+ LogToFile("Entering %s", __FUNCTION__);
+ hInst=hinstDLL;
+ if (fdwReason == DLL_PROCESS_ATTACH) DisableThreadLibraryCalls(hinstDLL);
+ EnglishLocale = MAKELCID(MAKELANGID(0x09, 0x01), SORT_DEFAULT); //create our english locale and use it everywhere it's needed
+ LogToFile("Leaving %s", __FUNCTION__);
+ return TRUE;
+}
+
+extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion)
+{
+ LogToFile("Entering %s", __FUNCTION__);
+ LogToFile("Leaving %s", __FUNCTION__);
+ return &pluginInfo;
+}
+
+extern "C" int __declspec(dllexport) Load(PLUGINLINK *link)
+{
+ LogToFile("Entering %s", __FUNCTION__);
+ pluginLink=link;
+
+ LogToFile("Initialising services ...");
+ InitServices();
+ LogToFile("Hooking events ...");
+ HookEvents();
+
+ hiVIIcon = LoadIcon(hInst,MAKEINTRESOURCE(IDI_MAIN));
+
+ //get the name of the dll itself
+ char filePath[512] = {0};
+ GetModuleFileName(hInst, filePath, sizeof(filePath));
+ char *fileName = NULL;
+ size_t i = strlen(filePath) - 1;
+ _strlwr(filePath);
+
+ //check that the name begins with svc_
+ while ((i > 0) && (filePath[i] != '\\')) { i--; }
+ if (i > 0)
+ {
+ filePath[i] = 0;
+ fileName = filePath + i + 1;
+
+ if (strstr(fileName, "svc_") != fileName)
+ {
+ char buffer[1024];
+ mir_snprintf(buffer, sizeof(buffer), "Please rename the plugin '%s' to 'svc_vi.dll' to enable service mode functionality.", fileName);
+ MessageBox(NULL, TranslateTS(buffer), Translate("Version Information"), MB_OK | MB_ICONEXCLAMATION);
+ }
+ }
+
+ //Menu item
+ //if (DBGetContactSettingByte(NULL, ModuleName, "MenuItem", TRUE)) {
+ {
+ LogToFile("creating menu item ...");
+ CLISTMENUITEM mi = { 0 };
+
+ mi.cbSize = sizeof(mi);
+ mi.position = mi.popupPosition = 2000089999;
+ mi.flags = 0;
+ mi.hIcon = hiVIIcon;
+ mi.pszName = Translate("Version Information");
+ mi.pszService = MS_VERSIONINFO_MENU_COMMAND;
+ CallService(MS_CLIST_ADDMAINMENUITEM,0,(LPARAM)&mi);
+// mi.pszPopupName = "Version Information";
+// mi.popupPosition = 2;
+// mi.pszName = "Test 1";
+// CallService(MS_CLIST_ADDMAINMENUITEM, 0, (LPARAM) &mi);
+ }
+ LogToFile("Check riched32.dll ...");
+ if (LoadLibrary("RichEd32.dll") == NULL) {
+ MessageBox(NULL, "d'oh", "d'oh", MB_OK);
+ }
+
+ //get miranda's malloc, realloc and free functions
+ LogToFile("Get miranda memory functions ...");
+ MM_INTERFACE mmInterface;
+ mmInterface.cbSize = sizeof(MM_INTERFACE);
+ CallService(MS_SYSTEM_GET_MMI, 0, (LPARAM) &mmInterface);
+ MirandaFree = mmInterface.mmi_free;
+ MirandaMalloc = mmInterface.mmi_malloc;
+ MirandaRealloc = mmInterface.mmi_realloc;
+
+ LogToFile("Leaving %s", __FUNCTION__);
+ return 0;
+}
+
+extern "C" int __declspec(dllexport) Unload(void)
+{
+ LogToFile("Entering %s", __FUNCTION__);
+
+ LogToFile("Unhooking events ...");
+ UnhookEvents();
+
+ LogToFile("Destroying services ...");
+ DestroyServices();
+
+ LogToFile("Leaving %s", __FUNCTION__);
+ return 0;
+} \ No newline at end of file
diff --git a/plugins/VersionInfo/resource.h b/plugins/VersionInfo/resource.h
new file mode 100644
index 0000000000..b282e8bca6
--- /dev/null
+++ b/plugins/VersionInfo/resource.h
@@ -0,0 +1,71 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by resource.rc
+//
+#define IDD_DIALOG1 101
+#define IDD_OPT_VERSIONINFO 102
+#define IDD_DIALOGBOX 103
+#define IDD_DIALOGINFO 103
+#define IDI_ICON1 104
+#define IDI_MAIN 104
+#define IDD_ASKDIALOG 106
+#define IDC_MENUITEM 1000
+#define IDC_TOFILE 1001
+#define IDC_TOMESSAGEBOX 1002
+#define IDC_TODIALOGBOX 1003
+#define IDC_DISABLEDTOO 1004
+#define IDC_FILENAME 1005
+#define IDC_TEXT 1006
+#define IDC_TODEBUGSTRING 1006
+#define IDC_CLOSE 1007
+#define IDC_TOCLIPBOARD 1007
+#define IDC_GETINFONOW 1009
+#define IDC_TOUPLOAD 1010
+#define IDC_GETINFONOW2 1011
+#define IDC_COPYTEXT 1012
+#define IDC_DEBUG 1013
+#define IDC_FORUMSTYLE 1014
+#define IDC_CLIPBOARDALSO 1015
+#define IDC_SHOWINTASKBAR 1016
+#define IDC_QUOTECOMBOBOX 1017
+#define IDC_SIZECOMBOBOX 1018
+#define IDC_BOLDVERSION 1020
+#define IDC_CHECKUNLOADABLE 1021
+#define IDC_ASKEVERYTIME 1022
+#define IDC_ASK_TOFILE 1023
+#define IDC_ASK_TOMESSAGEBOX 1024
+#define IDC_ASK_TODIALOGBOX 1025
+#define IDC_ASK_TOOUTPUTDEBUGSTRING 1026
+#define IDC_ASK_TOCLIPBOARD 1027
+#define IDC_ASK_CANCEL 1028
+#define IDC_ASK_OK 1029
+#define IDC_BOLDCOMBOBOX 1030
+#define IDC_SUPPRESSHEADER 1031
+#define IDC_SHOWHARDWAREINFO 1033
+#define IDC_UPLOAD 1034
+#define IDC_ASK_UPLOAD 1036
+#define IDC_ASK_TOUPLOAD 1036
+#define IDC_UPLOAD_SERVER 1038
+#define IDC_UPLOAD_PORT 1039
+#define IDC_UPLOAD_USERNAME 1040
+#define IDC_UPLOAD_PASSWORD 1041
+#define IDC_TEMPORARY_FORUMSTYLE 1042
+#define IDC_ASK_FORUMSTYLE 1042
+#define IDC_ASK_QUOTECOMBOBOX 1043
+#define IDC_ASK_SIZECOMBOBOX 1044
+#define IDC_ASK_BOLDCOMBOBOX 1045
+#define IDC_SAVETOFILE 1046
+#define IDC_SHOWUUIDS 1048
+#define IDC_CHECK1 1049
+#define IDC_SHOWINSTALLEDLANGUAGES 1049
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 107
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1050
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/plugins/VersionInfo/resource.rc b/plugins/VersionInfo/resource.rc
new file mode 100644
index 0000000000..b4a8eb819a
--- /dev/null
+++ b/plugins/VersionInfo/resource.rc
@@ -0,0 +1,225 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_ASKDIALOG DIALOGEX 0, 0, 231, 146
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Output to:"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ DEFPUSHBUTTON "OK",IDC_ASK_OK,63,125,50,14
+ PUSHBUTTON "Cancel",IDC_ASK_CANCEL,117,125,50,14
+ CONTROL "Text file",IDC_ASK_TOFILE,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,15,17,206,10
+ CONTROL "MessageBox()",IDC_ASK_TOMESSAGEBOX,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,15,27,206,10
+ CONTROL "DialogBox",IDC_ASK_TODIALOGBOX,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,15,37,206,10
+ CONTROL "OutputDebugString()",IDC_ASK_TOOUTPUTDEBUGSTRING,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,15,47,206,10
+ CONTROL "Clipboard",IDC_ASK_TOCLIPBOARD,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,15,57,206,10
+ GROUPBOX "Select output:",IDC_STATIC,7,7,217,72
+ CONTROL "Upload to site",IDC_ASK_TOUPLOAD,"Button",BS_AUTORADIOBUTTON | WS_DISABLED | WS_TABSTOP,15,67,206,10
+ CONTROL "Forum style formatting",IDC_ASK_FORUMSTYLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,92,206,9
+ GROUPBOX "Aditional options:",IDC_STATIC,7,81,217,39
+ COMBOBOX IDC_ASK_QUOTECOMBOBOX,15,104,75,50,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ COMBOBOX IDC_ASK_SIZECOMBOBOX,93,104,71,48,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ COMBOBOX IDC_ASK_BOLDCOMBOBOX,167,104,54,47,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+ IDD_ASKDIALOG, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 224
+ VERTGUIDE, 15
+ VERTGUIDE, 221
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 139
+ HORZGUIDE, 116
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Italian (Italy) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ITA)
+#ifdef _WIN32
+LANGUAGE LANG_ITALIAN, SUBLANG_ITALIAN
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_OPT_VERSIONINFO DIALOGEX 0, 0, 315, 222
+STYLE DS_SETFONT | DS_MODALFRAME | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_VISIBLE
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+ PUSHBUTTON "Do it now",IDC_GETINFONOW,265,4,48,13
+ GROUPBOX "Output to:",IDC_STATIC,5,4,197,130
+ CONTROL "Text file",IDC_TOFILE,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,12,16,186,10
+ EDITTEXT IDC_FILENAME,24,26,150,14,ES_AUTOHSCROLL
+ CONTROL "MessageBox()",IDC_TOMESSAGEBOX,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,12,40,186,10
+ CONTROL "DialogBox",IDC_TODIALOGBOX,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,12,51,186,10
+ CONTROL "Show window in taskbar",IDC_SHOWINTASKBAR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,21,62,177,10
+ CONTROL "OutputDebugString()",IDC_TODEBUGSTRING,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,12,73,186,10
+ CONTROL "Clipboard",IDC_TOCLIPBOARD,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,12,84,186,10
+ CONTROL "Upload to site",IDC_TOUPLOAD,"Button",BS_AUTORADIOBUTTON | WS_DISABLED | WS_TABSTOP,12,95,186,10
+ CONTROL "Ask every time",IDC_ASKEVERYTIME,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,12,106,186,10
+ CONTROL "Also copy info to clipboard",IDC_CLIPBOARDALSO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,121,186,10
+ GROUPBOX "Upload site settings",IDC_STATIC,205,74,108,60
+ EDITTEXT IDC_UPLOAD_SERVER,209,83,71,14,ES_AUTOHSCROLL | WS_DISABLED
+ EDITTEXT IDC_UPLOAD_PORT,281,83,27,14,ES_AUTOHSCROLL | WS_DISABLED
+ LTEXT "Username",IDC_STATIC,209,103,42,8
+ EDITTEXT IDC_UPLOAD_USERNAME,253,99,55,14,ES_AUTOHSCROLL | WS_DISABLED
+ LTEXT "Password",IDC_STATIC,209,118,43,8
+ EDITTEXT IDC_UPLOAD_PASSWORD,253,115,55,14,ES_PASSWORD | ES_AUTOHSCROLL | WS_DISABLED
+ CONTROL "Forum style formatting",IDC_FORUMSTYLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,139,149,10
+ COMBOBOX IDC_QUOTECOMBOBOX,159,137,75,58,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ COMBOBOX IDC_SIZECOMBOBOX,238,137,75,58,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ CONTROL "Highlight version number using",IDC_BOLDVERSION,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,153,216,10
+ COMBOBOX IDC_BOLDCOMBOBOX,252,153,61,37,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ CONTROL "Show disabled plugins too",IDC_DISABLEDTOO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,164,232,10
+ CONTROL "Attempt to find unloadable plugins (doesn't work on Windows 98)",IDC_CHECKUNLOADABLE,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,174,272,10
+ CONTROL "Suppress header information",IDC_SUPPRESSHEADER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,184,274,10
+ CONTROL "Enable debug messages",IDC_DEBUG,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_DISABLED | WS_TABSTOP,220,207,93,10
+ CONTROL "Show plugin UUIDs",IDC_SHOWUUIDS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,195,272,10
+ CONTROL "Show installed languages",IDC_SHOWINSTALLEDLANGUAGES,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,206,273,10
+END
+
+IDD_DIALOGINFO DIALOGEX 0, 0, 373, 217
+STYLE DS_LOCALEDIT | DS_SETFONT | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+EXSTYLE WS_EX_TOOLWINDOW | WS_EX_CONTROLPARENT
+CAPTION "Miranda Version Information"
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+ CONTROL "",IDC_TEXT,"RICHEDIT",TCS_HOTTRACK | TCS_FOCUSONBUTTONDOWN | TCS_MULTISELECT | WS_BORDER | WS_VSCROLL | WS_TABSTOP,7,7,298,203
+ PUSHBUTTON "Close",IDC_CLOSE,316,7,50,14
+ PUSHBUTTON "&Copy text",IDC_COPYTEXT,316,26,50,14
+ PUSHBUTTON "Upload",IDC_UPLOAD,316,196,50,14,WS_DISABLED
+ PUSHBUTTON "&Save to file",IDC_SAVETOFILE,316,45,50,14
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+ IDD_OPT_VERSIONINFO, DIALOG
+ BEGIN
+ LEFTMARGIN, 5
+ RIGHTMARGIN, 313
+ VERTGUIDE, 12
+ VERTGUIDE, 198
+ VERTGUIDE, 202
+ VERTGUIDE, 205
+ VERTGUIDE, 304
+ VERTGUIDE, 308
+ TOPMARGIN, 4
+ BOTTOMMARGIN, 217
+ HORZGUIDE, 149
+ END
+
+ IDD_DIALOGINFO, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 366
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 210
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_MAIN ICON "VersionInfo.ico"
+#endif // Italian (Italy) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/plugins/VersionInfo/sdk/m_folders.h b/plugins/VersionInfo/sdk/m_folders.h
new file mode 100644
index 0000000000..5971cff81a
--- /dev/null
+++ b/plugins/VersionInfo/sdk/m_folders.h
@@ -0,0 +1,284 @@
+/*
+Custom profile folders plugin for Miranda IM
+
+Copyright © 2005 Cristian Libotean
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef M_CUSTOM_FOLDERS_H
+#define M_CUSTOM_FOLDERS_H
+
+#define FOLDERS_API 501 //dunno why it's here but it is :)
+
+#define PROFILE_PATH "%profile_path%"
+#define CURRENT_PROFILE "%current_profile%"
+#define MIRANDA_PATH "%miranda_path%"
+#define PLUGINS_PATH "%miranda_path%" "\\plugins"
+#define MIRANDA_USERDATA "%miranda_userdata%"
+
+#define TO_WIDE(x) L ## x
+
+#define PROFILE_PATHW L"%profile_path%"
+#define CURRENT_PROFILEW L"%current_profile%"
+#define MIRANDA_PATHW L"%miranda_path%"
+#define MIRANDA_USERDATAW L"%miranda_userdata%"
+
+#define FOLDER_AVATARS PROFILE_PATH "\\" CURRENT_PROFILE "\\avatars"
+#define FOLDER_VCARDS PROFILE_PATH "\\" CURRENT_PROFILE "\\vcards"
+#define FOLDER_LOGS PROFILE_PATH "\\" CURRENT_PROFILE "\\logs"
+#define FOLDER_RECEIVED_FILES PROFILE_PATH "\\" CURRENT_PROFILE "\\received files"
+#define FOLDER_DOCS MIRANDA_PATH "\\" "docs"
+
+#define FOLDER_CONFIG PLUGINS_PATH "\\" "config"
+
+#define FOLDER_SCRIPTS MIRANDA_PATH "\\" "scripts"
+
+#define FOLDER_UPDATES MIRANDA_PATH "\\" "updates"
+
+#define FOLDER_CUSTOMIZE MIRANDA_PATH "\\" "customize"
+#define FOLDER_CUSTOMIZE_SOUNDS FOLDER_CUSTOMIZE "\\sounds"
+#define FOLDER_CUSTOMIZE_ICONS FOLDER_CUSTOMIZE "\\icons"
+#define FOLDER_CUSTOMIZE_SMILEYS FOLDER_CUSTOMIZE "\\smileys"
+#define FOLDER_CUSTOMIZE_SKINS FOLDER_CUSTOMIZE "\\skins"
+#define FOLDER_CUSTOMIZE_THEMES FOLDER_CUSTOMIZE "\\themes"
+
+
+#define FOLDERS_NAME_MAX_SIZE 64 //maximum name and section size
+
+#define FF_UNICODE 0x00000001
+
+#if defined (UNICODE)
+ #define FF_TCHAR FF_UNICODE
+#else
+ #define FF_TCHAR 0
+#endif
+
+typedef struct{
+ int cbSize; //size of struct
+ char szSection[FOLDERS_NAME_MAX_SIZE]; //section name, if it doesn't exist it will be created otherwise it will just add this entry to it
+ char szName[FOLDERS_NAME_MAX_SIZE]; //entry name - will be shown in options
+ union{
+ const char *szFormat; //default string format. Fallback string in case there's no entry in the database for this folder. This should be the initial value for the path, users will be able to change it later.
+ const wchar_t *szFormatW; //String is dup()'d so you can free it later. If you set the unicode string don't forget to set the flag accordingly.
+ const TCHAR *szFormatT;
+ };
+ DWORD flags; //FF_* flags
+} FOLDERSDATA;
+
+/*Folders/Register/Path service
+ wParam - not used, must be 0
+ lParam - (LPARAM) (const FOLDERDATA *) - Data structure filled with
+ the necessary information.
+ Returns a handle to the registered path or 0 on error.
+ You need to use this to call the other services.
+*/
+#define MS_FOLDERS_REGISTER_PATH "Folders/Register/Path"
+
+/*Folders/Get/PathSize service
+ wParam - (WPARAM) (int) - handle to registered path
+ lParam - (LPARAM) (int *) - pointer to the variable that receives the size of the path
+ string (not including the null character). Depending on the flags set when creating the path
+ it will either call strlen() or wcslen() to get the length of the string.
+ Returns the size of the buffer.
+*/
+#define MS_FOLDERS_GET_SIZE "Folders/Get/PathSize"
+
+typedef struct{
+ int cbSize;
+ int nMaxPathSize; //maximum size of buffer. This represents the number of characters that can be copied to it (so for unicode strings you don't send the number of bytes but the length of the string).
+ union{
+ char *szPath; //pointer to the buffer that receives the path without the last "\\"
+ wchar_t *szPathW; //unicode version of the buffer.
+ TCHAR *szPathT;
+ };
+} FOLDERSGETDATA;
+
+/*Folders/Get/Path service
+ wParam - (WPARAM) (int) - handle to registered path
+ lParam - (LPARAM) (FOLDERSGETDATA *) pointer to a FOLDERSGETDATA that has all the relevant fields filled.
+ Should return 0 on success, or nonzero otherwise.
+*/
+#define MS_FOLDERS_GET_PATH "Folders/Get/Path"
+
+typedef struct{
+ int cbSize;
+ union{
+ char **szPath; //address of a string variable (char *) or (wchar_t*) where the path should be stored (the last \ won't be copied).
+ wchar_t **szPathW; //unicode version of string.
+ TCHAR **szPathT;
+ };
+} FOLDERSGETALLOCDATA;
+
+/*Folders/GetRelativePath/Alloc service
+ wParam - (WPARAM) (int) - Handle to registered path
+ lParam - (LPARAM) (FOLDERSALLOCDATA *) data
+ This service is the same as MS_FOLDERS_GET_PATH with the difference that this service
+ allocates the needed space for the buffer. It uses miranda's memory functions for that and you need
+ to use those to free the resulting buffer.
+ Should return 0 on success, or nonzero otherwise. Currently it only returns 0.
+*/
+#define MS_FOLDERS_GET_PATH_ALLOC "Folders/Get/Path/Alloc"
+
+
+/*Folders/On/Path/Changed
+ wParam - (WPARAM) 0
+ lParam - (LPARAM) 0
+ Triggered when the folders change, you should reget the paths you registered.
+*/
+#define ME_FOLDERS_PATH_CHANGED "Folders/On/Path/Changed"
+
+#ifndef FOLDERS_NO_HELPER_FUNCTIONS
+
+#ifndef M_UTILS_H__
+#error The helper functions require that m_utils.h be included in the project. Please include that file if you want to use the helper functions. If you don''t want to use the functions just define FOLDERS_NO_HELPER_FUNCTIONS.
+#endif
+//#include "../../../include/newpluginapi.h"
+
+__inline static HANDLE FoldersRegisterCustomPath(const char *section, const char *name, const char *defaultPath)
+{
+ FOLDERSDATA fd = {0};
+ if (!ServiceExists(MS_FOLDERS_REGISTER_PATH)) return 0;
+ fd.cbSize = sizeof(FOLDERSDATA);
+ strncpy(fd.szSection, section, FOLDERS_NAME_MAX_SIZE);
+ fd.szSection[FOLDERS_NAME_MAX_SIZE - 1] = '\0';
+ strncpy(fd.szName, name, FOLDERS_NAME_MAX_SIZE);
+ fd.szName[FOLDERS_NAME_MAX_SIZE - 1] = '\0';
+ fd.szFormat = defaultPath;
+ return (HANDLE) CallService(MS_FOLDERS_REGISTER_PATH, 0, (LPARAM) &fd);
+}
+
+__inline static HANDLE FoldersRegisterCustomPathW(const char *section, const char *name, const wchar_t *defaultPathW)
+{
+ FOLDERSDATA fd = {0};
+ if (!ServiceExists(MS_FOLDERS_REGISTER_PATH)) return 0;
+ fd.cbSize = sizeof(FOLDERSDATA);
+ strncpy(fd.szSection, section, FOLDERS_NAME_MAX_SIZE);
+ fd.szSection[FOLDERS_NAME_MAX_SIZE - 1] = '\0'; //make sure it's NULL terminated
+ strncpy(fd.szName, name, FOLDERS_NAME_MAX_SIZE);
+ fd.szName[FOLDERS_NAME_MAX_SIZE - 1] = '\0'; //make sure it's NULL terminated
+ fd.szFormatW = defaultPathW;
+ fd.flags = FF_UNICODE;
+ return (HANDLE) CallService(MS_FOLDERS_REGISTER_PATH, 0, (LPARAM) &fd);
+}
+
+__inline static INT_PTR FoldersGetCustomPath(HANDLE hFolderEntry, char *path, const int size, const char *notFound)
+{
+ FOLDERSGETDATA fgd = {0};
+ INT_PTR res;
+ fgd.cbSize = sizeof(FOLDERSGETDATA);
+ fgd.nMaxPathSize = size;
+ fgd.szPath = path;
+ res = CallService(MS_FOLDERS_GET_PATH, (WPARAM) hFolderEntry, (LPARAM) &fgd);
+ if (res)
+ {
+ char buffer[MAX_PATH];
+ CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM) notFound, (LPARAM) buffer);
+ mir_snprintf(path, size, "%s", buffer);
+ }
+
+ return res;
+}
+
+__inline static INT_PTR FoldersGetCustomPathW(HANDLE hFolderEntry, wchar_t *pathW, const int count, const wchar_t *notFoundW)
+{
+ FOLDERSGETDATA fgd = {0};
+ INT_PTR res;
+ fgd.cbSize = sizeof(FOLDERSGETDATA);
+ fgd.nMaxPathSize = count;
+ fgd.szPathW = pathW;
+ res = CallService(MS_FOLDERS_GET_PATH, (WPARAM) hFolderEntry, (LPARAM) &fgd);
+ if (res)
+ {
+ wcsncpy(pathW, notFoundW, count);
+ pathW[count - 1] = '\0';
+ }
+
+ return res;
+}
+
+__inline static INT_PTR FoldersGetCustomPathEx(HANDLE hFolderEntry, char *path, const int size, char *notFound, char *fileName)
+{
+ FOLDERSGETDATA fgd = {0};
+ INT_PTR res;
+ fgd.cbSize = sizeof(FOLDERSGETDATA);
+ fgd.nMaxPathSize = size;
+ fgd.szPath = path;
+ res = CallService(MS_FOLDERS_GET_PATH, (WPARAM) hFolderEntry, (LPARAM) &fgd);
+ if (res)
+ {
+ char buffer[MAX_PATH];
+ CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM) notFound, (LPARAM) buffer);
+ mir_snprintf(path, size, "%s", buffer);
+ }
+ if (strlen(path) > 0)
+ {
+ strcat(path, "\\");
+ }
+ else{
+ path[0] = '\0';
+ }
+
+ if (fileName)
+ {
+ strcat(path, fileName);
+ }
+
+ return res;
+}
+
+__inline static INT_PTR FoldersGetCustomPathExW(HANDLE hFolderEntry, wchar_t *pathW, const int count, wchar_t *notFoundW, wchar_t *fileNameW)
+{
+ FOLDERSGETDATA fgd = {0};
+ INT_PTR res;
+ fgd.cbSize = sizeof(FOLDERSGETDATA);
+ fgd.nMaxPathSize = count;
+ fgd.szPathW = pathW;
+ res = CallService(MS_FOLDERS_GET_PATH, (WPARAM) hFolderEntry, (LPARAM) &fgd);
+ if (res)
+ {
+ wcsncpy(pathW, notFoundW, count);
+ pathW[count - 1] = '\0';
+ }
+
+ if (wcslen(pathW) > 0)
+ {
+ wcscat(pathW, L"\\");
+ }
+ else{
+ pathW[0] = L'\0';
+ }
+
+ if (fileNameW)
+ {
+ wcscat(pathW, fileNameW);
+ }
+
+ return res;
+}
+
+# ifdef _UNICODE
+# define FoldersGetCustomPathT FoldersGetCustomPathW
+# define FoldersGetCustomPathExT FoldersGetCustomPathExW
+# define FoldersRegisterCustomPathT FoldersRegisterCustomPathW
+#else
+# define FoldersGetCustomPathT FoldersGetCustomPath
+# define FoldersGetCustomPathExT FoldersGetCustomPath
+# define FoldersRegisterCustomPathT FoldersRegisterCustomPath
+#endif
+
+#endif
+
+#endif //M_CUSTOM_FOLDERS_H \ No newline at end of file
diff --git a/plugins/VersionInfo/sdk/m_updater.h b/plugins/VersionInfo/sdk/m_updater.h
new file mode 100644
index 0000000000..371b7437a0
--- /dev/null
+++ b/plugins/VersionInfo/sdk/m_updater.h
@@ -0,0 +1,146 @@
+#ifndef _M_UPDATER_H
+#define _M_UPDATER_H
+
+// NOTES:
+// - For langpack updates, include a string of the following format in the langpack text file:
+// ";FLID: <file listing name> <version>"
+// version must be four numbers seperated by '.', in the range 0-255 inclusive
+// - Updater will disable plugins that are downloaded but were not active prior to the update (this is so that, if an archive contains e.g. ansi and
+// unicode versions, the correct plugin will be the only one active after the new version is installed)...so if you add a support plugin, you may need
+// to install an ini file to make the plugin activate when miranda restarts after the update
+// - Updater will replace all dlls that have the same internal shortName as a downloaded update dll (this is so that msn1.dll and msn2.dll, for example,
+// will both be updated) - so if you have a unicode and a non-unicode version of a plugin in your archive, you should make the internal names different (which will break automatic
+// updates from the file listing if there is only one file listing entry for both versions, unless you use the 'MS_UPDATE_REGISTER' service below)
+// - Updater will install all files in the root of the archive into the plugins folder, except for langpack files that contain the FLID string which go into the root folder (same
+// folder as miranda32.exe)...all folders in the archive will also be copied to miranda's root folder, and their contents transferred into the new folders. The only exception is a
+// special folder called 'root_files' - if there is a folder by that name in the archive, it's contents will also be copied into miranda's root folder - this is intended to be used
+// to install additional dlls etc that a plugin may require)
+
+// if you set Update.szUpdateURL to the following value when registering, as well as setting your beta site and version data,
+// Updater will ignore szVersionURL and pbVersionPrefix, and attempt to find the file listing URL's from the backend XML data.
+// for this to work, the plugin name in pluginInfo.shortName must match the file listing exactly (except for case)
+#define UPDATER_AUTOREGISTER "UpdaterAUTOREGISTER"
+// Updater will also use the backend xml data if you provide URL's that reference the miranda file listing for updates (so you can use that method
+// if e.g. your plugin shortName does not match the file listing) - it will grab the file listing id from the end of these URLs
+
+typedef struct Update_tag {
+ int cbSize;
+ char *szComponentName; // component name as it will appear in the UI (will be translated before displaying)
+
+ char *szVersionURL; // URL where the current version can be found (NULL to disable)
+ BYTE *pbVersionPrefix; // bytes occuring in VersionURL before the version, used to locate the version information within the URL data
+ // (note that this URL could point at a binary file - dunno why, but it could :)
+ int cpbVersionPrefix; // number of bytes pointed to by pbVersionPrefix
+ char *szUpdateURL; // URL where dll/zip is located
+ // set to UPDATER_AUTOREGISTER if you want Updater to find the file listing URLs (ensure plugin shortName matches file listing!)
+
+ char *szBetaVersionURL; // URL where the beta version can be found (NULL to disable betas)
+ BYTE *pbBetaVersionPrefix; // bytes occuring in VersionURL before the version, used to locate the version information within the URL data
+ int cpbBetaVersionPrefix; // number of bytes pointed to by pbVersionPrefix
+ char *szBetaUpdateURL; // URL where dll/zip is located
+
+ BYTE *pbVersion; // bytes of current version, used for comparison with those in VersionURL
+ int cpbVersion; // number of bytes pointed to by pbVersion
+
+ char *szBetaChangelogURL; // url for displaying changelog for beta versions
+} Update;
+
+// register a comonent with Updater
+//
+// wparam = 0
+// lparam = (LPARAM)&Update
+#define MS_UPDATE_REGISTER "Update/Register"
+
+// utility functions to create a version string from a DWORD or from pluginInfo
+// point buf at a buffer at least 16 chars wide - but note the version string returned may be shorter
+//
+__inline static char *CreateVersionString(DWORD version, char *buf) {
+ mir_snprintf(buf, 16, "%d.%d.%d.%d", (version >> 24) & 0xFF, (version >> 16) & 0xFF, (version >> 8) & 0xFF, version & 0xFF);
+ return buf;
+}
+
+__inline static char *CreateVersionStringPlugin(PLUGININFO *pluginInfo, char *buf) {
+ return CreateVersionString(pluginInfo->version, buf);
+}
+
+
+// register the 'easy' way - use this method if you have no beta URL and the plugin is on the miranda file listing
+// NOTE: the plugin version string on the file listing must be the string version of the version in pluginInfo (i.e. 0.0.0.1,
+// four numbers between 0 and 255 inclusivem, so no letters, brackets, etc.)
+//
+// wParam = (int)fileID - this is the file ID from the file listing (i.e. the number at the end of the download link)
+// lParam = (PLUGININFO*)&pluginInfo
+#define MS_UPDATE_REGISTERFL "Update/RegisterFL"
+
+// this function can be used to 'unregister' components - useful for plugins that register non-plugin/langpack components and
+// may need to change those components on the fly
+// lParam = (char *)szComponentName
+#define MS_UPDATE_UNREGISTER "Update/Unregister"
+
+// this event is fired when the startup process is complete, but NOT if a restart is imminent
+// it is designed for status managment plugins to use as a trigger for beggining their own startup process
+// wParam = lParam = 0 (unused)
+// (added in version 0.1.6.0)
+#define ME_UPDATE_STARTUPDONE "Update/StartupDone"
+
+// this service can be used to enable/disable Updater's global status control
+// it can be called from the StartupDone event handler
+// wParam = (BOOL)enable
+// lParam = 0
+// (added in version 0.1.6.0)
+#define MS_UPDATE_ENABLESTATUSCONTROL "Update/EnableStatusControl"
+
+// An description of usage of the above service and event:
+// Say you are a status control plugin that normally sets protocol or global statuses in your ModulesLoaded event handler.
+// In order to make yourself 'Updater compatible', you would move the status control code from ModulesLoaded to another function,
+// say DoStartup. Then, in ModulesLoaded you would check for the existence of the MS_UPDATE_ENABLESTATUSCONTROL service.
+// If it does not exist, call DoStartup. If it does exist, hook the ME_UPDATE_STARTUPDONE event and call DoStartup from there. You may
+// also wish to call MS_UPDATE_ENABLESTATUSCONTROL with wParam == FALSE at this time, to disable Updater's own status control feature.
+
+// this service can be used to determine whether updates are possible for a component with the given name
+// wParam = 0
+// lParam = (char *)szComponentName
+// returns TRUE if updates are supported, FALSE otherwise
+#define MS_UPDATE_ISUPDATESUPPORTED "Update/IsUpdateSupported"
+
+#endif
+
+
+/////////////// Usage Example ///////////////
+
+#ifdef EXAMPLE_CODE
+
+// you need to #include "m_updater.h" and HookEvent(ME_SYSTEM_MODULESLOADED, OnModulesLoaded) in your Load function...
+
+int OnModulesLoaded(WPARAM wParam, LPARAM lParam) {
+
+ Update update = {0}; // for c you'd use memset or ZeroMemory...
+ char szVersion[16];
+
+ update.cbSize = sizeof(Update);
+
+ update.szComponentName = pluginInfo.shortName;
+ update.pbVersion = (BYTE *)CreateVersionString(&pluginInfo, szVersion);
+ update.cpbVersion = strlen((char *)update.pbVersion);
+
+ // these are the three lines that matter - the archive, the page containing the version string, and the text (or data)
+ // before the version that we use to locate it on the page
+ // (note that if the update URL and the version URL point to standard file listing entries, the backend xml
+ // data will be used to check for updates rather than the actual web page - this is not true for beta urls)
+ update.szUpdateURL = "http://scottellis.com.au:81/test/updater.zip";
+ update.szVersionURL = "http://scottellis.com.au:81/test/updater_test.html";
+ update.pbVersionPrefix = (BYTE *)"Updater version ";
+
+ update.cpbVersionPrefix = strlen((char *)update.pbVersionPrefix);
+
+ // do the same for the beta versions of the above struct members if you wish to allow beta updates from another URL
+
+ CallService(MS_UPDATE_REGISTER, 0, (WPARAM)&update);
+
+ // Alternatively, to register a plugin with e.g. file ID 2254 on the file listing...
+ // CallService(MS_UPDATE_REGISTERFL, (WPARAM)2254, (LPARAM)&pluginInfo);
+
+ return 0;
+}
+
+#endif
diff --git a/plugins/VersionInfo/services.cpp b/plugins/VersionInfo/services.cpp
new file mode 100644
index 0000000000..3e137abf7c
--- /dev/null
+++ b/plugins/VersionInfo/services.cpp
@@ -0,0 +1,80 @@
+/*
+Version information plugin for Miranda IM
+
+Copyright © 2002-2006 Luca Santarelli, Cristian Libotean
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "services.h"
+
+HANDLE hsMenuCommand;
+HANDLE hsGetInfo;
+HANDLE hsServiceMode;
+
+int bServiceMode = 0; //true only if plugin is running in service mode
+
+int InitServices()
+{
+ hsMenuCommand = CreateServiceFunction(MS_VERSIONINFO_MENU_COMMAND, PluginMenuCommand);
+ hsGetInfo = CreateServiceFunction(MS_VERSIONINFO_GETINFO, GetInfoService);
+ hsServiceMode = CreateServiceFunction(MS_SERVICEMODE_LAUNCH, ServiceModeService);
+ return 0;
+}
+
+int DestroyServices()
+{
+ DestroyServiceFunction(hsMenuCommand);
+ DestroyServiceFunction(hsGetInfo);
+ DestroyServiceFunction(hsServiceMode);
+ return 0;
+}
+
+INT_PTR PluginMenuCommand(WPARAM wParam, LPARAM lParam)
+{
+ int debugTo = DBGetContactSettingByte(NULL, ModuleName, "DebugTo", TO_DIALOGBOX);
+ DoDebugTo(debugTo);
+ if (verbose) PUShowMessage("I have printed the information.", SM_NOTIFY);
+/* char *data;
+ CallService(MS_VERSIONINFO_GETINFO, 1, (LPARAM) &data); */
+ return 0;
+}
+
+INT_PTR GetInfoService(WPARAM wParam, LPARAM lParam)
+{
+ int result = 1; //failure
+ if (lParam != NULL)
+ {
+ CVersionInfo myInfo;
+ myInfo.Initialize();
+ std::string VI = myInfo.GetInformationsAsString(wParam);
+ char **retData = (char **) lParam;
+ (*retData) = (char *) MirandaMalloc(VI.size() + 1);
+ if (retData)
+ {
+ strcpy(*retData, VI.c_str());
+ result = 0; //success
+ }
+ }
+ return result;
+}
+
+INT_PTR ServiceModeService(WPARAM wParam, LPARAM lParam)
+{
+ bServiceMode = 1;
+ DoDebugTo(TO_ASK);
+
+ return 0;
+}
diff --git a/plugins/VersionInfo/services.h b/plugins/VersionInfo/services.h
new file mode 100644
index 0000000000..00bb262acd
--- /dev/null
+++ b/plugins/VersionInfo/services.h
@@ -0,0 +1,33 @@
+/*
+Version information plugin for Miranda IM
+
+Copyright © 2002-2006 Luca Santarelli, Cristian Libotean
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef M_VERSIONINFO_SERVICES_H
+#define M_VERSIONINFO_SERVICES_H
+
+#include "common.h"
+
+int InitServices();
+int DestroyServices();
+
+INT_PTR PluginMenuCommand(WPARAM wParam, LPARAM lParam);
+INT_PTR GetInfoService(WPARAM wParam, LPARAM lParam);
+INT_PTR ServiceModeService(WPARAM wParam, LPARAM lParam);
+
+#endif //M_VERSIONINFO_SERVICES_H \ No newline at end of file
diff --git a/plugins/VersionInfo/utils.cpp b/plugins/VersionInfo/utils.cpp
new file mode 100644
index 0000000000..182ea441c1
--- /dev/null
+++ b/plugins/VersionInfo/utils.cpp
@@ -0,0 +1,606 @@
+/*
+Version information plugin for Miranda IM
+
+Copyright © 2002-2006 Luca Santarelli, Cristian Libotean
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+//#define USE_LOG_FUNCTIONS
+
+#define STRICT
+#define WIN32_LEAN_AND_MEAN
+
+#include "utils.h"
+
+/*
+My usual MessageBoxes :-)
+*/
+void MB(char* message) {
+ if (verbose) MessageBox(NULL, message, ModuleName, MB_OK | MB_ICONEXCLAMATION);
+}
+
+void Log(char* message) {
+ if (ServiceExists(MS_POPUP_ADDPOPUP))
+ {
+ POPUPDATA pu = {0};
+ pu.lchIcon = hiVIIcon;
+ strncpy(pu.lptzContactName, Translate("Version Information"), MAX_CONTACTNAME);
+ strncpy(pu.lptzText, message, MAX_SECONDLINE);
+ PUAddPopUp(&pu);
+ }
+ else {
+ MessageBox(NULL, message, ModuleName, MB_OK | MB_ICONINFORMATION);
+ }
+}
+
+int SplitStringInfo(const char *szWholeText, char *szStartText, char *szEndText)
+{
+ const char *pos = strchr(szWholeText, '|');
+ if (pos)
+ {
+ size_t index = pos - szWholeText;
+ memmove(szStartText, szWholeText, index);
+ szStartText[index] = '\0';
+ StrTrim(szStartText, " ");
+ memmove(szEndText, pos + 1, strlen(pos)); //copies the \0 as well ... :)
+ StrTrim(szEndText, " ");
+ }
+ else{
+ szStartText[0] = szEndText[0] = '\0';
+ }
+ return 0;
+}
+
+int GetStringFromDatabase(char *szSettingName, char *szError, char *szResult, size_t size)
+{
+ DBVARIANT dbv = {0};
+ int res = 1;
+ size_t len;
+ dbv.type = DBVT_ASCIIZ;
+ if (DBGetContactSetting(NULL, ModuleName, szSettingName, &dbv) == 0)
+ {
+ res = 0;
+ size_t tmp = strlen(dbv.pszVal);
+ len = (tmp < size - 1) ? tmp : size - 1;
+ strncpy(szResult, dbv.pszVal, len);
+ szResult[len] = '\0';
+ MirandaFree(dbv.pszVal);
+ }
+ else{
+ res = 1;
+ size_t tmp = strlen(szError);
+ len = (tmp < size - 1) ? tmp : size - 1;
+ strncpy(szResult, szError, len);
+ szResult[len] = '\0';
+ }
+ return res;
+}
+
+char *RelativePathToAbsolute(char *szRelative, char *szAbsolute, size_t size)
+{
+ size_t len;
+
+ if (size < MAX_PATH)
+ {
+ char buffer[MAX_PATH]; //new path should be at least MAX_PATH chars
+ len = CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM) szRelative, (LPARAM) buffer);
+ strncpy(szAbsolute, buffer, size);
+ }
+ else{
+ len = CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM) szRelative, (LPARAM) szAbsolute);
+ }
+
+ return szAbsolute;
+}
+
+char *AbsolutePathToRelative(char *szAbsolute, char *szRelative, size_t size)
+{
+ size_t len;
+
+ if (size < MAX_PATH)
+ {
+ char buffer[MAX_PATH];
+ len = CallService(MS_UTILS_PATHTORELATIVE, (WPARAM) szAbsolute, (LPARAM) szRelative);
+ strncpy(szRelative, buffer, size);
+ }
+ else{
+ len = CallService(MS_UTILS_PATHTORELATIVE, (WPARAM) szAbsolute, (LPARAM) szRelative);
+ }
+
+ return szRelative;
+}
+
+void LogToFileInit()
+{
+#ifdef USE_LOG_FUNCTIONS
+ DeleteFile("versioninfo.log");
+#endif
+}
+
+void LogToFile(char *format, ...)
+{
+#ifdef USE_LOG_FUNCTIONS
+ char str[4096];
+ va_list vararg;
+ int tBytes;
+ FILE *fout = fopen("versioninfo.log", "at");
+ if (!fout)
+ {
+ Log("Can't open file versioninfo.log ...");
+ }
+ time_t currentTime = time(NULL);
+ tm *timp = localtime(&currentTime);
+ strftime(str, sizeof(str), "%d %b @ %H:%M:%S -> ", timp);
+ fputs(str, fout);
+
+ va_start(vararg, format);
+
+ tBytes = _vsnprintf(str, sizeof(str), format, vararg);
+ if (tBytes > 0)
+ {
+ str[tBytes] = 0;
+ }
+
+ va_end(vararg);
+ if (str[strlen(str) - 1] != '\n')
+ {
+ strcat(str, "\n");
+ }
+
+ fputs(str, fout);
+ fclose(fout);
+#endif
+}
+
+
+#define GetFacility(dwError) (HIWORD(dwError) && 0x0000111111111111)
+#define GetErrorCode(dwError) (LOWORD(dwError))
+
+void NotifyError(DWORD dwError, char* szSetting, int iLine) {
+ char str[1024];
+ mir_snprintf(str, sizeof(str), Translate("Ok, something went wrong in the \"%s\" setting. Report back the following values:\nFacility: %X\nError code: %X\nLine number: %d"), szSetting, GetFacility(dwError), GetErrorCode(dwError), iLine);
+ Log(str);
+}
+
+char *StrTrim(char *szText, const char *szTrimChars)
+{
+ size_t i = strlen(szText) - 1;
+ while ((i >= 0) && (strchr(szTrimChars, szText[i])))
+ {
+ szText[i--] = '\0';
+ }
+ i = 0;
+ while (((unsigned int )i < strlen(szText)) && (strchr(szTrimChars, szText[i])))
+ {
+ i++;
+ }
+ if (i)
+ {
+ size_t size = strlen(szText);
+ size_t j;
+ for (j = i; j <= size; j++) //shift the \0 as well
+ {
+ szText[j - i] = szText[j];
+ }
+// memmove(szText, szText + i, size - i + 1); //copy the string without the first i characters
+ }
+ return szText;
+}
+
+bool DoesDllExist(char *dllName)
+{
+ HMODULE dllHandle;
+ dllHandle = LoadLibraryEx(dllName, NULL, DONT_RESOLVE_DLL_REFERENCES);
+ if (dllHandle)
+ {
+ FreeLibrary(dllHandle);
+ return true;
+ }
+ return false;
+}
+
+//========== From Cyreve ==========
+PLUGININFOEX *GetPluginInfo(const char *filename,HINSTANCE *hPlugin)
+{
+ char szMirandaPath[MAX_PATH],szPluginPath[MAX_PATH];
+ char *str2;
+ PLUGININFOEX *(*MirandaPluginInfo)(DWORD);
+ PLUGININFOEX *pPlugInfo;
+ HMODULE hLoadedModule;
+ DWORD mirandaVersion = CallService(MS_SYSTEM_GETVERSION,0,0);
+
+ GetModuleFileName(GetModuleHandle(NULL),szMirandaPath,sizeof(szMirandaPath));
+ str2=strrchr(szMirandaPath,'\\');
+ if(str2!=NULL) *str2=0;
+
+ hLoadedModule=GetModuleHandle(filename);
+ if(hLoadedModule!=NULL) {
+ *hPlugin=NULL;
+ MirandaPluginInfo=(PLUGININFOEX *(*)(DWORD))GetProcAddress(hLoadedModule,"MirandaPluginInfo");
+ return MirandaPluginInfo(mirandaVersion);
+ }
+ wsprintf(szPluginPath,"%s\\Plugins\\%s",szMirandaPath,filename);
+ *hPlugin=LoadLibrary(szPluginPath);
+ if(*hPlugin==NULL) return NULL;
+ MirandaPluginInfo=(PLUGININFOEX *(*)(DWORD))GetProcAddress(*hPlugin,"MirandaPluginInfo");
+ if(MirandaPluginInfo==NULL) {FreeLibrary(*hPlugin); *hPlugin=NULL; return NULL;}
+ pPlugInfo=MirandaPluginInfo(mirandaVersion);
+ if(pPlugInfo==NULL) {FreeLibrary(*hPlugin); *hPlugin=NULL; return NULL;}
+ if(pPlugInfo->cbSize!=sizeof(PLUGININFOEX)) {FreeLibrary(*hPlugin); *hPlugin=NULL; return NULL;}
+ return pPlugInfo;
+}
+
+//========== from Frank Cheng (wintime98) ==========
+// I've changed something to suit VersionInfo :-)
+#include <imagehlp.h>
+
+void TimeStampToSysTime(DWORD Unix,SYSTEMTIME* SysTime)
+{
+ SYSTEMTIME S;
+ DWORDLONG FileReal,UnixReal;
+ S.wYear=1970;
+ S.wMonth=1;
+ S.wDay=1;
+ S.wHour=0;
+ S.wMinute=0;
+ S.wSecond=0;
+ S.wMilliseconds=0;
+ SystemTimeToFileTime(&S,(FILETIME*)&FileReal);
+ UnixReal = Unix;
+ UnixReal*=10000000;
+ FileReal+=UnixReal;
+ FileTimeToSystemTime((FILETIME*)&FileReal,SysTime);
+}
+
+void GetModuleTimeStamp(char* pszDate, char* pszTime)
+{
+ char date[128],time[128],szModule[MAX_PATH];
+ HANDLE mapfile,file;
+ DWORD timestamp,filesize;
+ LPVOID mapmem;
+ SYSTEMTIME systime;
+ GetModuleFileName(NULL,szModule,MAX_PATH);
+ file = CreateFile(szModule,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
+ filesize = GetFileSize(file,NULL);
+ mapfile = CreateFileMapping(file, NULL, PAGE_READONLY, 0, filesize, NULL);
+ mapmem = MapViewOfFile(mapfile, FILE_MAP_READ, 0, 0, 0);
+ timestamp = GetTimestampForLoadedLibrary((HINSTANCE)mapmem);
+ TimeStampToSysTime(timestamp,&systime);
+ GetTimeFormat(LOCALE_USER_DEFAULT,0,&systime,"HH':'mm':'ss",time,128);
+ GetDateFormat(EnglishLocale,0,&systime,"dd' 'MMMM' 'yyyy",date,128);
+ //MessageBox(NULL,date,time,0);
+ lstrcpy(pszTime, time);
+ lstrcpy(pszDate, date);
+ UnmapViewOfFile(mapmem);
+ CloseHandle(mapfile);
+ CloseHandle(file);
+}
+
+//From Egodust or Cyreve... I don't really know.
+PLUGININFOEX *CopyPluginInfo(PLUGININFOEX *piSrc)
+{
+ PLUGININFOEX *pi;
+ if(piSrc==NULL) return NULL;
+ pi=(PLUGININFOEX *)malloc(sizeof(PLUGININFOEX));
+
+ *pi=*piSrc;
+ pi->uuid = UUID_NULL;
+
+ if (piSrc->cbSize >= sizeof(PLUGININFOEX))
+ {
+ pi->uuid = piSrc->uuid;
+ }
+
+ if (piSrc->cbSize >= sizeof(PLUGININFO))
+ {
+ if(pi->author) pi->author=_strdup(pi->author);
+ if(pi->authorEmail) pi->authorEmail=_strdup(pi->authorEmail);
+ if(pi->copyright) pi->copyright=_strdup(pi->copyright);
+ if(pi->description) pi->description=_strdup(pi->description);
+ if(pi->homepage) pi->homepage=_strdup(pi->homepage);
+ if(pi->shortName) pi->shortName=_strdup(pi->shortName);
+ }
+
+ return pi;
+}
+
+void FreePluginInfo(PLUGININFOEX *pi)
+{
+ if(pi->author) free(pi->author);
+ if(pi->authorEmail) free(pi->authorEmail);
+ if(pi->copyright) free(pi->copyright);
+ if(pi->description) free(pi->description);
+ if(pi->homepage) free(pi->homepage);
+ if(pi->shortName) free(pi->shortName);
+ free(pi);
+}
+
+BOOL IsCurrentUserLocalAdministrator(void)
+{
+ BOOL fReturn = FALSE;
+ DWORD dwStatus;
+ DWORD dwAccessMask;
+ DWORD dwAccessDesired;
+ DWORD dwACLSize;
+ DWORD dwStructureSize = sizeof(PRIVILEGE_SET);
+ PACL pACL = NULL;
+ PSID psidAdmin = NULL;
+
+ HANDLE hToken = NULL;
+ HANDLE hImpersonationToken = NULL;
+
+ PRIVILEGE_SET ps;
+ GENERIC_MAPPING GenericMapping;
+
+ PSECURITY_DESCRIPTOR psdAdmin = NULL;
+ SID_IDENTIFIER_AUTHORITY SystemSidAuthority = SECURITY_NT_AUTHORITY;
+
+
+ /*
+ Determine if the current thread is running as a user that is a member of
+ the local admins group. To do this, create a security descriptor that
+ has a DACL which has an ACE that allows only local aministrators access.
+ Then, call AccessCheck with the current thread's token and the security
+ descriptor. It will say whether the user could access an object if it
+ had that security descriptor. Note: you do not need to actually create
+ the object. Just checking access against the security descriptor alone
+ will be sufficient.
+ */
+ const DWORD ACCESS_READ = 1;
+ const DWORD ACCESS_WRITE = 2;
+
+
+ __try
+ {
+
+ /*
+ AccessCheck() requires an impersonation token. We first get a primary
+ token and then create a duplicate impersonation token. The
+ impersonation token is not actually assigned to the thread, but is
+ used in the call to AccessCheck. Thus, this function itself never
+ impersonates, but does use the identity of the thread. If the thread
+ was impersonating already, this function uses that impersonation context.
+ */
+ if (!OpenThreadToken(GetCurrentThread(), TOKEN_DUPLICATE|TOKEN_QUERY, TRUE, &hToken))
+ {
+ if (GetLastError() != ERROR_NO_TOKEN)
+ __leave;
+
+ if (!OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE|TOKEN_QUERY, &hToken))
+ __leave;
+ }
+
+ if (!DuplicateToken (hToken, SecurityImpersonation, &hImpersonationToken))
+ __leave;
+
+
+ /*
+ Create the binary representation of the well-known SID that
+ represents the local administrators group. Then create the security
+ descriptor and DACL with an ACE that allows only local admins access.
+ After that, perform the access check. This will determine whether
+ the current user is a local admin.
+ */
+ if (!AllocateAndInitializeSid(&SystemSidAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &psidAdmin))
+ __leave;
+
+ psdAdmin = LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
+ if (psdAdmin == NULL)
+ __leave;
+
+ if (!InitializeSecurityDescriptor(psdAdmin, SECURITY_DESCRIPTOR_REVISION))
+ __leave;
+
+ // Compute size needed for the ACL.
+ dwACLSize = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psidAdmin) - sizeof(DWORD);
+
+ pACL = (PACL)LocalAlloc(LPTR, dwACLSize);
+ if (pACL == NULL)
+ __leave;
+
+ if (!InitializeAcl(pACL, dwACLSize, ACL_REVISION2))
+ __leave;
+
+ dwAccessMask= ACCESS_READ | ACCESS_WRITE;
+
+ if (!AddAccessAllowedAce(pACL, ACL_REVISION2, dwAccessMask, psidAdmin))
+ __leave;
+
+ if (!SetSecurityDescriptorDacl(psdAdmin, TRUE, pACL, FALSE))
+ __leave;
+
+ /*
+ AccessCheck validates a security descriptor somewhat; set the group
+ and owner so that enough of the security descriptor is filled out to
+ make AccessCheck happy.
+ */
+ SetSecurityDescriptorGroup(psdAdmin, psidAdmin, FALSE);
+ SetSecurityDescriptorOwner(psdAdmin, psidAdmin, FALSE);
+
+ if (!IsValidSecurityDescriptor(psdAdmin))
+ __leave;
+
+ dwAccessDesired = ACCESS_READ;
+
+ /*
+ Initialize GenericMapping structure even though you
+ do not use generic rights.
+ */
+ GenericMapping.GenericRead = ACCESS_READ;
+ GenericMapping.GenericWrite = ACCESS_WRITE;
+ GenericMapping.GenericExecute = 0;
+ GenericMapping.GenericAll = ACCESS_READ | ACCESS_WRITE;
+
+ if (!AccessCheck(psdAdmin, hImpersonationToken, dwAccessDesired, &GenericMapping, &ps, &dwStructureSize, &dwStatus, &fReturn))
+ {
+ fReturn = FALSE;
+ __leave;
+ }
+ }
+ __finally
+ {
+ // Clean up.
+ if (pACL) LocalFree(pACL);
+ if (psdAdmin) LocalFree(psdAdmin);
+ if (psidAdmin) FreeSid(psidAdmin);
+ if (hImpersonationToken) CloseHandle (hImpersonationToken);
+ if (hToken) CloseHandle (hToken);
+ }
+
+ return fReturn;
+}
+
+BOOL GetWindowsShell(char *shellPath, size_t shSize)
+{
+ OSVERSIONINFO vi = {0};
+ vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ GetVersionEx(&vi);
+
+ char szShell[1024] = {0};
+ DWORD size = sizeof(szShell);
+
+ if (vi.dwPlatformId == VER_PLATFORM_WIN32_NT)
+ {
+ HKEY hKey;
+ if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\IniFileMapping\\system.ini\\boot", 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
+ {
+ RegQueryValueEx(hKey, "Shell", NULL, NULL, (LPBYTE) szShell, &size);
+ _strlwr(szShell);
+ HKEY hRootKey = (strstr(szShell, "sys:") == szShell) ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
+ RegCloseKey(hKey);
+
+ strcpy(szShell, "<unknown>");
+ if (RegOpenKeyEx(hRootKey, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
+ {
+ size = sizeof(szShell);
+ RegQueryValueEx(hKey, "Shell", NULL, NULL, (LPBYTE) szShell, &size);
+ RegCloseKey(hKey);
+ }
+ }
+ }
+ else{
+ char szSystemIniPath[2048];
+ GetWindowsDirectory(szSystemIniPath, sizeof(szSystemIniPath));
+ size_t len = strlen(szSystemIniPath);
+ if (len > 0)
+ {
+ if (szSystemIniPath[len - 1] == '\\') { szSystemIniPath[--len] = '\0'; }
+ strcat(szSystemIniPath, "\\system.ini");
+ GetPrivateProfileString("boot", "shell", "<unknown>", szShell, size, szSystemIniPath);
+ }
+ }
+
+ char *pos = strrchr(szShell, '\\');
+ char *res = (pos) ? pos + 1 : szShell;
+ strncpy(shellPath, res, shSize);
+
+ return TRUE;
+}
+
+BOOL GetInternetExplorerVersion(char *ieVersion, size_t ieSize)
+{
+ HKEY hKey;
+ char ieVer[1024];
+ DWORD size = sizeof(ieVer);
+ char ieBuild[64] = {0};
+
+ strncpy(ieVer, "<not installed>", size);
+
+ if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Internet Explorer", 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
+ {
+ if (RegQueryValueEx(hKey, "Version", NULL, NULL, (LPBYTE) ieVer, &size) == ERROR_SUCCESS)
+ {
+ char *pos = strchr(ieVer, '.');
+ if (pos)
+ {
+ pos = strchr(pos + 1, '.');
+ if (pos) { *pos = 0; }
+ strncpy(ieBuild, pos + 1, sizeof(ieBuild));
+ pos = strchr(ieBuild, '.');
+ if (pos) { *pos = 0; }
+ }
+ }
+ else{
+ size = sizeof(ieVer);
+ if (RegQueryValueEx(hKey, "Build", NULL, NULL, (LPBYTE) ieVer, &size) == ERROR_SUCCESS)
+ {
+ char *pos = ieVer + 1;
+ strncpy(ieBuild, pos, sizeof(ieBuild));
+ *pos = 0;
+ pos = strchr(ieBuild, '.');
+ if (pos) { *pos = 0; }
+ }
+ else{
+ strncpy(ieVer, "<unknown version>", size);
+ }
+ }
+ RegCloseKey(hKey);
+ }
+
+ strncpy(ieVersion, ieVer, ieSize);
+ if (strlen(ieBuild) > 0)
+ {
+ strncat(ieVersion, ".", ieSize);
+ strncat(ieVersion, ieBuild, ieSize);
+ //strncat(ieVersion, ")", ieSize);
+ }
+
+ return TRUE;
+}
+
+
+char *GetLanguageName(LANGID language)
+{
+
+ LCID lc = MAKELCID(language, SORT_DEFAULT);
+
+ return GetLanguageName(lc);
+}
+
+extern char *GetLanguageName(LCID locale)
+{
+ static char name[1024];
+
+ GetLocaleInfo(locale, LOCALE_SENGLANGUAGE, name, sizeof(name));
+
+ return name;
+}
+
+BOOL UUIDToString(MUUID uuid, char *str, size_t len)
+{
+ if ((len < sizeof(MUUID)) || (!str))
+ {
+ return 0;
+ }
+
+ mir_snprintf(str, len, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", uuid.a, uuid.b, uuid.c, uuid.d[0], uuid.d[1], uuid.d[2], uuid.d[3], uuid.d[4], uuid.d[5], uuid.d[6], uuid.d[7]);
+
+ return 1;
+}
+
+BOOL IsUUIDNull(MUUID uuid)
+{
+ int i;
+ for (i = 0; i < sizeof(uuid.d); i++)
+ {
+ if (uuid.d[i])
+ {
+ return 0;
+ }
+ }
+
+ return ((uuid.a == 0) && (uuid.b == 0) && (uuid.c == 0));
+} \ No newline at end of file
diff --git a/plugins/VersionInfo/utils.h b/plugins/VersionInfo/utils.h
new file mode 100644
index 0000000000..ef2b29ba59
--- /dev/null
+++ b/plugins/VersionInfo/utils.h
@@ -0,0 +1,54 @@
+#ifndef _M_VERSIONINFO_UTILS_H
+#define _M_VERSIONINFO_UTILS_H
+
+#include "common.h"
+
+//utils.cpp
+void MB(char*);
+void Log(char*);
+char *StrTrim(char *, const char *);
+
+//logging functions
+//utils.cpp
+void LogToFileInit();
+void LogToFile(char *format, ...);
+
+//utils.cpp
+char *RelativePathToAbsolute(char *szRelative, char *szAbsolute, size_t size);
+char *AbsolutePathToRelative(char *szAbsolute, char *szRelative, size_t size);
+
+//returns a string from the database and uses MirandaFree to deallocate the string, leaving only the local copy
+//utils.cpp
+int GetStringFromDatabase(char *szSettingName, char *szError, char *szResult, size_t size);
+
+//a string of the form %s(start) | %s(end) is split into the two strings (start and end)
+//utils.cpp
+int SplitStringInfo(const char *szWholeText, char *szStartText, char *szEndText);
+
+//utils.cpp
+bool DoesDllExist(char *dllName);
+
+//utils.cpp
+void GetModuleTimeStamp(char*, char*);
+void NotifyError(DWORD, char*, int);
+
+//utils.cpp
+PLUGININFOEX *GetPluginInfo(const char *,HINSTANCE *);
+PLUGININFOEX *CopyPluginInfo(PLUGININFOEX *);
+void FreePluginInfo(PLUGININFOEX *);
+
+//utils.cpp
+
+BOOL IsCurrentUserLocalAdministrator();
+
+char *GetLanguageName(LANGID language);
+char *GetLanguageName(LCID locale);
+
+BOOL GetWindowsShell(char *shellPath, size_t shSize);
+BOOL GetInternetExplorerVersion(char *ieVersion, size_t ieSize);
+
+BOOL UUIDToString(MUUID uuid, char *str, size_t len);
+
+BOOL IsUUIDNull(MUUID uuid);
+
+#endif \ No newline at end of file
diff --git a/plugins/VersionInfo/version.h b/plugins/VersionInfo/version.h
new file mode 100644
index 0000000000..b5653f869f
--- /dev/null
+++ b/plugins/VersionInfo/version.h
@@ -0,0 +1,49 @@
+/*
+Version information plugin for Miranda IM
+
+Copyright © 2002-2005 Luca Santarelli, © 2005-2008 Cristian Libotean
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef M_VERSIONINFO_VERSION_H
+#define M_VERSIONINFO_VERSION_H
+
+#define __MAJOR_VERSION 1
+#define __MINOR_VERSION 4
+#define __RELEASE_NUM 3
+#define __BUILD_NUM 4
+
+#define VERSION PLUGIN_MAKE_VERSION(__MAJOR_VERSION, __MINOR_VERSION, __RELEASE_NUM, __BUILD_NUM)
+
+#define __PLUGINVERSION_STRING __MAJOR_VERSION,__MINOR_VERSION,__RELEASE_NUM,__BUILD_NUM
+#define __PLUGINVERSION_STRING_DOTS __MAJOR_VERSION.__MINOR_VERSION.__RELEASE_NUM.__BUILD_NUM
+#define __STRINGIFY_(x) #x
+#define __STRINGIFY(x) __STRINGIFY_(x)
+#define __VERSION_STRING __STRINGIFY(__PLUGINVERSION_STRING_DOTS)
+
+#define __DESC "Collects and prints information related to Miranda, the plugins and the OS."
+#define __AUTHOR "Luca Santarelli, Cristian Libotean"
+#define __AUTHOREMAIL "hrk@users.sourceforge.net, eblis102@yahoo.com"
+#define __COPYRIGHT "© 2002-2005 Luca Santarelli, © 2005-2009 Cristian Libotean"
+#define __AUTHORWEB "http://www.miranda-im.org/"
+
+#if defined(WIN64) || defined(_WIN64)
+#define __PLUGIN_DISPLAY_NAME "Version Information (x64)"
+#else
+#define __PLUGIN_DISPLAY_NAME "Version Information"
+#endif
+
+#endif //M_VERSIONINFO_VERSION_H
diff --git a/plugins/VersionInfo/version.rc b/plugins/VersionInfo/version.rc
new file mode 100644
index 0000000000..0f8fea03fc
--- /dev/null
+++ b/plugins/VersionInfo/version.rc
@@ -0,0 +1,100 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+#include "version.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource1.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION __PLUGINVERSION_STRING
+ PRODUCTVERSION __PLUGINVERSION_STRING
+ FILEFLAGSMASK 0x17L
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Author", __AUTHOR
+ VALUE "FileDescription", __DESC
+ VALUE "FileVersion", __VERSION_STRING
+ VALUE "InternalName", __PLUGIN_DISPLAY_NAME
+ VALUE "LegalCopyright", __COPYRIGHT
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/plugins/dbeditorpp/Res/Contacts.ico b/plugins/dbeditorpp/Res/Contacts.ico
new file mode 100644
index 0000000000..f3de15b54b
--- /dev/null
+++ b/plugins/dbeditorpp/Res/Contacts.ico
Binary files differ
diff --git a/plugins/dbeditorpp/Res/Icon_1.ico b/plugins/dbeditorpp/Res/Icon_1.ico
new file mode 100644
index 0000000000..a99fe06619
--- /dev/null
+++ b/plugins/dbeditorpp/Res/Icon_1.ico
Binary files differ
diff --git a/plugins/dbeditorpp/Res/Icon_14.ico b/plugins/dbeditorpp/Res/Icon_14.ico
new file mode 100644
index 0000000000..d14e4a1f96
--- /dev/null
+++ b/plugins/dbeditorpp/Res/Icon_14.ico
Binary files differ
diff --git a/plugins/dbeditorpp/Res/Icon_15.ico b/plugins/dbeditorpp/Res/Icon_15.ico
new file mode 100644
index 0000000000..343fd1aaf0
--- /dev/null
+++ b/plugins/dbeditorpp/Res/Icon_15.ico
Binary files differ
diff --git a/plugins/dbeditorpp/Res/Icon_16.ico b/plugins/dbeditorpp/Res/Icon_16.ico
new file mode 100644
index 0000000000..6cd2cd8e58
--- /dev/null
+++ b/plugins/dbeditorpp/Res/Icon_16.ico
Binary files differ
diff --git a/plugins/dbeditorpp/Res/Icon_17.ico b/plugins/dbeditorpp/Res/Icon_17.ico
new file mode 100644
index 0000000000..e11509e6cb
--- /dev/null
+++ b/plugins/dbeditorpp/Res/Icon_17.ico
Binary files differ
diff --git a/plugins/dbeditorpp/Res/Icon_18.ico b/plugins/dbeditorpp/Res/Icon_18.ico
new file mode 100644
index 0000000000..e25d704f71
--- /dev/null
+++ b/plugins/dbeditorpp/Res/Icon_18.ico
Binary files differ
diff --git a/plugins/dbeditorpp/Res/Icon_4.ico b/plugins/dbeditorpp/Res/Icon_4.ico
new file mode 100644
index 0000000000..cac9a01f7e
--- /dev/null
+++ b/plugins/dbeditorpp/Res/Icon_4.ico
Binary files differ
diff --git a/plugins/dbeditorpp/Res/Red.ico b/plugins/dbeditorpp/Res/Red.ico
new file mode 100644
index 0000000000..f6431fc7c1
--- /dev/null
+++ b/plugins/dbeditorpp/Res/Red.ico
Binary files differ
diff --git a/plugins/dbeditorpp/Res/Red_open.ico b/plugins/dbeditorpp/Res/Red_open.ico
new file mode 100644
index 0000000000..1aa476a9d6
--- /dev/null
+++ b/plugins/dbeditorpp/Res/Red_open.ico
Binary files differ
diff --git a/plugins/dbeditorpp/Res/UserMenu.ico b/plugins/dbeditorpp/Res/UserMenu.ico
new file mode 100644
index 0000000000..acc2af901c
--- /dev/null
+++ b/plugins/dbeditorpp/Res/UserMenu.ico
Binary files differ
diff --git a/plugins/dbeditorpp/Res/Yellow.ico b/plugins/dbeditorpp/Res/Yellow.ico
new file mode 100644
index 0000000000..378bdb3909
--- /dev/null
+++ b/plugins/dbeditorpp/Res/Yellow.ico
Binary files differ
diff --git a/plugins/dbeditorpp/Res/Yellow_open.ico b/plugins/dbeditorpp/Res/Yellow_open.ico
new file mode 100644
index 0000000000..df3ae478c2
--- /dev/null
+++ b/plugins/dbeditorpp/Res/Yellow_open.ico
Binary files differ
diff --git a/plugins/dbeditorpp/Res/dbepp.ico b/plugins/dbeditorpp/Res/dbepp.ico
new file mode 100644
index 0000000000..817dba66f4
--- /dev/null
+++ b/plugins/dbeditorpp/Res/dbepp.ico
Binary files differ
diff --git a/plugins/dbeditorpp/Res/handle.ico b/plugins/dbeditorpp/Res/handle.ico
new file mode 100644
index 0000000000..5a4448f8a7
--- /dev/null
+++ b/plugins/dbeditorpp/Res/handle.ico
Binary files differ
diff --git a/plugins/dbeditorpp/Res/handle1.ico b/plugins/dbeditorpp/Res/handle1.ico
new file mode 100644
index 0000000000..705cbd3028
--- /dev/null
+++ b/plugins/dbeditorpp/Res/handle1.ico
Binary files differ
diff --git a/plugins/dbeditorpp/Res/ico_RegEdit.ico b/plugins/dbeditorpp/Res/ico_RegEdit.ico
new file mode 100644
index 0000000000..6d1287ddd2
--- /dev/null
+++ b/plugins/dbeditorpp/Res/ico_RegEdit.ico
Binary files differ
diff --git a/plugins/dbeditorpp/Res/offline2.ico b/plugins/dbeditorpp/Res/offline2.ico
new file mode 100644
index 0000000000..e31abd9905
--- /dev/null
+++ b/plugins/dbeditorpp/Res/offline2.ico
Binary files differ
diff --git a/plugins/dbeditorpp/Res/online2.ico b/plugins/dbeditorpp/Res/online2.ico
new file mode 100644
index 0000000000..c30bcee643
--- /dev/null
+++ b/plugins/dbeditorpp/Res/online2.ico
Binary files differ
diff --git a/plugins/dbeditorpp/Res/unicode.ico b/plugins/dbeditorpp/Res/unicode.ico
new file mode 100644
index 0000000000..c65c3f0875
--- /dev/null
+++ b/plugins/dbeditorpp/Res/unicode.ico
Binary files differ
diff --git a/plugins/dbeditorpp/Version.h b/plugins/dbeditorpp/Version.h
new file mode 100644
index 0000000000..9ce8b1874c
--- /dev/null
+++ b/plugins/dbeditorpp/Version.h
@@ -0,0 +1,28 @@
+#define __MAJOR_VERSION 3
+#define __MINOR_VERSION 2
+#define __RELEASE_NUM 0
+#define __BUILD_NUM 0
+
+#define __FILEVERSION_STRING __MAJOR_VERSION,__MINOR_VERSION,__RELEASE_NUM,__BUILD_NUM
+#define __FILEVERSION_DOTS __MAJOR_VERSION.__MINOR_VERSION.__RELEASE_NUM.__BUILD_NUM
+
+#define __STRINGIFY_IMPL(x) #x
+#define __STRINGIFY(x) __STRINGIFY_IMPL(x)
+#define __VERSION_STRING __STRINGIFY(__FILEVERSION_DOTS)
+
+#ifdef _UNICODE
+#if defined(WIN64) || defined(_WIN64)
+ #define __PLUGIN_NAME "Database Editor++ (Unicode x64)"
+#else
+ #define __PLUGIN_NAME "Database Editor++ (Unicode)"
+#endif
+#else
+ #define __PLUGIN_NAME "Database Editor++"
+#endif
+#define __INTERNAL_NAME "DBEditor"
+#define __FILENAME "Svc_dbepp.dll"
+#define __DESCRIPTION "Advanced Database Editor."
+#define __AUTHOR "Bio, Jonathan Gordon"
+#define __AUTHOREMAIL "bio@msx.ru, jdgordy@gmail.com"
+#define __AUTHORWEB "http://addons.miranda-im.org/details.php?action=viewfile&id=2957"
+#define __COPYRIGHT "© 2003-2011 Bio, Jonathan Gordon"
diff --git a/plugins/dbeditorpp/Version.rc b/plugins/dbeditorpp/Version.rc
new file mode 100644
index 0000000000..e637f0cb33
--- /dev/null
+++ b/plugins/dbeditorpp/Version.rc
@@ -0,0 +1,38 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "afxres.h"
+#include "version.h"
+
+#ifdef _WIN32
+LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
+#endif //_WIN32
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION __FILEVERSION_STRING
+ PRODUCTVERSION __FILEVERSION_STRING
+ FILEFLAGSMASK 0x17L
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x0L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "000004b0"
+ BEGIN
+ VALUE "FileDescription", __DESCRIPTION
+ VALUE "InternalName", __PLUGIN_NAME
+ VALUE "LegalCopyright", __COPYRIGHT
+ VALUE "OriginalFilename", __FILENAME
+ VALUE "ProductName", __PLUGIN_NAME
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x0, 1200
+ END
+END
diff --git a/plugins/dbeditorpp/addeditsettingsdlg.cpp b/plugins/dbeditorpp/addeditsettingsdlg.cpp
new file mode 100644
index 0000000000..6c21fe498c
--- /dev/null
+++ b/plugins/dbeditorpp/addeditsettingsdlg.cpp
@@ -0,0 +1,458 @@
+#include "headers.h"
+
+
+static BOOL Convert(HANDLE hContact, char* module, char* setting, int value, int toType) // 0 = byte, 1 = word, 2 = dword, 3 = string
+{
+ int Result = 1;
+ char temp[64];
+
+ switch (toType)
+ {
+ case 0:
+ if (value > 0xFF)
+ Result = 0;
+ else
+ DBWriteContactSettingByte(hContact, module, setting, (BYTE)value);
+ break;
+ case 1:
+ if (value > 0xFFFF)
+ Result = 0;
+ else
+ DBWriteContactSettingWord(hContact, module, setting, (WORD)value);
+ break;
+ case 2:
+ DBWriteContactSettingDword(hContact, module, setting, (DWORD)value);
+ break;
+ case 3:
+ DBDeleteContactSetting(hContact, module, setting);
+ DBWriteContactSettingString(hContact, module, setting, itoa(value,temp,10));
+ break;
+ }
+ return Result;
+}
+
+
+BOOL convertSetting(HANDLE hContact, char* module, char* setting, int toType) // 0 = byte, 1 = word, 2 = dword, 3 = string, 4 = unicode
+{
+ DBVARIANT dbv = {0};
+ BOOL Result = 0;
+
+ if (!GetSetting(hContact, module, setting, &dbv))
+ {
+ switch (dbv.type)
+ {
+ case DBVT_BYTE:
+ Result = Convert(hContact, module, setting, dbv.bVal, toType);
+ break;
+
+ case DBVT_WORD:
+ Result = Convert(hContact, module, setting, dbv.wVal, toType);
+ break;
+
+ case DBVT_DWORD:
+ Result = Convert(hContact, module, setting, dbv.dVal, toType);
+ break;
+
+ case DBVT_ASCIIZ:
+ if (toType == 4) // convert to UNICODE
+ {
+ int len = (int)strlen(dbv.pszVal) + 1;
+ WCHAR *wc = (WCHAR*)_alloca(len*sizeof(WCHAR));
+ MultiByteToWideChar(CP_ACP, 0, dbv.pszVal, -1, wc, len);
+ Result = !DBWriteContactSettingWString(hContact, module, setting, wc);
+ }
+ else
+ if (strlen(dbv.pszVal) < 11 && toType != 3)
+ {
+ int val = atoi(dbv.pszVal);
+ if (val == 0 && dbv.pszVal[0] != '0')
+ break;
+
+ Result = Convert(hContact, module, setting, val, toType);
+ }
+ break;
+ case DBVT_UTF8:
+ if (toType == 3 && UOS) // convert to ANSI
+ {
+ int len = (int)strlen(dbv.pszVal) + 1;
+ char *sz = (char*)_alloca(len*3);
+ WCHAR *wc = (WCHAR*)_alloca(len*sizeof(WCHAR));
+ MultiByteToWideChar(CP_UTF8, 0, dbv.pszVal, -1, wc, len);
+ WideCharToMultiByte(CP_ACP, 0, wc, -1, sz, len, NULL, NULL);
+ Result = !DBWriteContactSettingString(hContact, module, setting, sz);
+ }
+ break;
+ }
+
+ if (!Result)
+ msg(Translate("Cannot Convert!"), modFullname);
+
+ DBFreeVariant(&dbv);
+ }
+
+ return Result;
+}
+
+
+int saveAsType(HWND hwnd)
+{
+ if(IsDlgButtonChecked(hwnd, CHK_BYTE))
+ return 0;
+ else if(IsDlgButtonChecked(hwnd, CHK_WORD))
+ return 1;
+ else if(IsDlgButtonChecked(hwnd, CHK_DWORD))
+ return 2;
+ else if(IsDlgButtonChecked(hwnd, CHK_STRING))
+ return 3;
+ return 3;
+}
+
+
+INT_PTR CALLBACK EditSettingDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch(msg)
+ {
+ case WM_INITDIALOG:
+ {
+ char tmp[32];
+ SetWindowLongPtr(hwnd,GWLP_USERDATA,(LPARAM)lParam);
+ switch (((struct DBsetting*)lParam)->dbv.type)
+ {
+ case DBVT_BYTE:
+ ShowWindow(GetDlgItem(hwnd, IDC_STRING),SW_HIDE);
+ if (!((struct DBsetting*)lParam)->setting[0])
+ {
+ SetWindowText(hwnd, Translate("New BYTE value"));
+ }
+ else
+ {
+ SetWindowText(hwnd, Translate("Edit BYTE value"));
+ SetDlgItemText(hwnd, IDC_SETTINGNAME, ((struct DBsetting*)lParam)->setting);
+ SetDlgItemText(hwnd, IDC_SETTINGVALUE, itoa(((struct DBsetting*)lParam)->dbv.bVal, tmp, 10));
+ }
+ CheckRadioButton(hwnd, CHK_HEX, CHK_DECIMAL, CHK_DECIMAL);
+ CheckRadioButton(hwnd, CHK_BYTE, CHK_STRING, CHK_BYTE);
+ break;
+ case DBVT_WORD:
+ ShowWindow(GetDlgItem(hwnd, IDC_STRING),SW_HIDE);
+ if (!((struct DBsetting*)lParam)->setting[0])
+ {
+ SetWindowText(hwnd, Translate("New WORD value"));
+ }
+ else
+ {
+ SetWindowText(hwnd, Translate("Edit WORD value"));
+ SetDlgItemText(hwnd, IDC_SETTINGNAME, ((struct DBsetting*)lParam)->setting);
+ SetDlgItemText(hwnd, IDC_SETTINGVALUE, itoa(((struct DBsetting*)lParam)->dbv.wVal, tmp, 10));
+ }
+ CheckRadioButton(hwnd, CHK_HEX, CHK_DECIMAL, CHK_DECIMAL);
+ CheckRadioButton(hwnd, CHK_BYTE, CHK_STRING, CHK_WORD);
+ break;
+ case DBVT_DWORD:
+ ShowWindow(GetDlgItem(hwnd, IDC_STRING),SW_HIDE);
+ if (!((struct DBsetting*)lParam)->setting[0])
+ {
+ SetWindowText(hwnd, Translate("New DWORD value"));
+ }
+ else
+ {
+ char text[32];
+ SetWindowText(hwnd, Translate("Edit DWORD value"));
+ SetDlgItemText(hwnd, IDC_SETTINGNAME, ((struct DBsetting*)lParam)->setting);
+ mir_snprintf(text, SIZEOF(text), "%X", ((struct DBsetting*)lParam)->dbv.dVal);
+ SetDlgItemText(hwnd, IDC_SETTINGVALUE, text);
+ }
+ CheckRadioButton(hwnd, CHK_HEX, CHK_DECIMAL, CHK_HEX);
+ CheckRadioButton(hwnd, CHK_BYTE, CHK_STRING, CHK_DWORD);
+ break;
+ case DBVT_ASCIIZ:
+ ShowWindow(GetDlgItem(hwnd, IDC_STRING),SW_SHOW);
+ ShowWindow(GetDlgItem(hwnd, IDC_SETTINGVALUE),SW_HIDE);
+ ShowWindow(GetDlgItem(hwnd, CHK_HEX),SW_HIDE);
+ ShowWindow(GetDlgItem(hwnd, CHK_DECIMAL),SW_HIDE);
+ ShowWindow(GetDlgItem(hwnd, GRP_BASE),SW_HIDE);
+ ShowWindow(GetDlgItem(hwnd, GRP_TYPE),SW_HIDE);
+ ShowWindow(GetDlgItem(hwnd, CHK_BYTE),SW_HIDE);
+ ShowWindow(GetDlgItem(hwnd, CHK_WORD),SW_HIDE);
+ ShowWindow(GetDlgItem(hwnd, CHK_DWORD),SW_HIDE);
+ ShowWindow(GetDlgItem(hwnd, CHK_STRING),SW_HIDE);
+ if (!((struct DBsetting*)lParam)->setting[0])
+ {
+ SetWindowText(hwnd, Translate("New STRING value"));
+ }
+ else
+ {
+ SetWindowText(hwnd, Translate("Edit STRING value"));
+ SetDlgItemText(hwnd, IDC_SETTINGNAME, ((struct DBsetting*)lParam)->setting);
+ SetDlgItemText(hwnd, IDC_STRING, ((struct DBsetting*)lParam)->dbv.pszVal);
+ }
+ break;
+ case DBVT_UTF8:
+ ShowWindow(GetDlgItem(hwnd, IDC_STRING),SW_SHOW);
+ ShowWindow(GetDlgItem(hwnd, IDC_SETTINGVALUE),SW_HIDE);
+ ShowWindow(GetDlgItem(hwnd, CHK_HEX),SW_HIDE);
+ ShowWindow(GetDlgItem(hwnd, CHK_DECIMAL),SW_HIDE);
+ ShowWindow(GetDlgItem(hwnd, GRP_BASE),SW_HIDE);
+ ShowWindow(GetDlgItem(hwnd, GRP_TYPE),SW_HIDE);
+ ShowWindow(GetDlgItem(hwnd, CHK_BYTE),SW_HIDE);
+ ShowWindow(GetDlgItem(hwnd, CHK_WORD),SW_HIDE);
+ ShowWindow(GetDlgItem(hwnd, CHK_DWORD),SW_HIDE);
+ ShowWindow(GetDlgItem(hwnd, CHK_STRING),SW_HIDE);
+ if (!((struct DBsetting*)lParam)->setting[0])
+ {
+ SetWindowText(hwnd, Translate("New UNICODE value"));
+ }
+ else
+ {
+ char *tmp = (((struct DBsetting*)lParam)->dbv.pszVal);
+ if (UOS)
+ {
+ int length = (int)strlen(tmp) + 1;
+ WCHAR *wc = (WCHAR*)_alloca(length*sizeof(WCHAR));
+ MultiByteToWideChar(CP_UTF8, 0, tmp, -1, wc, length);
+ SendMessageW(GetDlgItem(hwnd, IDC_STRING), WM_SETTEXT, 0, (LPARAM)wc);
+ }
+ else {
+ // convert from UTF8
+ SetDlgItemText(hwnd, IDC_STRING, tmp);
+ }
+ SetWindowText(hwnd, Translate("Edit UNICODE value"));
+ SetDlgItemText(hwnd, IDC_SETTINGNAME, ((struct DBsetting*)lParam)->setting);
+ }
+ break;
+ case DBVT_BLOB:
+ {
+ ShowWindow(GetDlgItem(hwnd, IDC_STRING),SW_HIDE);
+ ShowWindow(GetDlgItem(hwnd, IDC_SETTINGVALUE),SW_HIDE);
+ ShowWindow(GetDlgItem(hwnd, IDC_BLOB),SW_SHOW);
+
+ if (!((struct DBsetting*)lParam)->setting[0])
+ {
+ SetWindowText(hwnd, Translate("New BLOB value"));
+ }
+ else
+ {
+ int j;
+ char tmp[16];
+ int len = ((struct DBsetting*)lParam)->dbv.cpbVal;
+ char *data = (char*)_alloca(3*(len+1)+10);
+ BYTE *p = ((struct DBsetting*)lParam)->dbv.pbVal;
+
+ if (!data) return TRUE;
+ data[0] = '\0';
+
+ for(j=0; j<len; j++)
+ {
+ mir_snprintf(tmp, SIZEOF(tmp), "%02X ", (BYTE)p[j]);
+ strcat(data, tmp);
+ }
+
+ SetWindowText(hwnd, Translate("Edit BLOB value"));
+ SetDlgItemText(hwnd, IDC_SETTINGNAME, ((struct DBsetting*)lParam)->setting);
+ SetDlgItemText(hwnd, IDC_BLOB, data);
+ }
+ ShowWindow(GetDlgItem(hwnd, CHK_HEX),SW_HIDE);
+ ShowWindow(GetDlgItem(hwnd, CHK_DECIMAL),SW_HIDE);
+ ShowWindow(GetDlgItem(hwnd, GRP_BASE),SW_HIDE);
+ ShowWindow(GetDlgItem(hwnd, GRP_TYPE),SW_HIDE);
+ ShowWindow(GetDlgItem(hwnd, CHK_BYTE),SW_HIDE);
+ ShowWindow(GetDlgItem(hwnd, CHK_WORD),SW_HIDE);
+ ShowWindow(GetDlgItem(hwnd, CHK_DWORD),SW_HIDE);
+ ShowWindow(GetDlgItem(hwnd, CHK_STRING),SW_HIDE);
+ }
+ break;
+ default: return TRUE;
+ }
+ TranslateDialogDefault(hwnd);
+ }
+ return TRUE;
+ case WM_COMMAND:
+ switch(LOWORD(wParam))
+ {
+ case CHK_BYTE:
+ case CHK_WORD:
+ case CHK_DWORD:
+ EnableWindow(GetDlgItem(hwnd, CHK_HEX),1);
+ EnableWindow(GetDlgItem(hwnd, CHK_DECIMAL),1);
+ CheckRadioButton(hwnd, CHK_BYTE, CHK_STRING, LOWORD(wParam));
+ break;
+ case CHK_STRING:
+ EnableWindow(GetDlgItem(hwnd, CHK_HEX),0);
+ EnableWindow(GetDlgItem(hwnd, CHK_DECIMAL),0);
+ CheckRadioButton(hwnd, CHK_BYTE, CHK_STRING, LOWORD(wParam));
+ break;
+
+ case CHK_HEX:
+ case CHK_DECIMAL:
+ CheckRadioButton(hwnd,CHK_HEX, CHK_DECIMAL, LOWORD(wParam));
+ {
+ char *setting, temp[32];
+ int settingLength, tmp;
+ settingLength = GetWindowTextLength(GetDlgItem(hwnd, IDC_SETTINGVALUE));
+ if (settingLength)
+ {
+ setting = (char*)_alloca(settingLength + 1);
+ if (setting)
+ {
+ // havta convert it with sprintf()
+ GetWindowText(GetDlgItem(hwnd, IDC_SETTINGVALUE), setting, settingLength+1);
+ if (LOWORD(wParam) == CHK_DECIMAL && IsDlgButtonChecked(hwnd, CHK_DECIMAL))
+ {
+ sscanf(setting, "%X", &tmp);
+ mir_snprintf(temp, SIZEOF(temp), "%ld", tmp);
+ }
+ else
+ {
+ sscanf(setting, "%d", &tmp);
+ mir_snprintf(temp, SIZEOF(temp), "%X", tmp);
+ }
+ SetWindowText(GetDlgItem(hwnd, IDC_SETTINGVALUE), temp);
+ }
+ }
+ }
+ break;
+ case IDOK:
+ {
+ struct DBsetting *dbsetting = (struct DBsetting*)GetWindowLongPtr(hwnd,GWLP_USERDATA);
+ char *setting, *value;
+ int settingLength, valueLength, valueID = IDC_SETTINGVALUE;
+ settingLength = GetWindowTextLength(GetDlgItem(hwnd, IDC_SETTINGNAME));
+
+ if (IsWindowVisible(GetDlgItem(hwnd,IDC_STRING)))
+ valueID = IDC_STRING;
+ else
+ if (IsWindowVisible(GetDlgItem(hwnd,IDC_SETTINGVALUE)))
+ valueID = IDC_SETTINGVALUE;
+ else
+ if (IsWindowVisible(GetDlgItem(hwnd,IDC_BLOB)))
+ valueID = IDC_BLOB;
+ else
+ break;
+
+ valueLength = GetWindowTextLength(GetDlgItem(hwnd, valueID));
+
+ if (dbsetting->dbv.type == DBVT_UTF8 && UOS)
+ valueLength *= sizeof(WCHAR);
+
+ if (settingLength)
+ {
+ int settingValue;
+ setting = (char*)_alloca(settingLength + 1);
+
+ if (valueLength)
+ value = (char*)_alloca(valueLength + 2);
+ else
+ value = (char*)_alloca(2);
+
+ if (!setting || !value)
+ {
+ msg(Translate("Couldnt allocate enough memory!"), modFullname);
+ DestroyWindow(hwnd);
+ break;
+ }
+
+ GetWindowText(GetDlgItem(hwnd, IDC_SETTINGNAME), setting, settingLength+1);
+
+ if (valueLength)
+ {
+ if (dbsetting->dbv.type == DBVT_UTF8 && UOS)
+ SendMessageW(GetDlgItem(hwnd, valueID), WM_GETTEXT, valueLength+2, (LPARAM)value);
+ else
+ GetWindowText(GetDlgItem(hwnd, valueID), value, valueLength+1);
+ }
+ else
+ if (IsWindowVisible(GetDlgItem(hwnd,IDC_STRING)) || (saveAsType(hwnd)==3))
+ memcpy(value,"\0\0",2);
+ else
+ strcpy(value,"0");
+
+ // delete the old setting
+ if (mir_strcmp(setting, dbsetting->setting) && dbsetting->setting && (dbsetting->setting)[0] != 0)
+ DBDeleteContactSetting(dbsetting->hContact, dbsetting->module, dbsetting->setting);
+
+ // delete the setting if we are saving as a different type
+ switch (dbsetting->dbv.type)
+ {
+ case DBVT_BYTE:
+ if (saveAsType(hwnd) != 0) DBDeleteContactSetting(dbsetting->hContact, dbsetting->module, setting);
+ break;
+ case DBVT_WORD:
+ if (saveAsType(hwnd) != 1) DBDeleteContactSetting(dbsetting->hContact, dbsetting->module, setting);
+ break;
+ case DBVT_DWORD:
+ if (saveAsType(hwnd) != 2) DBDeleteContactSetting(dbsetting->hContact, dbsetting->module, setting);
+ break;
+ //case DBVT_ASCIIZ:
+ //DBWriteContactSettingString(dbsetting->hContact, dbsetting->module, setting, value);
+ //break;
+ }
+ // write the setting
+ switch (saveAsType(hwnd))
+ {
+ case 0:
+ if (IsDlgButtonChecked(hwnd, CHK_HEX)) sscanf(value, "%x", &settingValue);
+ else sscanf(value, "%d", &settingValue);
+ DBWriteContactSettingByte(dbsetting->hContact, dbsetting->module, setting, (BYTE)settingValue);
+ break;
+ case 1:
+ if (IsDlgButtonChecked(hwnd, CHK_HEX)) sscanf(value, "%x", &settingValue);
+ else sscanf(value, "%d", &settingValue);
+ DBWriteContactSettingWord(dbsetting->hContact, dbsetting->module, setting, (WORD)settingValue);
+ break;
+ case 2:
+ if (IsDlgButtonChecked(hwnd, CHK_HEX)) sscanf(value, "%x", &settingValue);
+ else sscanf(value, "%d", &settingValue);
+ DBWriteContactSettingDword(dbsetting->hContact, dbsetting->module, setting, (DWORD)settingValue);
+ break;
+ case 3:
+ if (dbsetting->dbv.type == DBVT_UTF8)
+ {
+ if (UOS)
+ DBWriteContactSettingWString(dbsetting->hContact, dbsetting->module, setting, (WCHAR*)value);
+ else
+ DBWriteContactSettingStringUtf(dbsetting->hContact, dbsetting->module, setting, value);
+ }
+ else
+ if (dbsetting->dbv.type == DBVT_BLOB)
+ WriteBlobFromString(dbsetting->hContact,dbsetting->module,setting,value,valueLength);
+ else
+ if (dbsetting->dbv.type == DBVT_ASCIIZ)
+ DBWriteContactSettingString(dbsetting->hContact, dbsetting->module, setting, value);
+ break;
+ }
+
+ }
+ } // fall through
+ case IDCANCEL:
+ {
+ struct DBsetting *dbsetting = (struct DBsetting*)GetWindowLongPtr(hwnd,GWLP_USERDATA);
+ mir_free(dbsetting->module);
+ mir_free(dbsetting->setting);
+ mir_free(dbsetting);
+ DestroyWindow(hwnd);
+ }
+ break;
+ }
+ break;
+ }
+ return 0;
+}
+
+void editSetting(HANDLE hContact, char* module, char* setting)
+{
+ DBVARIANT dbv = {0}; // freed in the dialog
+ if (!GetSetting(hContact,module, setting, &dbv))
+ {
+ struct DBsetting *dbsetting = (struct DBsetting *)mir_alloc(sizeof(struct DBsetting)); // gets free()ed in the window proc
+
+ dbsetting->dbv = dbv; // freed in the dialog
+ dbsetting->hContact = hContact;
+ dbsetting->module = mir_tstrdup(module);
+ dbsetting->setting = mir_tstrdup(setting);
+
+ if (dbv.type == DBVT_UTF8 && UOS)
+ CreateDialogParamW(hInst, MAKEINTRESOURCEW(IDD_EDIT_SETTING), hwnd2mainWindow, EditSettingDlgProc, (LPARAM)dbsetting);
+ else
+ CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_EDIT_SETTING), hwnd2mainWindow, EditSettingDlgProc, (LPARAM)dbsetting);
+ }
+} \ No newline at end of file
diff --git a/plugins/dbeditorpp/copymodule.cpp b/plugins/dbeditorpp/copymodule.cpp
new file mode 100644
index 0000000000..25489a7f52
--- /dev/null
+++ b/plugins/dbeditorpp/copymodule.cpp
@@ -0,0 +1,197 @@
+#include "headers.h"
+
+void copyModule(char* module, HANDLE hContactFrom, HANDLE hContactTo)
+{
+ ModuleSettingLL msll;
+ struct ModSetLinkLinkItem *setting;
+
+ EnumSettings(hContactFrom,module, &msll);
+
+ setting = msll.first;
+ while(setting)
+ {
+ DBVARIANT dbv;
+ if (!GetSetting(hContactFrom, module, setting->name, &dbv))
+ {
+ switch (dbv.type)
+ {
+ case DBVT_BYTE:
+ DBWriteContactSettingByte(hContactTo, module, setting->name, dbv.bVal);
+ break;
+ case DBVT_WORD:
+ DBWriteContactSettingWord(hContactTo, module, setting->name, dbv.wVal);
+ break;
+ case DBVT_DWORD:
+ DBWriteContactSettingDword(hContactTo, module, setting->name, dbv.dVal);
+ break;
+ case DBVT_ASCIIZ:
+ DBWriteContactSettingString(hContactTo, module, setting->name, dbv.pszVal);
+ break;
+ case DBVT_UTF8:
+ DBWriteContactSettingStringUtf(hContactTo, module, setting->name, dbv.pszVal);
+ break;
+ case DBVT_BLOB:
+ DBWriteContactSettingBlob(hContactTo, module, setting->name, dbv.pbVal, dbv.cpbVal);
+ break;
+ }
+ }
+ DBFreeVariant(&dbv);
+ setting = (struct ModSetLinkLinkItem *)setting->next;
+ }
+ FreeModuleSettingLL(&msll);
+}
+
+INT_PTR CALLBACK copyModDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ ModuleAndContact *mac = (ModuleAndContact *)GetWindowLongPtr(hwnd,GWLP_USERDATA);
+ if (msg == WM_INITDIALOG)
+ {
+ int index, loaded;
+ char szProto[256];
+ HANDLE hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+
+ while (hContact)
+ {
+ if (GetValue(hContact,"Protocol","p",szProto,SIZEOF(szProto)))
+ loaded = IsProtocolLoaded(szProto);
+ else
+ loaded = 0;
+
+ // filter
+ if ((loaded && Mode == MODE_UNLOADED) || (!loaded && Mode == MODE_LOADED))
+ {
+ hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0);
+ continue;
+ }
+
+ // contacts name
+ if (UOS)
+ {
+ DBVARIANT dbv ={0};
+ WCHAR nick[256];
+ WCHAR protoW[256]; // unicode proto
+
+ if (szProto[0])
+ a2u(szProto, protoW, SIZEOF(protoW));
+ else
+ protoW[0] = 0;
+
+ if (!szProto[0] || !loaded)
+ {
+ if (protoW)
+ {
+ if (Order)
+ mir_snwprintf(nick, SIZEOF(nick), L"(%s) %s %s", protoW, GetContactName(hContact, szProto, 1), L"(UNLOADED)");
+ else
+ mir_snwprintf(nick, SIZEOF(nick), L"%s (%s) %s", GetContactName(hContact, szProto, 1), protoW, L"(UNLOADED)");
+ }
+ else
+ wcscpy(nick, nick_unknownW);
+ }
+ else
+ {
+ if (Order)
+ mir_snwprintf(nick, SIZEOF(nick), L"(%s) %s", protoW, GetContactName(hContact, szProto, 1));
+ else
+ mir_snwprintf(nick, SIZEOF(nick), L"%s (%s)", GetContactName(hContact, szProto, 1), protoW);
+ }
+
+ index = SendMessageW(GetDlgItem(hwnd, IDC_CONTACTS), CB_ADDSTRING, 0, (LPARAM)nick);
+ SendMessageW(GetDlgItem(hwnd, IDC_CONTACTS), CB_SETITEMDATA, index, (LPARAM)hContact);
+ }
+ else
+ {
+ char nick[256];
+
+ if (!szProto[0] || !loaded)
+ {
+ if (szProto[0])
+ {
+ if (Order)
+ mir_snprintf(nick, SIZEOF(nick), "(%s) %s %s", szProto, (char*)GetContactName(hContact, szProto, 0), "(UNLOADED)");
+ else
+ mir_snprintf(nick, SIZEOF(nick), "%s (%s) %s", (char*)GetContactName(hContact, szProto, 0), szProto, "(UNLOADED)");
+ }
+ else
+ strcpy(nick, nick_unknown);
+ }
+ else
+ {
+ if (Order)
+ mir_snprintf(nick, SIZEOF(nick), "(%s) %s", szProto, (char*)GetContactName(hContact, szProto, 0));
+ else
+ mir_snprintf(nick, SIZEOF(nick), "%s (%s)", (char*)GetContactName(hContact, szProto, 0), szProto);
+ }
+
+ index = SendMessage(GetDlgItem(hwnd, IDC_CONTACTS), CB_ADDSTRING, 0, (LPARAM)nick);
+ SendMessage(GetDlgItem(hwnd, IDC_CONTACTS), CB_SETITEMDATA, index, (LPARAM)hContact);
+ }
+
+ hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)(HANDLE)hContact, 0);
+ }
+
+ index = (int)SendMessage(GetDlgItem(hwnd, IDC_CONTACTS), CB_INSERTSTRING, 0, (LPARAM)(char*)Translate("Settings"));
+ SendMessage(GetDlgItem(hwnd, IDC_CONTACTS), CB_SETITEMDATA, index, (LPARAM)0);
+ SendMessage(GetDlgItem(hwnd, IDC_CONTACTS), CB_SETCURSEL, index, 0);
+
+ SetWindowLongPtr(hwnd,GWLP_USERDATA,lParam);
+ TranslateDialogDefault(hwnd);
+ }
+ else
+ if (msg == WM_COMMAND)
+ {
+ switch(LOWORD(wParam))
+ {
+ case CHK_COPY2ALL:
+ EnableWindow(GetDlgItem(hwnd, IDC_CONTACTS),!IsDlgButtonChecked(hwnd,CHK_COPY2ALL));
+ break;
+ case IDOK:
+ {
+ HANDLE hContact;
+
+ if (!IsDlgButtonChecked(hwnd,CHK_COPY2ALL))
+ {
+ hContact = (HANDLE)SendMessage(GetDlgItem(hwnd, IDC_CONTACTS), CB_GETITEMDATA, SendMessage(GetDlgItem(hwnd, IDC_CONTACTS), CB_GETCURSEL, 0, 0), 0);
+ copyModule(mac->module, mac->hContact, hContact);
+ }
+ else
+ {
+ SetCursor(LoadCursor(NULL,IDC_WAIT));
+ hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+
+ while (hContact)
+ {
+ copyModule(mac->module, mac->hContact, hContact);
+ hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)(HANDLE)hContact, 0);
+ }
+
+ SetCursor(LoadCursor(NULL,IDC_ARROW));
+ }
+ mir_free(mac);
+ refreshTree(1);
+ DestroyWindow(hwnd);
+ }
+ break;
+ case IDCANCEL:
+ {
+ mir_free(mac);
+ DestroyWindow(hwnd);
+ }
+ break;
+ }
+ }
+ return 0;
+}
+
+void copyModuleMenuItem(char* module, HANDLE hContact)
+{
+ HWND hwnd;
+ ModuleAndContact *mac = (ModuleAndContact *)mir_calloc(sizeof(ModuleAndContact));
+ mac->hContact = hContact;
+ strncpy(mac->module, module, 255);
+
+ if (UOS)
+ hwnd = CreateDialogParamW(hInst, MAKEINTRESOURCEW(IDD_COPY_MOD), 0, copyModDlgProc, (LPARAM)mac);
+ else
+ hwnd = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_COPY_MOD), 0, copyModDlgProc, (LPARAM)mac);
+} \ No newline at end of file
diff --git a/plugins/dbeditorpp/dbeditorpp.dep b/plugins/dbeditorpp/dbeditorpp.dep
new file mode 100644
index 0000000000..5ae3b8e32b
--- /dev/null
+++ b/plugins/dbeditorpp/dbeditorpp.dep
@@ -0,0 +1,51 @@
+# Microsoft Developer Studio Generated Dependency File, included by dbeditorpp.mak
+
+.\main.cpp : \
+ "..\..\include\m_clc.h"\
+ "..\..\include\m_clist.h"\
+ "..\..\include\m_clui.h"\
+ "..\..\include\m_database.h"\
+ "..\..\include\m_history.h"\
+ "..\..\include\m_icolib.h"\
+ "..\..\include\m_ignore.h"\
+ "..\..\include\m_langpack.h"\
+ "..\..\include\m_options.h"\
+ "..\..\include\m_plugins.h"\
+ "..\..\include\m_popup.h"\
+ "..\..\include\m_protocols.h"\
+ "..\..\include\m_protomod.h"\
+ "..\..\include\m_protosvc.h"\
+ "..\..\include\m_skin.h"\
+ "..\..\include\m_system.h"\
+ "..\..\include\m_userinfo.h"\
+ "..\..\include\m_utils.h"\
+ "..\..\include\newpluginapi.h"\
+ "..\..\include\statusmodes.h"\
+ "..\..\include\win2k.h"\
+ "..\externalapi\m_toptoolbar.h"\
+ "..\externalapi\m_updater.h"\
+ ".\headers.h"\
+ ".\modsettingenum.h"\
+ ".\version.h"\
+
+
+.\resource.rc : \
+ ".\res\Contacts.ico"\
+ ".\res\dbepp.ico"\
+ ".\res\handle.ico"\
+ ".\res\Icon_1.ico"\
+ ".\res\Icon_14.ico"\
+ ".\res\Icon_15.ico"\
+ ".\res\Icon_16.ico"\
+ ".\res\Icon_17.ico"\
+ ".\res\Icon_18.ico"\
+ ".\res\Icon_4.ico"\
+ ".\res\offline2.ico"\
+ ".\res\online2.ico"\
+ ".\res\Red.ico"\
+ ".\res\Red_open.ico"\
+ ".\res\unicode.ico"\
+ ".\res\usermenu.ico"\
+ ".\res\Yellow.ico"\
+ ".\res\Yellow_open.ico"\
+
diff --git a/plugins/dbeditorpp/dbeditorpp.dsp b/plugins/dbeditorpp/dbeditorpp.dsp
new file mode 100644
index 0000000000..bf67828f7e
--- /dev/null
+++ b/plugins/dbeditorpp/dbeditorpp.dsp
@@ -0,0 +1,293 @@
+# Microsoft Developer Studio Project File - Name="dbeditorpp" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=dbeditorpp - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "dbeditorpp.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "dbeditorpp.mak" CFG="dbeditorpp - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "dbeditorpp - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "dbeditorpp - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "dbeditorpp - Win32 Release Unicode" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "dbeditorpp - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DBEDITORPP_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX- /O1 /I "../../include" /I "../ExternalAPI" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DBEDITORPP_EXPORTS" /FR /Yu"headers.h" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 gdi32.lib winspool.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib comdlg32.lib advapi32.lib shell32.lib shlwapi.lib comctl32.lib /nologo /dll /machine:I386 /out:"../../bin/release/plugins/svc_dbepp.dll"
+
+!ELSEIF "$(CFG)" == "dbeditorpp - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DBEDITORPP_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX- /ZI /Od /I "../../include" /I "../ExternalAPI" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DBEDITORPP_EXPORTS" /Yu"headers.h" /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 gdi32.lib winspool.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib comdlg32.lib advapi32.lib shell32.lib shlwapi.lib comctl32.lib /nologo /dll /debug /machine:I386 /out:"../../bin/debug/plugins/svc_dbepp.dll" /pdbtype:sept
+
+!ELSEIF "$(CFG)" == "dbeditorpp - Win32 Release Unicode"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "dbeditorpp___Win32_Release_Unicode"
+# PROP BASE Intermediate_Dir "dbeditorpp___Win32_Release_Unicode"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir ".\Release_Unicode"
+# PROP Intermediate_Dir ".\Release_Unicode"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /GX /O1 /I "../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DBEDITORPP_EXPORTS" /FR /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX- /Ox /Ot /Og /Os /I "../../include" /I "../ExternalAPI" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DBEDITORPP_EXPORTS" /FR /Yu"headers.h" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"../../bin/release/plugins/dbeditorpp.dll"
+# ADD LINK32 kernel32.lib user32.lib comdlg32.lib advapi32.lib shell32.lib shlwapi.lib comctl32.lib /nologo /dll /debug /machine:I386 /out:"../../bin/release unicode/plugins/svc_dbepp.dll"
+
+!ENDIF
+
+# Begin Target
+
+# Name "dbeditorpp - Win32 Release"
+# Name "dbeditorpp - Win32 Debug"
+# Name "dbeditorpp - Win32 Release Unicode"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Group "ModSetting Enuming"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\modsettingenum.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\modsettingenum.h
+# End Source File
+# End Group
+# Begin Group "dialogs"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\addeditsettingsdlg.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\copymodule.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\deletemodule.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\findwindow.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\main_window.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\moduletree.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\options.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\settinglist.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\watchedvars.cpp
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\exportimport.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\icons.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\knownmodules.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\main.cpp
+# ADD CPP /Yc"headers.h"
+# End Source File
+# Begin Source File
+
+SOURCE=.\modules.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\threads.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\headers.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\IcoLib.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\icons.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# Begin Source File
+
+SOURCE=.\res\Contacts.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\dbeditorpp_readme.txt
+# End Source File
+# Begin Source File
+
+SOURCE=.\dbeditorpp_translation.txt
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\Icon_1.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\Icon_14.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\Icon_15.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\Icon_16.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\Icon_17.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\Icon_18.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\Icon_4.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\offline2.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\online2.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\Red.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\Red_open.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource.rc
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\Yellow.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\Yellow_open.ico
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/plugins/dbeditorpp/dbeditorpp.dsw b/plugins/dbeditorpp/dbeditorpp.dsw
new file mode 100644
index 0000000000..8575853b0b
--- /dev/null
+++ b/plugins/dbeditorpp/dbeditorpp.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "dbeditorpp"=.\dbeditorpp.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/plugins/dbeditorpp/dbeditorpp.mak b/plugins/dbeditorpp/dbeditorpp.mak
new file mode 100644
index 0000000000..fb38d39ecf
--- /dev/null
+++ b/plugins/dbeditorpp/dbeditorpp.mak
@@ -0,0 +1,737 @@
+# Microsoft Developer Studio Generated NMAKE File, Based on dbeditorpp.dsp
+!IF "$(CFG)" == ""
+CFG=dbeditorpp - Win32 Release Unicode
+!MESSAGE No configuration specified. Defaulting to dbeditorpp - Win32 Release Unicode.
+!ENDIF
+
+!IF "$(CFG)" != "dbeditorpp - Win32 Release" && "$(CFG)" != "dbeditorpp - Win32 Debug" && "$(CFG)" != "dbeditorpp - Win32 Release Unicode"
+!MESSAGE Invalid configuration "$(CFG)" specified.
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "dbeditorpp.mak" CFG="dbeditorpp - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "dbeditorpp - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "dbeditorpp - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "dbeditorpp - Win32 Release Unicode" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+!ERROR An invalid configuration is specified.
+!ENDIF
+
+!IF "$(OS)" == "Windows_NT"
+NULL=
+!ELSE
+NULL=nul
+!ENDIF
+
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "dbeditorpp - Win32 Release"
+
+OUTDIR=.\Release
+INTDIR=.\Release
+# Begin Custom Macros
+OutDir=.\Release
+# End Custom Macros
+
+ALL : "..\..\bin\release\plugins\svc_dbepp.dll" "$(OUTDIR)\dbeditorpp.bsc"
+
+
+CLEAN :
+ -@erase "$(INTDIR)\addeditsettingsdlg.obj"
+ -@erase "$(INTDIR)\addeditsettingsdlg.sbr"
+ -@erase "$(INTDIR)\copymodule.obj"
+ -@erase "$(INTDIR)\copymodule.sbr"
+ -@erase "$(INTDIR)\dbeditorpp.pch"
+ -@erase "$(INTDIR)\deletemodule.obj"
+ -@erase "$(INTDIR)\deletemodule.sbr"
+ -@erase "$(INTDIR)\exportimport.obj"
+ -@erase "$(INTDIR)\exportimport.sbr"
+ -@erase "$(INTDIR)\findwindow.obj"
+ -@erase "$(INTDIR)\findwindow.sbr"
+ -@erase "$(INTDIR)\icons.obj"
+ -@erase "$(INTDIR)\icons.sbr"
+ -@erase "$(INTDIR)\knownmodules.obj"
+ -@erase "$(INTDIR)\knownmodules.sbr"
+ -@erase "$(INTDIR)\main.obj"
+ -@erase "$(INTDIR)\main.sbr"
+ -@erase "$(INTDIR)\main_window.obj"
+ -@erase "$(INTDIR)\main_window.sbr"
+ -@erase "$(INTDIR)\modsettingenum.obj"
+ -@erase "$(INTDIR)\modsettingenum.sbr"
+ -@erase "$(INTDIR)\modules.obj"
+ -@erase "$(INTDIR)\modules.sbr"
+ -@erase "$(INTDIR)\moduletree.obj"
+ -@erase "$(INTDIR)\moduletree.sbr"
+ -@erase "$(INTDIR)\options.obj"
+ -@erase "$(INTDIR)\options.sbr"
+ -@erase "$(INTDIR)\resource.res"
+ -@erase "$(INTDIR)\settinglist.obj"
+ -@erase "$(INTDIR)\settinglist.sbr"
+ -@erase "$(INTDIR)\threads.obj"
+ -@erase "$(INTDIR)\threads.sbr"
+ -@erase "$(INTDIR)\vc60.idb"
+ -@erase "$(INTDIR)\watchedvars.obj"
+ -@erase "$(INTDIR)\watchedvars.sbr"
+ -@erase "$(OUTDIR)\dbeditorpp.bsc"
+ -@erase "$(OUTDIR)\svc_dbepp.exp"
+ -@erase "$(OUTDIR)\svc_dbepp.lib"
+ -@erase "..\..\bin\release\plugins\svc_dbepp.dll"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP_PROJ=/nologo /MD /W3 /GX- /O1 /I "../../include" /I "../ExternalAPI" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DBEDITORPP_EXPORTS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\dbeditorpp.pch" /Yu"headers.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
+MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\resource.res" /d "NDEBUG"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\dbeditorpp.bsc"
+BSC32_SBRS= \
+ "$(INTDIR)\modsettingenum.sbr" \
+ "$(INTDIR)\addeditsettingsdlg.sbr" \
+ "$(INTDIR)\copymodule.sbr" \
+ "$(INTDIR)\deletemodule.sbr" \
+ "$(INTDIR)\findwindow.sbr" \
+ "$(INTDIR)\main_window.sbr" \
+ "$(INTDIR)\moduletree.sbr" \
+ "$(INTDIR)\options.sbr" \
+ "$(INTDIR)\settinglist.sbr" \
+ "$(INTDIR)\watchedvars.sbr" \
+ "$(INTDIR)\exportimport.sbr" \
+ "$(INTDIR)\icons.sbr" \
+ "$(INTDIR)\knownmodules.sbr" \
+ "$(INTDIR)\main.sbr" \
+ "$(INTDIR)\modules.sbr" \
+ "$(INTDIR)\threads.sbr"
+
+"$(OUTDIR)\dbeditorpp.bsc" : "$(OUTDIR)" $(BSC32_SBRS)
+ $(BSC32) @<<
+ $(BSC32_FLAGS) $(BSC32_SBRS)
+<<
+
+LINK32=link.exe
+LINK32_FLAGS=gdi32.lib winspool.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib comdlg32.lib advapi32.lib shell32.lib shlwapi.lib comctl32.lib /nologo /dll /incremental:no /pdb:"$(OUTDIR)\svc_dbepp.pdb" /machine:I386 /out:"../../bin/release/plugins/svc_dbepp.dll" /implib:"$(OUTDIR)\svc_dbepp.lib"
+LINK32_OBJS= \
+ "$(INTDIR)\modsettingenum.obj" \
+ "$(INTDIR)\addeditsettingsdlg.obj" \
+ "$(INTDIR)\copymodule.obj" \
+ "$(INTDIR)\deletemodule.obj" \
+ "$(INTDIR)\findwindow.obj" \
+ "$(INTDIR)\main_window.obj" \
+ "$(INTDIR)\moduletree.obj" \
+ "$(INTDIR)\options.obj" \
+ "$(INTDIR)\settinglist.obj" \
+ "$(INTDIR)\watchedvars.obj" \
+ "$(INTDIR)\exportimport.obj" \
+ "$(INTDIR)\icons.obj" \
+ "$(INTDIR)\knownmodules.obj" \
+ "$(INTDIR)\main.obj" \
+ "$(INTDIR)\modules.obj" \
+ "$(INTDIR)\threads.obj" \
+ "$(INTDIR)\resource.res"
+
+"..\..\bin\release\plugins\svc_dbepp.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ELSEIF "$(CFG)" == "dbeditorpp - Win32 Debug"
+
+OUTDIR=.\Debug
+INTDIR=.\Debug
+
+ALL : "..\..\bin\debug\plugins\svc_dbepp.dll"
+
+
+CLEAN :
+ -@erase "$(INTDIR)\addeditsettingsdlg.obj"
+ -@erase "$(INTDIR)\copymodule.obj"
+ -@erase "$(INTDIR)\dbeditorpp.pch"
+ -@erase "$(INTDIR)\deletemodule.obj"
+ -@erase "$(INTDIR)\exportimport.obj"
+ -@erase "$(INTDIR)\findwindow.obj"
+ -@erase "$(INTDIR)\icons.obj"
+ -@erase "$(INTDIR)\knownmodules.obj"
+ -@erase "$(INTDIR)\main.obj"
+ -@erase "$(INTDIR)\main_window.obj"
+ -@erase "$(INTDIR)\modsettingenum.obj"
+ -@erase "$(INTDIR)\modules.obj"
+ -@erase "$(INTDIR)\moduletree.obj"
+ -@erase "$(INTDIR)\options.obj"
+ -@erase "$(INTDIR)\resource.res"
+ -@erase "$(INTDIR)\settinglist.obj"
+ -@erase "$(INTDIR)\threads.obj"
+ -@erase "$(INTDIR)\vc60.idb"
+ -@erase "$(INTDIR)\vc60.pdb"
+ -@erase "$(INTDIR)\watchedvars.obj"
+ -@erase "$(OUTDIR)\svc_dbepp.exp"
+ -@erase "$(OUTDIR)\svc_dbepp.lib"
+ -@erase "$(OUTDIR)\svc_dbepp.pdb"
+ -@erase "..\..\bin\debug\plugins\svc_dbepp.dll"
+ -@erase "..\..\bin\debug\plugins\svc_dbepp.ilk"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP_PROJ=/nologo /MDd /W3 /Gm /GX- /ZI /Od /I "../../include" /I "../ExternalAPI" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DBEDITORPP_EXPORTS" /Fp"$(INTDIR)\dbeditorpp.pch" /Yu"headers.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c
+MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\resource.res" /d "_DEBUG"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\dbeditorpp.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=gdi32.lib winspool.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib comdlg32.lib advapi32.lib shell32.lib shlwapi.lib comctl32.lib /nologo /dll /incremental:yes /pdb:"$(OUTDIR)\svc_dbepp.pdb" /debug /machine:I386 /out:"../../bin/debug/plugins/svc_dbepp.dll" /implib:"$(OUTDIR)\svc_dbepp.lib" /pdbtype:sept
+LINK32_OBJS= \
+ "$(INTDIR)\modsettingenum.obj" \
+ "$(INTDIR)\addeditsettingsdlg.obj" \
+ "$(INTDIR)\copymodule.obj" \
+ "$(INTDIR)\deletemodule.obj" \
+ "$(INTDIR)\findwindow.obj" \
+ "$(INTDIR)\main_window.obj" \
+ "$(INTDIR)\moduletree.obj" \
+ "$(INTDIR)\options.obj" \
+ "$(INTDIR)\settinglist.obj" \
+ "$(INTDIR)\watchedvars.obj" \
+ "$(INTDIR)\exportimport.obj" \
+ "$(INTDIR)\icons.obj" \
+ "$(INTDIR)\knownmodules.obj" \
+ "$(INTDIR)\main.obj" \
+ "$(INTDIR)\modules.obj" \
+ "$(INTDIR)\threads.obj" \
+ "$(INTDIR)\resource.res"
+
+"..\..\bin\debug\plugins\svc_dbepp.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ELSEIF "$(CFG)" == "dbeditorpp - Win32 Release Unicode"
+
+OUTDIR=.\Release_Unicode
+INTDIR=.\Release_Unicode
+# Begin Custom Macros
+OutDir=.\Release_Unicode
+# End Custom Macros
+
+ALL : "..\..\bin\release unicode\plugins\svc_dbepp.dll" "$(OUTDIR)\dbeditorpp.bsc"
+
+
+CLEAN :
+ -@erase "$(INTDIR)\addeditsettingsdlg.obj"
+ -@erase "$(INTDIR)\addeditsettingsdlg.sbr"
+ -@erase "$(INTDIR)\copymodule.obj"
+ -@erase "$(INTDIR)\copymodule.sbr"
+ -@erase "$(INTDIR)\dbeditorpp.pch"
+ -@erase "$(INTDIR)\deletemodule.obj"
+ -@erase "$(INTDIR)\deletemodule.sbr"
+ -@erase "$(INTDIR)\exportimport.obj"
+ -@erase "$(INTDIR)\exportimport.sbr"
+ -@erase "$(INTDIR)\findwindow.obj"
+ -@erase "$(INTDIR)\findwindow.sbr"
+ -@erase "$(INTDIR)\icons.obj"
+ -@erase "$(INTDIR)\icons.sbr"
+ -@erase "$(INTDIR)\knownmodules.obj"
+ -@erase "$(INTDIR)\knownmodules.sbr"
+ -@erase "$(INTDIR)\main.obj"
+ -@erase "$(INTDIR)\main.sbr"
+ -@erase "$(INTDIR)\main_window.obj"
+ -@erase "$(INTDIR)\main_window.sbr"
+ -@erase "$(INTDIR)\modsettingenum.obj"
+ -@erase "$(INTDIR)\modsettingenum.sbr"
+ -@erase "$(INTDIR)\modules.obj"
+ -@erase "$(INTDIR)\modules.sbr"
+ -@erase "$(INTDIR)\moduletree.obj"
+ -@erase "$(INTDIR)\moduletree.sbr"
+ -@erase "$(INTDIR)\options.obj"
+ -@erase "$(INTDIR)\options.sbr"
+ -@erase "$(INTDIR)\resource.res"
+ -@erase "$(INTDIR)\settinglist.obj"
+ -@erase "$(INTDIR)\settinglist.sbr"
+ -@erase "$(INTDIR)\threads.obj"
+ -@erase "$(INTDIR)\threads.sbr"
+ -@erase "$(INTDIR)\vc60.idb"
+ -@erase "$(INTDIR)\watchedvars.obj"
+ -@erase "$(INTDIR)\watchedvars.sbr"
+ -@erase "$(OUTDIR)\dbeditorpp.bsc"
+ -@erase "$(OUTDIR)\svc_dbepp.exp"
+ -@erase "$(OUTDIR)\svc_dbepp.lib"
+ -@erase "$(OUTDIR)\svc_dbepp.pdb"
+ -@erase "..\..\bin\release unicode\plugins\svc_dbepp.dll"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP_PROJ=/nologo /MD /W3 /GX- /Ox /Ot /Og /Os /I "../../include" /I "../ExternalAPI" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DBEDITORPP_EXPORTS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\dbeditorpp.pch" /Yu"headers.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
+MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\resource.res" /d "NDEBUG"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\dbeditorpp.bsc"
+BSC32_SBRS= \
+ "$(INTDIR)\modsettingenum.sbr" \
+ "$(INTDIR)\addeditsettingsdlg.sbr" \
+ "$(INTDIR)\copymodule.sbr" \
+ "$(INTDIR)\deletemodule.sbr" \
+ "$(INTDIR)\findwindow.sbr" \
+ "$(INTDIR)\main_window.sbr" \
+ "$(INTDIR)\moduletree.sbr" \
+ "$(INTDIR)\options.sbr" \
+ "$(INTDIR)\settinglist.sbr" \
+ "$(INTDIR)\watchedvars.sbr" \
+ "$(INTDIR)\exportimport.sbr" \
+ "$(INTDIR)\icons.sbr" \
+ "$(INTDIR)\knownmodules.sbr" \
+ "$(INTDIR)\main.sbr" \
+ "$(INTDIR)\modules.sbr" \
+ "$(INTDIR)\threads.sbr"
+
+"$(OUTDIR)\dbeditorpp.bsc" : "$(OUTDIR)" $(BSC32_SBRS)
+ $(BSC32) @<<
+ $(BSC32_FLAGS) $(BSC32_SBRS)
+<<
+
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib user32.lib comdlg32.lib advapi32.lib shell32.lib shlwapi.lib comctl32.lib /nologo /dll /incremental:no /pdb:"$(OUTDIR)\svc_dbepp.pdb" /debug /machine:I386 /out:"../../bin/release unicode/plugins/svc_dbepp.dll" /implib:"$(OUTDIR)\svc_dbepp.lib"
+LINK32_OBJS= \
+ "$(INTDIR)\modsettingenum.obj" \
+ "$(INTDIR)\addeditsettingsdlg.obj" \
+ "$(INTDIR)\copymodule.obj" \
+ "$(INTDIR)\deletemodule.obj" \
+ "$(INTDIR)\findwindow.obj" \
+ "$(INTDIR)\main_window.obj" \
+ "$(INTDIR)\moduletree.obj" \
+ "$(INTDIR)\options.obj" \
+ "$(INTDIR)\settinglist.obj" \
+ "$(INTDIR)\watchedvars.obj" \
+ "$(INTDIR)\exportimport.obj" \
+ "$(INTDIR)\icons.obj" \
+ "$(INTDIR)\knownmodules.obj" \
+ "$(INTDIR)\main.obj" \
+ "$(INTDIR)\modules.obj" \
+ "$(INTDIR)\threads.obj" \
+ "$(INTDIR)\resource.res"
+
+"..\..\bin\release unicode\plugins\svc_dbepp.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ENDIF
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+
+!IF "$(NO_EXTERNAL_DEPS)" != "1"
+!IF EXISTS("dbeditorpp.dep")
+!INCLUDE "dbeditorpp.dep"
+!ELSE
+!MESSAGE Warning: cannot find "dbeditorpp.dep"
+!ENDIF
+!ENDIF
+
+
+!IF "$(CFG)" == "dbeditorpp - Win32 Release" || "$(CFG)" == "dbeditorpp - Win32 Debug" || "$(CFG)" == "dbeditorpp - Win32 Release Unicode"
+SOURCE=.\modsettingenum.cpp
+
+!IF "$(CFG)" == "dbeditorpp - Win32 Release"
+
+
+"$(INTDIR)\modsettingenum.obj" "$(INTDIR)\modsettingenum.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\dbeditorpp.pch"
+
+
+!ELSEIF "$(CFG)" == "dbeditorpp - Win32 Debug"
+
+
+"$(INTDIR)\modsettingenum.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\dbeditorpp.pch"
+
+
+!ELSEIF "$(CFG)" == "dbeditorpp - Win32 Release Unicode"
+
+
+"$(INTDIR)\modsettingenum.obj" "$(INTDIR)\modsettingenum.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\dbeditorpp.pch"
+
+
+!ENDIF
+
+SOURCE=.\addeditsettingsdlg.cpp
+
+!IF "$(CFG)" == "dbeditorpp - Win32 Release"
+
+
+"$(INTDIR)\addeditsettingsdlg.obj" "$(INTDIR)\addeditsettingsdlg.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\dbeditorpp.pch"
+
+
+!ELSEIF "$(CFG)" == "dbeditorpp - Win32 Debug"
+
+
+"$(INTDIR)\addeditsettingsdlg.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\dbeditorpp.pch"
+
+
+!ELSEIF "$(CFG)" == "dbeditorpp - Win32 Release Unicode"
+
+
+"$(INTDIR)\addeditsettingsdlg.obj" "$(INTDIR)\addeditsettingsdlg.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\dbeditorpp.pch"
+
+
+!ENDIF
+
+SOURCE=.\copymodule.cpp
+
+!IF "$(CFG)" == "dbeditorpp - Win32 Release"
+
+
+"$(INTDIR)\copymodule.obj" "$(INTDIR)\copymodule.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\dbeditorpp.pch"
+
+
+!ELSEIF "$(CFG)" == "dbeditorpp - Win32 Debug"
+
+
+"$(INTDIR)\copymodule.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\dbeditorpp.pch"
+
+
+!ELSEIF "$(CFG)" == "dbeditorpp - Win32 Release Unicode"
+
+
+"$(INTDIR)\copymodule.obj" "$(INTDIR)\copymodule.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\dbeditorpp.pch"
+
+
+!ENDIF
+
+SOURCE=.\deletemodule.cpp
+
+!IF "$(CFG)" == "dbeditorpp - Win32 Release"
+
+
+"$(INTDIR)\deletemodule.obj" "$(INTDIR)\deletemodule.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\dbeditorpp.pch"
+
+
+!ELSEIF "$(CFG)" == "dbeditorpp - Win32 Debug"
+
+
+"$(INTDIR)\deletemodule.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\dbeditorpp.pch"
+
+
+!ELSEIF "$(CFG)" == "dbeditorpp - Win32 Release Unicode"
+
+
+"$(INTDIR)\deletemodule.obj" "$(INTDIR)\deletemodule.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\dbeditorpp.pch"
+
+
+!ENDIF
+
+SOURCE=.\findwindow.cpp
+
+!IF "$(CFG)" == "dbeditorpp - Win32 Release"
+
+
+"$(INTDIR)\findwindow.obj" "$(INTDIR)\findwindow.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\dbeditorpp.pch"
+
+
+!ELSEIF "$(CFG)" == "dbeditorpp - Win32 Debug"
+
+
+"$(INTDIR)\findwindow.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\dbeditorpp.pch"
+
+
+!ELSEIF "$(CFG)" == "dbeditorpp - Win32 Release Unicode"
+
+
+"$(INTDIR)\findwindow.obj" "$(INTDIR)\findwindow.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\dbeditorpp.pch"
+
+
+!ENDIF
+
+SOURCE=.\main_window.cpp
+
+!IF "$(CFG)" == "dbeditorpp - Win32 Release"
+
+
+"$(INTDIR)\main_window.obj" "$(INTDIR)\main_window.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\dbeditorpp.pch"
+
+
+!ELSEIF "$(CFG)" == "dbeditorpp - Win32 Debug"
+
+
+"$(INTDIR)\main_window.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\dbeditorpp.pch"
+
+
+!ELSEIF "$(CFG)" == "dbeditorpp - Win32 Release Unicode"
+
+
+"$(INTDIR)\main_window.obj" "$(INTDIR)\main_window.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\dbeditorpp.pch"
+
+
+!ENDIF
+
+SOURCE=.\moduletree.cpp
+
+!IF "$(CFG)" == "dbeditorpp - Win32 Release"
+
+
+"$(INTDIR)\moduletree.obj" "$(INTDIR)\moduletree.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\dbeditorpp.pch"
+
+
+!ELSEIF "$(CFG)" == "dbeditorpp - Win32 Debug"
+
+
+"$(INTDIR)\moduletree.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\dbeditorpp.pch"
+
+
+!ELSEIF "$(CFG)" == "dbeditorpp - Win32 Release Unicode"
+
+
+"$(INTDIR)\moduletree.obj" "$(INTDIR)\moduletree.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\dbeditorpp.pch"
+
+
+!ENDIF
+
+SOURCE=.\options.cpp
+
+!IF "$(CFG)" == "dbeditorpp - Win32 Release"
+
+
+"$(INTDIR)\options.obj" "$(INTDIR)\options.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\dbeditorpp.pch"
+
+
+!ELSEIF "$(CFG)" == "dbeditorpp - Win32 Debug"
+
+
+"$(INTDIR)\options.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\dbeditorpp.pch"
+
+
+!ELSEIF "$(CFG)" == "dbeditorpp - Win32 Release Unicode"
+
+
+"$(INTDIR)\options.obj" "$(INTDIR)\options.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\dbeditorpp.pch"
+
+
+!ENDIF
+
+SOURCE=.\settinglist.cpp
+
+!IF "$(CFG)" == "dbeditorpp - Win32 Release"
+
+
+"$(INTDIR)\settinglist.obj" "$(INTDIR)\settinglist.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\dbeditorpp.pch"
+
+
+!ELSEIF "$(CFG)" == "dbeditorpp - Win32 Debug"
+
+
+"$(INTDIR)\settinglist.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\dbeditorpp.pch"
+
+
+!ELSEIF "$(CFG)" == "dbeditorpp - Win32 Release Unicode"
+
+
+"$(INTDIR)\settinglist.obj" "$(INTDIR)\settinglist.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\dbeditorpp.pch"
+
+
+!ENDIF
+
+SOURCE=.\watchedvars.cpp
+
+!IF "$(CFG)" == "dbeditorpp - Win32 Release"
+
+
+"$(INTDIR)\watchedvars.obj" "$(INTDIR)\watchedvars.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\dbeditorpp.pch"
+
+
+!ELSEIF "$(CFG)" == "dbeditorpp - Win32 Debug"
+
+
+"$(INTDIR)\watchedvars.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\dbeditorpp.pch"
+
+
+!ELSEIF "$(CFG)" == "dbeditorpp - Win32 Release Unicode"
+
+
+"$(INTDIR)\watchedvars.obj" "$(INTDIR)\watchedvars.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\dbeditorpp.pch"
+
+
+!ENDIF
+
+SOURCE=.\exportimport.cpp
+
+!IF "$(CFG)" == "dbeditorpp - Win32 Release"
+
+
+"$(INTDIR)\exportimport.obj" "$(INTDIR)\exportimport.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\dbeditorpp.pch"
+
+
+!ELSEIF "$(CFG)" == "dbeditorpp - Win32 Debug"
+
+
+"$(INTDIR)\exportimport.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\dbeditorpp.pch"
+
+
+!ELSEIF "$(CFG)" == "dbeditorpp - Win32 Release Unicode"
+
+
+"$(INTDIR)\exportimport.obj" "$(INTDIR)\exportimport.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\dbeditorpp.pch"
+
+
+!ENDIF
+
+SOURCE=.\icons.cpp
+
+!IF "$(CFG)" == "dbeditorpp - Win32 Release"
+
+
+"$(INTDIR)\icons.obj" "$(INTDIR)\icons.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\dbeditorpp.pch"
+
+
+!ELSEIF "$(CFG)" == "dbeditorpp - Win32 Debug"
+
+
+"$(INTDIR)\icons.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\dbeditorpp.pch"
+
+
+!ELSEIF "$(CFG)" == "dbeditorpp - Win32 Release Unicode"
+
+
+"$(INTDIR)\icons.obj" "$(INTDIR)\icons.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\dbeditorpp.pch"
+
+
+!ENDIF
+
+SOURCE=.\knownmodules.cpp
+
+!IF "$(CFG)" == "dbeditorpp - Win32 Release"
+
+
+"$(INTDIR)\knownmodules.obj" "$(INTDIR)\knownmodules.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\dbeditorpp.pch"
+
+
+!ELSEIF "$(CFG)" == "dbeditorpp - Win32 Debug"
+
+
+"$(INTDIR)\knownmodules.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\dbeditorpp.pch"
+
+
+!ELSEIF "$(CFG)" == "dbeditorpp - Win32 Release Unicode"
+
+
+"$(INTDIR)\knownmodules.obj" "$(INTDIR)\knownmodules.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\dbeditorpp.pch"
+
+
+!ENDIF
+
+SOURCE=.\main.cpp
+
+!IF "$(CFG)" == "dbeditorpp - Win32 Release"
+
+CPP_SWITCHES=/nologo /MD /W3 /GX- /O1 /I "../../include" /I "../ExternalAPI" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DBEDITORPP_EXPORTS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\dbeditorpp.pch" /Yc"headers.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
+
+"$(INTDIR)\main.obj" "$(INTDIR)\main.sbr" "$(INTDIR)\dbeditorpp.pch" : $(SOURCE) "$(INTDIR)"
+ $(CPP) @<<
+ $(CPP_SWITCHES) $(SOURCE)
+<<
+
+
+!ELSEIF "$(CFG)" == "dbeditorpp - Win32 Debug"
+
+CPP_SWITCHES=/nologo /MDd /W3 /Gm /GX- /ZI /Od /I "../../include" /I "../ExternalAPI" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DBEDITORPP_EXPORTS" /Fp"$(INTDIR)\dbeditorpp.pch" /Yc"headers.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c
+
+"$(INTDIR)\main.obj" "$(INTDIR)\dbeditorpp.pch" : $(SOURCE) "$(INTDIR)"
+ $(CPP) @<<
+ $(CPP_SWITCHES) $(SOURCE)
+<<
+
+
+!ELSEIF "$(CFG)" == "dbeditorpp - Win32 Release Unicode"
+
+CPP_SWITCHES=/nologo /MD /W3 /GX- /Ox /Ot /Og /Os /I "../../include" /I "../ExternalAPI" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DBEDITORPP_EXPORTS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\dbeditorpp.pch" /Yc"headers.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
+
+"$(INTDIR)\main.obj" "$(INTDIR)\main.sbr" "$(INTDIR)\dbeditorpp.pch" : $(SOURCE) "$(INTDIR)"
+ $(CPP) @<<
+ $(CPP_SWITCHES) $(SOURCE)
+<<
+
+
+!ENDIF
+
+SOURCE=.\modules.cpp
+
+!IF "$(CFG)" == "dbeditorpp - Win32 Release"
+
+
+"$(INTDIR)\modules.obj" "$(INTDIR)\modules.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\dbeditorpp.pch"
+
+
+!ELSEIF "$(CFG)" == "dbeditorpp - Win32 Debug"
+
+
+"$(INTDIR)\modules.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\dbeditorpp.pch"
+
+
+!ELSEIF "$(CFG)" == "dbeditorpp - Win32 Release Unicode"
+
+
+"$(INTDIR)\modules.obj" "$(INTDIR)\modules.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\dbeditorpp.pch"
+
+
+!ENDIF
+
+SOURCE=.\threads.cpp
+
+!IF "$(CFG)" == "dbeditorpp - Win32 Release"
+
+
+"$(INTDIR)\threads.obj" "$(INTDIR)\threads.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\dbeditorpp.pch"
+
+
+!ELSEIF "$(CFG)" == "dbeditorpp - Win32 Debug"
+
+
+"$(INTDIR)\threads.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\dbeditorpp.pch"
+
+
+!ELSEIF "$(CFG)" == "dbeditorpp - Win32 Release Unicode"
+
+
+"$(INTDIR)\threads.obj" "$(INTDIR)\threads.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\dbeditorpp.pch"
+
+
+!ENDIF
+
+SOURCE=.\resource.rc
+
+"$(INTDIR)\resource.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) $(RSC_PROJ) $(SOURCE)
+
+
+
+!ENDIF
diff --git a/plugins/dbeditorpp/dbeditorpp.ncb b/plugins/dbeditorpp/dbeditorpp.ncb
new file mode 100644
index 0000000000..bd426696f3
--- /dev/null
+++ b/plugins/dbeditorpp/dbeditorpp.ncb
Binary files differ
diff --git a/plugins/dbeditorpp/dbeditorpp.opt b/plugins/dbeditorpp/dbeditorpp.opt
new file mode 100644
index 0000000000..d6d51c6656
--- /dev/null
+++ b/plugins/dbeditorpp/dbeditorpp.opt
Binary files differ
diff --git a/plugins/dbeditorpp/dbeditorpp.sln b/plugins/dbeditorpp/dbeditorpp.sln
new file mode 100644
index 0000000000..0b21c9a2f6
--- /dev/null
+++ b/plugins/dbeditorpp/dbeditorpp.sln
@@ -0,0 +1,21 @@
+Microsoft Visual Studio Solution File, Format Version 7.00
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dbeditorpp", "dbeditorpp.vcproj", "{9C6040B8-1173-40FA-A3DB-DE044CCD8250}"
+EndProject
+Global
+ GlobalSection(SolutionConfiguration) = preSolution
+ ConfigName.0 = Debug
+ ConfigName.1 = Release
+ EndGlobalSection
+ GlobalSection(ProjectDependencies) = postSolution
+ EndGlobalSection
+ GlobalSection(ProjectConfiguration) = postSolution
+ {9C6040B8-1173-40FA-A3DB-DE044CCD8250}.Debug.ActiveCfg = Debug|Win32
+ {9C6040B8-1173-40FA-A3DB-DE044CCD8250}.Debug.Build.0 = Debug|Win32
+ {9C6040B8-1173-40FA-A3DB-DE044CCD8250}.Release.ActiveCfg = Release|Win32
+ {9C6040B8-1173-40FA-A3DB-DE044CCD8250}.Release.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ EndGlobalSection
+ GlobalSection(ExtensibilityAddIns) = postSolution
+ EndGlobalSection
+EndGlobal
diff --git a/plugins/dbeditorpp/dbeditorpp_10.vcxproj b/plugins/dbeditorpp/dbeditorpp_10.vcxproj
new file mode 100644
index 0000000000..e0e95a02aa
--- /dev/null
+++ b/plugins/dbeditorpp/dbeditorpp_10.vcxproj
@@ -0,0 +1,519 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug Unicode|Win32">
+ <Configuration>Debug Unicode</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug Unicode|x64">
+ <Configuration>Debug Unicode</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release Unicode|Win32">
+ <Configuration>Release Unicode</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release Unicode|x64">
+ <Configuration>Release Unicode</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectName>dbeditorpp</ProjectName>
+ <ProjectGuid>{9C6040B8-1173-40FA-A3DB-DE044CCD8250}</ProjectGuid>
+ <RootNamespace>dbeditorpp_8</RootNamespace>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\Plugins\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Configuration)\Plugins\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\Obj\$(ProjectName)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Configuration)\Obj\$(ProjectName)\</IntDir>
+ <IgnoreImportLibrary Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</IgnoreImportLibrary>
+ <IgnoreImportLibrary Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</IgnoreImportLibrary>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\Plugins\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Configuration)\Plugins\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\Obj\$(ProjectName)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Configuration)\Obj\$(ProjectName)\</IntDir>
+ <IgnoreImportLibrary Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</IgnoreImportLibrary>
+ <IgnoreImportLibrary Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</IgnoreImportLibrary>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">$(SolutionDir)$(Configuration)\Plugins\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">$(SolutionDir)$(Configuration)\Plugins\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">$(SolutionDir)$(Configuration)\Obj\$(ProjectName)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">$(SolutionDir)$(Configuration)\Obj\$(ProjectName)\</IntDir>
+ <IgnoreImportLibrary Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">true</IgnoreImportLibrary>
+ <IgnoreImportLibrary Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">true</IgnoreImportLibrary>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">$(SolutionDir)$(Configuration)\Plugins\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">$(SolutionDir)$(Configuration)\Plugins\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">$(SolutionDir)$(Configuration)\Obj\$(ProjectName)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">$(SolutionDir)$(Configuration)\Obj\$(ProjectName)\</IntDir>
+ <IgnoreImportLibrary Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">true</IgnoreImportLibrary>
+ <IgnoreImportLibrary Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">true</IgnoreImportLibrary>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">svc_dbepp</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">svc_dbepp</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">svc_dbepp</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">svc_dbepp</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">svc_dbepp</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">svc_dbepp</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">svc_dbepp</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">svc_dbepp</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Midl>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ <TypeLibraryName>.\Debug/dbeditorpp.tlb</TypeLibraryName>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>../../include;../ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;DBEDITORPP_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>headers.h</PrecompiledHeaderFile>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0409</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalOptions>/MACHINE:I386 %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalDependencies>shlwapi.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Midl>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TypeLibraryName>.\Debug/dbeditorpp.tlb</TypeLibraryName>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>../../include;../ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;DBEDITORPP_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>headers.h</PrecompiledHeaderFile>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0409</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>shlwapi.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ <TypeLibraryName>.\Release/dbeditorpp.tlb</TypeLibraryName>
+ </Midl>
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <AdditionalIncludeDirectories>../../include;../ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;DBEDITORPP_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>headers.h</PrecompiledHeaderFile>
+ <AssemblerOutput>AssemblyAndSourceCode</AssemblerOutput>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0409</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalOptions>/MACHINE:I386 %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalDependencies>shlwapi.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <AdditionalManifestDependencies>type=%27Win32%27 name=%27Microsoft.Windows.Common-Controls%27 version=%276.0.0.0%27 processorArchitecture=%27X86%27 publicKeyToken=%276595b64144ccf1df%27 language=%27*%27;%(AdditionalManifestDependencies)</AdditionalManifestDependencies>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TypeLibraryName>.\Release/dbeditorpp.tlb</TypeLibraryName>
+ </Midl>
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <AdditionalIncludeDirectories>../../include;../ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;DBEDITORPP_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>headers.h</PrecompiledHeaderFile>
+ <AssemblerOutput>AssemblyAndSourceCode</AssemblerOutput>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0409</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>shlwapi.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <AdditionalManifestDependencies>type=%27Win32%27 name=%27Microsoft.Windows.Common-Controls%27 version=%276.0.0.0%27 processorArchitecture=%27X86%27 publicKeyToken=%276595b64144ccf1df%27 language=%27*%27;%(AdditionalManifestDependencies)</AdditionalManifestDependencies>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">
+ <Midl>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ <TypeLibraryName>.\Debug/dbeditorpp.tlb</TypeLibraryName>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>../../include;../ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;DBEDITORPP_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>headers.h</PrecompiledHeaderFile>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0409</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalOptions>/MACHINE:I386 %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalDependencies>shlwapi.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">
+ <Midl>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TypeLibraryName>.\Debug/dbeditorpp.tlb</TypeLibraryName>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>../../include;../ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;DBEDITORPP_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>headers.h</PrecompiledHeaderFile>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0409</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>shlwapi.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ <TypeLibraryName>.\Release/dbeditorpp.tlb</TypeLibraryName>
+ </Midl>
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <AdditionalIncludeDirectories>../../include;../ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;DBEDITORPP_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>headers.h</PrecompiledHeaderFile>
+ <AssemblerOutput>AssemblyAndSourceCode</AssemblerOutput>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0409</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalOptions>/MACHINE:I386 %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalDependencies>shlwapi.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalManifestDependencies>type=%27Win32%27 name=%27Microsoft.Windows.Common-Controls%27 version=%276.0.0.0%27 processorArchitecture=%27X86%27 publicKeyToken=%276595b64144ccf1df%27 language=%27*%27;%(AdditionalManifestDependencies)</AdditionalManifestDependencies>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TypeLibraryName>.\Release/dbeditorpp.tlb</TypeLibraryName>
+ </Midl>
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <AdditionalIncludeDirectories>../../include;../ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;DBEDITORPP_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>headers.h</PrecompiledHeaderFile>
+ <AssemblerOutput>AssemblyAndSourceCode</AssemblerOutput>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0409</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>shlwapi.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="exportimport.cpp" />
+ <ClCompile Include="icons.cpp" />
+ <ClCompile Include="knownmodules.cpp" />
+ <ClCompile Include="main.cpp">
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="modules.cpp" />
+ <ClCompile Include="threads.cpp" />
+ <ClCompile Include="modsettingenum.cpp" />
+ <ClCompile Include="addeditsettingsdlg.cpp" />
+ <ClCompile Include="copymodule.cpp" />
+ <ClCompile Include="deletemodule.cpp" />
+ <ClCompile Include="findwindow.cpp" />
+ <ClCompile Include="main_window.cpp" />
+ <ClCompile Include="moduletree.cpp" />
+ <ClCompile Include="options.cpp" />
+ <ClCompile Include="settinglist.cpp" />
+ <ClCompile Include="watchedvars.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="modsettingenum.h" />
+ <ClInclude Include="headers.h" />
+ <ClInclude Include="resource.h" />
+ <ClInclude Include="Version.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="res\Contacts.ico" />
+ <None Include="dbeditorpp_readme.txt" />
+ <None Include="dbeditorpp_translation.txt" />
+ <None Include="res\Icon_1.ico" />
+ <None Include="res\Icon_14.ico" />
+ <None Include="res\Icon_15.ico" />
+ <None Include="res\Icon_16.ico" />
+ <None Include="res\Icon_17.ico" />
+ <None Include="res\Icon_18.ico" />
+ <None Include="res\Icon_4.ico" />
+ <None Include="res\offline2.ico" />
+ <None Include="res\online2.ico" />
+ <None Include="res\Red.ico" />
+ <None Include="res\Red_open.ico" />
+ <None Include="Res\unicode.ico" />
+ <None Include="res\Yellow.ico" />
+ <None Include="res\Yellow_open.ico" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="resource.rc" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/plugins/dbeditorpp/dbeditorpp_10.vcxproj.filters b/plugins/dbeditorpp/dbeditorpp_10.vcxproj.filters
new file mode 100644
index 0000000000..7b41fd05dd
--- /dev/null
+++ b/plugins/dbeditorpp/dbeditorpp_10.vcxproj.filters
@@ -0,0 +1,145 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{bc4414ca-bfab-4385-a016-6239272b67ab}</UniqueIdentifier>
+ <Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
+ </Filter>
+ <Filter Include="Source Files\ModSetting Enuming">
+ <UniqueIdentifier>{8ba4deb9-307a-4c99-9c87-2243a0ef802e}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\dialogs">
+ <UniqueIdentifier>{b1b3b1b6-9fe0-435d-b8ab-1715cc5e7430}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{adcc58df-dacb-48fe-a36b-59f8221cb71e}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{fb09bf3d-d973-466d-b87b-0b785885753b}</UniqueIdentifier>
+ <Extensions>ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="exportimport.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="icons.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="knownmodules.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="main.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="modules.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="threads.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="modsettingenum.cpp">
+ <Filter>Source Files\ModSetting Enuming</Filter>
+ </ClCompile>
+ <ClCompile Include="addeditsettingsdlg.cpp">
+ <Filter>Source Files\dialogs</Filter>
+ </ClCompile>
+ <ClCompile Include="copymodule.cpp">
+ <Filter>Source Files\dialogs</Filter>
+ </ClCompile>
+ <ClCompile Include="deletemodule.cpp">
+ <Filter>Source Files\dialogs</Filter>
+ </ClCompile>
+ <ClCompile Include="findwindow.cpp">
+ <Filter>Source Files\dialogs</Filter>
+ </ClCompile>
+ <ClCompile Include="main_window.cpp">
+ <Filter>Source Files\dialogs</Filter>
+ </ClCompile>
+ <ClCompile Include="moduletree.cpp">
+ <Filter>Source Files\dialogs</Filter>
+ </ClCompile>
+ <ClCompile Include="options.cpp">
+ <Filter>Source Files\dialogs</Filter>
+ </ClCompile>
+ <ClCompile Include="settinglist.cpp">
+ <Filter>Source Files\dialogs</Filter>
+ </ClCompile>
+ <ClCompile Include="watchedvars.cpp">
+ <Filter>Source Files\dialogs</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="modsettingenum.h">
+ <Filter>Source Files\ModSetting Enuming</Filter>
+ </ClInclude>
+ <ClInclude Include="headers.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="resource.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Version.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="res\Contacts.ico">
+ <Filter>Resource Files</Filter>
+ </None>
+ <None Include="dbeditorpp_readme.txt">
+ <Filter>Resource Files</Filter>
+ </None>
+ <None Include="dbeditorpp_translation.txt">
+ <Filter>Resource Files</Filter>
+ </None>
+ <None Include="res\Icon_1.ico">
+ <Filter>Resource Files</Filter>
+ </None>
+ <None Include="res\Icon_14.ico">
+ <Filter>Resource Files</Filter>
+ </None>
+ <None Include="res\Icon_15.ico">
+ <Filter>Resource Files</Filter>
+ </None>
+ <None Include="res\Icon_16.ico">
+ <Filter>Resource Files</Filter>
+ </None>
+ <None Include="res\Icon_17.ico">
+ <Filter>Resource Files</Filter>
+ </None>
+ <None Include="res\Icon_18.ico">
+ <Filter>Resource Files</Filter>
+ </None>
+ <None Include="res\Icon_4.ico">
+ <Filter>Resource Files</Filter>
+ </None>
+ <None Include="res\offline2.ico">
+ <Filter>Resource Files</Filter>
+ </None>
+ <None Include="res\online2.ico">
+ <Filter>Resource Files</Filter>
+ </None>
+ <None Include="res\Red.ico">
+ <Filter>Resource Files</Filter>
+ </None>
+ <None Include="res\Red_open.ico">
+ <Filter>Resource Files</Filter>
+ </None>
+ <None Include="res\Yellow.ico">
+ <Filter>Resource Files</Filter>
+ </None>
+ <None Include="res\Yellow_open.ico">
+ <Filter>Resource Files</Filter>
+ </None>
+ <None Include="Res\unicode.ico">
+ <Filter>Resource Files</Filter>
+ </None>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="resource.rc">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/plugins/dbeditorpp/dbeditorpp_readme.txt b/plugins/dbeditorpp/dbeditorpp_readme.txt
new file mode 100644
index 0000000000..774560721d
--- /dev/null
+++ b/plugins/dbeditorpp/dbeditorpp_readme.txt
@@ -0,0 +1,143 @@
+Database Editor ++
+-------------------
+
+Database Editor ++ allows you to easily modify your database settings (which is a good and bad thing..). Be carefull editing values that you dont know what they are used for... you couldnt couse Miranda IM to not work if you change the wrong setting...
+YOU HAVE BEEN WARNED...
+
+A summary of what DBE++ can do.. (each will be explained below)
+- Edit every database setting (not history)
+- export / import your entire (or partial) database to/from a txt file
+- Remove an entire module from the database
+- Find and replace a value in string variables..
+- Find text (numbers or letters) in any module, setting name or value
+- Keep a list of variables you need to watch (usefull for developers)
+- display modules which are not currently being used (if the plugin that uses that module isnt loaded)
+- clone a contact
+- copy a module to a contact
+- rename module and settings
+- change a variable type
+- show popups when a certain setting changes
+- show encrypted strings decrypted (as well as encrypt/decrypt any string variable)
+and more....
+
+Editing Variables
+-----------------
+The easiest way to edit or rename a setting is to dowuble click the setting's icon, a new window will popup and you can edit it there...
+well, i lie.. the easiest way to edit/rename the settings is a bit more complicated :)
+if you click twice the setting name a edit window should popup where you can rename the setting... pressing escape will cancel it, everything else will accpet your changes without confirmation.
+Same goes for the setting value (2nd column) except you can do nifty stuff here which needs to be explained...
+just typing a number will keep the vairable type the same and change the value to your new number (it does not check if your new number is larger that the type's largest possible number).
+Typeing anything other than numbers will convert the variable to a string with your new data as the value.
+Typeing a number into a string variable will keep the variable as a string.
+
+You can force a variable to a type by prepending the value with a letter.
+'b' or 'B' to force a BYTE variable.
+'w' or 'W' to force a WORD variable.
+'d' or 'D' to force a DWORD variable.
+If your new data starts with a ' or " the setting will be converted to a string, so if you actually want to start the value with a ' you need to put 2 ' marks at the start!..
+unless a number starts with 0x or 0X the number is assumed to be decimal, with a 0x/0X it is hexidecimal.
+
+Exporting / Importing
+---------------------
+To export the entire database go Actions > Export / Import > Export entire database (in the DBE++ window), you can choose any file extension you want, it just saves as a plaintext file, so .txt is logical :)
+To export only a certain module or contact right click it and go export..
+
+Importing is a bit more complex...
+there are two ways to import settings, either useing the import window, or just importing an entire file.
+Using the import window lets you choose exactly which modules/settings to import into the selected contact.
+Importing an entire file will start importing all the settings into the selected contact (the Settings contact if you do it from the actions menu item).
+
+Every time a line starting with "CONTACT:" is read a new contact is created and the following modules/settings get imported into that contact... there is one exception tho. if the line is "CONTACT: Settings" then the following modules/settings get imported into the Settings contact ( a new contact is not created..)
+
+Remove an entire module from the database
+----------------------------------------------
+To remove a module from the database use the actions > Delete module menu item. If you have alot of modules this window can take a few seconds to finish setting up. when it finishes loading all the modules just choose the one u want to delete and press ok. there is no confirmation here so be careful... Also its a good idea to run dbtool after doing this as you may have lots of wasted space in the DB...
+
+Find and replace a value in string variables..
+----------------------------------------------
+Actions > find > find and replace...
+This searches every string value in the DB and will replace the find text with the new text.. it does not replace text in value names, and there is no confirmation...
+
+Find text (numbers or letters) in any module, setting name or value
+----------------------------------------------------------
+Actions > find > find
+This window lets you search the entire database for any text (numbers included..) in module names, setting names and setting values...
+Double clicking any of the found items will cause the main DBE++ window to select that item...
+
+Keep a list of variables you need to watch (AKA watch list)
+-------------------------------------------
+if there is a variable you want to keep an eye on (testing something?) then right click the setting in the list and go "watch". (you can also watch entire modules by right clicking them). To then see the watch list use the watches > view all menu item. A new window will apear with all the watched settings. double clicking any of them will find the item in the main window. If you have chosen to be notified with popups then any watched setting that changes will create a popup (even if the DBE++ and watch list windows are not open)
+Currently there is no way to save the list after a restart...
+
+display modules which are not currently being used (AKA known modules list)
+---------------------------------------------------------------------------
+If a module has the yellow folder icon it means that the module is currently being used, e.g the DBEditorpp module will always be yellow because its being used by this plugin... but the Chat module will only be yellow if you have the chat plugin enabled and installed... If you dont care whether a module is being used or not then u can turn this feature off in the options...
+Unfortuantly, the only way to know which modules are being used is by other plugins letting DBE++ know... so untill more plugins get updated to use this feature you can add module names to the edit box in options > plugins > Database Editor++ (changeing this requires a restart to take effect), OR you can use an mbot script to add modules "on the fly" (read below)
+Plugin developers please read below how to add your modules...
+
+Renameing modules
+-----------------
+Select the module you want to rename and press f2 or click the name again and you can type a new name, pressing esc will cancel the change, anything else will accept the change with no confirmation.
+
+Other Stuff
+----------
+Everything else should be self-explanatory or easily done by context menu items....
+
+
+ADDING YOUR MODULES TO THE KNOWN MODULES LIST
+------------------------------------------------
+If your plugin only uses ONE module then you can use the "DBEditorpp/RegisterSingleModule" Service function like this:
+CallService("DBEditorpp/RegisterSingleModule",(WPARAM)"modName",0);
+If you have more than one module then use the "DBEditorpp/RegisterModule" with the WPARAM char** and LPARAM int being the number of modules to register..
+e.g
+{
+ char *mods[4] = {"module1","Module2","Module3"};
+ CallService("DBEditorpp/RegisterModule",(WPARAM)mods,(LPARAM)3);
+}
+REMEMBER TO DO THIS IN OR AFTER ME_SYSTEM_MODULESLOADED HAS BEEN TRIGGERED....
+
+DOING IT WITH MSP (formerly mBot)..
+If you want to add modules "on-the-fly" you can add them with an mbot script like this:
+<?php
+mb_SysCallService('DBEditorpp/RegisterSingleModule',"modulename",0);
+?>
+then refresh the module tree and the module will be known..
+
+Translation
+-----------
+ive added a translation.txt file in the archive... apart from the text in the windows i tihnk it has everything...
+
+Changelog
+---------
+3.1
+- added icon manager support coz you people are annoying... btw huge thanx to Angeli-ka for the icons
+- fixed a bug in the find and replace code...
+- added a fix to disallow inline setting editing on win98 and winME to stop crashes
+- big thanx to Std for pointing out (and fixing) some stupid bugs in the export/import code
+- menu should be translatable now
+- added a bit more room in the options dialog for tranlsators
+- added in bio's code changes which seems to have fixed the popup module crash problem... (hopefully) (THANX BIO)
+- the old "KnownModules" module is now used again... any modules in that are added
+- still trying to work out how to not save the window size if it was maximised...
+- added a "add module to known list" menu item
+- modules added in the options page can now have a space in their name (put a \ before the space for it to work)
+- fixed the options page a bit
+- now asks to overwrite files when you export...
+- no more contact proto icons in the contact list
+- fixed various translation problems
+
+3.0
+- 99% recode and now it all works nicely :)
+
+1.0->2.0
+- old stuff.... not relevant anymore
+
+------------------------------
+
+(c) 2005 Jonathan Gordon (jdgordy@gmail.com)
+
+contact me on ICQ, MSN, Email or Telepathy... just make sure you tell me who you are or youll get blocked :)
+ICQ: 98791178
+MSN: jonnog@hotmail.com
+Jabber: jdgordy@jabber.zim.net.au
+
diff --git a/plugins/dbeditorpp/dbeditorpp_translation.txt b/plugins/dbeditorpp/dbeditorpp_translation.txt
new file mode 100644
index 0000000000..6d90341b35
--- /dev/null
+++ b/plugins/dbeditorpp/dbeditorpp_translation.txt
@@ -0,0 +1,38 @@
+Database Editor++
+Error Loading Module List
+Couldnt create the image list...
+Error Loading Setting List
+Settings
+(UNLOADED)
+(UNKNOWN)
+Contacts
+
+Are you sure you want to delete module \"%s\"?
+Confirm Module Deletion
+
+Name
+Data
+Type
+Size
+BLOB
+BYTE
+WORD
+DWORD
+STRING
+
+Delete module from Database
+Delete module from Database... Loading
+Enter a string to search the DB for
+
+Found Module \"%s\" in contact \"%s\" ; <- module, contact name
+Found Setting \"%s\" in module \"%s\" in contact \"%s\" ; <- setting, module, contact name
+Found in Setting \"%s\" in module \"%s\" in contact \"%s\" ; <-setting,module, contact name
+Finished. %d items found
+
+
+Closed Known Module
+Open Known Module
+Closed Unknown Module
+Open Unknown Module
+Contacts Group
+Unknown Contact \ No newline at end of file
diff --git a/plugins/dbeditorpp/deletemodule.cpp b/plugins/dbeditorpp/deletemodule.cpp
new file mode 100644
index 0000000000..a0eddf73a1
--- /dev/null
+++ b/plugins/dbeditorpp/deletemodule.cpp
@@ -0,0 +1,148 @@
+#include "headers.h"
+
+static int working;
+static HWND hwnd2Delete = NULL;
+
+int deleteModule(char* module, HANDLE hContact, int fromMenu)
+{
+ char msg[1024];
+ ModuleSettingLL settinglist;
+ struct ModSetLinkLinkItem *setting;
+
+ if (!module) return 0;
+
+ if (!fromMenu)
+ {
+ mir_snprintf(msg, SIZEOF(msg), Translate("Are you sure you want to delete module \"%s\"?"), module);
+ if (DBGetContactSettingByte(NULL,modname, "WarnOnDelete",1))
+ {
+ if (MessageBox(0,msg, Translate("Confirm Module Deletion"), MB_YESNO|MB_ICONEXCLAMATION) == IDNO)
+ return 0;
+ }
+ }
+
+ if (!EnumSettings(hContact,module,&settinglist)) return 0;
+
+ setting = settinglist.first;
+ while (setting)
+ {
+ DBDeleteContactSetting(hContact, module, setting->name);
+ setting = (struct ModSetLinkLinkItem *)setting->next;
+ }
+ FreeModuleSettingLL(&settinglist);
+ return 1;
+}
+
+void __cdecl PopulateModuleDropListThreadFunc(LPVOID di)
+{
+ HWND hwnd = (HWND)di;
+ ModuleSettingLL msll;
+ struct ModSetLinkLinkItem *module;
+ HANDLE hContact;
+ int moduleEmpty;
+ if (!EnumModules(&msll)) DestroyWindow(hwnd);
+ module = msll.first;
+ while (module && working)
+ {
+ moduleEmpty = 1;
+ // check the null
+ if (!IsModuleEmpty(NULL,module->name))
+ {
+ SendDlgItemMessage(hwnd,IDC_CONTACTS,CB_ADDSTRING,0,(LPARAM)module->name);
+ moduleEmpty = 0;
+ module = (struct ModSetLinkLinkItem *)module->next;
+ continue;
+ }
+ for (hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);moduleEmpty && hContact;hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0))
+ {
+ if (!IsModuleEmpty(hContact,module->name))
+ {
+ SendDlgItemMessage(hwnd,IDC_CONTACTS,CB_ADDSTRING,0,(LPARAM)module->name);
+ moduleEmpty = 0;
+ break;
+ }
+ }
+
+ module = (struct ModSetLinkLinkItem *)module->next;
+ SendDlgItemMessage(hwnd,IDC_CONTACTS,CB_SETCURSEL,0,0);
+ }
+ SendDlgItemMessage(hwnd,IDC_CONTACTS,CB_SETCURSEL,0,0);
+ FreeModuleSettingLL(&msll);
+ SetWindowText(hwnd,Translate("Delete module from Database"));
+ EnableWindow(GetDlgItem(hwnd,IDC_CONTACTS),1);
+ EnableWindow(GetDlgItem(hwnd,IDOK),1);
+ EnableWindow(GetDlgItem(hwnd,IDCANCEL),1);
+
+ if (!working)
+ PostMessage(hwnd, WM_COMMAND, (WPARAM)IDCANCEL, 0);
+ else
+ working = 2;
+}
+
+INT_PTR CALLBACK DeleteModuleDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch(msg)
+ {
+ case WM_INITDIALOG:
+ {
+ SetWindowText(hwnd,Translate("Delete module from Database... Loading"));
+ EnableWindow(GetDlgItem(hwnd,IDC_CONTACTS),0);
+ EnableWindow(GetDlgItem(hwnd,IDOK),0);
+ SetDlgItemText(hwnd,IDC_INFOTEXT,"Delete module from Database");
+ SetDlgItemText(hwnd,CHK_COPY2ALL,"Delete module from all contacts (Includes Setting)");
+ EnableWindow(GetDlgItem(hwnd,CHK_COPY2ALL),0);
+ CheckDlgButton(hwnd,CHK_COPY2ALL,1);
+ TranslateDialogDefault(hwnd);
+ working = 1;
+ forkthread(PopulateModuleDropListThreadFunc,0,hwnd);
+ }
+ return TRUE;
+ case WM_COMMAND:
+ switch(LOWORD(wParam))
+ {
+ case IDOK:
+ {
+ char text[128];
+ HANDLE hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ GetDlgItemText(hwnd,IDC_CONTACTS,text,128);
+ SetCursor(LoadCursor(NULL,IDC_WAIT));
+ while (hContact)
+ {
+ deleteModule(text,hContact,1);
+ hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0);
+ }
+ // do the null
+ deleteModule(text,NULL,1);
+ SetCursor(LoadCursor(NULL,IDC_ARROW));
+ refreshTree(1);
+ }
+ // fall through
+ case IDCANCEL:
+ {
+ if (working == 1)
+ {
+ working = 0;
+ EnableWindow(GetDlgItem(hwnd,IDCANCEL),0);
+ }
+ else
+ DestroyWindow(hwnd);
+ }
+ break;
+ }
+ break;
+ case WM_DESTROY:
+ hwnd2Delete = NULL;
+ break;
+ }
+ return 0;
+}
+
+
+
+void deleteModuleGui()
+{
+ if (!hwnd2Delete)
+ hwnd2Delete = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_COPY_MOD), hwnd2mainWindow, DeleteModuleDlgProc, (LPARAM)0);
+ else
+ SetForegroundWindow(hwnd2Delete);
+} \ No newline at end of file
diff --git a/plugins/dbeditorpp/exportimport.cpp b/plugins/dbeditorpp/exportimport.cpp
new file mode 100644
index 0000000000..83b15e7e0a
--- /dev/null
+++ b/plugins/dbeditorpp/exportimport.cpp
@@ -0,0 +1,758 @@
+#include "headers.h"
+
+int Mode;
+HWND hwnd2importWindow;
+
+int Openfile(char *outputFile, const char *module)
+{
+ OPENFILENAME ofn = {0};
+ char filename[MAX_PATH] = "";
+ char filter[MAX_PATH];
+ mir_snprintf(filter, SIZEOF(filter), "%s%c*.ini%c%s%c*.*%c", Translate("INI Files"), 0, 0, Translate("All Files"), 0, 0);
+ char *title = Translate("Export to file");
+
+ if (module)
+ {
+ int n = 0;
+ mir_strncpy(filename, module, MAX_PATH);
+
+ while(filename[n])
+ {
+ switch(filename[n])
+ {
+ case '*':
+ case ':':
+ case '/':
+ case '?':
+ case '|':
+ case '\\':
+ filename[n] = '_';
+ break;
+ }
+ n++;
+ }
+ }
+
+ ofn.lStructSize = sizeof(ofn);
+ ofn.lpstrFile = filename;
+ ofn.lpstrFilter = filter;
+ ofn.Flags = OFN_HIDEREADONLY | OFN_SHAREAWARE | OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT;
+ ofn.lpstrTitle = title;
+ ofn.nMaxFile = MAX_PATH;
+ ofn.lpstrDefExt = "ini";
+
+ if (!GetSaveFileName(&ofn))
+ return 0;
+ lstrcpy(outputFile,filename);
+ return 1;
+}
+
+char* StrReplace (char* Search, char* Replace, char* Resource)
+{
+ int i = 0;
+ int SearchLen = (int)_tcslen(Search);
+ char* Work = mir_tstrdup(Replace);
+ int ReplaceLen = (int)_tcslen(Work);
+
+ char* Pointer = _tcsstr(Resource, Search);
+
+ while (Pointer != NULL)
+ {
+ int PointerLen = (int)_tcslen(Pointer);
+ int ResourceLen = (int)_tcslen(Resource);
+
+ char* NewText = (char*)mir_calloc((ResourceLen - SearchLen + ReplaceLen + 1)*sizeof(char));
+
+ _tcsncpy(NewText, Resource, ResourceLen - PointerLen);
+ _tcscat(NewText, Work);
+ _tcscat(NewText, Pointer + SearchLen);
+
+ Resource = (char*)mir_realloc(Resource, (ResourceLen - SearchLen + ReplaceLen + 1)*sizeof(char));
+
+ for (i = 0; i < (ResourceLen - SearchLen + ReplaceLen); i++)
+ Resource[i] = NewText[i];
+ Resource[i] = 0;
+ mir_free(NewText);
+
+ Pointer = _tcsstr(Resource + (ResourceLen - PointerLen + ReplaceLen), Search);
+ }
+ mir_free(Work);
+
+ return Resource;
+}
+
+void exportModule(HANDLE hContact, char* module, FILE* file)
+{
+ char tmp[32];
+ ModuleSettingLL settinglist;
+ struct ModSetLinkLinkItem *setting;
+
+ EnumSettings(hContact,module,&settinglist);
+
+ // print the module header..
+ fprintf(file, "\n[%s]", module);
+ setting = settinglist.first;
+ while(setting)
+ {
+ DBVARIANT dbv;
+ if (!GetSetting(hContact, module, setting->name, &dbv))
+ {
+ switch (dbv.type)
+ {
+ case DBVT_BYTE:
+ fprintf(file, "\n%s=b%s", setting->name, itoa(dbv.bVal,tmp,10));
+ DBFreeVariant(&dbv);
+ break;
+ case DBVT_WORD:
+ fprintf(file, "\n%s=w%s", setting->name, itoa(dbv.wVal,tmp,10));
+ DBFreeVariant(&dbv);
+ break;
+ case DBVT_DWORD:
+ fprintf(file, "\n%s=d%s", setting->name, itoa(dbv.dVal,tmp,10));
+ DBFreeVariant(&dbv);
+ break;
+ case DBVT_ASCIIZ:
+ case DBVT_UTF8:
+ if (strchr(dbv.pszVal, '\r'))
+ {
+ char *end = StrReplace("\\", "\\\\", dbv.pszVal);
+ end = StrReplace("\r", "\\r", end);
+ end = StrReplace("\n", "\\n", end);
+ fprintf(file, "\n%s=g%s", setting->name, end);
+ break;
+ }
+ if (dbv.type == DBVT_UTF8)
+ fprintf(file, "\n%s=u%s", setting->name, dbv.pszVal);
+ else
+ fprintf(file, "\n%s=s%s", setting->name, dbv.pszVal);
+ DBFreeVariant(&dbv);
+ break;
+ case DBVT_BLOB:
+ {
+ int j;
+ char *data = NULL;
+ if (!(data = (char*)mir_alloc( 3*(dbv.cpbVal+1)*sizeof(char)) ))
+ break;
+ data[0] = '\0';
+ for (j=0; j<dbv.cpbVal; j++)
+ {
+ char tmp[16];
+ mir_snprintf(tmp, SIZEOF(tmp), "%02X ", (BYTE)dbv.pbVal[j]);
+ strcat(data, tmp);
+ }
+ fprintf(file,"\n%s=n%s",setting->name , data);
+ mir_free(data);
+ }
+ DBFreeVariant(&dbv);
+ break;
+ }
+ }
+ setting = (struct ModSetLinkLinkItem *)setting->next;
+ }
+ FreeModuleSettingLL(&settinglist);
+}
+
+
+char *NickFromHContact(HANDLE hContact)
+{
+ static char nick[512] = "";
+
+ if (hContact)
+ {
+ char szProto[256];
+ int loaded = 0;
+
+ if (GetValue(hContact,"Protocol","p",szProto,SIZEOF(szProto)))
+ loaded = IsProtocolLoaded(szProto);
+
+ if (!szProto[0] || !loaded)
+ {
+ char name[256];
+
+ if (szProto[0])
+ {
+ if (GetValue(hContact,szProto,"Nick",name,SIZEOF(name)))
+ mir_snprintf(nick, SIZEOF(nick),"%s (%s)", name, szProto);
+ else
+ mir_snprintf(nick, SIZEOF(nick),"(UNKNOWN) (%s)", szProto);
+ }
+ else
+ mir_snprintf(nick, SIZEOF(nick),"(UNKNOWN)");
+ }
+ else
+ {
+ char *uid;
+ char szUID[256];
+
+ uid = (char*)CallProtoService(szProto,PS_GETCAPS,PFLAG_UNIQUEIDSETTING,0);
+ if ((int)uid!=CALLSERVICE_NOTFOUND && uid)
+ {
+ GetValue(hContact, szProto, uid, szUID, SIZEOF(szUID));
+ mir_snprintf(nick, SIZEOF(nick), "%s *(%s)*<%s>*{%s}*", (char*)GetContactName(hContact,szProto,0), szProto, uid, szUID);
+ }
+ else
+ mir_snprintf(nick, SIZEOF(nick), "%s (%s)", (char*)GetContactName(hContact,szProto,0), szProto);
+ }
+ }
+
+ return nick;
+}
+
+
+void exportDB(HANDLE hContact, char* module) // hContact == -1 export entire db. module == NULL export entire contact.
+{ // hContact == -1, module == "" - all contacts
+ FILE* file = NULL;
+ char fileName[MAX_PATH];
+ int nullcontactDone = 0;
+ ModuleSettingLL modlist;
+ struct ModSetLinkLinkItem *mod;
+
+ // enum all the modules
+ if (!EnumModules(&modlist)) { msg(Translate("Error Loading Module List"),modFullname); return;}
+
+ if (Openfile(fileName, ((int)hContact==-1)?NULL:module))
+ {
+ if (!(file = fopen(fileName, "wt"))) { msg(Translate("Couldn't open file for writing"), modFullname); return; }
+
+ SetCursor(LoadCursor(NULL,IDC_WAIT));
+
+ // exporting entire db
+ if (hContact == INVALID_HANDLE_VALUE)
+ {
+ hContact = NULL;
+
+ if (module == NULL)
+ {
+ fprintf(file, "SETTINGS:\n");
+ mod = modlist.first;
+ while(mod)
+ {
+ if (IsModuleEmpty(hContact, mod->name))
+ {
+ mod = (struct ModSetLinkLinkItem *)mod->next;
+ continue;
+ }
+ exportModule(hContact, mod->name, file);
+ mod = (struct ModSetLinkLinkItem *)mod->next;
+ if (mod)
+ fprintf(file, "\n");
+ }
+ }
+ else
+ {
+ if (module == "") module = NULL; // reset module for all contacts export
+ }
+
+ hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+
+ while (hContact)
+ {
+ if (!hContact) continue;
+
+ // filter
+ if (Mode != MODE_ALL)
+ {
+ char szProto[256];
+ int loaded = 0;
+
+ if (GetValue(hContact,"Protocol","p",szProto,SIZEOF(szProto)))
+ loaded = IsProtocolLoaded(szProto);
+
+ if ((loaded && Mode == MODE_UNLOADED) || (!loaded && Mode == MODE_LOADED))
+ {
+ hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0);
+ continue;
+ }
+ }
+
+ fprintf(file, "CONTACT: %s\n", NickFromHContact(hContact));
+
+ if (module == NULL) // export all modules
+ {
+ mod = modlist.first;
+ while(mod)
+ {
+ if (IsModuleEmpty(hContact, mod->name))
+ {
+ mod = (struct ModSetLinkLinkItem *)mod->next;
+ continue;
+ }
+ exportModule(hContact, mod->name, file);
+ mod = (struct ModSetLinkLinkItem *)mod->next;
+ if (mod)
+ fprintf(file, "\n");
+ }
+ }
+ else // export module
+ {
+ exportModule(hContact, module, file);
+ }
+ hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)(HANDLE)hContact, 0);
+ }
+ }
+ // exporting a contact
+ else
+ {
+ if (!module) // exporting every module
+ {
+ if (hContact)
+ fprintf(file, "CONTACT: %s\n", NickFromHContact(hContact));
+ else
+ fprintf(file, "SETTINGS:\n");
+
+ mod = modlist.first;
+ while(mod)
+ {
+ if (IsModuleEmpty(hContact, mod->name))
+ {
+ mod = (struct ModSetLinkLinkItem *)mod->next;
+ continue;
+ }
+ exportModule(hContact, mod->name, file);
+ mod = (struct ModSetLinkLinkItem *)mod->next;
+ if (mod)
+ fprintf(file, "\n");
+ }
+ }
+ else
+ {
+ if (hContact)
+ fprintf(file, "FROM CONTACT: %s\n", NickFromHContact(hContact));
+ else
+ fprintf(file, "SETTINGS:\n");
+
+ exportModule(hContact, module, file);
+ }
+ }
+ fclose(file);
+
+ SetCursor(LoadCursor(NULL,IDC_ARROW));
+ }
+
+ FreeModuleSettingLL(&modlist);
+}
+
+
+HANDLE CheckNewContact(char *myProto, char *uid, char *myName)
+{
+ char szProto[256], szName[256];
+ HANDLE resultHandle = INVALID_HANDLE_VALUE;
+ HANDLE hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+
+ while (hContact)
+ {
+ //szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
+ if (DBGetContactSettingStringStatic(hContact, "Protocol", "p", szProto, 256))
+ {
+ if (!mir_strcmp(szProto, myProto))
+ {
+ if (GetValue(hContact, szProto, uid, szName, SIZEOF(szName)) &&
+ !mir_strcmp(szName, myName))
+ {
+ //char msg[1024];
+ //_snprintf(msg, 1024, Translate("Do you want to overwrite it \"%s\"?"), szName);
+ //if (MessageBox(0,msg, Translate("Contact already exists"), MB_YESNO|MB_ICONEXCLAMATION) == IDYES)
+ resultHandle = hContact;
+ break;
+ }
+ }
+ }
+
+ hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0);
+ }
+
+ return resultHandle;
+
+}
+
+TCHAR* __stdcall rtrim(TCHAR *string)
+{
+ TCHAR* p = string + _tcslen(string) - 1;
+
+ while (p >= string) {
+ if (*p != ' ' && *p != '\t' && *p != '\n' && *p != '\r')
+ break;
+
+ *p-- = 0;
+ }
+ return string;
+}
+
+HANDLE Clist_GroupExists(WCHAR *tszGroup)
+{
+ unsigned int i = 0;
+ WCHAR* _t = 0;
+ char str[10];
+ INT_PTR result = 0;
+ DBVARIANT dbv = {0};
+ int match;
+
+ do {
+ _itoa(i, str, 10);
+ result = DBGetContactSettingTString(0, "CListGroups", str, &dbv);
+ if(!result) {
+ match = (!lstrcmpW(tszGroup, (LPCWSTR)&dbv.ptszVal[1]) && (lstrlenW(tszGroup) == lstrlenW((LPCWSTR)&dbv.ptszVal[1])));
+ DBFreeVariant(&dbv);
+ if(match)
+ return((HANDLE)(i + 1));
+ }
+ i++;
+ }
+ while(result == 0);
+ return(0);
+}
+
+void importSettings(HANDLE hContact, char *importstring )
+{
+ char module[256] = "", setting[256] = "", *end;
+ int i=0, value, type;
+ importstring = strtok(importstring, "\n");
+
+ SetCursor(LoadCursor(NULL,IDC_WAIT));
+
+ while (importstring != NULL)
+ {
+ i=0;
+ rtrim(importstring);
+ if (importstring[i] == '\0')
+ {
+ importstring = strtok(NULL, "\n");
+ continue;
+ }
+ else if (!strncmp(&importstring[i],"SETTINGS:",strlen("SETTINGS:")))
+ {
+ importstring = strtok(NULL, "\n");
+ continue;
+ }
+ else if (!strncmp(&importstring[i],"CONTACT:", strlen("CONTACT:")))
+ {
+ int len, add = 1;
+ hContact = INVALID_HANDLE_VALUE;
+
+ i = i + (int)strlen("CONTACT:");
+ len = (int)strlen(&importstring[i]);
+
+ if (len > 10)
+ {
+ char uid[256]="",szUID[256]="",szProto[512]="";
+ char *p1,*p2;
+
+ p1 = strrchr(&importstring[i], '>*{');
+ p2 = strrchr(&importstring[i], '}*');
+
+ if (p1 && p2 && p1+3 < p2 && p2-p1 < SIZEOF(szUID))
+ {
+ strncpy(szUID, p1+1, p2-p1-2);
+
+ p1 = strrchr(&importstring[i], ')*<');
+ p2 = strrchr(&importstring[i], '>*{');
+
+ if (p1 && p2 && p1+3 < p2 && p2-p1 < SIZEOF(uid))
+ {
+ strncpy(uid, p1+1, p2-p1-3);
+
+ p1 = strrchr(&importstring[i], ' *(');
+ p2 = strrchr(&importstring[i], ')*<');
+
+ if (p1 && p2 && p1+3 < p2 && p2-p1 < SIZEOF(szProto))
+ {
+ char *protouid;
+ strncpy(szProto, p1+1, p2-p1-3);
+
+ protouid = (char*)CallProtoService(szProto,PS_GETCAPS,PFLAG_UNIQUEIDSETTING,0);
+ if ((int)protouid!=CALLSERVICE_NOTFOUND)
+ {
+ if (!mir_strcmp(protouid, uid))
+ hContact = CheckNewContact(szProto, uid, szUID);
+ }
+ else
+ hContact = CheckNewContact(szProto, uid, szUID);
+ }
+ }
+ }
+ }
+
+ if (hContact == INVALID_HANDLE_VALUE)
+ {
+ HANDLE temp = (HANDLE)CallService(MS_DB_CONTACT_ADD,0,0);
+ if (temp)
+ hContact = temp;
+ }
+ }
+ else if (importstring[i] == '[' && !strchr(&importstring[i+1],'=') )// get the module
+ {
+ if (end = strpbrk(&importstring[i+1], "]")) {
+ if ((end+1) != '\0') *end = '\0';
+ strcpy(module, &importstring[i+1]);
+ }
+ }
+ else if (importstring[i] == '-' && importstring[i+1] == '[' &&
+ !strchr(&importstring[i+2],'='))// get the module
+ {
+ if (end = strpbrk(&importstring[i+2], "]")) {
+ if ((end+1) != '\0') *end = '\0';
+ strcpy(module, &importstring[i+2]);
+ deleteModule(module, hContact, 1);
+ }
+ }
+ else if (strstr(&importstring[i], "=") && module[0]) // get the setting
+ {
+ if (end = strpbrk(&importstring[i+1], "=")) {
+ if ((end+1) != '\0') *end = '\0';
+ strcpy(setting, &importstring[i]);
+
+ // get the type
+ type = *(end+1);
+ if (lstrcmp(module, "CList") == 0 && lstrcmp(setting, "Group") == 0)
+ {
+ WCHAR* GroupName = mir_a2u(end+2);
+ if (!GroupName)
+ continue;
+ HANDLE GroupHandle = Clist_GroupExists(GroupName);
+ if(GroupHandle == 0) {
+ GroupHandle = (HANDLE)CallService(MS_CLIST_GROUPCREATE, 0, (LPARAM)GroupName);
+
+ if(GroupHandle) {
+ CallService(MS_CLUI_GROUPADDED, (WPARAM)GroupHandle, 0);
+ CallService(MS_CLIST_GROUPSETEXPANDED, (WPARAM)GroupHandle, 1);
+ }
+ }
+ mir_free(GroupName);
+ }
+ switch (type)
+ {
+ case 'b':
+ case 'B':
+ if (sscanf((end+2), "%d", &value) == 1)
+ DBWriteContactSettingByte(hContact, module, setting, (BYTE)value);
+ break;
+ case 'w':
+ case 'W':
+ if (sscanf((end+2), "%d", &value) == 1)
+ DBWriteContactSettingWord(hContact, module, setting, (WORD)value);
+ break;
+ case 'd':
+ case 'D':
+ if (sscanf((end+2), "%d", &value) == 1)
+ DBWriteContactSettingDword(hContact, module, setting, (DWORD)value);
+ break;
+ case 's':
+ case 'S':
+ DBWriteContactSettingString(hContact,module, setting, (end+2));
+ break;
+ case 'g':
+ case 'G':
+ { char *pstr;
+ for(pstr=end+2;*pstr;pstr++){
+ if(*pstr=='\\'){
+ switch(pstr[1]){
+ case 'n': *pstr='\n'; break;
+ case 't': *pstr='\t'; break;
+ case 'r': *pstr='\r'; break;
+ default: *pstr=pstr[1]; break;
+ }
+ MoveMemory(pstr+1,pstr+2,lstrlenA(pstr+2)+1);
+ } } }
+ case 'u':
+ case 'U':
+ DBWriteContactSettingStringUtf(hContact,module, setting, (end+2));
+ break;
+ case 'l':
+ case 'L':
+ DBDeleteContactSetting(hContact, module, setting);
+ break;
+ case 'n':
+ case 'N':
+ WriteBlobFromString(hContact, module, setting, (end+2), (int)strlen((end+2)));
+ break;
+ }
+ }
+ }
+ importstring = strtok(NULL, "\n");
+ }
+ SetCursor(LoadCursor(NULL,IDC_ARROW));
+}
+
+INT_PTR CALLBACK ImportDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch(msg)
+ {
+ case WM_INITDIALOG:
+ {
+ hwnd2importWindow = hwnd;
+ SetWindowLongPtr(hwnd,GWLP_USERDATA,lParam);
+ TranslateDialogDefault(hwnd);
+ SendDlgItemMessage(hwnd, IDC_TEXT, EM_LIMITTEXT, (WPARAM)sizeof(TCHAR)*0x7FFFFFFF, 0);
+ }
+ break;
+
+ case WM_COMMAND:
+ {
+ switch(LOWORD(wParam))
+ {
+ case IDC_CRLF:
+ {
+ int length = GetWindowTextLength(GetDlgItem(hwnd, IDC_TEXT));
+ char *string = (char*)_alloca(length+3);
+ int Pos = 2;
+
+ if (length)
+ {
+ int Range = SendDlgItemMessage(hwnd,IDC_TEXT,EM_GETSEL,0,0);
+ int Min = LOWORD(Range);
+ int Max = HIWORD(Range);
+
+
+ GetDlgItemText(hwnd, IDC_TEXT, string, length+1);
+
+ if (Min == -1)
+ memcpy(string, crlf_string, SIZEOF(crlf_string));
+ else
+ if (Max == -1 || Max >= length)
+ memcpy(&string[Min], crlf_string, SIZEOF(crlf_string));
+ else
+ if (Max-Min > 2)
+ {
+ memcpy(&string[Min], crlf_string, SIZEOF(crlf_string));
+ memmove(&string[Min+2], &string[Max], length - Max + 1);
+ }
+ else
+ {
+ memmove(&string[Min+2], &string[Max], length - Max + 1);
+ memcpy(&string[Min], crlf_string, SIZEOF(crlf_string));
+ }
+
+ if (Min) Pos += Min;
+ }
+ else
+ memcpy(string, crlf_string, SIZEOF(crlf_string));
+
+ SetDlgItemText(hwnd, IDC_TEXT, string);
+ SendDlgItemMessage(hwnd,IDC_TEXT,EM_SETSEL,Pos,Pos);
+ SetFocus(GetDlgItem(hwnd, IDC_TEXT));
+ }
+ break;
+
+ case IDOK:
+ {
+ HANDLE hContact = (HANDLE)GetWindowLongPtr(hwnd,GWLP_USERDATA);
+ int length = GetWindowTextLength(GetDlgItem(hwnd, IDC_TEXT));
+ char *string;
+ if (length)
+ {
+ string = (char*)_alloca(length+1);
+ if (!string) {msg(Translate("Couldnt allocate enough memory!"), modFullname); DestroyWindow(hwnd); }
+ GetDlgItemText(hwnd, IDC_TEXT, string, length+1);
+ importSettings(hContact, string);
+ refreshTree(1);
+ }
+ }
+ break;
+
+ case IDCANCEL:
+ DestroyWindow(hwnd);
+ hwnd2importWindow = 0;
+ break;
+ }
+ }
+ break;
+ }
+ return 0;
+}
+
+void ImportSettingsMenuItem(HANDLE hContact)
+{
+ if (hwnd2importWindow)
+ DestroyWindow(hwnd2importWindow);
+
+ CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_IMPORT), 0, ImportDlgProc, (LPARAM)hContact);
+}
+
+int Openfile2Import(char *outputFiles)
+{
+ OPENFILENAME ofn = {0};
+ char filter[MAX_PATH];
+ mir_snprintf(filter, SIZEOF(filter), "%s%c*.ini%c%s%c*.*%c", Translate("INI Files"), 0, 0, Translate("All Files"), 0, 0);
+ char *title = Translate("Import from files");
+
+ ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400;
+ ofn.lpstrFilter = filter;
+ ofn.hwndOwner = 0;
+ ofn.lpstrFile = outputFiles;
+ ofn.nMaxFile = MAX_PATH*10;
+ ofn.nMaxFileTitle = MAX_PATH;
+ ofn.Flags = OFN_HIDEREADONLY | OFN_SHAREAWARE | OFN_PATHMUSTEXIST | OFN_ALLOWMULTISELECT | OFN_EXPLORER;
+ ofn.lpstrTitle = title;
+ if (!GetOpenFileName(&ofn))
+ return 0;
+
+ return ofn.nFileOffset;
+}
+
+BOOL Exists(LPCTSTR strName)
+{
+ return GetFileAttributes(strName) != INVALID_FILE_ATTRIBUTES;
+}
+
+void ImportSettingsFromFileMenuItem(HANDLE hContact, char* FilePath)
+{
+ char szFileNames[MAX_PATH*10] = {0};
+ char szPath[MAX_PATH] = "";
+ char szFile[MAX_PATH];
+ int index = 0;
+ HANDLE hFile, hMap;
+ PBYTE pFile = NULL;
+ DWORD offset = 0;
+ if (lstrcmp(FilePath, "") == 0)
+ offset = Openfile2Import(szFileNames);
+ else
+ {
+ if(Exists(FilePath))
+ lstrcpy(szFileNames, FilePath);
+ else
+ lstrcpy(szFileNames, "");
+ }
+
+ if (!lstrcmp(szFileNames, "") == 0)
+ {
+ if ((DWORD)lstrlenA(szFileNames) < offset)
+ {
+ index += offset;
+ strncpy(szPath, szFileNames, offset);
+ strcat(szPath, "\\");
+ }
+
+ while(szFileNames[index])
+ {
+ strcpy(szFile, szPath);
+ strcat(szFile, &szFileNames[index]);
+ index += (int)strlen(&szFileNames[index])+1;
+
+ hFile = CreateFile(szFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
+ if (hFile != INVALID_HANDLE_VALUE)
+ {
+ if (GetFileSize(hFile, NULL) > 0)
+ {
+ hMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
+
+ if (hMap) {
+ pFile = (PBYTE)MapViewOfFile(hMap, FILE_MAP_COPY, 0, 0 ,0);
+
+ if (pFile) {
+ importSettings(hContact, (char*)pFile);
+ UnmapViewOfFile(pFile);
+ }
+ CloseHandle(hMap);
+ }
+
+ }
+ CloseHandle(hFile);
+ }
+ else
+ break;
+
+ }
+ if (lstrcmp(FilePath, "") == 0)
+ refreshTree(1);
+ }
+}
diff --git a/plugins/dbeditorpp/findwindow.cpp b/plugins/dbeditorpp/findwindow.cpp
new file mode 100644
index 0000000000..b9957cd246
--- /dev/null
+++ b/plugins/dbeditorpp/findwindow.cpp
@@ -0,0 +1,725 @@
+#include "headers.h"
+
+void __cdecl FindSettings(LPVOID di);
+
+static int working;
+static int replace;
+
+#define FW_CASE 1
+#define FW_EXACT 2
+#define FW_MODNAME 4
+#define FW_SETNAME 8
+#define FW_SETVAL 16
+
+#define FW_REPLACED 0x100
+#define FW_DELETED 0x200
+
+#define RW_MODULE 1
+#define RW_SETNAME 2
+#define RW_SETVAL 4
+#define RW_FOUND 8
+
+#define RW_FULL 0x100
+#define RW_CASE 0x200
+
+typedef struct {
+ HWND hwnd; // hwnd 2 item list
+ char* text; // text to find
+ int options; // or'd about items
+ char* replace; // text to replace
+ int mode; // replace mode
+} FindInfo;
+
+
+int FindDialogResize(HWND hwnd,LPARAM lParam,UTILRESIZECONTROL *urc)
+{
+ switch(urc->wId) {
+ case IDC_LIST:
+ return RD_ANCHORX_WIDTH|RD_ANCHORY_HEIGHT;
+ case IDC_SBAR:
+ return RD_ANCHORX_WIDTH|RD_ANCHORY_BOTTOM;
+ default:
+ return RD_ANCHORX_LEFT|RD_ANCHORY_TOP;
+ }
+}
+
+
+void freeItems(HWND hwnd)
+{
+ int i;
+ ItemInfo *ii;
+ for (i=0;i<SendMessage(hwnd,LB_GETCOUNT,0,0);i++)
+ {
+ ii = (ItemInfo*)SendMessage(hwnd,LB_GETITEMDATA,i,0);
+
+ if ((LRESULT)ii != LB_ERR)
+ mir_free(ii);
+ }
+}
+
+
+INT_PTR CALLBACK FindWindowDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch(msg)
+ {
+ case WM_INITDIALOG:
+ {
+ TranslateDialogDefault(hwnd);
+ SendMessage(GetDlgItem(hwnd,IDC_SBAR),SB_SETTEXT,0,(LPARAM)Translate("Enter a string to search the DB for"));
+ CheckDlgButton(hwnd,IDC_MODNAME,1);
+ CheckDlgButton(hwnd,IDC_SETTINGNAME,1);
+ CheckDlgButton(hwnd,IDC_SETTINGVALUE,1);
+ CheckDlgButton(hwnd,IDC_FOUND,1);
+ SendMessage(hwnd,WM_SETICON,ICON_BIG,(LPARAM)LoadIcon(hInst,MAKEINTRESOURCE(ICO_REGEDIT)));
+ SetWindowLongPtr(GetDlgItem(hwnd,IDC_REPLACE),GWLP_USERDATA, 0);
+ SetWindowLongPtr(GetDlgItem(hwnd,IDC_SEARCH),GWLP_USERDATA, 0);
+ }
+ return TRUE;
+ case WM_COMMAND:
+ switch(LOWORD(wParam))
+ {
+ case IDOK:
+ SetWindowLongPtr(GetDlgItem(hwnd,IDC_REPLACE),GWLP_USERDATA, 1);
+
+ case IDC_SEARCH:
+ {
+
+ if (GetWindowLongPtr(GetDlgItem(hwnd,IDC_SEARCH),GWLP_USERDATA)) // stop the search
+ {
+ SetWindowLongPtr(GetDlgItem(hwnd,IDC_SEARCH),GWLP_USERDATA,0);
+ }
+ else
+ {
+
+ FindInfo *fi;
+ char text[256];
+ char replace[256]="";
+
+ if (!GetDlgItemText(hwnd,IDC_TEXT,text,SIZEOF(text))) break;
+
+ if (GetWindowLongPtr(GetDlgItem(hwnd,IDC_REPLACE),GWLP_USERDATA) &&
+ !GetDlgItemText(hwnd,IDC_REPLACE,replace,SIZEOF(replace)) &&
+ !IsDlgButtonChecked(hwnd,IDC_ENTIRELY))
+ break;
+
+ if (!IsDlgButtonChecked(hwnd,IDC_MODNAME) &&
+ !IsDlgButtonChecked(hwnd,IDC_SETTINGNAME) &&
+ !IsDlgButtonChecked(hwnd,IDC_SETTINGVALUE)
+ ) break;
+
+ fi = (FindInfo*)mir_calloc(sizeof(FindInfo));
+ if (!fi) break;
+
+ fi->hwnd = GetDlgItem(hwnd,IDC_LIST);
+ fi->options = (IsDlgButtonChecked(hwnd,IDC_CASESENSITIVE)?FW_CASE:0)|
+ (IsDlgButtonChecked(hwnd,IDC_EXACT)?FW_EXACT:0)|
+ (IsDlgButtonChecked(hwnd,IDC_MODNAME)?FW_MODNAME:0)|
+ (IsDlgButtonChecked(hwnd,IDC_SETTINGNAME)?FW_SETNAME:0)|
+ (IsDlgButtonChecked(hwnd,IDC_SETTINGVALUE)?FW_SETVAL:0);
+
+ if (GetWindowLongPtr(GetDlgItem(hwnd,IDC_REPLACE),GWLP_USERDATA))
+ {
+ if (IsDlgButtonChecked(hwnd,IDC_FOUND))
+ fi->mode = RW_FOUND;
+ else
+ if (IsDlgButtonChecked(hwnd,IDC_MODNAME2))
+ fi->mode = RW_MODULE;
+ else
+ if (IsDlgButtonChecked(hwnd,IDC_SETTINGNAME2))
+ fi->mode = RW_SETNAME;
+ else
+ if (IsDlgButtonChecked(hwnd,IDC_SETTINGVALUE2))
+ fi->mode = RW_SETVAL;
+
+ if (IsDlgButtonChecked(hwnd,IDC_ENTIRELY))
+ fi->mode |= RW_FULL;
+
+ fi->replace = mir_tstrdup(replace);
+
+ SetWindowText(GetDlgItem(hwnd,IDOK),Translate("Stop"));
+ EnableWindow(GetDlgItem(hwnd,IDC_SEARCH),0);
+
+ if (IsDlgButtonChecked(hwnd,IDC_CASESENSITIVE))
+ fi->mode |= RW_CASE;
+ }
+ else
+ {
+ SetWindowText(GetDlgItem(hwnd,IDC_SEARCH),Translate("Stop"));
+ EnableWindow(GetDlgItem(hwnd,IDOK),0);
+ }
+
+ fi->text = mir_tstrdup(text);
+
+ SendDlgItemMessage(hwnd,IDC_LIST,LB_RESETCONTENT,0,0);
+ SetWindowLongPtr(GetDlgItem(hwnd,IDC_SEARCH),GWLP_USERDATA,1);
+
+ EnableWindow(GetDlgItem(hwnd,IDCANCEL),0);
+ forkthread(FindSettings,0,fi);
+ }
+ }
+ break;
+ case IDCANCEL:
+ DestroyWindow(hwnd);
+ break;
+ case IDC_LIST:
+ if (HIWORD(wParam) == LBN_DBLCLK)
+ {
+ int i = SendDlgItemMessage(hwnd,IDC_LIST,LB_GETCURSEL,0,0);
+ ItemInfo *ii =(ItemInfo*)SendDlgItemMessage(hwnd,IDC_LIST,LB_GETITEMDATA,i,0);
+ if (!ii) break;
+ SendMessage(GetParent(hwnd),WM_FINDITEM,(WPARAM)ii,0);
+ }
+ break;
+ }
+ break;
+ case WM_GETMINMAXINFO:
+ {
+ MINMAXINFO *mmi=(MINMAXINFO*)lParam;
+ mmi->ptMinTrackSize.x=520;
+ mmi->ptMinTrackSize.y=300;
+ return 0;
+ }
+ case WM_SIZE:
+ {
+ UTILRESIZEDIALOG urd;
+ ZeroMemory(&urd,sizeof(urd));
+ urd.cbSize=sizeof(urd);
+ urd.hInstance=hInst;
+ urd.hwndDlg=hwnd;
+ urd.lpTemplate=MAKEINTRESOURCE(IDD_FIND);
+ urd.pfnResizer=FindDialogResize;
+ CallService(MS_UTILS_RESIZEDIALOG,0,(LPARAM)&urd);
+ }
+ break;
+ case WM_DESTROY:
+ freeItems(hwnd);
+ break;
+ }
+ return 0;
+}
+
+
+void ItemFound(HWND hwnd, HANDLE hContact,const char *module,const char *setting,const char* value,int type)
+{
+ ItemInfo *ii = (ItemInfo*)mir_calloc(sizeof(ItemInfo));
+ int index;
+ char text[256] = "";
+ int result = 0;
+ char szValue[256];
+ char *name, *mode;
+
+ if (!ii) return;
+
+ if (type & FW_REPLACED)
+ mode = Translate("Replaced with");
+ else
+ if (type & FW_DELETED)
+ mode = Translate("Deleted");
+ else
+ mode = Translate("Found");
+
+ name = hContact?(char*)GetContactName(hContact,NULL,0):Translate("Settings");
+
+ switch (type & 0xFF)
+ {
+ case FW_MODULE:
+ ii->type = FW_MODULE;
+ mir_snprintf(text, SIZEOF(text), Translate("%s Module \"%s\" in contact \"%s\""), mode, module, name);
+ break;
+ case FW_SETTINGNAME:
+ mir_strncpy(ii->setting,setting,256);
+ ii->type = FW_SETTINGNAME;
+ if (GetValue(hContact,module,setting, szValue, SIZEOF(szValue)))
+ mir_snprintf(text, SIZEOF(text), Translate("%s Setting \"%s\" in module \"%s\" in contact \"%s\" - \"%s\""), mode, setting, module, name, szValue);
+ else
+ mir_snprintf(text, SIZEOF(text), Translate("%s Setting \"%s\" in module \"%s\" in contact \"%s\""), mode, setting, module, name);
+ break;
+ case FW_SETTINGVALUE:
+ mir_strncpy(ii->setting,setting,256);
+ ii->type = FW_SETTINGVALUE;
+ mir_snprintf(text, SIZEOF(text), Translate("%s \"%s\" in Setting \"%s\" in module \"%s\" in contact \"%s\""), mode, value, setting, module, name);
+ break;
+ }
+
+ index = SendMessage(hwnd,LB_ADDSTRING,0,(LPARAM)text);
+ if (type & FW_DELETED)
+ {
+ SendMessage(hwnd,LB_SETITEMDATA,index,0);
+ mir_free(ii);
+ }
+ else
+ {
+ ii->hContact= hContact;
+ mir_strncpy(ii->module,module,256);
+ SendMessage(hwnd,LB_SETITEMDATA,index,(LPARAM)ii);
+ }
+}
+
+
+char *multiReplace(const char* value, const char *find, const char *replace, int cs)
+{
+ char *head, *temp, *string;
+
+ int len = (int)strlen(find);
+ int replen = (int)strlen(replace);
+
+ if (head = (char*)(cs?strstr(value, find):StrStrI(value, find))) // only should be 1 '=' sign there...
+ {
+ string = (char*)value;
+ temp = (char*)mir_alloc(1*sizeof(char));
+ temp[0] = '\0';
+
+ while (head)
+ {
+ temp = (char*)mir_realloc(temp, strlen(temp) + strlen(string) + replen + 1);
+ if (!temp) mir_tstrdup(value);
+
+ strncat(temp, string, (head - string));
+ string = head + len;
+ strcat(temp, replace);
+
+ head = (cs?strstr(string, find):StrStrI(string, find));
+ }
+ strcat(temp, string);
+
+ return temp;
+ }
+
+ return mir_tstrdup(value);
+}
+
+
+int replaceValue(HWND hwnd, HANDLE hContact, const char *module, const char *setting, DBVARIANT *dbv, const char *find, const char *replace, int mode)
+{
+
+ int count = 0;
+
+ DWORD num = 0;
+ BOOL write = 0;
+ int isNumeric;
+ char *myreplace = NULL;
+ DBCONTACTWRITESETTING cws = {0};
+
+ if (!dbv->type || dbv->type == DBVT_BLOB)
+ return 0;
+
+ if (!replace[0])
+ isNumeric = 1;
+ else
+ isNumeric = sscanf(replace,"%d",&num);
+
+ cws.szModule=module;
+ cws.szSetting=setting;
+ cws.value.type=dbv->type;
+
+ switch(dbv->type)
+ {
+ case DBVT_UTF8:
+ case DBVT_ASCIIZ:
+ if (mode & RW_FULL)
+ cws.value.pszVal = (char*)replace;
+ else
+ {
+ myreplace = multiReplace(dbv->pszVal, find, replace, mode & RW_CASE);
+ cws.value.pszVal=myreplace;
+ }
+ break;
+
+ case DBVT_BYTE:
+ if (isNumeric && num < 0x100)
+ cws.value.bVal = (BYTE)num;
+ else
+ return 0;
+ break;
+
+ case DBVT_WORD:
+ if (isNumeric && num < 0x10000)
+ cws.value.wVal = (WORD)num;
+ else
+ return 0;
+ break;
+
+ case DBVT_DWORD:
+ if (isNumeric)
+ cws.value.dVal = num;
+ else
+ return 0;
+ break;
+
+ default:
+ return 0;
+ }
+
+ if ((!cws.value.pszVal && !replace[0]) || (cws.value.pszVal && !cws.value.pszVal[0]))
+ {
+ ItemFound(hwnd,hContact,module,setting,NULL,FW_SETTINGNAME|FW_DELETED);
+ DBDeleteContactSetting(hContact,module,setting);
+ mir_free(myreplace);
+ return 1;
+ }
+
+ if (!CallService(MS_DB_CONTACT_WRITESETTING,(WPARAM)hContact,(LPARAM)&cws))
+ {
+ count++;
+ ItemFound(hwnd,hContact,module,setting,myreplace?myreplace:(char*)replace,FW_SETTINGVALUE|FW_REPLACED);
+ }
+
+ mir_free(myreplace);
+
+ return count;
+}
+
+
+int replaceSetting(HWND hwnd, HANDLE hContact, const char *module, const char *setting, DBVARIANT *dbv, const char *find, const char *replace, int mode)
+{
+ DBCONTACTWRITESETTING cws;
+ char *myreplace = NULL;
+ int count = 0;
+ DBVARIANT dbv2;
+
+ if (!dbv->type) return 0;
+
+ if (mode & RW_FULL)
+ cws.szSetting = (char*)replace;
+ else
+ {
+ myreplace = multiReplace(setting, find, replace, mode & RW_CASE);
+ cws.szSetting = myreplace;
+ }
+
+ if (cws.szSetting[0]==0)
+ {
+ ItemFound(hwnd,hContact,module,setting,NULL,FW_SETTINGNAME|FW_DELETED);
+ DBDeleteContactSetting(hContact,module,setting);
+ mir_free(myreplace);
+ return 1;
+ }
+
+ // check & write
+ if (GetSetting(hContact, module, myreplace, &dbv2))
+ {
+ cws.szModule=module;
+ cws.value.type=dbv->type;
+ cws.value.pszVal=dbv->pszVal;
+ cws.value.bVal=dbv->bVal;
+ cws.value.wVal=dbv->wVal;
+ cws.value.dVal=dbv->dVal;
+ cws.value.pbVal = dbv->pbVal;
+ cws.value.cpbVal = dbv->cpbVal;
+
+ if (!CallService(MS_DB_CONTACT_WRITESETTING,(WPARAM)hContact,(LPARAM)&cws))
+ {
+ count++;
+ DBDeleteContactSetting(hContact,module,setting);
+ ItemFound(hwnd,hContact,module,cws.szSetting,NULL,FW_SETTINGNAME|FW_REPLACED);
+ }
+ }
+ else
+ DBFreeVariant(&dbv2);
+
+ mir_free(myreplace);
+
+ return count;
+}
+
+
+int replaceModule(HWND hwnd, HANDLE hContact, const char *module, const char *find, const char *replace, int mode)
+{
+
+ ModuleSettingLL msll;
+ struct ModSetLinkLinkItem *setting;
+ char *myreplace = NULL;
+ char *newModule;
+ int count = 0;
+
+ if (mode & RW_FULL)
+ newModule = (char*)replace;
+ else
+ {
+ myreplace = multiReplace(module, find, replace, mode & RW_CASE);
+ newModule = myreplace;
+ }
+
+ if (newModule[0]==0)
+ {
+ ItemFound(hwnd,hContact,module,NULL,NULL,FW_MODULE|FW_DELETED);
+ deleteModule((char*)module, hContact, 1);
+ replaceTreeItem(GetDlgItem(hwnd2mainWindow,IDC_MODULES), hContact, module, NULL);
+ mir_free(myreplace);
+ return 1;
+ }
+
+ if (!IsModuleEmpty(hContact, newModule))
+ return 0;
+
+ if (EnumSettings(hContact,(char*)module,&msll))
+ {
+ setting = msll.first;
+
+ while(setting)
+ {
+ DBVARIANT dbv;
+
+ if (!GetSetting(hContact, module, setting->name, &dbv))
+ {
+ switch (dbv.type)
+ {
+ case DBVT_BYTE:
+ DBWriteContactSettingByte(hContact, newModule, setting->name, dbv.bVal);
+ break;
+ case DBVT_WORD:
+ DBWriteContactSettingWord(hContact, newModule, setting->name, dbv.wVal);
+ break;
+ case DBVT_DWORD:
+ DBWriteContactSettingDword(hContact, newModule, setting->name, dbv.dVal);
+ break;
+ case DBVT_ASCIIZ:
+ DBWriteContactSettingString(hContact, newModule, setting->name, dbv.pszVal);
+ break;
+ case DBVT_UTF8:
+ DBWriteContactSettingStringUtf(hContact, newModule, setting->name, dbv.pszVal);
+ break;
+ case DBVT_BLOB:
+ DBWriteContactSettingBlob(hContact, newModule, setting->name, dbv.pbVal, dbv.cpbVal);
+ break;
+ }
+
+ DBFreeVariant(&dbv);
+ DBDeleteContactSetting(hContact, module, setting->name);
+ }
+
+ setting = (struct ModSetLinkLinkItem *)setting->next;
+ }
+ FreeModuleSettingLL(&msll);
+
+ replaceTreeItem(GetDlgItem(hwnd2mainWindow,IDC_MODULES), hContact, module, newModule);
+
+ ItemFound(hwnd,hContact,newModule,NULL,NULL,FW_MODULE|FW_REPLACED);
+ count++;
+ }
+
+ mir_free(myreplace);
+
+ return count;
+}
+
+
+char* stringToUpper(char* in, char* out, int maxlen)
+{
+ int i;
+ int len;
+
+ if (maxlen>0)
+ len = maxlen - 1;
+ else
+ len = 0x10000;
+
+ for (i=0;in[i] && i<len;i++)
+ out[i] = (in[i]>='a' && in[i]<='z')?toupper(in[i]):in[i];
+ out[i] = '\0';
+
+ return out;
+}
+
+
+void __cdecl FindSettings(LPVOID di)
+{
+ char* text = ((FindInfo*)di)->text;
+ char* replace = ((FindInfo*)di)->replace;
+ int mode = ((FindInfo*)di)->mode;
+ HWND hwnd = ((FindInfo*)di)->hwnd;
+ HWND prnthwnd = GetParent(hwnd);
+ int options = ((FindInfo*)di)->options;
+ ModuleSettingLL ModuleList, SettingList;
+ struct ModSetLinkLinkItem *module, *setting;
+ HANDLE hContact;
+ DBVARIANT dbv = {0};
+ int caseSensitive = options&FW_CASE;
+ int exactMatch = options&FW_EXACT;
+ int inModuleName = options&FW_MODNAME;
+ int inSettingName = options&FW_SETNAME;
+ int inSettingValue = options&FW_SETVAL;
+ int foundCount = 0;
+ int replaceCount = 0;
+ char szTmp[128];
+ int settingValue, isNumber, NULLContactDone = 0;
+
+ freeItems(hwnd);
+ if (!text) return;
+
+ if (!EnumModules(&ModuleList)) { msg(Translate("Error Loading Module List"),modFullname); mir_free(di); return;}
+
+ SendMessage(GetDlgItem(GetParent(hwnd),IDC_SBAR),SB_SETTEXT,0,(LPARAM)Translate("Searching..."));
+
+ hContact = 0;
+
+ isNumber = sscanf(text,"%d",&settingValue);
+
+ while (GetWindowLongPtr(GetDlgItem(prnthwnd,IDC_SEARCH),GWLP_USERDATA))
+ {
+ if (!hContact)
+ {
+ if (NULLContactDone) break;
+ else
+ {
+ NULLContactDone = 1;
+ hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ }
+ }
+ else hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0);
+
+ module = ModuleList.first;
+ while (module)
+ {
+ if (IsModuleEmpty(hContact, module->name))
+ {
+ module = (struct ModSetLinkLinkItem *)module->next;
+ continue;
+ }
+
+ if (!EnumSettings(hContact,module->name,&SettingList))
+ {
+ msg(Translate("Error Loading Setting List"),modFullname);
+ mir_free(text);
+ mir_free(di);
+ FreeModuleSettingLL(&ModuleList);
+ return;
+ }
+ setting = SettingList.first;
+
+ // check in settings value
+ while (setting)
+ {
+ if (inSettingValue)
+ {
+ dbv.type = 0;
+ // check the setting value
+ if (!GetSetting(hContact,module->name,setting->name,&dbv))
+ {
+ switch (dbv.type)
+ {
+ case DBVT_UTF8: // no conversion atm
+ case DBVT_ASCIIZ:
+ if ((exactMatch && !(caseSensitive?strcmp(dbv.pszVal,text):strcmpi(dbv.pszVal,text))) || (!exactMatch && (caseSensitive?strstr(dbv.pszVal,text):StrStrI(dbv.pszVal,text))))
+ {
+ if ((mode & RW_FOUND) || (mode & RW_SETVAL))
+ replaceCount += replaceValue(hwnd, hContact, module->name, setting->name, &dbv, text, replace, mode);
+ else
+ ItemFound(hwnd,hContact,module->name,setting->name,dbv.pszVal,FW_SETTINGVALUE);
+
+ foundCount++;
+ }
+ break;
+
+ case DBVT_BYTE:
+ if (isNumber && settingValue == dbv.bVal)
+ {
+ if ((mode & RW_FOUND) || (mode & RW_SETVAL))
+ replaceCount += replaceValue(hwnd, hContact, module->name, setting->name, &dbv, NULL, replace, mode);
+ else
+ ItemFound(hwnd,hContact,module->name,setting->name,text,FW_SETTINGVALUE);
+ foundCount++;
+ }
+ break;
+
+ case DBVT_WORD:
+ if (isNumber && settingValue == dbv.wVal)
+ {
+ if ((mode & RW_FOUND) || (mode & RW_SETVAL))
+ replaceCount += replaceValue(hwnd, hContact, module->name, setting->name, &dbv, NULL, replace, mode);
+ else
+ ItemFound(hwnd,hContact,module->name,setting->name,text,FW_SETTINGVALUE);
+ foundCount++;
+ }
+ break;
+
+ case DBVT_DWORD:
+ if (isNumber && settingValue == (int)dbv.dVal)
+ {
+ if ((mode & RW_FOUND) || (mode & RW_SETVAL))
+ replaceCount += replaceValue(hwnd, hContact, module->name, setting->name, &dbv, NULL, replace, mode);
+ else
+ ItemFound(hwnd,hContact,module->name,setting->name,text,FW_SETTINGVALUE);
+ foundCount++;
+ }
+ break;
+
+ }
+ DBFreeVariant(&dbv);
+ }
+ }
+
+ // check in setting name
+ if (inSettingName)
+ {
+ if ((exactMatch && !(caseSensitive?strcmp(setting->name,text):strcmpi(setting->name,text))) || (!exactMatch && (caseSensitive?StrStrI(setting->name,text):StrStrI(setting->name,text))))
+ {
+ if ((mode & RW_FOUND) || (mode & RW_SETNAME))
+ {
+ if (!GetSetting(hContact,module->name,setting->name,&dbv))
+ {
+ replaceCount += replaceSetting(hwnd, hContact, module->name, setting->name, &dbv, text, replace, mode);
+ DBFreeVariant(&dbv);
+ }
+ }
+ else
+ ItemFound(hwnd,hContact,module->name,setting->name, NULL, FW_SETTINGNAME);
+ foundCount++;
+ }
+ }
+
+ setting = (struct ModSetLinkLinkItem *)setting->next;
+ }
+
+ // check in module name
+ if (inModuleName)
+ {
+ if ((exactMatch && !(caseSensitive?strcmp(module->name,text):strcmpi(module->name,text))) || (!exactMatch && (caseSensitive?strstr(module->name,text):StrStrI(module->name,text))))
+ {
+ if ((mode & RW_FOUND) || (mode & RW_MODULE))
+ replaceCount += replaceModule(hwnd, hContact, module->name, text, replace, mode);
+ else
+ ItemFound(hwnd,hContact,module->name,0, 0, FW_MODULE);
+ foundCount++;
+ }
+ }
+
+ FreeModuleSettingLL(&SettingList);
+ module = (struct ModSetLinkLinkItem *)module->next;
+ }
+ }
+
+ if (mode)
+ {
+ if (!replace[0])
+ mir_snprintf(szTmp, SIZEOF(szTmp), Translate("Finished. %d items were found, %d items were deleted."), foundCount, replaceCount);
+ else
+ mir_snprintf(szTmp, SIZEOF(szTmp), Translate("Finished. %d items were found, %d items were replaced."), foundCount, replaceCount);
+ }
+ else
+ mir_snprintf(szTmp, SIZEOF(szTmp), Translate("Finished. %d items were found."), foundCount);
+
+ SendMessage(GetDlgItem(prnthwnd,IDC_SBAR),SB_SETTEXT,0,(LPARAM)szTmp);
+
+ SetWindowLongPtr(GetDlgItem(prnthwnd,IDC_SEARCH),GWLP_USERDATA,0);
+
+ if (GetWindowLongPtr(GetDlgItem(prnthwnd,IDC_REPLACE),GWLP_USERDATA))
+ {
+ SetWindowLongPtr(GetDlgItem(prnthwnd,IDC_REPLACE),GWLP_USERDATA, 0);
+ EnableWindow(GetDlgItem(prnthwnd,IDC_SEARCH),1);
+ SetWindowText(GetDlgItem(prnthwnd,IDOK),Translate("&Replace"));
+ }
+ else
+ {
+ SetWindowText(GetDlgItem(prnthwnd,IDC_SEARCH),Translate("&Search"));
+ EnableWindow(GetDlgItem(prnthwnd,IDOK),1);
+ }
+
+ mir_free(replace);
+ mir_free(text);
+ mir_free(di);
+ FreeModuleSettingLL(&ModuleList);
+
+ EnableWindow(GetDlgItem(prnthwnd,IDCANCEL),1);
+
+}
diff --git a/plugins/dbeditorpp/headers.h b/plugins/dbeditorpp/headers.h
new file mode 100644
index 0000000000..838d09c165
--- /dev/null
+++ b/plugins/dbeditorpp/headers.h
@@ -0,0 +1,267 @@
+#ifndef _COMMONHEADERS_H
+#define _COMMONHEADERS_H
+//=====================================================
+// Includes
+//=====================================================
+
+#define _WIN32_WINNT 0x0501
+#define MIRANDA_VER 0x0900
+#define MIRANDA_CUSTOM_LP
+
+#if defined( UNICODE ) && !defined( _UNICODE )
+ #define _UNICODE
+#endif
+
+#include <tchar.h>
+
+#include <Windows.h>
+#include <commctrl.h>
+#include <stdio.h>
+#include <io.h>
+#include <time.h>
+#include <stddef.h>
+#include <shlwapi.h>
+#include <process.h>
+#include <string.h>
+#include <win2k.h>
+#include <malloc.h>
+
+#include <newpluginapi.h>
+#include <m_utils.h>
+#include <m_clist.h>
+#include <m_clui.h>
+#include <m_skin.h>
+#include <m_langpack.h>
+#include <m_protomod.h>
+#include <m_database.h>
+#include <m_system.h>
+#include <m_protocols.h>
+#include <m_userinfo.h>
+#include <m_options.h>
+#include <m_protosvc.h>
+#include <m_ignore.h>
+#include <m_clc.h>
+#include <m_history.h>
+#include <m_popup.h>
+#include <m_icolib.h>
+#include <m_hotkeys.h>
+
+#include "m_updater.h"
+#include "m_toptoolbar.h"
+
+#include "resource.h"
+#include "Version.h"
+#include "modsettingenum.h"
+
+#define DEF_ICON 7
+#define crlf_string "\r\n\0"
+
+/////// icons support
+
+extern BYTE UsingIconManager;
+void addIcons(TCHAR* szModuleFileName);
+HICON LoadSkinnedDBEIcon(int icon);
+int AddIconToList(HIMAGELIST hil, HICON hIcon);
+void AddProtoIconsToList(HIMAGELIST hil, int newshift);
+int GetProtoIcon(char *szProto);
+extern HANDLE hRestore;
+extern HANDLE hUserMenu;
+/////////////////////
+
+#ifndef NDEBUG
+ #define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
+#endif
+
+//=======================================================
+// Definitions
+//=======================================================
+#define modname "DBEditorpp"
+#define modFullname "Database Editor++"
+#define msg(a,b) MessageBoxA(0,a,b,MB_OK)
+#define nick_unknown "(UNKNOWN)"
+#define nick_unknownW L"(UNKNOWN)"
+
+
+#define WM_FINDITEM (WM_USER+1) // onyl for the main window, wparam is ItemIfno* lparam is 0
+
+#define mir_strlen(ptr) ((ptr==NULL)?0:(int)strlen(ptr))
+#define mir_strncpy(dst, src, len) strncpy(dst, src, len)[len-1]=0;
+#define mir_strcmp(ptr1, ptr2) ((ptr1 && ptr2)?strcmp(ptr1, ptr2):1) // (ptr1||ptr2)
+
+#define ListView_SetItemTextW(hwndLV, i, iSubItem_, pszText_) \
+{ LV_ITEMW _ms_lvi;\
+ _ms_lvi.iSubItem = iSubItem_;\
+ _ms_lvi.pszText = pszText_;\
+ SendMessageW((hwndLV), LVM_SETITEMTEXTW, (WPARAM)(i), (LPARAM)(LV_ITEMW *)&_ms_lvi);\
+}
+
+#define ListView_InsertItemW(hwnd, pitem) \
+ SendMessageW((hwnd), LVM_INSERTITEMW, 0, (LPARAM)(const LV_ITEMW *)(pitem))
+
+
+#define TreeView_InsertItemW(hwnd, lpis) \
+ (HTREEITEM)SendMessageW((hwnd), TVM_INSERTITEMW, 0, (LPARAM)(LPTV_INSERTSTRUCTW)(lpis))
+
+/***********************
+ ModuleTreeInfoStruct
+ this gets dumped as the lparam for each module tree item
+************************/
+// types
+#define CONTACT_ROOT_ITEM 0
+#define CONTACT 1
+#define MODULE 0x2
+#define KNOWN_MODULE 2
+#define UNKNOWN_MODULE 3
+#define STUB 4
+#define EMPTY 8
+
+typedef struct {
+ int type; // from above types
+ HANDLE hContact;
+} ModuleTreeInfoStruct;
+
+typedef struct {
+ HANDLE hContact;
+ char* module;
+ HWND hwnd2Edit;
+ int selectedItem; // item that is currently selected
+ int clicks; // set to 0 when selection changes, 1 after another click.. cant edit till this is 1
+} SettingListInfo;
+
+#define WATCH_MODULE 1
+#define WATCH_SETTING 0
+
+struct DBsetting {
+ DBVARIANT dbv;
+ HANDLE hContact;
+ char *module;
+ char *setting;
+ int WatchModule; // above defines
+};
+
+typedef struct {
+ char module[256];
+ HANDLE hContact;
+} ModuleAndContact;
+
+// find window
+#define FW_MODULE 0
+#define FW_SETTINGNAME 1
+#define FW_SETTINGVALUE 2
+
+typedef struct {
+ int type; // above types
+ HANDLE hContact;
+ char module[256];
+ char setting[256];
+} ItemInfo;
+
+// watchwindow
+struct WatchListArrayStruct{
+ struct DBsetting *item; // gotta malloc this
+ int count;
+ int size;
+};
+extern WatchListArrayStruct WatchListArray;
+
+//=======================================================
+// Variables
+//=======================================================
+extern HINSTANCE hInst;
+extern HWND hwnd2mainWindow, hwnd2watchedVarsWindow, hwnd2importWindow;
+extern HIMAGELIST himl;
+extern HIMAGELIST himl2;
+extern int Mode;
+extern int Hex;
+extern int Order;
+extern BOOL UDB, UOS;
+
+extern BOOL usePopUps;
+
+#define NAMEORDERCOUNT 8
+
+#define MODE_UNLOADED 1
+#define MODE_LOADED 2
+#define MODE_ALL 3
+
+#define HEX_BYTE 1
+#define HEX_WORD 2
+#define HEX_DWORD 4
+
+//main.c
+int DBGetContactSettingStringStatic(HANDLE hContact, char* szModule, char* szSetting, char* value, int maxLength);
+int WriteBlobFromString(HANDLE hContact,const char *szModule,const char *szSetting, const char *Value, int len);
+int GetSetting(HANDLE hContact, const char *szModule, const char *szSetting, DBVARIANT *dbv);
+int GetValue(HANDLE hContact, const char* szModule, const char* szSetting, char* Value, int length);
+int GetValueW(HANDLE hContact, const char* szModule, const char* szSetting, WCHAR* Value, int length);
+char* u2a( wchar_t* src );
+wchar_t *a2u( char* src , wchar_t *buffer, int len );
+int mir_snwprintf(WCHAR *buffer, size_t count, const WCHAR* fmt, ...);
+WCHAR *GetContactName(HANDLE hContact, const char *szProto, int unicode);
+BOOL IsProtocolLoaded(char* pszProtocolName);
+
+// main_window.c
+INT_PTR CALLBACK MainDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+
+// modules.c
+int deleteModule(char* module, HANDLE hContact, int fromMenu);
+void deleteModuleGui();
+void renameModule(char* oldName, char* newName, HANDLE hContact);
+INT_PTR CALLBACK AddModDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+int CloneContact(HANDLE hContact);
+
+// moduletree.c
+void replaceTreeItem(HWND hwnd, HANDLE hContact, const char *module, const char *newModule);
+void refreshTree(BOOL restore);
+void __cdecl PopulateModuleTreeThreadFunc(LPVOID di);
+void freeTree(HWND hwnd2Tree, HANDLE hContact);
+int findItemInTree(HWND hwnd2Tree, HANDLE hContact, char* module);
+
+// threads.c
+unsigned long forkthread ( void (__cdecl *threadcode)(void*),unsigned long stacksize,void *arg) ;
+
+// settinglist.c
+void setupSettingsList(HWND hwnd2List);
+void saveListSettings(HWND hwnd2List);
+void ClearListview(HWND hwnd2Settings);
+void DeleteSettingsFromList(HWND hSettings, HANDLE hContact, char *module, char *setting);
+void PopulateSettings(HWND hwnd2Settings, HANDLE hContact, char* module);
+void SelectSetting(char* setting);
+
+// addeditsettingsdlg.c
+INT_PTR CALLBACK EditSettingDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+void editSetting(HANDLE hContact, char* module, char* setting);
+BOOL convertSetting(HANDLE hContact, char* module, char* setting, int toType); // 0 = byte, 1 = word, 2 = dword, 3 = string
+
+// exportimport.c
+void exportDB(HANDLE hContact, char* module); // hContact == -1 export entire db. module == NULL export entire contact
+void ImportSettingsMenuItem(HANDLE hContact);
+void ImportSettingsFromFileMenuItem(HANDLE hContact, char* FilePath);
+
+// find window.c
+INT_PTR CALLBACK FindWindowDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+
+// knownmodules.c
+extern BYTE UseKnownModList;
+INT_PTR RegisterModule(WPARAM wParam, LPARAM lParam);
+INT_PTR RegisterSingleModule(WPARAM wParam, LPARAM lParam);
+void FreeKnownModuleList();
+int IsModuleKnown(char* moduleName);
+void doOldKnownModulesList();
+
+// copymodule.c
+void copyModuleMenuItem(char* module, HANDLE hContact);
+void copyModule(char* module, HANDLE hContactFrom, HANDLE hContactTo);
+
+// options.c
+int OptInit(WPARAM wParam,LPARAM lParam);
+
+// watchlist
+int addSettingToWatchList(HANDLE hContact, char* module, char* setting);
+void freeWatchListItem(int item);
+void PopulateWatchedWindow(HWND hwnd);
+void freeAllWatches();
+INT_PTR CALLBACK WatchDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+void popupWatchedVar(HANDLE hContact,const char* module,const char* setting);
+
+#endif //_COMMONHEADERS_H \ No newline at end of file
diff --git a/plugins/dbeditorpp/icons.cpp b/plugins/dbeditorpp/icons.cpp
new file mode 100644
index 0000000000..f6ac36e95e
--- /dev/null
+++ b/plugins/dbeditorpp/icons.cpp
@@ -0,0 +1,176 @@
+#include "headers.h"
+
+HIMAGELIST himl;
+
+void addIcons(TCHAR* szModuleFileName)
+{
+ SKINICONDESC sid={0};
+ char name[32];
+ sid.cbSize = sizeof(sid);
+ sid.ptszSection = _T(modFullname);
+ sid.ptszDefaultFile = szModuleFileName;
+ sid.flags = SIDF_ALL_TCHAR;
+
+ // closed known module
+ sid.ptszDescription = LPGENT("Closed Known Module");
+ mir_snprintf(name, SIZEOF(name), "DBE++_%d", ICO_KNOWN);
+ sid.pszName = name;
+ sid.iDefaultIndex = -ICO_KNOWN;
+ CallService(MS_SKIN2_ADDICON,0,(LPARAM)&sid);
+
+ // open known module
+ sid.ptszDescription = LPGENT("Open Known Module");
+ mir_snprintf(name, SIZEOF(name), "DBE++_%d", ICO_KNOWNOPEN);
+ sid.pszName = name;
+ sid.iDefaultIndex = -ICO_KNOWNOPEN;
+ CallService(MS_SKIN2_ADDICON,0,(LPARAM)&sid);
+
+ // closed unknown module
+ sid.ptszDescription = LPGENT("Closed Unknown Module");
+ mir_snprintf(name, SIZEOF(name), "DBE++_%d", ICO_UNKNOWN);
+ sid.pszName = name;
+ sid.iDefaultIndex = -ICO_UNKNOWN;
+ CallService(MS_SKIN2_ADDICON,0,(LPARAM)&sid);
+
+ // open unknown module
+ sid.ptszDescription = LPGENT("Open Unknown Module");
+ mir_snprintf(name, SIZEOF(name), "DBE++_%d", ICO_UNKNOWNOPEN);
+ sid.pszName = name;
+ sid.iDefaultIndex = -ICO_UNKNOWNOPEN;
+ CallService(MS_SKIN2_ADDICON,0,(LPARAM)&sid);
+
+ // settings contact
+ sid.ptszDescription = LPGENT("Settings");
+ mir_snprintf(name, SIZEOF(name), "DBE++_%d", ICO_SETTINGS);
+ sid.pszName = name;
+ sid.iDefaultIndex = -ICO_SETTINGS;
+ CallService(MS_SKIN2_ADDICON,0,(LPARAM)&sid);
+
+ // contact group
+ sid.ptszDescription = LPGENT("Contacts Group");
+ mir_snprintf(name, SIZEOF(name), "DBE++_%d", ICO_CONTACTS);
+ sid.pszName = name;
+ sid.iDefaultIndex = -ICO_CONTACTS;
+ CallService(MS_SKIN2_ADDICON,0,(LPARAM)&sid);
+
+ // unknwon contact
+ sid.ptszDescription = LPGENT("Unknown Contact");
+ mir_snprintf(name, SIZEOF(name), "DBE++_%d", ICO_OFFLINE);
+ sid.pszName = name;
+ sid.iDefaultIndex = -ICO_OFFLINE;
+ CallService(MS_SKIN2_ADDICON,0,(LPARAM)&sid);
+
+ // known contact
+ sid.ptszDescription = LPGENT("Known Contact");
+ mir_snprintf(name, SIZEOF(name), "DBE++_%d", ICO_ONLINE);
+ sid.pszName = name;
+ sid.iDefaultIndex = -ICO_ONLINE;
+ CallService(MS_SKIN2_ADDICON,0,(LPARAM)&sid);
+}
+
+HICON LoadSkinnedDBEIcon(int icon)
+{
+ HICON hIcon = 0;
+ if (UsingIconManager)
+ {
+ char name[32];
+ mir_snprintf(name, SIZEOF(name), "DBE++_%d", icon);
+
+ hIcon = (HICON)CallService(MS_SKIN2_GETICON,0,(LPARAM)name);
+ }
+ if (!hIcon)
+ return LoadIcon(hInst, MAKEINTRESOURCE(icon));
+ else
+ return hIcon;
+}
+
+
+int AddIconToList(HIMAGELIST hil, HICON hIcon)
+{
+
+ if (!hIcon || !hil) return 0;
+
+ ImageList_AddIcon(hil, hIcon);
+
+ return 1;
+
+}
+
+
+static PROTOCOLDESCRIPTOR **protocols = NULL;
+static int protoCount = 0;
+static int shift = 0;
+
+
+void AddProtoIconsToList(HIMAGELIST hil, int newshift)
+{
+ HICON hIcon;
+ int i;
+ shift = newshift;
+
+ CallService(MS_PROTO_ENUMPROTOCOLS,(WPARAM)&protoCount,(LPARAM)&protocols);
+
+ for(i = 0 ;i < protoCount; i++)
+ {
+ if (protocols[i]->type != PROTOTYPE_PROTOCOL)
+ continue;
+
+ if (hIcon=LoadSkinnedProtoIcon(protocols[i]->szName, ID_STATUS_ONLINE))
+ AddIconToList(hil, hIcon);
+ else
+ AddIconToList(himl, LoadSkinnedDBEIcon(ICO_ONLINE));
+ }
+}
+
+
+int GetProtoIcon(char *szProto)
+{
+ int result = DEF_ICON;
+ int i, n = 0;
+
+ if (!protoCount || !protocols || !szProto) return result;
+
+ for(i = 0 ;i < protoCount; i++)
+ {
+ if (protocols[i]->type != PROTOTYPE_PROTOCOL)
+ continue;
+
+ if (!mir_strcmp(protocols[i]->szName, szProto))
+ {
+ result = n + shift;
+ break;
+ }
+
+ n++;
+
+ }
+
+ return result;
+}
+
+
+BOOL IsProtocolLoaded(char* pszProtocolName)
+{
+/*
+ if (pszProtocolName && pszProtocolName[0])
+ {
+ int res = CallService(MS_PROTO_ISPROTOCOLLOADED, 0, (LPARAM)pszProtocolName);
+
+ if (res != CALLSERVICE_NOTFOUND && res)
+ return TRUE;
+ }
+*/
+ int i;
+
+ if (protoCount)
+ for(i = 0 ;i < protoCount; i++)
+ {
+ if (protocols[i]->type != PROTOTYPE_PROTOCOL)
+ continue;
+
+ if (!mir_strcmp(protocols[i]->szName, pszProtocolName))
+ return TRUE;
+ }
+
+ return FALSE;
+}
diff --git a/plugins/dbeditorpp/knownmodules.cpp b/plugins/dbeditorpp/knownmodules.cpp
new file mode 100644
index 0000000000..13c4379f6b
--- /dev/null
+++ b/plugins/dbeditorpp/knownmodules.cpp
@@ -0,0 +1,84 @@
+#include "headers.h"
+
+BYTE UseKnownModList;
+
+#define MAXMODS 1024
+char *KnownModules[MAXMODS];
+int KnownModulesCount = 0;
+
+INT_PTR RegisterModule(WPARAM wParam, LPARAM lParam)
+{
+ char **mods = (char**)wParam;
+ int count = lParam;
+ int i;
+ for (i=0;i<count && KnownModulesCount<MAXMODS;i++)
+ KnownModules[KnownModulesCount++] = mir_tstrdup(mods[i]);
+ return 0;
+}
+
+INT_PTR RegisterSingleModule(WPARAM wParam, LPARAM lParam)
+{
+ char *mods = (char*)wParam;
+ if (KnownModulesCount<MAXMODS)
+ KnownModules[KnownModulesCount++] = mir_tstrdup(mods);
+ return 0;
+}
+
+int IsModuleKnown(char *module)
+{
+ int i;
+
+ if (!UseKnownModList) return 1; // not using known list so all are "known"
+
+ for(i=0;i<KnownModulesCount;i++)
+ {
+ if (KnownModules[i] && !mir_strcmp(module,KnownModules[i]))
+ return 1;
+ }
+
+ return 0;
+}
+
+void FreeKnownModuleList()
+{
+ int i;
+ for(i=0;i<KnownModulesCount;i++)
+ {
+ mir_free(KnownModules[i]);
+ }
+}
+
+void doOldKnownModulesList()
+{
+ ModuleSettingLL msll;
+ struct ModSetLinkLinkItem *setting;
+ DBVARIANT dbv;
+ char *var, *temp;
+
+ if (!EnumSettings(NULL,"KnownModules", &msll)) return;
+
+ setting = msll.first;
+ while(setting)
+ {
+ if (!DBGetContactSetting(NULL,"KnownModules",setting->name,&dbv) && dbv.type == DBVT_ASCIIZ)
+ {
+ temp = (char*)mir_alloc((strlen(dbv.pszVal)+5)*sizeof(char));
+ if (!temp) break;
+ strcpy(temp,dbv.pszVal);
+ strcat(temp,",\0");
+ var = strtok(temp,", ");
+ while (var)
+ {
+ if (KnownModulesCount<MAXMODS)
+ KnownModules[KnownModulesCount++] = mir_tstrdup(var);
+ var = strtok(NULL,", ");
+ }
+ mir_free(temp);
+ }
+ DBFreeVariant(&dbv);
+ setting = (struct ModSetLinkLinkItem *)setting->next;
+ }
+ FreeModuleSettingLL(&msll);
+
+ UseKnownModList = DBGetContactSettingByte(NULL,modname,"UseKnownModList",0);
+}
diff --git a/plugins/dbeditorpp/main.cpp b/plugins/dbeditorpp/main.cpp
new file mode 100644
index 0000000000..f230d1e958
--- /dev/null
+++ b/plugins/dbeditorpp/main.cpp
@@ -0,0 +1,715 @@
+#include "headers.h"
+
+// {A8A417EF-07AA-4f37-869F-7BFD74886534}
+#define MIID_DBEDITOR {0xa8a417ef, 0x7aa, 0x4f37, { 0x86, 0x9f, 0x7b, 0xfd, 0x74, 0x88, 0x65, 0x34}}
+
+PLUGINLINK *pluginLink;
+HINSTANCE hInst = NULL;
+
+struct MM_INTERFACE mmi;
+struct UTF8_INTERFACE utfi;
+HANDLE hTTBButt = NULL;
+BOOL bServiceMode = FALSE;
+BOOL usePopUps;
+HWND hwnd2watchedVarsWindow;
+int UDB;
+int hLangpack;
+BYTE nameOrder[NAMEORDERCOUNT];
+HANDLE hUserMenu;
+HANDLE hRestore;
+WatchListArrayStruct WatchListArray;
+BYTE UsingIconManager;
+HANDLE sMenuCommand, sRegisterModule, sRegisterSingleModule, sImport, sServicemodeLaunch;
+HANDLE hModulesLoadedHook = NULL, hSettingsChangedHook=NULL, hOptInitHook=NULL, hPreShutdownHook=NULL, hTTBHook = NULL;
+
+//========================
+// MirandaPluginInfo
+//========================
+PLUGININFOEX pluginInfoEx={
+ sizeof(PLUGININFOEX),
+ __PLUGIN_NAME,
+ PLUGIN_MAKE_VERSION(__MAJOR_VERSION, __MINOR_VERSION, __RELEASE_NUM, __BUILD_NUM),
+ __DESCRIPTION,
+ __AUTHOR,
+ __AUTHOREMAIL,
+ __COPYRIGHT,
+ __AUTHORWEB,
+ UNICODE_AWARE,
+ 0,
+ MIID_DBEDITOR
+};
+
+extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion)
+{
+ if (mirandaVersion < PLUGIN_MAKE_VERSION(0, 7, 0, 0)) // 0.4 better. 0.3 have too many bugs
+ {
+ return NULL;
+ }
+ return &pluginInfoEx;
+}
+
+// we implement service mode interface
+static const MUUID interfaces[] = {MIID_SERVICEMODE, MIID_LAST};
+extern "C" __declspec(dllexport) const MUUID* MirandaPluginInterfaces(void)
+{
+ return interfaces;
+}
+
+//========================
+// WINAPI DllMain
+//========================
+BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)
+{
+ hInst=hinstDLL;
+ return TRUE;
+}
+
+void settingChanged(HWND hwnd2Settings, HANDLE hContact, char* module, char* setting);
+
+int DBSettingChanged(WPARAM wParam,LPARAM lParam)
+{
+ DBCONTACTWRITESETTING *cws=(DBCONTACTWRITESETTING*)lParam;
+ HANDLE hContact = (HANDLE)wParam;
+ char *setting;
+ int i;
+ SettingListInfo* info;
+
+ if (hwnd2mainWindow)
+ {
+ HWND hwnd2Settings = GetDlgItem(hwnd2mainWindow, IDC_SETTINGS);
+ if (info = (SettingListInfo*)GetWindowLongPtr(hwnd2Settings,GWLP_USERDATA))
+ {
+ if ((hContact == info->hContact) && !mir_strcmp(info->module, cws->szModule))
+ {
+ setting = mir_strdup(cws->szSetting);
+ if (cws->value.type == DBVT_DELETED)
+ {
+ LVFINDINFO lvfi;
+ int index;
+ lvfi.flags = LVFI_STRING;
+ lvfi.psz = setting;
+ lvfi.vkDirection = VK_DOWN;
+ index = ListView_FindItem(hwnd2Settings,-1,&lvfi);
+ if (index > -1)
+ ListView_DeleteItem(hwnd2Settings, index);
+ mir_free(setting);
+ return 0;
+ }
+ settingChanged(hwnd2Settings, hContact, info->module, setting);
+ mir_free(setting);
+ }
+ }
+ }
+ // watch list
+ if (!hwnd2watchedVarsWindow && !usePopUps) return 0;
+
+ for (i=0; i<WatchListArray.count; i++)
+ {
+ if (WatchListArray.item[i].module && (hContact == WatchListArray.item[i].hContact) )
+ {
+ if (!mir_strcmp(cws->szModule, WatchListArray.item[i].module))
+ {
+ if (!WatchListArray.item[i].setting || !mir_strcmp(cws->szSetting, WatchListArray.item[i].setting))
+ {
+ if (usePopUps)
+ popupWatchedVar(hContact, cws->szModule, cws->szSetting);
+ if (hwnd2watchedVarsWindow)
+ PopulateWatchedWindow(GetDlgItem(hwnd2watchedVarsWindow, IDC_VARS));
+ break;
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+INT_PTR DBEditorppMenuCommand(WPARAM wParam, LPARAM lParam)
+{
+
+ if (!hwnd2mainWindow) // so only opens 1 at a time
+ {
+ hRestore = (HANDLE)wParam;
+ SetCursor(LoadCursor(NULL,IDC_WAIT));
+ CreateDialog(hInst, MAKEINTRESOURCE(IDD_MAIN), 0, MainDlgProc);
+ }
+ else
+ {
+ ShowWindow(hwnd2mainWindow, SW_RESTORE);
+ SetForegroundWindow(hwnd2mainWindow);
+ if (!hRestore && wParam) {
+ hRestore = (HANDLE)wParam;
+ refreshTree(4);
+ }
+ }
+
+ if (hTTBButt)
+ CallService(MS_TTB_SETBUTTONSTATE, (WPARAM)hTTBButt, (LPARAM)(TTBST_RELEASED));
+
+ return 0;
+}
+
+BOOL IsCP_UTF8(void)
+{
+ CPINFO CPInfo;
+
+ return GetCPInfo(CP_UTF8, &CPInfo);
+}
+
+static int OnTTBLoaded(WPARAM wParam,LPARAM lParam)
+{
+ TTBButtonV2 ttbb = {0};
+ HICON ico = LoadIcon(hInst,MAKEINTRESOURCE(ICO_DBE_BUTT));
+ UnhookEvent(hTTBHook);
+
+ ttbb.cbSize = sizeof(ttbb);
+ ttbb.dwFlags=TTBBF_VISIBLE|TTBBF_SHOWTOOLTIP;
+ ttbb.pszServiceDown = "DBEditorpp/MenuCommand";
+ ttbb.name = Translate("Database Editor++");
+ ttbb.hIconUp = ico;
+ ttbb.hIconDn = ico;
+// ttbb.tooltipDn = Translate("Show DataBase Editor");
+
+ hTTBButt = (HANDLE)CallService(MS_TTB_ADDBUTTON, (WPARAM)&ttbb, 0);
+
+ if (hTTBButt)
+ CallService(MS_TTB_SETBUTTONOPTIONS,MAKEWPARAM(TTBO_TIPNAME,hTTBButt),
+ (LPARAM)(Translate("Show DataBase Editor")));
+
+ return 0;
+}
+
+int ModulesLoaded(WPARAM wParam,LPARAM lParam)
+{
+ DBVARIANT dbv;
+ char *coreMods = "";
+ char *mods;
+ char mod[64] = "";
+ TCHAR szModuleFileName[MAX_PATH];
+ int i=0, len;
+ if (!DBGetContactSetting(NULL,modname,"CoreModules",&dbv) && dbv.type == DBVT_ASCIIZ)
+ mods = dbv.pszVal;
+ else
+ {
+ DBWriteContactSettingString(NULL,modname,"CoreModules",coreMods);
+ mods = coreMods;
+ }
+
+ len = (int)strlen(mods);
+ while (i < len)
+ {
+ if (mods[i] == '\\' && mods[i+1] == ' ')
+ {
+ strcat(mod," ");
+ i++;
+ }
+ else if (mods[i] == ' ' || mods[i] == ',' || mods[i] == '\r' || mods[i] == '\n'|| mods[i] == '\0')
+ {
+ if (mod[0])
+ CallService("DBEditorpp/RegisterSingleModule",(WPARAM)mod,0);
+ mod[0] = '\0';
+ }
+ else strncat(mod,&mods[i],1);
+ i++;
+ }
+ if (mod[0]) CallService("DBEditorpp/RegisterSingleModule",(WPARAM)mod,0);
+
+ doOldKnownModulesList(); // add the old plugins which havnt been changed over yet..
+
+ // icons
+ if (GetModuleFileName(hInst, szModuleFileName, MAX_PATH) && ServiceExists(MS_SKIN2_ADDICON))
+ {
+ UsingIconManager =1;
+ addIcons(szModuleFileName);
+ }
+ else
+ UsingIconManager = 0;
+
+ DBFreeVariant(&dbv);
+ UnhookEvent(hModulesLoadedHook);
+
+ usePopUps = DBGetContactSettingByte(NULL,modname,"UsePopUps",0);
+
+ // Load the name order
+ for(i=0;i<NAMEORDERCOUNT;i++) nameOrder[i]=i;
+
+ if(!DBGetContactSetting(NULL,"Contact","NameOrder",&dbv))
+ {
+ CopyMemory(nameOrder,dbv.pbVal,dbv.cpbVal);
+ DBFreeVariant(&dbv);
+ }
+
+ // check DB engine for unicode support
+ UDB = FALSE;
+
+ if (ServiceExists(MS_DB_CONTACT_GETSETTING_STR))
+ {
+ DBCONTACTGETSETTING cgs;
+ dbv.type = 0;
+
+ if (DBGetContactSettingByte(NULL,modname,"WarnOnDelete",-1) == -1)
+ DBWriteContactSettingByte(NULL,modname,"WarnOnDelete",1);
+
+ cgs.szModule=modname;
+ cgs.szSetting="WarnOnDelete";
+ cgs.pValue=&dbv;
+
+ if (!CallService(MS_DB_CONTACT_GETSETTING_STR, 0,(LPARAM)&cgs))
+ if (dbv.type == DBVT_BYTE)
+ UDB = TRUE;
+
+ }
+
+ // check OS support for unicode
+ // useless if DB doesnt not support unicode
+ UOS = (UDB && IsCP_UTF8() && IsWinVerNT());
+
+ CallService(MS_UPDATE_REGISTERFL,2957,(LPARAM)&pluginInfoEx);
+
+ hTTBHook = HookEvent(ME_TTB_MODULELOADED, OnTTBLoaded);
+
+ if ( bServiceMode ) {
+ CallService("DBEditorpp/MenuCommand",0,0);
+ }
+
+ return 0;
+}
+
+int PreShutdown(WPARAM wParam,LPARAM lParam)
+{
+ if (hwnd2watchedVarsWindow) DestroyWindow(hwnd2watchedVarsWindow);
+ if (hwnd2mainWindow) DestroyWindow(hwnd2mainWindow);
+ if (hwnd2importWindow) DestroyWindow(hwnd2importWindow);
+
+ UnhookEvent(hSettingsChangedHook);
+ UnhookEvent(hOptInitHook);
+ UnhookEvent(hPreShutdownHook);
+
+ DestroyServiceFunction(sServicemodeLaunch);
+ DestroyServiceFunction(sMenuCommand);
+ DestroyServiceFunction(sRegisterModule);
+ DestroyServiceFunction(sRegisterSingleModule);
+ DestroyServiceFunction(sImport);
+
+ return 0;
+}
+
+INT_PTR ServiceMode(WPARAM wParam,LPARAM lParam) {
+ bServiceMode = TRUE;
+ return 0;
+}
+
+INT_PTR ImportFromFile(WPARAM wParam,LPARAM lParam)
+{
+ ImportSettingsFromFileMenuItem((HANDLE)wParam, (char*)lParam);
+ return 0;
+}
+
+extern "C" __declspec(dllexport) int Load(PLUGINLINK *link)
+{
+ CLISTMENUITEM mi;
+/*
+ #ifndef NDEBUG //mem leak detector :-) Thanks Tornado!
+ int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); // Get current flag
+ flag |= _CRTDBG_LEAK_CHECK_DF; // Turn on leak-checking bit
+ _CrtSetDbgFlag(flag); // Set flag to the new value
+ #endif
+*/
+ pluginLink = link;
+ mir_getMMI(&mmi);
+ mir_getUTFI( &utfi );
+ mir_getLP(&pluginInfoEx);
+
+ hwnd2mainWindow = 0;
+ hwnd2watchedVarsWindow = 0;
+ hwnd2importWindow = 0;
+ hRestore = NULL;
+ hSettingsChangedHook = HookEvent(ME_DB_CONTACT_SETTINGCHANGED,DBSettingChanged);
+ hOptInitHook = HookEvent(ME_OPT_INITIALISE,OptInit);
+ hPreShutdownHook = HookEvent(ME_SYSTEM_PRESHUTDOWN, PreShutdown);
+ hModulesLoadedHook = HookEvent(ME_SYSTEM_MODULESLOADED,ModulesLoaded);
+ sMenuCommand = CreateServiceFunction("DBEditorpp/MenuCommand", DBEditorppMenuCommand);
+ sRegisterModule = CreateServiceFunction("DBEditorpp/RegisterModule", RegisterModule);
+ sRegisterSingleModule = CreateServiceFunction("DBEditorpp/RegisterSingleModule", RegisterSingleModule);
+ sImport = CreateServiceFunction("DBEditorpp/Import", ImportFromFile);
+ ZeroMemory(&mi, sizeof(mi));
+ mi.cbSize = sizeof(mi);
+ mi.position = 1900000001;
+ mi.flags = CMIF_TCHAR;
+ mi.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(ICO_REGEDIT));
+ mi.ptszName = _T(modFullname);
+ mi.pszService = "DBEditorpp/MenuCommand";
+ mi.pszContactOwner = NULL;
+ CallService(MS_CLIST_ADDMAINMENUITEM, 0, (LPARAM)&mi);
+
+ ZeroMemory(&mi, sizeof(mi));
+ mi.cbSize = sizeof(mi);
+ mi.position = 1900000001;
+ mi.flags = DBGetContactSettingByte(NULL,modname,"UserMenuItem",0)?0:CMIF_HIDDEN;
+ mi.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(ICO_REGUSER));
+ mi.ptszName = LPGENT("Open user tree in DBE++");
+ mi.pszService = "DBEditorpp/MenuCommand";
+ mi.pszContactOwner = NULL;
+ hUserMenu = (HANDLE)CallService(MS_CLIST_ADDCONTACTMENUITEM, 0, (LPARAM) & mi);
+
+ sServicemodeLaunch = CreateServiceFunction(MS_SERVICEMODE_LAUNCH, ServiceMode);
+
+ CallService("DBEditorpp/RegisterSingleModule",(WPARAM)modname,0);
+
+ // Ensure that the common control DLL is loaded.
+ {
+ INITCOMMONCONTROLSEX icex;
+
+ icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
+ icex.dwICC = ICC_LISTVIEW_CLASSES;
+ InitCommonControlsEx(&icex);
+ }
+
+ ZeroMemory(&WatchListArray, sizeof(WatchListArray));
+
+ if(ServiceExists(MS_HOTKEY_REGISTER))
+ {
+ HOTKEYDESC hkd = {0};
+ hkd.cbSize = sizeof(hkd);
+ hkd.dwFlags = HKD_TCHAR;
+ hkd.pszName = "hk_dbepp_open";
+ hkd.pszService = "DBEditorpp/MenuCommand";
+ hkd.ptszDescription = LPGENT("Open Database Editor");
+ hkd.ptszSection = _T(modFullname);
+ hkd.DefHotKey = HOTKEYCODE(HOTKEYF_SHIFT|HOTKEYF_EXT, 'D');
+
+ CallService(MS_HOTKEY_REGISTER,0,(LPARAM)&hkd);
+ }
+
+ return 0;
+}
+
+extern "C" __declspec(dllexport) int Unload(void)
+{
+ FreeKnownModuleList();
+ freeAllWatches();
+ return 0;
+}
+
+
+
+//=======================================================
+//DBGetContactSettingString (prob shouldnt use this unless u know how big the string is gonna be..)
+//=======================================================
+
+int DBGetContactSettingStringStatic(HANDLE hContact, char* szModule, char* szSetting, char* value, int maxLength)
+{
+ DBVARIANT dbv;
+ if (!DBGetContactSetting(hContact, szModule, szSetting, &dbv))
+ {
+ strncpy(value, dbv.pszVal, maxLength);
+ DBFreeVariant(&dbv);
+ return 1;
+ }
+ else
+ {
+ DBFreeVariant(&dbv);
+ return 0;
+ }
+
+ return 0;
+}
+
+int WriteBlobFromString(HANDLE hContact,const char *szModule,const char *szSetting, const char *szValue, int len)
+{
+ int j=0, i = 0;
+ BYTE *data = NULL;
+ BYTE b;
+ int tmp;
+
+ if (!(data = (BYTE *)_alloca(2+len/2)))
+ {
+ msg(Translate("Couldnt allocate enough memory!"), modFullname);
+ return 0;
+ }
+
+ while(j<len)
+ {
+ b = szValue[j];
+
+ if ((b>='0' && b<='9') ||
+ (b>='A' && b<='F') ||
+ (b>='a' && b<='f'))
+ {
+ if (sscanf(&szValue[j], "%02X", &tmp) == 1)
+ {
+ data[i++] = (BYTE)tmp;
+ j++;
+ }
+ }
+ j++;
+ }
+
+ if (i)
+ return DBWriteContactSettingBlob(hContact,szModule,szSetting, data, (WORD)i);
+
+ return 0;
+}
+
+
+int GetSetting(HANDLE hContact, const char *szModule, const char *szSetting, DBVARIANT *dbv)
+{
+ DBCONTACTGETSETTING cgs;
+
+ cgs.szModule=szModule;
+ cgs.szSetting=szSetting;
+ cgs.pValue=dbv;
+ dbv->type = 0;
+
+ if (UDB)
+ return CallService(MS_DB_CONTACT_GETSETTING_STR,(WPARAM)hContact,(LPARAM)&cgs);
+ else
+ {
+ int rr = CallService(MS_DB_CONTACT_GETSETTING,(WPARAM)hContact,(LPARAM)&cgs);
+
+ if (dbv->type != DBVT_UTF8)
+ return rr;
+ else
+ return 1;
+ }
+}
+
+
+int GetValue(HANDLE hContact, const char* szModule, const char* szSetting, char* Value, int length)
+{
+ DBVARIANT dbv = {0};
+
+ if (Value && length >= 10 && !GetSetting(hContact, szModule, szSetting, &dbv))
+ {
+ switch(dbv.type) {
+ case DBVT_UTF8:
+ if (UOS)
+ {
+ int len = (int)strlen(dbv.pszVal)+1;
+ char *sz = (char*)_alloca(len*3);
+ WCHAR *wc = (WCHAR*)_alloca(len*sizeof(WCHAR));
+ MultiByteToWideChar(CP_UTF8, 0, dbv.pszVal, -1, wc, len);
+ WideCharToMultiByte(CP_ACP, 0, wc, -1, sz, len, NULL, NULL);
+ strncpy(Value, sz, length);
+ break;
+ }// else fall through
+ case DBVT_ASCIIZ:
+ strncpy(Value, dbv.pszVal, length);
+ break;
+ case DBVT_DWORD:
+ _itoa(dbv.dVal,Value,10);
+ break;
+ case DBVT_BYTE:
+ _itoa(dbv.bVal,Value,10);
+ break;
+ case DBVT_WORD:
+ _itoa(dbv.wVal,Value,10);
+ break;
+ }
+
+ DBFreeVariant(&dbv);
+
+ Value[length-1] = 0;
+ return 1;
+ }
+
+ if (Value)
+ Value[0] = 0;
+
+ return 0;
+}
+
+
+int GetValueW(HANDLE hContact, const char* szModule, const char* szSetting, WCHAR* Value, int length)
+{
+ DBVARIANT dbv ={0};
+
+ if (Value && length >= 10 && !GetSetting(hContact, szModule, szSetting, &dbv))
+ {
+ switch(dbv.type) {
+ case DBVT_UTF8:
+ {
+ int len = (int)strlen(dbv.pszVal) + 1;
+ WCHAR *wc = (WCHAR*)_alloca(length*sizeof(WCHAR));
+ MultiByteToWideChar(CP_UTF8, 0, dbv.pszVal, -1, wc, len);
+ wcsncpy((WCHAR*)Value, wc, length);
+ }
+ break;
+ case DBVT_ASCIIZ:
+ {
+ int len = (int)strlen(dbv.pszVal) + 1;
+ WCHAR *wc = (WCHAR*)_alloca(len*sizeof(WCHAR));
+ MultiByteToWideChar(CP_ACP, 0, dbv.pszVal, -1, wc, len);
+ wcsncpy((WCHAR*)Value, wc, length);
+ }
+ break;
+ case DBVT_DWORD:
+ _itow(dbv.dVal,Value,10);
+ break;
+ case DBVT_BYTE:
+ _itow(dbv.bVal,Value,10);
+ break;
+ case DBVT_WORD:
+ _itow(dbv.wVal,Value,10);
+ break;
+ }
+
+ DBFreeVariant(&dbv);
+
+ Value[length-1] = 0;
+ return 1;
+ }
+
+ if (Value)
+ Value[0] = 0;
+
+ return 0;
+}
+
+
+char *u2a( wchar_t* src )
+{
+ if (src)
+ {
+ int cbLen = WideCharToMultiByte( CP_ACP, 0, src, -1, NULL, 0, NULL, NULL );
+ char* result = (char*)mir_calloc((cbLen+1)*sizeof(char));
+ if ( result == NULL )
+ return NULL;
+
+ WideCharToMultiByte( CP_ACP, 0, src, -1, result, cbLen, NULL, NULL );
+ result[ cbLen ] = 0;
+ return result;
+ }
+ else
+ return NULL;
+}
+
+
+wchar_t *a2u( char* src , wchar_t *buffer, int len )
+{
+ wchar_t *result = buffer;
+ if ( result == NULL || len < 3)
+ return NULL;
+
+ MultiByteToWideChar( CP_ACP, 0, src, -1, result, len - 1 );
+ result[ len - 1 ] = 0;
+
+ return result;
+}
+
+int mir_snwprintf(WCHAR *buffer, size_t count, const WCHAR* fmt, ...)
+{
+ va_list va;
+ int len;
+
+ va_start(va, fmt);
+ len = _vsnwprintf(buffer, count-1, fmt, va);
+ va_end(va);
+
+ buffer[count-1] = 0;
+
+ return len;
+}
+
+
+int GetDatabaseString(HANDLE hContact, const char *szModule, const char* szSetting, WCHAR *Value, int length, BOOL unicode)
+{
+ if (unicode)
+ return GetValueW(hContact, szModule, szSetting, Value, length);
+ else
+ return GetValue(hContact, szModule, szSetting, (char*)Value, length);
+}
+
+
+WCHAR *GetContactName(HANDLE hContact, const char *szProto, int unicode)
+{
+
+ int i, r = 0;
+ static WCHAR res[512];
+ char *proto = (char*)szProto;
+ char name[256];
+
+ if (hContact && !proto)
+ {
+ if (GetValue(hContact,"Protocol","p",name,SIZEOF(name)))
+ proto = name;
+ }
+
+ if (proto)
+ {
+
+ for(i=0;i<NAMEORDERCOUNT-1;i++)
+ {
+ switch(nameOrder[i]) {
+ case 0: // custom name
+ {
+ r = GetDatabaseString(hContact,"CList","MyHandle",res,SIZEOF(res),unicode);
+ break;
+ }
+ case 1: // nick
+ {
+ r = GetDatabaseString(hContact,proto,"Nick",res,SIZEOF(res),unicode);
+ break;
+ }
+ case 2: // First Name
+ {
+ r = GetDatabaseString(hContact,proto,"FirstName",res,SIZEOF(res),unicode);
+ break;
+ }
+ case 3: // E-mail
+ {
+ r = GetDatabaseString(hContact,proto,"e-mail",res,SIZEOF(res),unicode);
+ break;
+ }
+ case 4: // Last Name
+ {
+ if (GetDatabaseString(hContact,proto,"LastName",res,SIZEOF(res),unicode))
+ break;
+ }
+ case 5: // Unique id
+ {
+ // protocol must define a PFLAG_UNIQUEIDSETTING
+ char *uid = (char*)CallProtoService(proto,PS_GETCAPS,PFLAG_UNIQUEIDSETTING,0);
+ if ((int)uid!=CALLSERVICE_NOTFOUND && uid)
+ r = GetDatabaseString(hContact,proto,uid,res,SIZEOF(res),unicode);
+ break;
+ }
+ case 6: // first + last name
+ {
+ int len = 0;
+
+ if (r = GetDatabaseString(hContact,proto,"FirstName",res,SIZEOF(res),unicode))
+ {
+ if (unicode)
+ len = (int)wcslen(res);
+ else
+ len = (int)strlen((char*)res);
+ }
+ else
+ res[0] = 0;
+
+ if (len && len < SIZEOF(res) - 2)
+ {
+ if (unicode)
+ wcscat(res,L" ");
+ else
+ strcat((char*)res," ");
+
+ len++;
+ }
+
+ if (SIZEOF(res)-len > 1)
+ r |= GetDatabaseString(hContact,proto,"LastName",&res[len],SIZEOF(res)-len,unicode);
+
+ break;
+ }
+ }
+
+ if (r) return res;
+ }
+ }
+
+ if (unicode)
+ return nick_unknownW;
+ else
+ return (WCHAR*)nick_unknown;
+}
diff --git a/plugins/dbeditorpp/main_window.cpp b/plugins/dbeditorpp/main_window.cpp
new file mode 100644
index 0000000000..da58799e1c
--- /dev/null
+++ b/plugins/dbeditorpp/main_window.cpp
@@ -0,0 +1,665 @@
+#include "headers.h"
+
+HWND hwnd2mainWindow;
+int Order;
+HIMAGELIST himl2;
+int Hex;
+
+#define GC_SPLITTERMOVED (WM_USER+101)
+
+extern BOOL bServiceMode;
+
+static WNDPROC SettingListSubClass, ModuleTreeSubClass, SplitterSubClass;
+
+void moduleListWM_NOTIFY(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam);
+void SettingsListWM_NOTIFY(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam);
+
+int DialogResize(HWND hwnd,LPARAM lParam,UTILRESIZECONTROL *urc)
+{
+ switch(urc->wId)
+ {
+ case IDC_MODULES:
+ urc->rcItem.right = lParam-3;
+ urc->rcItem.top = 0;
+ urc->rcItem.left = 0;
+ urc->rcItem.bottom = urc->dlgNewSize.cy;
+ return RD_ANCHORX_CUSTOM|RD_ANCHORY_CUSTOM;
+ case IDC_SPLITTER:
+ urc->rcItem.top = 0;
+ urc->rcItem.bottom = urc->dlgNewSize.cy;
+ urc->rcItem.right = lParam;
+ urc->rcItem.left = lParam-3;
+ return RD_ANCHORX_CUSTOM|RD_ANCHORY_CUSTOM;
+ case IDC_SETTINGS:
+ urc->rcItem.top = 0;
+ urc->rcItem.bottom = urc->dlgNewSize.cy;
+ urc->rcItem.left = lParam;
+ urc->rcItem.right = urc->dlgNewSize.cx;
+ return RD_ANCHORX_CUSTOM|RD_ANCHORY_CUSTOM;
+ case IDC_VARS:
+ urc->rcItem.top = 0;
+ urc->rcItem.bottom = urc->dlgNewSize.cy;
+ urc->rcItem.left = 0;
+ urc->rcItem.right = urc->dlgNewSize.cx;
+ return RD_ANCHORY_CUSTOM|RD_ANCHORX_CUSTOM;
+ }
+ return RD_ANCHORX_LEFT|RD_ANCHORY_TOP;
+
+}
+
+static LRESULT CALLBACK SplitterSubclassProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
+{
+ switch(msg) {
+ case WM_NCHITTEST:
+ return HTCLIENT;
+ case WM_SETCURSOR:
+ { RECT rc;
+ GetClientRect(hwnd,&rc);
+ SetCursor(rc.right>rc.bottom?LoadCursor(NULL, IDC_SIZENS):LoadCursor(NULL, IDC_SIZEWE));
+ return TRUE;
+ }
+ case WM_LBUTTONDOWN:
+ SetCapture(hwnd);
+ return 0;
+ case WM_MOUSEMOVE:
+ if(GetCapture()==hwnd) {
+ RECT rc;
+ GetClientRect(hwnd,&rc);
+ SendMessage(GetParent(hwnd),GC_SPLITTERMOVED,rc.right>rc.bottom?(short)HIWORD(GetMessagePos())+rc.bottom/2:(short)LOWORD(GetMessagePos())+rc.right/2,(LPARAM)hwnd);
+ }
+ return 0;
+ case WM_LBUTTONUP:
+ ReleaseCapture();
+ return 0;
+ }
+ return CallWindowProc(SplitterSubClass,hwnd,msg,wParam,lParam);
+}
+LRESULT CALLBACK ModuleTreeSubclassProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
+{
+ switch(msg) {
+ case WM_RBUTTONDOWN:
+ {
+ TVHITTESTINFO hti;
+ hti.pt.x=(short)LOWORD(GetMessagePos());
+ hti.pt.y=(short)HIWORD(GetMessagePos());
+ ScreenToClient(hwnd,&hti.pt);
+
+ if(TreeView_HitTest(hwnd,&hti))
+ {
+ if(hti.flags&TVHT_ONITEM)
+ TreeView_SelectItem(hwnd, hti.hItem);
+ }
+ }
+ break;
+ case WM_CHAR:
+ if (GetKeyState(VK_CONTROL)&0x8000 && wParam == 6)
+ CreateDialog(hInst, MAKEINTRESOURCE(IDD_FIND), hwnd, FindWindowDlgProc);
+ break;
+ case WM_KEYUP:
+ {
+ if (wParam == VK_DELETE ||
+ wParam == VK_F2 ||
+ //wParam == VK_UP ||
+ //wParam == VK_DOWN ||
+ wParam == VK_F5 ||
+ wParam == VK_F3)
+
+ {
+ TVITEM tvi;
+ char module[256];
+ tvi.mask=TVIF_HANDLE|TVIF_PARAM|TVIF_TEXT;
+ tvi.hItem=TreeView_GetSelection(hwnd);
+ tvi.pszText = module;
+ tvi.cchTextMax = 255;
+ if (TreeView_GetItem(hwnd,&tvi) && tvi.lParam)
+ {
+ ModuleTreeInfoStruct *mtis = (ModuleTreeInfoStruct*)tvi.lParam;
+ HANDLE hContact = mtis->hContact;
+ if (wParam == VK_DELETE)
+ {
+ if ((mtis->type) & MODULE)
+ {
+ if (deleteModule(module, hContact,0))
+ {
+ mir_free(mtis);
+ TreeView_DeleteItem(hwnd,tvi.hItem);
+ }
+ }
+ else if ((mtis->type == CONTACT) && hContact)
+ {
+ char msg[1024];
+ mir_snprintf(msg, SIZEOF(msg), Translate("Are you sure you want to delete contact \"%s\"?"), module);
+ if (DBGetContactSettingByte(NULL,"CList", "ConfirmDelete",1))
+ {
+ if (MessageBox(0,msg, Translate("Confirm Contact Delete"), MB_YESNO|MB_ICONEXCLAMATION) == IDNO)
+ break;
+ }
+ CallService(MS_DB_CONTACT_DELETE, (WPARAM)hContact,0);
+ freeTree(hwnd,mtis->hContact);
+ TreeView_DeleteItem(hwnd,tvi.hItem);
+ }
+ }
+ else if (wParam == VK_F2 && (mtis->type == MODULE || mtis->type == UNKNOWN_MODULE))
+ TreeView_EditLabel(hwnd,tvi.hItem);
+ else if (wParam == VK_F5)
+ {
+ refreshTree(1);
+ break;
+ }
+
+ else if (wParam == VK_F3)
+ {
+ CreateDialog(hInst, MAKEINTRESOURCE(IDD_FIND), hwnd, FindWindowDlgProc);
+ break;
+ }
+ }
+ }
+ }
+ break;
+ default:break;
+ }
+ return CallWindowProc(ModuleTreeSubClass,hwnd,msg,wParam,lParam);
+}
+static LRESULT CALLBACK SettingListSubclassProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
+{
+ switch(msg) {
+ case WM_CHAR:
+ if (GetKeyState(VK_CONTROL)&0x8000 && wParam == 6)
+ CreateDialog(hInst, MAKEINTRESOURCE(IDD_FIND), hwnd, FindWindowDlgProc);
+ break;
+ case WM_KEYDOWN:
+ if (wParam == VK_DELETE || wParam == VK_F5 || (wParam == VK_F2 && ListView_GetSelectedCount(hwnd) == 1))
+ {
+ char *module, setting[256];
+ HANDLE hContact;
+ SettingListInfo* sli = (SettingListInfo*)GetWindowLongPtr(hwnd,GWLP_USERDATA);
+ if (!sli) break;
+ hContact = sli->hContact;
+ module = sli->module;
+ ListView_GetItemText(hwnd, ListView_GetSelectionMark(hwnd), 0, setting, 256);
+
+ if (wParam == VK_F2)
+ editSetting(hContact,module, setting);
+ else if (wParam == VK_F5)
+ {
+ char *szModule = mir_tstrdup(module); // need to do this, otheriwse the setlist stays empty
+ PopulateSettings(hwnd,hContact,szModule);
+ mir_free(szModule);
+ }
+ else if (wParam == VK_DELETE)
+ DeleteSettingsFromList(hwnd, hContact, module, setting);
+
+ return 0;
+ }
+ else if (wParam == VK_F3)
+ CreateDialog(hInst, MAKEINTRESOURCE(IDD_FIND), hwnd, FindWindowDlgProc);
+ break;
+
+ default: break;
+ }
+ return CallWindowProc(SettingListSubClass,hwnd,msg,wParam,lParam);
+}
+
+INT_PTR CALLBACK MainDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch(msg)
+ {
+ case WM_INITDIALOG:
+ {
+ int i;
+ HMENU hMenu = GetMenu(hwnd);
+
+ hwnd2mainWindow = hwnd;
+ // do the icon
+ SendMessage(hwnd,WM_SETICON,ICON_BIG,(LPARAM)LoadIcon(hInst,MAKEINTRESOURCE(ICO_REGEDIT)));
+ if (UOS)
+ SetWindowText(hwnd, Translate("Database Editor++ (unicode mode)"));
+ else
+ SetWindowText(hwnd, Translate("Database Editor++ (ansi mode)"));
+ // setup the splitter
+ SetWindowLongPtr(GetDlgItem(hwnd,IDC_SPLITTER),GWLP_USERDATA,(LPARAM)DBGetContactSettingWord(NULL, modname, "Splitter", 300));
+ SendMessage(hwnd, GC_SPLITTERMOVED, 0,0);
+ SplitterSubClass=(WNDPROC)SetWindowLongPtr(GetDlgItem(hwnd,IDC_SPLITTER),GWLP_WNDPROC,(LONG)SplitterSubclassProc);
+ // module tree
+ TreeView_SetUnicodeFormat(GetDlgItem(hwnd,IDC_MODULES), UOS);
+ ModuleTreeSubClass=(WNDPROC)SetWindowLongPtr(GetDlgItem(hwnd,IDC_MODULES),GWLP_WNDPROC,(LONG)ModuleTreeSubclassProc);
+ //setting list
+ setupSettingsList(GetDlgItem(hwnd,IDC_SETTINGS));
+ SettingListSubClass=(WNDPROC)SetWindowLongPtr(GetDlgItem(hwnd,IDC_SETTINGS),GWLP_WNDPROC,(LONG)SettingListSubclassProc);
+ // traslation stuff
+ TranslateDialogDefault(hwnd);
+ CallService(MS_LANGPACK_TRANSLATEMENU,(WPARAM)hMenu,0);
+
+ for (i=0;i<6;i++)
+ {
+ CallService(MS_LANGPACK_TRANSLATEMENU,(WPARAM)GetSubMenu(hMenu,i),0);
+ }
+
+ // move the dialog to the users position
+ MoveWindow(hwnd,DBGetContactSettingDword(NULL,modname,"x",0),DBGetContactSettingDword(NULL,modname,"y",0),DBGetContactSettingDword(NULL,modname,"width",500),DBGetContactSettingDword(NULL,modname,"height",250),0);
+ if (DBGetContactSettingByte(NULL,modname,"Maximised",0))
+ {
+ WINDOWPLACEMENT wp;
+ wp.length = sizeof(WINDOWPLACEMENT);
+ wp.flags = WPF_RESTORETOMAXIMIZED;
+ wp.showCmd = SW_SHOWMAXIMIZED;
+
+ SetWindowPlacement(hwnd,&wp);
+ }
+ SetCursor(LoadCursor(NULL,IDC_ARROW));
+
+ Mode = MODE_ALL;
+ CheckMenuItem(GetSubMenu(hMenu,5),MENU_FILTER_ALL,MF_BYCOMMAND|MF_CHECKED);
+
+ Hex = DBGetContactSettingByte(NULL,modname,"HexMode",0);
+ CheckMenuItem(GetSubMenu(hMenu,5),MENU_BYTE_HEX,MF_BYCOMMAND|((Hex & HEX_BYTE)?MF_CHECKED:MF_UNCHECKED));
+ CheckMenuItem(GetSubMenu(hMenu,5),MENU_WORD_HEX,MF_BYCOMMAND|((Hex & HEX_WORD)?MF_CHECKED:MF_UNCHECKED));
+ CheckMenuItem(GetSubMenu(hMenu,5),MENU_DWORD_HEX,MF_BYCOMMAND|((Hex & HEX_DWORD)?MF_CHECKED:MF_UNCHECKED));
+
+ CheckMenuItem(GetSubMenu(GetMenu(hwnd),5),MENU_SAVE_POSITION,MF_BYCOMMAND|(DBGetContactSettingByte(NULL,modname,"RestoreOnOpen",1)?MF_CHECKED:MF_UNCHECKED));
+
+ Order = DBGetContactSettingByte(NULL,modname,"SortMode",1);
+ CheckMenuItem(GetSubMenu(GetMenu(hwnd),5),MENU_SORT_ORDER,MF_BYCOMMAND|(Order?MF_CHECKED:MF_UNCHECKED));
+
+
+
+ // image list
+ {
+ int numberOfIcons = 0;
+ himl = NULL;
+
+ if (himl = ImageList_Create(16, 16, IsWinVerXPPlus() ? ILC_COLOR32 | ILC_MASK : ILC_COLOR8 | ILC_MASK, 10, 0))
+ {
+ if (AddIconToList(himl, LoadSkinnedDBEIcon(ICO_SETTINGS)))
+ numberOfIcons++;
+ if (AddIconToList(himl, LoadSkinnedDBEIcon(ICO_KNOWN)))
+ numberOfIcons++;
+ if (AddIconToList(himl, LoadSkinnedDBEIcon(ICO_KNOWNOPEN)))
+ numberOfIcons++;
+ if (AddIconToList(himl, LoadSkinnedDBEIcon(ICO_CONTACTS)))
+ numberOfIcons++;
+ if (AddIconToList(himl, LoadSkinnedDBEIcon(ICO_OFFLINE)))
+ numberOfIcons++;
+ if (AddIconToList(himl, LoadSkinnedDBEIcon(ICO_UNKNOWN)))
+ numberOfIcons++;
+ if (AddIconToList(himl, LoadSkinnedDBEIcon(ICO_UNKNOWNOPEN)))
+ numberOfIcons++;
+ if (AddIconToList(himl, LoadSkinnedDBEIcon(ICO_ONLINE)))
+ numberOfIcons++;
+
+ if (numberOfIcons < DEF_ICON + 1)
+ {
+ if (numberOfIcons)
+ ImageList_Destroy(himl);
+ himl = NULL;
+ }
+
+ AddProtoIconsToList(himl, numberOfIcons);
+
+ }
+
+ himl2 = NULL;
+ numberOfIcons = 0;
+
+ if (himl2 = ImageList_Create(16, 16, IsWinVerXPPlus() ? ILC_COLOR32 | ILC_MASK : ILC_COLOR8 | ILC_MASK, 5, 0))
+ {
+
+ if (AddIconToList(himl2, LoadIcon(hInst, MAKEINTRESOURCE(ICO_BINARY))))
+ numberOfIcons++;
+ if (AddIconToList(himl2, LoadIcon(hInst, MAKEINTRESOURCE(ICO_BYTE))))
+ numberOfIcons++;
+ if (AddIconToList(himl2, LoadIcon(hInst, MAKEINTRESOURCE(ICO_WORD))))
+ numberOfIcons++;
+ if (AddIconToList(himl2, LoadIcon(hInst, MAKEINTRESOURCE(ICO_DWORD))))
+ numberOfIcons++;
+ if (AddIconToList(himl2, LoadIcon(hInst, MAKEINTRESOURCE(ICO_STRING))))
+ numberOfIcons++;
+ if (AddIconToList(himl2, LoadIcon(hInst, MAKEINTRESOURCE(ICO_UNICODE))))
+ numberOfIcons++;
+ if (AddIconToList(himl2, LoadIcon(hInst, MAKEINTRESOURCE(ICO_HANDLE))))
+ numberOfIcons++;
+
+ if (numberOfIcons < 7)
+ {
+ if (numberOfIcons)
+ ImageList_Destroy(himl2);
+ himl2 = NULL;
+ }
+ }
+ }
+
+ {
+ int restore;
+
+ if (hRestore)
+ restore = 3;
+ else
+ if (DBGetContactSettingByte(NULL,modname,"RestoreOnOpen",1))
+ restore = 2;
+ else
+ restore = 0;
+
+ refreshTree(restore);
+ }
+
+ }
+ return TRUE;
+ case GC_SPLITTERMOVED:
+ {
+ POINT pt;
+ RECT rc;
+ RECT rc2;
+
+ int splitterPos = GetWindowLongPtr(GetDlgItem(hwnd,IDC_SPLITTER),GWLP_USERDATA);
+
+ GetWindowRect(hwnd,&rc2);
+
+ if((HWND)lParam==GetDlgItem(hwnd,IDC_SPLITTER))
+ {
+ GetClientRect(hwnd,&rc);
+ pt.x=wParam; pt.y=0;
+ ScreenToClient(hwnd,&pt);
+
+ splitterPos=rc.left+pt.x+1;
+ if (splitterPos<65) splitterPos=65;
+ if (splitterPos > rc2.right-rc2.left-65) splitterPos=rc2.right-rc2.left-65;
+ SetWindowLongPtr(GetDlgItem(hwnd,IDC_SPLITTER),GWLP_USERDATA, splitterPos);
+ DBWriteContactSettingWord(NULL, modname, "Splitter",(WORD)splitterPos);
+ }
+ PostMessage(hwnd,WM_SIZE,0,0);
+ }
+ break;
+ case WM_GETMINMAXINFO:
+ {
+ MINMAXINFO *mmi=(MINMAXINFO*)lParam;
+ int splitterPos = GetWindowLongPtr(GetDlgItem(hwnd,IDC_SPLITTER),GWLP_USERDATA);
+
+ if(splitterPos+40 > 200)
+ mmi->ptMinTrackSize.x=splitterPos+65;
+ else
+ mmi->ptMinTrackSize.x=200;
+ mmi->ptMinTrackSize.y=150;
+ return 0;
+ }
+ case WM_MOVE:
+ case WM_SIZE:
+ {
+ UTILRESIZEDIALOG urd;
+
+ ZeroMemory(&urd,sizeof(urd));
+ urd.cbSize=sizeof(urd);
+ urd.hInstance=hInst;
+ urd.hwndDlg=hwnd;
+ urd.lParam=(LPARAM)GetWindowLongPtr(GetDlgItem(hwnd,IDC_SPLITTER),GWLP_USERDATA);
+ urd.lpTemplate=MAKEINTRESOURCE(IDD_MAIN);
+ urd.pfnResizer=DialogResize;
+ CallService(MS_UTILS_RESIZEDIALOG,0,(LPARAM)&urd);
+
+ if (msg == WM_SIZE && wParam == SIZE_MAXIMIZED || wParam == SIZE_MINIMIZED)
+ {
+ DBWriteContactSettingByte(NULL,modname,"Maximised",1);
+ }
+ else if (msg == WM_SIZE && wParam == SIZE_RESTORED)
+ {
+ DBWriteContactSettingByte(NULL,modname,"Maximised",0);
+ }
+
+ }
+ break;
+ case WM_DESTROY: // free our shit!
+
+ if (DBGetContactSettingByte(NULL,modname,"RestoreOnOpen",1))
+ {
+ HTREEITEM item;
+ HWND hwnd2Tree = GetDlgItem(hwnd,IDC_MODULES);
+ char module[256] = {0};
+ if (item = TreeView_GetSelection(hwnd2Tree))
+ {
+ int type = MODULE;
+ TVITEM tvi = {0};
+ HANDLE hContact = NULL;
+ tvi.mask=TVIF_HANDLE|TVIF_PARAM|TVIF_TEXT;
+ tvi.pszText = module;
+ tvi.cchTextMax = 255;
+ tvi.hItem=item;
+
+ if (TreeView_GetItem(hwnd2Tree, &tvi))
+ {
+ if (tvi.lParam)
+ {
+ ModuleTreeInfoStruct *mtis = (ModuleTreeInfoStruct *)tvi.lParam;
+ hContact = mtis->hContact;
+ type = mtis->type;
+ }
+
+ DBWriteContactSettingDword(NULL,modname,"LastContact",(DWORD)hContact);
+
+ if (type == CONTACT)
+ DBWriteContactSettingString(NULL,modname,"LastModule","");
+ else
+ DBWriteContactSettingString(NULL,modname,"LastModule",module);
+ }
+ else
+ {
+ DBDeleteContactSetting(NULL,modname,"LastContact");
+ DBDeleteContactSetting(NULL,modname,"LastModule");
+ }
+
+ // setting list
+ {
+ HWND hwnd2Settings = GetDlgItem(hwnd, IDC_SETTINGS);
+ int pos = ListView_GetSelectionMark(hwnd2Settings);
+
+ if (pos != -1)
+ {
+ char text[256];
+
+ ListView_GetItemText(hwnd2Settings, pos, 0, text, SIZEOF(text));
+
+ DBWriteContactSettingString(NULL,modname,"LastSetting",text);
+ }
+ else
+ DBDeleteContactSetting(NULL,modname,"LastSetting");
+ }
+ }
+ }
+ DBWriteContactSettingByte(NULL,modname,"HexMode",(byte)Hex);
+ DBWriteContactSettingByte(NULL,modname,"SortMode",(byte)Order);
+ saveListSettings(GetDlgItem(hwnd,IDC_SETTINGS));
+ hwnd2mainWindow = 0;
+ ClearListview(GetDlgItem(hwnd,IDC_SETTINGS));
+ freeTree(GetDlgItem(hwnd,IDC_MODULES),0);
+ if (himl)
+ ImageList_Destroy(himl);
+ if (himl2)
+ ImageList_Destroy(himl2);
+ SetWindowLongPtr(GetDlgItem(hwnd,IDC_SETTINGS),GWLP_WNDPROC,(LONG)SettingListSubClass);
+ SetWindowLongPtr(GetDlgItem(hwnd,IDC_MODULES),GWLP_WNDPROC,(LONG)ModuleTreeSubClass);
+ SetWindowLongPtr(GetDlgItem(hwnd,IDC_SPLITTER),GWLP_WNDPROC,(LONG)SplitterSubClass);
+ if (!DBGetContactSettingByte(NULL,modname,"Maximised",0))
+ {
+ RECT rc;
+ GetWindowRect(hwnd,&rc);
+ DBWriteContactSettingDword(NULL,modname,"x",rc.left);
+ DBWriteContactSettingDword(NULL,modname,"y",rc.top);
+ DBWriteContactSettingDword(NULL,modname,"width",rc.right-rc.left);
+ DBWriteContactSettingDword(NULL,modname,"height",rc.bottom-rc.top);
+ }
+ if (hwnd2importWindow) {
+ DestroyWindow(hwnd2importWindow);
+ hwnd2importWindow = 0;
+ }
+ if ( bServiceMode ) {
+ PostQuitMessage(0);
+ }
+
+ return 0;
+ case WM_COMMAND:
+ if (GetKeyState(VK_ESCAPE) & 0x8000) return TRUE; // this needs to be changed to c if htere is a label edit happening..
+ switch(LOWORD(wParam))
+ {
+ case MENU_REFRESH_MODS:
+ refreshTree(1);
+ break;
+ case MENU_REFRESH_SETS:
+ {
+ TVITEM tvi;
+ ModuleTreeInfoStruct *mtis;
+ char module[256];
+ tvi.mask=TVIF_HANDLE|TVIF_PARAM|TVIF_TEXT;
+ tvi.hItem=TreeView_GetSelection(GetDlgItem(hwnd, IDC_MODULES));
+ tvi.pszText = module;
+ tvi.cchTextMax = 255;
+ if (!TreeView_GetItem(GetDlgItem(hwnd, IDC_MODULES),&tvi)) break;
+ if (tvi.lParam)
+ {
+ mtis = (ModuleTreeInfoStruct *)tvi.lParam;
+ if (mtis->type == MODULE || mtis->type == UNKNOWN_MODULE)
+ PopulateSettings(GetDlgItem(hwnd, IDC_SETTINGS), mtis->hContact, module);
+ else ClearListview(GetDlgItem(hwnd, IDC_SETTINGS));
+ }
+ else ClearListview(GetDlgItem(hwnd, IDC_SETTINGS));
+ }
+ break;
+ ///////////////////////// // watches
+ case MENU_VIEW_WATCHES:
+ {
+ if (!hwnd2watchedVarsWindow) // so only opens 1 at a time
+ hwnd2watchedVarsWindow = CreateDialog(hInst, MAKEINTRESOURCE(IDD_WATCH_DIAG), 0, WatchDlgProc);
+ else SetForegroundWindow(hwnd2watchedVarsWindow);
+ }
+ break;
+ case MENU_REMALL_WATCHES:
+ freeAllWatches();
+ break;
+ case MENU_EXPORTDB: // all db
+ exportDB(INVALID_HANDLE_VALUE,0);
+ break;
+ case MENU_EXPORTCONTACT: // all contacts
+ exportDB(INVALID_HANDLE_VALUE, "");
+ break;
+ case MENU_EXPORTMODULE: // all settings
+ exportDB(NULL, 0);
+ break;
+ case MENU_IMPORTFROMFILE:
+ ImportSettingsFromFileMenuItem(NULL, "");
+ break;
+ case MENU_IMPORTFROMTEXT:
+ ImportSettingsMenuItem(NULL);
+ break;
+ case MENU_EXIT:
+ case IDCANCEL:
+ DestroyWindow(hwnd);
+ break;
+ case MENU_DELETE:
+ deleteModuleGui();
+ break;
+ case MENU_FINDANDREPLACE:
+ CreateDialog(hInst, MAKEINTRESOURCE(IDD_FIND), hwnd, FindWindowDlgProc);
+ break;
+ case MENU_FILTER_ALL:
+ if (Mode != MODE_ALL)
+ {
+ HMENU hMenu = GetMenu(hwnd);
+ CheckMenuItem(GetSubMenu(hMenu,5),MENU_FILTER_ALL,MF_BYCOMMAND|MF_CHECKED);
+ CheckMenuItem(GetSubMenu(hMenu,5),MENU_FILTER_LOADED,MF_BYCOMMAND|MF_UNCHECKED);
+ CheckMenuItem(GetSubMenu(hMenu,5),MENU_FILTER_UNLOADED,MF_BYCOMMAND|MF_UNCHECKED);
+ Mode = MODE_ALL;
+ refreshTree(1);
+ }
+ break;
+ case MENU_FILTER_LOADED:
+ if (Mode != MODE_LOADED)
+ {
+ HMENU hMenu = GetMenu(hwnd);
+ CheckMenuItem(GetSubMenu(hMenu,5),MENU_FILTER_ALL,MF_BYCOMMAND|MF_UNCHECKED);
+ CheckMenuItem(GetSubMenu(hMenu,5),MENU_FILTER_LOADED,MF_BYCOMMAND|MF_CHECKED);
+ CheckMenuItem(GetSubMenu(hMenu,5),MENU_FILTER_UNLOADED,MF_BYCOMMAND|MF_UNCHECKED);
+ Mode = MODE_LOADED;
+ refreshTree(1);
+ }
+ break;
+ case MENU_FILTER_UNLOADED:
+ if (Mode != MODE_UNLOADED)
+ {
+ HMENU hMenu = GetMenu(hwnd);
+ CheckMenuItem(GetSubMenu(hMenu,5),MENU_FILTER_ALL,MF_BYCOMMAND|MF_UNCHECKED);
+ CheckMenuItem(GetSubMenu(hMenu,5),MENU_FILTER_LOADED,MF_BYCOMMAND|MF_UNCHECKED);
+ CheckMenuItem(GetSubMenu(hMenu,5),MENU_FILTER_UNLOADED,MF_BYCOMMAND|MF_CHECKED);
+ Mode = MODE_UNLOADED;
+ refreshTree(1);
+ }
+ break;
+ case MENU_BYTE_HEX:
+ {
+ Hex ^= HEX_BYTE;
+ CheckMenuItem(GetSubMenu(GetMenu(hwnd),5),MENU_BYTE_HEX,MF_BYCOMMAND|((Hex & HEX_BYTE)?MF_CHECKED:MF_UNCHECKED));
+ }
+ break;
+ case MENU_WORD_HEX:
+ {
+ Hex ^= HEX_WORD;
+ CheckMenuItem(GetSubMenu(GetMenu(hwnd),5),MENU_WORD_HEX,MF_BYCOMMAND|((Hex & HEX_WORD)?MF_CHECKED:MF_UNCHECKED));
+ }
+ break;
+ case MENU_DWORD_HEX:
+ {
+ Hex ^= HEX_DWORD;
+ CheckMenuItem(GetSubMenu(GetMenu(hwnd),5),MENU_DWORD_HEX,MF_BYCOMMAND|((Hex & HEX_DWORD)?MF_CHECKED:MF_UNCHECKED));
+ }
+ break;
+ case MENU_SAVE_POSITION:
+ {
+ BOOL save = !DBGetContactSettingByte(NULL,modname,"RestoreOnOpen",1);
+ CheckMenuItem(GetSubMenu(GetMenu(hwnd),5),MENU_SAVE_POSITION,MF_BYCOMMAND|(save?MF_CHECKED:MF_UNCHECKED));
+ DBWriteContactSettingByte(NULL,modname,"RestoreOnOpen", (byte)save);
+ }
+ break;
+ case MENU_SORT_ORDER:
+ Order = !Order;
+ CheckMenuItem(GetSubMenu(GetMenu(hwnd),5),MENU_SORT_ORDER,MF_BYCOMMAND|(Order?MF_CHECKED:MF_UNCHECKED));
+ refreshTree(1);
+ break;
+ }
+ return TRUE; // case WM_COMMAND
+ case WM_NOTIFY:
+ switch(LOWORD(wParam))
+ {
+ case IDC_MODULES:
+ moduleListWM_NOTIFY(hwnd,msg,wParam,lParam);
+ break;
+ case IDC_SETTINGS:
+ SettingsListWM_NOTIFY(hwnd,msg,wParam,lParam);
+ break;
+ }
+ return TRUE; // case WM_NOTIFY
+ case WM_FINDITEM:
+ {
+ ItemInfo *ii = (ItemInfo*)wParam;
+ HWND hwnd2Settings = GetDlgItem(hwnd,IDC_SETTINGS);
+ int hItem = findItemInTree(GetDlgItem(hwnd,IDC_MODULES),ii->hContact,ii->module);
+
+ if (hItem != -1)
+ {
+ TreeView_SelectItem(GetDlgItem(hwnd,IDC_MODULES), (HTREEITEM)hItem);
+ if (ii->type != FW_MODULE)
+ {
+ LVITEM lvItem;
+ LVFINDINFO lvfi;
+
+ lvfi.flags = LVFI_STRING;
+ lvfi.psz = ii->setting;
+ lvfi.vkDirection = VK_DOWN;
+
+ lvItem.mask = LVIF_TEXT|LVIF_IMAGE;
+ lvItem.iItem = ListView_FindItem(hwnd2Settings,-1,&lvfi);
+ lvItem.iSubItem = 0;
+ if (lvItem.iItem >= 0)
+ ListView_SetItemState(hwnd2Settings,lvItem.iItem, LVIS_SELECTED, LVIS_SELECTED);
+ }
+ }
+ }
+ break;
+ } // switch(msg)
+ return 0;
+}
diff --git a/plugins/dbeditorpp/modsettingenum.cpp b/plugins/dbeditorpp/modsettingenum.cpp
new file mode 100644
index 0000000000..7eaecdd1a0
--- /dev/null
+++ b/plugins/dbeditorpp/modsettingenum.cpp
@@ -0,0 +1,88 @@
+#include "headers.h"
+
+void FreeModuleSettingLL(ModuleSettingLL* msll)
+{
+ if (msll)
+ {
+
+ struct ModSetLinkLinkItem *item = msll->first;
+ struct ModSetLinkLinkItem *temp;
+
+ while (item)
+ {
+ mir_free(item->name);
+ temp = item;
+ item = (struct ModSetLinkLinkItem *)item->next;
+ mir_free(temp);
+ }
+
+ msll->first = 0;
+ msll->last = 0;
+ }
+}
+
+int enumModulesSettingsProc( const char *szName , DWORD ofsModuleName , LPARAM lParam)
+{
+ ModuleSettingLL *msll = (ModuleSettingLL *)lParam;
+ if (!msll->first)
+ {
+ msll->first = (struct ModSetLinkLinkItem *)mir_alloc(sizeof(struct ModSetLinkLinkItem));
+ if (!msll->first) return 1;
+ msll->first->name = mir_tstrdup(szName);
+ msll->first->next = 0;
+ msll->last = msll->first;
+ }
+ else
+ {
+ struct ModSetLinkLinkItem *item = (struct ModSetLinkLinkItem *)mir_alloc(sizeof(struct ModSetLinkLinkItem));
+ if (!item) return 1;
+ msll->last->next = (BYTE*)item;
+ msll->last = (struct ModSetLinkLinkItem *)item;
+ item->name = mir_tstrdup(szName);
+ item->next = 0;
+ }
+ return 0;
+}
+
+int EnumModules(ModuleSettingLL *msll) // 1 = success, 0 = fail
+{
+ msll->first = 0;
+ msll->last = 0;
+ return !CallService(MS_DB_MODULES_ENUM, (WPARAM)msll,(WPARAM)enumModulesSettingsProc);
+}
+
+
+int enumSettingsProc(const char *szSetting,LPARAM lParam)
+{
+ return enumModulesSettingsProc(szSetting,0,lParam);
+}
+
+
+int EnumSettings(HANDLE hContact, char* module, ModuleSettingLL *msll)
+{
+ DBCONTACTENUMSETTINGS dbces;
+ // enum all setting the contact has for the module
+ dbces.pfnEnumProc = enumSettingsProc;
+ dbces.szModule = module;
+ dbces.lParam = (LPARAM)msll;
+ msll->first = 0;
+ msll->last = 0;
+ return !CallService(MS_DB_CONTACT_ENUMSETTINGS, (WPARAM)hContact,(LPARAM)&dbces);
+}
+
+int CheckIfModuleIsEmptyProc(const char *szSetting,LPARAM lParam)
+{
+ return 1;
+}
+
+int IsModuleEmpty(HANDLE hContact, char* szModule)
+{
+ DBCONTACTENUMSETTINGS dbces;
+ int retVal;
+ dbces.pfnEnumProc = CheckIfModuleIsEmptyProc;
+ dbces.szModule = szModule;
+ retVal = CallService(MS_DB_CONTACT_ENUMSETTINGS, (WPARAM)hContact,(LPARAM)&dbces);
+ if (retVal >= 0)
+ return 0;
+ else return 1;
+} \ No newline at end of file
diff --git a/plugins/dbeditorpp/modsettingenum.h b/plugins/dbeditorpp/modsettingenum.h
new file mode 100644
index 0000000000..0ef32f8cc5
--- /dev/null
+++ b/plugins/dbeditorpp/modsettingenum.h
@@ -0,0 +1,17 @@
+struct ModSetLinkLinkItem {
+ char *name;
+ BYTE *next; //struct ModSetLinkLinkItem
+ int known;
+};
+
+typedef struct {
+ struct ModSetLinkLinkItem *first;
+ struct ModSetLinkLinkItem *last;
+} ModuleSettingLL;
+
+int EnumModules(ModuleSettingLL *msll);
+int EnumSettings(HANDLE hContact, char* module, ModuleSettingLL *msll);
+
+void FreeModuleSettingLL(ModuleSettingLL *msll);
+
+int IsModuleEmpty(HANDLE hContact, char* szModule); \ No newline at end of file
diff --git a/plugins/dbeditorpp/modules.cpp b/plugins/dbeditorpp/modules.cpp
new file mode 100644
index 0000000000..4053180038
--- /dev/null
+++ b/plugins/dbeditorpp/modules.cpp
@@ -0,0 +1,109 @@
+#include "headers.h"
+
+
+void renameModule(char* oldName, char* newName, HANDLE hContact)
+{
+ DBVARIANT dbv;
+ ModuleSettingLL settinglist;
+ struct ModSetLinkLinkItem *setting;
+
+ if (!EnumSettings(hContact,oldName,&settinglist)) { msg(Translate("Error Loading Setting List"),modFullname); return;}
+
+ setting = settinglist.first;
+ while (setting)
+ {
+ if (!GetSetting(hContact,oldName,setting->name,&dbv))
+ {
+ switch (dbv.type)
+ {
+ case DBVT_BYTE:
+ DBWriteContactSettingByte(hContact, newName, setting->name, dbv.bVal);
+ break;
+ case DBVT_WORD:
+ DBWriteContactSettingWord(hContact, newName, setting->name, dbv.wVal);
+ break;
+ case DBVT_DWORD:
+ DBWriteContactSettingDword(hContact, newName, setting->name, dbv.dVal);
+ break;
+ case DBVT_ASCIIZ:
+ DBWriteContactSettingString(hContact, newName, setting->name, dbv.pszVal);
+ break;
+ case DBVT_UTF8:
+ DBWriteContactSettingStringUtf(hContact, newName, setting->name, dbv.pszVal);
+ break;
+ case DBVT_BLOB:
+ DBWriteContactSettingBlob(hContact, newName, setting->name, dbv.pbVal, dbv.cpbVal);
+ break;
+
+ }
+ DBDeleteContactSetting(hContact, oldName, setting->name);
+ }
+ DBFreeVariant(&dbv);
+ setting = (struct ModSetLinkLinkItem *)setting->next;
+ }
+ FreeModuleSettingLL(&settinglist);
+}
+
+INT_PTR CALLBACK AddModDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ if (msg == WM_INITDIALOG)
+ {
+ SetWindowLongPtr(hwnd,GWLP_USERDATA,lParam);
+ TranslateDialogDefault(hwnd);
+ }
+ if (msg == WM_COMMAND)
+ {
+ switch(LOWORD(wParam))
+ {
+ case IDOK:
+ {
+ if (GetWindowTextLength(GetDlgItem(hwnd, IDC_MODNAME)))
+ {
+ char modulename[256];
+ GetDlgItemText(hwnd, IDC_MODNAME, modulename, 256);
+ if (IsDlgButtonChecked(hwnd,CHK_ADD2ALL))
+ {
+ HANDLE hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ // null contact
+ DBWriteContactSettingByte(NULL, modulename, "(Default)", 0);
+ while (hContact)
+ {
+ DBWriteContactSettingByte(hContact, modulename, "(Default)", 0);
+ hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)(HANDLE)hContact, 0);
+ }
+ }
+ else
+ {
+ DBWriteContactSettingByte((HANDLE)GetWindowLongPtr(hwnd,GWLP_USERDATA), modulename, "(Default)", 0);
+ }
+ refreshTree(1);
+ }
+ }
+ // fall through
+ case IDCANCEL:
+ DestroyWindow(hwnd);
+ break;
+ }
+ }
+ return 0;
+}
+
+int CloneContact(HANDLE hContact)
+{
+ HANDLE newContact = (HANDLE)CallService(MS_DB_CONTACT_ADD,0,0);
+
+ ModuleSettingLL modlist;
+ struct ModSetLinkLinkItem *mod;
+ if (!newContact) return 0;
+ // enum all the modules
+ if (!EnumModules(&modlist)) { msg(Translate("Error Loading Module List"),modFullname); return 0;}
+
+ mod = modlist.first;
+ while (mod)
+ {
+ copyModule(mod->name,hContact,newContact);
+ mod = (struct ModSetLinkLinkItem *)mod->next;
+ }
+ FreeModuleSettingLL(&modlist);
+ return 1;
+} \ No newline at end of file
diff --git a/plugins/dbeditorpp/moduletree.cpp b/plugins/dbeditorpp/moduletree.cpp
new file mode 100644
index 0000000000..a3828b843e
--- /dev/null
+++ b/plugins/dbeditorpp/moduletree.cpp
@@ -0,0 +1,1135 @@
+#include "headers.h"
+
+static BOOL populating = 0;
+int Select = 0;
+static ModuleTreeInfoStruct contacts_mtis = {CONTACT_ROOT_ITEM, 0};
+static ModuleTreeInfoStruct settings_mtis = {CONTACT, 0};
+
+
+int doContacts(HWND hwnd2Tree,HTREEITEM contactsRoot,ModuleSettingLL *modlist, HANDLE hSelectedContact, char *SelectedModule, char *SelectedSetting)
+{
+ TVINSERTSTRUCT tvi;
+ char szProto[256];
+ HANDLE hContact;
+ HTREEITEM contact;
+ ModuleTreeInfoStruct *lParam;
+ struct ModSetLinkLinkItem *module;
+ int count = CallService(MS_DB_CONTACT_GETCOUNT, 0, 0);
+ int itemscount = 0;
+ int loaded, i = 0, icon = 0;
+ HWND hwnd = GetParent(hwnd2Tree);
+ int hItem = -1;
+
+// char percent[96], title[64];
+// mir_snprintf(title, sizeof(title),Translate("Loading contacts..."));
+ SetWindowText(hwnd2mainWindow, Translate("Loading contacts..."));
+
+ hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+
+ tvi.hInsertAfter = TVI_SORT;
+ tvi.item.cChildren = 1;
+
+ while (hContact && hwnd2mainWindow) // break after null contact
+ {
+
+ if (GetValue(hContact,"Protocol","p",szProto,SIZEOF(szProto)))
+ {
+ icon = GetProtoIcon(szProto);
+ loaded = (icon != DEF_ICON);
+ }
+ else
+ {
+ icon = DEF_ICON;
+ loaded = 0;
+ }
+
+ i++;
+
+ // filter
+ if ((loaded && Mode == MODE_UNLOADED) || (!loaded && Mode == MODE_LOADED))
+ {
+ hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0);
+ continue;
+ }
+
+ // Caption
+// mir_snprintf(percent,sizeof(percent),"%s %d%%",title,(int)(100*i/count));
+// SetWindowText(hwnd2mainWindow, percent);
+
+ // add the contact
+ lParam = (ModuleTreeInfoStruct *)mir_calloc(sizeof(ModuleTreeInfoStruct));
+ lParam->hContact = hContact;
+ lParam->type = CONTACT;
+ tvi.item.mask = TVIF_TEXT|TVIF_CHILDREN|TVIF_PARAM|TVIF_IMAGE|TVIF_SELECTEDIMAGE;
+ tvi.item.lParam = (LPARAM)lParam;
+ tvi.hParent = contactsRoot;
+
+ if (hSelectedContact != hContact)
+ lParam->type |= EMPTY;
+
+ // contacts name
+ if (UOS)
+ {
+ DBVARIANT dbv ={0};
+ WCHAR nick[256];
+ WCHAR protoW[256]; // unicode proto
+
+ if (szProto[0])
+ a2u(szProto, protoW, SIZEOF(protoW));
+ else
+ protoW[0] = 0;
+
+ if (!szProto[0] || !loaded)
+ {
+ tvi.item.iSelectedImage = (tvi.item.iImage = 4);
+
+ if (protoW)
+ {
+ if (Order)
+ mir_snwprintf(nick, SIZEOF(nick), L"(%s) %s %s", protoW, GetContactName(hContact, szProto, 1), L"(UNLOADED)");
+ else
+ mir_snwprintf(nick, SIZEOF(nick), L"%s (%s) %s", GetContactName(hContact, szProto, 1), protoW, L"(UNLOADED)");
+ }
+ else
+ wcscpy(nick, nick_unknownW);
+ }
+ else
+ {
+ tvi.item.iSelectedImage = (tvi.item.iImage = icon); //GetProtoIcon(szProto, 7));
+ if (Order)
+ mir_snwprintf(nick, SIZEOF(nick), L"(%s) %s", protoW, GetContactName(hContact, szProto, 1));
+ else
+ mir_snwprintf(nick, SIZEOF(nick), L"%s (%s)", GetContactName(hContact, szProto, 1), protoW);
+ }
+
+ tvi.item.pszText = (char*)nick;
+ contact = TreeView_InsertItemW(hwnd2Tree, &tvi);
+ }
+ else
+ {
+ char nick[256];
+
+ if (!szProto[0] || !loaded)
+ {
+ tvi.item.iSelectedImage = (tvi.item.iImage = 4);
+
+ if (szProto[0])
+ {
+ if (Order)
+ mir_snprintf(nick, SIZEOF(nick), "(%s) %s %s", szProto, (char*)GetContactName(hContact, szProto, 0), "(UNLOADED)");
+ else
+ mir_snprintf(nick, SIZEOF(nick), "%s (%s) %s", (char*)GetContactName(hContact, szProto, 0), szProto, "(UNLOADED)");
+ }
+ else
+ strcpy(nick, nick_unknown);
+ }
+ else
+ {
+ tvi.item.iSelectedImage = (tvi.item.iImage = icon); //GetProtoIcon(szProto, 7));
+ if (Order)
+ mir_snprintf(nick, SIZEOF(nick), "(%s) %s", szProto, (char*)GetContactName(hContact, szProto, 0));
+ else
+ mir_snprintf(nick, SIZEOF(nick), "%s (%s)", (char*)GetContactName(hContact, szProto, 0), szProto);
+ }
+
+ tvi.item.pszText = nick;
+ contact = TreeView_InsertItem(hwnd2Tree, &tvi);
+ }
+
+ itemscount++;
+
+ if (hSelectedContact == hContact)
+ {
+
+ module = modlist->first;
+ while(module && hwnd2mainWindow)
+ {
+ if (module->name[0] && !IsModuleEmpty(hContact,module->name))
+ {
+ tvi.hParent = contact;
+ tvi.hInsertAfter = TVI_SORT;
+ tvi.item.mask = TVIF_TEXT|TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIF_PARAM;
+ tvi.item.pszText = module->name;
+
+ lParam = (ModuleTreeInfoStruct *)mir_calloc(sizeof(ModuleTreeInfoStruct));
+ lParam->hContact = hContact;
+
+ if (!module->known)
+ {
+ tvi.item.iImage = 5;
+ tvi.item.iSelectedImage = 6;
+ lParam->type = UNKNOWN_MODULE;
+ }
+ else
+ {
+ tvi.item.iImage = 1;
+ tvi.item.iSelectedImage = 2;
+ lParam->type = KNOWN_MODULE;
+ }
+
+ tvi.item.lParam = (LPARAM)lParam;
+ TreeView_InsertItem(hwnd2Tree, &tvi);
+ }
+ module = (struct ModSetLinkLinkItem *)module->next;
+ }
+
+ hItem = findItemInTree(hwnd2Tree, hSelectedContact, SelectedModule);
+
+ }
+
+ hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0);
+ }
+
+
+ if (hItem != -1)
+ {
+ TreeView_SelectItem(hwnd2Tree, (HTREEITEM)hItem);
+ TreeView_Expand(hwnd2Tree,hItem,TVE_EXPAND);
+ if (SelectedSetting[0]) SelectSetting(SelectedSetting);
+ }
+
+// if (UOS)
+// SetWindowText(hwnd, Translate("Database Editor++ (unicode mode)"));
+// else
+// SetWindowText(hwnd, Translate("Database Editor++ (ansi mode)"));
+
+
+ return itemscount;
+}
+
+
+
+void doItems(HWND hwnd2Tree,ModuleSettingLL *modlist, int count)
+{
+ TVINSERTSTRUCT tvi;
+ TVITEM item ={0};
+ HANDLE hContact;
+ HTREEITEM contact;
+ ModuleTreeInfoStruct *lParam;
+ struct ModSetLinkLinkItem *module;
+ char percent[96], title[64];
+ HWND hwnd = GetParent(hwnd2Tree);
+ int i = 0;
+
+ mir_snprintf(title, SIZEOF(title), Translate("Loading modules..."));
+
+ item.mask = TVIF_STATE|TVIF_PARAM;
+
+ contact = TreeView_GetChild( hwnd2Tree, TVI_ROOT );
+ contact = TreeView_GetNextSibling(hwnd2Tree, contact);
+ contact = TreeView_GetChild(hwnd2Tree, contact);
+
+ while (contact && hwnd2mainWindow)
+ {
+ i++;
+ item.hItem = contact;
+ contact = TreeView_GetNextSibling(hwnd2Tree, contact);
+
+ if (TreeView_GetItem( hwnd2Tree, &item ) &&
+ item.lParam) // && item.state != TVE_EXPAND)
+ {
+ ModuleTreeInfoStruct *mtis = (ModuleTreeInfoStruct *)item.lParam;
+ hContact = mtis->hContact;
+ if (hContact == NULL || mtis->type != (CONTACT|EMPTY))
+ continue;
+ else
+ mtis->type = CONTACT;
+ }
+ else continue;
+
+ // Caption
+ mir_snprintf(percent, SIZEOF(percent), "%s %d%%", title, (int)(100*i/count));
+ SetWindowText(hwnd, percent);
+
+ module = modlist->first;
+ while(module && hwnd2mainWindow)
+ {
+ if (module->name[0] && !IsModuleEmpty(hContact,module->name))
+ {
+ tvi.hParent = item.hItem;
+ tvi.hInsertAfter = TVI_SORT;
+ tvi.item.mask = TVIF_TEXT|TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIF_PARAM;
+ tvi.item.pszText = module->name;
+
+ lParam = (ModuleTreeInfoStruct *)mir_calloc(sizeof(ModuleTreeInfoStruct));
+ lParam->hContact = hContact;
+
+ if (!module->known)
+ {
+ tvi.item.iImage = 5;
+ tvi.item.iSelectedImage = 6;
+ lParam->type = UNKNOWN_MODULE;
+ }
+ else
+ {
+ tvi.item.iImage = 1;
+ tvi.item.iSelectedImage = 2;
+ lParam->type = KNOWN_MODULE;
+ }
+
+ tvi.item.lParam = (LPARAM)lParam;
+ TreeView_InsertItem(hwnd2Tree, &tvi);
+ }
+ module = (struct ModSetLinkLinkItem *)module->next;
+ }
+
+ }
+
+ if (UOS)
+ SetWindowText(hwnd, Translate("Database Editor++ (unicode mode)"));
+ else
+ SetWindowText(hwnd, Translate("Database Editor++ (ansi mode)"));
+
+
+}
+
+
+int findItemInTree(HWND hwnd2Tree, HANDLE hContact, char* module)
+/* the following code to go through the whole tree is nicked from codeguru..
+http://www.codeguru.com/Cpp/controls/treeview/treetraversal/comments.php/c683/?thread=7680 */
+{
+ TVITEM item;
+ char text[265];
+ HTREEITEM lastItem;
+ if (!TreeView_GetCount(hwnd2Tree)) return 0;
+
+ item.mask = TVIF_STATE|TVIF_PARAM|TVIF_TEXT;
+ item.hItem = TVI_ROOT;
+ item.pszText = text;
+ item.cchTextMax = 264;
+ do
+ {
+ do
+ {
+ lastItem = item.hItem;
+ if (lastItem != TVI_ROOT)
+ {
+/* these next 2 lines are not from code guru..... */
+ if (TreeView_GetItem( hwnd2Tree, &item) && item.lParam)
+ {
+ if ((hContact == ((ModuleTreeInfoStruct *)item.lParam)->hContact) && (!module[0] || !mir_strcmp(module,text)))
+ {
+ //TreeView_SelectItem(hwnd2Tree,item.hItem);
+ return (int)item.hItem;
+ }
+ }
+/* back to coduguru's code*/
+ }
+ } while ( (item.hItem = TreeView_GetChild( hwnd2Tree, lastItem )) );
+ while ( (! (item.hItem = TreeView_GetNextSibling( hwnd2Tree, lastItem ))) && (lastItem = item.hItem = TreeView_GetParent( hwnd2Tree, lastItem )) ) {}
+
+ } while ( item.hItem );
+/*****************************************************************************/
+
+ return -1;
+}
+
+void freeTree(HWND hwnd2Tree, HANDLE hContact)
+/* the following code to go through the whole tree is nicked from codeguru..
+http://www.codeguru.com/Cpp/controls/treeview/treetraversal/comments.php/c683/?thread=7680 */
+{
+ TVITEM item;
+ HTREEITEM lastItem;
+ if (!TreeView_GetCount(hwnd2Tree)) return;
+
+ item.mask = TVIF_STATE|TVIF_PARAM;
+ item.hItem = TVI_ROOT;
+ do
+ {
+ do
+ {
+ lastItem = item.hItem;
+ if (lastItem != TVI_ROOT)
+ {
+ TreeView_GetItem( hwnd2Tree, &item );
+/* these next 2 lines are not from code guru..... */
+ if (item.lParam)
+ {
+ ModuleTreeInfoStruct *mtis = (ModuleTreeInfoStruct *)item.lParam;
+
+ if (!hContact || (hContact == mtis->hContact))
+ {
+ if (hContact != NULL) {
+ TreeView_DeleteItem(hwnd2Tree,item.hItem);
+ mir_free(mtis);
+ } else
+ mtis->type = STUB;
+ }
+ }
+/* back to coduguru's code*/
+ }
+ } while ( (item.hItem = TreeView_GetChild( hwnd2Tree, lastItem )) );
+ while ( (! (item.hItem = TreeView_GetNextSibling( hwnd2Tree, lastItem ))) && (lastItem = item.hItem = TreeView_GetParent( hwnd2Tree, lastItem )) ) {}
+
+ } while ( item.hItem );
+/*****************************************************************************/
+}
+
+BOOL findAndRemoveDuplicates(HWND hwnd2Tree, HANDLE hContact, char* module)
+/* the following code to go through the whole tree is nicked from codeguru..
+http://www.codeguru.com/Cpp/controls/treeview/treetraversal/comments.php/c683/?thread=7680 */
+{
+ TVITEM item;
+ HTREEITEM lastItem, prelastItem;
+ BOOL Result = 0;
+ char text[265];
+ if (!TreeView_GetCount(hwnd2Tree)) return Result;
+
+ item.mask = TVIF_STATE|TVIF_PARAM|TVIF_TEXT;
+ item.hItem = TVI_ROOT;
+ item.pszText = text;
+ item.cchTextMax = 264;
+ prelastItem = item.hItem;
+
+ do
+ {
+ do
+ {
+ lastItem = item.hItem;
+ if (lastItem != TVI_ROOT)
+ {
+ TreeView_GetItem( hwnd2Tree, &item );
+/* these next lines are not from code guru..... */
+ if (item.lParam)
+ {
+ ModuleTreeInfoStruct *mtis = (ModuleTreeInfoStruct *)item.lParam;
+ if (hContact == mtis->hContact && !mir_strcmp(text,module))
+ {
+ mir_free(mtis);
+ TreeView_DeleteItem(hwnd2Tree,item.hItem);
+ lastItem = prelastItem;
+ Result = 1;
+ }
+ else
+ prelastItem = lastItem;
+ }
+/* back to coduguru's code*/
+ }
+ } while ( (item.hItem = TreeView_GetChild( hwnd2Tree, lastItem )) );
+ while ( (! (item.hItem = TreeView_GetNextSibling( hwnd2Tree, lastItem ))) && (lastItem = item.hItem = TreeView_GetParent( hwnd2Tree, lastItem )) ) {}
+
+ } while ( item.hItem );
+/*****************************************************************************/
+
+ return Result;
+}
+
+
+void replaceTreeItem(HWND hwnd, HANDLE hContact, const char *module, const char *newModule)
+{
+ int hItem = findItemInTree(hwnd, hContact, (char*)module);
+ HTREEITEM hParent;
+
+ if (hItem == -1) return;
+
+ hParent = TreeView_GetParent(hwnd,(HTREEITEM)hItem);
+
+ {
+ TVITEM item;
+ item.mask = TVIF_PARAM;
+ item.hItem = (HTREEITEM)hItem;
+
+ if (TreeView_GetItem(hwnd, &item))
+ mir_free((ModuleTreeInfoStruct *)item.lParam);
+ TreeView_DeleteItem(hwnd,item.hItem);
+ }
+
+ if (hParent && newModule)
+ {
+ TVINSERTSTRUCT tvi = {0};
+ ModuleTreeInfoStruct *lParam;
+
+ tvi.hParent = hParent;
+ tvi.hInsertAfter = TVI_SORT;
+ tvi.item.mask = TVIF_TEXT|TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIF_PARAM;
+ tvi.item.pszText = (char*)newModule;
+
+ lParam = (ModuleTreeInfoStruct *)mir_calloc(sizeof(ModuleTreeInfoStruct));
+ lParam->hContact = hContact;
+ lParam->type = IsModuleKnown((char*)newModule)?KNOWN_MODULE:UNKNOWN_MODULE;
+ if (lParam->type == UNKNOWN_MODULE)
+ {
+ tvi.item.iImage = 5;
+ tvi.item.iSelectedImage = 6;
+ }
+ else
+ {
+ tvi.item.iImage = 1;
+ tvi.item.iSelectedImage = 2;
+ }
+
+ tvi.item.lParam = (LPARAM)lParam;
+
+ TreeView_InsertItem(hwnd, &tvi);
+ }
+
+}
+
+
+void refreshTree(int restore)
+{
+ UseKnownModList = DBGetContactSettingByte(NULL,modname,"UseKnownModList",0);
+ if (populating) return;
+ populating = 1;
+ forkthread(PopulateModuleTreeThreadFunc,0,(HWND)restore);
+}
+
+
+void __cdecl PopulateModuleTreeThreadFunc(LPVOID di)
+{
+ TVINSERTSTRUCT tvi;
+ HWND hwnd2Tree = GetDlgItem(hwnd2mainWindow,IDC_MODULES);
+ char SelectedModule[256] = {0};
+ char SelectedSetting[256] = {0};
+ HANDLE hSelectedContact = hRestore;
+ HANDLE hContact;
+ HTREEITEM contact, contactsRoot;
+ int count;
+
+ // item lParams
+ ModuleTreeInfoStruct *lParam;
+
+ // module list
+ struct ModSetLinkLinkItem *module;
+ ModuleSettingLL modlist;
+
+ hRestore = NULL;
+
+ if (!hwnd2Tree) { msg(Translate("Module tree not found"),modFullname); return;}
+
+ Select = 0;
+
+ switch((int)di) {
+ case 1: // restore after rebuild
+ {
+ HTREEITEM item;
+ if (item = TreeView_GetSelection(hwnd2Tree))
+ {
+ TVITEM tvi = {0};
+
+ tvi.mask=TVIF_HANDLE|TVIF_PARAM|TVIF_TEXT;
+ tvi.pszText = SelectedModule;
+ tvi.cchTextMax = 255;
+ tvi.hItem=item;
+
+ TreeView_GetItem(hwnd2Tree, &tvi);
+ if (tvi.lParam)
+ {
+ ModuleTreeInfoStruct *mtis = (ModuleTreeInfoStruct *)tvi.lParam;
+ hSelectedContact = mtis->hContact;
+ if (mtis->type == CONTACT) SelectedModule[0] = 0;
+ Select = 1;
+ }
+ }
+ break;
+ }
+ case 2: // restore saved
+ if (GetValue(NULL,modname,"LastModule",SelectedModule,SIZEOF(SelectedModule)))
+ {
+ hSelectedContact = (HANDLE)DBGetContactSettingDword(NULL,modname,"LastContact",(DWORD)INVALID_HANDLE_VALUE);
+ if (hSelectedContact != INVALID_HANDLE_VALUE)
+ Select = 1;
+ GetValue(NULL,modname,"LastSetting",SelectedSetting,SIZEOF(SelectedSetting));
+ }
+ break;
+ case 3: // restore from user menu
+ case 4: // jump from user menu
+ {
+ if (hSelectedContact && hSelectedContact != INVALID_HANDLE_VALUE)
+ {
+ Select = 1;
+ }
+ break;
+ }
+ } // switch
+
+ if ((int)di != 4) // do not rebuild on just going to another setting
+ {
+
+ if (!EnumModules(&modlist)) { msg(Translate("Error Loading Module List"),modFullname); return;}
+
+ // remove all items (incase there are items there...
+ freeTree(hwnd2Tree,0);
+ TreeView_DeleteAllItems(hwnd2Tree);
+ TreeView_SelectItem(hwnd2Tree,0);
+
+ //image list
+ TreeView_SetImageList(hwnd2Tree, himl, TVSIL_NORMAL);
+
+ /// contact root item
+ contacts_mtis.type = CONTACT_ROOT_ITEM;
+ tvi.item.lParam = (LPARAM)&contacts_mtis;
+ tvi.hParent = NULL;
+ tvi.item.mask = TVIF_TEXT|TVIF_CHILDREN|TVIF_STATE|TVIF_PARAM|TVIF_IMAGE|TVIF_SELECTEDIMAGE;
+ tvi.item.state = TVIS_BOLD;
+ tvi.item.stateMask = TVIS_BOLD;
+ tvi.item.cChildren = 1;
+ tvi.hInsertAfter = TVI_FIRST;
+
+ tvi.item.pszText = Translate("Contacts");
+ tvi.item.iImage = 3;
+ tvi.item.iSelectedImage = 3;
+ contactsRoot = TreeView_InsertItem(hwnd2Tree, &tvi);
+
+ // add the settings item
+ settings_mtis.type = STUB;
+ tvi.item.lParam = (LPARAM)&settings_mtis;
+ tvi.item.mask = TVIF_TEXT|TVIF_CHILDREN|TVIF_PARAM|TVIF_IMAGE|TVIF_SELECTEDIMAGE;
+ tvi.item.cChildren = 1;
+ tvi.hParent = NULL;
+ tvi.hInsertAfter = TVI_FIRST;
+ tvi.item.pszText = Translate("Settings");
+ tvi.item.iSelectedImage = (tvi.item.iImage = 0);
+ contact = TreeView_InsertItem(hwnd2Tree, &tvi);
+
+ // to fix bug with CHANGE NOTIFY on window activation
+ TreeView_SelectItem(hwnd2Tree, contact);
+ settings_mtis.type = CONTACT;
+
+ hContact = 0;
+ module = modlist.first;
+ while (module)
+ {
+ // set the module status type for the icon
+ module->known = IsModuleKnown(module->name);
+
+ if (!IsModuleEmpty(hContact,module->name))
+ {
+ tvi.hParent = contact;
+ tvi.hInsertAfter = TVI_SORT;
+ tvi.item.mask = TVIF_TEXT|TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIF_PARAM;
+ tvi.item.pszText = module->name;
+
+ lParam = (ModuleTreeInfoStruct *)mir_calloc(sizeof(ModuleTreeInfoStruct));
+ lParam->hContact = hContact;
+ if (!module->known)
+ {
+ tvi.item.iImage = 5;
+ tvi.item.iSelectedImage = 6;
+ lParam->type = UNKNOWN_MODULE;
+ }
+ else
+ {
+ tvi.item.iImage = 1;
+ tvi.item.iSelectedImage = 2;
+ lParam->type = KNOWN_MODULE;
+ }
+
+ tvi.item.lParam = (LPARAM)lParam;
+
+ TreeView_InsertItem(hwnd2Tree, &tvi);
+ }
+ module = (struct ModSetLinkLinkItem *)module->next;
+ }
+
+ if (DBGetContactSettingByte(NULL,modname,"ExpandSettingsOnOpen",0))
+ TreeView_Expand(hwnd2Tree,contact,TVE_EXPAND);
+
+ if (Select && hSelectedContact == NULL)
+ {
+ int hItem = findItemInTree(hwnd2Tree, hSelectedContact, SelectedModule);
+ if (hItem != -1)
+ {
+ TreeView_SelectItem(hwnd2Tree, (HTREEITEM)hItem);
+ TreeView_Expand(hwnd2Tree,hItem,TVE_EXPAND);
+ if (SelectedSetting[0]) SelectSetting(SelectedSetting);
+ }
+ Select = 0;
+ }
+
+ count = doContacts(hwnd2Tree,contactsRoot,&modlist, Select?hSelectedContact:NULL, SelectedModule, SelectedSetting);
+ Select = 0;
+ doItems(hwnd2Tree,&modlist,count);
+
+ FreeModuleSettingLL(&modlist);
+ }
+
+ if (Select)
+ {
+ int hItem = findItemInTree(hwnd2Tree, hSelectedContact, SelectedModule);
+ if (hItem != -1)
+ {
+ TreeView_SelectItem(hwnd2Tree, (HTREEITEM)hItem);
+ TreeView_Expand(hwnd2Tree,hItem,TVE_EXPAND);
+ if (SelectedSetting[0]) SelectSetting(SelectedSetting);
+ }
+ }
+
+ populating = 0;
+
+}
+
+
+static WNDPROC ModuleTreeLabelEditSubClass;
+
+static LRESULT CALLBACK ModuleTreeLabelEditSubClassProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
+{
+ switch(msg) {
+ case WM_KEYUP:
+ switch (wParam)
+ {
+ case VK_RETURN:
+ TreeView_EndEditLabelNow(GetParent(hwnd),0);
+ return 0;
+ case VK_ESCAPE:
+ TreeView_EndEditLabelNow(GetParent(hwnd),1);
+ return 0;
+ }
+ break;
+ }
+ return CallWindowProc(ModuleTreeLabelEditSubClass,hwnd,msg,wParam,lParam);
+}
+void moduleListRightClick(HWND hwnd, WPARAM wParam,LPARAM lParam);
+
+void moduleListWM_NOTIFY(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)// hwnd here is to the main window, NOT the treview
+{
+ switch(((NMHDR*)lParam)->code)
+ {
+ case TVN_ITEMEXPANDINGA:
+ case TVN_ITEMEXPANDINGW:
+ if (populating && ((LPNMTREEVIEW)lParam)->action == TVE_EXPAND)
+ {
+ ModuleTreeInfoStruct *mtis = (ModuleTreeInfoStruct *)((LPNMTREEVIEW)lParam)->itemNew.lParam;
+ if (mtis && (mtis->type == (CONTACT | EMPTY)))
+ {
+ TVINSERTSTRUCT tvi;
+ HTREEITEM item = {0};
+ ModuleTreeInfoStruct *_lParam;
+ HWND hwnd2Tree = GetDlgItem(hwnd2mainWindow,IDC_MODULES);
+ struct ModSetLinkLinkItem *module;
+ ModuleSettingLL modlist;
+ HANDLE hContact = mtis->hContact;
+
+ mtis->type = CONTACT;
+
+ if (!EnumModules(&modlist)) { msg(Translate("Error Loading Module List"),modFullname); break;}
+
+ module = modlist.first;
+ while(module && hwnd2mainWindow)
+ {
+ if (module->name[0] && !IsModuleEmpty(hContact,module->name))
+ {
+ tvi.hParent = ((LPNMTREEVIEW)lParam)->itemNew.hItem;
+ tvi.hInsertAfter = TVI_SORT;
+ tvi.item.mask = TVIF_TEXT|TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIF_PARAM;
+ tvi.item.pszText = module->name;
+
+ _lParam = (ModuleTreeInfoStruct *)mir_calloc(sizeof(ModuleTreeInfoStruct));
+ _lParam->hContact = hContact;
+
+ if (IsModuleKnown(module->name))
+ {
+ tvi.item.iImage = 5;
+ tvi.item.iSelectedImage = 6;
+ _lParam->type = KNOWN_MODULE;
+ }
+ else
+ {
+ tvi.item.iImage = 1;
+ tvi.item.iSelectedImage = 2;
+ _lParam->type = UNKNOWN_MODULE;
+ }
+
+ tvi.item.lParam = (LPARAM)_lParam;
+ TreeView_InsertItem(hwnd2Tree, &tvi);
+ }
+ module = (struct ModSetLinkLinkItem *)module->next;
+ }
+
+ FreeModuleSettingLL(&modlist);
+ }
+
+ }
+ break;
+
+ case TVN_SELCHANGEDA:
+ case TVN_SELCHANGEDW:
+ {
+ ModuleTreeInfoStruct *mtis;
+ LPNMTREEVIEW pnmtv = (LPNMTREEVIEW)lParam;
+ TVITEM tvi = {0};
+ char text[264];
+ HANDLE hContact;
+ HWND hwnd2Settings = GetDlgItem(hwnd, IDC_SETTINGS);
+ tvi.mask = TVIF_HANDLE|TVIF_PARAM|TVIF_TEXT;
+ tvi.hItem = pnmtv->itemNew.hItem;
+ tvi.pszText = text;
+ tvi.cchTextMax = 264;
+ TreeView_GetItem(pnmtv->hdr.hwndFrom,&tvi);
+
+ if (tvi.lParam)
+ {
+ mtis = (ModuleTreeInfoStruct *)tvi.lParam;
+ hContact = mtis->hContact;
+
+ if (mtis->type == STUB) break;
+
+ if (populating) Select = 0;
+
+ if (mtis->type == MODULE || mtis->type == UNKNOWN_MODULE)
+ {
+ SettingListInfo *info = (SettingListInfo*)GetWindowLongPtr(hwnd2Settings,GWLP_USERDATA);
+ BOOL refresh = 1;
+
+ if (info)
+ {
+ if (info->hContact == hContact &&
+ !mir_strcmp(info->module, text))
+ refresh = 0;
+ }
+
+ if (refresh)
+ PopulateSettings(hwnd2Settings, hContact, text);
+ }
+ else
+ if (((mtis->type & CONTACT) == CONTACT && hContact) ||
+ (mtis->type == CONTACT_ROOT_ITEM && !hContact))
+ {
+ char data[32], szProto[256];
+ int index, loaded, multi = 0;
+ LVITEM lvi = {0};
+ lvi.mask = LVIF_IMAGE|LVIF_TEXT|LVIF_PARAM;
+ lvi.iImage = 6;
+
+ ClearListview(hwnd2Settings);
+ SetWindowLongPtr(hwnd2Settings,GWLP_USERDATA, (LONG)NULL);
+ if (himl2) ListView_SetImageList(hwnd2Settings, himl2, LVSIL_SMALL);
+
+ if (mtis->type == CONTACT_ROOT_ITEM && !hContact)
+ {
+ multi = 1;
+ hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ }
+
+ while(hContact && hwnd2mainWindow)
+ {
+ if (multi)
+ {
+ // filter
+ if (GetValue(hContact,"Protocol","p",szProto,SIZEOF(szProto)))
+ loaded = IsProtocolLoaded(szProto);
+ else
+ loaded = 0;
+
+ if ((loaded && Mode == MODE_UNLOADED) || (!loaded && Mode == MODE_LOADED))
+ {
+ hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0);
+ continue;
+ }
+ }
+
+ lvi.iItem = 0;
+ lvi.pszText = (char*)GetContactName(hContact,NULL,UOS);
+
+ if (UOS)
+ index = ListView_InsertItemW(hwnd2Settings,&lvi);
+ else
+ index = ListView_InsertItem(hwnd2Settings,&lvi);
+
+ mir_snprintf(data, SIZEOF(data), "0x%08X (%ld)", hContact, hContact);
+
+ ListView_SetItemText(hwnd2Settings,index,1,data);
+ ListView_SetItemText(hwnd2Settings,index,2,Translate("HANDLE"));
+ ListView_SetItemText(hwnd2Settings,index,3,"0x0004 (4)");
+
+ if (!multi) break;
+
+ hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0);
+ }
+
+ }
+ else
+ ClearListview(hwnd2Settings);
+ }
+ else
+ {
+ // clear any settings that may be there...
+ ClearListview(hwnd2Settings);
+ }
+ }
+ break; //TVN_SELCHANGED:
+ case NM_RCLICK:
+ if (((NMHDR*)lParam)->code == NM_RCLICK)
+ moduleListRightClick(hwnd,wParam,lParam);
+ break;
+ case TVN_BEGINLABELEDITA: // subclass it..
+ case TVN_BEGINLABELEDITW:
+ {
+ LPNMTVDISPINFO ptvdi = (LPNMTVDISPINFO) lParam;
+ ModuleTreeInfoStruct *mtis = (ModuleTreeInfoStruct *)ptvdi->item.lParam;
+ HWND hwnd2Edit = TreeView_GetEditControl(GetDlgItem(hwnd, IDC_MODULES));
+ if (!mtis->type || (mtis->type == CONTACT))
+ {
+ SetWindowLongPtr(hwnd, DWLP_MSGRESULT, TRUE);
+ break;
+ }
+ ModuleTreeLabelEditSubClass = (WNDPROC)SetWindowLongPtr(hwnd2Edit, GWLP_WNDPROC, (LONG)ModuleTreeLabelEditSubClassProc);
+ SetWindowLongPtr(hwnd, DWLP_MSGRESULT, FALSE);
+ }
+ break;
+ case TVN_ENDLABELEDITA:
+ case TVN_ENDLABELEDITW:
+ {
+ LPNMTVDISPINFO ptvdi = (LPNMTVDISPINFO) lParam;
+ TVITEM tvi = {0};
+ char text[264];
+ char *newtext;
+ ModuleTreeInfoStruct *mtis;
+ tvi.mask=TVIF_HANDLE|TVIF_TEXT|TVIF_PARAM;
+ tvi.hItem=ptvdi->item.hItem;
+ tvi.pszText = text;
+ tvi.cchTextMax = 264;
+ TreeView_GetItem(((LPNMHDR)lParam)->hwndFrom,&tvi);
+ mtis = (ModuleTreeInfoStruct *)ptvdi->item.lParam;
+
+ if (UOS)
+ newtext = u2a((WCHAR*)ptvdi->item.pszText);
+ else
+ newtext = mir_tstrdup(ptvdi->item.pszText);
+
+ if (!newtext || // edit control failed
+ !mtis->type || // its a root item
+ mtis->type == CONTACT || // its a contact
+ *newtext == 0) // empty string
+ SetWindowLongPtr(hwnd, DWLP_MSGRESULT, FALSE);
+ else
+ {
+ if (mir_strcmp(tvi.pszText, newtext))
+ {
+ renameModule(tvi.pszText, newtext, mtis->hContact);
+
+ findAndRemoveDuplicates(((LPNMHDR)lParam)->hwndFrom,mtis->hContact,newtext);
+
+ if (TreeView_GetItem(((LPNMHDR)lParam)->hwndFrom,&tvi))
+ {
+ tvi.mask = TVIF_IMAGE|TVIF_SELECTEDIMAGE;
+ if (!IsModuleKnown(newtext))
+ {
+ tvi.iImage = 5;
+ tvi.iSelectedImage = 6;
+ }
+ else
+ {
+ tvi.iImage = 1;
+ tvi.iSelectedImage = 2;
+ }
+ TreeView_SetItem(((LPNMHDR)lParam)->hwndFrom, &tvi);
+
+ PopulateSettings(GetDlgItem(hwnd, IDC_SETTINGS), mtis->hContact, newtext);
+ }
+ }
+ SetWindowLongPtr(hwnd, DWLP_MSGRESULT, TRUE);
+ }
+
+ mir_free(newtext);
+ }
+ break;
+ }
+}
+
+void moduleListRightClick(HWND hwnd, WPARAM wParam,LPARAM lParam) // hwnd here is to the main window, NOT the treview
+{
+ TVHITTESTINFO hti;
+ hti.pt.x=(short)LOWORD(GetMessagePos());
+ hti.pt.y=(short)HIWORD(GetMessagePos());
+ ScreenToClient(((LPNMHDR)lParam)->hwndFrom,&hti.pt);
+
+ if(TreeView_HitTest(((LPNMHDR)lParam)->hwndFrom,&hti))
+ {
+ if(hti.flags&TVHT_ONITEM)
+ {
+ TVITEM tvi = {0};
+ HMENU hMenu,hSubMenu;
+ int menuNumber;
+ char module[256];
+ tvi.mask=TVIF_HANDLE|TVIF_PARAM|TVIF_TEXT;
+ tvi.hItem=hti.hItem;
+ tvi.pszText = module;
+ tvi.cchTextMax = 255;
+ TreeView_GetItem(((LPNMHDR)lParam)->hwndFrom,&tvi);
+ if (tvi.lParam)
+ {
+ ModuleTreeInfoStruct *mtis = (ModuleTreeInfoStruct *)tvi.lParam;
+ HANDLE hContact = mtis->hContact;
+ GetCursorPos(&(hti.pt));
+ hMenu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_CONTEXTMENU));
+ CallService(MS_LANGPACK_TRANSLATEMENU,(WPARAM)hMenu,0);
+ if (mtis->type == CONTACT && hContact) menuNumber = 2;
+ else if ((mtis->type == MODULE || mtis->type == UNKNOWN_MODULE) && !hContact) menuNumber = 1;
+ else if (mtis->type == CONTACT && !hContact) menuNumber = 3;
+ else if (mtis->type == CONTACT_ROOT_ITEM && !hContact) menuNumber = 4;
+ else if ((mtis->type == MODULE || mtis->type == UNKNOWN_MODULE) && hContact) menuNumber = 5;
+ else return;
+ hSubMenu = GetSubMenu(hMenu, menuNumber);
+
+ CallService(MS_LANGPACK_TRANSLATEMENU, (WPARAM) hSubMenu, 0);
+ switch (menuNumber)
+ {
+ case 1: // null module
+ case 5: // contact module
+ {
+ // check if we r already watching the module
+ int i;
+ int watching = 0;
+ // check if the setting is being watched and if it is then check the menu item
+ if (WatchListArray.item)
+ for (i=0; i<WatchListArray.count; i++)
+ {
+ if (WatchListArray.item[i].module && (hContact == WatchListArray.item[i].hContact) )
+ {
+ if (!mir_strcmp(module, WatchListArray.item[i].module) && !WatchListArray.item[i].setting)
+ {
+ // yes so uncheck it
+ CheckMenuItem(hSubMenu, MENU_WATCH_ITEM, MF_CHECKED|MF_BYCOMMAND);
+ watching =1;
+ break;
+ }
+ }
+ }
+ switch (TrackPopupMenu(hSubMenu, TPM_RETURNCMD, hti.pt.x, hti.pt.y, 0, hwnd, NULL))
+ {
+ case MENU_RENAME_MOD:
+ TreeView_EditLabel(GetDlgItem(hwnd, IDC_MODULES),tvi.hItem);
+ break;
+ case MENU_DELETE_MOD:
+ if (deleteModule(module, hContact, 0))
+ {
+ TreeView_DeleteItem(((LPNMHDR)lParam)->hwndFrom,hti.hItem);
+ mir_free(mtis);
+ }
+ break;
+ case MENU_COPY_MOD:
+ copyModuleMenuItem(module, hContact);
+ break;
+////////////////////////////////////////////////////////////////////// divider
+ case MENU_WATCH_ITEM:
+ if (!watching)
+ addSettingToWatchList(hContact,module,0);
+ else freeWatchListItem(i);
+ if (hwnd2watchedVarsWindow)
+ PopulateWatchedWindow(GetDlgItem(hwnd2watchedVarsWindow, IDC_VARS));
+ break;
+ case MENU_EXPORTMODULE:
+ exportDB(hContact, module);
+ break;
+ case MENU_EXPORTDB:
+ exportDB(INVALID_HANDLE_VALUE, module);
+ break;
+ case MENU_ADDKNOWN:
+ {
+ DBVARIANT dbv;
+ char *moduletemp = (char*)_alloca(strlen(module)*3);
+ unsigned int i;
+ moduletemp[0] = '\0';
+ for(i=0;i<strlen(module);i++)
+ {
+ if (module[i]==' ')
+ strcat(moduletemp,"\\ ");
+ else strncat(moduletemp,&module[i],1);
+ }
+ if (!DBGetContactSetting(NULL,modname,"CoreModules",&dbv) && dbv.type == DBVT_ASCIIZ)
+ {
+ int len = (int)strlen(dbv.pszVal) + 10 + (int)strlen(moduletemp);
+ char* temp = (char*)_alloca(len);
+ mir_snprintf(temp, len, "%s, %s", dbv.pszVal, moduletemp);
+ DBWriteContactSettingString(NULL,modname,"CoreModules",temp);
+ DBFreeVariant(&dbv);
+ }
+ else DBWriteContactSettingString(NULL,modname,"CoreModules",moduletemp);
+ RegisterSingleModule((WPARAM)module,0);
+ }
+ break;
+
+
+ }
+ }
+ break;
+ case 2: // contact
+ switch (TrackPopupMenu(hSubMenu, TPM_RETURNCMD, hti.pt.x, hti.pt.y, 0, hwnd, NULL))
+ {
+ case MENU_CLONE_CONTACT:
+ if (CloneContact(hContact))
+ refreshTree(1);
+ break;
+ case MENU_DELETE_CONTACT:
+ if (DBGetContactSettingByte(NULL,"CList", "ConfirmDelete",1))
+ {
+ char msg[1024];
+ mir_snprintf(msg, SIZEOF(msg), Translate("Are you sure you want to delete contact \"%s\"?"), module);
+ if (MessageBox(0,msg, Translate("Confirm Contact Delete"), MB_YESNO|MB_ICONEXCLAMATION) == IDYES)
+ {
+ CallService(MS_DB_CONTACT_DELETE, (WPARAM)hContact,0);
+ freeTree(((LPNMHDR)lParam)->hwndFrom,hContact);
+ TreeView_DeleteItem(((LPNMHDR)lParam)->hwndFrom,tvi.hItem);
+ }
+ }
+ else
+ {
+ CallService(MS_DB_CONTACT_DELETE, (WPARAM)hContact,0);
+ freeTree(((LPNMHDR)lParam)->hwndFrom,hContact);
+ TreeView_DeleteItem(((LPNMHDR)lParam)->hwndFrom,tvi.hItem);
+ }
+ break;
+////////////////////////////////////////////////////////////////////// divider
+ case MENU_EXPORTCONTACT:
+ exportDB(hContact, 0);
+ break;
+ case MENU_IMPORTFROMTEXT:
+ ImportSettingsMenuItem(hContact);
+ break;
+ case MENU_IMPORTFROMFILE:
+ ImportSettingsFromFileMenuItem(hContact, "");
+ break;
+////////////////////////////////////////////////////////////////////// divider
+ case MENU_ADD_MODULE:
+ {
+ HWND AddModhwnd = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_ADD_MODULE), hwnd, AddModDlgProc, (LPARAM)hContact);
+ char msg[1024];
+ mir_snprintf(msg, SIZEOF(msg), Translate("Add module to contact \"%s\""), module);
+ SetWindowText(AddModhwnd, module);
+ }
+ break;
+ }
+ break;
+ case 3: // NULL contact
+ switch (TrackPopupMenu(hSubMenu, TPM_RETURNCMD, hti.pt.x, hti.pt.y, 0, hwnd, NULL))
+ {
+ case MENU_ADD_MODULE:
+ {
+ HWND AddModhwnd = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_ADD_MODULE), hwnd, AddModDlgProc, (LPARAM)hContact);
+ char msg[1024];
+ mir_snprintf(msg, SIZEOF(msg), Translate("Add module to contact \"%s\""), module);
+ SetWindowText(AddModhwnd, module);
+ }
+ break;
+ case MENU_EXPORTCONTACT:
+ exportDB(NULL, 0);
+ break;
+ case MENU_IMPORTFROMTEXT:
+ ImportSettingsMenuItem(NULL);
+ break;
+ case MENU_IMPORTFROMFILE:
+ ImportSettingsFromFileMenuItem(NULL, "");
+ break;
+ }
+ break;
+ case 4: // Contacts root
+ switch (TrackPopupMenu(hSubMenu, TPM_RETURNCMD, hti.pt.x, hti.pt.y, 0, hwnd, NULL))
+ {
+ case MENU_EXPORTCONTACT:
+ exportDB(INVALID_HANDLE_VALUE, "");
+ break;
+ case MENU_IMPORTFROMTEXT:
+ ImportSettingsMenuItem(NULL);
+ break;
+ case MENU_IMPORTFROMFILE:
+ ImportSettingsFromFileMenuItem(NULL, "");
+ break;
+ }
+ break;
+ }
+ DestroyMenu(hMenu);
+ }
+ } // if (tvi.lParam)
+ } // if(hti.flags&TVHT_ONITEM)
+} \ No newline at end of file
diff --git a/plugins/dbeditorpp/options.cpp b/plugins/dbeditorpp/options.cpp
new file mode 100644
index 0000000000..741796ca25
--- /dev/null
+++ b/plugins/dbeditorpp/options.cpp
@@ -0,0 +1,98 @@
+#include "headers.h"
+
+INT_PTR CALLBACK DlgProcOpts(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch(msg)
+ {
+ case WM_INITDIALOG:
+ {
+ DBVARIANT dbv;
+ CheckDlgButton(hwnd,IDC_EXPANDSETTINGS,DBGetContactSettingByte(NULL,modname,"ExpandSettingsOnOpen",0));
+ CheckDlgButton(hwnd,IDC_RESTORESETTINGS,DBGetContactSettingByte(NULL,modname,"RestoreOnOpen",1));
+ CheckDlgButton(hwnd,IDC_USEKNOWNMODS,DBGetContactSettingByte(NULL,modname,"UseKnownModList",0));
+ CheckDlgButton(hwnd,IDC_WARNONDEL,DBGetContactSettingByte(NULL,modname,"WarnOnDelete",1));
+ CheckDlgButton(hwnd,IDC_MENU,DBGetContactSettingByte(NULL,modname,"UserMenuItem",0));
+ CheckDlgButton(hwnd,IDC_POPUPS,usePopUps);
+ if (!DBGetContactSetting(NULL,modname,"CoreModules",&dbv) && dbv.type == DBVT_ASCIIZ)
+ SetDlgItemText(hwnd,IDC_MODULES,dbv.pszVal);
+ DBFreeVariant(&dbv);
+ SetDlgItemInt(hwnd,IDC_POPUPTIMEOUT,DBGetContactSettingWord(NULL,modname,"PopupDelay",4),0);
+ SendDlgItemMessage(hwnd, IDC_COLOUR, CPM_SETCOLOUR, 0, (LPARAM)DBGetContactSettingDword(NULL,modname,"PopupColour",RGB(255,0,0)));
+ TranslateDialogDefault(hwnd);
+ }
+ return TRUE;
+ case WM_COMMAND:
+ switch(LOWORD(wParam))
+ {
+ case IDC_RESTORESETTINGS:
+ case IDC_EXPANDSETTINGS:
+ case IDC_USEKNOWNMODS:
+ case IDC_MODULES:
+ case IDC_MENU:
+ case IDC_POPUPS:
+ case IDC_WARNONDEL:
+ case IDC_COLOUR:
+ case IDC_POPUPTIMEOUT:
+ SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0);
+ break;
+ }
+ break;
+ case WM_NOTIFY:
+ switch(((LPNMHDR)lParam)->idFrom)
+ {
+ case 0:
+ switch (((LPNMHDR)lParam)->code)
+ {
+ case PSN_APPLY:
+ {
+ CLISTMENUITEM mi = {0};
+ char mods[4096];
+ DBWriteContactSettingByte(NULL,modname,"ExpandSettingsOnOpen",(BYTE)IsDlgButtonChecked(hwnd,IDC_EXPANDSETTINGS));
+ DBWriteContactSettingByte(NULL,modname,"RestoreOnOpen",(BYTE)IsDlgButtonChecked(hwnd,IDC_RESTORESETTINGS));
+ DBWriteContactSettingByte(NULL,modname,"WarnOnDelete",(BYTE)IsDlgButtonChecked(hwnd,IDC_WARNONDEL));
+ DBWriteContactSettingByte(NULL,modname,"UserMenuItem",(BYTE)IsDlgButtonChecked(hwnd,IDC_MENU));
+ DBWriteContactSettingByte(NULL,modname,"UseKnownModList",(BYTE)IsDlgButtonChecked(hwnd,IDC_USEKNOWNMODS));
+ usePopUps = IsDlgButtonChecked(hwnd,IDC_POPUPS);
+ DBWriteContactSettingByte(NULL,modname,"UsePopUps",(BYTE)usePopUps);
+ if (GetDlgItemText(hwnd,IDC_MODULES,mods,4096))
+ DBWriteContactSettingString(NULL,modname,"CoreModules",mods);
+ DBWriteContactSettingWord(NULL,modname,"PopupDelay",(WORD)GetDlgItemInt(hwnd,IDC_POPUPTIMEOUT,NULL,0));
+ DBWriteContactSettingDword(NULL,modname,"PopupColour",(DWORD)SendDlgItemMessage(hwnd, IDC_COLOUR, CPM_GETCOLOUR, 0, 0));
+
+ mi.cbSize = sizeof(mi);
+
+ if (!IsDlgButtonChecked(hwnd,IDC_MENU))
+ mi.flags = CMIM_FLAGS | CMIF_HIDDEN;
+ else
+ mi.flags = CMIM_FLAGS;
+
+ CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM) hUserMenu, (LPARAM) & mi);
+
+ }
+ return TRUE;
+ }
+ break;
+ }
+ break;
+ }
+ return FALSE;
+}
+
+INT OptInit(WPARAM wParam,LPARAM lParam)
+{
+ OPTIONSDIALOGPAGE odp;
+
+ ZeroMemory(&odp,sizeof(odp));
+ odp.cbSize=sizeof(odp);
+ odp.position=0;
+ odp.hInstance=hInst;
+ odp.pszTemplate=MAKEINTRESOURCE(IDD_OPTIONS);
+ odp.pszGroup= "Services";
+ odp.pszTitle= modFullname;
+ odp.pfnDlgProc = DlgProcOpts;
+ odp.flags = ODPF_BOLDGROUPS;
+ odp.expertOnlyControls=NULL;
+ CallService(MS_OPT_ADDPAGE,wParam,(LPARAM)&odp);
+
+ return 0;
+} \ No newline at end of file
diff --git a/plugins/dbeditorpp/resource.h b/plugins/dbeditorpp/resource.h
new file mode 100644
index 0000000000..9e40bcf899
--- /dev/null
+++ b/plugins/dbeditorpp/resource.h
@@ -0,0 +1,156 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by resource.rc
+//
+#define ICO_REGEDIT 1
+#define ICO_UNICODE 2
+#define ICO_DBE_BUTT 3
+#define ICO_REGUSER 4
+#define ICO_STRING 5
+#define ICO_BINARY 6
+#define ICO_DWORD 7
+#define ICO_BYTE 8
+#define ICO_WORD 9
+#define ICO_HANDLE 10
+#define IDD_MAIN 101
+#define IDR_MAINMENU 103
+#define IDR_CONTEXTMENU 104
+#define ICO_CONTACTS 106
+#define ICO_OFFLINE 107
+#define IDD_ADD_MODULE 108
+#define IDD_EDIT_SETTING 109
+#define IDD_WATCH_DIAG 110
+#define IDR_WATCHWINDOWMENU 112
+#define ICO_UNLOADED 115
+#define IDD_COPY_MOD 116
+#define IDD_IMPORT 118
+#define IDD_CHANGE_ARRAYSIZE 120
+#define IDD_FIND 121
+#define IDD_OPTIONS 122
+#define ICO_KNOWN 124
+#define ICO_KNOWNOPEN 125
+#define ICO_UNKNOWNOPEN 126
+#define ICO_UNKNOWN 127
+#define ICO_SETTINGS 128
+#define ICO_ONLINE 129
+#define IDC_MODULES 1000
+#define IDC_SETTINGS 1001
+#define IDC_MENU 1002
+#define IDC_MODNAME 1004
+#define CHK_ADD2ALL 1005
+#define IDC_MODNAME2 1005
+#define IDC_SETTINGNAME 1006
+#define IDC_SPLITTER 1006
+#define IDC_STRING 1007
+#define IDC_SETTINGNAME2 1007
+#define GRP_BASE 1008
+#define CHK_HEX 1009
+#define CHK_DECIMAL 1010
+#define IDC_SETTINGVALUE 1011
+#define GRP_TYPE 1012
+#define IDC_SETTINGVALUE2 1012
+#define CHK_BYTE 1013
+#define IDC_SETTINGVALUE3 1013
+#define CHK_WORD 1014
+#define CHK_DWORD 1015
+#define CHK_STRING 1016
+#define IDC_VARS 1017
+#define IDC_ADDMODNAMESTATIC 1020
+#define IDC_CONTACTS 1021
+#define CHK_COPY2ALL 1022
+#define IDC_TEXT 1025
+#define IDC_FIND 1026
+#define IDC_REPLACE 1027
+#define IDC_CASE_SENSITIVE 1027
+#define IDC_REQUIRED 1028
+#define IDC_ARRAYSIZE 1030
+#define IDC_CURRENTSIZE 1032
+#define IDC_INFOTEXT 1033
+#define IDC_CRLF 1035
+#define IDC_CASESENSITIVE 1040
+#define IDC_LIST 1041
+#define IDC_SEARCH 1042
+#define IDC_EXACT 1043
+#define IDC_EXPANDSETTINGS 1044
+#define IDC_USEKNOWNMODS 1045
+#define IDC_WARNONDEL 1047
+#define IDC_POPUPS 1048
+#define IDC_POPUPTIMEOUT 1049
+#define IDC_COLOUR 1050
+#define IDC_RESTORESETTINGS 1051
+#define IDC_BLOB 1052
+#define IDC_FOUND 1056
+#define IDC_SBAR 1057
+#define IDC_ENTIRELY 1058
+#define MENU_REFRESH_MODS 40001
+#define MENU_REFRESH_SETS 40002
+#define MENU_EXIT 40003
+#define MENU_CHANGE2UNICODE 40004
+#define MENU_ADD_UNICODE 40005
+#define MENU_RENAME_SET 40006
+#define MENU_EDIT_SET 40007
+#define MENU_CHANGE2BYTE 40008
+#define MENU_CHANGE2WORD 40009
+#define MENU_CHANGE2DWORD 40010
+#define MENU_CHANGE2STRING 40011
+#define MENU_DELETE_SET 40012
+#define MENU_DELETE_MOD 40013
+#define MENU_CREATE_MOD 40014
+#define MENU_VIEW_WATCHES 40016
+#define MENU_REMALL_WATCHES 40017
+#define MENU_ADD_WATCH 40018
+#define MENU_WATCH_ITEM 40018
+#define MENU_WATCH_MOD 40019
+#define MENU_ADD_BLOB 40020
+#define MENU_CLONE_CONTACT 40021
+#define MENU_DELETE_CONTACT 40022
+#define MENU_ADD_MODULE 40023
+#define MENU_ADD_BYTE 40024
+#define MENU_ADD_WORD 40025
+#define MENU_ADD_DWORD 40026
+#define MENU_ADD_STRING 40027
+#define MENU_SAVE_WATCHES 40028
+#define MENU_RENAME_MOD 40030
+#define MENU_COPY_MOD 40032
+#define MENU_USE_MODLIST 40033
+#define MENU_USE_POPUPS 40034
+#define MENU_SORT_ORDER 40035
+#define MENU_EXPORTDB 40036
+#define MENU_EXPORTMODULE 40037
+#define MENU_EXPORTCONTACT 40038
+#define MENU_SAVE_POSITION 40039
+#define MENU_IMPORTSETTINGS 40040
+#define MENU_ADDCONTACT 40041
+#define MENU_WARNONDEL 40042
+#define MENU_LOAD_WATCHES 40043
+#define MENU_WORD_HEX 40044
+#define MENU_DECRYPT 40045
+#define MENU_ENCRYPT 40046
+#define MENU_VIEWDECRYPT 40047
+#define MENU_VIEWENCRYPT 40048
+#define MENU_LOGTODISK 40049
+#define MENU_FINDANDREPLACE 40050
+#define MENU_FINDMODSETTING 40051
+#define MENU_DWORD_HEX 40052
+#define MENU_IMPORTFROMFILE 40053
+#define MENU_IMPORTFROMTEXT 40054
+#define MENU_CHANGEARRAYSIZE 40055
+#define MENU_OPTIONS 40056
+#define MENU_DELETE 40057
+#define MENU_REFRESH 40058
+#define MENU_ADDKNOWN 40059
+#define MENU_FILTER_ALL 40060
+#define MENU_FILTER_LOADED 40061
+#define MENU_FILTER_UNLOADED 40062
+#define MENU_BYTE_HEX 40063
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 131
+#define _APS_NEXT_COMMAND_VALUE 40064
+#define _APS_NEXT_CONTROL_VALUE 1059
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/plugins/dbeditorpp/resource.rc b/plugins/dbeditorpp/resource.rc
new file mode 100644
index 0000000000..12e527dad0
--- /dev/null
+++ b/plugins/dbeditorpp/resource.rc
@@ -0,0 +1,515 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Àíãëèéñêèé (ÑØÀ) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_FIND DIALOGEX 0, 0, 340, 249
+STYLE DS_SETFONT | DS_SETFOREGROUND | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
+CAPTION "Database Editor++ Search and Replace"
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+ EDITTEXT IDC_TEXT,40,13,216,12,ES_AUTOHSCROLL
+ CONTROL "Case Sensitive",IDC_CASESENSITIVE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,40,30,72,10
+ CONTROL "Module Name",IDC_MODNAME,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,40,44,73,10
+ CONTROL "Exact Match",IDC_EXACT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,115,30,64,10
+ CONTROL "Setting Name",IDC_SETTINGNAME,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,115,44,72,10
+ CONTROL "Setting Value",IDC_SETTINGVALUE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,194,44,69,10
+ DEFPUSHBUTTON "&Search",IDC_SEARCH,277,5,60,14
+ EDITTEXT IDC_REPLACE,40,72,216,12,ES_AUTOHSCROLL
+ CONTROL "Module Name",IDC_MODNAME2,"Button",BS_AUTORADIOBUTTON | NOT WS_VISIBLE | WS_DISABLED | WS_GROUP | WS_TABSTOP,40,90,73,10
+ CONTROL "Setting Name",IDC_SETTINGNAME2,"Button",BS_AUTORADIOBUTTON | NOT WS_VISIBLE | WS_DISABLED | WS_TABSTOP,115,90,72,10
+ CONTROL "Setting Value",IDC_SETTINGVALUE2,"Button",BS_AUTORADIOBUTTON | NOT WS_VISIBLE | WS_DISABLED | WS_TABSTOP,194,90,67,10
+ CONTROL "Found field",IDC_FOUND,"Button",BS_AUTORADIOBUTTON | NOT WS_VISIBLE | WS_TABSTOP,267,90,65,10
+ PUSHBUTTON "&Replace",IDOK,277,25,60,14
+ PUSHBUTTON "&Cancel",IDCANCEL,277,45,60,14
+ LISTBOX IDC_LIST,3,95,334,136,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_HSCROLL | WS_TABSTOP
+ GROUPBOX "Search For",IDC_STATIC,3,1,268,58
+ LTEXT "Text:",IDC_STATIC,10,15,26,8
+ LTEXT "In:",IDC_STATIC,10,30,23,8
+ GROUPBOX "Replace With",IDC_STATIC,3,60,334,30
+ LTEXT "Text:",IDC_STATIC,10,74,26,8
+ LTEXT "In:",IDC_STATIC,10,90,23,8,NOT WS_VISIBLE
+ CONTROL "",IDC_SBAR,"msctls_statusbar32",WS_TABSTOP | 0x100,3,237,334,12
+ CONTROL "Entirely",IDC_ENTIRELY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,262,74,67,10
+END
+
+IDD_OPTIONS DIALOGEX 0, 0, 314, 239
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_CHILD | WS_VISIBLE
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+ CONTROL "Restore last opened position",IDC_RESTORESETTINGS,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,13,283,10
+ CONTROL "Automatically expand ""settings"" when Database Editor ++ starts",IDC_EXPANDSETTINGS,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,26,283,10
+ CONTROL "Use known modules list",IDC_USEKNOWNMODS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,39,253,10
+ CONTROL "Warn when deleting modules",IDC_WARNONDEL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,52,280,10
+ CONTROL """Open user tree in DBE++"" menu item",IDC_MENU,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,65,280,10
+ CONTROL "Use popups when watched settings change values",IDC_POPUPS,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,78,275,10
+ EDITTEXT IDC_POPUPTIMEOUT,144,89,20,12,ES_NUMBER
+ CONTROL "",IDC_COLOUR,"ColourPicker",WS_TABSTOP,257,89,26,12
+ EDITTEXT IDC_MODULES,12,140,288,46,ES_MULTILINE | ES_AUTOVSCROLL | ES_WANTRETURN | WS_VSCROLL
+ GROUPBOX "Modules to ALWAYS mark as known (e.g core modules)",IDC_STATIC,7,105,300,96
+ LTEXT "Put a space or comma between each module name",IDC_STATIC,12,116,286,8
+ LTEXT "Changes to this list will take effect next time miranda starts",IDC_STATIC,12,189,284,8
+ RTEXT "Popup timeout (0 for infinite)",IDC_STATIC,35,91,103,8
+ RTEXT "Background Colour",IDC_STATIC,177,91,77,8
+ LTEXT "If the module name has a space in it, put a \\ before the space. eg ""aaa\\ bbb""",IDC_STATIC,12,127,286,8
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+ IDD_FIND, DIALOG
+ BEGIN
+ LEFTMARGIN, 3
+ RIGHTMARGIN, 337
+ VERTGUIDE, 10
+ VERTGUIDE, 40
+ VERTGUIDE, 115
+ VERTGUIDE, 194
+ VERTGUIDE, 277
+ TOPMARGIN, 7
+ HORZGUIDE, 18
+ HORZGUIDE, 35
+ HORZGUIDE, 48
+ HORZGUIDE, 68
+ HORZGUIDE, 95
+ END
+
+ IDD_OPTIONS, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 307
+ VERTGUIDE, 12
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 232
+ HORZGUIDE, 68
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+ICO_KNOWN ICON "res\\Yellow.ico"
+ICO_KNOWNOPEN ICON "res\\Yellow_open.ico"
+ICO_UNKNOWNOPEN ICON "res\\Red_open.ico"
+ICO_UNKNOWN ICON "res\\Red.ico"
+ICO_SETTINGS ICON "res\\Icon_4.ico"
+ICO_ONLINE ICON "res\\online2.ico"
+#endif // Àíãëèéñêèé (ÑØÀ) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Àíãëèéñêèé (Àâñòðàëèÿ) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENA)
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_AUS
+#pragma code_page(1252)
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_ADD_MODULE DIALOGEX 0, 0, 186, 67
+STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+CAPTION "Add a module to contact"
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+ EDITTEXT IDC_MODNAME,7,17,172,12,ES_AUTOHSCROLL
+ LTEXT "Add a module named",IDC_ADDMODNAMESTATIC,7,6,124,8
+ CONTROL "Add to all contacts (Includes Settings)",CHK_COPY2ALL,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,35,172,10
+ DEFPUSHBUTTON "OK",IDOK,29,49,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,107,49,50,14
+END
+
+IDD_EDIT_SETTING DIALOGEX 0, 0, 252, 121
+STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION
+CAPTION "Edit Setting"
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+ EDITTEXT IDC_SETTINGNAME,7,18,238,14,ES_AUTOHSCROLL
+ EDITTEXT IDC_SETTINGVALUE,7,49,159,14,ES_AUTOHSCROLL
+ EDITTEXT IDC_STRING,49,37,196,61,ES_MULTILINE | ES_WANTRETURN | NOT WS_VISIBLE | WS_VSCROLL | WS_HSCROLL
+ EDITTEXT IDC_BLOB,49,37,196,61,ES_MULTILINE | NOT WS_VISIBLE | WS_VSCROLL
+ RADIOBUTTON "Byte",CHK_BYTE,13,81,30,10
+ RADIOBUTTON "Word",CHK_WORD,50,81,33,10
+ RADIOBUTTON "Dword",CHK_DWORD,90,81,37,10
+ RADIOBUTTON "String",CHK_STRING,132,81,34,10
+ DEFPUSHBUTTON "OK",IDOK,70,102,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,132,102,50,14
+ RADIOBUTTON "Hexadecimal",CHK_HEX,182,49,57,10
+ RADIOBUTTON "Decimal",CHK_DECIMAL,182,62,41,10
+ LTEXT "Value Name:",IDC_STATIC,7,7,42,8
+ LTEXT "Value Data:",IDC_STATIC,7,37,38,8
+ GROUPBOX "Base",GRP_BASE,174,37,71,38
+ GROUPBOX "Save Value as:",GRP_TYPE,7,67,160,29
+END
+
+IDD_WATCH_DIAG DIALOGEX 0, 0, 414, 190
+STYLE DS_SETFONT | DS_SETFOREGROUND | DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
+CAPTION "Watched Database Variables"
+MENU IDR_WATCHWINDOWMENU
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+ CONTROL "List1",IDC_VARS,"SysListView32",LVS_REPORT | LVS_SHOWSELALWAYS | LVS_SORTDESCENDING | LVS_SHAREIMAGELISTS | LVS_AUTOARRANGE | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,0,0,414,190
+END
+
+IDD_COPY_MOD DIALOGEX 0, 0, 186, 67
+STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+CAPTION "Copy module to contact"
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+ COMBOBOX IDC_CONTACTS,7,17,172,99,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP
+ CONTROL "Copy to all contacts (Includes Settings)",CHK_COPY2ALL,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,35,172,10
+ DEFPUSHBUTTON "OK",IDOK,29,49,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,107,49,50,14
+ LTEXT "Contact to copy module and settings to",IDC_INFOTEXT,7,6,124,8
+END
+
+IDD_IMPORT DIALOGEX 0, 0, 268, 170
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+CAPTION "Import Module/Settings"
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+ EDITTEXT IDC_TEXT,7,18,254,124,ES_MULTILINE | ES_WANTRETURN | WS_VSCROLL | WS_HSCROLL
+ DEFPUSHBUTTON "Import",IDOK,153,149,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,211,149,50,14
+ PUSHBUTTON "Insert &CR/LF",IDC_CRLF,20,149,58,14
+ LTEXT "Paste the Settings to import here.",IDC_STATIC,7,7,105,8
+END
+
+IDD_MAIN DIALOGEX 0, 0, 408, 225
+STYLE DS_ABSALIGN | DS_SETFONT | DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
+CAPTION "DBEditor++"
+MENU IDR_MAINMENU
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+ CONTROL "Tree1",IDC_MODULES,"SysTreeView32",TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | TVS_EDITLABELS | TVS_DISABLEDRAGDROP | TVS_SHOWSELALWAYS | WS_BORDER | WS_HSCROLL | WS_TABSTOP,0,3,102,222
+ CONTROL "List1",IDC_SETTINGS,"SysListView32",LVS_REPORT | LVS_SHOWSELALWAYS | LVS_SORTASCENDING | LVS_SHAREIMAGELISTS | WS_BORDER | WS_TABSTOP,103,3,305,222
+ CONTROL "",IDC_SPLITTER,"Static",SS_ENHMETAFILE,102,3,1,222
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+ IDD_ADD_MODULE, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 63
+ END
+
+ IDD_EDIT_SETTING, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 245
+ VERTGUIDE, 166
+ VERTGUIDE, 174
+ VERTGUIDE, 182
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 116
+ HORZGUIDE, 37
+ HORZGUIDE, 49
+ HORZGUIDE, 67
+ HORZGUIDE, 75
+ HORZGUIDE, 81
+ END
+
+ IDD_COPY_MOD, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 179
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 63
+ END
+
+ IDD_IMPORT, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 261
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 163
+ END
+
+ IDD_MAIN, DIALOG
+ BEGIN
+ VERTGUIDE, 102
+ VERTGUIDE, 103
+ TOPMARGIN, 3
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+ICO_REGEDIT ICON "res\\Icon_1.ico"
+ICO_DBE_BUTT ICON "res\\dbepp.ico"
+ICO_REGUSER ICON "res\\usermenu.ico"
+ICO_STRING ICON "res\\Icon_14.ico"
+ICO_CONTACTS ICON "res\\Contacts.ico"
+ICO_BINARY ICON "res\\Icon_15.ico"
+ICO_DWORD ICON "res\\Icon_16.ico"
+ICO_BYTE ICON "res\\Icon_17.ico"
+ICO_WORD ICON "res\\Icon_18.ico"
+ICO_OFFLINE ICON "res\\offline2.ico"
+ICO_UNICODE ICON "res\\unicode.ico"
+ICO_HANDLE ICON "res\\handle.ico"
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Menu
+//
+
+IDR_MAINMENU MENU
+BEGIN
+ POPUP "&Main"
+ BEGIN
+ MENUITEM "&Refresh Modules", MENU_REFRESH_MODS
+ MENUITEM "Refresh &Settings", MENU_REFRESH_SETS
+ MENUITEM SEPARATOR
+ MENUITEM "E&xit", MENU_EXIT
+ END
+ POPUP "&Actions"
+ BEGIN
+ MENUITEM "&Search and Replace", MENU_FINDANDREPLACE
+ MENUITEM SEPARATOR
+ MENUITEM "&Delete Module", MENU_DELETE
+ END
+ POPUP "&Watches"
+ BEGIN
+ MENUITEM "&View all", MENU_VIEW_WATCHES
+ MENUITEM "&Delete all", MENU_REMALL_WATCHES
+ END
+ POPUP "&Export"
+ BEGIN
+ MENUITEM "Entire &Database", MENU_EXPORTDB
+ MENUITEM "All &Settings", MENU_EXPORTMODULE
+ MENUITEM "All &Contacts", MENU_EXPORTCONTACT
+ END
+ POPUP "&Import"
+ BEGIN
+ MENUITEM "From a &file", MENU_IMPORTFROMFILE
+ MENUITEM "From pasted &text", MENU_IMPORTFROMTEXT
+ END
+ POPUP "&Options"
+ BEGIN
+ MENUITEM "&Sort by protocol", MENU_SORT_ORDER
+ MENUITEM SEPARATOR
+ MENUITEM "Show &All", MENU_FILTER_ALL
+ MENUITEM "Show only &Loaded", MENU_FILTER_LOADED
+ MENUITEM "Show only &Unloaded", MENU_FILTER_UNLOADED
+ MENUITEM SEPARATOR
+ MENUITEM "Edit &Bytes in Hex", MENU_BYTE_HEX
+ MENUITEM "Edit &Words in Hex", MENU_WORD_HEX
+ MENUITEM "Edit &Dwords in Hex", MENU_DWORD_HEX
+ MENUITEM SEPARATOR
+ MENUITEM "&Restore position", MENU_SAVE_POSITION
+ END
+END
+
+IDR_CONTEXTMENU MENU
+BEGIN
+ POPUP "Item context"
+ BEGIN
+ MENUITEM "&Edit / Rename", MENU_EDIT_SET
+ MENUITEM SEPARATOR
+ POPUP "NEW"
+ BEGIN
+ MENUITEM "&Byte", MENU_ADD_BYTE
+ MENUITEM "&Word", MENU_ADD_WORD
+ MENUITEM "&Dword", MENU_ADD_DWORD
+ MENUITEM "&String", MENU_ADD_STRING
+ MENUITEM "&Unicode", MENU_ADD_UNICODE
+ MENUITEM "BL&OB", MENU_ADD_BLOB
+ END
+ POPUP "&Convert to"
+ BEGIN
+ MENUITEM "&Byte", MENU_CHANGE2BYTE
+ MENUITEM "&Word", MENU_CHANGE2WORD
+ MENUITEM "&Dword", MENU_CHANGE2DWORD
+ MENUITEM "&String", MENU_CHANGE2STRING
+ MENUITEM "&Unicode", MENU_CHANGE2UNICODE
+ END
+ POPUP "Encyption"
+ BEGIN
+ MENUITEM "View Decrypted String", MENU_VIEWDECRYPT
+ MENUITEM "View Encrypted String", MENU_VIEWENCRYPT
+ MENUITEM "Decrypt String", MENU_DECRYPT
+ MENUITEM "Encrypt String", MENU_ENCRYPT
+ END
+ MENUITEM SEPARATOR
+ MENUITEM "&Watch", MENU_WATCH_ITEM
+ MENUITEM "&Delete", MENU_DELETE_SET
+ END
+ POPUP "Null Mod context"
+ BEGIN
+ MENUITEM "&Rename", MENU_RENAME_MOD
+ MENUITEM "Copy To Contact", MENU_COPY_MOD
+ MENUITEM SEPARATOR
+ MENUITEM "Export Module", MENU_EXPORTMODULE
+ MENUITEM "Add To Known Modules", MENU_ADDKNOWN
+ MENUITEM SEPARATOR
+ MENUITEM "&Watch", MENU_WATCH_ITEM
+ MENUITEM "&Delete", MENU_DELETE_MOD
+ END
+ POPUP "Contact menu"
+ BEGIN
+ MENUITEM "&Clone", MENU_CLONE_CONTACT
+ MENUITEM "&Delete", MENU_DELETE_CONTACT
+ MENUITEM SEPARATOR
+ MENUITEM "Export Contact", MENU_EXPORTCONTACT
+ POPUP "Import Settings"
+ BEGIN
+ MENUITEM "From a file", MENU_IMPORTFROMFILE
+ MENUITEM "From pasted text", MENU_IMPORTFROMTEXT
+ END
+ MENUITEM SEPARATOR
+ MENUITEM "&Add Module", MENU_ADD_MODULE
+ END
+ POPUP "NULL contact menu"
+ BEGIN
+ MENUITEM "&Add Module", MENU_ADD_MODULE
+ MENUITEM "Export Settings", MENU_EXPORTCONTACT
+ POPUP "Import Settings"
+ BEGIN
+ MENUITEM "From a file", MENU_IMPORTFROMFILE
+ MENUITEM "From pasted text", MENU_IMPORTFROMTEXT
+ END
+ END
+ POPUP "Contacts menu"
+ BEGIN
+ MENUITEM "Export Contacts", MENU_EXPORTCONTACT
+ POPUP "Import Contacts"
+ BEGIN
+ MENUITEM "From a file", MENU_IMPORTFROMFILE
+ MENUITEM "From pasted text", MENU_IMPORTFROMTEXT
+ END
+ END
+ POPUP "Contact Mod context"
+ BEGIN
+ MENUITEM "&Rename", MENU_RENAME_MOD
+ MENUITEM "Copy To Contact", MENU_COPY_MOD
+ MENUITEM SEPARATOR
+ MENUITEM "Export Module", MENU_EXPORTMODULE
+ MENUITEM "Export Module from all contacts", MENU_EXPORTDB
+ MENUITEM "Add To Known Modules", MENU_ADDKNOWN
+ MENUITEM SEPARATOR
+ MENUITEM "&Watch", MENU_WATCH_ITEM
+ MENUITEM "&Delete", MENU_DELETE_MOD
+ END
+ POPUP "new item"
+ BEGIN
+ POPUP "NEW"
+ BEGIN
+ MENUITEM "&Byte", MENU_ADD_BYTE
+ MENUITEM "&Word", MENU_ADD_WORD
+ MENUITEM "&Dword", MENU_ADD_DWORD
+ MENUITEM "&String", MENU_ADD_STRING
+ MENUITEM "&Unicode", MENU_ADD_UNICODE
+ MENUITEM "BL&OB", MENU_ADD_BLOB
+ END
+ END
+END
+
+IDR_WATCHWINDOWMENU MENU
+BEGIN
+ POPUP "Watch Window"
+ BEGIN
+ MENUITEM "Reload Watch List", MENU_REFRESH
+ MENUITEM "&Delete all", MENU_REMALL_WATCHES
+ MENUITEM SEPARATOR
+ MENUITEM "E&xit", MENU_EXIT
+ END
+END
+
+#endif // Àíãëèéñêèé (Àâñòðàëèÿ) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/plugins/dbeditorpp/settinglist.cpp b/plugins/dbeditorpp/settinglist.cpp
new file mode 100644
index 0000000000..9225fe04a8
--- /dev/null
+++ b/plugins/dbeditorpp/settinglist.cpp
@@ -0,0 +1,1261 @@
+#include "headers.h"
+
+int UOS;
+
+void setupSettingsList(HWND hwnd2List)
+{
+ LVCOLUMN sLC;
+
+ ListView_SetUnicodeFormat(hwnd2List, UOS);
+
+ sLC.fmt = LVCFMT_LEFT;
+ ListView_SetExtendedListViewStyle(hwnd2List, 32|LVS_EX_SUBITEMIMAGES); //LVS_EX_FULLROWSELECT
+ sLC.mask = LVCF_FMT | LVCF_TEXT | LVCF_SUBITEM | LVCF_WIDTH;
+
+ sLC.pszText = Translate("Name");
+ sLC.cx = DBGetContactSettingWord(NULL, modname, "Column0width", 145);
+ ListView_InsertColumn(hwnd2List,0,&sLC);
+ sLC.pszText = Translate("Data");
+ sLC.cx = DBGetContactSettingWord(NULL, modname, "Column1width", 145);
+ ListView_InsertColumn(hwnd2List,1,&sLC);
+ sLC.pszText = Translate("Type");
+ sLC.cx = DBGetContactSettingWord(NULL, modname, "Column2width", 60);
+ ListView_InsertColumn(hwnd2List,2,&sLC);
+ sLC.pszText = Translate("Size");
+ sLC.cx = DBGetContactSettingWord(NULL, modname, "Column3width", 80);
+ ListView_InsertColumn(hwnd2List,3,&sLC);
+}
+
+
+void saveListSettings(HWND hwnd2List)
+{
+ int i;
+ LVCOLUMN sLC = {0};
+ char tmp[33]; tmp[32] = 0;
+
+ sLC.mask = LVCF_WIDTH;
+
+ for (i=0; i <= 3; i++)
+ if (ListView_GetColumn(hwnd2List,i,&sLC))
+ {
+ mir_snprintf(tmp, SIZEOF(tmp), "Column%dwidth", i);
+ DBWriteContactSettingWord(NULL, modname, tmp, (WORD)sLC.cx);
+ }
+
+}
+
+
+void ClearListview(HWND hwnd2Settings)
+{
+ SettingListInfo *info = (SettingListInfo*)GetWindowLongPtr(hwnd2Settings,GWLP_USERDATA);
+ if (info && ListView_GetItemCount(hwnd2Settings))
+ {
+ mir_free(info->module);
+ if (info->hwnd2Edit)
+ {
+ SendMessage(info->hwnd2Edit,WM_COMMAND,MAKEWPARAM(IDCANCEL,0),0);
+ info->hwnd2Edit = NULL;
+ }
+ mir_free(info);
+ SetWindowLongPtr(hwnd2Settings,GWLP_USERDATA, 0);
+ }
+ ListView_DeleteAllItems(hwnd2Settings);
+}
+
+void DeleteSettingsFromList(HWND hSettings, HANDLE hContact, char *module, char *setting)
+{
+ int count = ListView_GetSelectedCount(hSettings);
+
+ if (!count) return;
+ else
+ if (count == 1)
+ {
+ DBDeleteContactSetting(hContact,module,setting);
+ }
+ else
+ {
+ int items = ListView_GetItemCount(hSettings);
+ int i = 0;
+ char text[256];
+
+ while(i<items)
+ {
+ if (ListView_GetItemState(hSettings,i,LVIS_SELECTED))
+ {
+ ListView_GetItemText(hSettings, i, 0, text, SIZEOF(text));
+ DBDeleteContactSetting(hContact,module,text);
+ items--;
+ }
+ else
+ i++;
+ }
+
+ }
+ if (ListView_GetItemCount(hSettings) == 0)
+ {
+ HWND hModules = GetDlgItem(hwnd2mainWindow,IDC_MODULES);
+ TVITEM item;
+ char text[265];
+ item.mask = TVIF_PARAM|TVIF_TEXT;
+ item.pszText = text;
+ item.cchTextMax = 264;
+ item.hItem = (HTREEITEM)findItemInTree(hModules, hContact, module);
+ if ((int)item.hItem != -1)
+ if (TreeView_GetItem(hModules, &item) && item.lParam)
+ {
+ mir_free((char*)item.lParam);
+ TreeView_DeleteItem(hModules,item.hItem);
+ }
+ }
+}
+
+
+void additem(HWND hwnd2Settings,HANDLE hContact, char* module, char* setting, int index)
+{
+ DBVARIANT dbv = {0};
+ char *data = NULL;
+ LVITEM lvi;
+ lvi.mask = LVIF_IMAGE;
+ lvi.iItem = index;
+ lvi.iSubItem = 0;
+
+ if (!GetSetting(hContact, module, setting, &dbv))
+ {
+ switch (dbv.type)
+ {
+ case DBVT_BLOB:
+ {
+ int j;
+ if (!(data = (char*)mir_realloc(data, 3*(dbv.cpbVal+1)+10) ))
+ {msg(Translate("Couldnt allocate enough memory!"), modFullname); return;}
+ data[0] = '\0';
+ for (j=0; j<dbv.cpbVal; j++)
+ {
+ char tmp[16];
+ mir_snprintf(tmp, SIZEOF(tmp), "%02X ", (BYTE)dbv.pbVal[j]);
+ strcat(data, tmp);
+ }
+ lvi.iImage = 0;
+ ListView_SetItem(hwnd2Settings,&lvi);
+ ListView_SetItemText(hwnd2Settings,index,1,data);
+ ListView_SetItemText(hwnd2Settings,index,2,Translate("BLOB"));
+ mir_snprintf(data, 3*(dbv.cpbVal+1)+10, "0x%04X (%d)", dbv.cpbVal,dbv.cpbVal);
+ ListView_SetItemText(hwnd2Settings,index,3,data);
+ }
+ break;
+ case DBVT_BYTE:
+ if (!(data = (char*)mir_realloc(data, 16))) // 0x00 (000)
+ return;
+ lvi.iImage = 1;
+ ListView_SetItem(hwnd2Settings,&lvi);
+ mir_snprintf(data, 16, "0x%02X (%d)", dbv.bVal, dbv.bVal);
+ ListView_SetItemText(hwnd2Settings,index,1,data);
+ ListView_SetItemText(hwnd2Settings,index,2,Translate("BYTE"));
+ ListView_SetItemText(hwnd2Settings,index,3,"0x0001 (1)");
+ break;
+ case DBVT_WORD:
+ if (!(data = (char*)mir_realloc(data, 16))) // 0x0000 (00000)
+ return;
+
+ lvi.iImage = 2;
+ ListView_SetItem(hwnd2Settings,&lvi);
+ mir_snprintf(data, 16, "0x%04X (%ld)", dbv.wVal,dbv.wVal);
+ ListView_SetItemText(hwnd2Settings,index,1,data);
+ ListView_SetItemText(hwnd2Settings,index,2,Translate("WORD"));
+ ListView_SetItemText(hwnd2Settings,index,3,"0x0002 (2)");
+ break;
+ case DBVT_DWORD:
+ if (!(data = (char*)mir_realloc(data, 32))) // 0x00000000 (0000000000)
+ return;
+
+ lvi.iImage = 3;
+ ListView_SetItem(hwnd2Settings,&lvi);
+ mir_snprintf(data, 32, "0x%08X (%ld)", dbv.dVal, dbv.dVal);
+ ListView_SetItemText(hwnd2Settings,index,1,data);
+ ListView_SetItemText(hwnd2Settings,index,2,Translate("DWORD"));
+ ListView_SetItemText(hwnd2Settings,index,3,"0x0004 (4)");
+ break;
+ case DBVT_ASCIIZ:
+ {
+ int length = mir_strlen(dbv.pszVal)+1;
+ if (!(data = (char*)mir_realloc(data, 512)))
+ return;
+
+ lvi.iImage = 4;
+ ListView_SetItem(hwnd2Settings,&lvi);
+ ListView_SetItemText(hwnd2Settings,index,1,dbv.pszVal);
+ ListView_SetItemText(hwnd2Settings,index,2,Translate("STRING"));
+ mir_snprintf(data, 512, "0x%04X (%d)", length,length);
+ ListView_SetItemText(hwnd2Settings,index,3,data);
+ }
+ break;
+ case DBVT_UTF8:
+ {
+ int length = (int)strlen(dbv.pszVal) + 1;
+
+ if (!(data = (char*)mir_realloc(data, 512)))
+ return;
+
+ lvi.iImage = 5;
+ ListView_SetItem(hwnd2Settings,&lvi);
+
+ if (UOS)
+ {
+ WCHAR *wc = (WCHAR*)_alloca(length*sizeof(WCHAR));
+ MultiByteToWideChar(CP_UTF8, 0, dbv.pszVal, -1, wc, length);
+ ListView_SetItemTextW(hwnd2Settings,index,1,wc);
+ }
+ else
+ {
+ // convert from UTF8
+ ListView_SetItemText(hwnd2Settings,index,1,dbv.pszVal);
+ }
+
+ ListView_SetItemText(hwnd2Settings,index,2,Translate("UNICODE"));
+ mir_snprintf(data, 512, "0x%04X (%d)", length,length);
+ ListView_SetItemText(hwnd2Settings,index,3,data);
+ }
+ break;
+ case DBVT_DELETED:
+ return;
+ break;
+
+ }
+ }
+ else
+ if (dbv.type == DBVT_UTF8)
+ {
+ lvi.iImage = 5;
+ ListView_SetItem(hwnd2Settings,&lvi);
+ ListView_SetItemText(hwnd2Settings,index,1,Translate("<unsupported>"));
+ ListView_SetItemText(hwnd2Settings,index,2,Translate("UNICODE"));
+ ListView_SetItemText(hwnd2Settings,index,3,Translate("<unknown>"));
+ }
+ else
+ ListView_DeleteItem(hwnd2Settings,index);
+
+ DBFreeVariant(&dbv);
+ mir_free(data);
+}
+
+void PopulateSettings(HWND hwnd2Settings, HANDLE hContact, char* module)
+{
+ SettingListInfo* info = (SettingListInfo*)mir_calloc(sizeof(SettingListInfo));
+ LVITEM lvItem;
+
+ struct ModSetLinkLinkItem *setting;
+ ModuleSettingLL setlist;
+ if (!EnumSettings(hContact,module,&setlist)) { msg(Translate("Error Loading Setting List"),modFullname); mir_free(info); return;}
+
+ // clear any settings that may be there...
+ ClearListview(hwnd2Settings);
+
+ info->hContact = hContact;
+ info->module = mir_tstrdup(module);
+ SetWindowLongPtr(hwnd2Settings,GWLP_USERDATA, (LONG)info);
+
+ // icons
+ if (himl2) ListView_SetImageList(hwnd2Settings, himl2, LVSIL_SMALL);
+
+ lvItem.mask = LVIF_TEXT;
+ lvItem.iItem = 0;
+ lvItem.iSubItem = 0;
+ setting = setlist.first;
+
+ while (setting)
+ {
+ lvItem.pszText = setting->name;
+ additem(hwnd2Settings,hContact,module, setting->name, ListView_InsertItem(hwnd2Settings,&lvItem));
+ setting = (struct ModSetLinkLinkItem *)setting->next;
+ }
+
+ FreeModuleSettingLL(&setlist);
+}
+
+
+void SelectSetting(char* setting)
+{
+ LVITEM lvItem;
+ LVFINDINFO lvfi;
+ HWND hwnd2Settings = GetDlgItem(hwnd2mainWindow,IDC_SETTINGS);
+
+ lvfi.flags = LVFI_STRING;
+ lvfi.psz = setting;
+ lvfi.vkDirection = VK_DOWN;
+
+ lvItem.mask = LVIF_TEXT;
+ lvItem.iItem = ListView_FindItem(hwnd2Settings,-1,&lvfi);
+ if (lvItem.iItem != -1)
+ {
+ lvItem.mask = LVIF_STATE;
+ lvItem.state = LVIS_SELECTED | LVIS_FOCUSED;
+ lvItem.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
+ ListView_SetItem(hwnd2Settings,&lvItem);
+ }
+}
+
+void settingChanged(HWND hwnd2Settings, HANDLE hContact, char* module, char* setting)
+{
+ LVITEM lvItem;
+ LVFINDINFO lvfi;
+
+ lvfi.flags = LVFI_STRING;
+ lvfi.psz = setting;
+ lvfi.vkDirection = VK_DOWN;
+
+ lvItem.mask = LVIF_TEXT|LVIF_IMAGE;
+ lvItem.iItem = ListView_FindItem(hwnd2Settings,-1,&lvfi);
+ lvItem.iSubItem = 0;
+
+ if (lvItem.iItem == -1)
+ {
+ lvItem.iItem = 0;
+ lvItem.pszText = setting;
+ lvItem.cchTextMax = mir_strlen(setting);
+ lvItem.iItem = ListView_InsertItem(hwnd2Settings,&lvItem);
+ }
+ additem(hwnd2Settings,hContact,module, setting,lvItem.iItem);
+}
+
+static WNDPROC SettingLabelEditSubClass;
+
+typedef struct {
+ HANDLE hContact;
+ char module[256];
+ char setting[256];
+ int item;
+ int subitem;
+ HWND hwnd;
+ int unicode;
+} EditLabelInfoStruct;
+
+void writeStandardTextfromLabel(EditLabelInfoStruct* info, char* value, WCHAR *wc, int type)
+{
+ if (type != DBVT_ASCIIZ && type != DBVT_UTF8)
+ DBDeleteContactSetting(info->hContact,info->module,info->setting);
+ if (type == DBVT_UTF8 && wc)
+ {
+ DBWriteContactSettingWString(info->hContact,info->module,info->setting,wc);
+ mir_free(wc);
+ }
+ else
+ DBWriteContactSettingString(info->hContact,info->module,info->setting,value);
+
+}
+
+static LRESULT CALLBACK SettingLabelEditSubClassProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
+{
+ EditLabelInfoStruct* info = (EditLabelInfoStruct*)GetWindowLongPtr(hwnd,GWLP_USERDATA);
+ switch(msg) {
+ case WM_KEYDOWN:
+ switch (wParam)
+ {
+ case VK_RETURN:
+ if (GetKeyState(VK_CONTROL)&0x8000) // ctrl is pressed
+ break;
+ SendMessage(hwnd,WM_COMMAND,MAKEWPARAM(IDOK,0),0);
+ return 0;
+ case VK_ESCAPE:
+ SendMessage(hwnd,WM_COMMAND,MAKEWPARAM(IDCANCEL,0),0);
+ return 0;
+ }
+ break;
+ case WM_USER:
+ SetWindowLongPtr(hwnd,GWLP_USERDATA,lParam);
+ SetFocus(hwnd);
+ SendMessage(hwnd, WM_SETFONT, SendMessage(GetParent(hwnd), WM_GETFONT, 0, 0), 1);
+ info = ((EditLabelInfoStruct*)lParam);
+ if (info->subitem)
+ SendMessage(hwnd, EM_LIMITTEXT, (WPARAM)65535, 0);
+ else
+ SendMessage(hwnd, EM_LIMITTEXT, (WPARAM)255, 0);
+ SendMessage(hwnd, EM_SETSEL,0,-1);
+ break;
+ case WM_PAINT:
+ break;
+ case WM_COMMAND:
+ switch (LOWORD(wParam))
+ {
+ case IDOK:
+ {
+ int len = GetWindowTextLength(hwnd)+1;
+ char *value = (char*)_alloca(len);
+ WCHAR *wc = NULL;
+ DBVARIANT dbv = {0};
+
+ GetWindowText(hwnd,value,len);
+
+ if (info->unicode)
+ wc = mir_a2u(value);
+
+ if (len <= 1 || GetSetting(info->hContact,info->module,info->setting,&dbv))
+ {
+ SendMessage(hwnd,WM_COMMAND,MAKEWPARAM(IDCANCEL,0),0);
+ return 0;
+ }
+
+ switch (info->subitem)
+ {
+ case 0:// setting name
+ if (!mir_strcmp(info->setting,value) || mir_strlen(value)>255)
+ {
+ DBFreeVariant(&dbv);
+ SendMessage(hwnd,WM_COMMAND,MAKEWPARAM(IDCANCEL,0),0);
+ return 0;
+ }
+ switch (dbv.type)
+ {
+ case DBVT_UTF8:
+ DBWriteContactSettingStringUtf(info->hContact,info->module,value,dbv.pszVal);
+ break;
+ case DBVT_ASCIIZ:
+ DBWriteContactSettingString(info->hContact,info->module,value,dbv.pszVal);
+ break;
+ case DBVT_BYTE:
+ DBWriteContactSettingByte(info->hContact,info->module,value,dbv.bVal);
+ break;
+ case DBVT_WORD:
+ DBWriteContactSettingWord(info->hContact,info->module,value,dbv.wVal);
+ break;
+ case DBVT_DWORD:
+ DBWriteContactSettingDword(info->hContact,info->module,value,dbv.dVal);
+ break;
+ case DBVT_BLOB:
+ DBWriteContactSettingBlob(info->hContact,info->module,value,dbv.pbVal,dbv.cpbVal);
+ break;
+ }
+ DBDeleteContactSetting(info->hContact,info->module,info->setting);
+ {
+ LVFINDINFO lvfi;
+ int item;
+
+ lvfi.flags = LVFI_STRING;
+ lvfi.psz = info->setting;
+ lvfi.vkDirection = VK_DOWN;
+
+ item = ListView_FindItem(info->hwnd,-1,&lvfi);
+ ListView_DeleteItem(info->hwnd,item);
+ }
+ break;
+ case 1: // value
+ {
+ int val;
+ int i = 0;
+
+ if (dbv.type == DBVT_BLOB)
+ {
+ WriteBlobFromString(info->hContact,info->module,info->setting,value,len);
+ break;
+ }
+
+ switch (value[0])
+ {
+ case 'b':
+ case 'B':
+ if (value[1] == '0' && (value[2] == 'x' || value[2] == 'X'))
+ sscanf(&value[3],"%x",&val);
+ else if (value[1] >= '0' && value[1] <= '9')
+ {
+ val = atoi(&value[1]);
+ if (dbv.type == DBVT_ASCIIZ || dbv.type == DBVT_UTF8)
+ DBDeleteContactSetting(info->hContact,info->module,info->setting);
+
+ DBWriteContactSettingByte(info->hContact,info->module,info->setting,(BYTE)val);
+ }
+ else
+ writeStandardTextfromLabel(info, value, wc, dbv.type);
+ break;
+ case 'w':
+ case 'W':
+ if (value[1] == '0' && (value[2] == 'x' || value[2] == 'X'))
+ sscanf(&value[3],"%x",&val);
+ else if (value[1] >= '0' && value[1] <= '9')
+ {
+ val = atoi(&value[1]);
+ if (dbv.type == DBVT_ASCIIZ || dbv.type == DBVT_UTF8)
+ DBDeleteContactSetting(info->hContact,info->module,info->setting);
+ DBWriteContactSettingWord(info->hContact,info->module,info->setting,(WORD)val);
+ }
+ else
+ writeStandardTextfromLabel(info, value, wc, dbv.type);
+ break;
+ case 'd':
+ case 'D':
+ if (value[1] == '0' && (value[2] == 'x' || value[2] == 'X'))
+ sscanf(&value[3],"%x",&val);
+ else if (value[1] >= '0' && value[1] <= '9')
+ {
+ val = atoi(&value[1]);
+ if (dbv.type == DBVT_ASCIIZ || dbv.type == DBVT_UTF8)
+ DBDeleteContactSetting(info->hContact,info->module,info->setting);
+ DBWriteContactSettingDword(info->hContact,info->module,info->setting,val);
+ }
+ else
+ writeStandardTextfromLabel(info, value, wc, dbv.type);
+ break;
+ case '0':
+ i=1;
+ case 'x':
+ case 'X':
+ if (value[i] == 'x' || value[i] == 'X')
+ {
+
+ sscanf(&value[i+1],"%x",&val);
+ switch (dbv.type)
+ {
+ case DBVT_UTF8:
+ case DBVT_ASCIIZ:
+ writeStandardTextfromLabel(info, value, wc, dbv.type);
+ break;
+ case DBVT_BYTE:
+ DBWriteContactSettingByte(info->hContact,info->module,info->setting,(BYTE)val);
+ break;
+ case DBVT_WORD:
+ DBWriteContactSettingWord(info->hContact,info->module,info->setting,(WORD)val);
+ break;
+ case DBVT_DWORD:
+ DBWriteContactSettingDword(info->hContact,info->module,info->setting,(DWORD)val);
+ break;
+ }
+ }
+ else
+ {
+ val = atoi(value);
+ switch (dbv.type)
+ {
+ case DBVT_ASCIIZ:
+ case DBVT_UTF8:
+ writeStandardTextfromLabel(info, value, wc, dbv.type);
+ break;
+ case DBVT_BYTE:
+ DBWriteContactSettingByte(info->hContact,info->module,info->setting,(BYTE)val);
+ break;
+ case DBVT_WORD:
+ DBWriteContactSettingWord(info->hContact,info->module,info->setting,(WORD)val);
+ break;
+ case DBVT_DWORD:
+ DBWriteContactSettingDword(info->hContact,info->module,info->setting,(DWORD)val);
+ break;
+ }
+ }
+ break;
+ case '\"':
+ case '\'':
+ {
+ int nlen = mir_strlen(value);
+ int sh = 0;
+ if (nlen > 3)
+ {
+ if (value[nlen-1] == value[0])
+ {
+ value[nlen-1] = '\0';
+ sh = 1;
+ }
+ }
+ writeStandardTextfromLabel(info, &value[sh], wc, dbv.type);
+ }
+ break;
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ case '-':
+ val = atoi(value);
+ switch (dbv.type)
+ {
+ case DBVT_ASCIIZ:
+ case DBVT_UTF8:
+ writeStandardTextfromLabel(info, value, wc, dbv.type);
+ break;
+ case DBVT_BYTE:
+ DBWriteContactSettingByte(info->hContact,info->module,info->setting,(BYTE)val);
+ break;
+ case DBVT_WORD:
+ DBWriteContactSettingWord(info->hContact,info->module,info->setting,(WORD)val);
+ break;
+ case DBVT_DWORD:
+ DBWriteContactSettingDword(info->hContact,info->module,info->setting,(DWORD)val);
+ break;
+ }
+ break;
+ default:
+ writeStandardTextfromLabel(info, value, wc, dbv.type);
+ break;
+ } // switch (value[0])
+ }
+ break; // case 1:
+ }
+ DBFreeVariant(&dbv);
+ } // fall through
+ case IDCANCEL:
+ {
+ SettingListInfo *sli = (SettingListInfo*)GetWindowLongPtr(info->hwnd,GWLP_USERDATA);
+
+ if (sli && sli->hwnd2Edit==hwnd)
+ sli->hwnd2Edit = NULL;
+
+ mir_free(info);
+ DestroyWindow(hwnd);
+ }
+ return 0;
+ }
+ break; // wm_command
+ case WM_GETDLGCODE:
+ return DLGC_WANTALLKEYS;
+ }
+ if (UOS)
+ return CallWindowProcW(SettingLabelEditSubClass,hwnd,msg,wParam,lParam);
+ else
+ return CallWindowProc(SettingLabelEditSubClass,hwnd,msg,wParam,lParam);
+}
+
+
+void EditLabel(HWND hwnd2List, int item, int subitem)
+{
+ RECT rc;
+ LVITEM lvi;
+ char setting[256], value[16] = {0};
+ DBVARIANT dbv;
+ SettingListInfo* info = (SettingListInfo*)GetWindowLongPtr(hwnd2List,GWLP_USERDATA);
+ EditLabelInfoStruct *data = (EditLabelInfoStruct*)mir_calloc(sizeof(EditLabelInfoStruct));
+ if (!data || !info) return;
+ if (info->hwnd2Edit)
+ {
+ SendMessage(info->hwnd2Edit,WM_COMMAND,MAKEWPARAM(IDCANCEL,0),0); // ignore the new value of the last edit
+ info->hwnd2Edit = NULL;
+ }
+ lvi.mask = LVIF_TEXT;
+ lvi.iItem = item;
+ lvi.iSubItem = 0;
+ lvi.pszText = setting;
+ lvi.cchTextMax = 256;
+
+ if (!ListView_GetItem(hwnd2List, &lvi) ||
+ !ListView_GetSubItemRect
+ (hwnd2List,item,subitem,LVIR_LABEL,&rc) ||
+ GetSetting(info->hContact,info->module,setting,&dbv))
+ {
+ mir_free(data);
+ return;
+ }
+
+ data->hContact = info->hContact;
+ strcpy(data->module, info->module);
+ strcpy(data->setting, setting);
+ data->item = item;
+ data->subitem = subitem;
+ data->hwnd = hwnd2List;
+
+ // fix size for long strings
+
+ switch (dbv.type)
+ {
+ case DBVT_UTF8:
+ if (subitem && UOS)
+ {
+ int len = mir_strlen(dbv.pszVal)+1;
+ WCHAR *wc = (WCHAR*)_alloca(len*sizeof(WCHAR));
+ MultiByteToWideChar(CP_UTF8, 0, dbv.pszVal, -1, wc, len);
+ data->unicode = 1;
+ info->hwnd2Edit = CreateWindowW(L"EDIT",wc,WS_BORDER|WS_VISIBLE|WS_CHILD|WS_VSCROLL|ES_MULTILINE|ES_AUTOHSCROLL, rc.left,rc.top,(int)((rc.right - rc.left)*1.5),(rc.bottom - rc.top)*3,hwnd2List, 0,hInst,0);
+ break;
+ }
+ // fall through
+ case DBVT_ASCIIZ:
+ if (subitem) {
+ // convert from UTF8
+ info->hwnd2Edit = CreateWindow("EDIT",dbv.pszVal,WS_BORDER|WS_VISIBLE|WS_CHILD|WS_VSCROLL|ES_MULTILINE|ES_AUTOHSCROLL, rc.left,rc.top,(int)((rc.right - rc.left)*1.5),(rc.bottom - rc.top)*3,hwnd2List, 0,hInst,0);
+ }
+ else
+ info->hwnd2Edit = CreateWindow("EDIT",setting,WS_BORDER|WS_VISIBLE|WS_CHILD|ES_AUTOHSCROLL, rc.left,rc.top,(rc.right - rc.left),(rc.bottom - rc.top),hwnd2List, 0,hInst,0);
+ break;
+ case DBVT_BYTE:
+ if (Hex&HEX_BYTE)
+ mir_snprintf(value, SIZEOF(value), "0x%02X", dbv.bVal);
+ else
+ itoa(dbv.bVal,value,10);
+ info->hwnd2Edit = CreateWindow("EDIT",!subitem?setting:value,WS_BORDER|WS_VISIBLE|WS_CHILD|ES_AUTOHSCROLL, rc.left,rc.top,(rc.right - rc.left),(rc.bottom - rc.top),hwnd2List, 0,hInst,0);
+ break;
+ case DBVT_WORD:
+ if (Hex&HEX_WORD)
+ mir_snprintf(value, SIZEOF(value), "0x%04X", dbv.wVal);
+ else
+ itoa(dbv.wVal,value,10);
+ info->hwnd2Edit = CreateWindow("EDIT",!subitem?setting:value,WS_BORDER|WS_VISIBLE|WS_CHILD|ES_AUTOHSCROLL, rc.left,rc.top,(rc.right - rc.left),(rc.bottom - rc.top),hwnd2List, 0,hInst,0);
+ break;
+ case DBVT_DWORD:
+ if (Hex&HEX_DWORD)
+ mir_snprintf(value, SIZEOF(value), "0x%08X", dbv.dVal);
+ else
+ itoa(dbv.dVal,value,10);
+ info->hwnd2Edit = CreateWindow("EDIT",!subitem?setting:value,WS_BORDER|WS_VISIBLE|WS_CHILD|ES_AUTOHSCROLL, rc.left,rc.top,(rc.right - rc.left),(rc.bottom - rc.top),hwnd2List, 0,hInst,0);
+ break;
+ case DBVT_BLOB:
+ if (!subitem)
+ info->hwnd2Edit = CreateWindow("EDIT",setting,WS_BORDER|WS_VISIBLE|WS_CHILD|ES_AUTOHSCROLL, rc.left,rc.top,(rc.right - rc.left),(rc.bottom - rc.top),hwnd2List, 0,hInst,0);
+ else
+ {
+ int j;
+ char tmp[16];
+ char *data = (char*)_alloca(3*(dbv.cpbVal+1)+10);
+
+ if (!data) {msg(Translate("Couldnt allocate enough memory!"), modFullname); return;}
+ data[0] = '\0';
+
+ for(j=0; j<dbv.cpbVal; j++)
+ {
+ mir_snprintf(tmp, SIZEOF(tmp), "%02X ", (BYTE)dbv.pbVal[j]);
+ strcat(data, tmp);
+ }
+
+ info->hwnd2Edit = CreateWindow("EDIT",data,WS_BORDER|WS_VISIBLE|WS_CHILD|WS_VSCROLL|ES_MULTILINE, rc.left,rc.top,(int)((rc.right - rc.left)*1.5),(rc.bottom - rc.top)*3,hwnd2List,0,hInst,0);
+ }
+ break;
+ default: return;
+ }
+
+ DBFreeVariant(&dbv);
+
+ if (UOS)
+ SettingLabelEditSubClass=(WNDPROC)SetWindowLongPtrW(info->hwnd2Edit,GWLP_WNDPROC,(LONG)SettingLabelEditSubClassProc);
+ else
+ SettingLabelEditSubClass=(WNDPROC)SetWindowLongPtr(info->hwnd2Edit,GWLP_WNDPROC,(LONG)SettingLabelEditSubClassProc);
+
+ SendMessage(info->hwnd2Edit,WM_USER,0,(LPARAM)data);
+}
+
+static int test;
+void SettingsListRightClick(HWND hwnd, WPARAM wParam,LPARAM lParam);
+static int lastColumn = -1;
+
+struct SettingsSortParams{
+ HWND hList;
+ int column;
+};
+
+INT_PTR CALLBACK SettingsCompare(LPARAM lParam1, LPARAM lParam2, LPARAM myParam)
+{
+ SettingsSortParams params = *(SettingsSortParams *) myParam;
+ const int maxSize = 1024;
+ TCHAR text1[maxSize];
+ TCHAR text2[maxSize];
+ ListView_GetItemText(params.hList, (int) lParam1, params.column, text1, maxSize);
+ ListView_GetItemText(params.hList, (int) lParam2, params.column, text2, maxSize);
+
+ int res = _tcsicmp(text1, text2);
+ res = (params.column == lastColumn) ? -res : res;
+ return res;
+}
+
+void SettingsListWM_NOTIFY(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
+{
+ switch(((NMHDR*)lParam)->code)
+ {
+ case NM_CLICK:
+ {
+ SettingListInfo* info = (SettingListInfo*)GetWindowLongPtr(GetDlgItem(hwnd,IDC_SETTINGS),GWLP_USERDATA);
+
+ LVHITTESTINFO hti;
+ hti.pt=((NMLISTVIEW*)lParam)->ptAction;
+ if (DBGetContactSettingByte(NULL,modname,"DontAllowInLineEdit",0) || !IsWinVer2000Plus()) /* fix for TioDuke and win98 */
+ break;
+ if (info && ListView_SubItemHitTest(GetDlgItem(hwnd,IDC_SETTINGS),&hti) >-1)
+ {
+ if (hti.iSubItem < 2 && hti.flags != LVHT_ONITEMICON)
+ {
+ if (info->selectedItem == hti.iItem)
+ EditLabel(GetDlgItem(hwnd,IDC_SETTINGS),hti.iItem,hti.iSubItem);
+ else if (info->hwnd2Edit)
+ {
+ SendMessage(info->hwnd2Edit,WM_COMMAND,MAKEWPARAM(IDOK,0),0);
+ info->hwnd2Edit = NULL;
+ info->selectedItem = hti.iItem;
+ }
+ else info->selectedItem = hti.iItem;
+ }
+ else
+ {
+ if (info->hwnd2Edit)
+ {
+ SendMessage(info->hwnd2Edit,WM_COMMAND,MAKEWPARAM(IDOK,0),0);
+ info->hwnd2Edit = NULL;
+ }
+ info->selectedItem = hti.iItem;
+ }
+ }
+ else if (info && info->hwnd2Edit)
+ {
+ SendMessage(info->hwnd2Edit,WM_COMMAND,MAKEWPARAM(IDOK,0),0);
+ info->hwnd2Edit = NULL;
+ info->selectedItem = 0;
+ }
+ break;
+ }
+
+ case NM_DBLCLK:
+ {
+ SettingListInfo* info = (SettingListInfo*)GetWindowLongPtr(GetDlgItem(hwnd,IDC_SETTINGS),GWLP_USERDATA);
+
+ LVHITTESTINFO hti;
+
+ hti.pt=((NMLISTVIEW*)lParam)->ptAction;
+ if (info && ListView_SubItemHitTest(GetDlgItem(hwnd,IDC_SETTINGS),&hti) >-1)
+ {
+ if ((hti.iSubItem > 1 || hti.flags == LVHT_ONITEMICON) || (DBGetContactSettingByte(NULL,modname,"DontAllowInLineEdit",0) || !IsWinVer2000Plus()/* fix for TioDuke and win98 */ ))
+ {
+ char setting[256];
+ SendMessage(info->hwnd2Edit,WM_COMMAND,MAKEWPARAM(IDOK,0),0);
+ info->hwnd2Edit = NULL;
+ ListView_GetItemText(GetDlgItem(hwnd, IDC_SETTINGS), hti.iItem, 0, setting, 256);
+ editSetting(info->hContact,info->module, setting);
+ }
+ else EditLabel(GetDlgItem(hwnd,IDC_SETTINGS),hti.iItem,hti.iSubItem);
+ }
+ break;
+ }
+
+ case NM_RCLICK:
+ SettingsListRightClick(hwnd,wParam,lParam);
+ break;
+
+ case LVN_COLUMNCLICK:
+ {
+ LPNMLISTVIEW lv = (LPNMLISTVIEW) lParam;
+ SettingsSortParams params = {0};
+ params.hList = GetDlgItem(hwnd, IDC_SETTINGS);
+ params.column = lv->iSubItem;
+ ListView_SortItemsEx(params.hList, SettingsCompare, (LPARAM) &params);
+ lastColumn = (params.column == lastColumn) ? -1 : params.column;
+ break;
+ }
+
+ } // switch(((NMHDR*)lParam)->code)
+}
+
+void SettingsListRightClick(HWND hwnd, WPARAM wParam,LPARAM lParam) // hwnd here is to the main window, NOT the listview
+{
+ HWND hSettings = GetDlgItem(hwnd,IDC_SETTINGS);
+ SettingListInfo* info = (SettingListInfo*)GetWindowLongPtr(hSettings,GWLP_USERDATA);
+ char setting[256], *module;
+ HANDLE hContact;
+ LVHITTESTINFO hti;
+ POINT pt;
+ HMENU hMenu, hSubMenu;
+
+ if (!info) return;
+ module = info->module;
+ hContact = info->hContact;
+
+ hti.pt=((NMLISTVIEW*)lParam)->ptAction;
+ if (ListView_SubItemHitTest(hSettings,&hti) == -1)
+ {
+ // nowhere.. new item menu
+ GetCursorPos(&pt);
+ hMenu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_CONTEXTMENU));
+ hSubMenu = GetSubMenu(hMenu, 6);
+ CallService(MS_LANGPACK_TRANSLATEMENU, (WPARAM) hSubMenu, 0);
+
+ if (!UDB)
+ RemoveMenu(hSubMenu, MENU_ADD_UNICODE, MF_BYCOMMAND);
+
+ switch (TrackPopupMenu(hSubMenu, TPM_RETURNCMD, pt.x, pt.y, 0, hwnd, NULL))
+ {
+ case MENU_ADD_BYTE:
+ {
+ struct DBsetting *dbsetting = (struct DBsetting *)mir_alloc(sizeof(struct DBsetting)); // gets safe_free()ed in the window proc
+ DBVARIANT dbv = {0}; // freed in the dialog
+ dbv.type = DBVT_BYTE;
+ dbsetting->dbv = dbv;
+ dbsetting->hContact = hContact;
+ dbsetting->module = mir_tstrdup(module);
+ dbsetting->setting = mir_tstrdup("");
+ CreateDialogParam(hInst,MAKEINTRESOURCE(IDD_EDIT_SETTING),hwnd,EditSettingDlgProc, (LPARAM)dbsetting);
+ }
+ break;
+ case MENU_ADD_WORD:
+ {
+ struct DBsetting *dbsetting = (struct DBsetting *)mir_alloc(sizeof(struct DBsetting)); // gets safe_free()ed in the window proc
+ DBVARIANT dbv = {0}; // freed in the dialog
+ dbv.type = DBVT_WORD;
+ dbsetting->dbv = dbv;
+ dbsetting->hContact = hContact;
+ dbsetting->module = mir_tstrdup(module);
+ dbsetting->setting = mir_tstrdup("");
+ CreateDialogParam(hInst,MAKEINTRESOURCE(IDD_EDIT_SETTING),hwnd,EditSettingDlgProc, (LPARAM)dbsetting);
+ }
+ break;
+ case MENU_ADD_DWORD:
+ {
+ struct DBsetting *dbsetting = (struct DBsetting *)mir_alloc(sizeof(struct DBsetting)); // gets safe_free()ed in the window proc
+ DBVARIANT dbv = {0}; // freed in the dialog
+ dbv.type = DBVT_DWORD;
+ dbsetting->dbv = dbv;
+ dbsetting->hContact = hContact;
+ dbsetting->module = mir_tstrdup(module);
+ dbsetting->setting = mir_tstrdup("");
+ CreateDialogParam(hInst,MAKEINTRESOURCE(IDD_EDIT_SETTING),hwnd,EditSettingDlgProc, (LPARAM)dbsetting);
+ }
+ break;
+ case MENU_ADD_STRING:
+ {
+ struct DBsetting *dbsetting = (struct DBsetting *)mir_alloc(sizeof(struct DBsetting)); // gets safe_free()ed in the window proc
+ DBVARIANT dbv = {0}; // freed in the dialog
+ dbv.type = DBVT_ASCIIZ;
+ dbsetting->dbv = dbv;
+ dbsetting->hContact = hContact;
+ dbsetting->module = mir_tstrdup(module);
+ dbsetting->setting = mir_tstrdup("");
+ CreateDialogParam(hInst,MAKEINTRESOURCE(IDD_EDIT_SETTING),hwnd,EditSettingDlgProc, (LPARAM)dbsetting);
+ }
+ break;
+ case MENU_ADD_UNICODE:
+ if (UDB)
+ {
+ struct DBsetting *dbsetting = (struct DBsetting *)mir_alloc(sizeof(struct DBsetting)); // gets safe_free()ed in the window proc
+ DBVARIANT dbv = {0}; // freed in the dialog
+ dbv.type = DBVT_UTF8;
+ dbsetting->dbv = dbv;
+ dbsetting->hContact = hContact;
+ dbsetting->module = mir_tstrdup(module);
+ dbsetting->setting = mir_tstrdup("");
+ if (UOS)
+ CreateDialogParamW(hInst,MAKEINTRESOURCEW(IDD_EDIT_SETTING),hwnd,EditSettingDlgProc, (LPARAM)dbsetting);
+ else
+ CreateDialogParam(hInst,MAKEINTRESOURCE(IDD_EDIT_SETTING),hwnd,EditSettingDlgProc, (LPARAM)dbsetting);
+ }
+ break;
+ case MENU_ADD_BLOB:
+ {
+ struct DBsetting *dbsetting = (struct DBsetting *)mir_alloc(sizeof(struct DBsetting)); // gets safe_free()ed in the window proc
+ DBVARIANT dbv = {0}; // freed in the dialog
+ dbv.type = DBVT_BLOB;
+ dbsetting->dbv = dbv;
+ dbsetting->hContact = hContact;
+ dbsetting->module = mir_tstrdup(module);
+ dbsetting->setting = mir_tstrdup("");
+ CreateDialogParam(hInst,MAKEINTRESOURCE(IDD_EDIT_SETTING),hwnd,EditSettingDlgProc, (LPARAM)dbsetting);
+ }
+ break;
+
+ } // switch
+ }
+ else // on item
+ {
+ char type[8];
+ LVITEM lvi;
+ int i;
+ int watching = 0;
+ GetCursorPos(&pt);
+ hMenu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_CONTEXTMENU));
+ hSubMenu = GetSubMenu(hMenu, 0);
+ CallService(MS_LANGPACK_TRANSLATEMENU, (WPARAM) hSubMenu, 0);
+
+ lvi.mask = LVIF_IMAGE|LVIF_TEXT;
+ lvi.iItem = hti.iItem;
+ lvi.iSubItem = 0;
+ lvi.pszText = setting;
+ lvi.cchTextMax = 256;
+
+ ListView_GetItem(hSettings,&lvi);
+ ListView_GetItemText(hSettings, hti.iItem, 2, type, 8);
+
+ if (!UDB)
+ {
+ RemoveMenu(hSubMenu, MENU_ADD_UNICODE, MF_BYCOMMAND);
+ RemoveMenu(hSubMenu, MENU_CHANGE2UNICODE, MF_BYCOMMAND);
+ }
+
+ switch(lvi.iImage) {
+ case 4: // STRING
+ RemoveMenu(hSubMenu, MENU_CHANGE2STRING, MF_BYCOMMAND);
+ break;
+ case 1: // BYTE
+ RemoveMenu(hSubMenu, 4, MF_BYPOSITION);
+ RemoveMenu(hSubMenu, MENU_CHANGE2BYTE, MF_BYCOMMAND);
+ RemoveMenu(hSubMenu, MENU_CHANGE2UNICODE, MF_BYCOMMAND);
+ break;
+ case 2: // WORD
+ RemoveMenu(hSubMenu, 4, MF_BYPOSITION);
+ RemoveMenu(hSubMenu, MENU_CHANGE2WORD, MF_BYCOMMAND);
+ RemoveMenu(hSubMenu, MENU_CHANGE2UNICODE, MF_BYCOMMAND);
+ break;
+ case 3: // DWORD
+ RemoveMenu(hSubMenu, 4, MF_BYPOSITION);
+ RemoveMenu(hSubMenu, MENU_CHANGE2DWORD, MF_BYCOMMAND);
+ RemoveMenu(hSubMenu, MENU_CHANGE2UNICODE, MF_BYCOMMAND);
+ break;
+ case 0: // BLOB
+ RemoveMenu(hSubMenu, 3, MF_BYPOSITION);
+ RemoveMenu(hSubMenu, 1, MF_BYPOSITION);
+ RemoveMenu(hSubMenu, 2, MF_BYPOSITION);
+ RemoveMenu(hSubMenu, MENU_EDIT_SET, MF_BYCOMMAND);
+ break;
+ case 5: // UTF8
+ RemoveMenu(hSubMenu, 4, MF_BYPOSITION);
+ RemoveMenu(hSubMenu, MENU_CHANGE2DWORD, MF_BYCOMMAND);
+ RemoveMenu(hSubMenu, MENU_CHANGE2WORD, MF_BYCOMMAND);
+ RemoveMenu(hSubMenu, MENU_CHANGE2BYTE, MF_BYCOMMAND);
+ if (!UDB)
+ {
+ RemoveMenu(hSubMenu, 3, MF_BYPOSITION);
+ RemoveMenu(hSubMenu, 1, MF_BYPOSITION);
+ RemoveMenu(hSubMenu, 2, MF_BYPOSITION);
+ RemoveMenu(hSubMenu, MENU_EDIT_SET, MF_BYCOMMAND);
+ RemoveMenu(hSubMenu, MENU_WATCH_ITEM, MF_BYCOMMAND);
+ }
+ else
+ RemoveMenu(hSubMenu, MENU_CHANGE2UNICODE, MF_BYCOMMAND);
+ break;
+ }
+
+ // watch list stuff
+
+ if (ListView_GetSelectedCount(hSettings) >1)
+ {
+ RemoveMenu(hSubMenu, 3, MF_BYPOSITION);
+ RemoveMenu(hSubMenu, 1, MF_BYPOSITION);
+ RemoveMenu(hSubMenu, 3, MF_BYPOSITION);
+ RemoveMenu(hSubMenu, MENU_EDIT_SET, MF_BYCOMMAND);
+ }
+
+ // check if the setting is being watched and if it is then check the menu item
+ for (i=0; i<WatchListArray.count; i++)
+ {
+ if (WatchListArray.item[i].module && (hContact == WatchListArray.item[i].hContact) )
+ {
+ if (WatchListArray.item[i].WatchModule == WATCH_MODULE) continue;
+
+ if (!mir_strcmp(module, WatchListArray.item[i].module) && WatchListArray.item[i].setting[0])
+ {
+ if (!mir_strcmp(setting, WatchListArray.item[i].setting))
+ {
+ // yes so uncheck it
+ CheckMenuItem(hSubMenu, MENU_WATCH_ITEM, MF_CHECKED|MF_BYCOMMAND);
+ watching =1;
+ break;
+ }
+ }
+ }
+ }
+ switch (TrackPopupMenu(hSubMenu, TPM_RETURNCMD, pt.x, pt.y, 0, hwnd, NULL))
+ {
+ case MENU_EDIT_SET:
+ editSetting(info->hContact,info->module, setting);
+ break;
+///////////////////////// divider
+//////////////////////// NEW item submenu
+ case MENU_ADD_BYTE:
+ {
+ struct DBsetting *dbsetting = (struct DBsetting *)mir_alloc(sizeof(struct DBsetting)); // gets safe_free()ed in the window proc
+ DBVARIANT dbv = {0}; // freed in the dialog
+ dbv.type = DBVT_BYTE;
+ dbsetting->dbv = dbv;
+ dbsetting->hContact = hContact;
+ dbsetting->module = mir_tstrdup(module);
+ dbsetting->setting = mir_tstrdup("");
+ CreateDialogParam(hInst,MAKEINTRESOURCE(IDD_EDIT_SETTING),hwnd,EditSettingDlgProc, (LPARAM)dbsetting);
+ }
+ break;
+ case MENU_ADD_WORD:
+ {
+ struct DBsetting *dbsetting = (struct DBsetting *)mir_alloc(sizeof(struct DBsetting)); // gets safe_free()ed in the window proc
+ DBVARIANT dbv = {0}; // freed in the dialog
+ dbv.type = DBVT_WORD;
+ dbsetting->dbv = dbv;
+ dbsetting->hContact = hContact;
+ dbsetting->module = mir_tstrdup(module);
+ dbsetting->setting = mir_tstrdup("");
+ CreateDialogParam(hInst,MAKEINTRESOURCE(IDD_EDIT_SETTING),hwnd,EditSettingDlgProc, (LPARAM)dbsetting);
+ }
+ break;
+ case MENU_ADD_DWORD:
+ {
+ struct DBsetting *dbsetting = (struct DBsetting *)mir_alloc(sizeof(struct DBsetting)); // gets safe_free()ed in the window proc
+ DBVARIANT dbv = {0}; // freed in the dialog
+ dbv.type = DBVT_DWORD;
+ dbsetting->dbv = dbv;
+ dbsetting->hContact = hContact;
+ dbsetting->module = mir_tstrdup(module);
+ dbsetting->setting = mir_tstrdup("");
+ CreateDialogParam(hInst,MAKEINTRESOURCE(IDD_EDIT_SETTING),hwnd,EditSettingDlgProc, (LPARAM)dbsetting);
+ }
+ break;
+ case MENU_ADD_STRING:
+ {
+ struct DBsetting *dbsetting = (struct DBsetting *)mir_alloc(sizeof(struct DBsetting)); // gets safe_free()ed in the window proc
+ DBVARIANT dbv = {0}; // freed in the dialog
+ dbv.type = DBVT_ASCIIZ;
+ dbsetting->dbv = dbv;
+ dbsetting->hContact = hContact;
+ dbsetting->module = mir_tstrdup(module);
+ dbsetting->setting = mir_tstrdup("");
+ CreateDialogParam(hInst,MAKEINTRESOURCE(IDD_EDIT_SETTING),hwnd,EditSettingDlgProc, (LPARAM)dbsetting);
+ }
+ break;
+ case MENU_ADD_UNICODE:
+ if (UDB)
+ {
+ struct DBsetting *dbsetting = (struct DBsetting *)mir_alloc(sizeof(struct DBsetting)); // gets safe_free()ed in the window proc
+ DBVARIANT dbv = {0}; // freed in the dialog
+ dbv.type = DBVT_UTF8;
+ dbsetting->dbv = dbv;
+ dbsetting->hContact = hContact;
+ dbsetting->module = mir_tstrdup(module);
+ dbsetting->setting = mir_tstrdup("");
+ if (UOS)
+ CreateDialogParamW(hInst,MAKEINTRESOURCEW(IDD_EDIT_SETTING),hwnd,EditSettingDlgProc, (LPARAM)dbsetting);
+ else
+ CreateDialogParam(hInst,MAKEINTRESOURCE(IDD_EDIT_SETTING),hwnd,EditSettingDlgProc, (LPARAM)dbsetting);
+ }
+ break;
+ case MENU_ADD_BLOB:
+ {
+ struct DBsetting *dbsetting = (struct DBsetting *)mir_alloc(sizeof(struct DBsetting)); // gets safe_free()ed in the window proc
+ DBVARIANT dbv = {0}; // freed in the dialog
+ dbv.type = DBVT_BLOB;
+ dbsetting->dbv = dbv;
+ dbsetting->hContact = hContact;
+ dbsetting->module = mir_tstrdup(module);
+ dbsetting->setting = mir_tstrdup("");
+ CreateDialogParam(hInst,MAKEINTRESOURCE(IDD_EDIT_SETTING),hwnd,EditSettingDlgProc, (LPARAM)dbsetting);
+ }
+ break;
+///////////////////////// convert to submenu
+ case MENU_CHANGE2BYTE:
+ if (convertSetting(hContact, module, setting, 0))
+ {
+ lvi.iImage = 1;
+ ListView_SetItem(hSettings,&lvi);
+ }
+ break;
+ case MENU_CHANGE2WORD:
+ if (convertSetting(hContact, module, setting, 1))
+ {
+ lvi.iImage = 2;
+ ListView_SetItem(hSettings,&lvi);
+ }
+ break;
+ case MENU_CHANGE2DWORD:
+ if (convertSetting(hContact, module, setting, 2))
+ {
+ lvi.iImage = 3;
+ ListView_SetItem(hSettings,&lvi);
+ }
+ break;
+ case MENU_CHANGE2STRING:
+ if (convertSetting(hContact, module, setting, 3))
+ {
+ lvi.iImage = 4;
+ ListView_SetItem(hSettings,&lvi);
+ }
+ break;
+ case MENU_CHANGE2UNICODE:
+ if (convertSetting(hContact, module, setting, 4))
+ {
+ lvi.iImage = 5;
+ ListView_SetItem(hSettings,&lvi);
+ }
+ break;
+///////////////////////// convert to submenu
+ case MENU_VIEWDECRYPT:
+ {
+ DBVARIANT dbv;
+ if (!DBGetContactSetting(hContact,module,setting,&dbv) && dbv.type==DBVT_ASCIIZ)
+ {
+ if (lstrcmpA(setting, "LoginPassword"))
+ {
+ char *text = mir_strdup(dbv.pszVal);
+ CallService(MS_DB_CRYPT_DECODESTRING, (WPARAM)lstrlenA(dbv.pszVal)+1, (LPARAM)text);
+ msg(text, Translate("Decoded string.."));
+ mir_free(text);
+ }
+ else
+ {
+ char *str = mir_strdup(dbv.pszVal);
+ char *str1 = str;
+ for (;*str1; ++str1)
+ {
+ const char c = *str1 ^ 0xc3;
+ if (c) *str1 = c;
+ }
+ if (UOS)
+ {
+ WCHAR *res = mir_utf8decodeW(str);
+ MessageBoxW(0, res, TranslateW(L"Decoded string.."),MB_OK);
+ mir_free(res);
+ }
+ else
+ {
+ mir_utf8decode(str, NULL);
+ MessageBoxA(0, str, Translate("Decoded string.."),MB_OK);
+ }
+ mir_free(str);
+ }
+ }
+ DBFreeVariant(&dbv);
+ }
+ break;
+ case MENU_VIEWENCRYPT:
+ {
+ DBVARIANT dbv;
+ char *text;
+ if (!DBGetContactSetting(hContact,module,setting,&dbv) && dbv.type==DBVT_ASCIIZ)
+ {
+ text = mir_tstrdup(dbv.pszVal);
+ CallService(MS_DB_CRYPT_ENCODESTRING, (WPARAM)strlen(dbv.pszVal)+1, (LPARAM)text);
+ msg(text, Translate("Encoded string.."));
+ mir_free(text);
+ }
+ DBFreeVariant(&dbv);
+ }
+ break;
+ case MENU_DECRYPT:
+ {
+ DBVARIANT dbv;
+ char *text;
+ if (!DBGetContactSetting(hContact,module,setting,&dbv) && dbv.type==DBVT_ASCIIZ)
+ {
+ text = mir_tstrdup(dbv.pszVal);
+ CallService(MS_DB_CRYPT_DECODESTRING, (WPARAM)strlen(dbv.pszVal)+1, (LPARAM)text);
+ DBWriteContactSettingString(hContact,module,setting,text);
+ mir_free(text);
+ }
+ DBFreeVariant(&dbv);
+ }
+ break;
+ case MENU_ENCRYPT:
+ {
+ DBVARIANT dbv;
+ char *text;
+ if (!DBGetContactSetting(hContact,module,setting,&dbv) && dbv.type==DBVT_ASCIIZ)
+ {
+ text = mir_tstrdup(dbv.pszVal);
+ CallService(MS_DB_CRYPT_ENCODESTRING, (WPARAM)strlen(dbv.pszVal)+1, (LPARAM)text);
+ DBWriteContactSettingString(hContact,module,setting,text);
+ mir_free(text);
+ }
+ DBFreeVariant(&dbv);
+ }
+ break;
+///////////////////////// divider
+ case MENU_WATCH_ITEM:
+
+ if (!watching)
+ {
+ addSettingToWatchList(hContact,module,setting);
+ }
+ else freeWatchListItem(i);
+ if (hwnd2watchedVarsWindow)
+ PopulateWatchedWindow(GetDlgItem(hwnd2watchedVarsWindow, IDC_VARS));
+ break;
+ case MENU_DELETE_SET:
+ DeleteSettingsFromList(hSettings, hContact, module, setting);
+ break;
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/dbeditorpp/threads.cpp b/plugins/dbeditorpp/threads.cpp
new file mode 100644
index 0000000000..7ac144adc4
--- /dev/null
+++ b/plugins/dbeditorpp/threads.cpp
@@ -0,0 +1,48 @@
+#include "headers.h"
+
+// thread stuff
+
+struct FORK_ARG {
+ HANDLE hEvent;
+ void (__cdecl *threadcode)(void*);
+ unsigned (__stdcall *threadcodeex)(void*);
+ void *arg;
+};
+
+void __cdecl forkthread_r(void *param)
+{
+ struct FORK_ARG *fa=(struct FORK_ARG*)param;
+ void (*callercode)(void*)=fa->threadcode;
+ void *arg=fa->arg;
+
+ CallService(MS_SYSTEM_THREAD_PUSH,0,0);
+
+ SetEvent(fa->hEvent);
+
+ __try {
+ callercode(arg);
+ } __finally {
+ CallService(MS_SYSTEM_THREAD_POP,0,0);
+ }
+
+ return;
+}
+
+unsigned long forkthread ( void (__cdecl *threadcode)(void*),unsigned long stacksize,void *arg)
+{
+ unsigned long rc;
+ struct FORK_ARG fa;
+
+ fa.hEvent=CreateEvent(NULL,FALSE,FALSE,NULL);
+ fa.threadcode=threadcode;
+ fa.arg=arg;
+
+ rc=_beginthread(forkthread_r,stacksize,&fa);
+
+ if ((unsigned long)-1L != rc) {
+ WaitForSingleObject(fa.hEvent,INFINITE);
+ }
+ CloseHandle(fa.hEvent);
+
+ return rc;
+}
diff --git a/plugins/dbeditorpp/watchedvars.cpp b/plugins/dbeditorpp/watchedvars.cpp
new file mode 100644
index 0000000000..08813de6ba
--- /dev/null
+++ b/plugins/dbeditorpp/watchedvars.cpp
@@ -0,0 +1,391 @@
+#include "headers.h"
+
+int addSettingToWatchList(HANDLE hContact, char* module, char* setting)
+{
+ if (WatchListArray.count == WatchListArray.size)
+ {
+ WatchListArray.size += 32;
+ WatchListArray.item = (struct DBsetting*)mir_realloc(WatchListArray.item, sizeof(struct DBsetting)*WatchListArray.size);
+ }
+ if (!WatchListArray.item) return 0;
+ if (setting && DBGetContactSetting(hContact,module, setting, &(WatchListArray.item[WatchListArray.count].dbv))) return 0;
+ WatchListArray.item[WatchListArray.count].hContact = hContact;
+ WatchListArray.item[WatchListArray.count].module = mir_tstrdup(module);
+ if (setting) WatchListArray.item[WatchListArray.count].setting = mir_tstrdup(setting);
+ else WatchListArray.item[WatchListArray.count].setting = 0;
+
+ WatchListArray.item[WatchListArray.count].WatchModule = setting?WATCH_SETTING:WATCH_MODULE;
+ WatchListArray.count++;
+ return 1;
+}
+
+void freeWatchListItem(int item)
+{
+ if (WatchListArray.item[item].module) mir_free(WatchListArray.item[item].module);
+ WatchListArray.item[item].module = 0;
+ if (WatchListArray.item[item].setting) mir_free(WatchListArray.item[item].setting);
+ WatchListArray.item[item].setting = 0;
+ DBFreeVariant(&(WatchListArray.item[item].dbv));
+ WatchListArray.item[item].hContact = 0;
+}
+
+
+void addwatchtolist(HWND hwnd2list, struct DBsetting *lParam)
+{
+ LVITEM lvItem;
+ int index;
+ char data[32], tmp[32];
+ DBVARIANT *dbv = &(lParam->dbv);
+ HANDLE hContact = lParam->hContact;
+ char *module = lParam->module;
+ char *setting = lParam->setting;
+ if (!module) return;
+ lvItem.lParam = (LPARAM)lParam->hContact;
+ lvItem.mask = LVIF_TEXT|LVIF_PARAM;
+ lvItem.iItem = 0;
+ lvItem.iSubItem = 0;
+
+ if (!setting || (int)(lParam->setting) == WATCH_MODULE) // add every item in the module and return
+ {
+ ModuleSettingLL settinglist;
+ struct DBsetting dummy;
+ struct ModSetLinkLinkItem *setting;
+ if (!EnumSettings(hContact,module,&settinglist)) return;
+ dummy.hContact = hContact;
+ dummy.module = mir_tstrdup(module);
+ setting = settinglist.first;
+ while (setting)
+ {
+ dummy.setting = setting->name;
+ addwatchtolist(hwnd2list, &dummy);
+ setting = (struct ModSetLinkLinkItem *)setting->next;
+ }
+ mir_free(dummy.module);
+ FreeModuleSettingLL(&settinglist);
+ return;
+ }
+ DBFreeVariant(&(lParam->dbv));
+ if (GetSetting(hContact, module, setting, &(lParam->dbv))) return;
+
+ if (!hContact)
+ lvItem.pszText = "NULL";
+ else
+ lvItem.pszText = (char*)GetContactName(hContact,NULL,UOS);
+
+ index = ListView_InsertItem(hwnd2list,&lvItem);
+
+ if (UOS)
+ {
+ WCHAR* ptszText = mir_a2u(lvItem.pszText);
+ ListView_SetItemTextW(hwnd2list, index, 0, ptszText);
+ mir_free(ptszText);
+ }
+
+ ListView_SetItemText(hwnd2list,index,1,module);
+ ListView_SetItemText(hwnd2list,index,2,setting);
+
+ switch (dbv->type)
+ {
+ case DBVT_BLOB:
+ {
+ int j;
+ char *data = NULL;
+ if (!(data = (char*)mir_realloc(data, 3*(dbv->cpbVal+1)) ))
+ return;
+ data[0] = '\0';
+ for (j=0; j<dbv->cpbVal; j++)
+ {
+ char tmp[16];
+ mir_snprintf(tmp, SIZEOF(tmp), "%02X ", (BYTE)dbv->pbVal[j]);
+ strcat(data, tmp);
+ }
+ ListView_SetItemText(hwnd2list,index,4,data);
+ ListView_SetItemText(hwnd2list,index,3,"BLOB");
+ mir_free(data);
+ }
+ break;
+ case DBVT_BYTE:
+ mir_snprintf(data, 32, "0x%02X (%s)", dbv->bVal, itoa(dbv->bVal,tmp,10));
+ ListView_SetItemText(hwnd2list,index,4,data);
+ ListView_SetItemText(hwnd2list,index,3,"BYTE");
+ break;
+ case DBVT_WORD:
+ mir_snprintf(data, 32, "0x%04X (%s)", dbv->wVal, itoa(dbv->wVal,tmp,10));
+ ListView_SetItemText(hwnd2list,index,4,data);
+ ListView_SetItemText(hwnd2list,index,3,"WORD");
+ break;
+ case DBVT_DWORD:
+ mir_snprintf(data, 32, "0x%08X (%s)", dbv->dVal, itoa(dbv->dVal,tmp,10));
+ ListView_SetItemText(hwnd2list,index,4,data);
+ ListView_SetItemText(hwnd2list,index,3,"DWORD");
+ break;
+ case DBVT_ASCIIZ:
+ ListView_SetItemText(hwnd2list,index,4,dbv->pszVal);
+ ListView_SetItemText(hwnd2list,index,3,"STRING");
+ break;
+ case DBVT_UTF8:
+ {
+ if (UOS)
+ {
+ int length = (int)strlen(dbv->pszVal) + 1;
+ WCHAR *wc = (WCHAR*)_alloca(length*sizeof(WCHAR));
+ MultiByteToWideChar(CP_UTF8, 0, dbv->pszVal, -1, wc, length);
+ ListView_SetItemTextW(hwnd2list,index,4,wc);
+ }
+ else {
+ // convert from UTF8
+ ListView_SetItemText(hwnd2list,index,4,dbv->pszVal);
+ }
+ ListView_SetItemText(hwnd2list,index,3,"UNICODE");
+ }
+ break;
+
+ }
+}
+
+void PopulateWatchedWindow(HWND hwnd)
+{
+ int i;
+ ListView_DeleteAllItems(hwnd);
+ for (i=0;i<WatchListArray.count;i++)
+ {
+ addwatchtolist(hwnd, &(WatchListArray.item[i]));
+ }
+}
+
+void freeAllWatches()
+{
+ int i;
+ for (i=0;i<WatchListArray.count;i++)
+ {
+ freeWatchListItem(i);
+ }
+ mir_free(WatchListArray.item);
+ WatchListArray.item = 0;
+ WatchListArray.count = 0;
+}
+
+int WatchDialogResize(HWND hwnd,LPARAM lParam,UTILRESIZECONTROL *urc)
+{
+ switch(urc->wId)
+ {
+ case IDC_VARS:
+ urc->rcItem.top = 0;
+ urc->rcItem.bottom = urc->dlgNewSize.cy;
+ urc->rcItem.left = 0;
+ urc->rcItem.right = urc->dlgNewSize.cx;
+ return RD_ANCHORY_CUSTOM|RD_ANCHORX_CUSTOM;
+ }
+ return RD_ANCHORX_LEFT|RD_ANCHORY_TOP;
+}
+
+INT_PTR CALLBACK WatchDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch(msg)
+ {
+ case WM_INITDIALOG:
+ {
+ // setup the list...
+ LVCOLUMN sLC;
+
+ sLC.fmt = LVCFMT_LEFT;
+ ListView_SetExtendedListViewStyle(GetDlgItem(hwnd, IDC_VARS), 32|LVS_EX_SUBITEMIMAGES); //LVS_EX_FULLROWSELECT
+ sLC.mask = LVCF_FMT | LVCF_TEXT | LVCF_SUBITEM | LVCF_WIDTH;
+
+ sLC.pszText = Translate("Contact"); sLC.cx = 80;
+ ListView_InsertColumn(GetDlgItem(hwnd, IDC_VARS),0,&sLC);
+ sLC.pszText = Translate("Module"); sLC.cx = 80;
+ ListView_InsertColumn(GetDlgItem(hwnd, IDC_VARS),1,&sLC);
+ sLC.pszText = Translate("Setting"); sLC.cx = 80;
+ ListView_InsertColumn(GetDlgItem(hwnd, IDC_VARS),2,&sLC);
+ sLC.pszText = Translate("Type"); sLC.cx = 60;
+ ListView_InsertColumn(GetDlgItem(hwnd, IDC_VARS),3,&sLC);
+ sLC.pszText = Translate("Data"); sLC.cx = 300;
+ ListView_InsertColumn(GetDlgItem(hwnd, IDC_VARS),4,&sLC);
+
+ PopulateWatchedWindow(GetDlgItem(hwnd, IDC_VARS));
+/* if (DBGetContactSettingByte("NULL", modname, "LoadWatchesOnStartup",0))
+ {
+ MENUITEMINFO mmi;
+ mmi.cbSize = sizeof(MENUITEMINFO);
+ mmi.fMask = MIIM_STATE;
+ mmi.fState = MFS_CHECKED;
+ SetMenuItemInfo(GetMenu(hwnd), MENU_LOADAUTOMATCIALLY, FALSE, &mmi);
+ }
+*/ CallService(MS_LANGPACK_TRANSLATEMENU,(WPARAM)GetMenu(hwnd),0);
+ CallService(MS_LANGPACK_TRANSLATEMENU,(WPARAM)GetSubMenu(GetMenu(hwnd),0),0);
+ TranslateDialogDefault(hwnd);
+ // do the icon
+ SendMessage(hwnd,WM_SETICON,ICON_BIG,(LPARAM)LoadIcon(hInst,MAKEINTRESOURCE(ICO_REGEDIT)));
+ }
+ return TRUE;
+ // for the resize
+ case WM_GETMINMAXINFO:
+ {
+ MINMAXINFO *mmi=(MINMAXINFO*)lParam;
+ mmi->ptMinTrackSize.x=200;
+ mmi->ptMinTrackSize.y=90;
+ return 0;
+ }
+ case WM_SIZE:
+ {
+ UTILRESIZEDIALOG urd;
+ ZeroMemory(&urd,sizeof(urd));
+ urd.cbSize=sizeof(urd);
+ urd.hInstance=hInst;
+ urd.hwndDlg=hwnd;
+ urd.lParam=(LPARAM)0;
+ urd.lpTemplate=MAKEINTRESOURCE(IDD_WATCH_DIAG);
+ urd.pfnResizer=WatchDialogResize;
+ CallService(MS_UTILS_RESIZEDIALOG,0,(LPARAM)&urd);
+ break;
+
+ }
+ case WM_COMMAND:
+ switch(LOWORD(wParam))
+ {
+ case MENU_REMALL_WATCHES:
+ freeAllWatches();
+ ListView_DeleteAllItems(GetDlgItem(hwnd, IDC_VARS));
+ break;
+ case MENU_EXIT:
+ case IDCANCEL:
+ hwnd2watchedVarsWindow = 0;
+ DestroyWindow(hwnd);
+ break;
+ case MENU_REFRESH:
+ PopulateWatchedWindow(GetDlgItem(hwnd, IDC_VARS));
+ break;
+ /* case MENU_LOADAUTOMATCIALLY:
+ {
+ MENUITEMINFO mmi;
+ mmi.cbSize = sizeof(MENUITEMINFO);
+ mmi.fMask = MIIM_STATE;
+ GetMenuItemInfo(GetSubMenu(GetMenu(hwnd),2), MENU_LOADAUTOMATCIALLY, FALSE, &mmi);
+ if (mmi.fState == MFS_CHECKED)
+ {
+ mmi.fState = MFS_UNCHECKED;
+ DBWriteContactSettingByte(NULL,modname, "LoadWatchesOnStartup", 0);
+ SetMenuItemInfo(GetSubMenu(GetMenu(hwnd),2), MENU_LOADAUTOMATCIALLY, FALSE, &mmi);
+ }
+ else if (mmi.fState == MFS_UNCHECKED)
+ {
+ mmi.fState = MFS_CHECKED;
+ DBWriteContactSettingByte(NULL,modname, "LoadWatchesOnStartup", 1);
+ SetMenuItemInfo(GetSubMenu(GetMenu(hwnd),2), MENU_LOADAUTOMATCIALLY, FALSE, &mmi);
+ }
+ }
+ break;
+ case MENU_SAVE_WATCHES:
+ saveWatchedList();
+ break;
+ case MENU_LOAD_WATCHES:
+ loadWatchedList();
+ break;
+ */ }
+ break;
+ case WM_NOTIFY:
+ switch(LOWORD(wParam))
+ {
+ case IDC_VARS:
+ switch(((NMHDR*)lParam)->code)
+ {
+ case NM_DBLCLK:
+ {
+ LVHITTESTINFO hti;
+ LVITEM lvi;
+ hti.pt=((NMLISTVIEW*)lParam)->ptAction;
+ if (ListView_SubItemHitTest(GetDlgItem(hwnd,IDC_VARS),&hti) >-1)
+ {
+ if (hti.flags&LVHT_ONITEM)
+ {
+ lvi.mask = LVIF_PARAM;
+ lvi.iItem = hti.iItem;
+ lvi.iSubItem = 0;
+ if (ListView_GetItem(GetDlgItem(hwnd,IDC_VARS),&lvi))
+ {
+ ItemInfo ii;
+ ii.hContact = (HANDLE)lvi.lParam;
+ ListView_GetItemText(GetDlgItem(hwnd,IDC_VARS),hti.iItem,1,ii.module,128);
+ ListView_GetItemText(GetDlgItem(hwnd,IDC_VARS),hti.iItem,2,ii.setting,128);
+ ii.type = FW_SETTINGNAME;
+ SendMessage(hwnd2mainWindow,WM_FINDITEM,(WPARAM)&ii,0);
+ }
+ }
+ }
+ }
+ break;
+ }
+ break;
+ }
+ break;
+ }
+ return 0;
+}
+
+
+void popupWatchedVar(HANDLE hContact,const char* module,const char* setting)
+{
+ POPUPDATAEX ppd = {0};
+ HICON hIcon = LoadIcon(hInst, MAKEINTRESOURCE(ICO_REGEDIT));
+ char lpzContactName[MAX_CONTACTNAME];
+ char lpzText[MAX_SECONDLINE];
+ COLORREF colorBack = DBGetContactSettingDword(NULL,modname,"PopupColour",RGB(255,0,0));
+ COLORREF colorText = RGB(0,0,0);
+ DBVARIANT dbv;
+ int timeout = DBGetContactSettingByte(NULL,modname,"PopupDelay",3);
+
+ if (hContact)
+ {
+ // contacts nick
+ char szProto[256];
+ if (GetValue(hContact,"Protocol","p",szProto,SIZEOF(szProto)))
+ mir_snprintf(lpzContactName, MAX_SECONDLINE, "%s (%s)", (char*)GetContactName(hContact, szProto, 0), szProto);
+ else
+ mir_snprintf(lpzContactName, MAX_SECONDLINE, nick_unknown);
+ }
+ else
+ {
+ strcpy(lpzContactName,Translate("Settings"));
+ }
+ // 2nd line
+ if (!GetSetting(hContact, module, setting, &dbv))
+ {
+ switch (dbv.type)
+ {
+ case DBVT_BYTE:
+ mir_snprintf(lpzText, SIZEOF(lpzText), Translate("Database Setting Changed: \nModule: \"%s\" , Setting: \"%s\"\nNew Value: (BYTE) %d"), module, setting, dbv.bVal);
+ break;
+ case DBVT_WORD:
+ mir_snprintf(lpzText, SIZEOF(lpzText), Translate("Database Setting Changed: \nModule: \"%s\" , Setting: \"%s\"\nNew Value: (WORD) %d"), module, setting, dbv.wVal);
+ break;
+ case DBVT_DWORD:
+ mir_snprintf(lpzText, SIZEOF(lpzText), Translate("Database Setting Changed: \nModule: \"%s\" , Setting: \"%s\"\nNew Value: (DWORD) 0x%X"), module, setting, dbv.dVal);
+ break;
+ case DBVT_ASCIIZ:
+ mir_snprintf(lpzText, SIZEOF(lpzText), Translate("Database Setting Changed: \nModule: \"%s\" , Setting: \"%s\"\nNew Value: \"%s\""), module, setting, dbv.pszVal);
+ break;
+ case DBVT_UTF8:
+ mir_snprintf(lpzText, SIZEOF(lpzText), Translate("Database Setting Changed: \nModule: \"%s\" , Setting: \"%s\"\nNew Value (UTF8): \"%s\""), module, setting, dbv.pszVal);
+ break;
+ default:
+ return;
+ }
+ }
+ else return;
+
+ DBFreeVariant(&dbv);
+
+ ppd.lchContact = (HANDLE)hContact;
+ ppd.lchIcon = hIcon;
+ lstrcpyn(ppd.lpzContactName, lpzContactName,MAX_CONTACTNAME);
+ lstrcpyn(ppd.lpzText, lpzText,MAX_SECONDLINE);
+ ppd.colorBack = colorBack;
+ ppd.colorText = colorText;
+ ppd.PluginWindowProc = NULL;
+ ppd.PluginData = NULL;
+ ppd.iSeconds = timeout?timeout:-1;
+
+ //Now that every field has been filled, we want to see the popup.
+ CallService(MS_POPUP_ADDPOPUPEX, (WPARAM)&ppd, 0);
+}
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 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?fileVersion 4.0.0?>
+
+<cproject>
+<storageModule moduleId="org.eclipse.cdt.core.settings">
+<cconfiguration id="cdt.managedbuild.config.gnu.mingw.so.debug.15108384">
+<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.mingw.so.debug.15108384" moduleId="org.eclipse.cdt.core.settings" name="Debug">
+<externalSettings>
+<externalSetting>
+<entry flags="VALUE_WORKSPACE_PATH" kind="includePath" name="/extraicons"/>
+<entry flags="VALUE_WORKSPACE_PATH" kind="libraryPath" name="/extraicons/Debug"/>
+</externalSetting>
+</externalSettings>
+<extensions>
+<extension id="org.eclipse.cdt.core.PE" point="org.eclipse.cdt.core.BinaryParser"/>
+<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+</extensions>
+</storageModule>
+<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+<configuration artifactExtension="dll" artifactName="extraicons" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.sharedLib" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.sharedLib" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.mingw.so.debug.15108384" name="Debug" parent="cdt.managedbuild.config.gnu.mingw.so.debug">
+<folderInfo id="cdt.managedbuild.config.gnu.mingw.so.debug.15108384." name="/" resourcePath="">
+<toolChain id="cdt.managedbuild.toolchain.gnu.mingw.so.debug.1630533798" name="MinGW GCC" superClass="cdt.managedbuild.toolchain.gnu.mingw.so.debug">
+<targetPlatform id="cdt.managedbuild.target.gnu.platform.mingw.so.debug.870504549" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.mingw.so.debug"/>
+<builder buildPath="${workspace_loc:/extraicons/Debug}" id="cdt.managedbuild.tool.gnu.builder.mingw.base.350801954" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="CDT Internal Builder" superClass="cdt.managedbuild.tool.gnu.builder.mingw.base"/>
+<tool commandLinePattern="${COMMAND} ${FLAGS} ${OUTPUT_FLAG}&quot;${OUTPUT_PREFIX}${OUTPUT}&quot; ${INPUTS}" id="cdt.managedbuild.tool.gnu.assembler.mingw.so.debug.1233286928" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.mingw.so.debug">
+<option id="gnu.both.asm.option.include.paths.29026724" name="Include paths (-I)" superClass="gnu.both.asm.option.include.paths"/>
+<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1442357417" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
+</tool>
+<tool id="cdt.managedbuild.tool.gnu.archiver.mingw.base.1382733034" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.mingw.base"/>
+<tool commandLinePattern="${COMMAND} ${FLAGS} ${OUTPUT_FLAG}&quot;${OUTPUT_PREFIX}${OUTPUT}&quot; ${INPUTS}" id="cdt.managedbuild.tool.gnu.cpp.compiler.mingw.so.debug.1415411771" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.mingw.so.debug">
+<option id="gnu.cpp.compiler.option.include.paths.678483963" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" valueType="includePath">
+<listOptionValue builtIn="false" value="&quot;C:\Desenvolvimento\Miranda\include&quot;"/>
+<listOptionValue builtIn="false" value="&quot;${workspace_loc:/extraicons/sdk}&quot;"/>
+<listOptionValue builtIn="false" value="&quot;C:\Desenvolvimento\Miranda\include\mingw&quot;"/>
+</option>
+<option id="gnu.cpp.compiler.mingw.so.debug.option.debugging.level.553002841" name="Debug Level" superClass="gnu.cpp.compiler.mingw.so.debug.option.debugging.level" value="gnu.cpp.compiler.debugging.level.max" valueType="enumerated"/>
+<option id="gnu.cpp.compiler.mingw.so.debug.option.optimization.level.1074111021" name="Optimization Level" superClass="gnu.cpp.compiler.mingw.so.debug.option.optimization.level" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/>
+<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1142292324" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
+</tool>
+<tool commandLinePattern="${COMMAND} ${FLAGS} ${OUTPUT_FLAG}&quot;${OUTPUT_PREFIX}${OUTPUT}&quot; ${INPUTS}" id="cdt.managedbuild.tool.gnu.c.compiler.mingw.so.debug.678236892" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.mingw.so.debug">
+<option defaultValue="gnu.c.optimization.level.none" id="gnu.c.compiler.mingw.so.debug.option.optimization.level.885283172" name="Optimization Level" superClass="gnu.c.compiler.mingw.so.debug.option.optimization.level" valueType="enumerated"/>
+<option id="gnu.c.compiler.mingw.so.debug.option.debugging.level.1962008655" name="Debug Level" superClass="gnu.c.compiler.mingw.so.debug.option.debugging.level" value="gnu.c.debugging.level.max" valueType="enumerated"/>
+<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.971451912" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
+</tool>
+<tool id="cdt.managedbuild.tool.gnu.c.linker.mingw.so.debug.650923336" name="MinGW C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.mingw.so.debug">
+<option defaultValue="true" id="gnu.c.link.mingw.so.debug.option.shared.1575843488" name="Shared (-shared)" superClass="gnu.c.link.mingw.so.debug.option.shared" valueType="boolean"/>
+</tool>
+<tool commandLinePattern="${COMMAND} ${FLAGS} ${OUTPUT_FLAG}&quot;C:\Desenvolvimento\Miranda\bin\Debug Unicode\Plugins\${OUTPUT_PREFIX}${OUTPUT}&quot; ${INPUTS}" id="cdt.managedbuild.tool.gnu.cpp.linker.mingw.so.debug.836489507" name="MinGW C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.mingw.so.debug">
+<option id="gnu.cpp.link.option.paths.1417684678" name="Library search path (-L)" superClass="gnu.cpp.link.option.paths"/>
+<option defaultValue="true" id="gnu.cpp.link.mingw.so.debug.option.shared.1239249880" name="Shared (-shared)" superClass="gnu.cpp.link.mingw.so.debug.option.shared" valueType="boolean"/>
+<option id="gnu.cpp.link.option.libs.1498281393" name="Libraries (-l)" superClass="gnu.cpp.link.option.libs" valueType="libs">
+<listOptionValue builtIn="false" value="gdi32"/>
+<listOptionValue builtIn="false" value="comctl32"/>
+</option>
+<option id="gnu.cpp.link.option.flags.714506212" name="Linker flags" superClass="gnu.cpp.link.option.flags" value="" valueType="string"/>
+<inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.417851543" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
+<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
+<additionalInput kind="additionalinput" paths="$(LIBS)"/>
+</inputType>
+<outputType id="cdt.managedbuild.tool.gnu.cpp.linker.mingw.so.debug.output.314794898" outputPrefix="" superClass="cdt.managedbuild.tool.gnu.cpp.linker.mingw.so.debug.output"/>
+</tool>
+</toolChain>
+</folderInfo>
+<sourceEntries>
+<entry excluding="multitree|resource.aps|extraicons.plg|extraicons.opt|extraicons.ncb" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
+</sourceEntries>
+</configuration>
+</storageModule>
+<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets">
+<buildTargets>
+<target name="build" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
+<buildCommand>make</buildCommand>
+<buildArguments/>
+<buildTarget>build</buildTarget>
+<stopOnError>true</stopOnError>
+<useDefaultCommand>true</useDefaultCommand>
+<runAllBuilders>true</runAllBuilders>
+</target>
+</buildTargets>
+</storageModule>
+<storageModule moduleId="org.eclipse.cdt.core.language.mapping"/>
+<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
+<storageModule moduleId="scannerConfiguration">
+<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile"/>
+<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="makefileGenerator">
+<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.mingw.so.debug.15108384;cdt.managedbuild.config.gnu.mingw.so.debug.15108384.;cdt.managedbuild.tool.gnu.c.compiler.mingw.so.debug.678236892;cdt.managedbuild.tool.gnu.c.compiler.input.971451912">
+<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
+<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="makefileGenerator">
+<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+</scannerConfigBuildInfo>
+<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.mingw.so.release.1800759879;cdt.managedbuild.config.gnu.mingw.so.release.1800759879.;cdt.managedbuild.tool.gnu.c.compiler.mingw.so.release.138264807;cdt.managedbuild.tool.gnu.c.compiler.input.1743420690">
+<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
+<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="makefileGenerator">
+<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+</scannerConfigBuildInfo>
+<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.mingw.so.release.1800759879;cdt.managedbuild.config.gnu.mingw.so.release.1800759879.;cdt.managedbuild.tool.gnu.cpp.compiler.mingw.so.release.1742438449;cdt.managedbuild.tool.gnu.cpp.compiler.input.1065609886">
+<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP"/>
+<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="makefileGenerator">
+<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+</scannerConfigBuildInfo>
+<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.mingw.so.debug.15108384;cdt.managedbuild.config.gnu.mingw.so.debug.15108384.;cdt.managedbuild.tool.gnu.cpp.compiler.mingw.so.debug.1415411771;cdt.managedbuild.tool.gnu.cpp.compiler.input.1142292324">
+<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP"/>
+<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="makefileGenerator">
+<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+</scannerConfigBuildInfo>
+</storageModule>
+</cconfiguration>
+<cconfiguration id="cdt.managedbuild.config.gnu.mingw.so.release.1800759879">
+<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.mingw.so.release.1800759879" moduleId="org.eclipse.cdt.core.settings" name="Release">
+<externalSettings>
+<externalSetting>
+<entry flags="VALUE_WORKSPACE_PATH" kind="includePath" name="/extraicons"/>
+<entry flags="VALUE_WORKSPACE_PATH" kind="libraryPath" name="/extraicons/Release"/>
+</externalSetting>
+</externalSettings>
+<extensions>
+<extension id="org.eclipse.cdt.core.PE" point="org.eclipse.cdt.core.BinaryParser"/>
+<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+</extensions>
+</storageModule>
+<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+<configuration artifactExtension="dll" artifactName="extraicons" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.sharedLib" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.sharedLib" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.mingw.so.release.1800759879" name="Release" parent="cdt.managedbuild.config.gnu.mingw.so.release">
+<folderInfo id="cdt.managedbuild.config.gnu.mingw.so.release.1800759879." name="/" resourcePath="">
+<toolChain id="cdt.managedbuild.toolchain.gnu.mingw.so.release.635224325" name="MinGW GCC" superClass="cdt.managedbuild.toolchain.gnu.mingw.so.release">
+<targetPlatform id="cdt.managedbuild.target.gnu.platform.mingw.so.release.1715194353" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.mingw.so.release"/>
+<builder buildPath="${workspace_loc:/extraicons/Release}" id="cdt.managedbuild.tool.gnu.builder.mingw.base.1041661913" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="CDT Internal Builder" superClass="cdt.managedbuild.tool.gnu.builder.mingw.base"/>
+<tool id="cdt.managedbuild.tool.gnu.assembler.mingw.so.release.1662457277" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.mingw.so.release">
+<option id="gnu.both.asm.option.include.paths.99391252" name="Include paths (-I)" superClass="gnu.both.asm.option.include.paths" valueType="includePath">
+<listOptionValue builtIn="false" value="&quot;C:\Desenvolvimento\Miranda\include&quot;"/>
+<listOptionValue builtIn="false" value="&quot;C:\Desenvolvimento\Miranda\include\mingw&quot;"/>
+</option>
+<inputType id="cdt.managedbuild.tool.gnu.assembler.input.857296392" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
+</tool>
+<tool id="cdt.managedbuild.tool.gnu.archiver.mingw.base.1311905162" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.mingw.base"/>
+<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.mingw.so.release.1742438449" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.mingw.so.release">
+<option id="gnu.cpp.compiler.mingw.so.release.option.optimization.level.805732906" name="Optimization Level" superClass="gnu.cpp.compiler.mingw.so.release.option.optimization.level" value="gnu.cpp.compiler.optimization.level.most" valueType="enumerated"/>
+<option id="gnu.cpp.compiler.mingw.so.release.option.debugging.level.998079392" name="Debug Level" superClass="gnu.cpp.compiler.mingw.so.release.option.debugging.level" value="gnu.cpp.compiler.debugging.level.none" valueType="enumerated"/>
+<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1065609886" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
+</tool>
+<tool id="cdt.managedbuild.tool.gnu.c.compiler.mingw.so.release.138264807" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.mingw.so.release">
+<option id="gnu.c.compiler.mingw.so.release.option.debugging.level.2136199946" name="Debug Level" superClass="gnu.c.compiler.mingw.so.release.option.debugging.level" value="gnu.c.debugging.level.none" valueType="enumerated"/>
+<option defaultValue="gnu.c.optimization.level.most" id="gnu.c.compiler.mingw.so.release.option.optimization.level.681631198" name="Optimization Level" superClass="gnu.c.compiler.mingw.so.release.option.optimization.level" valueType="enumerated"/>
+<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1743420690" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
+</tool>
+<tool id="cdt.managedbuild.tool.gnu.c.linker.mingw.so.release.924915323" name="MinGW C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.mingw.so.release">
+<option defaultValue="true" id="gnu.c.link.mingw.so.release.option.shared.1414356821" name="Shared (-shared)" superClass="gnu.c.link.mingw.so.release.option.shared" valueType="boolean"/>
+</tool>
+<tool id="cdt.managedbuild.tool.gnu.cpp.linker.mingw.so.release.811741083" name="MinGW C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.mingw.so.release">
+<option defaultValue="true" id="gnu.cpp.link.mingw.so.release.option.shared.74104523" name="Shared (-shared)" superClass="gnu.cpp.link.mingw.so.release.option.shared" valueType="boolean"/>
+<inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.813227634" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
+<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
+<additionalInput kind="additionalinput" paths="$(LIBS)"/>
+</inputType>
+</tool>
+</toolChain>
+</folderInfo>
+<sourceEntries>
+<entry excluding="multitree|resource.aps|extraicons.plg|extraicons.opt|extraicons.ncb" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
+</sourceEntries>
+</configuration>
+</storageModule>
+<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets">
+<buildTargets>
+<target name="build" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
+<buildCommand>make</buildCommand>
+<buildArguments/>
+<buildTarget>build</buildTarget>
+<stopOnError>true</stopOnError>
+<useDefaultCommand>true</useDefaultCommand>
+<runAllBuilders>true</runAllBuilders>
+</target>
+</buildTargets>
+</storageModule>
+<storageModule moduleId="org.eclipse.cdt.core.language.mapping"/>
+<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
+<storageModule moduleId="scannerConfiguration">
+<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile"/>
+<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="makefileGenerator">
+<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.mingw.so.debug.15108384;cdt.managedbuild.config.gnu.mingw.so.debug.15108384.;cdt.managedbuild.tool.gnu.c.compiler.mingw.so.debug.678236892;cdt.managedbuild.tool.gnu.c.compiler.input.971451912">
+<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
+<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="makefileGenerator">
+<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+</scannerConfigBuildInfo>
+<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.mingw.so.release.1800759879;cdt.managedbuild.config.gnu.mingw.so.release.1800759879.;cdt.managedbuild.tool.gnu.c.compiler.mingw.so.release.138264807;cdt.managedbuild.tool.gnu.c.compiler.input.1743420690">
+<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
+<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="makefileGenerator">
+<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+</scannerConfigBuildInfo>
+<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.mingw.so.release.1800759879;cdt.managedbuild.config.gnu.mingw.so.release.1800759879.;cdt.managedbuild.tool.gnu.cpp.compiler.mingw.so.release.1742438449;cdt.managedbuild.tool.gnu.cpp.compiler.input.1065609886">
+<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP"/>
+<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="makefileGenerator">
+<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+</scannerConfigBuildInfo>
+<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.mingw.so.debug.15108384;cdt.managedbuild.config.gnu.mingw.so.debug.15108384.;cdt.managedbuild.tool.gnu.cpp.compiler.mingw.so.debug.1415411771;cdt.managedbuild.tool.gnu.cpp.compiler.input.1142292324">
+<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP"/>
+<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="makefileGenerator">
+<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+</scannerConfigBuildInfo>
+</storageModule>
+</cconfiguration>
+</storageModule>
+<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+<project id="extraicons.cdt.managedbuild.target.gnu.mingw.so.959706806" name="Shared Library" projectType="cdt.managedbuild.target.gnu.mingw.so"/>
+</storageModule>
+</cproject>
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 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>extraicons</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
+ <triggers>clean,full,incremental,</triggers>
+ <arguments>
+ <dictionary>
+ <key>?name?</key>
+ <value></value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.append_environment</key>
+ <value>true</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.buildArguments</key>
+ <value></value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.buildCommand</key>
+ <value>make</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.buildLocation</key>
+ <value>${workspace_loc:/extraicons/Debug}</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.contents</key>
+ <value>org.eclipse.cdt.make.core.activeConfigSettings</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.enableAutoBuild</key>
+ <value>false</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.enableCleanBuild</key>
+ <value>true</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.enableFullBuild</key>
+ <value>true</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.stopOnError</key>
+ <value>true</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key>
+ <value>true</value>
+ </dictionary>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.cdt.core.ccnature</nature>
+ <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
+ <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
+ <nature>org.eclipse.cdt.core.cnature</nature>
+ </natures>
+</projectDescription>
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<ProtoInfo> 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
--- /dev/null
+++ b/plugins/extraicons/Docs/extraicons.png
Binary files 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 <string>
+
+#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 <vector>
+#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<BaseExtraIcon*> 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://<user>:<password>@<ftp>/<path>
+
+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..b757122849
--- /dev/null
+++ b/plugins/extraicons/commons.h
@@ -0,0 +1,120 @@
+/*
+ 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 <windows.h>
+#include <tchar.h>
+#include <stdio.h>
+#include <time.h>
+#include <commctrl.h>
+
+#include <map>
+#include <vector>
+#include <string>
+#include <algorithm>
+using namespace std;
+
+// Miranda headers
+#define MIRANDA_VER 0x0800
+#define MIRANDA_CUSTOM_LP
+
+#include <newpluginapi.h>
+#include <m_system.h>
+#include <m_protocols.h>
+#include <m_protosvc.h>
+#include <m_clui.h>
+#include <m_clist.h>
+#include <m_cluiframes.h>
+#include <m_contacts.h>
+#include <m_langpack.h>
+#include <m_database.h>
+#include <m_options.h>
+#include <m_utils.h>
+#include <m_updater.h>
+#include <m_metacontacts.h>
+#include <m_icolib.h>
+#include <m_skin.h>
+#include <m_userinfo.h>
+
+#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<HANDLE> hHooks;
+
+extern vector<BaseExtraIcon*> registeredExtraIcons;
+extern vector<ExtraIcon*> extraIconsByHandle;
+extern vector<ExtraIcon*> extraIconsBySlot;
+void RebuildListsBasedOnGroups(vector<ExtraIconGroup *> &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<HANDLE> hHooks;
+vector<HANDLE> hServices;
+vector<BaseExtraIcon*> registeredExtraIcons;
+vector<ExtraIcon*> extraIconsByHandle;
+vector<ExtraIcon*> 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<ExtraIconGroup *> &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<ExtraIconGroup *> &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<const ExtraIcon *, const ExtraIcon *, bool>
+{
+ bool operator()(const ExtraIcon * one, const ExtraIcon * two) const
+ {
+ return *one < *two;
+ }
+};
+
+void RebuildListsBasedOnGroups(vector<ExtraIconGroup *> &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<ExtraIconGroup *> 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.vcxproj b/plugins/extraicons/extraicons.vcxproj
new file mode 100644
index 0000000000..ae64d2e5d4
--- /dev/null
+++ b/plugins/extraicons/extraicons.vcxproj
@@ -0,0 +1,720 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug Unicode|Win32">
+ <Configuration>Debug Unicode</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug Unicode|x64">
+ <Configuration>Debug Unicode</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release Unicode|Win32">
+ <Configuration>Release Unicode</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release Unicode|x64">
+ <Configuration>Release Unicode</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{778D0DEB-C798-45D3-98E0-ABAB242573C8}</ProjectGuid>
+ <RootNamespace>extraicons</RootNamespace>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)/Plugins\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Configuration)64/Plugins\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)/Obj/$(ProjectName)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Configuration)64/Obj/$(ProjectName)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">$(SolutionDir)$(Configuration)/Plugins\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">$(SolutionDir)$(Configuration)64/Plugins\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">$(SolutionDir)$(Configuration)/Obj/$(ProjectName)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">$(SolutionDir)$(Configuration)64/Obj/$(ProjectName)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">false</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">false</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)/Plugins\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Configuration)64/Plugins\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)/Obj/$(ProjectName)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Configuration)64/Obj/$(ProjectName)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">$(SolutionDir)$(Configuration)/Plugins\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">$(SolutionDir)$(Configuration)64/Plugins\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">$(SolutionDir)$(Configuration)/Obj/$(ProjectName)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">$(SolutionDir)$(Configuration)64/Obj/$(ProjectName)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">true</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">true</LinkIncremental>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ <TypeLibraryName>.\Debug/extraicons.tlb</TypeLibraryName>
+ <HeaderFileName>
+ </HeaderFileName>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>../../include;sdk;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BrowseInformation>true</BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>commons.h</PrecompiledHeaderFile>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0417</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalOptions>/ALIGN:4096 /filealign:0x200 /ignore:4108 %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <BaseAddress>0x3EC20000</BaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ <Bscmake>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <OutputFile>.\Debug/extraicons.bsc</OutputFile>
+ </Bscmake>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TypeLibraryName>.\Debug/extraicons.tlb</TypeLibraryName>
+ <HeaderFileName>
+ </HeaderFileName>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>../../include;sdk;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BrowseInformation>true</BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>commons.h</PrecompiledHeaderFile>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0417</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalOptions>/ALIGN:4096 /filealign:0x200 /ignore:4108 %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <BaseAddress>0x3EC20000</BaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ </Link>
+ <Bscmake>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <OutputFile>.\Debug/extraicons.bsc</OutputFile>
+ </Bscmake>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ <TypeLibraryName>.\Unicode_Release/extraicons.tlb</TypeLibraryName>
+ <HeaderFileName>
+ </HeaderFileName>
+ </Midl>
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <AdditionalIncludeDirectories>../../include;sdk;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>commons.h</PrecompiledHeaderFile>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0417</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalOptions>/ALIGN:4096 /filealign:0x200 /ignore:4108 %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+ <BaseAddress>0x3EC20000</BaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ <Bscmake>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <OutputFile>.\Unicode_Release/extraicons.bsc</OutputFile>
+ </Bscmake>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TypeLibraryName>.\Unicode_Release/extraicons.tlb</TypeLibraryName>
+ <HeaderFileName>
+ </HeaderFileName>
+ </Midl>
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <AdditionalIncludeDirectories>../../include;sdk;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>commons.h</PrecompiledHeaderFile>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0417</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalOptions>/ALIGN:4096 /filealign:0x200 /ignore:4108 %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+ <BaseAddress>0x3EC20000</BaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ <Bscmake>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <OutputFile>.\Unicode_Release/extraicons.bsc</OutputFile>
+ </Bscmake>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ <TypeLibraryName>.\Release/extraicons.tlb</TypeLibraryName>
+ <HeaderFileName>
+ </HeaderFileName>
+ </Midl>
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>Default</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>../../include;sdk;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>commons.h</PrecompiledHeaderFile>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0417</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalOptions>/ALIGN:4096 /filealign:0x200 /ignore:4108 %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+ <BaseAddress>0x3EC20000</BaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ <Bscmake>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <OutputFile>.\Release/extraicons.bsc</OutputFile>
+ </Bscmake>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TypeLibraryName>.\Release/extraicons.tlb</TypeLibraryName>
+ <HeaderFileName>
+ </HeaderFileName>
+ </Midl>
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>Default</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>../../include;sdk;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>commons.h</PrecompiledHeaderFile>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0417</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalOptions>/ALIGN:4096 /filealign:0x200 /ignore:4108 %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+ <BaseAddress>0x3EC20000</BaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ </Link>
+ <Bscmake>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <OutputFile>.\Release/extraicons.bsc</OutputFile>
+ </Bscmake>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ <TypeLibraryName>.\Unicode_Debug/extraicons.tlb</TypeLibraryName>
+ <HeaderFileName>
+ </HeaderFileName>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>../../include;sdk;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BrowseInformation>true</BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>commons.h</PrecompiledHeaderFile>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0417</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalOptions>/ALIGN:4096 /filealign:0x200 /ignore:4108 %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <BaseAddress>0x3EC20000</BaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ <Bscmake>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <OutputFile>.\Unicode_Debug/extraicons.bsc</OutputFile>
+ </Bscmake>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TypeLibraryName>.\Unicode_Debug/extraicons.tlb</TypeLibraryName>
+ <HeaderFileName>
+ </HeaderFileName>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>../../include;sdk;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BrowseInformation>true</BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>commons.h</PrecompiledHeaderFile>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0417</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalOptions>/ALIGN:4096 /filealign:0x200 /ignore:4108 %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <BaseAddress>0x3EC20000</BaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ </Link>
+ <Bscmake>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <OutputFile>.\Unicode_Debug/extraicons.bsc</OutputFile>
+ </Bscmake>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClInclude Include="BaseExtraIcon.h" />
+ <ClInclude Include="CallbackExtraIcon.h" />
+ <ClInclude Include="commons.h" />
+ <ClInclude Include="DefaultExtraIcons.h" />
+ <ClInclude Include="ExtraIcon.h" />
+ <ClInclude Include="ExtraIconGroup.h" />
+ <ClInclude Include="IcolibExtraIcon.h" />
+ <ClInclude Include="m_extraicons.h" />
+ <ClInclude Include="..\utils\mir_icons.h" />
+ <ClInclude Include="options.h" />
+ <ClInclude Include="resource.h" />
+ <ClInclude Include="usedIcons.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="res\AlwaysVis.ico" />
+ <None Include="res\Chatchannel.ico" />
+ <None Include="res\empty.ico" />
+ <None Include="res\female.ico" />
+ <None Include="res\male.ico" />
+ <None Include="res\NeverVis.ico" />
+ <None Include="Docs\extraicons_changelog.txt" />
+ <None Include="Docs\extraicons_readme.txt" />
+ <None Include="Docs\extraicons_version.txt" />
+ <None Include="Docs\langpack_extraicons.txt" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="resource.rc">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="BaseExtraIcon.cpp">
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="CallbackExtraIcon.cpp">
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="DefaultExtraIcons.cpp">
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="ExtraIcon.cpp">
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="ExtraIconGroup.cpp">
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="extraicons.cpp">
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="IcolibExtraIcon.cpp">
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="..\utils\mir_icons.cpp">
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">NotUsing</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">NotUsing</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">NotUsing</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">NotUsing</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="options.cpp">
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="usedIcons.cpp">
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ 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..08d30c2673
--- /dev/null
+++ b/plugins/extraicons/extraicons.vcxproj.filters
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{d1b17c52-ce87-4ebe-ab2d-69eab89a32a1}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{65beea6e-8646-427b-8827-1f1e70d835db}</UniqueIdentifier>
+ <Extensions>ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions>
+ </Filter>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{d6b93e43-b221-4629-bb6e-19f9fa9373a0}</UniqueIdentifier>
+ <Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
+ </Filter>
+ <Filter Include="Docs">
+ <UniqueIdentifier>{d7ab53c3-5a13-4c10-bd27-60f5549a39cd}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="BaseExtraIcon.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="CallbackExtraIcon.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="commons.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="DefaultExtraIcons.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="ExtraIcon.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="ExtraIconGroup.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="IcolibExtraIcon.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="m_extraicons.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\utils\mir_icons.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="options.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="resource.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="usedIcons.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="res\AlwaysVis.ico">
+ <Filter>Resource Files</Filter>
+ </None>
+ <None Include="res\Chatchannel.ico">
+ <Filter>Resource Files</Filter>
+ </None>
+ <None Include="res\empty.ico">
+ <Filter>Resource Files</Filter>
+ </None>
+ <None Include="res\female.ico">
+ <Filter>Resource Files</Filter>
+ </None>
+ <None Include="res\male.ico">
+ <Filter>Resource Files</Filter>
+ </None>
+ <None Include="res\NeverVis.ico">
+ <Filter>Resource Files</Filter>
+ </None>
+ <None Include="Docs\extraicons_changelog.txt">
+ <Filter>Docs</Filter>
+ </None>
+ <None Include="Docs\extraicons_readme.txt">
+ <Filter>Docs</Filter>
+ </None>
+ <None Include="Docs\extraicons_version.txt">
+ <Filter>Docs</Filter>
+ </None>
+ <None Include="Docs\langpack_extraicons.txt">
+ <Filter>Docs</Filter>
+ </None>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="resource.rc">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="BaseExtraIcon.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="CallbackExtraIcon.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="DefaultExtraIcons.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="ExtraIcon.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="ExtraIconGroup.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="extraicons.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="IcolibExtraIcon.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\utils\mir_icons.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="options.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="usedIcons.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/plugins/extraicons/m_extraicons.h b/plugins/extraicons/m_extraicons.h
new file mode 100644
index 0000000000..1e86cb168e
--- /dev/null
+++ b/plugins/extraicons/m_extraicons.h
@@ -0,0 +1,182 @@
+/*
+ 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 __M_EXTRAICONS_H__
+#define __M_EXTRAICONS_H__
+
+
+/*
+
+There is 2 ways of registering with Extra Icons service:
+
+1. Using callbacks
+ This works similar to clist API. When you register you provide 2 callbacks, one to rebuild the icons
+and one to apply the icons for a contact.
+ In the RebuildIcons callback, all icons that will be used have to be registered calling
+MS_CLIST_EXTRA_ADD_ICON service. The value returned by this service has to be stored and used in the
+apply icons.
+ The ApplyIcons callback will be called for all the needed contacts. Inside it, you must call
+MS_EXTRAICON_SET_ICON to set the icon for the contact, sending the value returned by MS_CLIST_EXTRA_ADD_ICON
+as the hImage.
+
+2. Using icolib
+ In this case no callback is needed and the plugin just need to call MS_EXTRAICON_SET_ICON passing the
+icolib name in icoName when needed. If your plugin can have extra icons on startup, remember to do a loop
+over all contacts to set the initial icon.
+
+
+To register a new extra icon, you have to call MS_EXTRAICON_REGISTER passing the needed atributes.
+
+*/
+
+#define MIID_EXTRAICONSSERVICE { 0x62d80749, 0xf169, 0x4592, { 0xb4, 0x4d, 0x3d, 0xd6, 0xde, 0x9d, 0x50, 0xc5 } }
+
+
+#define EXTRAICON_TYPE_CALLBACK 0 // Similar to old clist callbacks, it fires 2 notifications
+#define EXTRAICON_TYPE_ICOLIB 1 // This extra icon will use only icons registered with icolib. No callbacks
+ // needed. Just call MS_EXTRAICON_SET_ICON passing the name of the extraicon to set one.
+
+
+typedef struct {
+ int cbSize;
+ int type; // One of EXTRAICON_TYPE_*
+ const char *name; // Internal name. More than one plugin can register extra icons with the same name
+ // if both have the same type. In this case, both will be handled as one.
+ // If the types are different the second one will be denied.
+ const char *description; // [Translated by plugin] Description to be used in GUI
+ const char *descIcon; // [Optional] Name of an icon registered with icolib to be used in GUI.
+
+ // If type == EXTRAICON_TYPE_CALLBACK this two must be set
+
+ // Callback to add icons to clist, calling MS_CLIST_EXTRA_ADD_ICON
+ // wParam=lParam=0
+ MIRANDAHOOK RebuildIcons;
+
+ // Callback to set the icon to clist, calling MS_CLIST_EXTRA_SET_ICON or MS_EXTRAICON_SET_ICON
+ // wParam = HANDLE hContact
+ // lParam = 0
+ MIRANDAHOOK ApplyIcon;
+
+ // Other optional callbacks
+
+ // [Optional] Callback called when extra icon was clicked
+ // wParam = HANDLE hContact
+ // lParam = int slot
+ // param = onClickParam
+ MIRANDAHOOKPARAM OnClick;
+
+ LPARAM onClickParam;
+
+} EXTRAICON_INFO;
+
+
+// Register an extra icon
+// wParam = (EXTRAICON_INFO *) Extra icon info
+// lParam = 0
+// Return: (HANDLE) id of extra icon on success, 0 on error
+#define MS_EXTRAICON_REGISTER "ExtraIcon/Register"
+
+
+typedef struct {
+ int cbSize;
+ HANDLE hExtraIcon; // Value returned by MS_EXTRAICON_REGISTER
+ HANDLE hContact; // Contact to set the extra icon
+ union { // The icon to be set. This depends on the type of the extra icon:
+ HANDLE hImage; // Value returned by MS_CLIST_EXTRA_ADD_ICON (if EXTRAICON_TYPE_CALLBACK)
+ const char *icoName; // Name of the icon registered with icolib (if EXTRAICON_TYPE_ICOLIB)
+ };
+} EXTRAICON;
+
+// Set an extra icon icon
+// wParam = (EXTRAICON *) Extra icon
+// Return: 0 on success
+#define MS_EXTRAICON_SET_ICON "ExtraIcon/SetIcon"
+
+
+
+#ifndef _NO_WRAPPERS
+#ifdef __cplusplus
+
+static HANDLE ExtraIcon_Register(const char *name, const char *description, const char *descIcon,
+ MIRANDAHOOK RebuildIcons,
+ MIRANDAHOOK ApplyIcon,
+ MIRANDAHOOKPARAM OnClick = NULL, LPARAM onClickParam = 0)
+{
+ if (!ServiceExists(MS_EXTRAICON_REGISTER))
+ return NULL;
+
+ EXTRAICON_INFO ei = {0};
+ ei.cbSize = sizeof(ei);
+ ei.type = EXTRAICON_TYPE_CALLBACK;
+ ei.name = name;
+ ei.description = description;
+ ei.descIcon = descIcon;
+ ei.RebuildIcons = RebuildIcons;
+ ei.ApplyIcon = ApplyIcon;
+ ei.OnClick = OnClick;
+ ei.onClickParam = onClickParam;
+
+ return (HANDLE) CallService(MS_EXTRAICON_REGISTER, (WPARAM) &ei, 0);
+}
+
+static HANDLE ExtraIcon_Register(const char *name, const char *description, const char *descIcon = NULL,
+ MIRANDAHOOKPARAM OnClick = NULL, LPARAM onClickParam = 0)
+{
+ if (!ServiceExists(MS_EXTRAICON_REGISTER))
+ return NULL;
+
+ EXTRAICON_INFO ei = {0};
+ ei.cbSize = sizeof(ei);
+ ei.type = EXTRAICON_TYPE_ICOLIB;
+ ei.name = name;
+ ei.description = description;
+ ei.descIcon = descIcon;
+ ei.OnClick = OnClick;
+ ei.onClickParam = onClickParam;
+
+ return (HANDLE) CallService(MS_EXTRAICON_REGISTER, (WPARAM) &ei, 0);
+}
+
+static int ExtraIcon_SetIcon(HANDLE hExtraIcon, HANDLE hContact, HANDLE hImage)
+{
+ EXTRAICON ei = {0};
+ ei.cbSize = sizeof(ei);
+ ei.hExtraIcon = hExtraIcon;
+ ei.hContact = hContact;
+ ei.hImage = hImage;
+
+ return CallService(MS_EXTRAICON_SET_ICON, (WPARAM) &ei, 0);
+}
+
+static int ExtraIcon_SetIcon(HANDLE hExtraIcon, HANDLE hContact, const char *icoName)
+{
+ EXTRAICON ei = {0};
+ ei.cbSize = sizeof(ei);
+ ei.hExtraIcon = hExtraIcon;
+ ei.hContact = hContact;
+ ei.icoName = icoName;
+
+ return CallService(MS_EXTRAICON_SET_ICON, (WPARAM) &ei, 0);
+}
+
+#endif
+#endif
+
+
+#endif // __M_EXTRAICONS_H__
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<HTREEITEM> &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<HTREEITEM> &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<HTREEITEM> 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<HTREEITEM> 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<int> * Tree_GetIDs(HWND tree, HTREEITEM hItem)
+{
+ TVITEM tvi = { 0 };
+ tvi.mask = TVIF_HANDLE | TVIF_PARAM;
+ tvi.hItem = hItem;
+ TreeView_GetItem(tree, &tvi);
+
+ return (vector<int> *) tvi.lParam;
+}
+
+static HTREEITEM Tree_AddExtraIcon(HWND tree, BaseExtraIcon *extra, bool selected, HTREEITEM hAfter = TVI_LAST)
+{
+ vector<int> *ids = new vector<int> ;
+ 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<int> &group, bool selected, HTREEITEM hAfter = TVI_LAST)
+{
+ vector<int> *ids = new vector<int> ;
+ 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<HTREEITEM> toRemove;
+ vector<int> 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<int> *iids = (vector<int> *) 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<int> *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<int> *a = (vector<int> *) lParam1;
+ vector<int> *b = (vector<int> *) 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<int> 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<ExtraIconGroup *> 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<int> *ids = (vector<int> *) 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<int> *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
--- /dev/null
+++ b/plugins/extraicons/res/AlwaysVis.ico
Binary files differ
diff --git a/plugins/extraicons/res/Chatchannel.ico b/plugins/extraicons/res/Chatchannel.ico
new file mode 100644
index 0000000000..2e48365971
--- /dev/null
+++ b/plugins/extraicons/res/Chatchannel.ico
Binary files differ
diff --git a/plugins/extraicons/res/NeverVis.ico b/plugins/extraicons/res/NeverVis.ico
new file mode 100644
index 0000000000..6aebec2acc
--- /dev/null
+++ b/plugins/extraicons/res/NeverVis.ico
Binary files differ
diff --git a/plugins/extraicons/res/empty.ico b/plugins/extraicons/res/empty.ico
new file mode 100644
index 0000000000..8ba93283ac
--- /dev/null
+++ b/plugins/extraicons/res/empty.ico
Binary files differ
diff --git a/plugins/extraicons/res/female.ico b/plugins/extraicons/res/female.ico
new file mode 100644
index 0000000000..faa08fc6c0
--- /dev/null
+++ b/plugins/extraicons/res/female.ico
Binary files differ
diff --git a/plugins/extraicons/res/male.ico b/plugins/extraicons/res/male.ico
new file mode 100644
index 0000000000..5bee53143a
--- /dev/null
+++ b/plugins/extraicons/res/male.ico
Binary files 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/sdk/m_metacontacts.h b/plugins/extraicons/sdk/m_metacontacts.h
new file mode 100644
index 0000000000..1da12b97fa
--- /dev/null
+++ b/plugins/extraicons/sdk/m_metacontacts.h
@@ -0,0 +1,162 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright © 2004 Universite Louis PASTEUR, STRASBOURG.
+Copyright © 2004 Scott Ellis (www.scottellis.com.au mail@scottellis.com.au)
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef M_METACONTACTS_H__
+#define M_METACONTACTS_H__ 1
+
+//get the handle for a contact's parent metacontact
+//wParam=(HANDLE)hSubContact
+//lParam=0
+//returns a handle to the parent metacontact, or null if this contact is not a subcontact
+#define MS_MC_GETMETACONTACT "MetaContacts/GetMeta"
+
+//gets the handle for the default contact
+//wParam=(HANDLE)hMetaContact
+//lParam=0
+//returns a handle to the default contact, or null on failure
+#define MS_MC_GETDEFAULTCONTACT "MetaContacts/GetDefault"
+
+//gets the contact number for the default contact
+//wParam=(HANDLE)hMetaContact
+//lParam=0
+//returns a DWORD contact number, or -1 on failure
+#define MS_MC_GETDEFAULTCONTACTNUM "MetaContacts/GetDefaultNum"
+
+//gets the handle for the 'most online' contact
+//wParam=(HANDLE)hMetaContact
+//lParam=0
+//returns a handle to the 'most online' contact
+#define MS_MC_GETMOSTONLINECONTACT "MetaContacts/GetMostOnline"
+
+//gets the number of subcontacts for a metacontact
+//wParam=(HANDLE)hMetaContact
+//lParam=0
+//returns a DWORD representing the number of subcontacts for the given metacontact
+#define MS_MC_GETNUMCONTACTS "MetaContacts/GetNumContacts"
+
+//gets the handle of a subcontact, using the subcontact's number
+//wParam=(HANDLE)hMetaContact
+//lParam=(DWORD)contact number
+//returns a handle to the specified subcontact
+#define MS_MC_GETSUBCONTACT "MetaContacts/GetSubContact"
+
+//sets the default contact, using the subcontact's contact number
+//wParam=(HANDLE)hMetaContact
+//lParam=(DWORD)contact number
+//returns 0 on success
+#define MS_MC_SETDEFAULTCONTACTNUM "MetaContacts/SetDefault"
+
+//sets the default contact, using the subcontact's handle
+//wParam=(HANDLE)hMetaContact
+//lParam=(HANDLE)hSubcontact
+//returns 0 on success
+#define MS_MC_SETDEFAULTCONTACT "MetaContacts/SetDefaultByHandle"
+
+//forces the metacontact to send using a specific subcontact, using the subcontact's contact number
+//wParam=(HANDLE)hMetaContact
+//lParam=(DWORD)contact number
+//returns 0 on success
+#define MS_MC_FORCESENDCONTACTNUM "MetaContacts/ForceSendContact"
+
+//forces the metacontact to send using a specific subcontact, using the subcontact's handle
+//wParam=(HANDLE)hMetaContact
+//lParam=(HANDLE)hSubcontact
+//returns 0 on success (will fail if 'force default' is in effect)
+#define MS_MC_FORCESENDCONTACT "MetaContacts/ForceSendContactByHandle"
+
+//'unforces' the metacontact to send using a specific subcontact
+//wParam=(HANDLE)hMetaContact
+//lParam=0
+//returns 0 on success (will fail if 'force default' is in effect)
+#define MS_MC_UNFORCESENDCONTACT "MetaContacts/UnforceSendContact"
+
+//'forces' or 'unforces' (i.e. toggles) the metacontact to send using it's default contact
+// overrides (and clears) 'force send' above, and will even force use of offline contacts
+// will send ME_MC_FORCESEND or ME_MC_UNFORCESEND event
+//wParam=(HANDLE)hMetaContact
+//lParam=0
+//returns 1(true) or 0(false) representing new state of 'force default'
+#define MS_MC_FORCEDEFAULT "MetaContacts/ForceSendDefault"
+
+// method to get state of 'force' for a metacontact
+// wParam=(HANDLE)hMetaContact
+// lParam= (DWORD)&contact_number or NULL
+//
+// if lparam supplied, the contact_number of the contatct 'in force' will be copied to the address it points to,
+// or if none is in force, the value (DWORD)-1 will be copied
+// (v0.8.0.8+ returns 1 if 'force default' is true with *lParam == default contact number, else returns 0 with *lParam as above)
+#define MS_MC_GETFORCESTATE "MetaContacts/GetForceState"
+
+// fired when a metacontact's default contact changes (fired upon creation of metacontact also, when default is initially set)
+// wParam=(HANDLE)hMetaContact
+// lParam=(HANDLE)hDefaultContact
+#define ME_MC_DEFAULTTCHANGED "MetaContacts/DefaultChanged"
+
+// fired when a metacontact's subcontacts change (fired upon creation of metacontact, when contacts are added or removed, and when
+// contacts are reordered) - a signal to re-read metacontact data
+// wParam=(HANDLE)hMetaContact
+// lParam=0
+#define ME_MC_SUBCONTACTSCHANGED "MetaContacts/SubcontactsChanged"
+
+// fired when a metacontact is forced to send using a specific subcontact
+// wParam=(HANDLE)hMetaContact
+// lParam=(HANDLE)hForceContact
+#define ME_MC_FORCESEND "MetaContacts/ForceSend"
+
+// fired when a metacontact is 'unforced' to send using a specific subcontact
+// wParam=(HANDLE)hMetaContact
+// lParam=0
+#define ME_MC_UNFORCESEND "MetaContacts/UnforceSend"
+
+// method to get protocol name - used to be sure you're dealing with a "real" metacontacts plugin :)
+// wParam=lParam=0
+#define MS_MC_GETPROTOCOLNAME "MetaContacts/GetProtoName"
+
+
+// added 0.9.5.0 (22/3/05)
+// wParam=(HANDLE)hContact
+// lParam=0
+// convert a given contact into a metacontact
+#define MS_MC_CONVERTTOMETA "MetaContacts/ConvertToMetacontact"
+
+// added 0.9.5.0 (22/3/05)
+// wParam=(HANDLE)hContact
+// lParam=(HANDLE)hMeta
+// add an existing contact to a metacontact
+#define MS_MC_ADDTOMETA "MetaContacts/AddToMetacontact"
+
+// added 0.9.5.0 (22/3/05)
+// wParam=0
+// lParam=(HANDLE)hContact
+// remove a contact from a metacontact
+#define MS_MC_REMOVEFROMMETA "MetaContacts/RemoveFromMetacontact"
+
+
+// added 0.9.13.2 (6/10/05)
+// wParam=(BOOL)disable
+// lParam=0
+// enable/disable the 'hidden group hack' - for clists that support subcontact hiding using 'IsSubcontact' setting
+// should be called once in the clist 'onmodulesloaded' event handler (which, since it's loaded after the db, will be called
+// before the metacontact onmodulesloaded handler where the subcontact hiding is usually done)
+#define MS_MC_DISABLEHIDDENGROUP "MetaContacts/DisableHiddenGroup"
+
+#endif
diff --git a/plugins/extraicons/sdk/m_updater.h b/plugins/extraicons/sdk/m_updater.h
new file mode 100644
index 0000000000..371b7437a0
--- /dev/null
+++ b/plugins/extraicons/sdk/m_updater.h
@@ -0,0 +1,146 @@
+#ifndef _M_UPDATER_H
+#define _M_UPDATER_H
+
+// NOTES:
+// - For langpack updates, include a string of the following format in the langpack text file:
+// ";FLID: <file listing name> <version>"
+// version must be four numbers seperated by '.', in the range 0-255 inclusive
+// - Updater will disable plugins that are downloaded but were not active prior to the update (this is so that, if an archive contains e.g. ansi and
+// unicode versions, the correct plugin will be the only one active after the new version is installed)...so if you add a support plugin, you may need
+// to install an ini file to make the plugin activate when miranda restarts after the update
+// - Updater will replace all dlls that have the same internal shortName as a downloaded update dll (this is so that msn1.dll and msn2.dll, for example,
+// will both be updated) - so if you have a unicode and a non-unicode version of a plugin in your archive, you should make the internal names different (which will break automatic
+// updates from the file listing if there is only one file listing entry for both versions, unless you use the 'MS_UPDATE_REGISTER' service below)
+// - Updater will install all files in the root of the archive into the plugins folder, except for langpack files that contain the FLID string which go into the root folder (same
+// folder as miranda32.exe)...all folders in the archive will also be copied to miranda's root folder, and their contents transferred into the new folders. The only exception is a
+// special folder called 'root_files' - if there is a folder by that name in the archive, it's contents will also be copied into miranda's root folder - this is intended to be used
+// to install additional dlls etc that a plugin may require)
+
+// if you set Update.szUpdateURL to the following value when registering, as well as setting your beta site and version data,
+// Updater will ignore szVersionURL and pbVersionPrefix, and attempt to find the file listing URL's from the backend XML data.
+// for this to work, the plugin name in pluginInfo.shortName must match the file listing exactly (except for case)
+#define UPDATER_AUTOREGISTER "UpdaterAUTOREGISTER"
+// Updater will also use the backend xml data if you provide URL's that reference the miranda file listing for updates (so you can use that method
+// if e.g. your plugin shortName does not match the file listing) - it will grab the file listing id from the end of these URLs
+
+typedef struct Update_tag {
+ int cbSize;
+ char *szComponentName; // component name as it will appear in the UI (will be translated before displaying)
+
+ char *szVersionURL; // URL where the current version can be found (NULL to disable)
+ BYTE *pbVersionPrefix; // bytes occuring in VersionURL before the version, used to locate the version information within the URL data
+ // (note that this URL could point at a binary file - dunno why, but it could :)
+ int cpbVersionPrefix; // number of bytes pointed to by pbVersionPrefix
+ char *szUpdateURL; // URL where dll/zip is located
+ // set to UPDATER_AUTOREGISTER if you want Updater to find the file listing URLs (ensure plugin shortName matches file listing!)
+
+ char *szBetaVersionURL; // URL where the beta version can be found (NULL to disable betas)
+ BYTE *pbBetaVersionPrefix; // bytes occuring in VersionURL before the version, used to locate the version information within the URL data
+ int cpbBetaVersionPrefix; // number of bytes pointed to by pbVersionPrefix
+ char *szBetaUpdateURL; // URL where dll/zip is located
+
+ BYTE *pbVersion; // bytes of current version, used for comparison with those in VersionURL
+ int cpbVersion; // number of bytes pointed to by pbVersion
+
+ char *szBetaChangelogURL; // url for displaying changelog for beta versions
+} Update;
+
+// register a comonent with Updater
+//
+// wparam = 0
+// lparam = (LPARAM)&Update
+#define MS_UPDATE_REGISTER "Update/Register"
+
+// utility functions to create a version string from a DWORD or from pluginInfo
+// point buf at a buffer at least 16 chars wide - but note the version string returned may be shorter
+//
+__inline static char *CreateVersionString(DWORD version, char *buf) {
+ mir_snprintf(buf, 16, "%d.%d.%d.%d", (version >> 24) & 0xFF, (version >> 16) & 0xFF, (version >> 8) & 0xFF, version & 0xFF);
+ return buf;
+}
+
+__inline static char *CreateVersionStringPlugin(PLUGININFO *pluginInfo, char *buf) {
+ return CreateVersionString(pluginInfo->version, buf);
+}
+
+
+// register the 'easy' way - use this method if you have no beta URL and the plugin is on the miranda file listing
+// NOTE: the plugin version string on the file listing must be the string version of the version in pluginInfo (i.e. 0.0.0.1,
+// four numbers between 0 and 255 inclusivem, so no letters, brackets, etc.)
+//
+// wParam = (int)fileID - this is the file ID from the file listing (i.e. the number at the end of the download link)
+// lParam = (PLUGININFO*)&pluginInfo
+#define MS_UPDATE_REGISTERFL "Update/RegisterFL"
+
+// this function can be used to 'unregister' components - useful for plugins that register non-plugin/langpack components and
+// may need to change those components on the fly
+// lParam = (char *)szComponentName
+#define MS_UPDATE_UNREGISTER "Update/Unregister"
+
+// this event is fired when the startup process is complete, but NOT if a restart is imminent
+// it is designed for status managment plugins to use as a trigger for beggining their own startup process
+// wParam = lParam = 0 (unused)
+// (added in version 0.1.6.0)
+#define ME_UPDATE_STARTUPDONE "Update/StartupDone"
+
+// this service can be used to enable/disable Updater's global status control
+// it can be called from the StartupDone event handler
+// wParam = (BOOL)enable
+// lParam = 0
+// (added in version 0.1.6.0)
+#define MS_UPDATE_ENABLESTATUSCONTROL "Update/EnableStatusControl"
+
+// An description of usage of the above service and event:
+// Say you are a status control plugin that normally sets protocol or global statuses in your ModulesLoaded event handler.
+// In order to make yourself 'Updater compatible', you would move the status control code from ModulesLoaded to another function,
+// say DoStartup. Then, in ModulesLoaded you would check for the existence of the MS_UPDATE_ENABLESTATUSCONTROL service.
+// If it does not exist, call DoStartup. If it does exist, hook the ME_UPDATE_STARTUPDONE event and call DoStartup from there. You may
+// also wish to call MS_UPDATE_ENABLESTATUSCONTROL with wParam == FALSE at this time, to disable Updater's own status control feature.
+
+// this service can be used to determine whether updates are possible for a component with the given name
+// wParam = 0
+// lParam = (char *)szComponentName
+// returns TRUE if updates are supported, FALSE otherwise
+#define MS_UPDATE_ISUPDATESUPPORTED "Update/IsUpdateSupported"
+
+#endif
+
+
+/////////////// Usage Example ///////////////
+
+#ifdef EXAMPLE_CODE
+
+// you need to #include "m_updater.h" and HookEvent(ME_SYSTEM_MODULESLOADED, OnModulesLoaded) in your Load function...
+
+int OnModulesLoaded(WPARAM wParam, LPARAM lParam) {
+
+ Update update = {0}; // for c you'd use memset or ZeroMemory...
+ char szVersion[16];
+
+ update.cbSize = sizeof(Update);
+
+ update.szComponentName = pluginInfo.shortName;
+ update.pbVersion = (BYTE *)CreateVersionString(&pluginInfo, szVersion);
+ update.cpbVersion = strlen((char *)update.pbVersion);
+
+ // these are the three lines that matter - the archive, the page containing the version string, and the text (or data)
+ // before the version that we use to locate it on the page
+ // (note that if the update URL and the version URL point to standard file listing entries, the backend xml
+ // data will be used to check for updates rather than the actual web page - this is not true for beta urls)
+ update.szUpdateURL = "http://scottellis.com.au:81/test/updater.zip";
+ update.szVersionURL = "http://scottellis.com.au:81/test/updater_test.html";
+ update.pbVersionPrefix = (BYTE *)"Updater version ";
+
+ update.cpbVersionPrefix = strlen((char *)update.pbVersionPrefix);
+
+ // do the same for the beta versions of the above struct members if you wish to allow beta updates from another URL
+
+ CallService(MS_UPDATE_REGISTER, 0, (WPARAM)&update);
+
+ // Alternatively, to register a plugin with e.g. file ID 2254 on the file listing...
+ // CallService(MS_UPDATE_REGISTERFL, (WPARAM)2254, (LPARAM)&pluginInfo);
+
+ return 0;
+}
+
+#endif
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<Icon> 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__
diff --git a/plugins/modernb/icons_pack/ICONS_10.vcxproj b/plugins/modernb/icons_pack/ICONS_10.vcxproj
index 0b1280dcab..f8673a7b1e 100644
--- a/plugins/modernb/icons_pack/ICONS_10.vcxproj
+++ b/plugins/modernb/icons_pack/ICONS_10.vcxproj
@@ -9,6 +9,14 @@
<Configuration>Debug Unicode</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
<ProjectConfiguration Include="Release Unicode|Win32">
<Configuration>Release Unicode</Configuration>
<Platform>Win32</Platform>
@@ -37,11 +45,21 @@
<UseOfMfc>false</UseOfMfc>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
@@ -69,10 +87,18 @@
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+ </ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+ </ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
@@ -105,11 +131,17 @@
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">false</LinkIncremental>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">false</LinkIncremental>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">$(SolutionDir)$(Configuration)\Icons\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\Icons\</OutDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">$(SolutionDir)$(Configuration)64\Icons\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Configuration)64\Icons\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">$(SolutionDir)$(Configuration)\Obj\$(ProjectName)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\Obj\$(ProjectName)\</IntDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">$(SolutionDir)$(Configuration)64\Obj\$(ProjectName)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Configuration)64\Obj\$(ProjectName)\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">false</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkIncremental>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">false</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Midl>
@@ -264,6 +296,37 @@
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Midl>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ <HeaderFileName>
+ </HeaderFileName>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;ICONS_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile>
+ <PrecompiledHeaderOutputFile>.\Release/ICONS.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>.\Release/</AssemblerListingLocation>
+ <ObjectFileName>.\Release/</ObjectFileName>
+ <ProgramDataBaseFileName>.\Release/</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x0409</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalOptions>/ALIGN:4096 /ignore:4108 %(AdditionalOptions)</AdditionalOptions>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <NoEntryPoint>true</NoEntryPoint>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">
<Midl>
<SuppressStartupBanner>true</SuppressStartupBanner>
@@ -294,6 +357,36 @@
<NoEntryPoint>true</NoEntryPoint>
</Link>
</ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Midl>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <HeaderFileName>
+ </HeaderFileName>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;ICONS_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile>
+ <PrecompiledHeaderOutputFile>.\Release/ICONS.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>.\Release/</AssemblerListingLocation>
+ <ObjectFileName>.\Release/</ObjectFileName>
+ <ProgramDataBaseFileName>.\Release/</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x0409</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalOptions>/ALIGN:4096 /ignore:4108 %(AdditionalOptions)</AdditionalOptions>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <NoEntryPoint>true</NoEntryPoint>
+ </Link>
+ </ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="icon_resource.h" />
</ItemGroup>
diff --git a/plugins/utils/ContactAsyncQueue.cpp b/plugins/utils/ContactAsyncQueue.cpp
new file mode 100644
index 0000000000..2d5d1f104d
--- /dev/null
+++ b/plugins/utils/ContactAsyncQueue.cpp
@@ -0,0 +1,234 @@
+/*
+Copyright (C) 2006-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 "ContactAsyncQueue.h"
+#include <process.h>
+
+
+// Itens with higher time at end
+static int QueueSortItems(const QueueItem *oldItem, const QueueItem *newItem)
+{
+ if (oldItem->check_time == newItem->check_time)
+ return -1;
+
+ return oldItem->check_time - newItem->check_time;
+}
+
+// Itens with higher time at end
+static void ContactAsyncQueueThread(void *obj)
+{
+ ((ContactAsyncQueue *)obj)->Thread();
+}
+
+ContactAsyncQueue::ContactAsyncQueue(pfContactAsyncQueueCallback fContactAsyncQueueCallback, int initialSize)
+ : queue(30, QueueSortItems)
+{
+ hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+ finished = 0;
+ callback = fContactAsyncQueueCallback;
+
+ InitializeCriticalSection(&cs);
+
+ _beginthread(ContactAsyncQueueThread, 0, this);
+ //mir_forkthread(ContactAsyncQueueThread, this);
+}
+
+ContactAsyncQueue::~ContactAsyncQueue()
+{
+ Finish();
+
+ int count = 0;
+ while(finished != 2 && ++count < 50)
+ Sleep(30);
+
+ for (int i = 0; i < queue.getCount(); i++)
+ if (queue[i] != NULL)
+ mir_free(queue[i]);
+
+ DeleteCriticalSection(&cs);
+}
+
+void ContactAsyncQueue::Finish()
+{
+ if (finished == 0)
+ finished = 1;
+ SetEvent(hEvent);
+}
+
+void ContactAsyncQueue::Lock()
+{
+ EnterCriticalSection(&cs);
+}
+
+void ContactAsyncQueue::Release()
+{
+ LeaveCriticalSection(&cs);
+}
+
+void ContactAsyncQueue::RemoveAll(HANDLE hContact)
+{
+ Lock();
+
+ for (int i = queue.getCount() - 1; i >= 0; --i)
+ {
+ QueueItem *item = queue[i];
+
+ if (item->hContact == hContact)
+ {
+ queue.remove(i);
+ mir_free(item);
+ }
+ }
+
+ Release();
+}
+
+void ContactAsyncQueue::RemoveAllConsiderParam(HANDLE hContact, void *param)
+{
+ Lock();
+
+ for (int i = queue.getCount() - 1; i >= 0; --i)
+ {
+ QueueItem *item = queue[i];
+
+ if (item->hContact == hContact && item->param == param)
+ {
+ queue.remove(i);
+ mir_free(item);
+ }
+ }
+
+ Release();
+}
+
+void ContactAsyncQueue::Add(int waitTime, HANDLE hContact, void *param)
+{
+ Lock();
+
+ InternalAdd(waitTime, hContact, param);
+
+ Release();
+}
+
+void ContactAsyncQueue::AddIfDontHave(int waitTime, HANDLE hContact, void *param)
+{
+ Lock();
+
+ int i;
+ for (i = queue.getCount() - 1; i >= 0; --i)
+ if (queue[i]->hContact == hContact)
+ break;
+
+ if (i < 0)
+ InternalAdd(waitTime, hContact, param);
+
+ Release();
+}
+
+void ContactAsyncQueue::AddAndRemovePrevious(int waitTime, HANDLE hContact, void *param)
+{
+ Lock();
+
+ RemoveAll(hContact);
+ InternalAdd(waitTime, hContact, param);
+
+ Release();
+}
+
+void ContactAsyncQueue::AddAndRemovePreviousConsiderParam(int waitTime, HANDLE hContact, void *param)
+{
+ Lock();
+
+ RemoveAllConsiderParam(hContact, param);
+ InternalAdd(waitTime, hContact, param);
+
+ Release();
+}
+
+void ContactAsyncQueue::InternalAdd(int waitTime, HANDLE hContact, void *param)
+{
+ QueueItem *item = (QueueItem *) mir_alloc(sizeof(QueueItem));
+ item->hContact = hContact;
+ item->check_time = GetTickCount() + waitTime;
+ item->param = param;
+
+ queue.insert(item);
+
+ SetEvent(hEvent);
+}
+
+void ContactAsyncQueue::Thread()
+{
+ while (!finished)
+ {
+ ResetEvent(hEvent);
+
+ if (finished)
+ break;
+
+ Lock();
+
+ if (queue.getCount() <= 0)
+ {
+ // No items, so supend thread
+ Release();
+
+ wait(/*INFINITE*/ 2 * 60 * 1000);
+ }
+ else
+ {
+ // Take a look at first item
+ QueueItem *qi = queue[0];
+
+ int dt = qi->check_time - GetTickCount();
+ if (dt > 0)
+ {
+ // Not time to request yet, wait...
+ Release();
+
+ wait(dt);
+ }
+ else
+ {
+ // Will request this item
+ queue.remove(0);
+
+ Release();
+
+ callback(qi->hContact, qi->param);
+
+ mir_free(qi);
+ }
+ }
+ }
+
+ finished = 2;
+}
+
+void ContactAsyncQueue::wait(int time)
+{
+ if (!finished)
+ WaitForSingleObject(hEvent, time);
+}
+
+
+
+
+
+
diff --git a/plugins/utils/ContactAsyncQueue.h b/plugins/utils/ContactAsyncQueue.h
new file mode 100644
index 0000000000..f3297697e0
--- /dev/null
+++ b/plugins/utils/ContactAsyncQueue.h
@@ -0,0 +1,95 @@
+/*
+Copyright (C) 2006-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 __CONTACTASYNCQUEUE_H__
+# define __CONTACTASYNCQUEUE_H__
+
+#ifndef MIRANDA_VER
+#define MIRANDA_VER 0x0700
+#endif
+
+#include <windows.h>
+#include <newpluginapi.h>
+#include <m_system_cpp.h>
+
+
+typedef void (*pfContactAsyncQueueCallback) (HANDLE hContact, void *param);
+
+
+struct QueueItem
+{
+ DWORD check_time;
+ HANDLE hContact;
+ void *param;
+};
+
+
+class ContactAsyncQueue
+{
+public:
+
+ ContactAsyncQueue(pfContactAsyncQueueCallback fContactAsyncQueueCallback, int initialSize = 10);
+ ~ContactAsyncQueue();
+
+ void Finish();
+
+ inline int Size() const { return queue.getCount(); }
+ inline int Remove(int idx) { mir_free(queue[idx]); return queue.remove(idx); }
+ inline QueueItem* Get(int idx) const { return queue[idx]; }
+
+
+ void RemoveAll(HANDLE hContact);
+ void RemoveAllConsiderParam(HANDLE hContact, void *param);
+ void Add(int waitTime, HANDLE hContact, void *param = NULL);
+ void AddIfDontHave(int waitTime, HANDLE hContact, void *param = NULL);
+ void AddAndRemovePrevious(int waitTime, HANDLE hContact, void *param = NULL);
+ void AddAndRemovePreviousConsiderParam(int waitTime, HANDLE hContact, void *param = NULL);
+
+ void Lock();
+ void Release();
+
+
+ void Thread();
+
+private:
+
+ LIST<QueueItem> queue;
+
+ CRITICAL_SECTION cs;
+ pfContactAsyncQueueCallback callback;
+ HANDLE hEvent;
+ int finished;
+
+
+ void InternalAdd(int waitTime, HANDLE hContact, void *param);
+ void wait(int time);
+};
+
+
+
+
+
+
+
+
+
+
+
+#endif // __CONTACTASYNCQUEUE_H__
diff --git a/plugins/utils/MemoryModule.c b/plugins/utils/MemoryModule.c
new file mode 100644
index 0000000000..1e7ac0ac01
--- /dev/null
+++ b/plugins/utils/MemoryModule.c
@@ -0,0 +1,540 @@
+/*
+ * Memory DLL loading code
+ * Version 0.0.2 with additions from Thomas Heller
+ *
+ * Copyright (c) 2004-2005 by Joachim Bauch / mail@joachim-bauch.de
+ * http://www.joachim-bauch.de
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is MemoryModule.c
+ *
+ * The Initial Developer of the Original Code is Joachim Bauch.
+ *
+ * Portions created by Joachim Bauch are Copyright (C) 2004-2005
+ * Joachim Bauch. All Rights Reserved.
+ *
+ * Portions Copyright (C) 2005 Thomas Heller.
+ *
+ */
+
+// disable warnings about pointer <-> DWORD conversions
+#pragma warning( disable : 4311 4312 )
+
+#include <Windows.h>
+#include <winnt.h>
+#ifdef DEBUG_OUTPUT
+#include <stdio.h>
+#endif
+
+#ifndef IMAGE_SIZEOF_BASE_RELOCATION
+// Vista SDKs no longer define IMAGE_SIZEOF_BASE_RELOCATION!?
+# define IMAGE_SIZEOF_BASE_RELOCATION (sizeof(IMAGE_BASE_RELOCATION))
+#endif
+#include "MemoryModule.h"
+
+
+struct NAME_TABLE {
+ char *name;
+ DWORD ordinal;
+};
+
+typedef struct tagMEMORYMODULE {
+ PIMAGE_NT_HEADERS headers;
+ unsigned char *codeBase;
+ HMODULE *modules;
+ int numModules;
+ int initialized;
+
+ struct NAME_TABLE *name_table;
+} MEMORYMODULE, *PMEMORYMODULE;
+
+typedef BOOL (WINAPI *DllEntryProc)(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved);
+
+#define GET_HEADER_DICTIONARY(module, idx) &(module)->headers->OptionalHeader.DataDirectory[idx]
+
+#ifdef DEBUG_OUTPUT
+static void
+OutputLastError(const char *msg)
+{
+ LPVOID tmp;
+ char *tmpmsg;
+ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&tmp, 0, NULL);
+ tmpmsg = (char *)LocalAlloc(LPTR, strlen(msg) + strlen(tmp) + 3);
+ sprintf(tmpmsg, "%s: %s", msg, tmp);
+ OutputDebugString(tmpmsg);
+ LocalFree(tmpmsg);
+ LocalFree(tmp);
+}
+#endif
+
+static void
+CopySections(const unsigned char *data, PIMAGE_NT_HEADERS old_headers, PMEMORYMODULE module)
+{
+ int i, size;
+ unsigned char *codeBase = module->codeBase;
+ unsigned char *dest;
+ PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(module->headers);
+ for (i=0; i<module->headers->FileHeader.NumberOfSections; i++, section++)
+ {
+ if (section->SizeOfRawData == 0)
+ {
+ // section doesn't contain data in the dll itself, but may define
+ // uninitialized data
+ size = old_headers->OptionalHeader.SectionAlignment;
+ if (size > 0)
+ {
+ dest = (unsigned char *)VirtualAlloc(codeBase + section->VirtualAddress,
+ size,
+ MEM_COMMIT,
+ PAGE_READWRITE);
+
+ section->Misc.PhysicalAddress = (DWORD)dest;
+ memset(dest, 0, size);
+ }
+
+ // section is empty
+ continue;
+ }
+
+ // commit memory block and copy data from dll
+ dest = (unsigned char *)VirtualAlloc(codeBase + section->VirtualAddress,
+ section->SizeOfRawData,
+ MEM_COMMIT,
+ PAGE_READWRITE);
+ memcpy(dest, data + section->PointerToRawData, section->SizeOfRawData);
+ section->Misc.PhysicalAddress = (DWORD)dest;
+ }
+}
+
+// Protection flags for memory pages (Executable, Readable, Writeable)
+static int ProtectionFlags[2][2][2] = {
+ {
+ // not executable
+ {PAGE_NOACCESS, PAGE_WRITECOPY},
+ {PAGE_READONLY, PAGE_READWRITE},
+ }, {
+ // executable
+ {PAGE_EXECUTE, PAGE_EXECUTE_WRITECOPY},
+ {PAGE_EXECUTE_READ, PAGE_EXECUTE_READWRITE},
+ },
+};
+
+static void
+FinalizeSections(PMEMORYMODULE module)
+{
+ int i;
+ PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(module->headers);
+
+ // loop through all sections and change access flags
+ for (i=0; i<module->headers->FileHeader.NumberOfSections; i++, section++)
+ {
+ DWORD protect, oldProtect, size;
+ int executable = (section->Characteristics & IMAGE_SCN_MEM_EXECUTE) != 0;
+ int readable = (section->Characteristics & IMAGE_SCN_MEM_READ) != 0;
+ int writeable = (section->Characteristics & IMAGE_SCN_MEM_WRITE) != 0;
+
+ if (section->Characteristics & IMAGE_SCN_MEM_DISCARDABLE)
+ {
+ // section is not needed any more and can safely be freed
+ VirtualFree((LPVOID)section->Misc.PhysicalAddress, section->SizeOfRawData, MEM_DECOMMIT);
+ continue;
+ }
+
+ // determine protection flags based on characteristics
+ protect = ProtectionFlags[executable][readable][writeable];
+ if (section->Characteristics & IMAGE_SCN_MEM_NOT_CACHED)
+ protect |= PAGE_NOCACHE;
+
+ // determine size of region
+ size = section->SizeOfRawData;
+ if (size == 0)
+ {
+ if (section->Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA)
+ size = module->headers->OptionalHeader.SizeOfInitializedData;
+ else if (section->Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA)
+ size = module->headers->OptionalHeader.SizeOfUninitializedData;
+ }
+
+ if (size > 0)
+ {
+ // change memory access flags
+ if (VirtualProtect((LPVOID)section->Misc.PhysicalAddress, size, protect, &oldProtect) == 0)
+#ifdef DEBUG_OUTPUT
+ OutputLastError("Error protecting memory page")
+#endif
+ ;
+ }
+ }
+}
+
+static void
+PerformBaseRelocation(PMEMORYMODULE module, DWORD delta)
+{
+ DWORD i;
+ unsigned char *codeBase = module->codeBase;
+
+ PIMAGE_DATA_DIRECTORY directory = GET_HEADER_DICTIONARY(module, IMAGE_DIRECTORY_ENTRY_BASERELOC);
+ if (directory->Size > 0)
+ {
+ PIMAGE_BASE_RELOCATION relocation = (PIMAGE_BASE_RELOCATION)(codeBase + directory->VirtualAddress);
+ for (; relocation->VirtualAddress > 0; )
+ {
+ unsigned char *dest = (unsigned char *)(codeBase + relocation->VirtualAddress);
+ unsigned short *relInfo = (unsigned short *)((unsigned char *)relocation + IMAGE_SIZEOF_BASE_RELOCATION);
+ for (i=0; i<((relocation->SizeOfBlock-IMAGE_SIZEOF_BASE_RELOCATION) / 2); i++, relInfo++)
+ {
+ DWORD *patchAddrHL;
+ int type, offset;
+
+ // the upper 4 bits define the type of relocation
+ type = *relInfo >> 12;
+ // the lower 12 bits define the offset
+ offset = *relInfo & 0xfff;
+
+ switch (type)
+ {
+ case IMAGE_REL_BASED_ABSOLUTE:
+ // skip relocation
+ break;
+
+ case IMAGE_REL_BASED_HIGHLOW:
+ // change complete 32 bit address
+ patchAddrHL = (DWORD *)(dest + offset);
+ *patchAddrHL += delta;
+ break;
+
+ default:
+ //printf("Unknown relocation: %d\n", type);
+ break;
+ }
+ }
+
+ // advance to next relocation block
+ relocation = (PIMAGE_BASE_RELOCATION)(((DWORD)relocation) + relocation->SizeOfBlock);
+ }
+ }
+}
+
+static int
+BuildImportTable(PMEMORYMODULE module)
+{
+ int result=1;
+ unsigned char *codeBase = module->codeBase;
+
+ PIMAGE_DATA_DIRECTORY directory = GET_HEADER_DICTIONARY(module, IMAGE_DIRECTORY_ENTRY_IMPORT);
+ if (directory->Size > 0)
+ {
+ PIMAGE_IMPORT_DESCRIPTOR importDesc = (PIMAGE_IMPORT_DESCRIPTOR)(codeBase + directory->VirtualAddress);
+ for (; !IsBadReadPtr(importDesc, sizeof(IMAGE_IMPORT_DESCRIPTOR)) && importDesc->Name; importDesc++)
+ {
+ DWORD *thunkRef, *funcRef;
+ HMODULE handle = LoadLibraryA((LPCSTR)(codeBase + importDesc->Name));
+ if (handle == INVALID_HANDLE_VALUE || handle == NULL)
+ {
+ //LastError should already be set
+#if DEBUG_OUTPUT
+ OutputLastError("Can't load library");
+#endif
+ result = 0;
+ break;
+ }
+
+ module->modules = (HMODULE *)realloc(module->modules, (module->numModules+1)*(sizeof(HMODULE)));
+ if (module->modules == NULL)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ result = 0;
+ break;
+ }
+
+ module->modules[module->numModules++] = handle;
+ if (importDesc->OriginalFirstThunk)
+ {
+ thunkRef = (DWORD *)(codeBase + importDesc->OriginalFirstThunk);
+ funcRef = (DWORD *)(codeBase + importDesc->FirstThunk);
+ } else {
+ // no hint table
+ thunkRef = (DWORD *)(codeBase + importDesc->FirstThunk);
+ funcRef = (DWORD *)(codeBase + importDesc->FirstThunk);
+ }
+ for (; *thunkRef; thunkRef++, funcRef++)
+ {
+ if IMAGE_SNAP_BY_ORDINAL(*thunkRef)
+ *funcRef = (DWORD)GetProcAddress(handle, (LPCSTR)IMAGE_ORDINAL(*thunkRef));
+ else {
+ PIMAGE_IMPORT_BY_NAME thunkData = (PIMAGE_IMPORT_BY_NAME)(codeBase + *thunkRef);
+ *funcRef = (DWORD)GetProcAddress(handle, (LPCSTR)&thunkData->Name);
+ }
+ if (*funcRef == 0)
+ {
+ SetLastError(ERROR_PROC_NOT_FOUND);
+ result = 0;
+ break;
+ }
+ }
+
+ if (!result)
+ break;
+ }
+ }
+
+ return result;
+}
+
+HMEMORYMODULE MemoryLoadLibrary(const void *data)
+{
+ PMEMORYMODULE result;
+ PIMAGE_DOS_HEADER dos_header;
+ PIMAGE_NT_HEADERS old_header;
+ unsigned char *code, *headers;
+ DWORD locationDelta;
+ DllEntryProc DllEntry;
+ BOOL successfull;
+
+ dos_header = (PIMAGE_DOS_HEADER)data;
+ if (dos_header->e_magic != IMAGE_DOS_SIGNATURE)
+ {
+ SetLastError(ERROR_BAD_FORMAT);
+#if DEBUG_OUTPUT
+ OutputDebugString("Not a valid executable file.\n");
+#endif
+ return NULL;
+ }
+
+ old_header = (PIMAGE_NT_HEADERS)&((const unsigned char *)(data))[dos_header->e_lfanew];
+ if (old_header->Signature != IMAGE_NT_SIGNATURE)
+ {
+ SetLastError(ERROR_BAD_FORMAT);
+#if DEBUG_OUTPUT
+ OutputDebugString("No PE header found.\n");
+#endif
+ return NULL;
+ }
+
+ // reserve memory for image of library
+ code = (unsigned char *)VirtualAlloc((LPVOID)(old_header->OptionalHeader.ImageBase),
+ old_header->OptionalHeader.SizeOfImage,
+ MEM_RESERVE,
+ PAGE_READWRITE);
+
+ if (code == NULL)
+ // try to allocate memory at arbitrary position
+ code = (unsigned char *)VirtualAlloc(NULL,
+ old_header->OptionalHeader.SizeOfImage,
+ MEM_RESERVE,
+ PAGE_READWRITE);
+
+ if (code == NULL)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+#if DEBUG_OUTPUT
+ OutputLastError("Can't reserve memory");
+#endif
+ return NULL;
+ }
+
+ result = (PMEMORYMODULE)HeapAlloc(GetProcessHeap(), 0, sizeof(MEMORYMODULE));
+ result->codeBase = code;
+ result->numModules = 0;
+ result->modules = NULL;
+ result->initialized = 0;
+ result->name_table = NULL;
+
+ // XXX: is it correct to commit the complete memory region at once?
+ // calling DllEntry raises an exception if we don't...
+ VirtualAlloc(code,
+ old_header->OptionalHeader.SizeOfImage,
+ MEM_COMMIT,
+ PAGE_READWRITE);
+
+ // commit memory for headers
+ headers = (unsigned char *)VirtualAlloc(code,
+ old_header->OptionalHeader.SizeOfHeaders,
+ MEM_COMMIT,
+ PAGE_READWRITE);
+
+ // copy PE header to code
+ memcpy(headers, dos_header, dos_header->e_lfanew + old_header->OptionalHeader.SizeOfHeaders);
+ result->headers = (PIMAGE_NT_HEADERS)&((const unsigned char *)(headers))[dos_header->e_lfanew];
+
+ // update position
+ result->headers->OptionalHeader.ImageBase = (DWORD)code;
+
+ // copy sections from DLL file block to new memory location
+ CopySections(data, old_header, result);
+
+ // adjust base address of imported data
+ locationDelta = (DWORD)(code - old_header->OptionalHeader.ImageBase);
+ if (locationDelta != 0)
+ PerformBaseRelocation(result, locationDelta);
+
+ // load required dlls and adjust function table of imports
+ if (!BuildImportTable(result))
+ goto error;
+
+ // mark memory pages depending on section headers and release
+ // sections that are marked as "discardable"
+ FinalizeSections(result);
+
+ // get entry point of loaded library
+ if (result->headers->OptionalHeader.AddressOfEntryPoint != 0)
+ {
+ DllEntry = (DllEntryProc)(code + result->headers->OptionalHeader.AddressOfEntryPoint);
+ if (DllEntry == 0)
+ {
+ SetLastError(ERROR_BAD_FORMAT); /* XXX ? */
+#if DEBUG_OUTPUT
+ OutputDebugString("Library has no entry point.\n");
+#endif
+ goto error;
+ }
+
+ // notify library about attaching to process
+ successfull = (*DllEntry)((HINSTANCE)code, DLL_PROCESS_ATTACH, 0);
+ if (!successfull)
+ {
+#if DEBUG_OUTPUT
+ OutputDebugString("Can't attach library.\n");
+#endif
+ goto error;
+ }
+ result->initialized = 1;
+ }
+
+ return (HMEMORYMODULE)result;
+
+error:
+ // cleanup
+ MemoryFreeLibrary(result);
+ return NULL;
+}
+
+int _compare(const struct NAME_TABLE *p1, const struct NAME_TABLE *p2)
+{
+ return stricmp(p1->name, p2->name);
+}
+
+int _find(const char **name, const struct NAME_TABLE *p)
+{
+ return stricmp(*name, p->name);
+}
+
+struct NAME_TABLE *GetNameTable(PMEMORYMODULE module)
+{
+ unsigned char *codeBase;
+ PIMAGE_EXPORT_DIRECTORY exports;
+ PIMAGE_DATA_DIRECTORY directory;
+ DWORD i, *nameRef;
+ WORD *ordinal;
+ struct NAME_TABLE *p, *ptab;
+
+ if (module->name_table)
+ return module->name_table;
+
+ codeBase = module->codeBase;
+ directory = GET_HEADER_DICTIONARY(module, IMAGE_DIRECTORY_ENTRY_EXPORT);
+ exports = (PIMAGE_EXPORT_DIRECTORY)(codeBase + directory->VirtualAddress);
+
+ nameRef = (DWORD *)(codeBase + exports->AddressOfNames);
+ ordinal = (WORD *)(codeBase + exports->AddressOfNameOrdinals);
+
+ p = ((PMEMORYMODULE)module)->name_table = (struct NAME_TABLE *)malloc(sizeof(struct NAME_TABLE)
+ * exports->NumberOfNames);
+ if (p == NULL)
+ return NULL;
+ ptab = p;
+ for (i=0; i<exports->NumberOfNames; ++i) {
+ p->name = (char *)(codeBase + *nameRef++);
+ p->ordinal = *ordinal++;
+ ++p;
+ }
+ qsort(ptab, exports->NumberOfNames, sizeof(struct NAME_TABLE), _compare);
+ return ptab;
+}
+
+FARPROC MemoryGetProcAddress(HMEMORYMODULE module, const char *name)
+{
+ unsigned char *codeBase = ((PMEMORYMODULE)module)->codeBase;
+ int idx=-1;
+ PIMAGE_EXPORT_DIRECTORY exports;
+ PIMAGE_DATA_DIRECTORY directory = GET_HEADER_DICTIONARY((PMEMORYMODULE)module, IMAGE_DIRECTORY_ENTRY_EXPORT);
+
+ if (directory->Size == 0)
+ // no export table found
+ return NULL;
+
+ exports = (PIMAGE_EXPORT_DIRECTORY)(codeBase + directory->VirtualAddress);
+ if (exports->NumberOfNames == 0 || exports->NumberOfFunctions == 0)
+ // DLL doesn't export anything
+ return NULL;
+
+ if (HIWORD(name)) {
+ struct NAME_TABLE *ptab;
+ struct NAME_TABLE *found;
+ ptab = GetNameTable((PMEMORYMODULE)module);
+ if (ptab == NULL)
+ // some failure
+ return NULL;
+ found = bsearch(&name, ptab, exports->NumberOfNames, sizeof(struct NAME_TABLE), _find);
+ if (found == NULL)
+ // exported symbol not found
+ return NULL;
+
+ idx = found->ordinal;
+ }
+ else
+ idx = LOWORD(name) - exports->Base;
+
+ if ((DWORD)idx > exports->NumberOfFunctions)
+ // name <-> ordinal number don't match
+ return NULL;
+
+ // AddressOfFunctions contains the RVAs to the "real" functions
+ return (FARPROC)(codeBase + *(DWORD *)(codeBase + exports->AddressOfFunctions + (idx*4)));
+}
+
+void MemoryFreeLibrary(HMEMORYMODULE mod)
+{
+ int i;
+ PMEMORYMODULE module = (PMEMORYMODULE)mod;
+
+ if (module != NULL)
+ {
+ if (module->initialized != 0)
+ {
+ // notify library about detaching from process
+ DllEntryProc DllEntry = (DllEntryProc)(module->codeBase + module->headers->OptionalHeader.AddressOfEntryPoint);
+ (*DllEntry)((HINSTANCE)module->codeBase, DLL_PROCESS_DETACH, 0);
+ module->initialized = 0;
+ }
+
+ if (module->modules != NULL)
+ {
+ // free previously opened libraries
+ for (i=0; i<module->numModules; i++)
+ if (module->modules[i] != INVALID_HANDLE_VALUE)
+ FreeLibrary(module->modules[i]);
+
+ free(module->modules);
+ }
+
+ if (module->codeBase != NULL)
+ // release memory of library
+ VirtualFree(module->codeBase, 0, MEM_RELEASE);
+
+ if (module->name_table != NULL)
+ free(module->name_table);
+
+ HeapFree(GetProcessHeap(), 0, module);
+ }
+}
diff --git a/plugins/utils/MemoryModule.h b/plugins/utils/MemoryModule.h
new file mode 100644
index 0000000000..f314e5d1fb
--- /dev/null
+++ b/plugins/utils/MemoryModule.h
@@ -0,0 +1,48 @@
+/*
+ * Memory DLL loading code
+ * Version 0.0.2
+ *
+ * Copyright (c) 2004-2005 by Joachim Bauch / mail@joachim-bauch.de
+ * http://www.joachim-bauch.de
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is MemoryModule.h
+ *
+ * The Initial Developer of the Original Code is Joachim Bauch.
+ *
+ * Portions created by Joachim Bauch are Copyright (C) 2004-2005
+ * Joachim Bauch. All Rights Reserved.
+ *
+ */
+
+#ifndef __MEMORY_MODULE_HEADER
+#define __MEMORY_MODULE_HEADER
+
+#include <Windows.h>
+
+typedef void *HMEMORYMODULE;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+HMEMORYMODULE MemoryLoadLibrary(const void *);
+
+FARPROC MemoryGetProcAddress(HMEMORYMODULE, const char *);
+
+void MemoryFreeLibrary(HMEMORYMODULE);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __MEMORY_MODULE_HEADER
diff --git a/plugins/utils/mir_buffer.h b/plugins/utils/mir_buffer.h
new file mode 100644
index 0000000000..492050faf8
--- /dev/null
+++ b/plugins/utils/mir_buffer.h
@@ -0,0 +1,545 @@
+/*
+Copyright (C) 2005-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 __MIR_BUFFER_H__
+# define __MIR_BUFFER_H__
+
+#include <windows.h>
+
+#include "mir_memory.h"
+#include <m_variables.h>
+
+
+template<class T>
+static int __bvsnprintf(T *str, size_t size, const T *fmt, va_list args)
+{
+ return 0;
+}
+
+template<>
+static inline int __bvsnprintf<char>(char *str, size_t size, const char *fmt, va_list args)
+{
+ return _vsnprintf(str, size, fmt, args);
+}
+
+template<>
+static inline int __bvsnprintf<wchar_t>(wchar_t *str, size_t size, const wchar_t *fmt, va_list args)
+{
+ return _vsnwprintf(str, size, fmt, args);
+}
+
+template<class T>
+static inline size_t __blen(const T *str)
+{
+ return 0;
+}
+
+template<>
+static inline size_t __blen<char>(const char *str)
+{
+ return strlen(str);
+}
+
+template<>
+static inline size_t __blen<wchar_t>(const wchar_t *str)
+{
+ return lstrlenW(str);
+}
+
+template<class T>
+static inline T * __bTranslate(const T *str)
+{
+ return 0;
+}
+
+template<>
+static inline char * __bTranslate<char>(const char *str)
+{
+ return Translate(str);
+}
+
+template<>
+static inline wchar_t * __bTranslate<wchar_t>(const wchar_t *str)
+{
+ return TranslateW(str);
+}
+
+
+template<class O, class D>
+static void __bcopy(D *dest, const O *orig, size_t len)
+{
+}
+
+template<>
+static void __bcopy(char *dest, const char *orig, size_t len)
+{
+ strncpy(dest, orig, len);
+}
+
+template<>
+static void __bcopy(WCHAR *dest, const WCHAR *orig, size_t len)
+{
+ wcsncpy(dest, orig, len);
+}
+
+template<>
+static void __bcopy(WCHAR *dest, const char *orig, size_t len)
+{
+ MultiByteToWideChar(CallService("LangPack/GetCodePage", 0, 0), 0, orig, (int)len, dest, (int)len);
+}
+
+template<>
+static void __bcopy(char *dest, const WCHAR *orig, size_t len)
+{
+ WideCharToMultiByte(CallService("LangPack/GetCodePage", 0, 0), 0, orig, (int)len, dest, (int)len, NULL, NULL);
+}
+
+
+
+template<class T>
+class Buffer
+{
+ public:
+ size_t len;
+ T *str;
+
+ Buffer() : str(NULL), size(0), len(0)
+ {
+ alloc(1);
+ pack();
+ }
+
+ Buffer(T in) : str(NULL), size(0), len(0)
+ {
+ if (in == NULL)
+ {
+ alloc(1);
+ pack();
+ }
+ else
+ {
+ str = in;
+ size = len = __blen(str);
+ }
+ }
+
+ ~Buffer()
+ {
+ free();
+ }
+
+ void pack()
+ {
+ if (str != NULL)
+ memset(&str[len], 0, sizeof(str[len]));
+ }
+
+ void alloc(size_t total)
+ {
+ if (total > size)
+ {
+ size = total + 256 - total % 256;
+ if (str == NULL)
+ str = (T *) mir_alloc(size * sizeof(T));
+ else
+ str = (T *) mir_realloc(str, size * sizeof(T));
+ }
+ }
+
+ void free()
+ {
+ if (str != NULL)
+ {
+ mir_free(str);
+ str = NULL;
+ len = size = 0;
+ }
+ }
+
+ void clear()
+ {
+ len = 0;
+ pack();
+ }
+
+ void append(T app)
+ {
+ alloc(len + 1 + 1);
+
+ str[len] = app;
+ len++;
+ pack();
+ }
+
+ void appendn(size_t n, T app)
+ {
+ alloc(len + n + 1);
+
+ for(; n > 0; n--)
+ {
+ str[len] = app;
+ len++;
+ }
+ pack();
+ }
+
+ void append(const char *app, size_t appLen = -1)
+ {
+ if (app == NULL)
+ return;
+ if (appLen == -1)
+ appLen = __blen(app);
+
+ size_t total = len + appLen + 1;
+ alloc(total);
+
+ __bcopy(&str[len], app, appLen);
+ len += appLen;
+ pack();
+ }
+
+ void append(const WCHAR *app, size_t appLen = -1)
+ {
+ if (app == NULL)
+ return;
+ if (appLen == -1)
+ appLen = __blen(app);
+
+ size_t total = len + appLen + 1;
+ alloc(total);
+
+ __bcopy(&str[len], app, appLen);
+ len += appLen;
+ pack();
+ }
+
+ void append(const Buffer<char> &app)
+ {
+ if (app.str == NULL)
+ return;
+ size_t appLen = app.len;
+
+ size_t total = len + appLen + 1;
+ alloc(total);
+
+ __bcopy(&str[len], app.str, appLen);
+ len += appLen;
+ pack();
+ }
+
+ void append(const Buffer<WCHAR> &app)
+ {
+ size_t appLen = app.len;
+
+ size_t total = len + appLen + 1;
+ alloc(total);
+
+ __bcopy(&str[len], app.str , appLen);
+ len += appLen;
+ pack();
+ }
+
+ void appendPrintf(const T *app, ...)
+ {
+ size_t total = len + 512;
+ alloc(total);
+
+ va_list arg;
+ va_start(arg, app);
+ total = __bvsnprintf<T>(&str[len], size - len - 1, app, arg);
+ if (total < 0)
+ total = size - len - 1;
+ len += total;
+ pack();
+ }
+
+ void insert(size_t pos, T *app, size_t appLen = -1)
+ {
+ if (pos > len)
+ pos = len;
+ if (pos < 0)
+ pos = 0;
+
+ if (appLen == -1)
+ appLen = __blen(app);
+
+ alloc(len + appLen + 1);
+
+ if (pos < len)
+ memmove(&str[pos + appLen], &str[pos], (len - pos) * sizeof(T));
+ memmove(&str[pos], app, appLen * sizeof(T));
+
+ len += appLen;
+ pack();
+ }
+
+ void replace(size_t start, size_t end, T *app, size_t appLen = -1)
+ {
+ if (start > len)
+ start = len;
+ if (start < 0)
+ start = 0;
+
+ if (end > len)
+ end = len;
+ if (end < start)
+ end = start;
+
+ if (appLen == -1)
+ appLen = __blen(app);
+
+ size_t oldLen = end - start;
+ if (oldLen < appLen)
+ alloc(len + appLen - oldLen + 1);
+
+ if (end < len && oldLen != appLen)
+ memmove(&str[start + appLen], &str[end], (len - end) * sizeof(T));
+ memmove(&str[start], app, appLen * sizeof(T));
+
+ len += appLen - oldLen;
+ pack();
+ }
+
+ void replaceAll(T find, T replace)
+ {
+ for(size_t i = 0; i < len; i++)
+ if (str[len] == find)
+ str[len] = replace;
+ pack();
+ }
+
+ void translate()
+ {
+ if (str == NULL || len == 0)
+ return;
+
+ str[len] = 0;
+ T *tmp = __bTranslate(str);
+ len = __blen(tmp);
+ alloc(len + 1);
+ memmove(str, tmp, len * sizeof(T));
+ pack();
+ }
+
+ void reverse()
+ {
+ for(size_t i = 0; i < len/2; i++)
+ {
+ T tmp = str[i];
+ str[i] = str[len-i-1];
+ str[len-i-1] = tmp;
+ }
+ }
+
+ T *appender(size_t appLen)
+ {
+ alloc(len + appLen + 1);
+ T *ret = &str[len];
+ len += appLen;
+ return ret;
+ }
+
+ T *lock(size_t maxSize)
+ {
+ alloc(len + maxSize + 1);
+ return &str[len];
+ }
+
+ void release()
+ {
+ len += max(__blen(&str[len]), size - len - 1);
+ }
+
+ T *detach()
+ {
+ T *ret = str;
+ str = NULL;
+ len = 0;
+ return ret;
+ }
+
+ void trimRight()
+ {
+ if (str == NULL)
+ return;
+
+ int e;
+ for(e = len-1; e >= 0 && (str[e] == (T)' '
+ || str[e] == (T)'\t'
+ || str[e] == (T)'\r'
+ || str[e] == (T)'\n'); e--) ;
+ len = e+1;
+ pack();
+ }
+
+ void trimLeft()
+ {
+ if (str == NULL)
+ return;
+
+ int s;
+ for(s = 0; str[s] == (T)' '
+ || str[s] == (T)'\t'
+ || str[s] == (T)'\r'
+ || str[s] == (T)'\n'; s++) ;
+ if (s > 0)
+ {
+ memmove(str, &str[s], (len - s) * sizeof(T));
+ len -= s;
+ }
+ pack();
+ }
+
+ void trim()
+ {
+ trimRight();
+ trimLeft();
+ }
+
+ Buffer<T>& operator+=(const char *txt)
+ {
+ append(txt);
+ return *this;
+ }
+
+ Buffer<T>& operator+=(const WCHAR *txt)
+ {
+ append(txt);
+ return *this;
+ }
+
+ Buffer<T>& operator+=(const Buffer<T> &txt)
+ {
+ append(txt);
+ return *this;
+ }
+
+ Buffer<T>& operator=(const char *txt)
+ {
+ clear();
+ append(txt);
+ return *this;
+ }
+
+ Buffer<T>& operator=(const WCHAR *txt)
+ {
+ clear();
+ append(txt);
+ return *this;
+ }
+
+ Buffer<T>& operator=(const Buffer<T> &txt)
+ {
+ clear();
+ append(txt);
+ return *this;
+ }
+
+
+ private:
+ size_t size;
+};
+
+
+static void ReplaceVars(Buffer<TCHAR> *buffer, HANDLE hContact, TCHAR **variables, int numVariables)
+{
+ if (buffer->len < 3)
+ return;
+
+ if (numVariables < 0)
+ return;
+
+ for(size_t i = buffer->len - 1; i > 0; i--)
+ {
+ if (buffer->str[i] == _T('%'))
+ {
+ // Find previous
+ size_t j;
+ for(j = i - 1; j > 0 && ((buffer->str[j] >= _T('a') && buffer->str[j] <= _T('z'))
+ || (buffer->str[j] >= _T('A') && buffer->str[j] <= _T('Z'))
+ || buffer->str[j] == _T('-')
+ || buffer->str[j] == _T('_')); j--) ;
+
+ if (buffer->str[j] == _T('%'))
+ {
+ size_t foundLen = i - j + 1;
+ if (foundLen == 9 && _tcsncmp(&buffer->str[j], _T("%contact%"), 9) == 0)
+ {
+ buffer->replace(j, i + 1, (TCHAR *) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM) hContact, GCDNF_TCHAR | GCDNF_NOCACHE));
+ }
+ else if (foundLen == 6 && _tcsncmp(&buffer->str[j], _T("%date%"), 6) == 0)
+ {
+ TCHAR tmp[128];
+ DBTIMETOSTRINGT tst = {0};
+ tst.szFormat = _T("d s");
+ tst.szDest = tmp;
+ tst.cbDest = 128;
+ CallService(MS_DB_TIME_TIMESTAMPTOSTRINGT, (WPARAM) time(NULL), (LPARAM) &tst);
+ buffer->replace(j, i + 1, tmp);
+ }
+ else
+ {
+ for(int k = 0; k < numVariables; k += 2)
+ {
+ size_t len = lstrlen(variables[k]);
+ if (foundLen == len + 2 && _tcsncmp(&buffer->str[j]+1, variables[k], len) == 0)
+ {
+ buffer->replace(j, i + 1, variables[k + 1]);
+ break;
+ }
+ }
+ }
+ }
+
+ i = j;
+ if (i == 0)
+ break;
+ }
+ else if (buffer->str[i] == _T('\\') && i+1 <= buffer->len-1 && buffer->str[i+1] == _T('n'))
+ {
+ buffer->str[i] = _T('\r');
+ buffer->str[i+1] = _T('\n');
+ }
+ }
+}
+
+
+static void ReplaceTemplate(Buffer<TCHAR> *out, HANDLE hContact, TCHAR *templ, TCHAR **vars, int numVars)
+{
+
+ if (ServiceExists(MS_VARS_FORMATSTRING))
+ {
+ TCHAR *tmp = variables_parse_ex(templ, NULL, hContact, vars, numVars);
+ if (tmp != NULL)
+ {
+ out->append(tmp);
+ variables_free(tmp);
+ out->pack();
+ return;
+ }
+ }
+
+ out->append(templ);
+ ReplaceVars(out, hContact, vars, numVars);
+ out->pack();
+}
+
+
+#endif // __MIR_BUFFER_H__
diff --git a/plugins/utils/mir_dblists.cpp b/plugins/utils/mir_dblists.cpp
new file mode 100644
index 0000000000..a1711eda4b
--- /dev/null
+++ b/plugins/utils/mir_dblists.cpp
@@ -0,0 +1,149 @@
+/*
+Copyright (C) 2005 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+#include "mir_dblists.h"
+#include "mir_memory.h"
+
+#include <stdio.h>
+
+#include <newpluginapi.h>
+#include <m_system.h>
+
+
+struct LIST_INTERFACE list_interface = {0};
+
+
+void init_list_interface()
+{
+ list_interface.cbSize = sizeof(list_interface);
+ CallService(MS_SYSTEM_GET_LI, 0, (LPARAM)&list_interface);
+}
+
+
+void List_DestroyFreeContents( SortedList* p_list )
+{
+ if ( p_list == NULL )
+ return;
+
+ if ( p_list->items != NULL )
+ {
+ int i;
+ for ( i = 0 ; i < p_list->realCount ; i++ )
+ {
+ if ( p_list->items[i] != NULL )
+ {
+ mir_free( p_list->items[i] );
+ }
+ }
+ }
+
+ List_Destroy( p_list );
+}
+
+
+int List_Append( SortedList* p_list, void* p_value )
+{
+ return List_Insert( p_list, p_value, p_list->realCount );
+}
+
+
+int List_InsertOrdered( SortedList* p_list, void* p_value )
+{
+ int index;
+
+ List_GetIndex( p_list, p_value, &index );
+ List_Insert( p_list, p_value, index );
+
+ return index;
+}
+
+
+int List_RemoveByValue( SortedList* p_list, void* p_value )
+{
+ int ret = 0;
+
+ if ( p_list->items != NULL )
+ {
+ int i;
+ for ( i = p_list->realCount - 1 ; i >= 0 ; i-- )
+ {
+ if ( p_list->items[ i ] == p_value )
+ ret += List_Remove( p_list, i );
+ }
+ }
+
+ return ret;
+}
+
+
+int List_RemoveByValueFreeContents( SortedList* p_list, void* p_value )
+{
+ int ret = 0;
+
+ if ( p_list->items != NULL )
+ {
+ int i;
+ for ( i = p_list->realCount - 1 ; i >= 0 ; i-- )
+ {
+ if ( p_list->items[ i ] == p_value )
+ {
+ mir_free( p_list->items[ i ] );
+ ret += List_Remove( p_list, i );
+ }
+ }
+ }
+
+ return ret;
+}
+
+
+void List_Push( SortedList* p_list, void* p_value )
+{
+ List_Insert( p_list, p_value, p_list->realCount );
+}
+
+
+void* List_Pop( SortedList* p_list )
+{
+ void *ret;
+
+ if ( p_list->realCount <= 0 )
+ return NULL;
+
+ ret = p_list->items[ p_list->realCount - 1 ];
+ List_Remove( p_list, p_list->realCount - 1 );
+
+ return ret;
+}
+
+
+void* List_Peek( SortedList* p_list )
+{
+ if ( p_list->realCount <= 0 )
+ return NULL;
+
+ return p_list->items[ p_list->realCount - 1 ];
+}
+
+
+BOOL List_HasItens( SortedList* p_list )
+{
+ return p_list->realCount > 0;
+} \ No newline at end of file
diff --git a/plugins/utils/mir_dblists.h b/plugins/utils/mir_dblists.h
new file mode 100644
index 0000000000..4d4552b49d
--- /dev/null
+++ b/plugins/utils/mir_dblists.h
@@ -0,0 +1,62 @@
+/*
+Copyright (C) 2005 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef __MIR_DBLISTS_H__
+# define __MIR_DBLISTS_H__
+
+#include <windows.h>
+#include <newpluginapi.h>
+#include <m_system.h>
+
+
+
+extern struct LIST_INTERFACE list_interface;
+
+
+// Need to be called on ME_SYSTEM_MODULESLOADED
+void init_list_interface();
+
+
+#define List_Create(x,y) (list_interface.List_Create(x,y))
+#define List_Destroy(x) (list_interface.List_Destroy(x))
+#define List_Find(x,y) (list_interface.List_Find(x,y))
+#define List_GetIndex(x,y,z) (list_interface.List_GetIndex(x,y,z))
+#define List_Insert(x,y,z) (list_interface.List_Insert(x,y,z))
+#define List_Remove(x,y) (list_interface.List_Remove(x,y))
+#define List_IndexOf(x,y) (list_interface.List_IndexOf(x,y))
+
+
+BOOL List_HasItens( SortedList* p_list );
+
+void List_DestroyFreeContents( SortedList* );
+int List_RemoveByValue( SortedList*, void* );
+int List_RemoveByValueFreeContents( SortedList*, void* );
+
+int List_Append( SortedList*, void* );
+int List_InsertOrdered( SortedList*, void* );
+
+// Theese work on the end of the list
+void List_Push( SortedList* p_list, void* p_value );
+void* List_Pop( SortedList* p_list );
+void* List_Peek( SortedList* p_list );
+
+
+
+#endif // __MIR_DBLISTS_H__
diff --git a/plugins/utils/mir_dbutils.h b/plugins/utils/mir_dbutils.h
new file mode 100644
index 0000000000..cb7400a5ff
--- /dev/null
+++ b/plugins/utils/mir_dbutils.h
@@ -0,0 +1,70 @@
+/*
+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 __DBUTILS_H__
+# define __DBUTILS_H__
+
+
+class DBTString
+{
+ DBVARIANT dbv;
+ bool exists;
+
+public:
+ DBTString(HANDLE hContact, char *module, char *setting)
+ {
+ ZeroMemory(&dbv, sizeof(dbv));
+ exists = (DBGetContactSettingTString(hContact, module, setting, &dbv) == 0);
+ }
+
+ ~DBTString()
+ {
+ if (exists)
+ DBFreeVariant(&dbv);
+ }
+
+ const TCHAR * get() const
+ {
+ if (!exists)
+ return NULL;
+ else
+ return dbv.ptszVal;
+ }
+
+ const bool operator==(const TCHAR *other)
+ {
+ return get() == other;
+ }
+
+ const bool operator!=(const TCHAR *other)
+ {
+ return get() != other;
+ }
+
+ operator const TCHAR *() const
+ {
+ return get();
+ }
+};
+
+
+
+
+
+
+#endif // __DBUTILS_H__
diff --git a/plugins/utils/mir_icons.cpp b/plugins/utils/mir_icons.cpp
new file mode 100644
index 0000000000..1fb2c0ef82
--- /dev/null
+++ b/plugins/utils/mir_icons.cpp
@@ -0,0 +1,86 @@
+/*
+Copyright (C) 2007-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 "mir_icons.h"
+
+#include <newpluginapi.h>
+#include <m_system.h>
+#include <m_icolib.h>
+
+extern HINSTANCE hInst;
+
+
+
+HICON IcoLib_LoadIcon(const char *iconName, BOOL copy)
+{
+ if (!ServiceExists(MS_SKIN2_GETICON))
+ return NULL;
+
+ if (iconName == NULL || iconName[0] == 0)
+ return NULL;
+
+ HICON hIcon = (HICON) CallService(MS_SKIN2_GETICON, 0, (LPARAM) iconName);
+ if (copy && hIcon != NULL)
+ {
+ hIcon = CopyIcon(hIcon);
+ CallService(MS_SKIN2_RELEASEICON, (WPARAM) hIcon, 0);
+ }
+ return hIcon;
+}
+
+void IcoLib_ReleaseIcon(const char *iconName)
+{
+ if (ServiceExists(MS_SKIN2_RELEASEICON))
+ CallService(MS_SKIN2_RELEASEICON, 0, (LPARAM) iconName);
+}
+
+
+void IcoLib_ReleaseIcon(HICON hIcon)
+{
+ if (ServiceExists(MS_SKIN2_RELEASEICON))
+ CallService(MS_SKIN2_RELEASEICON, (WPARAM) hIcon, 0);
+}
+
+
+void IcoLib_Register(char *name, TCHAR *section, TCHAR *description, int id)
+{
+ HICON hIcon = (HICON) CallService(MS_SKIN2_GETICON, 0, (LPARAM) name);
+ if (hIcon != NULL)
+ {
+ CallService(MS_SKIN2_RELEASEICON, (WPARAM) hIcon, 0);
+ return;
+ }
+
+ SKINICONDESC sid = {0};
+ sid.cbSize = sizeof(SKINICONDESC);
+ sid.flags = SIDF_TCHAR;
+ sid.pszName = name;
+ sid.ptszSection = section;
+ sid.ptszDescription = description;
+
+ int cx = GetSystemMetrics(SM_CXSMICON);
+ sid.hDefaultIcon = (HICON) LoadImage(hInst, MAKEINTRESOURCE(id), IMAGE_ICON, cx, cx, LR_DEFAULTCOLOR | LR_SHARED);
+
+ CallService(MS_SKIN2_ADDICON, 0, (LPARAM)&sid);
+
+ if (sid.hDefaultIcon)
+ DestroyIcon(sid.hDefaultIcon);
+}
+
diff --git a/plugins/utils/mir_icons.h b/plugins/utils/mir_icons.h
new file mode 100644
index 0000000000..178094c803
--- /dev/null
+++ b/plugins/utils/mir_icons.h
@@ -0,0 +1,38 @@
+/*
+Copyright (C) 2005-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 __MIR_ICONS_H__
+# define __MIR_ICONS_H__
+
+#define _CRT_SECURE_NO_WARNINGS
+
+#include <windows.h>
+
+
+void IcoLib_Register(char *name, TCHAR *section, TCHAR *description, int id);
+
+HICON IcoLib_LoadIcon(const char *iconName, BOOL copy = FALSE);
+void IcoLib_ReleaseIcon(const char *iconName);
+void IcoLib_ReleaseIcon(HICON hIcon);
+
+
+
+
+#endif // __MIR_ICONS_H__
diff --git a/plugins/utils/mir_log.cpp b/plugins/utils/mir_log.cpp
new file mode 100644
index 0000000000..5a5a18060f
--- /dev/null
+++ b/plugins/utils/mir_log.cpp
@@ -0,0 +1,220 @@
+/*
+Copyright (C) 2005-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 "mir_log.h"
+
+#include <stdio.h>
+
+#include <newpluginapi.h>
+#include <m_netlib.h>
+#include <m_protocols.h>
+#include <m_clist.h>
+
+#define ENABLE_LOG
+
+
+int MLog::deep = 0;
+
+MLog::MLog(const char *aModule, const char *aFunction)
+ : module(aModule)
+{
+ memset(&total, 0, sizeof(total));
+
+ function = "";
+ for(int i = 0; i < deep; i++)
+ function += " ";
+ function += aFunction;
+
+ deep ++;
+
+ mlog(module.c_str(), function.c_str(), "BEGIN");
+
+ StartTimer();
+}
+
+MLog::~MLog()
+{
+ StopTimer();
+
+ mlog(module.c_str(), function.c_str(), "END in %2.1lf ms", GetTotalTimeMS());
+ deep --;
+}
+
+int MLog::log(const char *fmt, ...)
+{
+ StopTimer();
+
+ double elapsed = GetElapsedTimeMS();
+
+ va_list va;
+ va_start(va, fmt);
+
+ char text[1024];
+ mir_snprintf(text, sizeof(text) - 10, "%s [in %2.1lf ms | total %2.1lf ms]",
+ fmt, GetElapsedTimeMS(), GetTotalTimeMS());
+
+ int ret = mlog(module.c_str(), function.c_str(), text, va);
+
+ va_end(va);
+
+ StartTimer();
+
+ return ret;
+}
+
+void MLog::StartTimer()
+{
+ QueryPerformanceCounter(&start);
+}
+
+void MLog::StopTimer()
+{
+ QueryPerformanceCounter(&end);
+
+ total.QuadPart += end.QuadPart - start.QuadPart;
+}
+
+double MLog::GetElapsedTimeMS()
+{
+ LARGE_INTEGER frequency;
+ QueryPerformanceFrequency(&frequency);
+
+ return (end.QuadPart - start.QuadPart) * 1000. / frequency.QuadPart;
+}
+
+double MLog::GetTotalTimeMS()
+{
+ LARGE_INTEGER frequency;
+ QueryPerformanceFrequency(&frequency);
+
+ return total.QuadPart * 1000. / frequency.QuadPart;
+}
+
+
+int mlog(const char *module, const char *function, const char *fmt, va_list va)
+{
+#ifdef ENABLE_LOG
+
+ char text[1024];
+ size_t len;
+
+ mir_snprintf(text, sizeof(text) - 10, "[%08u - %08u] [%s] [%s] ",
+ GetCurrentThreadId(), GetTickCount(), module, function);
+ len = strlen(text);
+
+ mir_vsnprintf(&text[len], sizeof(text) - len, fmt, va);
+
+#ifdef LOG_TO_NETLIB
+
+ return CallService(MS_NETLIB_LOG, NULL, (LPARAM) text);
+
+#else
+ char file[256];
+ _snprintf(file, sizeof(file), "c:\\miranda_%s.log.txt", module);
+
+ FILE *fp = fopen(file,"at");
+
+ if (fp != NULL)
+ {
+ fprintf(fp, "%s\n", text);
+ fclose(fp);
+ return 0;
+ }
+ else
+ {
+ return -1;
+ }
+
+#endif
+
+#else
+
+ return 0;
+
+#endif
+}
+
+
+int mlog(const char *module, const char *function, const char *fmt, ...)
+{
+ va_list va;
+ va_start(va, fmt);
+
+ int ret = mlog(module, function, fmt, va);
+
+ va_end(va);
+
+ return ret;
+}
+
+int mlogC(const char *module, const char *function, HANDLE hContact, const char *fmt, ...)
+{
+#ifdef ENABLE_LOG
+
+ va_list va;
+ char text[1024];
+ size_t len;
+
+ char *name = NULL;
+ char *proto = NULL;
+ if (hContact != NULL)
+ {
+ name = (char*) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, 0);
+ proto = (char*) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
+ }
+
+ mir_snprintf(text, sizeof(text) - 10, "[%08u - %08u] [%s] [%s] [%08d - %s - %s] ",
+ GetCurrentThreadId(), GetTickCount(), module, function,
+ hContact, proto == NULL ? "" : proto, name == NULL ? "" : name);
+ len = strlen(text);
+
+ va_start(va, fmt);
+ mir_vsnprintf(&text[len], sizeof(text) - len, fmt, va);
+ va_end(va);
+
+#ifdef LOG_TO_NETLIB
+
+ return CallService(MS_NETLIB_LOG, NULL, (LPARAM) text);
+
+#else
+ char file[256];
+ _snprintf(file, sizeof(file), "c:\\miranda_%s.log.txt", module);
+
+ FILE *fp = fopen(file,"at");
+
+ if (fp != NULL)
+ {
+ fprintf(fp, "%s\n", text);
+ fclose(fp);
+ return 0;
+ }
+ else
+ {
+ return -1;
+ }
+
+#endif
+
+#else
+
+ return 0;
+
+#endif
+}
diff --git a/plugins/utils/mir_log.h b/plugins/utils/mir_log.h
new file mode 100644
index 0000000000..5785e191ff
--- /dev/null
+++ b/plugins/utils/mir_log.h
@@ -0,0 +1,63 @@
+/*
+Copyright (C) 2005-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 __LOG_H__
+# define __LOG_H__
+
+#include <windows.h>
+#include <string>
+
+
+int mlog(const char *module, const char *function, const char *fmt, ...);
+int mlog(const char *module, const char *function, const char *fmt, va_list va);
+int mlogC(const char *module, const char *function, HANDLE hContact, const char *fmt, ...);
+
+
+#ifdef __cplusplus
+
+class MLog
+{
+private:
+ std::string module;
+ std::string function;
+ LARGE_INTEGER start;
+ LARGE_INTEGER end;
+ LARGE_INTEGER total;
+
+ static int deep;
+
+ void StartTimer();
+ void StopTimer();
+ double GetElapsedTimeMS();
+ double GetTotalTimeMS();
+
+public:
+ MLog(const char *aModule, const char *aFunction);
+ ~MLog();
+
+ int log(const char *fmt, ...);
+};
+
+
+#endif __cplusplus
+
+
+
+#endif // __LOG_H__
diff --git a/plugins/utils/mir_memory.h b/plugins/utils/mir_memory.h
new file mode 100644
index 0000000000..b7ed17b6aa
--- /dev/null
+++ b/plugins/utils/mir_memory.h
@@ -0,0 +1,124 @@
+/*
+Copyright (C) 2005-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 __MIR_MEMORY_H__
+# define __MIR_MEMORY_H__
+
+
+#include <windows.h>
+
+
+
+static BOOL mir_is_unicode()
+{
+ static int is_unicode = -1;
+ if (is_unicode == -1)
+ {
+ char ver[1024];
+ CallService(MS_SYSTEM_GETVERSIONTEXT, (WPARAM) sizeof(ver), (LPARAM) ver);
+ is_unicode = (strstr(ver, "Unicode") != NULL ? 1 : 0);
+ }
+ return is_unicode;
+}
+
+
+static void * mir_alloc0(size_t size)
+{
+ void * ptr = mir_alloc(size);
+
+ if (ptr != NULL)
+ memset(ptr, 0, size);
+
+ return ptr;
+}
+
+static int strcmpnull(char *str1, char *str2)
+{
+ if ( str1 == NULL && str2 == NULL )
+ return 0;
+ if ( str1 != NULL && str2 == NULL )
+ return 1;
+ if ( str1 == NULL && str2 != NULL )
+ return -1;
+
+ return strcmp(str1, str2);
+}
+
+static int strcmpnullW(WCHAR *str1, WCHAR *str2)
+{
+ if ( str1 == NULL && str2 == NULL )
+ return 0;
+ if ( str1 != NULL && str2 == NULL )
+ return 1;
+ if ( str1 == NULL && str2 != NULL )
+ return -1;
+
+ return lstrcmpW(str1, str2);
+}
+
+
+#ifdef UNICODE
+
+#define CHECK_VERSION(_NAME_) \
+ if (!mir_is_unicode()) \
+ { \
+ MessageBox(NULL, _T("Your Miranda is ansi. You have to install ansi ") _T(_NAME_), \
+ _T(_NAME_), MB_OK | MB_ICONERROR); \
+ return -1; \
+ }
+
+# define lstrcmpnull strcmpnullW
+
+#define INPLACE_CHAR_TO_TCHAR(_new_var_, _size_, _old_var_) \
+ TCHAR _new_var_[_size_]; \
+ MultiByteToWideChar(CP_ACP, 0, _old_var_, -1, _new_var_, _size_)
+
+
+#define INPLACE_TCHAR_TO_CHAR(_new_var_, _size_, _old_var_) \
+ char _new_var_[_size_]; \
+ WideCharToMultiByte(CP_ACP, 0, _old_var_, -1, _new_var_, _size_, NULL, NULL);
+
+#else
+
+#define CHECK_VERSION(_NAME_) \
+ if (mir_is_unicode()) \
+ { \
+ MessageBox(NULL, _T("Your Miranda is unicode. You have to install unicode ") _T(_NAME_), \
+ _T(_NAME_), MB_OK | MB_ICONERROR); \
+ return -1; \
+ }
+
+# define lstrcmpnull strcmpnull
+
+#define INPLACE_CHAR_TO_TCHAR(_new_var_, _size_, _old_var_) \
+ TCHAR *_new_var_ = _old_var_
+
+#define INPLACE_TCHAR_TO_CHAR(_new_var_, _size_, _old_var_) \
+ char *_new_var_ = _old_var_;
+
+#endif
+
+
+
+// Free memory and set to NULL
+//#define MIR_FREE(_x_) if (_x_ != NULL) { mir_free(_x_); _x_ = NULL; }
+
+
+
+#endif // __MIR_MEMORY_H__
diff --git a/plugins/utils/mir_options.cpp b/plugins/utils/mir_options.cpp
new file mode 100644
index 0000000000..53c3fa6de2
--- /dev/null
+++ b/plugins/utils/mir_options.cpp
@@ -0,0 +1,650 @@
+/*
+Copyright (C) 2005-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 <windows.h>
+#include <commctrl.h>
+#include <stdio.h>
+#include <tchar.h>
+
+#define MIRANDA_VER 0x0600
+#include <newpluginapi.h>
+#include <m_database.h>
+#include <m_utils.h>
+#include <m_langpack.h>
+#include <m_protocols.h>
+#include <m_protosvc.h>
+#include <m_system.h>
+
+#include "mir_options.h"
+#include "mir_memory.h"
+
+
+#define MAX_REGS(_A_) ( sizeof(_A_) / sizeof(_A_[0]) )
+
+
+static TCHAR* MyDBGetContactSettingTString(HANDLE hContact, char* module, char* setting, TCHAR* out, size_t len, TCHAR *def)
+{
+ DBVARIANT dbv = {0};
+
+ out[0] = _T('\0');
+
+ if (!DBGetContactSettingTString(hContact, module, setting, &dbv))
+ {
+#ifdef UNICODE
+ if (dbv.type == DBVT_ASCIIZ)
+ {
+ MultiByteToWideChar(CP_ACP, 0, dbv.pszVal, -1, out, (int)len);
+ }
+ else if (dbv.type == DBVT_UTF8)
+ {
+ MultiByteToWideChar(CP_UTF8, 0, dbv.pszVal, -1, out, (int)len);
+ }
+ else if (dbv.type == DBVT_WCHAR)
+ {
+ lstrcpyn(out, dbv.pwszVal, (int)len);
+ }
+#else
+ if (dbv.type == DBVT_ASCIIZ)
+ {
+ lstrcpyn(out, dbv.pszVal, len);
+ }
+#endif
+ else
+ {
+ if (def != NULL)
+ lstrcpyn(out, def, (int)len);
+ }
+
+ DBFreeVariant(&dbv);
+ }
+ else
+ {
+ if (def != NULL)
+ lstrcpyn(out, def, (int)len);
+ }
+
+ return out;
+}
+
+
+static TCHAR dbPath[MAX_PATH] = {0}; // database profile path (read at startup only)
+
+
+static int PathIsAbsolute(const TCHAR *path)
+{
+ if (!path || !(lstrlen(path) > 2))
+ return 0;
+ if ((path[1]==_T(':') && path[2]==_T('\\')) || (path[0]==_T('\\')&&path[1]==_T('\\')))
+ return 1;
+ return 0;
+}
+
+static void PathToRelative(TCHAR *pOut, size_t outSize, const TCHAR *pSrc)
+{
+ if (!PathIsAbsolute(pSrc))
+ {
+ lstrcpyn(pOut, pSrc, (int)outSize);
+ }
+ else
+ {
+ if (dbPath[0] == _T('\0'))
+ {
+ char tmp[1024];
+ CallService(MS_DB_GETPROFILEPATH, MAX_REGS(tmp), (LPARAM) tmp);
+ mir_sntprintf(dbPath, MAX_REGS(dbPath), _T(TCHAR_STR_PARAM) _T("\\"), tmp);
+ }
+
+ size_t len = lstrlen(dbPath);
+ if (_tcsnicmp(pSrc, dbPath, len))
+ {
+ mir_sntprintf(pOut, outSize, _T("%s"), pSrc + len);
+ }
+ else
+ {
+ lstrcpyn(pOut, pSrc, (int)outSize);
+ }
+ }
+}
+
+static void PathToAbsolute(TCHAR *pOut, size_t outSize, const TCHAR *pSrc)
+{
+ if (PathIsAbsolute(pSrc) || !isalnum(pSrc[0]))
+ {
+ lstrcpyn(pOut, pSrc, (int)outSize);
+ }
+ else
+ {
+ if (dbPath[0] == _T('\0'))
+ {
+ char tmp[1024];
+ CallService(MS_DB_GETPROFILEPATH, MAX_REGS(tmp), (LPARAM) tmp);
+ mir_sntprintf(dbPath, MAX_REGS(dbPath), _T(TCHAR_STR_PARAM) _T("\\"), tmp);
+ }
+
+ mir_sntprintf(pOut, outSize, _T("%s%s"), dbPath, pSrc);
+ }
+}
+
+
+static void LoadOpt(OptPageControl *ctrl, char *module)
+{
+ if (ctrl->var == NULL)
+ return;
+
+ switch(ctrl->type)
+ {
+ case CONTROL_CHECKBOX:
+ {
+ *((BYTE *) ctrl->var) = DBGetContactSettingByte(NULL, module, ctrl->setting, ctrl->dwDefValue);
+ break;
+ }
+ case CONTROL_SPIN:
+ {
+ *((WORD *) ctrl->var) = DBGetContactSettingWord(NULL, module, ctrl->setting, ctrl->dwDefValue);
+ break;
+ }
+ case CONTROL_COLOR:
+ {
+ *((COLORREF *) ctrl->var) = (COLORREF) DBGetContactSettingDword(NULL, module, ctrl->setting, ctrl->dwDefValue);
+ break;
+ }
+ case CONTROL_RADIO:
+ {
+ *((WORD *) ctrl->var) = DBGetContactSettingWord(NULL, module, ctrl->setting, ctrl->dwDefValue);
+ break;
+ }
+ case CONTROL_COMBO:
+ {
+ *((WORD *) ctrl->var) = DBGetContactSettingWord(NULL, module, ctrl->setting, ctrl->dwDefValue);
+ break;
+ }
+ case CONTROL_PROTOCOL_LIST:
+ {
+ break;
+ }
+ case CONTROL_TEXT:
+ {
+ MyDBGetContactSettingTString(NULL, module, ctrl->setting, ((TCHAR *) ctrl->var), min(ctrl->max <= 0 ? 1024 : ctrl->max, 1024), ctrl->tszDefValue == NULL ? NULL : TranslateTS(ctrl->tszDefValue));
+ break;
+ }
+ case CONTROL_PASSWORD:
+ {
+ char tmp[1024];
+ tmp[0]=0;
+
+ DBVARIANT dbv = {0};
+ if (!DBGetContactSettingString(NULL, module, ctrl->setting, &dbv))
+ {
+ lstrcpynA(tmp, dbv.pszVal, MAX_REGS(tmp));
+ DBFreeVariant(&dbv);
+ }
+
+ if (tmp[0] != 0)
+ CallService(MS_DB_CRYPT_DECODESTRING, MAX_REGS(tmp), (LPARAM) tmp);
+ else if (ctrl->szDefValue != NULL)
+ lstrcpynA(tmp, ctrl->szDefValue, MAX_REGS(tmp));
+
+ char *var = (char *) ctrl->var;
+ int size = min(ctrl->max <= 0 ? 1024 : ctrl->max, 1024);
+ lstrcpynA(var, tmp, size);
+ break;
+ }
+ case CONTROL_INT:
+ {
+ *((int *) ctrl->var) = (int) DBGetContactSettingDword(NULL, module, ctrl->setting, ctrl->dwDefValue);
+ break;
+ }
+ case CONTROL_FILE:
+ {
+ TCHAR tmp[1024];
+ MyDBGetContactSettingTString(NULL, module, ctrl->setting, tmp, 1024, ctrl->tszDefValue == NULL ? NULL : ctrl->tszDefValue);
+ PathToAbsolute(((TCHAR *) ctrl->var), min(ctrl->max <= 0 ? 1024 : ctrl->max, 1024), tmp);
+ break;
+ }
+ case CONTROL_COMBO_TEXT:
+ case CONTROL_COMBO_ITEMDATA:
+ {
+ MyDBGetContactSettingTString(NULL, module, ctrl->setting, ((TCHAR *) ctrl->var), min(ctrl->max <= 0 ? 1024 : ctrl->max, 1024), ctrl->tszDefValue == NULL ? NULL : TranslateTS(ctrl->tszDefValue));
+ break;
+ }
+ }
+}
+
+void LoadOpts(OptPageControl *controls, int controlsSize, char *module)
+{
+ for (int i = 0 ; i < controlsSize ; i++)
+ {
+ LoadOpt(&controls[i], module);
+ }
+}
+
+
+
+INT_PTR CALLBACK SaveOptsDlgProc(OptPageControl *controls, int controlsSize, char *module, HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ {
+ TranslateDialogDefault(hwndDlg);
+
+ for (int i = 0 ; i < controlsSize ; i++)
+ {
+ OptPageControl *ctrl = &controls[i];
+
+ if (GetDlgItem(hwndDlg, ctrl->nID) == NULL)
+ continue;
+
+ switch(ctrl->type)
+ {
+ case CONTROL_CHECKBOX:
+ {
+ CheckDlgButton(hwndDlg, ctrl->nID, DBGetContactSettingByte(NULL, module, ctrl->setting, ctrl->dwDefValue) == 1 ? BST_CHECKED : BST_UNCHECKED);
+ break;
+ }
+ case CONTROL_SPIN:
+ {
+ SendDlgItemMessage(hwndDlg, ctrl->nIDSpin, UDM_SETBUDDY, (WPARAM)GetDlgItem(hwndDlg, ctrl->nID),0);
+ SendDlgItemMessage(hwndDlg, ctrl->nIDSpin, UDM_SETRANGE, 0, MAKELONG(ctrl->max, ctrl->min));
+ SendDlgItemMessage(hwndDlg, ctrl->nIDSpin, UDM_SETPOS,0, MAKELONG(DBGetContactSettingWord(NULL, module, ctrl->setting, ctrl->dwDefValue), 0));
+ break;
+ }
+ case CONTROL_COLOR:
+ {
+ SendDlgItemMessage(hwndDlg, ctrl->nID, CPM_SETCOLOUR, 0, (COLORREF) DBGetContactSettingDword(NULL, module, ctrl->setting, ctrl->dwDefValue));
+ break;
+ }
+ case CONTROL_RADIO:
+ {
+ CheckDlgButton(hwndDlg, ctrl->nID, DBGetContactSettingWord(NULL, module, ctrl->setting, ctrl->dwDefValue) == ctrl->value ? BST_CHECKED : BST_UNCHECKED);
+ break;
+ }
+ case CONTROL_COMBO:
+ {
+ SendDlgItemMessage(hwndDlg, ctrl->nID, CB_SETCURSEL, DBGetContactSettingWord(NULL, module, ctrl->setting, ctrl->dwDefValue), 0);
+ break;
+ }
+ case CONTROL_PROTOCOL_LIST:
+ {
+ // Fill list view
+ HWND hwndProtocols = GetDlgItem(hwndDlg, ctrl->nID);
+ LVCOLUMN lvc;
+ LVITEM lvi;
+
+ ListView_SetExtendedListViewStyle(hwndProtocols, LVS_EX_CHECKBOXES);
+
+ ZeroMemory(&lvc, sizeof(lvc));
+ lvc.mask = LVCF_FMT;
+ lvc.fmt = LVCFMT_IMAGE | LVCFMT_LEFT;
+ ListView_InsertColumn(hwndProtocols, 0, &lvc);
+
+ ZeroMemory(&lvi, sizeof(lvi));
+ lvi.mask = LVIF_TEXT | LVIF_PARAM;
+ lvi.iSubItem = 0;
+ lvi.iItem = 1000;
+
+ PROTOACCOUNT **protos;
+ int count;
+
+ BOOL hasAccounts = ServiceExists(MS_PROTO_ENUMACCOUNTS);
+
+ if (hasAccounts)
+ CallService(MS_PROTO_ENUMACCOUNTS, (WPARAM)&count, (LPARAM)&protos);
+ else
+ CallService(MS_PROTO_ENUMPROTOCOLS, (WPARAM)&count, (LPARAM)&protos);
+
+ for (int i = 0; i < count; i++)
+ {
+ if (protos[i]->type != PROTOTYPE_PROTOCOL)
+ continue;
+
+ if (protos[i]->szModuleName == NULL || protos[i]->szModuleName[0] == '\0')
+ continue;
+
+ if (ctrl->allowProtocol != NULL && !ctrl->allowProtocol(protos[i]->szModuleName))
+ continue;
+
+ TCHAR *name;
+ if (hasAccounts)
+ {
+ name = mir_tstrdup(protos[i]->tszAccountName);
+ }
+ else
+ {
+ char szName[128];
+ CallProtoService(protos[i]->szModuleName, PS_GETNAME, sizeof(szName), (LPARAM)szName);
+ name = mir_a2t(szName);
+ }
+
+ char *setting = (char *) mir_alloc(128 * sizeof(char));
+ mir_snprintf(setting, 128, ctrl->setting, protos[i]->szModuleName);
+
+ BOOL show = (BOOL)DBGetContactSettingByte(NULL, module, setting, ctrl->dwDefValue);
+
+ lvi.lParam = (LPARAM)setting;
+ lvi.pszText = TranslateTS(name);
+ lvi.iItem = ListView_InsertItem(hwndProtocols, &lvi);
+ ListView_SetItemState(hwndProtocols, lvi.iItem, INDEXTOSTATEIMAGEMASK(show?2:1), LVIS_STATEIMAGEMASK);
+
+ mir_free(name);
+ }
+
+ ListView_SetColumnWidth(hwndProtocols, 0, LVSCW_AUTOSIZE);
+ ListView_Arrange(hwndProtocols, LVA_ALIGNLEFT | LVA_ALIGNTOP);
+ break;
+ }
+ case CONTROL_TEXT:
+ {
+ TCHAR tmp[1024];
+ SetDlgItemText(hwndDlg, ctrl->nID, MyDBGetContactSettingTString(NULL, module, ctrl->setting, tmp, 1024, ctrl->tszDefValue == NULL ? NULL : TranslateTS(ctrl->tszDefValue)));
+ SendDlgItemMessage(hwndDlg, ctrl->nID, EM_LIMITTEXT, min(ctrl->max <= 0 ? 1024 : ctrl->max, 1024), 0);
+ break;
+ }
+ case CONTROL_PASSWORD:
+ {
+ char tmp[1024];
+ tmp[0]=0;
+
+ DBVARIANT dbv = {0};
+ if (!DBGetContactSettingString(NULL, module, ctrl->setting, &dbv))
+ {
+ lstrcpynA(tmp, dbv.pszVal, MAX_REGS(tmp));
+ DBFreeVariant(&dbv);
+ }
+
+ if (tmp[0] != 0)
+ CallService(MS_DB_CRYPT_DECODESTRING, MAX_REGS(tmp), (LPARAM) tmp);
+ else if (ctrl->szDefValue != NULL)
+ lstrcpynA(tmp, ctrl->szDefValue, MAX_REGS(tmp));
+
+ SetDlgItemTextA(hwndDlg, ctrl->nID, tmp);
+ SendDlgItemMessage(hwndDlg, ctrl->nID, EM_LIMITTEXT, min(ctrl->max <= 0 ? 1024 : ctrl->max, 1024), 0);
+ break;
+ }
+ case CONTROL_INT:
+ {
+ DWORD var = DBGetContactSettingDword(NULL, module, ctrl->setting, ctrl->dwDefValue);
+ SetDlgItemInt(hwndDlg, ctrl->nID, var, ctrl->min <= 0);
+ SendDlgItemMessage(hwndDlg, ctrl->nID, EM_LIMITTEXT, 9, 0);
+ break;
+ }
+ case CONTROL_FILE:
+ {
+ TCHAR tmp[1024];
+ MyDBGetContactSettingTString(NULL, module, ctrl->setting, tmp, 1024, ctrl->tszDefValue == NULL ? NULL : ctrl->tszDefValue);
+ TCHAR abs[1024];
+ PathToAbsolute(abs, 1024, tmp);
+
+ SetDlgItemText(hwndDlg, ctrl->nID, abs);
+ SendDlgItemMessage(hwndDlg, ctrl->nID, EM_LIMITTEXT, min(ctrl->max <= 0 ? 1024 : ctrl->max, 1024), 0);
+ break;
+ }
+ case CONTROL_COMBO_TEXT:
+ {
+ TCHAR tmp[1024];
+ MyDBGetContactSettingTString(NULL, module, ctrl->setting, tmp, 1024, ctrl->tszDefValue == NULL ? NULL : TranslateTS(ctrl->tszDefValue));
+ SendDlgItemMessage(hwndDlg, ctrl->nID, CB_SELECTSTRING, 0, (WPARAM) tmp);
+ break;
+ }
+ case CONTROL_COMBO_ITEMDATA:
+ {
+ TCHAR tmp[1024];
+ MyDBGetContactSettingTString(NULL, module, ctrl->setting, tmp, 1024, ctrl->tszDefValue == NULL ? NULL : TranslateTS(ctrl->tszDefValue));
+ int count = SendDlgItemMessage(hwndDlg, ctrl->nID, CB_GETCOUNT, 0, 0);
+ int i;
+ for(i = 0; i < count; i++)
+ {
+ TCHAR *id = (TCHAR *) SendDlgItemMessage(hwndDlg, ctrl->nID, CB_GETITEMDATA, (WPARAM) i, 0);
+ if (lstrcmp(id, tmp) == 0)
+ break;
+ }
+ if (i < count)
+ SendDlgItemMessage(hwndDlg, ctrl->nID, CB_SETCURSEL, i, 0);
+ break;
+ }
+ }
+ }
+ break;
+ }
+ case WM_COMMAND:
+ {
+ for (int i = 0 ; i < controlsSize ; i++)
+ {
+ OptPageControl *ctrl = &controls[i];
+
+ if (LOWORD(wParam) == ctrl->nID)
+ {
+ switch(ctrl->type)
+ {
+ case CONTROL_TEXT:
+ case CONTROL_SPIN:
+ case CONTROL_INT:
+ case CONTROL_PASSWORD:
+ {
+ // Don't make apply enabled during buddy set
+ if (HIWORD(wParam) != EN_CHANGE || (HWND)lParam != GetFocus())
+ return 0;
+
+ break;
+ }
+ case CONTROL_COMBO_ITEMDATA:
+ case CONTROL_COMBO_TEXT:
+ case CONTROL_COMBO:
+ {
+ if (HIWORD(wParam) != CBN_SELCHANGE || (HWND)lParam != GetFocus())
+ return 0;
+
+ break;
+ }
+ }
+
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ }
+ }
+
+ break;
+ }
+ case WM_NOTIFY:
+ {
+ LPNMHDR lpnmhdr = (LPNMHDR)lParam;
+
+ if (lpnmhdr->idFrom == 0 && lpnmhdr->code == PSN_APPLY)
+ {
+ for (int i = 0 ; i < controlsSize ; i++)
+ {
+ OptPageControl *ctrl = &controls[i];
+
+ if (GetDlgItem(hwndDlg, ctrl->nID) == NULL)
+ continue;
+
+ switch(ctrl->type)
+ {
+ case CONTROL_CHECKBOX:
+ {
+ DBWriteContactSettingByte(NULL, module, ctrl->setting, (BYTE) IsDlgButtonChecked(hwndDlg, ctrl->nID));
+ break;
+ }
+ case CONTROL_SPIN:
+ {
+ DBWriteContactSettingWord(NULL, module, ctrl->setting, (WORD) SendDlgItemMessage(hwndDlg, ctrl->nIDSpin, UDM_GETPOS, 0, 0));
+ break;
+ }
+ case CONTROL_COLOR:
+ {
+ DBWriteContactSettingDword(NULL, module, ctrl->setting, (DWORD) SendDlgItemMessage(hwndDlg, ctrl->nID, CPM_GETCOLOUR, 0, 0));
+ break;
+ }
+ case CONTROL_RADIO:
+ {
+ if (IsDlgButtonChecked(hwndDlg, ctrl->nID))
+ DBWriteContactSettingWord(NULL, module, ctrl->setting, (BYTE) ctrl->value);
+ break;
+ }
+ case CONTROL_COMBO:
+ {
+ DBWriteContactSettingWord(NULL, module, ctrl->setting, (WORD) SendDlgItemMessage(hwndDlg, ctrl->nID, CB_GETCURSEL, 0, 0));
+ break;
+ }
+ case CONTROL_PROTOCOL_LIST:
+ {
+ LVITEM lvi = {0};
+ HWND hwndProtocols = GetDlgItem(hwndDlg, ctrl->nID);
+ int i;
+
+ lvi.mask = (UINT) LVIF_PARAM;
+
+ for (i = 0; i < ListView_GetItemCount(hwndProtocols); i++)
+ {
+ lvi.iItem = i;
+ ListView_GetItem(hwndProtocols, &lvi);
+
+ char *setting = (char *)lvi.lParam;
+ DBWriteContactSettingByte(NULL, module, setting, (BYTE)ListView_GetCheckState(hwndProtocols, i));
+ }
+ break;
+ }
+ case CONTROL_TEXT:
+ {
+ TCHAR tmp[1024];
+ GetDlgItemText(hwndDlg, ctrl->nID, tmp, MAX_REGS(tmp));
+ DBWriteContactSettingTString(NULL, module, ctrl->setting, tmp);
+ break;
+ }
+ case CONTROL_PASSWORD:
+ {
+ char tmp[1024];
+ GetDlgItemTextA(hwndDlg, ctrl->nID, tmp, MAX_REGS(tmp));
+
+ if (ctrl->var != NULL)
+ {
+ char *var = (char *) ctrl->var;
+ int size = min(ctrl->max <= 0 ? 1024 : ctrl->max, 1024);
+ lstrcpynA(var, tmp, size);
+ }
+
+ if (ctrl->checkboxID != 0 && !IsDlgButtonChecked(hwndDlg, ctrl->checkboxID))
+ {
+ DBDeleteContactSetting(NULL, module, ctrl->setting);
+ continue;
+ }
+
+ CallService(MS_DB_CRYPT_ENCODESTRING, MAX_REGS(tmp), (LPARAM) tmp);
+ DBWriteContactSettingString(NULL, module, ctrl->setting, tmp);
+
+ // Don't load from DB
+ continue;
+ }
+ case CONTROL_INT:
+ {
+ BOOL trans;
+ int val = GetDlgItemInt(hwndDlg, ctrl->nID, &trans, ctrl->min <= 0);
+ if (!trans)
+ val = ctrl->dwDefValue;
+ if (ctrl->max != 0)
+ val = min(val, ctrl->max);
+ if (ctrl->min != 0)
+ val = max(val, ctrl->min);
+ DBWriteContactSettingDword(NULL, module, ctrl->setting, val);
+ break;
+ }
+ case CONTROL_FILE:
+ {
+ TCHAR tmp[1024];
+ GetDlgItemText(hwndDlg, ctrl->nID, tmp, 1024);
+ TCHAR rel[1024];
+ PathToRelative(rel, 1024, tmp);
+ DBWriteContactSettingTString(NULL, module, ctrl->setting, rel);
+ break;
+ }
+ case CONTROL_COMBO_TEXT:
+ {
+ TCHAR tmp[1024];
+ GetDlgItemText(hwndDlg, ctrl->nID, tmp, 1024);
+ DBWriteContactSettingTString(NULL, module, ctrl->setting, tmp);
+ break;
+ }
+ case CONTROL_COMBO_ITEMDATA:
+ {
+ int sel = SendDlgItemMessage(hwndDlg, ctrl->nID, CB_GETCURSEL, 0, 0);
+ DBWriteContactSettingTString(NULL, module, ctrl->setting, (TCHAR *) SendDlgItemMessage(hwndDlg, ctrl->nID, CB_GETITEMDATA, (WPARAM) sel, 0));
+ break;
+ }
+ }
+
+ LoadOpt(ctrl, module);
+ }
+
+ return TRUE;
+ }
+ else if (lpnmhdr->idFrom != 0 && lpnmhdr->code == LVN_ITEMCHANGED)
+ {
+ // Changed for protocols
+ for (int i = 0 ; i < controlsSize ; i++)
+ {
+ OptPageControl *ctrl = &controls[i];
+
+ if (ctrl->type == CONTROL_PROTOCOL_LIST && ctrl->nID == lpnmhdr->idFrom)
+ {
+ NMLISTVIEW *nmlv = (NMLISTVIEW *)lParam;
+
+ if(IsWindowVisible(GetDlgItem(hwndDlg, ctrl->nID)) && ((nmlv->uNewState ^ nmlv->uOldState) & LVIS_STATEIMAGEMASK))
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+
+ break;
+ }
+ }
+ }
+ break;
+ }
+ case WM_DESTROY:
+ {
+ for (int i = 0 ; i < controlsSize ; i++)
+ {
+ OptPageControl *ctrl = &controls[i];
+
+ if (GetDlgItem(hwndDlg, ctrl->nID) == NULL)
+ continue;
+
+ switch(ctrl->type)
+ {
+ case CONTROL_PROTOCOL_LIST:
+ {
+ LVITEM lvi = {0};
+ HWND hwndProtocols = GetDlgItem(hwndDlg, ctrl->nID);
+ int i;
+
+ lvi.mask = (UINT) LVIF_PARAM;
+
+ for (i = 0; i < ListView_GetItemCount(hwndProtocols); i++)
+ {
+ lvi.iItem = i;
+ ListView_GetItem(hwndProtocols, &lvi);
+ mir_free((char *) lvi.lParam);
+ }
+ break;
+ }
+ }
+ }
+ break;
+ }
+ }
+
+ return 0;
+}
diff --git a/plugins/utils/mir_options.h b/plugins/utils/mir_options.h
new file mode 100644
index 0000000000..8bfcd4dd0d
--- /dev/null
+++ b/plugins/utils/mir_options.h
@@ -0,0 +1,72 @@
+/*
+Copyright (C) 2005-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 __MIR_OPTIONS_H__
+# define __MIR_OPTIONS_H__
+
+#include <windows.h>
+
+
+#define CONTROL_CHECKBOX 0 // Stored as BYTE
+#define CONTROL_SPIN 1 // Stored as WORD
+#define CONTROL_COLOR 2 // Stored as DWORD
+#define CONTROL_RADIO 3 // Stored as WORD
+#define CONTROL_COMBO 4 // Stored as WORD
+#define CONTROL_PROTOCOL_LIST 5 // Stored as BYTEs
+#define CONTROL_TEXT 6 // Stored as TCHARs, max len 1024
+#define CONTROL_COMBO_TEXT 7 // Stored as TCHARs, max len 1024
+#define CONTROL_COMBO_ITEMDATA 8 // Stored as TCHARs, max len 1024
+#define CONTROL_FILE 9 // Stored as TCHARs, max len 1024
+#define CONTROL_INT 10 // Stored as DWORD
+#define CONTROL_PASSWORD 11 // Stored as chars, max len 1024
+
+
+typedef BOOL (* FPAllowProtocol) (const char *proto);
+
+typedef struct {
+ void *var;
+ int type;
+ unsigned int nID;
+ char *setting;
+ union {
+ ULONG_PTR dwDefValue;
+ TCHAR *tszDefValue;
+ char *szDefValue;
+ };
+ union {
+ int nIDSpin;
+ int value;
+ FPAllowProtocol allowProtocol;
+ unsigned int checkboxID;
+ };
+ WORD min;
+ WORD max;
+} OptPageControl;
+
+INT_PTR CALLBACK SaveOptsDlgProc(OptPageControl *controls, int controlsSize, char *module, HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+
+void LoadOpts(OptPageControl *controls, int controlsSize, char *module);
+
+
+
+
+
+
+#endif // __MIR_OPTIONS_H__
diff --git a/plugins/utils/mir_options_notify.cpp b/plugins/utils/mir_options_notify.cpp
new file mode 100644
index 0000000000..ddc0a548c1
--- /dev/null
+++ b/plugins/utils/mir_options_notify.cpp
@@ -0,0 +1,199 @@
+/*
+Copyright (C) 2005 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+#include "mir_options_notify.h"
+
+#include <stdio.h>
+#include <commctrl.h>
+#include <tchar.h>
+
+extern "C"
+{
+#include <newpluginapi.h>
+#include <m_database.h>
+#include <m_utils.h>
+#include <m_langpack.h>
+#include <m_notify.h>
+#include "templates.h"
+}
+
+
+#define MAX_REGS(_A_) ( sizeof(_A_) / sizeof(_A_[0]) )
+
+
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Dialog to save options
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+BOOL CALLBACK SaveOptsDlgProc(OptPageControl *controls, int controlsSize, HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg)
+ {
+ case WM_USER+100:
+ {
+ HANDLE hNotify = (HANDLE)lParam;
+ SetWindowLong(hwndDlg, GWL_USERDATA, lParam);
+
+ TranslateDialogDefault(hwndDlg);
+
+ for (int i = 0 ; i < controlsSize ; i++)
+ {
+ OptPageControl *ctrl = &controls[i];
+
+ switch(ctrl->type)
+ {
+ case CONTROL_CHECKBOX:
+ {
+ CheckDlgButton(hwndDlg, ctrl->nID, MNotifyGetByte(hNotify, ctrl->setting, (BYTE)ctrl->dwDefValue) == 1 ? BST_CHECKED : BST_UNCHECKED);
+ break;
+ }
+ case CONTROL_SPIN:
+ {
+ SendDlgItemMessage(hwndDlg, ctrl->nIDSpin, UDM_SETBUDDY, (WPARAM)GetDlgItem(hwndDlg, ctrl->nID),0);
+ SendDlgItemMessage(hwndDlg, ctrl->nIDSpin, UDM_SETRANGE, 0, MAKELONG(ctrl->max, ctrl->min));
+ SendDlgItemMessage(hwndDlg, ctrl->nIDSpin, UDM_SETPOS,0, MAKELONG(MNotifyGetWord(hNotify, ctrl->setting, (WORD)ctrl->dwDefValue), 0));
+
+ break;
+ }
+ case CONTROL_COLOR:
+ {
+ SendDlgItemMessage(hwndDlg, ctrl->nID, CPM_SETCOLOUR, 0, (COLORREF) MNotifyGetDWord(hNotify, ctrl->setting, (DWORD)ctrl->dwDefValue));
+
+ break;
+ }
+ case CONTROL_RADIO:
+ {
+ CheckDlgButton(hwndDlg, ctrl->nID, MNotifyGetWord(hNotify, ctrl->setting, (WORD)ctrl->dwDefValue) == ctrl->value ? BST_CHECKED : BST_UNCHECKED);
+ break;
+ }
+ case CONTROL_TEXT:
+ {
+ SetDlgItemText(hwndDlg, ctrl->nID, MNotifyGetTString(hNotify, ctrl->setting, ctrl->szDefVale));
+
+ if (ctrl->max > 0)
+ SendDlgItemMessage(hwndDlg, ctrl->nID, EM_LIMITTEXT, min(ctrl->max, 1024), 0);
+ else
+ SendDlgItemMessage(hwndDlg, ctrl->nID, EM_LIMITTEXT, 1024, 0);
+
+ break;
+ }
+ case CONTROL_TEMPLATE:
+ {
+ SetDlgItemText(hwndDlg, ctrl->nID, MNotifyGetTTemplate(hNotify, ctrl->setting, ctrl->szDefVale));
+
+ if (ctrl->max > 0)
+ SendDlgItemMessage(hwndDlg, ctrl->nID, EM_LIMITTEXT, min(ctrl->max, 1024), 0);
+ else
+ SendDlgItemMessage(hwndDlg, ctrl->nID, EM_LIMITTEXT, 1024, 0);
+
+ break;
+ }
+ }
+ }
+
+ return TRUE;
+ break;
+ }
+ case WM_COMMAND:
+ {
+ // Don't make apply enabled during buddy set crap
+ if (HIWORD(wParam) != EN_CHANGE || (HWND)lParam != GetFocus())
+ {
+ for (int i = 0 ; i < controlsSize ; i++)
+ {
+ if (controls[i].type == CONTROL_SPIN && LOWORD(wParam) == controls[i].nID)
+ {
+ return 0;
+ }
+ }
+ }
+
+ SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0);
+ break;
+ }
+ case WM_NOTIFY:
+ {
+ switch (((LPNMHDR)lParam)->idFrom)
+ {
+ case 0:
+ {
+ switch (((LPNMHDR)lParam)->code)
+ {
+ case PSN_APPLY:
+ {
+ HANDLE hNotify = (HANDLE)GetWindowLong(hwndDlg, GWL_USERDATA);
+ TCHAR tmp[1024];
+
+ for (int i = 0 ; i < controlsSize ; i++)
+ {
+ OptPageControl *ctrl = &controls[i];
+
+ switch(ctrl->type)
+ {
+ case CONTROL_CHECKBOX:
+ {
+ MNotifySetByte(hNotify, ctrl->setting, (BYTE)IsDlgButtonChecked(hwndDlg, ctrl->nID));
+ break;
+ }
+ case CONTROL_SPIN:
+ {
+ MNotifySetWord(hNotify, ctrl->setting, (WORD)SendDlgItemMessage(hwndDlg, ctrl->nIDSpin, UDM_GETPOS, 0, 0));
+ break;
+ }
+ case CONTROL_COLOR:
+ {
+ MNotifySetDWord(hNotify, ctrl->setting, (DWORD)SendDlgItemMessage(hwndDlg, ctrl->nID, CPM_GETCOLOUR, 0, 0));
+ break;
+ }
+ case CONTROL_RADIO:
+ {
+ if (IsDlgButtonChecked(hwndDlg, ctrl->nID))
+ MNotifySetWord(hNotify, ctrl->setting, (BYTE)ctrl->value);
+ break;
+ }
+ case CONTROL_TEXT:
+ {
+ GetDlgItemText(hwndDlg, ctrl->nID, tmp, MAX_REGS(tmp));
+ MNotifySetTString(hNotify, ctrl->setting, tmp);
+ break;
+ }
+ case CONTROL_TEMPLATE:
+ {
+ GetDlgItemText(hwndDlg, ctrl->nID, tmp, MAX_REGS(tmp));
+ MNotifySetTTemplate(hNotify, ctrl->setting, tmp);
+ break;
+ }
+ }
+ }
+
+ return TRUE;
+ }
+ }
+ break;
+ }
+ }
+ break;
+ }
+ }
+
+ return 0;
+}
diff --git a/plugins/utils/mir_options_notify.h b/plugins/utils/mir_options_notify.h
new file mode 100644
index 0000000000..1f5494863a
--- /dev/null
+++ b/plugins/utils/mir_options_notify.h
@@ -0,0 +1,69 @@
+/*
+Copyright (C) 2005 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef __MIR_OPTIONS_NOTIFY_H__
+# define __MIR_OPTIONS_NOTIFY_H__
+
+#include <windows.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Dialog to save options
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#define CONTROL_CHECKBOX 0 // Stored as BYTE
+#define CONTROL_SPIN 1 // Stored as WORD
+#define CONTROL_COLOR 2 // Stored as DWORD
+#define CONTROL_RADIO 3 // Stored as WORD
+#define CONTROL_TEXT 4 // Stored as char *
+#define CONTROL_TEMPLATE 5 // Stored as Template
+
+struct OptPageControl {
+ int type;
+ int nID;
+ char *setting;
+ union {
+ DWORD dwDefValue;
+ const TCHAR *szDefVale;
+ };
+ union {
+ int nIDSpin;
+ int value;
+ };
+ WORD min;
+ WORD max;
+};
+
+BOOL CALLBACK SaveOptsDlgProc(OptPageControl *controls, int controlsSize, HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __MIR_OPTIONS_NOTIFY_H__
diff --git a/plugins/utils/mir_profiler.cpp b/plugins/utils/mir_profiler.cpp
new file mode 100644
index 0000000000..b788fd2dd2
--- /dev/null
+++ b/plugins/utils/mir_profiler.cpp
@@ -0,0 +1,178 @@
+/*
+Copyright (C) 2005 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+// Disable "...truncated to '255' characters in the debug information" warnings
+#pragma warning(disable: 4786)
+
+
+#include "mir_profiler.h"
+#include "mir_log.h"
+
+#include <stdio.h>
+
+
+MProfiler::Block MProfiler::root;
+MProfiler::Block * MProfiler::current = &MProfiler::root;
+
+
+MProfiler::Block::Block()
+{
+ parent = NULL;
+ memset(&total, 0, sizeof(total));
+ started = false;
+}
+
+
+MProfiler::Block::~Block()
+{
+ Reset();
+}
+
+
+void MProfiler::Block::Reset()
+{
+ for(std::map<std::string, MProfiler::Block *>::iterator it = children.begin();
+ it != children.end(); ++it)
+ delete it->second;
+ children.clear();
+
+ memset(&total, 0, sizeof(total));
+ started = false;
+}
+
+
+void MProfiler::Block::Start()
+{
+ if (started)
+ return;
+
+ QueryPerformanceCounter(&start);
+ last_step = start;
+ started = true;
+}
+
+
+void MProfiler::Block::Step(const char *name)
+{
+ if (!started)
+ return;
+
+ LARGE_INTEGER end;
+ QueryPerformanceCounter(&end);
+
+ GetChild(name)->total.QuadPart += end.QuadPart - last_step.QuadPart;
+
+ last_step = end;
+}
+
+
+void MProfiler::Block::Stop()
+{
+ if (!started)
+ return;
+
+ LARGE_INTEGER end;
+ QueryPerformanceCounter(&end);
+
+ total.QuadPart += end.QuadPart - start.QuadPart;
+
+ started = false;
+}
+
+
+double MProfiler::Block::GetTimeMS() const
+{
+ LARGE_INTEGER frequency;
+ QueryPerformanceFrequency(&frequency);
+
+ return total.QuadPart * 1000. / frequency.QuadPart;
+}
+
+
+MProfiler::Block * MProfiler::Block::GetChild(const char *name)
+{
+ MProfiler::Block *ret = children[name];
+ if (ret == NULL)
+ {
+ ret = new MProfiler::Block();
+ ret->name = name;
+ ret->parent = this;
+ children[name] = ret;
+ }
+ return ret;
+}
+
+
+void MProfiler::Reset()
+{
+ root.Reset();
+}
+
+void MProfiler::Start(const char *name)
+{
+ current = current->GetChild(name);
+ current->Start();
+}
+
+void MProfiler::Step(const char *name)
+{
+ current->Step(name);
+}
+
+void MProfiler::End()
+{
+ current->Stop();
+
+ if (current->parent != NULL)
+ {
+ current = current->parent;
+ QueryPerformanceCounter(&current->last_step);
+ }
+}
+
+void MProfiler::Dump(const char *module)
+{
+ Dump(module, "", &root, -1, -1);
+}
+
+
+void MProfiler::Dump(const char *module, std::string prefix, Block *block, double parent, double total)
+{
+ for(std::map<std::string, MProfiler::Block *>::iterator it = block->children.begin();
+ it != block->children.end(); ++it)
+ {
+ Block *child = it->second;
+ double elapsed = child->GetTimeMS();
+
+ if (total > 0)
+ {
+ mlog(module, "Profiler", "%s%-20s\t%5.1lf\t[%3.0lf%%]\t[%3.0lf%%]", prefix.c_str(), it->first.c_str(),
+ elapsed, elapsed / parent * 100, elapsed / total * 100);
+ }
+ else
+ {
+ mlog(module, "Profiler", "%s%-20s\t%5.1lf", prefix.c_str(), it->first.c_str(),
+ elapsed);
+ }
+
+ Dump(module, prefix + " ", child, elapsed, total > 0 ? total : elapsed);
+ }
+}
+
diff --git a/plugins/utils/mir_profiler.h b/plugins/utils/mir_profiler.h
new file mode 100644
index 0000000000..92d776f2ee
--- /dev/null
+++ b/plugins/utils/mir_profiler.h
@@ -0,0 +1,77 @@
+/*
+Copyright (C) 2005 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef __PROFILER_H__
+# define __PROFILER_H__
+
+#include <windows.h>
+#include <string>
+#include <map>
+
+
+
+class MProfiler
+{
+public:
+
+ static void Reset();
+ static void Start(const char *name);
+ static void Step(const char *name);
+ static void End();
+ static void Dump(const char *module);
+
+
+
+ static struct Block
+ {
+ std::string name;
+ Block *parent;
+ std::map<std::string, Block *> children;
+ bool started;
+ LARGE_INTEGER start;
+ LARGE_INTEGER last_step;
+ LARGE_INTEGER total;
+
+ Block();
+ ~Block();
+
+ void Reset();
+ void Start();
+ void Step(const char *name);
+ void Stop();
+ double GetTimeMS() const;
+
+ Block * GetChild(const char *name);
+ };
+
+
+private:
+
+ static Block root;
+ static Block *current;
+
+ static void Dump(const char *module, std::string prefix, Block *block, double parent, double total);
+
+};
+
+
+
+
+#endif // __PROFILER_H__
diff --git a/plugins/utils/mir_scope.h b/plugins/utils/mir_scope.h
new file mode 100644
index 0000000000..2f54044d83
--- /dev/null
+++ b/plugins/utils/mir_scope.h
@@ -0,0 +1,35 @@
+#ifndef __PTR_H__
+# define __PTR_H__
+
+
+template<class T>
+class scope
+{
+public:
+ scope(T t) : p(t) {}
+ ~scope() { mir_free(); }
+
+ void free()
+ {
+ if (p != NULL)
+ mir_free(p);
+ p = NULL;
+ }
+
+// T operator->() const { return p; }
+ operator T() const { return p; }
+
+ T detach()
+ {
+ T ret = p;
+ p = NULL;
+ return ret;
+ }
+
+private:
+ T p;
+};
+
+
+
+#endif // __PTR_H__
diff --git a/plugins/utils/mir_smileys.cpp b/plugins/utils/mir_smileys.cpp
new file mode 100644
index 0000000000..241b315ff3
--- /dev/null
+++ b/plugins/utils/mir_smileys.cpp
@@ -0,0 +1,521 @@
+/*
+Copyright (C) 2005 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+#define MIRANDA_VER 0x0700
+#include "mir_smileys.h"
+#include "mir_memory.h"
+#include "utf8_helpers.h"
+
+#include <richedit.h>
+#include <m_smileyadd.h>
+#include <newpluginapi.h>
+#include <m_langpack.h>
+#include <m_clui.h>
+#include <m_database.h>
+#include <commctrl.h>
+#include <m_skin_eng.h>
+#include <tchar.h>
+
+
+
+// Prototypes
+
+#define TEXT_PIECE_TYPE_TEXT 0
+#define TEXT_PIECE_TYPE_SMILEY 1
+typedef struct
+{
+ int type;
+ int len;
+ union
+ {
+ struct
+ {
+ int start_pos;
+ };
+ struct
+ {
+ HICON smiley;
+ int smiley_width;
+ int smiley_height;
+ };
+ };
+} TextPiece;
+
+
+
+SortedList * ReplaceSmileys(const char *text, int text_size, const char *protocol, int *max_smiley_height);
+void DrawTextSmiley(HDC hdcMem, RECT free_rc, const char *szText, int len, SortedList *plText, UINT uTextFormat, int max_smiley_height);
+void DestroySmileyList( SortedList* p_list );
+SIZE GetTextSize(HDC hdcMem, const char *szText, SortedList *plText, UINT uTextFormat, int max_smiley_height);
+
+
+
+// Functions
+
+int InitContactListSmileys()
+{
+ // Register smiley category
+ if (ServiceExists(MS_SMILEYADD_REGISTERCATEGORY))
+ {
+ SMADD_REGCAT rc;
+
+ rc.cbSize = sizeof(rc);
+ rc.name = "clist";
+ rc.dispname = Translate("Contact List smileys");
+
+ CallService(MS_SMILEYADD_REGISTERCATEGORY, 0, (LPARAM)&rc);
+ }
+
+ return 0;
+}
+
+SmileysParseInfo Smileys_PreParse(LPCSTR lpString, int nCount, const char *protocol)
+{
+ SmileysParseInfo info = (SmileysParseInfo) mir_alloc0(sizeof(_SmileysParseInfo));
+
+ info->pieces = ReplaceSmileys(lpString, nCount, protocol, &info->max_height);
+
+ return info;
+}
+
+void Smileys_FreeParse(SmileysParseInfo parseInfo)
+{
+ if (parseInfo != NULL)
+ {
+ if (parseInfo->pieces != NULL)
+ DestroySmileyList(parseInfo->pieces);
+
+ mir_free(parseInfo);
+ }
+}
+
+int skin_DrawText(HDC hDC, LPCSTR lpString, int nCount, LPRECT lpRect, UINT uFormat)
+{
+ if ((uFormat & DT_CALCRECT) == 0 && ServiceExists(MS_SKINENG_ALPHATEXTOUT))
+ {
+ COLORREF color = SetTextColor(hDC, 0);
+ SetTextColor(hDC, color);
+
+ if (mir_is_unicode())
+ {
+ return AlphaText(hDC, (char *) (const WCHAR *) CharToWchar(lpString), nCount, lpRect, uFormat, color);
+ }
+ else
+ {
+ return AlphaText(hDC, lpString, nCount, lpRect, uFormat, color);
+ }
+ }
+ else
+ {
+ return DrawText(hDC, lpString, nCount, lpRect, uFormat);
+ }
+}
+
+int skin_DrawIconEx(HDC hdc, int xLeft, int yTop, HICON hIcon, int cxWidth, int cyWidth,
+ UINT istepIfAniCur, HBRUSH hbrFlickerFreeDraw, UINT diFlags)
+{
+ if (ServiceExists(MS_SKINENG_DRAWICONEXFIX))
+ return mod_DrawIconEx_helper(hdc, xLeft, yTop, hIcon, cxWidth, cyWidth, istepIfAniCur, hbrFlickerFreeDraw, diFlags);
+ else
+ return DrawIconEx(hdc, xLeft, yTop, hIcon, cxWidth, cyWidth, istepIfAniCur, hbrFlickerFreeDraw, diFlags);
+}
+
+
+
+// Similar to DrawText win32 api function
+// Pass uFormat | DT_CALCRECT to calc rectangle to be returned by lpRect
+// parseInfo is optional (pass NULL and it will be calculated and deleted inside function
+int Smileys_DrawText(HDC hDC, LPCSTR lpString, int nCount, LPRECT lpRect, UINT uFormat, const char *protocol, SmileysParseInfo parseInfo)
+{
+ SmileysParseInfo info;
+ int ret;
+
+ if (nCount < 0)
+ nCount = strlen(lpString);
+
+ // Get parse info
+ if (parseInfo == NULL)
+ info = Smileys_PreParse(lpString, nCount, protocol);
+ else
+ info = parseInfo;
+
+ if (uFormat & DT_CALCRECT)
+ {
+ SIZE text_size = GetTextSize(hDC, lpString, info->pieces, uFormat, info->max_height);
+
+ lpRect->bottom = min(lpRect->bottom, lpRect->top + text_size.cy);
+
+ if (text_size.cx < lpRect->right - lpRect->left)
+ {
+ if (uFormat & DT_RIGHT)
+ lpRect->left = lpRect->right - text_size.cx;
+ else
+ lpRect->right = lpRect->left + text_size.cx;
+ }
+
+ ret = text_size.cy;
+ }
+ else
+ {
+ // Clipping rgn
+ HRGN oldRgn = CreateRectRgn(0,0,1,1);
+ if (GetClipRgn(hDC, oldRgn) != 1)
+ {
+ DeleteObject(oldRgn);
+ oldRgn = NULL;
+ }
+
+ HRGN rgn = CreateRectRgnIndirect(lpRect);
+ ExtSelectClipRgn(hDC, rgn, RGN_AND);
+
+ // Draw
+ if (info->pieces == NULL)
+ {
+ ret = skin_DrawText(hDC, lpString, nCount, lpRect, uFormat);
+ }
+ else
+ {
+ RECT rc = *lpRect;
+
+ SIZE text_size = GetTextSize(hDC, lpString, info->pieces, uFormat, info->max_height);
+
+ if (text_size.cx < rc.right - rc.left)
+ {
+ if (uFormat & DT_RIGHT)
+ rc.left = rc.right - text_size.cx;
+ else
+ rc.right = rc.left + text_size.cx;
+ }
+
+ ret = text_size.cy;
+
+ DrawTextSmiley(hDC, rc, lpString, nCount, info->pieces, uFormat, info->max_height);
+ }
+
+ // Clipping rgn
+ SelectClipRgn(hDC, oldRgn);
+ DeleteObject(rgn);
+ if (oldRgn) DeleteObject(oldRgn);
+ }
+
+
+ // Free parse info
+ if (parseInfo == NULL)
+ Smileys_FreeParse(info);
+
+ return ret;
+}
+
+
+
+SIZE GetTextSize(HDC hdcMem, const char *szText, SortedList *plText, UINT uTextFormat, int max_smiley_height)
+{
+ SIZE text_size;
+
+ if (szText == NULL)
+ {
+ text_size.cy = 0;
+ text_size.cx = 0;
+ }
+ else
+ {
+ RECT text_rc = {0, 0, 0x7FFFFFFF, 0x7FFFFFFF};
+
+ // Always need cy...
+ DrawText(hdcMem,szText,lstrlen(szText), &text_rc, DT_CALCRECT | uTextFormat);
+ text_size.cy = text_rc.bottom - text_rc.top;
+
+ if (plText == NULL)
+ {
+ text_size.cx = text_rc.right - text_rc.left;
+ }
+ else
+ {
+ if (!(uTextFormat & DT_RESIZE_SMILEYS))
+ text_size.cy = max(text_size.cy, max_smiley_height);
+
+ text_size.cx = 0;
+
+ // See each item of list
+ for (int i = 0; i < plText->realCount; i++)
+ {
+ TextPiece *piece = (TextPiece *) plText->items[i];
+
+ if (piece->type == TEXT_PIECE_TYPE_TEXT)
+ {
+ RECT text_rc = {0, 0, 0x7FFFFFFF, 0x7FFFFFFF};
+
+ DrawText(hdcMem, &szText[piece->start_pos], piece->len, &text_rc, DT_CALCRECT | uTextFormat);
+ text_size.cx = text_size.cx + text_rc.right - text_rc.left;
+ }
+ else
+ {
+ double factor;
+
+ if ((uTextFormat & DT_RESIZE_SMILEYS) && piece->smiley_height > text_size.cy)
+ {
+ factor = text_size.cy / (double) piece->smiley_height;
+ }
+ else
+ {
+ factor = 1;
+ }
+
+ text_size.cx = text_size.cx + (LONG)(factor * piece->smiley_width);
+ }
+ }
+ }
+ }
+
+ return text_size;
+}
+
+void DrawTextSmiley(HDC hdcMem, RECT free_rc, const char *szText, int len, SortedList *plText, UINT uTextFormat, int max_smiley_height)
+{
+ if (szText == NULL)
+ {
+ return;
+ }
+
+ uTextFormat &= ~DT_RIGHT;
+
+ // Draw list
+ int i;
+ int pos_x = 0;
+ int row_height, text_height;
+ RECT tmp_rc = free_rc;
+
+ if (uTextFormat & DT_RTLREADING)
+ i = plText->realCount - 1;
+ else
+ i = 0;
+
+ // Get real height of the line
+ text_height = skin_DrawText(hdcMem, "A", 1, &tmp_rc, DT_CALCRECT | uTextFormat);
+ if (uTextFormat & DT_RESIZE_SMILEYS)
+ row_height = text_height;
+ else
+ row_height = max(text_height, max_smiley_height);
+
+ // Just draw ellipsis
+ if (free_rc.right <= free_rc.left)
+ {
+ skin_DrawText(hdcMem, "...", 3, &free_rc, uTextFormat & ~DT_END_ELLIPSIS);
+ }
+ else
+ {
+ // Draw text and smileys
+ for (; i < plText->realCount && i >= 0 && pos_x < free_rc.right - free_rc.left && len > 0; i += (uTextFormat & DT_RTLREADING ? -1 : 1))
+ {
+ TextPiece *piece = (TextPiece *) plText->items[i];
+ RECT text_rc = free_rc;
+
+ if (uTextFormat & DT_RTLREADING)
+ text_rc.right -= pos_x;
+ else
+ text_rc.left += pos_x;
+
+ if (piece->type == TEXT_PIECE_TYPE_TEXT)
+ {
+ text_rc.top += (row_height - text_height) >> 1;
+
+ tmp_rc = text_rc;
+ tmp_rc.right += 50;
+ skin_DrawText(hdcMem, &szText[piece->start_pos], min(len, piece->len), &tmp_rc, DT_CALCRECT | (uTextFormat & ~DT_END_ELLIPSIS));
+ pos_x += tmp_rc.right - tmp_rc.left;
+
+ if (uTextFormat & DT_RTLREADING)
+ text_rc.left = max(text_rc.left, text_rc.right - (tmp_rc.right - tmp_rc.left));
+
+ skin_DrawText(hdcMem, &szText[piece->start_pos], min(len, piece->len), &text_rc, uTextFormat);
+ len -= piece->len;
+ }
+ else
+ {
+ double factor;
+
+ if (len < piece->len)
+ {
+ len = 0;
+ }
+ else
+ {
+ len -= piece->len;
+
+ if ((uTextFormat & DT_RESIZE_SMILEYS) && piece->smiley_height > row_height)
+ {
+ factor = row_height / (double) piece->smiley_height;
+ }
+ else
+ {
+ factor = 1;
+ }
+
+ if (uTextFormat & DT_RTLREADING)
+ text_rc.left = max(text_rc.right - (LONG) (piece->smiley_width * factor), text_rc.left);
+
+ if ((LONG)(piece->smiley_width * factor) <= text_rc.right - text_rc.left)
+ {
+ text_rc.top += (row_height - (LONG)(piece->smiley_height * factor)) >> 1;
+
+ skin_DrawIconEx(hdcMem, text_rc.left, text_rc.top, piece->smiley,
+ (LONG)(piece->smiley_width * factor), (LONG)(piece->smiley_height * factor), 0, NULL, DI_NORMAL);
+ }
+ else
+ {
+ text_rc.top += (row_height - text_height) >> 1;
+ skin_DrawText(hdcMem, "...", 3, &text_rc, uTextFormat);
+ }
+
+ pos_x += (LONG)(piece->smiley_width * factor);
+ }
+ }
+ }
+ }
+}
+
+
+void DestroySmileyList( SortedList* p_list )
+{
+ if ( p_list == NULL )
+ return;
+
+ if ( p_list->items != NULL )
+ {
+ int i;
+ for ( i = 0 ; i < p_list->realCount ; i++ )
+ {
+ TextPiece *piece = (TextPiece *) p_list->items[i];
+
+ if ( piece != NULL )
+ {
+ if (piece->type == TEXT_PIECE_TYPE_SMILEY)
+ DestroyIcon(piece->smiley);
+
+ mir_free(piece);
+ }
+ }
+ }
+
+ List_Destroy( p_list );
+}
+
+
+
+// Generete the list of smileys / text to be drawn
+SortedList * ReplaceSmileys(const char *text, int text_size, const char *protocol, int *max_smiley_height)
+{
+ SMADD_BATCHPARSE2 sp = {0};
+ SMADD_BATCHPARSERES *spres;
+
+ *max_smiley_height = 0;
+
+ if (text[0] == '\0' || !ServiceExists(MS_SMILEYADD_BATCHPARSE))
+ {
+ return NULL;
+ }
+
+ // Parse it!
+ sp.cbSize = sizeof(sp);
+ sp.Protocolname = protocol;
+ sp.str = (char *)text;
+ sp.oflag = SAFL_TCHAR;
+ spres = (SMADD_BATCHPARSERES *) CallService(MS_SMILEYADD_BATCHPARSE, 0, (LPARAM)&sp);
+
+ if (spres == NULL)
+ {
+ // Did not find a simley
+ return NULL;
+ }
+
+ // Lets add smileys
+ SortedList *plText = List_Create(0, 10);
+
+ const char *next_text_pos = text;
+ const char *last_text_pos = _tcsninc(text, text_size);
+
+ for (unsigned int i = 0; i < sp.numSmileys; i++)
+ {
+ char * start = _tcsninc(text, spres[i].startChar);
+ char * end = _tcsninc(start, spres[i].size);
+
+ if (spres[i].hIcon != NULL) // For deffective smileypacks
+ {
+ // Add text
+ if (start > next_text_pos)
+ {
+ TextPiece *piece = (TextPiece *) mir_alloc0(sizeof(TextPiece));
+
+ piece->type = TEXT_PIECE_TYPE_TEXT;
+ piece->start_pos = next_text_pos - text;
+ piece->len = start - next_text_pos;
+
+ List_Append(plText, piece);
+ }
+
+ // Add smiley
+ {
+ BITMAP bm;
+ ICONINFO icon;
+ TextPiece *piece = (TextPiece *) mir_alloc0(sizeof(TextPiece));
+
+ piece->type = TEXT_PIECE_TYPE_SMILEY;
+ piece->len = end - start;
+ piece->smiley = spres[i].hIcon;
+
+ piece->smiley_width = 16;
+ piece->smiley_height = 16;
+ if (GetIconInfo(piece->smiley, &icon))
+ {
+ if (GetObject(icon.hbmColor,sizeof(BITMAP),&bm))
+ {
+ piece->smiley_width = bm.bmWidth;
+ piece->smiley_height = bm.bmHeight;
+ }
+
+ DeleteObject(icon.hbmMask);
+ DeleteObject(icon.hbmColor);
+ }
+
+ *max_smiley_height = max(piece->smiley_height, *max_smiley_height);
+
+ List_Append(plText, piece);
+ }
+
+ next_text_pos = end;
+ }
+ }
+
+ // Add rest of text
+ if (last_text_pos > next_text_pos)
+ {
+ TextPiece *piece = (TextPiece *) mir_alloc0(sizeof(TextPiece));
+
+ piece->type = TEXT_PIECE_TYPE_TEXT;
+ piece->start_pos = next_text_pos - text;
+ piece->len = last_text_pos - next_text_pos;
+
+ List_Append(plText, piece);
+ }
+
+ CallService(MS_SMILEYADD_BATCHFREE, 0, (LPARAM)spres);
+
+ return plText;
+}
diff --git a/plugins/utils/mir_smileys.h b/plugins/utils/mir_smileys.h
new file mode 100644
index 0000000000..cfbebb853a
--- /dev/null
+++ b/plugins/utils/mir_smileys.h
@@ -0,0 +1,69 @@
+/*
+Copyright (C) 2005 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef __MIR_SMILEYS_H__
+# define __MIR_SMILEYS_H__
+
+#include <windows.h>
+
+
+/*
+To use this files mir_dblists.h/.c are needed
+*/
+#include "mir_dblists.h"
+
+
+// Init settings needed to draw smileys using the contact list itens
+// To use then, pass "clist" as the protocol name
+// Need to be called on ME_SYSTEM_MODULESLOADED
+int InitContactListSmileys();
+
+
+// Pre-parse smileys
+typedef struct _SmileysParseInfo
+{
+ SortedList *pieces;
+ int max_height;
+} * SmileysParseInfo;
+
+SmileysParseInfo Smileys_PreParse(LPCSTR lpString, int nCount, const char *protocol);
+void Smileys_FreeParse(SmileysParseInfo parseInfo);
+
+// TODO:
+// SmileysParseInfo Smileys_PreParseW(HDC hDC, LPCWSTR lpString, int nCount, const char *protocol);
+
+
+#define DT_RESIZE_SMILEYS 0x10000000
+
+// Similar to DrawText win32 api function
+// Pass uFormat | DT_CALCRECT to calc rectangle to be returned by lpRect
+// parseInfo is optional (pass NULL and it will be calculated and deleted inside function)
+int Smileys_DrawText(HDC hDC, LPCSTR lpString, int nCount, LPRECT lpRect, UINT uFormat, const char *protocol, SmileysParseInfo parseInfo);
+
+// TODO:
+// int Smileys_DrawTextW(HDC hDC, LPCWSTR lpString, int nCount, LPRECT lpRect, UINT uFormat, const char *protocol, SmileysParseInfo parseInfo);
+
+
+int skin_DrawText(HDC hDC, LPCSTR lpString, int nCount, LPRECT lpRect, UINT uFormat);
+int skin_DrawIconEx(HDC hdc, int xLeft, int yTop, HICON hIcon, int cxWidth, int cyWidth, UINT istepIfAniCur, HBRUSH hbrFlickerFreeDraw, UINT diFlags);
+
+
+
+#endif // __MIR_SMILEYS_H__
diff --git a/plugins/utils/scope.h b/plugins/utils/scope.h
new file mode 100644
index 0000000000..5556e5f97f
--- /dev/null
+++ b/plugins/utils/scope.h
@@ -0,0 +1,106 @@
+/*
+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 __SCOPE_H__
+# define __SCOPE_H__
+
+
+#define DEFINE_SCOPED_TYPE(_NAME_, _DELETE_) \
+ template<class T> \
+ class _NAME_ \
+ { \
+ _NAME_(_NAME_ &); \
+ _NAME_ & operator=(_NAME_ &); \
+ \
+ public: \
+ _NAME_(T *t = NULL) : p(t) {} \
+ \
+ ~_NAME_() \
+ { \
+ release(); \
+ } \
+ \
+ T * operator=(T *t) \
+ { \
+ release(); \
+ p = t; \
+ return t; \
+ } \
+ \
+ operator T*() const \
+ { \
+ return p; \
+ } \
+ \
+ bool operator==(T *t) const \
+ { \
+ return p == t; \
+ } \
+ \
+ bool operator!=(T *t) const \
+ { \
+ return p != t; \
+ } \
+ \
+ T *get() const \
+ { \
+ return p; \
+ } \
+ \
+ void release() \
+ { \
+ if (p != NULL) \
+ dealoc(p); \
+ p = NULL; \
+ } \
+ \
+ T* detach() \
+ { \
+ T *ret = p; \
+ p = NULL; \
+ return ret; \
+ } \
+ \
+ protected: \
+ T *p; \
+ \
+ void dealoc(T *ptr) \
+ { \
+ _DELETE_; \
+ } \
+ }; \
+ \
+ template<typename T> \
+ inline bool operator==(T* p, const _NAME_<T> &b) { \
+ return p == b.get(); \
+ } \
+ \
+ template<typename T> \
+ inline bool operator!=(T* p, const _NAME_<T> &b) { \
+ return p != b.get(); \
+ }
+
+DEFINE_SCOPED_TYPE(scoped_ptr, delete ptr)
+DEFINE_SCOPED_TYPE(scoped_array, delete[] ptr)
+DEFINE_SCOPED_TYPE(scoped_free, free(ptr))
+DEFINE_SCOPED_TYPE(scoped_mir_free, mir_free(ptr))
+
+
+#endif // __SCOPE_H__
diff --git a/plugins/utils/templates.cpp b/plugins/utils/templates.cpp
new file mode 100644
index 0000000000..11a81d856e
--- /dev/null
+++ b/plugins/utils/templates.cpp
@@ -0,0 +1,476 @@
+#include "templates.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <tchar.h>
+
+extern "C"
+{
+#include <newpluginapi.h>
+#include <time.h>
+#include <win2k.h>
+#include <m_system.h>
+#include <m_plugins.h>
+#include <m_options.h>
+#include <m_langpack.h>
+#include <m_database.h>
+#include <m_utils.h>
+#include <m_protocols.h>
+
+#include <m_notify.h>
+
+#include "../utils/mir_memory.h"
+}
+
+
+const char *defaultVariables[] = { "%title%", "%text%" };
+const WCHAR *defaultVariablesW[] = { L"%title%", L"%text%" };
+
+const char *defaultVariableDescriptions[] = { "Notification Title", "Notification Text" };
+const WCHAR *defaultVariableDescriptionsW[] = { L"Notification Title", L"Notification Text" };
+
+
+#define MAX_REGS(_A_) ( sizeof(_A_) / sizeof(_A_[0]) )
+
+
+#define DATA_BLOCK 128
+
+
+// ASCII VERSIONS ///////////////////////////////////////////////////////////////////////
+
+struct StringHelper
+{
+ char *text;
+ size_t allocated;
+ size_t used;
+};
+
+
+int CopyData(StringHelper *str, const char *text, size_t len)
+{
+ if (len == 0)
+ return 0;
+
+ if (text == NULL)
+ return 0;
+
+ size_t totalSize = str->used + len + 1;
+
+ if (totalSize > str->allocated)
+ {
+ totalSize += DATA_BLOCK - (totalSize % DATA_BLOCK);
+
+ if (str->text != NULL)
+ {
+ char *tmp = (char *) mir_realloc(str->text, sizeof(char) * totalSize);
+
+ if (tmp == NULL)
+ {
+ mir_free(str->text);
+ return -1;
+ }
+
+ str->text = tmp;
+ }
+ else
+ {
+ str->text = (char *) mir_alloc(sizeof(char) * totalSize);
+
+ if (str->text == NULL)
+ {
+ return -2;
+ }
+ }
+
+ str->allocated = totalSize;
+ }
+
+ memmove(&str->text[str->used], text, sizeof(char) * len);
+ str->used += len;
+ str->text[str->used] = '\0';
+
+ return 0;
+}
+
+
+char * ParseText(const char *text,
+ const char **variables, size_t variablesSize,
+ const char **data, size_t dataSize)
+{
+ size_t length = strlen(text);
+ size_t nextPos = 0;
+ StringHelper ret = {0};
+
+ // length - 1 because a % in last char will be a % and point
+ for (size_t i = 0 ; i < length - 1 ; i++)
+ {
+ if (text[i] == '%')
+ {
+ bool found = false;
+
+ if (CopyData(&ret, &text[nextPos], i - nextPos))
+ return NULL;
+
+ if (text[i + 1] == '%')
+ {
+ if (CopyData(&ret, "%", 1))
+ return NULL;
+
+ i++;
+
+ found = true;
+ }
+ else
+ {
+ size_t size = min(variablesSize, dataSize);
+
+ // See if can find it
+ for(size_t j = 0 ; j < size ; j++)
+ {
+ size_t vlen = strlen(variables[j]);
+
+ if (strnicmp(&text[i], variables[j], vlen) == 0)
+ {
+ if (CopyData(&ret, data[j], strlen(data[j])))
+ return NULL;
+
+ i += vlen - 1;
+
+ found = true;
+
+ break;
+ }
+ }
+ }
+
+
+ if (found)
+ nextPos = i + 1;
+ else
+ nextPos = i;
+ }
+ }
+
+ if (nextPos < length)
+ if (CopyData(&ret, &text[nextPos], length - nextPos))
+ return NULL;
+
+ return ret.text;
+}
+
+
+// UNICODE VERSIONS /////////////////////////////////////////////////////////////////////
+
+struct StringHelperW
+{
+ WCHAR *text;
+ size_t allocated;
+ size_t used;
+};
+
+
+int CopyDataW(StringHelperW *str, const WCHAR *text, size_t len)
+{
+ if (len == 0)
+ return 0;
+
+ if (text == NULL)
+ return 0;
+
+ size_t totalSize = str->used + len + 1;
+
+ if (totalSize > str->allocated)
+ {
+ totalSize += DATA_BLOCK - (totalSize % DATA_BLOCK);
+
+ if (str->text != NULL)
+ {
+ WCHAR *tmp = (WCHAR *) mir_realloc(str->text, sizeof(WCHAR) * totalSize);
+
+ if (tmp == NULL)
+ {
+ mir_free(str->text);
+ return -1;
+ }
+
+ str->text = tmp;
+ }
+ else
+ {
+ str->text = (WCHAR *) mir_alloc(sizeof(WCHAR) * totalSize);
+
+ if (str->text == NULL)
+ {
+ return -2;
+ }
+ }
+
+ str->allocated = totalSize;
+ }
+
+ memmove(&str->text[str->used], text, sizeof(WCHAR) * len);
+ str->used += len;
+ str->text[str->used] = '\0';
+
+ return 0;
+}
+
+
+WCHAR * ParseTextW(const WCHAR *text,
+ const WCHAR **variables, size_t variablesSize,
+ const WCHAR **data, size_t dataSize)
+{
+ size_t length = lstrlenW(text);
+ size_t nextPos = 0;
+ StringHelperW ret = {0};
+
+ // length - 1 because a % in last char will be a % and point
+ for (size_t i = 0 ; i < length - 1 ; i++)
+ {
+ if (text[i] == L'%')
+ {
+ bool found = false;
+
+ if (CopyDataW(&ret, &text[nextPos], i - nextPos))
+ return NULL;
+
+ if (text[i + 1] == L'%')
+ {
+ if (CopyDataW(&ret, L"%", 1))
+ return NULL;
+
+ i++;
+
+ found = true;
+ }
+ else
+ {
+ size_t size = min(variablesSize, dataSize);
+
+ // See if can find it
+ for(size_t j = 0 ; j < size ; j++)
+ {
+ size_t vlen = lstrlenW(variables[j]);
+
+ if (_wcsnicmp(&text[i], variables[j], vlen) == 0)
+ {
+ if (CopyDataW(&ret, data[j], lstrlenW(data[j])))
+ return NULL;
+
+ i += vlen - 1;
+
+ found = true;
+
+ break;
+ }
+ }
+ }
+
+ if (found)
+ nextPos = i + 1;
+ else
+ nextPos = i;
+ }
+ }
+
+ if (nextPos < length)
+ if (CopyDataW(&ret, &text[nextPos], length - nextPos))
+ return NULL;
+
+ return ret.text;
+}
+
+
+// INTERFACE ////////////////////////////////////////////////////////////////////////////
+
+// In future maybe pre-parse here
+void MNotifySetTemplate(HANDLE notifyORtype, const char *name, const char *value)
+{
+ MNotifySetString(notifyORtype, name, value);
+}
+void MNotifySetWTemplate(HANDLE notifyORtype, const char *name, const WCHAR *value)
+{
+ MNotifySetWString(notifyORtype, name, value);
+}
+
+// Well, why not?
+const char *MNotifyGetTemplate(HANDLE notifyORtype, const char *name, const char *defValue)
+{
+ return MNotifyGetString(notifyORtype, name, defValue);
+}
+const WCHAR *MNotifyGetWTemplate(HANDLE notifyORtype, const char *name, const WCHAR *defValue)
+{
+ return MNotifyGetWString(notifyORtype, name, defValue);
+}
+
+// You must free the return with mir_sys_free
+char *MNotifyGetParsedTemplate(HANDLE notifyORtype, const char *name, const char *defValue)
+{
+ const char *temp = MNotifyGetString(notifyORtype, name, defValue);
+
+ if (MNotifyHasVariables(notifyORtype))
+ {
+ const char ** vars = (const char **) MNotifyGetDWord(notifyORtype, NFOPT_VARIABLES_STRS, NULL);
+ size_t varsSize = (size_t) MNotifyGetDWord(notifyORtype, NFOPT_VARIABLES_SIZE, 0);
+
+ const char ** data = (const char **) MNotifyGetDWord(notifyORtype, NFOPT_DATA_STRS, NULL);
+ size_t dataSize = (size_t) MNotifyGetDWord(notifyORtype, NFOPT_DATA_SIZE, 0);
+
+ return ParseText(temp, vars, varsSize, data, dataSize);
+ }
+ else
+ {
+ // Default values
+ const char * data[MAX_REGS(defaultVariables)];
+ data[0] = MNotifyGetString(notifyORtype, NFOPT_TITLE, NULL);
+ data[1] = MNotifyGetString(notifyORtype, NFOPT_TEXT, NULL);
+
+ return ParseText(temp, defaultVariables, MAX_REGS(defaultVariables), data, MAX_REGS(defaultVariables));
+ }
+}
+WCHAR *MNotifyGetWParsedTemplate(HANDLE notifyORtype, const char *name, const WCHAR *defValue)
+{
+ const WCHAR *temp = MNotifyGetWString(notifyORtype, name, defValue);
+
+ if (MNotifyHasWVariables(notifyORtype))
+ {
+ const WCHAR ** vars = (const WCHAR **) MNotifyGetDWord(notifyORtype, NFOPT_VARIABLES_STRSW, NULL);
+ size_t varsSize = (size_t) MNotifyGetDWord(notifyORtype, NFOPT_VARIABLES_SIZE, 0);
+
+ const WCHAR ** data = (const WCHAR **) MNotifyGetDWord(notifyORtype, NFOPT_DATA_STRSW, NULL);
+ size_t dataSize = (size_t) MNotifyGetDWord(notifyORtype, NFOPT_DATA_SIZE, 0);
+
+ return ParseTextW(temp, vars, varsSize, data, dataSize);
+ }
+ else
+ {
+ // Default values
+ const WCHAR * data[MAX_REGS(defaultVariablesW)];
+ data[0] = MNotifyGetWString(notifyORtype, NFOPT_TITLEW, NULL);
+ data[1] = MNotifyGetWString(notifyORtype, NFOPT_TEXTW, NULL);
+
+ return ParseTextW(temp, defaultVariablesW, MAX_REGS(defaultVariablesW), data, MAX_REGS(defaultVariablesW));
+ }
+}
+
+
+BOOL MNotifyHasVariables(HANDLE notifyORtype)
+{
+ return MNotifyGetDWord(notifyORtype, NFOPT_VARIABLES_STRS, NULL) != NULL &&
+ MNotifyGetDWord(notifyORtype, NFOPT_VARIABLES_SIZE, 0) != 0;
+}
+
+BOOL MNotifyHasWVariables(HANDLE notifyORtype)
+{
+ return MNotifyGetDWord(notifyORtype, NFOPT_VARIABLES_STRSW, NULL) != NULL &&
+ MNotifyGetDWord(notifyORtype, NFOPT_VARIABLES_SIZE, 0) != 0;
+}
+
+
+
+
+void MNotifyShowVariables(HANDLE notifyORtype)
+{
+ StringHelper ret = {0};
+
+ const char ** vars;
+ size_t varsSize;
+ const char ** descs;
+ size_t descsSize;
+
+ if (MNotifyHasVariables(notifyORtype))
+ {
+ vars = (const char **) MNotifyGetDWord(notifyORtype, NFOPT_VARIABLES_STRS, NULL);
+ varsSize = (size_t) MNotifyGetDWord(notifyORtype, NFOPT_VARIABLES_SIZE, 0);
+
+ descs = (const char **) MNotifyGetDWord(notifyORtype, NFOPT_VARIABLES_DESCRIPTIONS_STRS, NULL);
+ descsSize = (size_t) MNotifyGetDWord(notifyORtype, NFOPT_VARIABLES_DESCRIPTIONS_SIZE, 0);
+ }
+ else
+ {
+ // Default values
+ vars = defaultVariables;
+ varsSize = MAX_REGS(defaultVariables);
+
+ descs = defaultVariableDescriptions;
+ descsSize = MAX_REGS(defaultVariableDescriptions);
+ }
+
+ for(size_t i = 0 ; i < varsSize ; i++)
+ {
+ if (vars[i] != NULL)
+ {
+ if (CopyData(&ret, vars[i], strlen(vars[i])))
+ return;
+
+ if (i < descsSize && descs[i] != NULL && descs[i] != L'\0')
+ {
+ if (CopyData(&ret, " -> ", 4))
+ return;
+ if (CopyData(&ret, descs[i], strlen(descs[i])))
+ return;
+ }
+
+ if (CopyData(&ret, "\r\n", 2))
+ return;
+ }
+ }
+
+ MessageBoxA(NULL, ret.text, "Variables", MB_OK);
+
+ mir_free(ret.text);
+}
+
+void MNotifyShowWVariables(HANDLE notifyORtype)
+{
+ StringHelperW ret = {0};
+
+ const WCHAR ** vars;
+ size_t varsSize;
+ const WCHAR ** descs;
+ size_t descsSize;
+
+ if (MNotifyHasWVariables(notifyORtype))
+ {
+ vars = (const WCHAR **) MNotifyGetDWord(notifyORtype, NFOPT_VARIABLES_STRSW, NULL);
+ varsSize = (size_t) MNotifyGetDWord(notifyORtype, NFOPT_VARIABLES_SIZE, 0);
+
+ descs = (const WCHAR **) MNotifyGetDWord(notifyORtype, NFOPT_VARIABLES_DESCRIPTIONS_STRSW, NULL);
+ descsSize = (size_t) MNotifyGetDWord(notifyORtype, NFOPT_VARIABLES_DESCRIPTIONS_SIZE, 0);
+ }
+ else
+ {
+ // Default values
+ vars = defaultVariablesW;
+ varsSize = MAX_REGS(defaultVariablesW);
+
+ descs = defaultVariableDescriptionsW;
+ descsSize = MAX_REGS(defaultVariableDescriptionsW);
+ }
+
+ for(size_t i = 0 ; i < varsSize ; i++)
+ {
+ if (vars[i] != NULL)
+ {
+ if (CopyDataW(&ret, vars[i], lstrlenW(vars[i])))
+ return;
+
+ if (i < descsSize && descs[i] != NULL && descs[i] != L'\0')
+ {
+ if (CopyDataW(&ret, L" -> ", 3))
+ return;
+ if (CopyDataW(&ret, descs[i], lstrlenW(descs[i])))
+ return;
+ }
+
+ if (CopyDataW(&ret, L"\r\n", 2))
+ return;
+ }
+ }
+
+ MessageBoxW(NULL, ret.text, L"Variables", MB_OK);
+
+ mir_free(ret.text);
+}
+
+
diff --git a/plugins/utils/templates.h b/plugins/utils/templates.h
new file mode 100644
index 0000000000..e55fb7a50e
--- /dev/null
+++ b/plugins/utils/templates.h
@@ -0,0 +1,102 @@
+#ifndef __TEMPLATES_H__
+# define __TEMPLATES_H__
+
+
+#include <windows.h>
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+// Default templates to be set by using notifiers
+
+#define NFOPT_DEFTEMPL_TEXT "General/DefaultTemplate/Text"
+#define NFOPT_DEFTEMPL_TEXTW "General/DefaultTemplate/TextW"
+#define NFOPT_DEFTEMPL_TITLE "General/DefaultTemplate/Title"
+#define NFOPT_DEFTEMPL_TITLEW "General/DefaultTemplate/TitleW"
+
+
+
+
+// All of theese have to be stored as DWORDs
+
+#define NFOPT_VARIABLES_STRS "Variables/Strings" // char ** (each has to start and end with %)
+#define NFOPT_VARIABLES_DESCRIPTIONS_STRS "VariablesDescriptions/Strings" // char **
+#define NFOPT_DATA_STRS "Data/Strings" // char **
+
+#define NFOPT_VARIABLES_STRSW "Variables/StringsW" // WCHAR ** (each has to start and end with %)
+#define NFOPT_VARIABLES_DESCRIPTIONS_STRSW "VariablesDescriptions/StringsW"// WCHAR **
+#define NFOPT_DATA_STRSW "Data/StringsW" // WCHAR **
+
+#define NFOPT_VARIABLES_SIZE "Variables/Size" // size_t
+#define NFOPT_VARIABLES_DESCRIPTIONS_SIZE "VariablesDescriptions/Size" // size_t
+#define NFOPT_DATA_SIZE "Data/Size" // size_t
+
+
+// Default variables if none is provided by the plugin calling the notification
+// char *defaultVariables[] = { "%title%", "%text%" };
+
+
+void MNotifySetTemplate(HANDLE notifyORtype, const char *name, const char *value);
+void MNotifySetWTemplate(HANDLE notifyORtype, const char *name, const WCHAR *value);
+
+const char *MNotifyGetTemplate(HANDLE notifyORtype, const char *name, const char *defValue);
+const WCHAR *MNotifyGetWTemplate(HANDLE notifyORtype, const char *name, const WCHAR *defValue);
+
+// You must free the return with mir_sys_free
+char *MNotifyGetParsedTemplate(HANDLE notifyORtype, const char *name, const char *defValue);
+WCHAR *MNotifyGetWParsedTemplate(HANDLE notifyORtype, const char *name, const WCHAR *defValue);
+
+
+BOOL MNotifyHasVariables(HANDLE notifyORtype);
+BOOL MNotifyHasWVariables(HANDLE notifyORtype);
+
+void MNotifyShowVariables(HANDLE notifyORtype);
+void MNotifyShowWVariables(HANDLE notifyORtype);
+
+
+#ifdef _UNICODE
+
+# define MNotifyGetTString MNotifyGetWString
+# define MNotifyGetTTemplate MNotifyGetWTemplate
+# define MNotifySetTString MNotifySetWString
+# define MNotifySetTTemplate MNotifyGetWTemplate
+# define MNotifyGetTParsedTemplate MNotifyGetWParsedTemplate
+# define MNotifyHasTVariables MNotifyHasWVariables
+# define MNotifyShowTVariables MNotifyShowWVariables
+
+# define NFOPT_DEFTEMPL_TEXTT NFOPT_DEFTEMPL_TEXTW
+# define NFOPT_DEFTEMPL_TITLET NFOPT_DEFTEMPL_TITLEW
+
+# define NFOPT_VARIABLES_STRST NFOPT_VARIABLES_STRSW
+# define NFOPT_VARIABLES_DESCRIPTIONS_STRST NFOPT_VARIABLES_DESCRIPTIONS_STRSW
+# define NFOPT_DATA_STRST NFOPT_DATA_STRSW
+
+
+#else
+
+# define MNotifyGetTString MNotifyGetString
+# define MNotifyGetTTemplate MNotifyGetTemplate
+# define MNotifySetTString MNotifySetString
+# define MNotifySetTTemplate MNotifySetTemplate
+# define MNotifyGetTParsedTemplate MNotifyGetParsedTemplate
+# define MNotifyHasTVariables MNotifyHasVariables
+# define MNotifyShowTVariables MNotifyShowVariables
+
+# define NFOPT_DEFTEMPL_TEXTT NFOPT_DEFTEMPL_TEXT
+# define NFOPT_DEFTEMPL_TITLET NFOPT_DEFTEMPL_TITLE
+
+# define NFOPT_VARIABLES_STRST NFOPT_VARIABLES_STRS
+# define NFOPT_VARIABLES_DESCRIPTIONS_STRST NFOPT_VARIABLES_DESCRIPTIONS_STRS
+# define NFOPT_DATA_STRST NFOPT_DATA_STRS
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __TEMPLATES_H__
diff --git a/plugins/utils/tstring.h b/plugins/utils/tstring.h
new file mode 100644
index 0000000000..fb340bcd03
--- /dev/null
+++ b/plugins/utils/tstring.h
@@ -0,0 +1,14 @@
+#ifndef __TSTRING_H__
+# define __TSTRING_H__
+
+#include <windows.h>
+#include <tchar.h>
+#include <string>
+
+
+namespace std {
+ typedef basic_string<TCHAR, char_traits<TCHAR>, allocator<TCHAR> > tstring;
+}
+
+
+#endif // __TSTRING_H__
diff --git a/plugins/utils/utf8_helpers.h b/plugins/utils/utf8_helpers.h
new file mode 100644
index 0000000000..3eaf0f4fe0
--- /dev/null
+++ b/plugins/utils/utf8_helpers.h
@@ -0,0 +1,587 @@
+/*
+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 __UTF8_HELPERS_H__
+# define __UTF8_HELPERS_H__
+
+#include <windows.h>
+#include <newpluginapi.h>
+#include <m_system.h>
+
+
+class TcharToUtf8
+{
+public:
+ TcharToUtf8(const char *str) : utf8(NULL)
+ {
+ int size = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
+ if (size <= 0)
+ throw _T("Could not convert string to WCHAR");
+
+ WCHAR *tmp = (WCHAR *) mir_alloc(size * sizeof(WCHAR));
+ if (tmp == NULL)
+ throw _T("mir_alloc returned NULL");
+
+ MultiByteToWideChar(CP_ACP, 0, str, -1, tmp, size);
+
+ init(tmp);
+
+ mir_free(tmp);
+ }
+
+
+ TcharToUtf8(const WCHAR *str) : utf8(NULL)
+ {
+ init(str);
+ }
+
+
+ ~TcharToUtf8()
+ {
+ if (utf8 != NULL)
+ mir_free(utf8);
+ }
+
+ char *detach()
+ {
+ char *ret = utf8;
+ utf8 = NULL;
+ return ret;
+ }
+
+ const char * get() const
+ {
+ return utf8;
+ }
+
+ operator const char *() const
+ {
+ return utf8;
+ }
+
+ const char & operator[](int pos) const
+ {
+ return utf8[pos];
+ }
+
+private:
+ char *utf8;
+
+ void init(const WCHAR *str)
+ {
+ int size = WideCharToMultiByte(CP_UTF8, 0, str, -1, NULL, 0, NULL, NULL);
+ if (size <= 0)
+ throw _T("Could not convert string to UTF8");
+
+ utf8 = (char *) mir_alloc(size);
+ if (utf8 == NULL)
+ throw _T("mir_alloc returned NULL");
+
+ WideCharToMultiByte(CP_UTF8, 0, str, -1, utf8, size, NULL, NULL);
+ }
+};
+
+
+
+class Utf8ToTchar
+{
+public:
+ Utf8ToTchar(const char *str) : tchar(NULL)
+ {
+ if (str == NULL)
+ return;
+
+ int size = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0);
+ if (size <= 0)
+ throw _T("Could not convert string to WCHAR");
+
+ WCHAR *tmp = (WCHAR *) mir_alloc(size * sizeof(WCHAR));
+ if (tmp == NULL)
+ throw _T("mir_alloc returned NULL");
+
+ MultiByteToWideChar(CP_UTF8, 0, str, -1, tmp, size);
+
+#ifdef UNICODE
+
+ tchar = tmp;
+
+#else
+
+ size = WideCharToMultiByte(CP_ACP, 0, tmp, -1, NULL, 0, NULL, NULL);
+ if (size <= 0)
+ {
+ mir_free(tmp);
+ throw _T("Could not convert string to ACP");
+ }
+
+ tchar = (TCHAR *) mir_alloc(size * sizeof(char));
+ if (tchar == NULL)
+ {
+ mir_free(tmp);
+ throw _T("mir_alloc returned NULL");
+ }
+
+ WideCharToMultiByte(CP_ACP, 0, tmp, -1, tchar, size, NULL, NULL);
+
+ mir_free(tmp);
+
+#endif
+ }
+
+ ~Utf8ToTchar()
+ {
+ if (tchar != NULL)
+ mir_free(tchar);
+ }
+
+ TCHAR *detach()
+ {
+ TCHAR *ret = tchar;
+ tchar = NULL;
+ return ret;
+ }
+
+ TCHAR * get() const
+ {
+ return tchar;
+ }
+
+ operator TCHAR *() const
+ {
+ return tchar;
+ }
+
+ TCHAR & operator[](int pos)
+ {
+ return tchar[pos];
+ }
+
+private:
+ TCHAR *tchar;
+};
+
+
+class CharToTchar
+{
+public:
+ CharToTchar(const char *str) : tchar(NULL)
+ {
+ if (str == NULL)
+ return;
+
+#ifdef UNICODE
+
+ tchar = mir_a2u(str);
+
+#else
+
+ tchar = str;
+
+#endif
+ }
+
+
+ ~CharToTchar()
+ {
+#ifdef UNICODE
+ if (tchar != NULL)
+ mir_free(tchar);
+#endif
+ }
+
+ TCHAR *detach()
+ {
+#ifdef UNICODE
+ TCHAR *ret = tchar;
+#else
+ TCHAR *ret = (tchar == NULL ? NULL : mir_strdup(tchar));
+#endif
+
+ tchar = NULL;
+ return ret;
+ }
+
+ const TCHAR * get() const
+ {
+ return tchar;
+ }
+
+ operator const TCHAR *() const
+ {
+ return tchar;
+ }
+
+ const TCHAR & operator[](int pos) const
+ {
+ return tchar[pos];
+ }
+
+private:
+#ifdef UNICODE
+ TCHAR *tchar;
+#else
+ const TCHAR *tchar;
+#endif
+};
+
+
+class WcharToTchar
+{
+public:
+ WcharToTchar(const WCHAR *str) : tchar(NULL)
+ {
+ if (str == NULL)
+ return;
+
+#ifdef UNICODE
+
+ tchar = str;
+
+#else
+
+ tchar = mir_u2a(str);
+
+#endif
+ }
+
+
+ ~WcharToTchar()
+ {
+#ifndef UNICODE
+ if (tchar != NULL)
+ mir_free(tchar);
+#endif
+ }
+
+ TCHAR *detach()
+ {
+#ifdef UNICODE
+ TCHAR *ret = (tchar == NULL ? NULL : mir_wstrdup(tchar));
+#else
+ TCHAR *ret = tchar;
+#endif
+
+ tchar = NULL;
+ return ret;
+ }
+
+ const TCHAR * get() const
+ {
+ return tchar;
+ }
+
+ operator const TCHAR *() const
+ {
+ return tchar;
+ }
+
+ const TCHAR & operator[](int pos) const
+ {
+ return tchar[pos];
+ }
+
+private:
+#ifdef UNICODE
+ const TCHAR *tchar;
+#else
+ TCHAR *tchar;
+#endif
+};
+
+
+
+
+class CharToWchar
+{
+public:
+ CharToWchar(const char *str) : wchar(NULL)
+ {
+ if (str == NULL)
+ return;
+
+ wchar = mir_a2u(str);
+ }
+
+
+ ~CharToWchar()
+ {
+ if (wchar != NULL)
+ mir_free(wchar);
+ }
+
+ WCHAR *detach()
+ {
+ WCHAR *ret = wchar;
+ wchar = NULL;
+ return ret;
+ }
+
+ const WCHAR * get() const
+ {
+ return wchar;
+ }
+
+ operator const WCHAR *() const
+ {
+ return wchar;
+ }
+
+ const WCHAR & operator[](int pos) const
+ {
+ return wchar[pos];
+ }
+
+private:
+ WCHAR *wchar;
+};
+
+
+
+class TcharToChar
+{
+public:
+ TcharToChar(const TCHAR *str) : val(NULL)
+ {
+ if (str == NULL)
+ return;
+
+#ifdef UNICODE
+
+ val = mir_u2a(str);
+
+#else
+
+ val = str;
+
+#endif
+ }
+
+
+ ~TcharToChar()
+ {
+#ifdef UNICODE
+ if (val != NULL)
+ mir_free(val);
+#endif
+ }
+
+ char *detach()
+ {
+#ifdef UNICODE
+ char *ret = val;
+#else
+ char *ret = (val == NULL ? NULL : mir_strdup(val));
+#endif
+
+ val = NULL;
+ return ret;
+ }
+
+ const char * get() const
+ {
+ return val;
+ }
+
+ operator const char *() const
+ {
+ return val;
+ }
+
+ const char & operator[](int pos) const
+ {
+ return val[pos];
+ }
+
+private:
+#ifdef UNICODE
+ char *val;
+#else
+ const char *val;
+#endif
+};
+
+
+class TcharToWchar
+{
+public:
+ TcharToWchar(const TCHAR *str) : val(NULL)
+ {
+ if (str == NULL)
+ return;
+
+#ifdef UNICODE
+
+ val = str;
+
+#else
+
+ val = mir_a2u(str);
+
+#endif
+ }
+
+
+ ~TcharToWchar()
+ {
+#ifndef UNICODE
+ if (val != NULL)
+ mir_free(val);
+#endif
+ }
+
+ WCHAR *detach()
+ {
+#ifdef UNICODE
+ WCHAR *ret = (val == NULL ? NULL : mir_wstrdup(val));
+#else
+ WCHAR *ret = val;
+#endif
+
+ val = NULL;
+ return ret;
+ }
+
+ const WCHAR * get() const
+ {
+ return val;
+ }
+
+ operator const WCHAR *() const
+ {
+ return val;
+ }
+
+ const WCHAR & operator[](int pos) const
+ {
+ return val[pos];
+ }
+
+private:
+#ifdef UNICODE
+ const WCHAR *val;
+#else
+ WCHAR *val;
+#endif
+};
+
+
+
+
+class BstrToTchar
+{
+public:
+ BstrToTchar() : bstr(NULL)
+#ifndef UNICODE
+ , tchar(NULL)
+#endif
+ {
+ }
+
+ BstrToTchar(const WCHAR *str) : bstr(NULL)
+#ifndef UNICODE
+ , tchar(NULL)
+#endif
+ {
+ if (str == NULL)
+ return;
+
+ bstr = SysAllocString(str);
+ }
+
+ BstrToTchar(const char *str) : bstr(NULL)
+#ifndef UNICODE
+ , tchar(NULL)
+#endif
+ {
+ if (str == NULL)
+ return;
+
+ bstr = SysAllocString(CharToWchar(str));
+ }
+
+
+ ~BstrToTchar()
+ {
+ if (bstr != NULL)
+ SysFreeString(bstr);
+
+#ifndef UNICODE
+ freeTchar();
+#endif
+ }
+
+ BSTR detach()
+ {
+ BSTR ret = bstr;
+ bstr = NULL;
+ return ret;
+ }
+
+ operator const TCHAR *()
+ {
+#ifdef UNICODE
+
+ return bstr;
+
+#else
+
+ if (tchar == NULL)
+ tchar = mir_u2a(bstr);
+
+ return tchar;
+
+#endif
+ }
+
+ operator const BSTR() const
+ {
+ return bstr;
+ }
+
+ operator BSTR *()
+ {
+#ifndef UNICODE
+ freeTchar();
+#endif
+
+ return &bstr;
+ }
+
+private:
+ BSTR bstr;
+
+#ifndef UNICODE
+
+ TCHAR *tchar;
+
+ void freeTchar()
+ {
+ if (tchar != NULL)
+ {
+ mir_free(tchar);
+ tchar = NULL;
+ }
+ }
+
+#endif
+};
+
+
+#endif // __UTF8_HELPERS_H__
diff --git a/plugins/variables/Variables_10.vcxproj b/plugins/variables/Variables_10.vcxproj
index 97b7cb39c9..c6dbdeef1d 100644
--- a/plugins/variables/Variables_10.vcxproj
+++ b/plugins/variables/Variables_10.vcxproj
@@ -143,7 +143,7 @@
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
- <AdditionalIncludeDirectories>../../include;./pcre/include;./;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>../../include;../ExternalAPI;./pcre/include;./;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;VARIABLES_EXPORTS;UNICODE;_WIN32_WINNT=0x0502;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
@@ -184,7 +184,7 @@
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
- <AdditionalIncludeDirectories>../../include;./pcre/include;./;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>../../include;../ExternalAPI;./pcre/include;./;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;VARIABLES_EXPORTS;_WIN32_WINNT=0x0502;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
@@ -227,7 +227,7 @@
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <AdditionalIncludeDirectories>../../include;./pcre/include;./;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>../../include;../ExternalAPI;./pcre/include;./;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;VARIABLES_EXPORTS;_WIN32_WINNT=0x0502;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
@@ -272,7 +272,7 @@
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <AdditionalIncludeDirectories>../../include;./pcre/include;./;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>../../include;../ExternalAPI;./pcre/include;./;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;VARIABLES_EXPORTS;UNICODE;_WIN32_WINNT=0x0502;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
@@ -304,7 +304,7 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">
<ClCompile>
- <AdditionalIncludeDirectories>../../include;./pcre/include;./;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>../../include;../ExternalAPI;./pcre/include;./;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_WIN64;NDEBUG;_WINDOWS;_USRDLL;VARIABLES_EXPORTS;UNICODE;_WIN32_WINNT=0x0502;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
@@ -314,7 +314,7 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
- <AdditionalIncludeDirectories>../../include;./pcre/include;./;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>../../include;../ExternalAPI;./pcre/include;./;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_WIN64;NDEBUG;_WINDOWS;_USRDLL;VARIABLES_EXPORTS;_WIN32_WINNT=0x0502;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
@@ -324,7 +324,7 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">
<ClCompile>
- <AdditionalIncludeDirectories>../../include;./pcre/include;./;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>../../include;../ExternalAPI;./pcre/include;./;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_WIN64;_DEBUG;_WINDOWS;_USRDLL;VARIABLES_EXPORTS;UNICODE;_WIN32_WINNT=0x0502;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
@@ -334,7 +334,7 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
- <AdditionalIncludeDirectories>../../include;./pcre/include;./;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>../../include;../ExternalAPI;./pcre/include;./;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_WIN64;_DEBUG;_WINDOWS;_USRDLL;VARIABLES_EXPORTS;_WIN32_WINNT=0x0502;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
diff --git a/plugins/variables/action_variables.cpp b/plugins/variables/action_variables.cpp
index 49e76d5ed0..c981400410 100644
--- a/plugins/variables/action_variables.cpp
+++ b/plugins/variables/action_variables.cpp
@@ -18,7 +18,7 @@
*/
// This file has not been converted to unicode yet
#include "variables.h"
-#include "../NewTriggerPlugin/m_trigger.h"
+#include "m_trigger.h"
#include "trigger_variables.h"
#include "resource.h"
diff --git a/plugins/variables/condition_variables.cpp b/plugins/variables/condition_variables.cpp
index aaef7a208d..6e6739f112 100644
--- a/plugins/variables/condition_variables.cpp
+++ b/plugins/variables/condition_variables.cpp
@@ -18,7 +18,7 @@
*/
// This file has not been converted to unicode yet
#include "variables.h"
-#include "../NewTriggerPlugin/m_trigger.h"
+#include "m_trigger.h"
#include "trigger_variables.h"
#include "resource.h"
diff --git a/plugins/variables/trigger_variables.cpp b/plugins/variables/trigger_variables.cpp
index 4348b262ed..16333b29e6 100644
--- a/plugins/variables/trigger_variables.cpp
+++ b/plugins/variables/trigger_variables.cpp
@@ -17,7 +17,7 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "variables.h"
-#include "../NewTriggerPlugin/m_trigger.h"
+#include "m_trigger.h"
#include "trigger_variables.h"
#include "resource.h"
diff --git a/plugins/weather/langpack_defweather.txt b/plugins/weather/langpack_defweather.txt
new file mode 100644
index 0000000000..211c2451da
--- /dev/null
+++ b/plugins/weather/langpack_defweather.txt
@@ -0,0 +1,126 @@
+Miranda Language Pack Version 1
+Language: English (UK) for Weather Protocol Icon Assignment
+Locale: 0809
+Last-Modified-Using: Miranda 0.3.3.0
+Authors: NoName
+Author-email:
+Plugins-included: Weather Protocol
+
+; Weather protocol v0.3+ use this to assignment icon to weather condition
+; This file is just a sample, the weather protocol will function properly without file
+; if internal icon selection is turn on. If internal icon selection is off, these
+; translation strings must present (in any desired language) in order for the plugin
+; to function properly. Otherwise, NA will be set for all weather stations.
+
+; The format of this is similar to the other language pack string, using
+; [# Weather <status> <counter> #]
+; The protocol will read all string with counter = 1 until the first unavailable string
+; ie. the translated string is the same as the original string.
+; The priority of the condition icons is:
+; Lightning, Fog, Snow Shower, Snow, Rain Shower, Rain, Partly Cloudy, Cloudy, Sunny
+; Weather protocol will assign the icon if part of the string patches. If no match found,
+; an NA icon is assigned for that station.
+; String of all languages can be added so the icon can display properly even if the raw
+; data is in some language other than English.
+
+;==============================
+; Sunny
+[# Weather Sunny 1 #]
+Sunny
+
+[# Weather Sunny 2 #]
+Clear
+
+[# Weather Sunny 3 #]
+Fair
+
+;==============================
+; Partly Cloudy
+[# Weather Partly Cloudy 1 #]
+Mainy Sunny
+
+[# Weather Partly Cloudy 2 #]
+Mainy Clear
+
+[# Weather Partly Cloudy 3 #]
+Partly
+
+[# Weather Partly Cloudy 4 #]
+Mostly
+
+[# Weather Partly Cloudy 5 #]
+Clouds
+
+;==============================
+; Cloudy
+[# Weather Cloudy 1 #]
+Cloudy
+
+[# Weather Cloudy 2 #]
+Overcast
+
+;==============================
+; Rain
+[# Weather Rain 1 #]
+Drizzle
+
+[# Weather Rain 2 #]
+Rain
+
+;==============================
+; Rain Shower
+[# Weather Rain Shower 1 #]
+Rain Shower
+
+[# Weather Rain Shower 2 #]
+Shower
+
+;==============================
+; Snow
+[# Weather Snow 1 #]
+Snow
+
+[# Weather Snow 2 #]
+Ice
+
+[# Weather Snow 3 #]
+Freezing
+
+[# Weather Snow 4 #]
+Wintry
+
+;==============================
+; Snow Shower
+[# Weather Snow Shower 1 #]
+Snow Shower
+
+[# Weather Snow Shower 2 #]
+Flurries
+
+;==============================
+; Lightning
+[# Weather Lightning 1 #]
+Thunder
+
+[# Weather Lightning 1 #]
+T-storm
+
+;==============================
+; Fog
+[# Weather Fog 1 #]
+Fog
+
+[# Weather Fog 2 #]
+Mist
+
+[# Weather Fog 3 #]
+Smoke
+
+[# Weather Fog 4 #]
+Haze
+
+[# Weather Fog 5 #]
+Sand
+
+[# Weather Fog 6 #]
+Dust \ No newline at end of file
diff --git a/plugins/weather/license.txt b/plugins/weather/license.txt
new file mode 100644
index 0000000000..45645b4b53
--- /dev/null
+++ b/plugins/weather/license.txt
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/plugins/weather/m_cluiframes.h b/plugins/weather/m_cluiframes.h
new file mode 100644
index 0000000000..43b37b5133
--- /dev/null
+++ b/plugins/weather/m_cluiframes.h
@@ -0,0 +1,275 @@
+/*
+Miranda ICQ: the free icq client for MS Windows
+Copyright (C) 2000-2 Richard Hughes, Roland Rabien & Tristan Van de Vreede
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+//#pragma hdrstop
+
+////////////////////////////////////
+//Extra Image Column Support +0.5.0.0
+
+//Extra columns type.
+//column arranged in this way
+//
+// [statusicon] ContactName [ADV1][ADV2][SMS][EMAIL][PROTO]
+//
+#define EXTRA_ICON_EMAIL 1
+#define EXTRA_ICON_PROTO 2
+#define EXTRA_ICON_SMS 3
+#define EXTRA_ICON_ADV1 4
+#define EXTRA_ICON_ADV2 5
+#define DEFAULT_TITLEBAR_HEIGHT 18
+
+#define CLS_SKINNEDFRAME 0x0800 //this control will be the main contact list (v. 0.3.4.3+ 2004/11/02)
+
+typedef struct
+{
+int cbSize; //must be sizeof(IconExtraColumn)
+int ColumnType;
+HANDLE hImage; //return value from MS_CLIST_EXTRA_ADD_ICON
+}IconExtraColumn,*pIconExtraColumn;
+
+
+//Set icon for contact at needed column
+//wparam=hContact
+//lparam=pIconExtraColumn
+//return 0 on success,-1 on failure
+//
+//See above for supported columns
+#define MS_CLIST_EXTRA_SET_ICON "CListFrames/SetIconForExraColumn"
+
+//Adding icon to extra image list.
+//Call this in ME_CLIST_EXTRA_LIST_REBUILD event
+//
+//wparam=hIcon
+//lparam=0
+//return hImage on success,-1 on failure
+#define MS_CLIST_EXTRA_ADD_ICON "CListFrames/AddIconToExtraImageList"
+
+
+
+#define ME_CLIST_EXTRA_LIST_REBUILD "CListFrames/OnExtraListRebuild"
+
+//called with wparam=hContact
+#define ME_CLIST_EXTRA_IMAGE_APPLY "CListFrames/OnExtraImageApply"
+
+
+///////////////////////////////////
+
+
+
+
+//
+//want show tooltip for statusbar
+//wparam=(char *)protocolname
+//lparam=0
+#define ME_CLIST_FRAMES_SB_SHOW_TOOLTIP "CListFrames/StatusBarShowToolTip"
+
+
+//want hide tooltip for statusbar
+//wparam=lparam=0
+
+#define ME_CLIST_FRAMES_SB_HIDE_TOOLTIP "CListFrames/StatusBarHideToolTip"
+
+//
+
+
+
+//adds a frame window
+//wParam=(CLISTFrame*)
+//lParam=0
+//returns an integer, the frame id.
+typedef struct tagCLISTFrame {
+ DWORD cbSize;
+ HWND hWnd ;
+ HICON hIcon;
+ int align; //al flags below
+ int height;
+ int Flags; //F_flags below
+ union {
+ char *name; //frame window name indentifier (DO NOT TRANSLATE)
+ wchar_t *wname;
+ LPTSTR tname;
+ };
+ union {
+ char *TBname; //titlebar & menu caption
+ wchar_t *TBwname;
+ LPTSTR TBtname;
+ };
+ //COLORREF TBBackColour; //titlebar background colour
+} CLISTFrame;
+#define F_VISIBLE 1 //Frame visible
+#define F_SHOWTB 2 //Show TitleBar
+#define F_UNCOLLAPSED 4 //UnCollapse frame
+#define F_LOCKED 8 //Lock Frame
+#define F_NOBORDER 16 //Dont apply WS_BORDER style for window
+#define F_SHOWTBTIP 32 //Show titlebar tooltip
+#define F_NO_SUBCONTAINER 1024 //Support skining no subcontainer needed
+#define F_SKINNED 2048 // skinned frame (for owned subframe only)
+#define F_UNICODE 32768 //Use unicode text
+#ifdef _UNICODE
+# define F_TCHAR F_UNICODE
+#else
+# define F_TCHAR 0
+#endif
+
+// frame alignment
+#define alTop 0x00000001
+#define alBottom 0x00000002
+#define alClient 0x00000004 //only one alClient frame
+#define MS_CLIST_FRAMES_ADDFRAME "CListFrames/AddFrame"
+
+#define MS_CLIST_FRAMES_REMOVEFRAME "CListFrames/RemoveFrame"
+
+//shows all frames
+//wParam=lParam=0
+//returns 0 on success, -1 on failure
+#define MS_CLIST_FRAMES_SHOWALLFRAMES "CListFrames/ShowALLFrames"
+
+//shows the titlebars of all frames
+//wParam=lParam=0
+//returns 0 on success, -1 on failure
+#define MS_CLIST_FRAMES_SHOWALLFRAMESTB "CListFrames/ShowALLFramesTB"
+
+//hides the titlebars of all frames
+//wParam=lParam=0
+//returns 0 on success, -1 on failure
+#define MS_CLIST_FRAMES_HIDEALLFRAMESTB "CListFrames/HideALLFramesTB"
+
+//shows the frame if it is hidden,
+//hides the frame if it is shown
+//wParam=FrameId
+//lParam=0
+//returns 0 on success, -1 on failure
+#define MS_CLIST_FRAMES_SHFRAME "CListFrames/SHFrame"
+
+//shows the frame titlebar if it is hidden,
+//hides the frame titlebar if it is shown
+//wParam=FrameId
+//lParam=0
+//returns 0 on success, -1 on failure
+#define MS_CLIST_FRAMES_SHFRAMETITLEBAR "CListFrame/SHFrameTitleBar"
+
+//locks the frame if it is unlocked,
+//unlock the frame if it is locked
+//wParam=FrameId
+//lParam=0
+//returns 0 on success, -1 on failure
+#define MS_CLIST_FRAMES_ULFRAME "CListFrame/ULFrame"
+
+//collapses the frame if it is uncollapsed,
+//uncollapses the frame if it is collapsed
+//wParam=FrameId
+//lParam=0
+//returns 0 on success, -1 on failure
+#define MS_CLIST_FRAMES_UCOLLFRAME "CListFrame/UCOLLFrame"
+
+//trigger border flags
+//wparam=frameid
+//lparam=0
+#define MS_CLIST_FRAMES_SETUNBORDER "CListFrame/SetUnBorder"
+
+//trigger skinned flags
+//wparam=frameid
+//lparam=0
+#define MS_CLIST_FRAMES_SETSKINNED "CListFrame/SetSkinnedFrame"
+
+//redraws the frame
+//wParam=FrameId, -1 for all frames
+//lparam=FU_flags
+//returns a pointer to option, -1 on failure
+#define FU_TBREDRAW 1 //redraw titlebar
+#define FU_FMREDRAW 2 //redraw Frame
+#define FU_FMPOS 4 //update Frame position
+#define MS_CLIST_FRAMES_UPDATEFRAME "CListFrame/UpdateFrame"
+
+//gets the frame options
+//(HIWORD)wParam=FrameId
+//(LOWORD)wParam=FO_flag
+//lParam=0
+//returns a pointer to option, -1 on failure
+#define FO_FLAGS 0x0001 //return set of F_VISIBLE,F_SHOWTB,F_UNCOLLAPSED,F_LOCKED,F_NOBORDER,F_SHOWTBTIP
+#define FO_NAME 0x0002 //Change name
+#define FO_TBNAME 0x0003 //Change TB caption
+#define FO_TBSTYLE 0x0004 //Change TB style
+#define FO_TBEXSTYLE 0x0005 //Change TB exstyle
+#define FO_ICON 0x0006 //Change icon
+#define FO_HEIGHT 0x0007 //Change height
+#define FO_ALIGN 0x0008 //Change align
+#define FO_TBTIPNAME 0x0009 //Change TB tooltip
+#define FO_FLOATING 0x000a //Change floating mode
+
+#define FO_UNICODETEXT 0x8000 // flag for FO_NAME,FO_TBNAME, FO_TBTIPNAME set/get lPAram as unicode wchar_t
+#ifdef _UNICODE
+ #define FO_TCHAR FO_UNICODETEXT
+#else
+ #define FO_TCHAR 0x0000
+#endif
+
+#define MS_CLIST_FRAMES_GETFRAMEOPTIONS "CListFrame/GetFrameOptions"
+
+//sets the frame options
+//(HIWORLD)wParam=FrameId
+//(LOWORD)wParam=FO_flag
+//lParam=value
+//returns 0 on success, -1 on failure
+#define MS_CLIST_FRAMES_SETFRAMEOPTIONS "CListFrame/SetFrameOptions"
+
+
+//menu stuff
+
+//add a new item to the context frame menu
+//wParam=0
+//lParam=(LPARAM)(CLISTMENUITEM*)&mi
+//returns a handle to the new item
+//popupposition=frameid
+//contactowner=advanced parameter
+#define MS_CLIST_ADDCONTEXTFRAMEMENUITEM "CList/AddContextFrameMenuItem"
+
+//remove a item from context frame menu
+//wParam=hMenuItem returned by MS_CLIST_ADDCONTACTMENUITEM
+//lParam=0
+//returns 0 on success, nonzero on failure
+#define MS_CLIST_REMOVECONTEXTFRAMEMENUITEM "CList/RemoveContextFrameMenuItem"
+
+//builds the context menu for a frame
+//wparam=frameid
+//lParam=0
+//returns a HMENU on success, or NULL on failure
+#define MS_CLIST_MENUBUILDFRAMECONTEXT "CList/BuildContextFrameMenu"
+
+/*
+//the frame menu is about to be built
+wparam=frameid
+lparam=
+-1 for build from titlebar,
+ use
+ MS_CLIST_ADDCONTEXTFRAMEMENUITEM
+ MS_CLIST_REMOVECONTEXTFRAMEMENUITEM
+
+>0 for build in main menu,
+must be popupname=lparam to place your items in right popup of main menu.
+ use
+ MS_CLIST_ADDMAINMENUITEM
+ MS_CLIST_REMOVEMAINMENUITEM
+
+*/
+#define ME_CLIST_PREBUILDFRAMEMENU "CList/PreBuildFrameMenu"
+
+//needed by cluiframes module to add frames menu to main menu.
+//it just calls NotifyEventHooks(hPreBuildFrameMenuEvent,wParam,lParam);
+#define MS_CLIST_FRAMEMENUNOTIFY "CList/ContextFrameMenuNotify"
diff --git a/plugins/weather/m_weather.h b/plugins/weather/m_weather.h
new file mode 100644
index 0000000000..dbdd1de298
--- /dev/null
+++ b/plugins/weather/m_weather.h
@@ -0,0 +1,161 @@
+/*
+Weather Protocol plugin for Miranda IM
+Copyright (C) 2005-2009 Boris Krasnovskiy All Rights Reserved
+Copyright (C) 2002-2005 Calvin Che
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; version 2
+of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef M_WEATHER_H__
+#define M_WEATHER_H__ 1
+
+// {6B612A34-DCF2-4e32-85CF-B6FD006B745E}
+#define MIID_WEATHER { 0x6b612a34, 0xdcf2, 0x4e32, { 0x85, 0xcf, 0xb6, 0xfd, 0x0, 0x6b, 0x74, 0x5e } }
+
+//============ CONSTANTS ============
+
+// name
+#define WEATHERPROTONAME "Weather"
+#define WEATHERPROTOTEXT "Weather"
+#define DEFCURRENTWEATHER "WeatherCondition"
+#define WEATHERCONDITION "Current"
+
+// weather conditions
+#define SUNNY ID_STATUS_ONLINE
+#define NA ID_STATUS_OFFLINE
+#define PCLOUDY ID_STATUS_AWAY
+#define CLOUDY ID_STATUS_NA
+#define RAIN ID_STATUS_OCCUPIED
+#define RSHOWER ID_STATUS_DND
+#define SNOW ID_STATUS_FREECHAT
+#define LIGHT ID_STATUS_INVISIBLE
+#define THUNDER ID_STATUS_INVISIBLE
+#define SSHOWER ID_STATUS_ONTHEPHONE
+#define FOG ID_STATUS_OUTTOLUNCH
+#define UNAVAIL 40081
+
+
+//============ WEATHER CONDITION STRUCT ============
+
+// weather conditions (added in v0.1.2.0)
+typedef struct {
+ HANDLE hContact;
+ char id[128];
+ char city[128];
+ char update[64];
+ char cond[128];
+ char temp[16];
+ char low[16];
+ char high[16];
+ char feel[16];
+ char wind[16];
+ char winddir[64];
+ char dewpoint[16];
+ char pressure[16];
+ char humid[16];
+ char vis[16];
+ char sunrise[32];
+ char sunset[32];
+// are the other ones that important!?
+ WORD status;
+} WEATHERINFO;
+
+
+
+// =============== WEATHER SERVICES ================
+
+// Enable or disable weather protocol.
+// WPARAM = FALSE to toggle, TRUE to use the LPARAM
+// LPARAM = TRUE to enable, FALSE to disable
+#define MS_WEATHER_ENABLED "Weather/EnableDisable"
+
+// Update all weather info
+// WPARAM = LPARAM = NULL
+#define MS_WEATHER_UPDATEALL "Weather/UpdateAll"
+
+// Update all weather info + erase the old ones
+// WPARAM = LPARAM = NULL
+#define MS_WEATHER_REFRESHALL "Weather/RefreshAll"
+
+// Below are the service functions for weather contacts
+// The plugin does NOT verify that they are used in weather contact,
+// so bad call on these function may cause crashes.
+
+// Update a single station
+// WPARAM = (HANDLE)hContact
+// LPARAM = NULL
+#define MS_WEATHER_UPDATE "Weather/Update"
+
+// Update a single station + delete old settings
+// WPARAM = (HANDLE)hContact
+// LPARAM = NULL
+#define MS_WEATHER_REFRESH "Weather/Refresh"
+
+// View the brief info of a contact
+// WPARAM = (HANDLE)hContact
+// LPARAM = NULL
+#define MS_WEATHER_BRIEF "Weather/Brief"
+
+// Use default browser to open the complete forecast on web
+// WPARAM = (HANDLE)hContact
+// LPARAM = NULL
+#define MS_WEATHER_COMPLETE "Weather/CompleteForecast"
+
+// Use default browser to open the weather map defined for the contact
+// WPARAM = (HANDLE)hContact
+// LPARAM = NULL
+#define MS_WEATHER_MAP "Weather/Map"
+
+// Open the external log of the weather contact
+// WPARAM = (HANDLE)hContact
+// LPARAM = NULL
+#define MS_WEATHER_LOG "Weather/Log"
+
+// Edit weather contact setting
+// WPARAM = (HANDLE)hContact
+// LPARAM = NULL
+#define MS_WEATHER_EDIT "Weather/Edit"
+
+// parse the string to turn it to weather display
+// WPARAM = (WEATHERINFO*)hContact
+// LPARAM = (char*)display_str
+#define MS_WEATHER_GETDISPLAY "Weather/GetDisplay"
+
+// =============== WEATHER EVENTS ================
+
+/*
+HANDLE hContact = (HANDLE)wParam;
+BOOL Condition_Changed = (BOOL)lParam;
+
+hContact is the handle of updated contact
+If the weather condition is differ from the last update (either temperature/condition,
+or the last update time, depend what the user choose in the options), then
+Condition_Changed is true; otherwise is false.
+*/
+#define ME_WEATHER_UPDATED "Miranda/Weather/Updated"
+
+/*
+Shows a warning message for Weather PopUp.
+wParam = (char*) lpzMessage
+lParam = Type
+Type can either be SM_WARNING, SM_NOTIFY, or SM_WEATHERALERT
+
+This event is used to avoid the error popup to occurs within a thread, so the "Use
+multiply thread" fuction don't have to be enabled for weather popups to work.
+*/
+#define SM_WEATHERALERT 16
+#define ME_WEATHER_ERROR "Miranda/Weather/Error"
+
+
+#endif //M_WEATHER_H__
diff --git a/plugins/weather/mingw-comp.bat b/plugins/weather/mingw-comp.bat
new file mode 100644
index 0000000000..7c88825ecd
--- /dev/null
+++ b/plugins/weather/mingw-comp.bat
@@ -0,0 +1,2 @@
+c:\mingw\bin\windres resource.rc resource.o
+c:\mingw\bin\gcc -shared -Os -fmerge-constants -mno-align-stringops -s -o weather.dll -D_WIN32_IE=0x0501 -I..\..\include weather.c weather_addstn.c weather_contacts.c weather_conv.c weather_data.c weather_http.c weather_icons.c weather_info.c weather_ini.c weather_mwin.c weather_opt.c weather_popup.c weather_svcs.c weather_update.c weather_userinfo.c resource.o zlib.lib -lkernel32 -lgdi32 -lcomdlg32 -lcomctl32 -lwsock32 2>log \ No newline at end of file
diff --git a/plugins/weather/proto_weather/mingw-comp.bat b/plugins/weather/proto_weather/mingw-comp.bat
new file mode 100644
index 0000000000..167ee1786a
--- /dev/null
+++ b/plugins/weather/proto_weather/mingw-comp.bat
@@ -0,0 +1,2 @@
+c:\mingw\bin\windres resource.rc resource.o
+c:\mingw\bin\ld -n --strip-all -nostdlib -dll -o proto_weather.dll resource.o \ No newline at end of file
diff --git a/plugins/weather/proto_weather/proto_weather.dsp b/plugins/weather/proto_weather/proto_weather.dsp
new file mode 100644
index 0000000000..9c4e9e5075
--- /dev/null
+++ b/plugins/weather/proto_weather/proto_weather.dsp
@@ -0,0 +1,118 @@
+# Microsoft Developer Studio Project File - Name="proto_weather" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=PROTO_WEATHER - WIN32 RELEASE
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "proto_weather.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "proto_weather.mak" CFG="PROTO_WEATHER - WIN32 RELEASE"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "proto_weather - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "proto_weather___Win32_Release"
+# PROP BASE Intermediate_Dir "proto_weather___Win32_Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release\Obj"
+# PROP Ignore_Export_Lib 1
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PROTO_WEATHER_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /O1 /X /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PROTO_WEATHER_EXPORTS" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 /nologo /dll /pdb:none /machine:I386 /nodefaultlib /filealign:512 /noentry /opt:ref /opt:icf
+# Begin Target
+
+# Name "proto_weather - Win32 Release"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\resource.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# Begin Source File
+
+SOURCE=.\wicons\Cloud.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\wicons\FOG.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\wicons\LIGHT.ICO
+# End Source File
+# Begin Source File
+
+SOURCE=.\wicons\NA.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\wicons\PCLOUDY.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\wicons\RAIN.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource.rc
+# End Source File
+# Begin Source File
+
+SOURCE=.\wicons\RSHOWER.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\wicons\SNOW.ICO
+# End Source File
+# Begin Source File
+
+SOURCE=.\wicons\SSHOWER.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\wicons\SUN.ICO
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/plugins/weather/proto_weather/proto_weather.vcproj b/plugins/weather/proto_weather/proto_weather.vcproj
new file mode 100644
index 0000000000..73395dc20c
--- /dev/null
+++ b/plugins/weather/proto_weather/proto_weather.vcproj
@@ -0,0 +1,173 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="proto_weather"
+ ProjectGUID="{B2F4BA6C-1BD6-4A50-A706-DCBC6A5D439B}"
+ Keyword="Win32Proj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="Debug"
+ ConfigurationType="2"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;PROTO_WEATHER_EXPORTS"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="4"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/proto_weather.dll"
+ LinkIncremental="2"
+ IgnoreAllDefaultLibraries="TRUE"
+ GenerateDebugInformation="TRUE"
+ ProgramDatabaseFile="$(OutDir)/proto_weather.pdb"
+ SubSystem="2"
+ ResourceOnlyDLL="TRUE"
+ ImportLibrary="$(OutDir)/proto_weather.lib"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release"
+ ConfigurationType="2"
+ CharacterSet="2"
+ WholeProgramOptimization="FALSE">
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;PROTO_WEATHER_EXPORTS"
+ RuntimeLibrary="0"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ IgnoreImportLibrary="TRUE"
+ OutputFile="$(OutDir)/proto_weather.dll"
+ LinkIncremental="1"
+ IgnoreAllDefaultLibraries="TRUE"
+ GenerateDebugInformation="FALSE"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ ResourceOnlyDLL="TRUE"
+ ImportLibrary=""
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+ <File
+ RelativePath=".\resource.h">
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
+ <File
+ RelativePath=".\wicons\Cloud.ico">
+ </File>
+ <File
+ RelativePath=".\wicons\FOG.ico">
+ </File>
+ <File
+ RelativePath=".\wicons\LIGHT.ICO">
+ </File>
+ <File
+ RelativePath=".\wicons\NA.ico">
+ </File>
+ <File
+ RelativePath=".\wicons\PCLOUDY.ico">
+ </File>
+ <File
+ RelativePath=".\wicons\RAIN.ico">
+ </File>
+ <File
+ RelativePath=".\resource.rc">
+ </File>
+ <File
+ RelativePath=".\wicons\RSHOWER.ico">
+ </File>
+ <File
+ RelativePath=".\wicons\SNOW.ICO">
+ </File>
+ <File
+ RelativePath=".\wicons\SSHOWER.ico">
+ </File>
+ <File
+ RelativePath=".\wicons\SUN.ICO">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/plugins/weather/proto_weather/proto_weather_8.vcproj b/plugins/weather/proto_weather/proto_weather_8.vcproj
new file mode 100644
index 0000000000..72fb5f964c
--- /dev/null
+++ b/plugins/weather/proto_weather/proto_weather_8.vcproj
@@ -0,0 +1,254 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="proto_weather"
+ ProjectGUID="{B2F4BA6C-1BD6-4A50-A706-DCBC6A5D439B}"
+ RootNamespace="proto_weather"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="Debug"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ CharacterSet="0"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;PROTO_WEATHER_EXPORTS"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ IgnoreImportLibrary="true"
+ LinkLibraryDependencies="false"
+ OutputFile="$(OutDir)/proto_weather.dll"
+ LinkIncremental="2"
+ IgnoreAllDefaultLibraries="true"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile="$(OutDir)/proto_weather.pdb"
+ SubSystem="2"
+ ResourceOnlyDLL="true"
+ ImportLibrary="$(OutDir)/proto_weather.lib"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;PROTO_WEATHER_EXPORTS"
+ RuntimeLibrary="0"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ IgnoreImportLibrary="true"
+ OutputFile="$(OutDir)/proto_weather.dll"
+ LinkIncremental="1"
+ IgnoreAllDefaultLibraries="true"
+ GenerateDebugInformation="false"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ ResourceOnlyDLL="true"
+ ImportLibrary=""
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath=".\resource.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ <File
+ RelativePath=".\wicons\Cloud.ico"
+ >
+ </File>
+ <File
+ RelativePath=".\wicons\FOG.ico"
+ >
+ </File>
+ <File
+ RelativePath=".\wicons\LIGHT.ICO"
+ >
+ </File>
+ <File
+ RelativePath=".\wicons\NA.ico"
+ >
+ </File>
+ <File
+ RelativePath=".\wicons\PCLOUDY.ico"
+ >
+ </File>
+ <File
+ RelativePath=".\wicons\RAIN.ico"
+ >
+ </File>
+ <File
+ RelativePath=".\resource.rc"
+ >
+ </File>
+ <File
+ RelativePath=".\wicons\RSHOWER.ico"
+ >
+ </File>
+ <File
+ RelativePath=".\wicons\SNOW.ICO"
+ >
+ </File>
+ <File
+ RelativePath=".\wicons\SSHOWER.ico"
+ >
+ </File>
+ <File
+ RelativePath=".\wicons\SUN.ICO"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/plugins/weather/proto_weather/proto_weather_9.vcproj b/plugins/weather/proto_weather/proto_weather_9.vcproj
new file mode 100644
index 0000000000..fbf137c71c
--- /dev/null
+++ b/plugins/weather/proto_weather/proto_weather_9.vcproj
@@ -0,0 +1,421 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="proto_weather"
+ ProjectGUID="{B2F4BA6C-1BD6-4A50-A706-DCBC6A5D439B}"
+ RootNamespace="proto_weather"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)\Obj"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ CharacterSet="0"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;PROTO_WEATHER_EXPORTS"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ IgnoreImportLibrary="true"
+ LinkLibraryDependencies="false"
+ OutputFile="$(OutDir)/proto_weather.dll"
+ LinkIncremental="2"
+ GenerateManifest="false"
+ IgnoreAllDefaultLibraries="true"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile="$(OutDir)/proto_weather.pdb"
+ SubSystem="2"
+ ResourceOnlyDLL="true"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ ImportLibrary="$(OutDir)/proto_weather.lib"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="$(ConfigurationName)64"
+ IntermediateDirectory="$(ConfigurationName)64\Obj"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ CharacterSet="0"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;PROTO_WEATHER_EXPORTS"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ IgnoreImportLibrary="true"
+ LinkLibraryDependencies="false"
+ OutputFile="$(OutDir)/proto_weather.dll"
+ GenerateManifest="false"
+ IgnoreAllDefaultLibraries="true"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile="$(OutDir)/proto_weather.pdb"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ ResourceOnlyDLL="true"
+ RandomizedBaseAddress="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)\Obj"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;PROTO_WEATHER_EXPORTS"
+ RuntimeLibrary="0"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ IgnoreImportLibrary="true"
+ OutputFile="$(OutDir)/proto_weather.dll"
+ LinkIncremental="1"
+ GenerateManifest="false"
+ IgnoreAllDefaultLibraries="true"
+ GenerateDebugInformation="false"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ ResourceOnlyDLL="true"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ ImportLibrary=""
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="$(ConfigurationName)64"
+ IntermediateDirectory="$(ConfigurationName)64\Obj"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;PROTO_WEATHER_EXPORTS"
+ RuntimeLibrary="0"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ IgnoreImportLibrary="true"
+ OutputFile="$(OutDir)/proto_weather.dll"
+ LinkIncremental="1"
+ GenerateManifest="false"
+ IgnoreAllDefaultLibraries="true"
+ GenerateDebugInformation="false"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ ResourceOnlyDLL="true"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ ImportLibrary=""
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath=".\resource.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ <File
+ RelativePath=".\wicons\Cloud.ico"
+ >
+ </File>
+ <File
+ RelativePath=".\wicons\FOG.ico"
+ >
+ </File>
+ <File
+ RelativePath=".\wicons\LIGHT.ICO"
+ >
+ </File>
+ <File
+ RelativePath=".\wicons\NA.ico"
+ >
+ </File>
+ <File
+ RelativePath=".\wicons\PCLOUDY.ico"
+ >
+ </File>
+ <File
+ RelativePath=".\wicons\RAIN.ico"
+ >
+ </File>
+ <File
+ RelativePath=".\resource.rc"
+ >
+ </File>
+ <File
+ RelativePath=".\wicons\RSHOWER.ico"
+ >
+ </File>
+ <File
+ RelativePath=".\wicons\SNOW.ICO"
+ >
+ </File>
+ <File
+ RelativePath=".\wicons\SSHOWER.ico"
+ >
+ </File>
+ <File
+ RelativePath=".\wicons\SUN.ICO"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/plugins/weather/proto_weather/resource.h b/plugins/weather/proto_weather/resource.h
new file mode 100644
index 0000000000..0ac64a0f1c
--- /dev/null
+++ b/plugins/weather/proto_weather/resource.h
@@ -0,0 +1,26 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by resource.rc
+//
+#define IDI_ONLINE 104
+#define IDI_OFFLINE 105
+#define IDI_AWAY 128
+#define IDI_FREE4CHAT 129
+#define IDI_INVISIBLE 130
+#define IDI_NA 131
+#define IDI_DND 158
+#define IDI_OCCUPIED 159
+#define IDI_ONTHEPHONE 1002
+#define IDI_OUTTOLUNCH 1003
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NO_MFC 1
+#define _APS_NEXT_RESOURCE_VALUE 224
+#define _APS_NEXT_COMMAND_VALUE 40030
+#define _APS_NEXT_CONTROL_VALUE 2117
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/plugins/weather/proto_weather/resource.rc b/plugins/weather/proto_weather/resource.rc
new file mode 100644
index 0000000000..09a6fb0cb9
--- /dev/null
+++ b/plugins/weather/proto_weather/resource.rc
@@ -0,0 +1,81 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include <windows.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
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_ONLINE ICON "wicons\\SUN.ico"
+IDI_OFFLINE ICON "wicons\\NA.ico"
+IDI_AWAY ICON "wicons\\PCLOUDY.ico"
+IDI_DND ICON "wicons\\RSHOWER.ico"
+IDI_INVISIBLE ICON "wicons\\LIGHT.ico"
+IDI_OCCUPIED ICON "wicons\\RAIN.ico"
+IDI_FREE4CHAT ICON "wicons\\SNOW.ico"
+IDI_NA ICON "wicons\\CLOUD.ico"
+IDI_ONTHEPHONE ICON "wicons\\SSHOWER.ico"
+IDI_OUTTOLUNCH ICON "wicons\\FOG.ico"
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include <windows.h>\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Neutral resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/plugins/weather/proto_weather/wicons/Cloud.ico b/plugins/weather/proto_weather/wicons/Cloud.ico
new file mode 100644
index 0000000000..2edb539dcb
--- /dev/null
+++ b/plugins/weather/proto_weather/wicons/Cloud.ico
Binary files differ
diff --git a/plugins/weather/proto_weather/wicons/FOG.ico b/plugins/weather/proto_weather/wicons/FOG.ico
new file mode 100644
index 0000000000..fbd81b9a03
--- /dev/null
+++ b/plugins/weather/proto_weather/wicons/FOG.ico
Binary files differ
diff --git a/plugins/weather/proto_weather/wicons/LIGHT.ICO b/plugins/weather/proto_weather/wicons/LIGHT.ICO
new file mode 100644
index 0000000000..d266094fbe
--- /dev/null
+++ b/plugins/weather/proto_weather/wicons/LIGHT.ICO
Binary files differ
diff --git a/plugins/weather/proto_weather/wicons/NA.ico b/plugins/weather/proto_weather/wicons/NA.ico
new file mode 100644
index 0000000000..3e4a3aa324
--- /dev/null
+++ b/plugins/weather/proto_weather/wicons/NA.ico
Binary files differ
diff --git a/plugins/weather/proto_weather/wicons/PCLOUDY.ico b/plugins/weather/proto_weather/wicons/PCLOUDY.ico
new file mode 100644
index 0000000000..be3d0c88bd
--- /dev/null
+++ b/plugins/weather/proto_weather/wicons/PCLOUDY.ico
Binary files differ
diff --git a/plugins/weather/proto_weather/wicons/RAIN.ico b/plugins/weather/proto_weather/wicons/RAIN.ico
new file mode 100644
index 0000000000..4b65fb6714
--- /dev/null
+++ b/plugins/weather/proto_weather/wicons/RAIN.ico
Binary files differ
diff --git a/plugins/weather/proto_weather/wicons/RSHOWER.ico b/plugins/weather/proto_weather/wicons/RSHOWER.ico
new file mode 100644
index 0000000000..442552e155
--- /dev/null
+++ b/plugins/weather/proto_weather/wicons/RSHOWER.ico
Binary files differ
diff --git a/plugins/weather/proto_weather/wicons/SNOW.ICO b/plugins/weather/proto_weather/wicons/SNOW.ICO
new file mode 100644
index 0000000000..1a482c3bc8
--- /dev/null
+++ b/plugins/weather/proto_weather/wicons/SNOW.ICO
Binary files differ
diff --git a/plugins/weather/proto_weather/wicons/SSHOWER.ico b/plugins/weather/proto_weather/wicons/SSHOWER.ico
new file mode 100644
index 0000000000..0bd2264413
--- /dev/null
+++ b/plugins/weather/proto_weather/wicons/SSHOWER.ico
Binary files differ
diff --git a/plugins/weather/proto_weather/wicons/SUN.ICO b/plugins/weather/proto_weather/wicons/SUN.ICO
new file mode 100644
index 0000000000..b37fc6ad2a
--- /dev/null
+++ b/plugins/weather/proto_weather/wicons/SUN.ICO
Binary files differ
diff --git a/plugins/weather/res/brief.ico b/plugins/weather/res/brief.ico
new file mode 100644
index 0000000000..717ef66669
--- /dev/null
+++ b/plugins/weather/res/brief.ico
Binary files differ
diff --git a/plugins/weather/res/disabled.ico b/plugins/weather/res/disabled.ico
new file mode 100644
index 0000000000..ed6e27b691
--- /dev/null
+++ b/plugins/weather/res/disabled.ico
Binary files differ
diff --git a/plugins/weather/res/edit.ico b/plugins/weather/res/edit.ico
new file mode 100644
index 0000000000..f59dc79b9c
--- /dev/null
+++ b/plugins/weather/res/edit.ico
Binary files differ
diff --git a/plugins/weather/res/icon.ico b/plugins/weather/res/icon.ico
new file mode 100644
index 0000000000..be3d0c88bd
--- /dev/null
+++ b/plugins/weather/res/icon.ico
Binary files differ
diff --git a/plugins/weather/res/info.ico b/plugins/weather/res/info.ico
new file mode 100644
index 0000000000..97d34dc4a5
--- /dev/null
+++ b/plugins/weather/res/info.ico
Binary files differ
diff --git a/plugins/weather/res/infologo.ico b/plugins/weather/res/infologo.ico
new file mode 100644
index 0000000000..cf22ece1b1
--- /dev/null
+++ b/plugins/weather/res/infologo.ico
Binary files differ
diff --git a/plugins/weather/res/log.ico b/plugins/weather/res/log.ico
new file mode 100644
index 0000000000..86139d5e23
--- /dev/null
+++ b/plugins/weather/res/log.ico
Binary files differ
diff --git a/plugins/weather/res/map.ico b/plugins/weather/res/map.ico
new file mode 100644
index 0000000000..8c4c70742d
--- /dev/null
+++ b/plugins/weather/res/map.ico
Binary files differ
diff --git a/plugins/weather/res/more.ico b/plugins/weather/res/more.ico
new file mode 100644
index 0000000000..47e13df383
--- /dev/null
+++ b/plugins/weather/res/more.ico
Binary files differ
diff --git a/plugins/weather/res/popup.ico b/plugins/weather/res/popup.ico
new file mode 100644
index 0000000000..7e0301b42f
--- /dev/null
+++ b/plugins/weather/res/popup.ico
Binary files differ
diff --git a/plugins/weather/res/popup_no.ico b/plugins/weather/res/popup_no.ico
new file mode 100644
index 0000000000..08de082ec2
--- /dev/null
+++ b/plugins/weather/res/popup_no.ico
Binary files differ
diff --git a/plugins/weather/res/reload.ico b/plugins/weather/res/reload.ico
new file mode 100644
index 0000000000..3c81203c03
--- /dev/null
+++ b/plugins/weather/res/reload.ico
Binary files differ
diff --git a/plugins/weather/res/update.ico b/plugins/weather/res/update.ico
new file mode 100644
index 0000000000..ccc4d4611d
--- /dev/null
+++ b/plugins/weather/res/update.ico
Binary files differ
diff --git a/plugins/weather/res/update2.ico b/plugins/weather/res/update2.ico
new file mode 100644
index 0000000000..f71be51ee2
--- /dev/null
+++ b/plugins/weather/res/update2.ico
Binary files differ
diff --git a/plugins/weather/resource.h b/plugins/weather/resource.h
new file mode 100644
index 0000000000..a897f2f313
--- /dev/null
+++ b/plugins/weather/resource.h
@@ -0,0 +1,174 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by resource.rc
+//
+#define IDI_ICON 101
+#define IDD_USERINFO 201
+#define IDD_EDIT 202
+#define IDI_DISABLED 203
+#define IDD_POPUP 204
+#define IDD_OPTIONS 205
+#define IDI_LOG 206
+#define IDI_UPDATE2 208
+#define IDI_READ 209
+#define IDI_UPDATE 210
+#define IDI_S 211
+#define IDI_MAP 212
+#define IDR_PMENU 213
+#define IDI_POPUP 214
+#define IDI_NOPOPUP 215
+#define IDD_TEXTOPT 216
+#define IDD_BRIEF 217
+#define IDD_SETUP 218
+#define IDR_TMENU 219
+#define IDR_TMMENU 220
+#define IDI_EDIT 222
+#define IDD_INFO 224
+#define IDD_SEARCHCITY 225
+#define IDC_NAME 2000
+#define IDC_ID 2001
+#define IDC_LOG 2003
+#define IDC_UPDATETIME 2005
+#define IDC_CTEXT 2006
+#define IDC_AVATARSIZE 2006
+#define IDC_UPDATE 2007
+#define IDC_BTITLE 2008
+#define IDC_STARTUPUPD 2008
+#define IDC_CHANGE 2009
+#define IDC_BTITLE2 2009
+#define IDC_USEWINCOLORS 2010
+#define IDC_BTEXT 2011
+#define IDC_CH 2013
+#define IDC_NTEXT 2015
+#define IDC_DEGREE 2016
+#define IDC_E 2017
+#define IDC_W 2018
+#define IDC_POP1 2019
+#define IDC_XTEXT 2020
+#define IDC_POP2 2020
+#define IDC_PText 2021
+#define IDC_PTitle 2023
+#define IDC_Internal 2024
+#define IDC_ETEXT 2025
+#define IDC_DISCONDICON 2025
+#define IDC_External 2026
+#define IDC_DONOTAPPUNITS 2026
+#define IDC_DEFA 2027
+#define IDC_NOFRAC 2027
+#define IDC_HTEXT 2028
+#define IDC_DPop 2029
+#define IDC_DAutoUpdate 2030
+#define IDC_NEWWIN 2031
+#define IDC_IURL 2032
+#define IDC_MURL 2033
+#define IDC_PROTOCOND 2034
+#define IDC_Overwrite 2035
+#define IDC_UPDCONDCHG 2036
+#define IDC_REMOVEOLD 2037
+#define IDC_MAKEI 2039
+#define IDC_BGCOLOUR 2040
+#define IDC_TEXTCOLOUR 2041
+#define IDC_LeftClick 2042
+#define IDC_PREVIEW 2043
+#define IDC_VAR3 2044
+#define IDC_RightClick 2045
+#define IDC_DELAY 2046
+#define IDC_PDEF 2047
+#define IDC_T1 2048
+#define IDC_T2 2049
+#define IDC_W1 2050
+#define IDC_W2 2051
+#define IDC_W3 2052
+#define IDC_W4 2053
+#define IDC_BROWSE 2054
+#define IDC_VIEW1 2055
+#define IDC_RESET1 2056
+#define IDC_VIEW2 2057
+#define IDC_V1 2058
+#define IDC_V2 2059
+#define IDC_RESET2 2060
+#define IDC_SVCINFO 2061
+#define IDC_GETNAME 2062
+#define IDC_P1 2063
+#define IDC_P2 2064
+#define IDC_P3 2065
+#define IDC_P4 2066
+#define IDC_RESET 2067
+#define IDC_D1 2067
+#define IDC_D2 2068
+#define IDC_D3 2069
+#define IDC_INFO1 2069
+#define IDC_INFOICON 2070
+#define IDC_INFO11 2071
+#define IDC_INFO2 2072
+#define IDC_INFO3 2073
+#define IDC_VARLIST 2074
+#define IDC_INFO4 2075
+#define IDC_INFO5 2076
+#define IDC_PD1 2077
+#define IDC_PD2 2078
+#define IDC_PD3 2079
+#define IDC_INFO6 2079
+#define IDC_TM1 2080
+#define IDC_TM2 2081
+#define IDC_TM3 2082
+#define IDC_TM4 2083
+#define IDC_TM5 2084
+#define IDC_TM6 2085
+#define IDC_TM7 2086
+#define IDC_TM8 2087
+#define IDC_INFO7 2087
+#define IDC_TM9 2088
+#define IDC_INFO8 2089
+#define IDC_INFO9 2090
+#define IDC_INFO10 2091
+#define IDC_INFO12 2092
+#define IDC_INFO13 2093
+#define IDC_MORE 2094
+#define IDC_MOREDETAIL 2095
+#define IDC_DATALIST 2096
+#define IDC_MUPDATE 2097
+#define IDC_MFRAME 2099
+#define IDC_MTOGGLE 2101
+#define IDC_MWEBPAGE 2102
+#define IDC_MTEXT 2103
+#define IDC_STEP1 2107
+#define IDC_STEP2 2108
+#define IDC_STEP3 2109
+#define IDC_STEP4 2110
+#define IDC_INFOLIST 2117
+#define IDC_RELOADINI 2118
+#define IDC_MEMUSED 2119
+#define IDC_INICOUNT 2120
+#define IDC_AVATARSPIN 2124
+#define IDC_SEARCHCITY 2125
+#define IDC_HEADERBAR 2126
+#define OIC_HAND 32513
+#define OIC_QUES 32514
+#define OIC_BANG 32515
+#define OIC_NOTE 32516
+#define IDM_M1 40002
+#define IDM_M2 40003
+#define IDM_M3 40004
+#define IDM_M4 40005
+#define IDM_M5 40006
+#define IDM_M6 40007
+#define IDM_M7 40008
+#define IDM_M8 40009
+#define ID_T1 40010
+#define ID_T2 40011
+#define ID_MPREVIEW 40020
+#define ID_MRESET 40021
+#define IDC_STATIC -1
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NO_MFC 1
+#define _APS_NEXT_RESOURCE_VALUE 226
+#define _APS_NEXT_COMMAND_VALUE 40030
+#define _APS_NEXT_CONTROL_VALUE 2128
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/plugins/weather/resource.rc b/plugins/weather/resource.rc
new file mode 100644
index 0000000000..4cac31dfe1
--- /dev/null
+++ b/plugins/weather/resource.rc
@@ -0,0 +1,464 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include <windows.h>
+#include "version.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Neutral resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU)
+LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
+#pragma code_page(1252)
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_BRIEF DIALOGEX 0, 0, 245, 231
+STYLE DS_SETFONT | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
+EXSTYLE WS_EX_WINDOWEDGE | WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ CONTROL "",IDC_HEADERBAR,"MHeaderbarCtrl",0x0,0,0,245,25
+ CONTROL "",IDC_MTEXT,"RichEdit20A",ES_MULTILINE | ES_READONLY | NOT WS_VISIBLE | WS_VSCROLL | WS_TABSTOP,0,25,244,180,WS_EX_STATICEDGE
+ CONTROL "List1",IDC_DATALIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SORTASCENDING | WS_TABSTOP,0,25,244,180,WS_EX_STATICEDGE
+ PUSHBUTTON "Update",IDC_MUPDATE,10,213,48,13
+ PUSHBUTTON "Brief Info",IDC_MTOGGLE,79,213,48,13
+ PUSHBUTTON "Webpage",IDC_MWEBPAGE,132,213,48,13
+ DEFPUSHBUTTON "Close",IDCANCEL,184,213,48,13
+END
+
+IDD_OPTIONS DIALOGEX 0, 0, 306, 212
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ GROUPBOX "Options",IDC_STATIC,3,0,299,70,WS_GROUP
+ CONTROL "Update weather information on startup",IDC_STARTUPUPD,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,10,219,8
+ CONTROL "Update weather information every",IDC_UPDATE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,19,206,8
+ EDITTEXT IDC_UPDATETIME,231,15,21,12,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER,WS_EX_CLIENTEDGE | WS_EX_STATICEDGE
+ LTEXT "minutes",IDC_STATIC,257,16,45,9
+ CONTROL "Consider weather info updated only when condition and temperature are changed",IDC_UPDCONDCHG,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,28,282,8
+ CONTROL "Remove old data when updating",IDC_REMOVEOLD,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,38,282,8
+ CONTROL "Make the contact italic when weather alert is issued",IDC_MAKEI,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,48,282,8
+ CONTROL "Open URLs in new browser window",IDC_NEWWIN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,57,287,8
+ GROUPBOX "Modes",IDC_STATIC,3,70,300,37
+ CONTROL "Use weather condition as protocol status",IDC_PROTOCOND,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,81,278,8
+ CONTROL "Avatar only mode",IDC_DISCONDICON,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,91,278,8
+ GROUPBOX "Units",IDC_STATIC,3,107,299,70,WS_GROUP
+ LTEXT "Temperature",IDC_STATIC,8,116,53,8
+ CONTROL "Celsius",IDC_T1,"Button",BS_AUTORADIOBUTTON,65,116,40,8
+ CONTROL "Fahrenheit",IDC_T2,"Button",BS_AUTORADIOBUTTON,120,116,47,8
+ LTEXT "Degree sign:",IDC_STATIC,227,116,55,8
+ EDITTEXT IDC_DEGREE,283,116,13,12,ES_AUTOHSCROLL | NOT WS_BORDER,WS_EX_CLIENTEDGE | WS_EX_STATICEDGE
+ LTEXT "Wind",IDC_STATIC,8,125,53,8
+ CONTROL "km/h",IDC_W1,"Button",BS_AUTORADIOBUTTON,65,125,34,8
+ CONTROL "m/s",IDC_W2,"Button",BS_AUTORADIOBUTTON,120,125,34,8
+ CONTROL "mph",IDC_W3,"Button",BS_AUTORADIOBUTTON,176,125,34,8
+ CONTROL "knots",IDC_W4,"Button",BS_AUTORADIOBUTTON,232,125,49,8
+ LTEXT "Visibility",IDC_STATIC,8,134,53,8
+ CONTROL "km",IDC_V1,"Button",BS_AUTORADIOBUTTON,65,134,34,8
+ CONTROL "miles",IDC_V2,"Button",BS_AUTORADIOBUTTON,120,134,34,8
+ LTEXT "Pressure",IDC_STATIC,8,143,53,8
+ CONTROL "kPa",IDC_P1,"Button",BS_AUTORADIOBUTTON,65,143,38,8
+ CONTROL "mb (hPa)",IDC_P2,"Button",BS_AUTORADIOBUTTON,120,143,56,8
+ CONTROL "inches",IDC_P3,"Button",BS_AUTORADIOBUTTON,176,143,38,8
+ CONTROL "mm Hg (torr)",IDC_P4,"Button",BS_AUTORADIOBUTTON,232,143,62,8
+ LTEXT "Day/Month",IDC_STATIC,8,153,53,8
+ CONTROL "No change",IDC_D1,"Button",BS_AUTORADIOBUTTON,65,153,52,8
+ CONTROL "2 chars",IDC_D2,"Button",BS_AUTORADIOBUTTON,120,153,56,8
+ CONTROL "3 chars",IDC_D3,"Button",BS_AUTORADIOBUTTON,176,153,56,8
+ CONTROL "Do not append units to values",IDC_DONOTAPPUNITS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,164,144,8
+ CONTROL "Do not display fractional values",IDC_NOFRAC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,155,165,146,8
+ GROUPBOX "Frame",IDC_STATIC,3,177,300,29
+ EDITTEXT IDC_AVATARSIZE,11,187,29,14,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER,WS_EX_CLIENTEDGE | WS_EX_STATICEDGE
+ CONTROL "",IDC_AVATARSPIN,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,28,187,11,14
+ LTEXT "Avatar size",IDC_STATIC,42,190,85,9
+END
+
+IDD_EDIT DIALOGEX 0, 0, 241, 226
+STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+EXSTYLE WS_EX_CONTROLPARENT
+CAPTION "Edit Weather Station"
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ GROUPBOX "Weather Station",IDC_STATIC,5,7,231,46
+ LTEXT "City name",IDC_STATIC,12,21,57,8,SS_CENTERIMAGE
+ EDITTEXT IDC_NAME,69,19,146,12,ES_AUTOHSCROLL
+ LTEXT "ID",IDC_STATIC,12,37,57,8,SS_CENTERIMAGE
+ EDITTEXT IDC_ID,69,35,146,12,ES_AUTOHSCROLL
+ GROUPBOX "Log Information",IDC_STATIC,5,55,231,53
+ CONTROL "Use internal history",IDC_Internal,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,68,218,8
+ CONTROL "Use external file",IDC_External,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,80,98,8
+ CONTROL "Overwrite file upon update",IDC_Overwrite,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,119,80,111,8
+ LTEXT "Path:",IDC_STATIC,25,93,37,8,SS_CENTERIMAGE
+ EDITTEXT IDC_LOG,69,91,146,12,ES_AUTOHSCROLL | ES_READONLY
+ CONTROL "6",IDC_BROWSE,"MButtonClass",WS_TABSTOP,217,91,13,12,WS_EX_NOACTIVATE | 0x10000000L
+ GROUPBOX "Link Settings",IDC_STATIC,5,110,231,44
+ LTEXT "More Info URL",IDC_STATIC,12,123,57,8
+ EDITTEXT IDC_IURL,69,121,131,12,ES_AUTOHSCROLL
+ CONTROL "6",IDC_VIEW1,"MButtonClass",WS_TABSTOP,202,121,13,12,WS_EX_NOACTIVATE | 0x10000000L
+ CONTROL "6",IDC_RESET1,"MButtonClass",WS_TABSTOP,217,121,13,12,WS_EX_NOACTIVATE | 0x10000000L
+ LTEXT "Weather Map",IDC_STATIC,12,138,57,8
+ EDITTEXT IDC_MURL,69,137,131,12,ES_AUTOHSCROLL
+ CONTROL "6",IDC_VIEW2,"MButtonClass",WS_TABSTOP,202,137,13,12,WS_EX_NOACTIVATE | 0x10000000L
+ CONTROL "6",IDC_RESET2,"MButtonClass",WS_TABSTOP,217,137,13,12,WS_EX_NOACTIVATE | 0x10000000L
+ GROUPBOX "Other Options",IDC_STATIC,5,157,231,46
+ CONTROL "Set as default station",IDC_DEFA,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,168,218,8
+ CONTROL "Disable automatic update for this station",IDC_DAutoUpdate,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,179,218,8
+ CONTROL "Disable PopUp for this station",IDC_DPop,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,190,218,8
+ PUSHBUTTON "Change",IDC_CHANGE,57,207,46,14
+ DEFPUSHBUTTON "Cancel",IDCANCEL,136,207,46,14
+ CONTROL "",IDC_SVCINFO,"MButtonClass",WS_TABSTOP,217,35,13,12,WS_EX_NOACTIVATE | 0x10000000L
+ CONTROL "",IDC_GETNAME,"MButtonClass",WS_TABSTOP,217,19,13,12,WS_EX_NOACTIVATE | 0x10000000L
+END
+
+IDD_POPUP DIALOGEX 0, 0, 312, 182
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_CHILD
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ GROUPBOX "PopUp Options",IDC_STATIC,6,5,156,54
+ CONTROL "Enable popups",IDC_E,"Button",BS_AUTOCHECKBOX | BS_NOTIFY | WS_TABSTOP,15,15,143,9
+ CONTROL "Popup only when condition changes",IDC_CH,"Button",BS_AUTOCHECKBOX | BS_NOTIFY | WS_TABSTOP,15,44,140,10
+ GROUPBOX "Colours",IDC_STATIC,168,5,139,54
+ CONTROL "",IDC_BGCOLOUR,"ColourPicker",WS_TABSTOP,177,16,39,11
+ LTEXT "Background colour",IDC_STATIC,223,18,78,8,SS_CENTERIMAGE
+ CONTROL "",IDC_TEXTCOLOUR,"ColourPicker",WS_TABSTOP,177,30,39,11
+ LTEXT "Text colour",IDC_STATIC,223,31,80,8,SS_CENTERIMAGE
+ CONTROL "Use Windows colours",IDC_USEWINCOLORS,"Button",BS_AUTOCHECKBOX | BS_NOTIFY | WS_TABSTOP,177,43,125,13
+ GROUPBOX "Popup Actions",IDC_STATIC,6,63,155,46
+ LTEXT "Left Click",IDC_STATIC,15,77,40,8
+ CONTROL "",IDC_LeftClick,"MButtonClass",WS_TABSTOP,59,76,95,9,WS_EX_NOACTIVATE | 0x10000000L
+ LTEXT "Right Click",IDC_STATIC,15,93,42,8
+ CONTROL "",IDC_RightClick,"MButtonClass",WS_TABSTOP,59,92,95,9,WS_EX_NOACTIVATE | 0x10000000L
+ GROUPBOX "Popup Delay",IDC_STATIC,167,63,141,46
+ CONTROL "Delay",IDC_PD3,"Button",BS_AUTORADIOBUTTON,177,74,53,8
+ EDITTEXT IDC_DELAY,233,73,36,12,ES_RIGHT | ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER,WS_EX_STATICEDGE
+ LTEXT "seconds",IDC_STATIC,272,73,34,10
+ CONTROL "From PopUp plugin",IDC_PD1,"Button",BS_AUTORADIOBUTTON,177,85,110,8
+ CONTROL "Permanent",IDC_PD2,"Button",BS_AUTORADIOBUTTON,177,96,110,8
+ GROUPBOX "Popup Text",IDC_STATIC,6,112,302,66
+ LTEXT "Popup Title",IDC_STATIC,15,127,56,9
+ EDITTEXT IDC_PTitle,74,124,163,12,ES_AUTOHSCROLL
+ LTEXT "Popup Text",IDC_STATIC,15,142,55,9
+ EDITTEXT IDC_PText,73,140,164,31,ES_MULTILINE | ES_AUTOHSCROLL | ES_WANTRETURN | WS_VSCROLL
+ CONTROL "Variables",IDC_VAR3,"MButtonClass",WS_TABSTOP,244,124,47,12,WS_EX_NOACTIVATE | 0x10000000L
+ CONTROL "Default",IDC_PDEF,"MButtonClass",WS_TABSTOP,244,141,47,12,WS_EX_NOACTIVATE | 0x10000000L
+ CONTROL "Preview",IDC_PREVIEW,"MButtonClass",WS_TABSTOP,244,158,47,12,WS_EX_NOACTIVATE | 0x10000000L
+ CONTROL "Updates",IDC_POP1,"Button",BS_AUTOCHECKBOX | BS_NOTIFY | WS_TABSTOP,29,24,64,9
+ CONTROL "Alerts",IDC_POP2,"Button",BS_AUTOCHECKBOX | BS_NOTIFY | WS_TABSTOP,29,34,64,9
+ CONTROL "Errors",IDC_W,"Button",BS_AUTOCHECKBOX | BS_NOTIFY | WS_TABSTOP,97,24,54,9
+END
+
+IDD_TEXTOPT DIALOGEX 0, 0, 309, 228
+STYLE DS_SETFONT | DS_FIXEDSYS | DS_CENTER | WS_CHILD | WS_VISIBLE
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ CONTROL "Contact List",IDC_TM1,"MButtonClass",WS_TABSTOP | 0x100,2,9,58,9,WS_EX_WINDOWEDGE | WS_EX_NOACTIVATE | 0x10000000L
+ EDITTEXT IDC_CTEXT,64,8,139,12,ES_AUTOHSCROLL
+ CONTROL "Brief Info Title",IDC_TM2,"MButtonClass",WS_TABSTOP,2,41,58,9,WS_EX_WINDOWEDGE | WS_EX_NOACTIVATE | 0x10000000L
+ EDITTEXT IDC_BTITLE,64,40,139,12,ES_AUTOHSCROLL
+ CONTROL "Brief Info",IDC_TM3,"MButtonClass",WS_TABSTOP,2,55,58,9,WS_EX_WINDOWEDGE | WS_EX_NOACTIVATE | 0x10000000L
+ EDITTEXT IDC_BTEXT,64,54,139,44,ES_MULTILINE | ES_AUTOVSCROLL | ES_WANTRETURN | WS_VSCROLL
+ CONTROL "Note Text",IDC_TM4,"MButtonClass",WS_TABSTOP,2,101,58,9,WS_EX_WINDOWEDGE | WS_EX_NOACTIVATE | 0x10000000L
+ EDITTEXT IDC_NTEXT,64,100,139,44,ES_MULTILINE | ES_AUTOVSCROLL | ES_WANTRETURN | WS_VSCROLL
+ CONTROL "Extra Text",IDC_TM5,"MButtonClass",WS_TABSTOP,2,147,58,9,WS_EX_WINDOWEDGE | WS_EX_NOACTIVATE | 0x10000000L
+ EDITTEXT IDC_XTEXT,64,146,139,44,ES_MULTILINE | ES_AUTOVSCROLL | ES_WANTRETURN | WS_VSCROLL
+ CONTROL "External Log",IDC_TM6,"MButtonClass",WS_TABSTOP,2,193,58,9,WS_EX_WINDOWEDGE | WS_EX_NOACTIVATE | 0x10000000L
+ EDITTEXT IDC_ETEXT,64,192,139,12,ES_AUTOHSCROLL
+ CONTROL "History Log",IDC_TM7,"MButtonClass",WS_TABSTOP,2,208,58,9,WS_EX_WINDOWEDGE | WS_EX_NOACTIVATE | 0x10000000L
+ EDITTEXT IDC_HTEXT,64,207,139,12,ES_AUTOHSCROLL
+ GROUPBOX "Variable List",IDC_STATIC,206,4,99,198
+ LTEXT "",IDC_VARLIST,213,15,86,158
+ CONTROL "More Variables",IDC_MORE,"MButtonClass",WS_TABSTOP,214,188,76,9,WS_EX_WINDOWEDGE | WS_EX_NOACTIVATE | 0x10000000L
+ CONTROL "Reset",IDC_RESET,"MButtonClass",WS_TABSTOP,222,208,61,12,WS_EX_WINDOWEDGE | WS_EX_NOACTIVATE | 0x10000000L
+ EDITTEXT IDC_BTITLE2,64,24,139,12,ES_AUTOHSCROLL
+ CONTROL "Status Message",IDC_TM8,"MButtonClass",WS_TABSTOP | 0x100,2,25,58,9,WS_EX_WINDOWEDGE | WS_EX_NOACTIVATE | 0x10000000L
+END
+
+IDD_USERINFO DIALOGEX 0, 0, 222, 132
+STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ ICON "",IDC_INFOICON,16,15,20,20,SS_CENTERIMAGE
+ LTEXT "",IDC_INFO1,12,8,193,10
+ LTEXT "Sunset",IDC_STATIC,112,58,54,8
+ LTEXT "Feel-like",IDC_STATIC,12,46,39,8
+ LTEXT "Today's Low",IDC_STATIC,112,82,54,8
+ LTEXT "Wind",IDC_STATIC,12,70,39,8
+ LTEXT "Today's High",IDC_STATIC,112,70,54,8
+ LTEXT "Sunrise",IDC_STATIC,112,46,54,8
+ LTEXT "",IDC_INFO11,12,121,195,9
+ LTEXT "Dewpoint",IDC_STATIC,12,94,39,8
+ LTEXT "Pressure",IDC_STATIC,12,58,39,8
+ GROUPBOX "",IDC_STATIC,4,36,211,84
+ GROUPBOX "",IDC_STATIC,4,1,211,35
+ EDITTEXT IDC_INFO2,42,20,165,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
+ EDITTEXT IDC_INFO3,51,46,57,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
+ EDITTEXT IDC_INFO4,51,58,57,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
+ EDITTEXT IDC_INFO5,51,70,56,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
+ EDITTEXT IDC_INFO6,51,94,56,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
+ EDITTEXT IDC_INFO7,166,46,41,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
+ EDITTEXT IDC_INFO8,166,58,41,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
+ EDITTEXT IDC_INFO9,166,70,41,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
+ EDITTEXT IDC_INFO10,166,82,41,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
+ LTEXT "Humidity",IDC_STATIC,12,82,39,8
+ EDITTEXT IDC_INFO12,51,82,56,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
+ LTEXT "Visibility",IDC_STATIC,12,106,39,8
+ EDITTEXT IDC_INFO13,51,106,56,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
+ CONTROL "More...",IDC_MOREDETAIL,"MButtonClass",WS_TABSTOP,129,104,61,12,WS_EX_WINDOWEDGE | WS_EX_NOACTIVATE | 0x10000000L
+END
+
+IDD_SETUP DIALOGEX 0, 0, 244, 146
+STYLE DS_SETFONT | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+EXSTYLE WS_EX_CONTROLPARENT
+CAPTION "Weather Protocol INI Setup"
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ CONTROL "Weather Protocol INI Setup\nInstall and load your weather ini file here",IDC_HEADERBAR,
+ "MHeaderbarCtrl",0x0,0,0,243,28
+ CTEXT "Weather Protocol cannot find any weather INI file stored in your computer. To setup weather INI and add weather stations, please follow the steps:",IDC_STATIC,11,32,222,26
+ CONTROL "Click here to download a weather ini file from Miranda file listing",IDC_STEP1,
+ "MButtonClass",WS_TABSTOP,5,62,234,12,WS_EX_WINDOWEDGE | 0x800000L
+ CONTROL "Extract the weather ini file from archive to this directory",IDC_STEP2,
+ "MButtonClass",WS_TABSTOP,5,74,234,12,WS_EX_WINDOWEDGE | 0x800000L
+ CONTROL "Click here to load the data from the new ini file into memory",IDC_STEP3,
+ "MButtonClass",WS_TABSTOP,5,86,234,13,WS_EX_WINDOWEDGE | 0x800000L
+ CONTROL "Add new weather station and close this dialog",IDC_STEP4,
+ "MButtonClass",WS_TABSTOP,5,99,234,12,WS_EX_WINDOWEDGE | 0x800000L
+ PUSHBUTTON "Close",IDCANCEL,95,122,48,13
+ CONTROL "",IDC_MFRAME,"Static",SS_ETCHEDHORZ,0,117,244,1
+END
+
+IDD_INFO DIALOGEX 0, 0, 225, 155
+STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_SYSMENU
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ CONTROL "",IDC_INFOLIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,7,210,115
+ LTEXT "Total INI files",IDC_STATIC,7,125,95,8
+ LTEXT "Total memory used",IDC_STATIC,7,138,92,8
+ LTEXT "",IDC_INICOUNT,104,125,30,10,SS_SUNKEN
+ LTEXT "",IDC_MEMUSED,104,138,29,10,SS_SUNKEN
+ PUSHBUTTON "Reload INI",IDC_RELOADINI,145,128,64,18
+END
+
+IDD_SEARCHCITY DIALOGEX 0, 0, 114, 55
+STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_SYSMENU
+EXSTYLE WS_EX_TRANSPARENT | WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ EDITTEXT IDC_SEARCHCITY,3,18,103,12,0,WS_EX_CLIENTEDGE
+ LTEXT "City:",IDC_STATIC,6,7,99,8
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+ IDD_BRIEF, DIALOG
+ BEGIN
+ RIGHTMARGIN, 241
+ BOTTOMMARGIN, 226
+ END
+
+ IDD_OPTIONS, DIALOG
+ BEGIN
+ VERTGUIDE, 12
+ BOTTOMMARGIN, 209
+ END
+
+ IDD_POPUP, DIALOG
+ BEGIN
+ RIGHTMARGIN, 306
+ END
+
+ IDD_TEXTOPT, DIALOG
+ BEGIN
+ RIGHTMARGIN, 308
+ END
+
+ IDD_SETUP, DIALOG
+ BEGIN
+ BOTTOMMARGIN, 140
+ END
+
+ IDD_INFO, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 217
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 148
+ END
+
+ IDD_SEARCHCITY, DIALOG
+ BEGIN
+ RIGHTMARGIN, 113
+ BOTTOMMARGIN, 54
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Menu
+//
+
+IDR_PMENU MENU
+BEGIN
+ POPUP "Menu"
+ BEGIN
+ MENUITEM "Dismiss PopUp", IDM_M1
+ MENUITEM "Open brief information", IDM_M2
+ MENUITEM "Open complete forecast", IDM_M3
+ MENUITEM "Open weather map", IDM_M4
+ MENUITEM "View history", IDM_M5
+ MENUITEM "Open log file", IDM_M6
+ MENUITEM "Show user menu", IDM_M7
+ MENUITEM "Show user detail", IDM_M8
+ END
+END
+
+IDR_TMENU MENU
+BEGIN
+ POPUP "Menu"
+ BEGIN
+ MENUITEM "To old setting", ID_T1
+ MENUITEM "To default", ID_T2
+ END
+END
+
+IDR_TMMENU MENU
+BEGIN
+ POPUP "Menu"
+ BEGIN
+ MENUITEM "Preview", ID_MPREVIEW
+ MENUITEM "Reset", ID_MRESET
+ END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_ICON ICON "res\\icon.ico"
+IDI_UPDATE ICON "res\\update.ico"
+IDI_READ ICON "res\\more.ico"
+IDI_S ICON "res\\brief.ico"
+IDI_LOG ICON "res\\log.ico"
+IDI_EDIT ICON "res\\edit.ico"
+IDI_MAP ICON "res\\map.ico"
+IDI_POPUP ICON "res\\popup.ico"
+IDI_NOPOPUP ICON "res\\popup_no.ico"
+IDI_UPDATE2 ICON "res\\update2.ico"
+IDI_DISABLED ICON "res\\disabled.ico"
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include <windows.h>\r\n"
+ "#include ""version.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION __FILEVERSION_STRING
+ PRODUCTVERSION __FILEVERSION_STRING
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "CompanyName", "borkra, noname"
+ VALUE "FileDescription", "Miranda Weather Protocol"
+ VALUE "FileVersion", __VERSION_STRING
+ VALUE "InternalName", "Weather Protocol"
+ VALUE "LegalCopyright", "Copyright © 2005 - 2010 Boris Krasnovskiy All Rights Reserved"
+ VALUE "OriginalFilename", "weather.dll"
+ VALUE "ProductName", "Weather Protocol"
+ VALUE "ProductVersion", __VERSION_STRING
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // Neutral resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/plugins/weather/sample_ini.ini b/plugins/weather/sample_ini.ini
new file mode 100644
index 0000000000..dc36eda754
--- /dev/null
+++ b/plugins/weather/sample_ini.ini
@@ -0,0 +1,421 @@
+[Weather 0.3.x Update Data 1.4]
+
+; This file contains the information required for the weather protocol to obtain update.
+; For the plugin to function properly, at least one of these file must be present.
+; The proper location of these files is: plugins\weather
+
+; Note that for the entire file, DO NOT put spaces before or after the "=". The groups
+; and setting names (for example, [Header] and Name) are not case sensitive; however,
+; the values set for each settings ARE case sensitive.
+
+; Also note that the first line of this file must be either one of the following:
+; [Weather 0.3.x Update Data] (min. req. v0.3.0.0)
+; [Weather 0.3.x Update Data 1.1] (min. req. v0.3.1.8)
+; [Weather 0.3.x Update Data 1.1a] (min. req. v0.3.2.8)
+; [Weather 0.3.x Update Data 1.2] (min. req. v0.3.5.0)
+; [Weather 0.3.x Update Data 1.3] (min. req. v0.3.8.0)
+; [Weather 0.3.x Update Data 1.4] (min. req. v0.3.8.12)
+
+; Minimun version for not crashing Miranda (Set to this version to prevent the ini from
+; loading in an old version of weather plugin and crash Miranda)
+; 1.1a String longer than 256 characters.
+; 1.1 More than 16 data items in the ini
+; Not using [/...] footer at the end of the list
+; 1.0 All other features
+
+; Minimun version for using the new features (Set to this version to prevent invalid data
+; for user with old version of weather plugin. However, the other features still works)
+; 1.4 Using "Cookie="
+; 1.3 Using "Update Url2=" & "Update Url3="
+; 1.2 Using the operation "Break Data="
+; Using the setting "Hidden=" for each data item
+; Assign weather icons from ini
+; 1.1a Support for the units: Day, Month, %, Deg, Cond
+; 1.1 Using the operation "Set Data="
+; 1.0 All other features
+
+; Revision history:
+; 1.4 (Updated in v0.3.8.12)
+; New "Cookie="
+; 1.3 (Updated in v0.3.8.0)
+; New "Update Url2=" & "Update Url3="
+; 1.2 (Updated in v0.3.5.0; minimun req. v0.3.5.0)
+; New operation "Break Data="
+; New setting "Hidden=" that hide the data item from the mor data list
+; Weather icon assignment from the ini
+; 1.1a (Updated in v0.3.4.0; minimun req. v0.3.2.8)
+; Support for Day, Month units
+; 1.1a (Updated in v0.3.3.0; minimun req. v0.3.2.8)
+; Support the %, Deg, Cond units
+; 1.1a (For v0.3.2.8; minimun req. v0.3.2.8)
+; Now the string can be unlimited long (at least when it's within 4096 characters)
+; 1.1 (For v0.3.2.0; minimun req. v0.3.1.8)
+; No more need to use [/...] headers (now it just like a normal INI file)
+; Support more weather data, and the number of data is no longer limited to 16
+; New operation "Set Data=" that assign data items without download the info
+; 1.0 (For v0.3.0.0; minimun req. v0.3.0.0)
+; Initial version.
+
+; ======================================================================================
+
+; INI Headers
+
+[Header]
+; The name field contains the string that will appear to the user. Please be unique.
+; (for example, "Yahoo Weather")
+Name=
+
+; The internal name is the string that will be used to set the weather ID, and are used
+; internally to obtain the weather update information. This string should be short and
+; unique.
+; (for example, "yw" for "Yahoo Weather")
+Internal Name=
+
+; The following 3 fields are used in the plugin for INI information only, but it also
+; gives user some information about the file.
+Description=
+Author=
+Version=
+
+; For the following three default fields, %s is used for station ID (the one with the
+; internal name taken away, for example, CAXX0001)
+[Default]
+; The default URL for getting more weather information from contact menu or brief info
+; dialog. This setting is the default one assigned to the weather contact when it is
+; added, but can be changed by user in the Edit Settings dialog.
+Default URL=
+
+; The default URL for getting weather map from contact menu. Same as above.
+Default Map=
+
+; The URL for retrieving weather updates.
+Update URL=
+Update URL2=
+Update URL3=
+Update URL4=
+
+; Set cookie(s) when retrieving weather updates.
+Cookie=
+
+; ======================================================================================
+
+; Weather Data Fields
+
+; The following section list the data fields that are used to assign the data to be stored
+; in the database. These fields should be placed in the order of appearance in the
+; download information. For each item searched, the string before the item are discarded
+; so if the order is wrong, no information can be obtained from the latter item.
+
+; Format (not all settings are necessary):
+; [Field Name]
+; Start=
+; End=
+; Set Data=
+; Break Data=
+; Source=
+; Unit=
+; Hidden=
+
+; Default Fields:
+; [Condition] Current condition, to assign condition icon
+; [Update] For display of the update time of the weather data
+; [Temperature] Current temperature
+; [Feel] Feel-like temperature
+; [High] Today's high
+; [Low] Today's low
+; [Sunrise] Sun rise time
+; [Sunset] Sun set time
+; [Wind Direction] Wind direction (not including speed)
+; Be careful to consider the no wind situation (ie. calm)
+; [Wind Speed] The speed of the wind
+; [Pressure] Barometer pressure
+; [Visibility] Visibility, if the value is 0 or non-numerical value, then unit conversion
+; for this will not run and original string is retained
+; [Humidity] Humidity, without a % sign.
+
+; Special Fields:
+; [Alert]
+; Special item for weather alert.
+; If the data retrieved for this field is non-empty, then a special alert popup will
+; display and the city on the contact list will be in a special state (using the
+; setting for "Contact to whom you have a different visibility".
+; This will be reset to normal once the alert field becomes empty.
+; [Ignore]
+; Special item for the plugin to ignore what the value it gets and all errors when
+; getting it. The value obtained for this field will not be written into the
+; database, and no popup and notification will be raised. This is useful to skip
+; some specific text or end the download script. Multiple placement of this field
+; is allowed.
+; Note: For prevent the popup of error message, v0.3.2.11 is required
+
+; Custom Fields:
+; [%name%]
+; Where %name% can be any string you want.
+
+
+; Settings:
+; Settings for obtaining data: "Start=", "End=", "Set Data=", "Break Data=", "Source="
+
+; There are 3 ways for the plugin to obtain the information string:
+; 1. Parse directly from the webpage by specifying start and end strings. Note that these
+; strings are case sensitive.
+
+; When parsing the information, the following items are removed:
+; HTML tags example: <b> </b>
+; symbols example: &nbsp;
+; linefeed and tabs
+; multiple spaces, spaces at the beginning and at the end of the string
+; Also, if the start field is blank, that means the information starts immediately
+; after the string from the last "End=" field. If the end field is blank, that means
+; the information ends at the first space the plugin encounters (even if it is inside
+; a HTML tag).
+
+; An example, for parsing
+; "<sth before>Partly <!-- something in middle -->&nbsp; Cloudy<sth after>
+; The code to give "Partly Cloudy" (without quotation):
+; [Condition]
+; Start=<sth before>
+; End=<sth after>
+
+; 2. Concatenate strings, using "Set Data=", can merge various string together by placing
+; them around the operator " & " (without the quotation mark but with the 2 spaces).
+; For the variable strings (ie. the data item retrieved previously), use []
+; For constant strings, use ""
+
+; For example, merging two condition strings "Condition 1" and "Condition 2":
+; [Condition]
+; Set Data=[Condition 1] & " and " & [Condition 2]
+
+; Another example, copy the content of "Condition
+; [Copy of Condition]
+; Set Data=[Condition]
+
+; 3. Break a string into 2, using "Break Data=", by specifying the string in between the
+; two substrings. The first half will store into the name specify by the header, and
+; the second half will be specified by "End="
+
+; An example, to reverse what we did in Example 2 (the two condition strings):
+; [Condition 1]
+; Break Data= and
+; Source=Condition
+; End=Condition 2
+
+; Other Settings:
+; Unit=
+; Specify the unit for the data, for use in unit conversion. The conversion to use
+; depends on the value assigned.
+; For temperature conversion: C, F, K
+; For speed conversion: km/h, m/s, mph, knots
+; For pressure conversion: hPa, kPa, mb, torr, mm, in
+; For distance conversion: km, miles
+; For adding a percent sign at the end: %
+; For adding a degree sign at the end: Deg
+; Convert condition str to proper case: Cond
+; For weekday string length: Day
+; For month string length: Month
+
+; Hidden=
+; Acceptable values: true, false
+; Using this on any field will prevent it from being displayed in the "More Info"
+; list, but its value will still be stored in the database.
+
+; Url=
+; Acceptable values: 1, 2, 3
+; Specifies the url on where to look for data item
+; If parameter is not specified item is searched on all urls, the last found will be used
+
+; Here's an example:
+[Condition]
+Start=
+End=
+Unit=Cond
+
+[Temperature]
+Start=
+End=
+Unit=C
+
+[Humidity TEMP]
+Start=
+End=
+Hidden=true
+
+[Humidity]
+Set Data=[Humidity TEMP] & "%"
+
+; - or -
+
+[Humidity]
+Start=
+End=
+Unit=%
+
+
+; ======================================================================================
+
+; The setting for find and add contacts.
+
+; ID search is used when the user type in the ID in the "Station ID" field and pressed
+; "Search"
+[ID Search]
+
+; This can be "true" or "false" (without quotation, not case sensitive)
+; If this is set to "false", all the following strings are ignored and the ID are NOT
+; going to search for this weather service.
+; If this field is set to FALSE, no matter what the user type for station ID, the
+; plugin will always return a result with station name empty and ID the same as what
+; the user has typed.
+Available=
+
+; The URL for ID search. Note that %s is used for placing the ID.
+Search URL=
+
+; The string appeared in the downloaded information when there is no match
+; (ie. "Document not found")
+; If this string is found while searching, the search process quit and return no result.
+Not Found Str=
+
+; Similar to weather information retrival above. This is the string preceeding the
+; station name obtained from searching. Note that the parsing is the same as above, and
+; spaces can be used.
+Name Start=
+
+; This is what's after the station name.
+Name End=
+
+; END ID SEARCH
+
+; Name search is used when the user type in any of the name field (Nick, First, Last) and
+; click on the "search" button.
+[Name Search]
+
+; This can be "true" or "false" (without quotation, not case sensitive)
+; If this is set to "false", then the plugin igmore the information stated in the Single
+; fields (ie. from "Single Name Start" to "Single ID End")
+Single Result=
+
+; This can be "true" or "false" (without quotation, not case sensitive)
+; If this is set to "false", then the plugin igmore the information stated in the Multiple
+; fields (ie. from Multiple Name Start" to Multiple ID End")
+; Note that if both single and multiple are disabled, the Name search are disabled for
+; this weather service.
+Multiple Result=
+
+; The URL for doing the name search. %s will be replaced by the station name input from
+; the user.
+Search URL=
+
+; The string appeared in the downloaded information when there is no match
+; (ie. "Document not found")
+; If this string is found while searching, the search process quit and return no result.
+Not Found Str=
+
+; This field determines whether the search will return a single result or multiple result
+; If the string stated in this field is found and Single Result is enabled from above, the
+; settings for single result will be used. Otherwise, the settings in multiple result
+; will be used.
+Single Result Str=
+
+; These fields are for the single result
+
+; Determine which item is the first to appear in the download search result file
+; This field can be ID or Name (not case sensitive).
+; For example, if ID is used here, it means that station ID appears before the station
+; name in the downloaded document.
+Single First=
+
+; The start and end string for station name. Parsing using the same way as discribed
+; above for weather information.
+; Note that if both fields are empty, then whatever the user type into the search field
+; will be used for the station name.
+Single Name Start=
+Single Name End=
+
+; The start and end string for station name. Parsing using the same way as discribed
+; above for weather information.
+Single ID Start=
+Single ID End=
+
+; The multiple result is similar to the single result as described above.
+; For this search, the plugin will loop until no more Name's and ID's can be founded
+; in the downloaded file.
+Mult First=
+Mult Name Start=
+Mult Name End=
+Mult ID Start=
+Mult ID End=
+
+; END NAME SEARCH
+
+; For a workaround of URL forwarding issue:
+; If the page retrieved contains URL forward (ie. the 302 code), the download content
+; will appears as:
+; Moved/Location: <forwarded URL>
+; This might be useful for writing the start/end string settings for the single result
+; Name Search.
+; A typical use of this is:
+; Single Result Str=Moved/Location:
+; Single First=ID (this isn't really matter)
+; Single Name Start=
+; Single Name End= (this will use whatever user type in as stn name)
+; Single ID Start=/newpages/ (what's before the station ID in the URL)
+; Single ID End=.html (what's after the station ID)
+
+; ======================================================================================
+
+; INI Defined Icon Assignments (new in v1.2)
+
+; These assignment will take the highest priority (before the internal and the langpack
+; defined assignment) when matching the condition (icon) to the current condition.
+; These settings are INI specific, which means that the setting in one INI will not affect
+; the stations that are associated to another INI.
+
+; Format:
+; {icon name}={string to search}
+
+; The "icon name" is the icon to assigned with the condition string containing the string
+; specified in "string to search" is found.
+
+; Available icon names are (in order of assigning priority):
+; Lightning, Fog, Snow Shower, Snow, Rain Shower, Rain, Partly Cloudy, Cloudy, Sunny, N/A
+
+; For examples, mimicking what internal icon selection and langpack_defweather do (of
+; course, putting these in an actual INI is not needed and is waste of space and memory).
+
+[Icons]
+Sunny=Sunny
+Sunny=Clear
+Sunny=Fair
+
+Partly Cloudy=Mainly Sunny
+Partly Cloudy=Mainly Clear
+Partly Cloudy=Partly
+Partly Cloudy=Mostly
+Partly Cloudy=Clouds
+
+Cloudy=Cloudy
+Cloudy=Overcast
+
+Rain=Drizzle
+Rain=Rain
+
+Rain Shower=Rain Shower
+Rain Shower=Shower
+
+Snow=Snow
+Snow=Ice
+Snow=Freezing
+Snow=Wintery
+
+Snow Shower=Snow Shower
+Snow Shower=Flurries
+
+Ligntning=Thunder
+Ligntning=T-storm
+
+Fog=Fog
+Fog=Mist
+Fog=Smoke
+Fog=Haze
+Fog=Sand
+Fog=Dust
diff --git a/plugins/weather/version.h b/plugins/weather/version.h
new file mode 100644
index 0000000000..133e5f0818
--- /dev/null
+++ b/plugins/weather/version.h
@@ -0,0 +1,6 @@
+#define __FILEVERSION_STRING 0,3,8,19
+#define __VERSION_STRING "0.3.8.19"
+#define __VERSION_DWORD PLUGIN_MAKE_VERSION(0, 3, 8, 19)
+
+#define BETA FALSE
+#define AUTH "NoName, borkra"
diff --git a/plugins/weather/weather-history.txt b/plugins/weather/weather-history.txt
new file mode 100644
index 0000000000..ff936f56f2
--- /dev/null
+++ b/plugins/weather/weather-history.txt
@@ -0,0 +1,930 @@
+Weather Protocol - Version History
+==================================
+Version 0.3.8.19 2011/09/03
+ - Fixed Brief window update on weather station update
+ - Fixed No ini window no show
+
+Version 0.3.8.18 2010/08/20
+ - Specialized translations for all weather conditions
+ - Fixed possible crashes
+
+Version 0.3.8.17 2010/05/29
+ - Added possibility to add specialized translations for weather conditions
+ format: #condition Weather
+ - Added 32x32 icon support
+ - 32x32 icon is used in a frame in a frame if no avatar present
+ - Added support for Miranda 0.9 persistent http trasactions
+ - Changed Breif dialog appearence
+ - Fixed translation issues
+ - Fixed keyborad navigation in UserInfo dialog
+ - Requires Miranda 0.8 or higher
+
+Version 0.3.8.16 2009/08/09
+ - Increased allowed size of station id
+ - Removed built-in support for HTTP compression (compression not supported with pre 0.8 Miranda any longer)
+ - Fixed crash with no ini files
+ - x64 port
+
+Version 0.3.8.15 2009/03/22
+ - Added support for gif avatars
+ - Added support for 4 urls per ini
+ - Added supoort for html metadata (utf8)
+ - Fixed rounding with fractional reading display
+ - Added more http redirection support
+ - Allow to draw forced avatar in frame
+
+Version 0.3.8.14 2009/01/10
+ - Fixed Set Data failures
+ - Fixed crashes with http
+ - Fixed http errors processing
+ - Added support for temperature in format -<space><number>
+
+Version 0.3.8.13 2008/12/25
+ - Changed search UI to have more descriptive labels
+ - Documentation updates
+
+Version 0.3.8.12 2008/12/22
+ - Added support for cookies (cakes and ice cream)
+
+Version 0.3.8.10 2008/12/07
+ - Fixed temperature display
+
+Version 0.3.8.9 2008/12/06
+ - Added support for deflate compressed http streams
+ - Fixes for weather crashes
+ - Added option to round all values to nearest integer
+
+Version 0.3.8.8 2008/11/22
+ - Improved formatting for numerical values
+ - Fixed crashes due to compressed http stream
+ - Added support for gzip encoded http stream
+
+Version 0.3.8.7 2008/08/02
+ - Fixed crash for people measuring speed in km/h
+
+Version 0.3.8.6 2008/08/01
+ - Added display fraction of temperature and wind speed when available
+ - Added handling of UTF8 pages (needed for GisMeteo)
+
+Version 0.3.8.5 2008/07/27
+ - Fixed option dialog layout
+ - Fixed ini version display
+ - Fixed memory leak with multiurl ini
+ - Fixed plugin version number
+
+Version 0.3.8.3 2008/07/24
+ - Fixed url tag
+ - Added headers to variable view
+ - Fixed options dialog layout
+
+Version 0.3.8.2 2008/06/08
+ - Fixed ini version display in User Info
+ - Fixes for wind in Weather Underground ini to work correctly
+
+Version 0.3.8.1 2008/05/25
+ - Added ability to parse upto 3 URL per ini file for weather data
+ - Fixed break data and parameters with units
+ - Added ability to skin weather frame with clist_modern ("Main,ID=WeatherFrame")
+ - Added display "nickname" in the first line of the frame
+ - Added avatar display in the weather frame
+
+Version 0.3.7.2 2008/01/19
+ - Fixed updates in normal mode
+ - Fixed option dialog layout
+
+Version 0.3.7.1 2007/12/22
+ - Partial workaround for core HTTP problem
+ - Tabbed option dialog
+
+Version 0.3.7.0 2007/12/21
+ - Added icolib support
+ - Added frames support
+ - New icons by Angeli-Ka
+ - Compatible with Miranda 0.7 and later
+
+Version 0.3.6.5 2007/08/17
+ - Workaround for tray icon
+
+Version 0.3.6.4 2007/07/27
+ - Fixed caching problems
+
+Version 0.3.6.3 2007/07/08
+ - Fixed error message at stratup (with updater)
+ - Increased possible weather variable size
+ - More generic couldy definition
+
+Version 0.3.6.2 2007/06/02
+ - More sensible autoupdate Enable/Disable operation
+
+Version 0.3.6.1 2007/06/01
+ - Fixed popup click action
+ - Fixed translation
+
+Version 0.3.6.0 2007/05/18
+ - New icons by Angeli-Ka
+ - Protocol icons split into separate dll
+ - Option dialog and menus redesign
+ - Instant avatar update
+ - Ini file display name now used as client ID (MirVer)
+ - Moved ini file list into View/Change My Details
+ - Support for new plugin interface
+ - Fixed few parsing issues
+
+Version 0.3.5.19 2007/01/27
+ - Fixed translation
+
+Version 0.3.5.18 2007/01/26
+ - Fixed translation
+ - Fixed resource leaks
+ - Fixed crash
+ - Partial unicode support
+
+Version 0.3.5.17 2007/01/20
+ - Reduced GDI resource utilization
+ - Fixed memory leak with old ini files
+ - Fixed search function for stations with special characters
+
+Version 0.3.5.16 2006/11/27
+ - Fixed units conversion
+ - Fixed memory corruption
+ - Added ability to show clickable links in Brief window
+
+Version 0.3.5.15 2006/11/16
+ - Fixed web page parsing (Wind Speed in Yahoo)
+ - Fixed "No wind" condition handling
+ - Performance improvments for HTTP transfers
+ - Fixed memory corruption
+
+Version 0.3.5.14 2006/10/31
+ - Fixed status message operation
+
+Version 0.3.5.13 2006/10/29
+ - Fixed non english alphabets operation
+ - Fixed Weather condition update issues
+ - Added option to keep station status from reflecting weather condition
+ (should resolve avatar overlay problems with clist modern)
+ - Moved Weather main menu entry into the protocol group
+ - Improvements for forecast window sizing
+
+Version 0.3.5.12 2006/07/23
+ - Fixed non english alphabets operation
+
+Version 0.3.5.11 2006/07/22
+ - Fixed text corruption
+ - Added ability to display avatars for each weather condition
+ - Fixed Win95 operation
+
+Version 0.3.5.10 2006/07/16
+ - Changed Current Date/Time display (%d) according to locale
+ - Changed handling of HTTP redirect requests
+
+Version 0.3.5.9 2006/04/08
+ - Fixed misplaced buttons on forecast view window
+ - Fixed weather history incorrect source
+ - Fixed incorrect PopUp notification text in the menu
+
+Version 0.3.5.8 2005/09/20
+ - Fixed automatic set of deafult station logic failure and as a result crash at power-up
+ - Fixed INI info dialog layout and ini version information
+ - Fixed rare crash on exit
+ - Fixed resource leak
+ - Fixed few memory leaks
+ - Fixed crash at power-up with corrupted ini file
+ - A lot of code robustness updates
+
+Version 0.3.5.7 2005/09/18
+ - Fixed few resource leaks
+ - Fixed gloabal status
+ - Fixed weather alert format
+ - Fixed very rare crash on exit
+
+Version 0.3.5.6 2005/09/14
+ - Fixed few crashes on exit and
+ - A lot of code robustness updates
+ - Updater compatibility
+ - Fixed resource leaks
+
+Version 0.3.5.5 2005/09/11
+ - Fixed crash on exit
+ - Support for custom "Status Messages"
+
+Version 0.3.5.4 2005/09/08
+ - Fixed crash in my User details
+ - Fixed endless "updating user info ..."
+ - Fixed search function regression
+
+Version 0.3.5.3 2005/09/07
+ - Fixed crash at Powerup
+ - Fixed crash on Miranda exit
+ - Fixed numerous other crashes
+ - Fixed numerous memory leaks
+ - Fixed memory corruption
+ - Fixed resource leak
+
+Version 0.3.5.2 2005/09/07
+ - Fixed crash on Miranda exit
+ - Fixed numerous other crashes
+ - Fixed numerous memory leaks
+ - Fixed memory corruption
+ - Fixed resource leak
+
+Version 0.3.5.0 2005/03/21
+ - New Option: Disable update on startup
+ - New Option: Enable/Disable popups by type: update, alert, error
+ - INI Option: Support breaking string
+ - INI Option: Support hidden fields
+ - INI Option: Support icon assignment from ini
+ - Updated sample_ini.ini and translation
+ - Some other minor changes that I can't remember
+
+Version 0.3.4.4 2004/12/28
+ - Load window list correctly, fix problem with brief info and edit dlg not showing
+ - Some internal changes with new service functions
+
+Version 0.3.4.3 2004/12/26
+ - Minor change in INI loading
+
+Version 0.3.4.2 Beta 2004/12/16
+ - Bug fix: Miranda cannot quit after forkthread is used
+ - Bug fix: The unit % does not work anymore
+ - Bug fix: No longer crash when the link settings is not set
+ - Update the weather ini download link to the new location
+
+Version 0.3.4.1 Beta 2004/12/09
+ - ESC now works in weather dialogs
+ - More changes to forkthread
+ - Document updated: weather-translation, sample_ini
+
+Version 0.3.4.0 Beta 2004/11/21
+ - Change the threading to forkthread
+ - New option: Custom status when condition is unavailable
+ - New option: Convert day/month string into 2 char or 3 char format
+ - Some internal changes
+ - Minor change in ini format
+
+Version 0.3.3.17 2004/11/19
+ - Condition translated correctly when writing into database
+ - Correctly restore the windows position for edit setting dialog
+
+Version 0.3.3.16 2004/11/10
+
+Version 0.3.3.15 2004/10/21
+ - Remember the window position for edit settings dialog
+ - Minor change in dialog (I still can't get the close on ESC to work...)
+
+Version 0.3.3.14 Beta 2004/10/20
+ - Fix the crash in option page bug (hopefully)
+ - Fix the support for \n in text input
+ - Minor change in dialog
+
+Version 0.3.3.13 2004/10/16
+ - Another fix for default station
+ - Some changes to reduce database read/write for default station changes
+ - Now the plugin is correctly registered in known module list for DBEditor++
+ - Save the setting for popup and update enable/disable directly after menu click
+ - Some update in readme, more changes in translation (thanks smyle again)
+
+Version 0.3.3.12 2004/10/16
+ - Fix 2 possible crashes regarding default station
+
+Version 0.3.3.11 2004/10/15
+ - Fix a bug with global status
+ - Updated translation list (thanks smyle)
+
+Version 0.3.3.10 2004/10/14
+ - Changes in default station handling, hopefully will fix a crash in option page
+ - Add new sound event: Weather alert
+ - Add new menu item: Add new weather station (call up the find/add dialog)
+ - Document updated: weather_translation.txt
+
+Version 0.3.3.9 2004/09/26
+ - Some changes in code.
+
+Version 0.3.3.8 2004/09/24
+ - Now uses default system text for brief info and setup dialog.
+
+Version 0.3.3.7 (Beta)
+ - Test releases for crash in option page
+
+Version 0.3.3.6 2004/09/24
+ - Add a sound event when weather condition is updated
+ - Use the default system color for brief info and setup dialog
+ - Minor change in unit conversion
+ - Fix in brief info when there is no data for current conditions
+ - Add entry to Database Editor++ known module
+
+Version 0.3.3.5 2004/08/14
+ - Fix apply button in option pages
+ - Fix "Humidity" in default settings
+ - Ignore the sample ini file if it is placed in plugin\weather dir
+ - Minor changes in update timer and option dialog
+
+Version 0.3.3.4 (Beta) 2004/07/23
+ - Fix some bug in text option
+ - Take proto_weather.dll icon into account when auto-assigning icon
+ - Option to disable automatic icon assignment
+ - Few minor changes
+ - Document updated: weather_translation.txt
+
+Version 0.3.3.3 2004/07/21
+ - Automatically set to default weather icon if no custom one is set
+ - Add a ini setup information dialog to help setup weather protocol
+ - Update in brief info now retrieve new data from the internet
+ - Few minor changes
+ - Document updated: weather_translation.txt
+
+Version 0.3.3.2 (Beta) 2004/07/14
+ - Show error detail on update errors
+ - Includes simple set of 16-colors weather icons in the dll file
+ - Option to disable italic display for station with alert issued
+ - Option to disable warning dialog if ini is not found at startup
+ - Attempt to fix the black bar bug in brief info
+ - Fix the bug that shows connecting as weather status
+ - Document updated: weather_translation.txt
+
+Version 0.3.3.1 2004/06/19
+ - Minor change in the brief info dialog
+ - More info items are now translatable
+ - Case conversion in condition to make them translatable (use unit: Cond)
+ - Save window size for the brief info dialog
+ - Fix crash when invalid ID or ini file for the station is not found
+ - Few minor changes
+ - Document updated: sample_ini
+
+Version 0.3.3.0 (Beta) 2004/06/12
+ - A new feature that erase old data while updating for new data
+ - A change in the brief information dialog (thanks micron-x for last seen plugin)
+ - Double click a contact shows brief info dialog (thanks Matrix and JdGordon)
+ - Add brief info title setting
+ - Change in the weather, text, and popup options dialogs
+ - Add reset to default and preview for all display text field
+ - Change the way the plugin handles protocol status
+ - Enable/disable auto-update from the main menu
+ - Reconizes dust conditions and assign a fog icon (thanks Klenje)
+ - Support the units "%" and "Deg"
+ - Fix a crash if miranda32.exe is renamed
+ - Fix crashes in between updating of 2 stations (thanks Targaff)
+ - Update links in the readme and DLL to the new weather category (thanks lynlimz)
+ - Other bug fixes and minor changes
+ - Document updated: weather-translation, langpack_defweather, sample_ini
+
+Version 0.3.2.16 2004/05/27
+ - Reconizes condition in lower case
+ - Few changes.
+
+Version 0.3.2.15 2004/05/24
+ - Now reconizes the condition string "T-storm"
+ - No longer skip hidden weather contact while updating
+ - Bug fix when previewing weather popups
+ - Bug fix in parsing the HTML content (in cases where "&" exists)
+ - Few other minor fixes and changes.
+
+Version 0.3.2.14 2004/05/12
+ - Popup preview include a preview of popup text settings (use default station)
+ - Fix memory leaks in various places.
+
+Version 0.3.2.13 2004/05/08
+ - Changed some linker options to prevent plugin not loading
+
+Version 0.3.2.12 2004/05/08
+ - Assign fog icon to the sand conditions
+
+Version 0.3.2.11 2004/05/07
+ - Really ignore the "Ignore" item in the ini file
+ - Fix crash when unloading ini's (at reload or shutdown)
+ - Change in weather alert popup
+ - Few minor changes
+
+Version 0.3.2.10 2004/05/02
+ - Rebuild using Visual C++
+
+Version 0.3.2.9 2004/04/29
+ - Attempt to fix crash when searching for cities by name
+ - Display a list of custom variables
+ - Fix memory leak when reloading strings from ini files
+ - Changes in the code for parsing weather info and loading ini files
+ - Other minor changes
+
+Version 0.3.2.8 2004/04/28
+ - Fix on loading ini strings, support for v1.1a again
+ - Fix in weather station search
+ - Fix crash when not connected to the internet
+ - Add a new debug function (need DB Editor)
+ - A few other minor fixes and changes
+
+Version 0.3.2.7 2004/04/19
+ - Fixing the crash on startup bug one more time :(
+
+Version 0.3.2.6 2004/04/19
+ - Attempt to fix an crash on startup bug again.
+ - Temporary remove support for v1.1a of the INI file. :(
+
+Version 0.3.2.5 2004/04/19
+ - Attempt to fix an crash on startup bug.
+
+Version 0.3.2.4 2004/04/19
+ - Fix some error while loading weather ini file.
+ - Obtain station name from the net in edit dialog.
+ - Display N/A when temperature is unavail. and the string retrieved is not "N/A"
+ - Some minor changes.
+
+Version 0.3.2.3 2004/04/18
+ - Automatically suppress online notification for all weather contact when upgrade.
+ - Fixed crash when adding new contact.
+ - Fixed crash when importing contact using mContacts.
+ - Some minor changes.
+
+Version 0.3.2.2 2004/04/18
+ - Change the way weather handles status, now properly display NA for def stn.
+ - Protocol status can be changed freely if "Do not display weather conditions
+ as protocol status" is enabled.
+ - More memory leak fixes and crash fixes.
+
+Version 0.3.2.1 2004/04/17
+ - Reduce memory use by more than 60% and fixed some memory leaks
+ - Support a revision of v1.1 ini file (the length string now can be unlimited)
+ - Incrase the maximun text length to 4k (but try keep it as short as possible)
+ - A few minor fixes and changes
+ - Updated readme file.
+
+Version 0.3.2.0 2004/04/12
+ - Support new variable %% (same as \%) and %[..] (see readme)
+ - Now with the complete support of weather INI v1.1
+ - Very basic support of weather alert notifications (if the INI supports it)
+ - Add browse, view webpage, and reset to default buttons edit settings dialog
+ - Interface changes and fixed tab order for all dialogs
+ - Display information for the weather INI files
+ - Some other monor changes and fixes
+ - Updates Read Me, and now it is in HTML format.
+
+Version 0.3.1.8 2004/04/09
+ - "My Notes" text are copied to "Current\WeatherInfo" (might be useful for some plugins)
+ - Increase the length of display texts from 512b to 4k
+ - Bug Fix: when temperature is N/A, display N/A
+ - Bug Fix: rounding in unit conversion, err...
+ - Bug Fix: crash with new ini setting "Set Data="
+
+Version 0.3.1.7 2004/04/08
+ - Now correctly support the new ini files.
+
+Version 0.3.1.6 2004/04/04
+ - Support escape characters "\%" for displaying %
+ - Changes in warning popups
+
+Version 0.3.1.5 2004/04/02
+ - New option: Consider weather info updated only when cond and temp are changed
+ - Support v1.1 of weather ini files - only support loading, but not the new features ;)
+ - Rounding is used when converting units
+ - Attempt to fix the crash on exit and reload weather data bug
+ - The default update time is changed to 20 min
+ - Other minor fixes and changes that I don't remember
+
+Version 0.3.1.1 2004/03/27
+ - Fix the crash when opening brief info dialog
+ - The default for "Support online notification" is on when adding new station
+
+Version 0.3.1.0 2004/03/25
+ - Change the way popup is handled, no longer need to enable the threading option
+ - Manually add station without searching by entering "#" in the ID field
+ - Always provide a search result if the weather service has no ID search available.
+ - Some error handling and popups to prevent crashes.
+ - New hookable event: ME_WEATHER_UPDATED
+ - Bug fix: Translation of retrieved data
+ - Bug fix: Search don't work for city that has more than 1 word
+ - Bug fix: Speed conversion is wrong
+ - Bug fix: weatherch.ini: Crash if adding/updating a station in US Eastern timezone
+ - Updated: weatherch.ini, Read Me, Translation, Sample INI, m_weather.h
+
+Version 0.3.0.1 (Beta) 2004/03/23
+ - Do not update contacts that are hidden from list (see it as "disabled" contacts)
+ - Give error message box when selecting more info and weather map before setting the URL
+ - Bug fix: Find and search contacts (no result found + crashes)
+ - Bug fix: Issue with StartupStatus, now weather will update at least once on startup
+ regardless of what's the setting there.
+ - Bug fix: Visibility unit conversion
+ - Bug fix: Weather contacts appear offline if langpack is installed
+ - Bug fix: Some spelling error
+ - Bug fix: Feel-like temperature can't be displayed by mToolTip
+ - Bug fix: WU: Find and search for station that doesn't have current condition
+ - Updated: All 4 INI files, Read Me, Translation
+
+Version 0.3.0.0 (Beta) 2004/03/22
+ - Combine the weather dll's into one
+ - Using external file for getting update (in plugins\weather directory)
+ - Added user detail page for weather contacts
+ - New and improved option pages
+ - Proxy support (now uses netlib)
+ - Unit conversion for pressure, visibility, and wind
+ - Optimization in the edit setting dialog - Allow multiple window
+ - Changes in brief info dialog - able to open multiple brief info
+ - Reduce the number of DB access for getting settings
+ - Add more variables such as feel-like temperature, pressure
+ - Add menu item for enable/disable popup
+ - Support weather icon determination for site in other languages using langpack
+ - Support for plugin uninstaller
+ - Optimization in weather update - now update using a queue and minimize DB access
+ - Optimizaiton in add/search - now don't do unnecessary searches
+ - Other code optimization and reduce file size
+ - Reload weather update data file from the main menu
+ - Some other major and minor UI change
+ - Remove some useless features
+ - Bug fix: temperature conversion (thanks to sirius)
+ - Bug fix: crash on adding new station
+ - Some minor changes and fixes in webpage downloading.
+ - Includes documentation for INI update data file and icon selection translation.
+ - Major changes in translation strings.
+ - Some update in the readme documentation.
+ - Included in this version:
+ Weather Channel, Weather Underground (both US and International), Yahoo Weather.
+
+Version 0.2.5.2
+
+Version 0.2.5.1 2003/07/19
+ - Minor bug fixes
+
+Version 0.2.5.0 2003/06/09
+ - New feature: short weather information as status message and/or note.
+ - New option: display weather options inside plugin options.
+ - Create a seperate page for text and display options.
+ - Other minor changes and bug fixes
+
+Version 0.2.4.5 2003/06/12
+ - Bug fix: Backup/restore protocol icon (including rebuild icon) if status is hidden.
+ - Bug fix: Popup only condition changes.
+
+Version 0.2.4.4 2003/06/08
+ - Fixed typo in option
+ - Weather underground: Retrieve data for high/low temperature even if
+ current info is unavailable
+ - Minor code change.
+
+Version 0.2.4.3 2003/06/07
+ - Fix weather underground searching station
+
+Version 0.2.4.2 2003/06/06
+ - Fixed weather underground station name display problem.
+ - Changes to make compatible with earlier version in case of downgrading
+ - Reorganize language pack strings.
+
+Version 0.2.4.1 (Beta) 2003/05/28
+ - New preview using the selected timeout value.
+ - Modified timeout warning message box.
+
+Version 0.2.4.0 (Beta) 2003/05/28
+ - Added advanced option page
+ - New option: Popup timeout
+ - Restore the hide icons in status / task bar option
+ - Use old weather information if new data is unavailable
+ - Add the debug setting in advanced option page
+ - Major internal / weather update / DB settings change
+
+Version 0.2.3.13 2003/05/30
+ - Fixed searching weather underground station
+ - Few minor changes
+
+Version 0.2.3.12 2003/05/28
+
+Version 0.2.3.11 (Beta) 2003/05/27
+ - Fixed Weather Channel for the FOURTH time
+
+Version 0.2.3.10 2003/05/27
+ - Third fix for Weather Channel.
+ - Note: If v0.2.3.9 works, there is no need to upgrade
+
+Version 0.2.3.9 2003/05/26
+ - Fixed download from Weather Channel
+ - Few minor changes and updates
+
+Version 0.2.3.8 2003/05/25
+ - Removed some unnecessary popup that causes crash and/or confusion
+ - Minor code change in weather update.
+
+Version 0.2.3.7 (Beta) 2003/05/08
+ - Now compile using latest Miranda source code
+
+Version 0.2.3.6 (Beta) 2003/04/15
+
+Version 0.2.3.5 2003/03/16
+ - Fix in "Do not display weather condition as protocol status" option
+ - Fix in maximun temperature for weather channel plugin.
+
+Version 0.2.3.4 2003/03/16
+
+Version 0.2.3.3 (Beta) 2003/03/10
+ - Remove features that are incompatiable with latest version of Miranda
+ - Bug fix on retrieving weather (again!)
+
+Version 0.2.3.2 (Beta) 2003/02/28
+ - Few minor bug fixes
+
+Version 0.2.3.1 (Beta) 2003/02/17
+ - Bug fix in retrieving high and low temperature.
+ - Other minor fixes.
+
+Version 0.2.3.0 2003/02/05
+ - New option: Do not display default condition as protocol status
+ - Support Miranda Installer
+ - Other minor code changes.
+
+Version 0.2.2.11 2003/01/31
+ - Fixed some weather info parsing problems
+
+Version 0.2.2.10 2003/01/26
+ - Fix some minor errors in weather update
+
+Version 0.2.2.9 2003/01/25
+ - Add some warning messages.
+
+Version 0.2.2.8 (Beta) 2003/01/25
+ - Fixed on popup display.
+ - More infinite loop prevention.
+
+Version 0.2.2.7 2003/01/24
+ - Forget to update version number in last release
+
+Version 0.2.2.6 2003/01/24
+ - Popup only when condition changes now work properly.
+ - Minor bug fix in logging
+ - Smaller file size.
+ - Other minor changes.
+
+Version 0.2.2.5 (Beta) 2003/01/23
+ - Fixed weatherch.dll for new website format.
+
+Version 0.2.2.4 (Beta) 2003/01/18
+ - Minor code change
+
+Version 0.2.2.3 2003/01/16
+
+Version 0.2.2.2 2003/01/15
+ - Show popup action selection when menu is opened.
+ - Bug fix: Modified weather station now can update normally.
+
+Version 0.2.2.1 (Beta) 2003/01/12
+ - Bug fix: Opening menu when click on PopUp.
+ - Added link in main menu to the homepage of weathe source.
+ - New protocol icon.
+
+Version 0.2.2.0 (Beta) 2003/01/11
+ - Move pop-up related options to popup option page.
+ - New option: Set popup title
+ - New option: Specify command for popups when mouse is clicked.
+ - Added variable information popup.
+ - Some UI changes.
+ - Added version info.
+ - Some translation string added / changed.
+
+Version 0.2.1.6 (Beta) 2003/01/09
+ - Shorten code in some functions.
+
+Version 0.2.1.5 2003/01/08
+ - Updated weatherch.dll for data retrieval.
+ - Bug fix: Searching new weather station.
+ - Bug fix: Loading default settings.
+ - Few other minor changes.
+
+Version 0.2.1.3 (Beta) 2003/01/07
+ - Minor bug fix.
+
+Version 0.2.1.2 2003/01/04
+ - New option: Overwrite File upon Update.
+ - Update in translation doc.
+
+Version 0.2.1.1 2003/01/03
+ - Better support for multiline popups.
+ - Minor change in codes and readme document.
+
+Version 0.2.1.0 2002/12/31
+ - New option: Override default URL settings for each contact
+ - Display text are no longer case sensitive.
+ - Prevent opening two dialogs at the same time.
+
+Version 0.2.0.5 2002/12/18
+ - Few minor changes and bug fixes
+
+Version 0.2.0.4 (Beta) 2002/12/15
+ - Bug fix: changing status and popups.
+ - Minor change in weather update.
+
+Version 0.2.0.3 (Beta) 2002/12/14
+ - Bug fix: disable popup st startup.
+ - Other minor changes.
+
+Version 0.2.0.2 (Beta) 2002/12/12
+ - Try to make string compatible between each weather source (not tested)
+ - Bug fix: crash when not connected (not tested)
+ - New weather condition in translation string.
+ - Various other minor bug fixes and changes.
+
+Version 0.2.0.1 (Beta) 2002/12/11
+ - Fix in updating weather information in wunderground.dll
+ - Various other minor bug fixes and changes.
+
+Version 0.2.0.0 (Beta) 2002/12/10
+ - Completed wunderground.dll
+ - Bug fix: Update all weather.
+ - Bug fix: Weather update in weatherch.dll
+ - Various other bug fixes and improvements.
+
+Version 0.1.9.5 (Preview) 2002/12/10
+ - Completed weatherch.dll
+ - Weather Underground (wunderground.dll) included - not complete yet.
+ - Bug fix: Default weather station and weather status.
+ - Bug fix: Crash when edit weather station.
+ - Bug fix: Crash when adding new weather station.
+ - Bug fix: Searching for weather station when no contact found.
+ - Various other changes and bug fixes.
+
+Version 0.1.9.0 (Preview) 2002/12/09
+ - Split code into different files for easier modification.
+ - Support for multiple weather protocols (required minimal change + new build)
+ - Minor changes and bug fixes
+
+Version 0.1.5.2 2002/12/09
+ - Bug fix: crash when "Show multiple icons only when statuses differ" enabled
+ - Bug fix: some options not saved properly.
+ - Bug fix: bug fix when adding the first station.
+
+Version 0.1.5.1 2002/12/07
+ - Bug fix in showing notifying messages.
+
+Version 0.1.5.0 2002/12/06
+ - Error detections.
+ - New option: Show errors on popups.
+ - Display default station weather condition as status icon.
+ - Enable / Disable weather update through status.
+ - New weather conditions.
+ - Slight change in adding new weather station.
+ - Fixed tab orders.
+
+Version 0.1.4.9 2002/12/06
+
+Version 0.1.2.0 2002/11/29
+ - Add links to weather maps.
+ - Add option to change Popup text, Log text, and URL links.
+ - New variables: %d, %s, %S
+ - New option: open webpage in new window.
+ - Internal code changes and bug fixes.
+
+Version 0.1.1.1 2002/11/25
+ - Bug fix: Translations
+ - Minor code change and translation updates.
+
+Version 0.1.1.0 2002/11/24
+ - Brief Information template now translable.
+ - Add set to default button for Brief Information display.
+ - UI change in Brief Information dialog.
+ - Add some control over looping.
+ - Set default weather station (currently has no use, but it maybe useful later or by
+ other plugins)
+ - Bug fix: Searching for station using city names.
+ - Bug fix: Assigning icon to weather conditions.
+ - Fixed tab order.
+ - Other minor UI and code changes (hope this will fix some bugs).
+
+Version 0.1.0.0 2002/11/23
+ - Now add weather station via Find/Add Contact dialog.
+ - Able to search for station using city name.
+ - Customize string for showing brief information.
+ - New option: Log weather station in history.
+ - New option: Disable popup for specific weather station.
+ - Bug fix: Update after editing weather station.
+ - Bug fix: Now correctly update using the new webpage format.
+ - Updated translation string (both dll and weather condition).
+ - Updated debug output method.
+ - Smaller file size.
+ - Re-organized readme and language files.
+ - Various other minor bug fixes and improvement.
+
+Version 0.0.8.5 2002/11/22
+ - Bug fix: Hiding icon in task bar.
+ - New weather condition added (both dll and langpack).
+
+Version 0.0.8.4 2002/11/22
+ - Bug fix: Update issues.
+ - Updated translation string.
+
+Version 0.0.8.3 2002/11/21
+ - Interface change in option screen.
+ - Prevent displaying invalid data.
+ - Minor code change for update weather condition.
+ - Added missing translation string.
+
+Version 0.0.8.2 2002/11/20
+ - Bug fix: Translation of weather condition on contact list
+ - Bug fix: Temperature conversion.
+ - Minor change in option screens and edit setting screen.
+
+Version 0.0.8.1 2002/11/19
+ - Bug fix: Fixed temperature display.
+ - Fixed tab orders.
+
+Version 0.0.8.0 (Beta) 2002/11/19
+ - Retrieve high and low temperature forecast for the current day.
+ - Search and display temperature from alternative source when it is unknown.
+ (For the people who have N/A display beside their city, this ver should work now)
+ - More customizable contact list name display.
+ - Bug fix: C and F conversion when temperature < 0 degree C.
+ - Bug fix: Some update problems.
+ - Language pack updated: more weather conditions.
+
+Version 0.0.7.5 (Beta) 2002/11/18
+ - Right click -> Update Weather will no longer freeze Miranda.
+ - New option: Disable popup if condition doesn't change.
+ - Bug fix: prevent manual update when auto-update is in progress.
+ - Added missing translation string.
+
+Version 0.0.7.0 (Beta) 2002/11/17
+ - Updating weather will no longer freeze up miranda.
+ - Add option to disable popup.
+ - Bug fix: Now saves the degree sign in option.
+ - Bug fix: Logging weather condition and view log command.
+ - Bug fix: Update weather condition after modifying weather station.
+ - Added missing translation string.
+ - Various other improvements.
+
+Version 0.0.6.1 (Beta) 2002/11/16
+ - Bug fix: Update after modifying weather station.
+ - Bug fix: No cache (slower but more accurate info).
+
+Version 0.0.6.0 (Beta) 2002/11/16
+ - The plugin has it's own popup (not using NewStatusNotify's anymore)
+ - Add option to hide icon in status bar and status menu (expreimental release).
+ - Various minor changes.
+
+Version 0.0.5.1 (Alpha) 2002/11/16
+
+Version 0.0.5.0 (Alpha) 2002/11/15
+
+Version 0.0.4.3 (Beta) 2002/11/15
+ - Added option to disable main menu item.
+ - Various minor improvements.
+
+Version 0.0.4.2 (Beta) 2002/11/15
+ - Bug fix: translation strings.
+ - Bug fix: no longer open miranda directory when no log is found.
+
+Version 0.0.4.1 (Beta) 2002/11/15
+ - Bug fix on retrieving weather information.
+ - Removed debug string that was accidentally built in the last release. (see above)
+
+Version 0.0.4.0 (Beta) 2002/11/14
+ - Retrieve weather information no longer require temp files.
+ - Able to modify weather station settings.
+ - Add link to log file in contact menu.
+ - Add an option for degree sign (I can't think of a better way to do this).
+ - Relocate main menu item.
+ - Bug fix: DB: Attempt to get wrong type of value, word.
+ - Various other minor bug fixes.
+
+Version 0.0.3.7 (Beta) 2002/11/14
+ - Bug fix: degree signs (sorry for the copy-and-paste error).
+ - Move the temporary file to miranda directory.
+
+Version 0.0.3.6 (Beta) 2002/11/14
+ - Bug fix: degree signs (changable using language pack)
+ - Bug fix: DB: Attempt to get wrong type of value, word.
+ - More weather condition are now able to display with correct icon.
+
+Version 0.0.3.5 (Beta) 2002/11/13
+ - Initial public beta release.
+
+Version 0.0.3.1 (Beta) 2002/11/13
+
+Version 0.0.3.0 (Beta) 2002/11/12
+ - Disable auto update option.
+ - Logging weather condition.
+ - New option for displaying weather conditions on contact list.
+ - Bug fix: some tarnslation strings.
+ - Bug fix: switching between English and metric units.
+ - Bug fix: time of update.
+
+Version 0.0.2.1 (Preview) 2002/11/12
+ - Bug fix: F to C conversion.
+ - Bug fix: Display complete forcast page in correct unit system.
+
+Version 0.0.2.0 (Preview) 2002/11/12
+ - Display temperature on contact list.
+ - Translable strings.
+ - Display brief weather information as message box.
+ - Faster information download.
+ - Various other fixes.
+
+Version 0.0.1.2 (Pre-Alpha) 2002/11/12
+
+Version 0.0.1.1 (Pre-Alpha) 2002/11/11
+ - Faster and more reliable download.
+ - Various bug fixes.
+
+Version 0.0.1.0 (Pre-Alpha) 2002/11/11
+ - Retrieve temperature and update time.
+
+Version 0.0.0.3 (Pre-Alpha) 2002/11/11
+ - Bug fix in weather condition and icons.
+ - Various other bug fixes.
+
+Version 0.0.0.2 (Pre-Alpha) 2002/11/11
+ - Set the name for city, retrieve weather condition.
+
+Version 0.0.0.1 (Pre-Alpha) 2002/11/10
+ - Initial build
diff --git a/plugins/weather/weather-readme.html b/plugins/weather/weather-readme.html
new file mode 100644
index 0000000000..ff81561171
--- /dev/null
+++ b/plugins/weather/weather-readme.html
@@ -0,0 +1,230 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+ <head>
+ <title>Read Me for Weather Protocol</title>
+ <script language="javascript" type="text/javascript">
+function link(num){document.location="http://addons.miranda-im.org/details.php?action=viewfile&id="+num;}
+ </script>
+ </head>
+ <body>
+ <h2>Read Me for Weather Protocol</h2>
+ <hr/>
+ <pre>
+<a name="top"><font color="red">
+<b>*** IMPORTANT NOTICE ***</b>
+Be cautious when choosing the "special status" selection for selecting the status
+assign to contact whose current condition is unavailable. This feature is not
+officially support by Miranda and may cause a lot of plugins to crash. Be sure to
+backup your profile before you try this feature.</font>
+
+</a>
+</pre>
+<hr/>
+<pre>
+
+<b><u>File Content</u></b>
+
+<a href="#fea">Features</a>
+<a href="#fi">Files Included</a>
+<a href="#sr">System Requirement</a>
+<a href="#ins">Installation</a>
+<a href="#faq">Frequently Asked Questions</a>
+<a href="#lic">License</a>
+
+</pre>
+<hr/>
+<pre>
+
+<a name="fea"><b><u>Features</u></b>
+
+ - Retrieve weather information and display them on your Miranda contact list.
+ - Provide a contact information page for viewing the current weather conditions.
+ - Display PopUp when information is retrieved.
+ - Log weather conditions to a file or in history.
+ - Quick links for viewing complete forecast and weather maps.
+
+
+</a><a name="fi"><b><u>Files Included</u></b>
+
+ - plugins\weather.dll
+ The core to the weather plugin. Required component
+ - </a><a href="langpack_defweather.txt">langpack_defweather.txt</a> (stored in the documentation folder by default)
+ Langpack for weather icon assignment, containing documentation for how to use
+ - <a href="weather-readme.html">plugins\weather-doc\weather-readme.html</a>
+ Documentation and FAQ for Weather Protocol (this file).
+ - <a href="sample_ini.ini">plugins\weather-doc\sample_ini.ini</a>
+ Documentation of the format of the weather INI file.
+ - <a href="weather-translation.txt">plugins\weather-doc\weather-translation.txt</a>
+ A file that contains a translation of hopefully all string used in Weather Protocol.
+
+
+<a name="sr"><b><u>System Requirement</u></b>
+
+ - </a><a href=
+"http://www.miranda-im.org">Miranda IM</a> (v0.7.3.0 or later)
+ - <a href="http://addons.miranda-im.org/index.php?action=display&amp;id=78">Weather INI file</a>
+ - Weather icons (Optional)
+ Numerous choices available in <a href=
+"http://addons.miranda-im.org/index.php?action=display&amp;id=35">icon downloads</a>.
+ - <a href=
+"javascript:link(2759)">YAPP plugin</a> by sje or <a href=
+"javascript:link(3400)">PopUp Plus plugin</a> by nullbie (Optional)
+
+
+<a name="ins"><b><u>Installation</u></b>
+ For installation of weather protocol, it is recommended for installing it using Miranda
+ Installer. For manual installation, please following these steps:
+
+ 1. Copy weather.dll into plugins directory.
+ 2. Get the ini's from file listing and place them into plugin\weather directory.
+ 3. If you want external file for status icon selection, copy the content of
+ langpack_defweather.txt into your language pack and (optionally) enable
+ "Disable internal icon selection" from the option page.
+ 4. In icon option, customize the weather icon or use the default one in the dll
+
+ IMPORTANT UPGRADE NOTICE
+ Due to the changes made in this version, Weather 0.3.x is not compatible with older
+ releases (v0.2.x). Therefore, you should delete your weather contacts before
+ upgrading to this new version.
+
+
+</a><a name="faq"><b><u>Frequently Asked Question</u></b>
+
+<i><u>Setting Up Weather Protocol</u></i>
+For installation, follow the steps describe in the </a><a href=
+"#ins">installation</a> section of the readme.
+
+<b>Q1-1. Weather Protocol does not do anything after I installed it, and it
+ cannot go online.</b>
+A. You need to add a new station before you can go online.
+
+<b>Q1-2. How do I add new stations?</b>
+A. Use the find/add dialog box. You can either search for station ID (see the readme
+ for the ini file to see how it can be obtained) or search by city name by entering
+ the name in either one of the Nickname, Firstname, or Lastname field.
+
+<b>Q1-3. I can't find my station! Any help?</b>
+A. Make sure you have installed the plugin and ini file correctly. At least one INI
+ file must exist in the plugins\weather directory in order for the plugin to funciton
+ properly. For more information, click <a href=
+"#ins">here</a>.
+
+<b>Q1-4. I have installed the plugin properly, and it still doesn't work. I have
+ noticed that there is no traffic generated by the plugin.</b>
+A. Check you proxy setting, some proxy does not work properly under Miranda IM 0.3.3.0.
+ If your proxy is having problem connecting, you need to upgrade to Miranda IM 0.3.3.1
+ or try the <a href="http://www.miranda-im.org/development/">nightly builds</a>
+ (Note: They are experimental builds!)
+ Also, if you are using <a href="javascript:link(844)">traffic counter</a> plugin,
+ please make sure that you are using the latest version. The old version stops Weather
+ and some other plugin from working.
+
+<i><u>INI and Development Related Questions</u></i>
+
+<b>Q2-1. What are those INI files for?</b>
+A. The INI files contain information for downloading and parsing weather information
+ from a particular weather site. At least one INI file must exist in order for the
+ plugin to work. For a list of available INI's, click <a href="#top">here</a>.
+
+<b>Q2-2. Can I install or modify the INI files without restarting Miranda?</b>
+A. Yes, choose: M (main menu) -&gt; Weather -&gt; Reload Weather Data
+
+<b>Q2-3. I want to retrieve weather information from a different source than those
+ that are currently available. How can this be done?</b>
+A. You can write your own INI file. For more information, click <a href="sample_ini.ini">here</a>.
+
+<b>Q2-4. I wrote/downloaded an ini file that retrieve weather condition in a
+ language that weather protocol doesn't seems to reconize and always
+ display N/A. What should I do?</b>
+A. You can use translation string for assigning icons. For more information, click <a href="langpack_defweather.txt">here</a>.
+
+<b>Q2-5. How does weather assign status icons for each status?</b>
+A. Online = Sunny
+ Away = Partly Cloudy
+ NA = Cloudy
+ Occupied = Rain
+ DND = Rain Shower
+ Free for Chat = Snow / Wintery Conditions
+ Invisible = Lightning / Thunderstorm
+ On the Phone = Snow Shower
+ Out to Lunch = Fog / Haze
+ Offline = No Data Available
+
+<u><i>Obtaining Weather Data</i></u>
+
+<b>Q3-1. Does weather protocol retreve weather forecasts?</b>
+A. Support of this feature depend on the ini file you use. If it is supported, the most
+ likely variable you use for it is %[Forecast Day #] or %[FD#] where # is the day you
+ want the forecast for. See the readme supplied in the INI file package for more
+ information.
+
+<b>Q3-2. How long should the time between update be?</b>
+A. This depend on the update interval on the website. Generally, this field should set
+ to a value between 10 to 30 minutes. If the value is too small, a lot of traffics
+ will be generated by the protocol.
+
+<b>Q3-3. How can I temporary disable weather procotol?</b>
+A. Switch the weather status to OFFLINE, but this will not work if you have "Do not
+ display weather condition as protocol status" option enabled. To enable the
+ protocol again, switch it to a status other than OFFLINE. Automatic update of
+ weather condition can be disabled through menu and option page.
+
+<b>Q3-4. Why are the name of some weather contacts italic on my contact?</b>
+A. There are weather alerts issued for those cities. To see the alert title, use the
+ %[Alert] variable. You can disable this function in option page.
+
+<b>Q3-5. There are some status that the weather plugin doesn't seems to
+ reconize and always shows as N/A on the contact list. What can I do?</b>
+A. If the source of weather info is in a language other than English, please check the
+ INI package for instruction of how to install language pack. If the source is in
+ English, notify me.
+
+<u><i>Customizing the Weather Protocol</i></u>
+
+<b>Q4-1. Can I hide Weather from status bar and protocol menu?</b>
+A. Go to Options-&gt;Plugins-&gt;Weather, enable "Hide Weather in status bar and status menu".
+
+<b>Q4-2. I can't find Weather in the icon option drop-down list. How can I change
+ weather icons?</b>
+A. Weather icon cannot be changed if "Hide Weather in status bar and status menu" is
+ enabled. To change icons, disable the option (see Q4-1), make your change, then re-
+ enable it.
+
+<b>Q4-3. I can't find the options for changing display text.</b>
+A. Go to Options-&gt;Plugins-&gt;Weather, then click on the icon beside "Change display texts"
+
+<b>Q4-4. How can I change the display name of my city?</b>
+A. Right-click on the city and select "Edit Settings". Change the field "City name"
+ to the new display name.
+
+<b>Q4-5. How can I change the default station?</b>
+A. Use the Edit Settings dialog (See A4-4). Note that only 1 station can be default.
+
+<b>Q4-6. What is the %[..] variable for?</b>
+A. They are the custom variables. Replace the ".." with a setting name that can be
+ found in \Weather in the database. For more information about the availability of
+ the settings, use <a href=
+"javascript:link(2957)">Database Editor</a> or refer to the readme of the ini file.
+
+<b>Q4-7. What are the "Extra Text" for?</b>
+A. The field has no use internally. However, it can be useful for some other plugin
+ to obtain a weather information string that is already parsed.
+
+<b>Q4-8. I want weather protocol to have the same status as the other protocols.
+ Is such option available?</b>
+A.
+Disable the option "Use weather condition as protocol status", then you will be
+ able to change the status freely.
+
+<b>Q4-9. How do I create avatars for each weather condition?</b>
+A. Put the following files into the Miranda\Plugins\Weather folder:
+ Light.png, Fog.png, SShower.png, Snow.png, RShower.png, Rain.png
+ PCloudy.png, Cloudy.png, Sunny.png, NA.png
+
+
+<a name="lic">License
+
+This plugin is released under </a><a href="http://www.gnu.org/licenses/gpl.txt">GPL</a>.
+</pre>
+ </body>
+</html>
diff --git a/plugins/weather/weather-translation.txt b/plugins/weather/weather-translation.txt
new file mode 100644
index 0000000000..72a74ea9f8
--- /dev/null
+++ b/plugins/weather/weather-translation.txt
@@ -0,0 +1,798 @@
+; this is a template for translation of weather protocol
+; last updated March 21, 2005 for version 0.3.5.0
+
+*************************************************************************************
+********************************** NEW IN V0.3.8.17 *********************************
+*************************************************************************************
+[#condition Weather]
+example [#Sunny Weather]
+
+*************************************************************************************
+********************************** NEW IN V0.3.5.0 **********************************
+*************************************************************************************
+; options
+[Update weather information at startup]
+
+; popup options
+[Updates]
+[Errors]
+[Alerts]
+
+
+*************************************************************************************
+********************************** NEW IN V0.3.4.0 **********************************
+*************************************************************************************
+[When condition unavailable, use the status:]
+[Special status]
+[Day/Month]
+[No change]
+[2 chars]
+[3 chars]
+
+*************************************************************************************
+********************************** NEW IN V0.3.3.13 *********************************
+*************************************************************************************
+; missing translation strings - thanks smyle again
+[Edit Weather Station]
+[Link Settings]
+
+
+*************************************************************************************
+********************************** NEW IN V0.3.3.11 *********************************
+*************************************************************************************
+; missing translation strings - thanks smyle
+[Extra text]
+[Weather text]
+[Popup Text]
+[Do not display weather condition as protocol status]
+[Log]
+
+; missing weather conditions - thanks smyle again
+[Showers]
+[AM Showers]
+[PM Showers]
+[Scatter Showers]
+[Rain / Wind]
+[Showers / Wind]
+[AM Showers / Wind]
+[PM Showers / Wind]
+[Scatter Showers / Wind]
+[Few Showers]
+[Few Showers / Wind]
+
+
+*************************************************************************************
+********************************** NEW IN V0.3.3.10 *********************************
+*************************************************************************************
+; menu item
+[Add New Weather Station]
+
+; sound event
+[Weather Alert Issued]
+
+
+*************************************************************************************
+********************************** NEW IN V0.3.3.6 **********************************
+*************************************************************************************
+
+; sound event
+[Weather Condition Changed]
+
+
+*************************************************************************************
+********************************** NEW IN V0.3.3.5 **********************************
+*************************************************************************************
+
+; fix in defaults - change %h to %m
+[%c\nTemperature: %t\nFeel-Like: %f\nPressure: %p\nWind: %i %w\nHumidity: %m\nDew Point: %e\nVisibility: %v\n\nSun Rise: %r\nSun Set: %y\n\n5 Days Forecast:\n%[Forecast Day 1]\n%[Forecast Day 2]\n%[Forecast Day 3]\n%[Forecast Day 4]\n%[Forecast Day 5]]
+[Feel-Like: %f\nPressure: %p\nWind: %i %w\nHumidity: %m\nDew Point: %e\nVisibility: %v\n\nSun Rise: %r\nSun Set: %y\n\n5 Days Forecast:\n%[Forecast Day 1]\n%[Forecast Day 2]\n%[Forecast Day 3]\n%[Forecast Day 4]\n%[Forecast Day 5]"]
+[%c, %t (feel-like %f) Wind: %i %w Humidity: %m]
+[%n at %u: %c, %t (feel-like %f) Wind: %i %w Humidity: %m]
+
+
+*************************************************************************************
+********************************** NEW IN V0.3.3.4 **********************************
+*************************************************************************************
+
+; option dialog
+[Disable internal station status icon selection]
+[Disable support for automatic protocol icons assignment]
+
+
+*************************************************************************************
+********************************** NEW IN V0.3.3.3 **********************************
+*************************************************************************************
+
+; weather ini setup dialog
+[Weather Protocol INI Setup]
+[Install and load your weather ini file here]
+[Weather Protocol cannot find any weather INI file stored in your computer. To setup weather INI and add weather stations, please follow the steps:]
+[Click here to download a weather ini file from Miranda file listing]
+[Extract the weather ini file from archive to this directory]
+[Click here to load the data from the new ini file into memory]
+[Add new weather station and close this dialog]
+[Never show this at startup again]
+
+*************************************************************************************
+********************************** NEW IN V0.3.3.2 **********************************
+*************************************************************************************
+
+; options
+[Make the contact italic when weather alert is issued]
+[Display warning if INI file is not found at startup]
+
+; weather error codes
+[Invalid ID format, missing \"/\" (10)]
+[Invalid service (11)]
+[Invalid station (12)]
+[Weather service ini for this station is not found (20)]
+[Netlib error - check your internet connection (30)]
+[Empty data is retrieved (40)]
+[Document not found (42)]
+[Document too short to contain any weather data (43)]
+[Unknown error (99)]
+[HTTP Error: No content (204)]
+[HTTP Error: Data moved (301)]
+[HTTP Error: Use proxy (305)]
+[HTTP Error: Temporary redirect (307)]
+[HTTP Error: Bad request (400)]
+[HTTP Error: Unauthorized (401)]
+[HTTP Error: Payment required (402)]
+[HTTP Error: Forbidden (403)]
+[HTTP Error: Not found (404)]
+[HTTP Error: Method not allowed (405)]
+[HTTP Error: Proxy authentication required (407)]
+[HTTP Error: Gone (410)]
+[HTTP Error: Internal server error (500)]
+[HTTP Error: Bad gateway (502)]
+[HTTP Error: Service unavailable (503)]
+[HTTP Error: Gateway timeout (504)]
+[HTTP Error %i]
+
+
+*************************************************************************************
+********************************** NEW IN V0.3.3.0 **********************************
+*************************************************************************************
+
+; ------ Options ------
+[Disable auto update when status changes to offline, enable when changes to other]
+[Remove old data when updating]
+
+; ------ Popup Options ------
+[Show user detail]
+[From PopUp plugin]
+[Permanent]
+
+; ------ Text Options ------
+[To old settings]
+[To default]
+[Brief Info Title]
+[Weather Protocol Text Preview]
+
+; ------ Menu ------
+[Remove Old Data then Update All]
+[Remove Old Data then Update]
+[Auto Update Enabled]
+[Auto Update Disabled]
+
+; ------ Brief info ------
+[More...]
+[More Info]
+[Update]
+[Webpage]
+[View all weather details for this contact]
+
+; defaults
+[Weather Condition for %n as of %u]
+[%c, %t\nToday: High %h, Low %l]
+
+
+*************************************************************************************
+********************************** NEW IN V0.3.2.9 **********************************
+*************************************************************************************
+
+; ------ weather_opt.c ------
+[More Variables]
+[Here is a list of custom variables that are currently available]
+
+; ------ weather_info.c ------
+[bytes]
+
+
+*************************************************************************************
+********************************** NEW IN V0.3.2.4 **********************************
+*************************************************************************************
+
+; ------ weather_contacts.c ------
+[Get city name from ID]
+
+
+*************************************************************************************
+********************************** NEW IN V0.3.2.3 **********************************
+*************************************************************************************
+
+; ------ edit setting dialog ------
+[City name]
+
+; ------ weather_contacts.c ------
+[<Enter city name here>]
+
+
+*************************************************************************************
+********************************** NEW IN V0.3.2.2 **********************************
+*************************************************************************************
+
+; ------ option dialog ------
+[Weather status will free to change all the time if this option is enabled.]
+
+
+*************************************************************************************
+********************************** NEW IN V0.3.2.0 **********************************
+*************************************************************************************
+
+;==============================
+; Dialogs
+
+; ------ option dialogs ------
+[Change display texts]
+[View weather INI information]
+
+; ------ edit weather station -------
+[Disable automatic update for this station]
+[Browse]
+
+
+;==============================
+; Translation in Codes
+
+; ------ weather_contacts.c ------
+; dialog texts
+[Weather INI information]
+[View webpage]
+[Reset to default]
+[Text Files]
+[All Files]
+
+
+; ------ weather_ini.c ------
+[Click \"Yes\" to download new data files, \"No\" to load Weather Protocol without any update support]
+
+; ini info
+[A list of Weather INI files currently in memory:]
+[Name\tAuthor\tFile Version\tINI ver\tItems\tDisplay Name\t\tFile Name]
+[Total INI files:\t%i]
+[Total memory used:\t%i bytes]
+[Weather INI Information]
+
+; individual ini info
+[The corresponding INI file for \"%s\" is not found.]
+[Weather INI information for \"%s\":]
+[Name:]
+[Internal Name:]
+[Author:]
+[Version:]
+[INI Version:]
+[File Name:]
+[Item Count:]
+[Memory Used:]
+[Description:]
+
+
+; ------ weather_opt.c ------
+[%[..]\tcustom variables]
+
+
+;===============================
+; weather information (new in v0.3.x)
+
+; weekdays (short)
+[Mon]
+[Tue]
+[Wed]
+[Thu]
+[Fri]
+[Sat]
+[Sun]
+
+; weekdays (long)
+[Monday]
+[Tuesday]
+[Wednesday]
+[Thursday]
+[Friday]
+[Saturday]
+[Sunday]
+
+; pressure changes
+[Rising]
+[Steady]
+[Falling]
+[rising]
+[steady]
+[falling]
+
+
+*************************************************************************************
+********************************** NEW IN V0.3.1.5 **********************************
+*************************************************************************************
+
+; option page
+[Consider weather info updated only when condition and temperature are changed]
+
+; ------ weather_ini.c ------
+[Invalid ini format for: %s]
+
+
+*************************************************************************************
+********************************** NEW IN V0.3.1.0 **********************************
+*************************************************************************************
+
+; ------ weather_addstn.c ------
+; dummy searches
+[<Enter station name here>]
+[<Enter station ID here>]
+
+; ------ weather_contacts.c ------
+[All update data has been reloaded.]
+
+; ------ weather_ini.c ------
+; crash preventions
+[Error when obtaining data: %s]
+[<Error>]
+
+
+*************************************************************************************
+********************************** NEW IN V0.3.0.1 **********************************
+*************************************************************************************
+
+; ------ Option dialog ------
+[Fahrenheit]
+
+; ------ weather_contacts.c ------
+[The URL for complete forcast have not been set. You can set it from the Edit Settings dialog.]
+[The URL for weather map have not been set. You can set it from the Edit Settings dialog.]
+
+
+*************************************************************************************
+********************************** NEW IN V0.3.0.0 **********************************
+*************************************************************************************
+
+;==============================
+; Dialogs
+
+; ------ Option dialog ------
+[Open URLs in new browser window]
+
+[Units]
+[Temperature]
+[Celsius]
+[Wind]
+[km/h]
+[m/s]
+[mph]
+[knots]
+[Visibillity]
+[km]
+[miles]
+[Pressure]
+[kPa]
+[mb (hPa)]
+[inches]
+[mm Hg (torr)]
+
+[Texts]
+[Click the button on the left to change the display and log texts]
+
+[Advanced Options]
+[Hide Weather in status bar and status menu]
+[Note that icon cannot be changed when this feature is enabled]
+[Disable internal icon selection]
+[Miranda IM has to be restarted for the changes to take effect.]
+
+; ------ Text options dialog ------
+[Note Text]
+[Reset]
+
+; User info dialog
+[Feel-like]
+[Humidity]
+[Dewpoint]
+[Sunrise]
+[Sunset]
+[Today's High]
+[Today's Low]
+
+
+;==============================
+; Translation in Codes
+
+; ------ weather.c ------
+; for netlib
+[Weather HTTP connections]
+
+; ------ weather_contacts.c ------
+; menu item for enable/disable popups
+[Enable &weather notification]
+[Disable &weather notification]
+
+; menu item texts
+[Update All Weather]
+[Reload All Update Data]
+
+; ------ weather_ini.c ------
+[No update data file is found. Please check your Plugins\\Weather directory.]
+
+; ------ weather_opt.c ------
+; defaults
+[%n [%t, %c]]
+
+; variable list (this looks scary...)
+[%c\tcurrent condition\n%d\tcurrent date\n%e\tdewpoint\n%f\tfeel-like temperature\n%h\ttoday's high\n%i\twind direction\n%l\ttoday's low\n%m\thumidity\n%n\tstation name\n%p\tpressure\n%r\tsunrise time\n%s\tstation ID\n%t\ttemperature\n%u\tupdate time\n%v\tvisibility\n%w\twind speed\n%y\tsun set]
+
+
+;===============================
+; weather information (new in v0.3.x)
+
+; Wind (short)
+[calm]
+[Calm]
+[N]
+[W]
+[S]
+[E]
+[NW]
+[NE]
+[SW]
+[SE]
+[NNW]
+[NNE]
+[SSW]
+[SSE]
+[ENE]
+[WSW]
+[WNW]
+[ESE]
+
+; Wind (long)
+[North]
+[East]
+[South]
+[West]
+[Northwest]
+[Northeast]
+[Southwest]
+[Southeast]
+[North Northwest]
+[North Northeast]
+[South Southwest]
+[South Southeast]
+[East Northeast]
+[West Southwest]
+[West Northwest]
+[East Southeast]
+
+; Visibility
+[unlimited]
+[Unlimited]
+
+; units not included in the plugin translation
+[mb]
+[hPa]
+[in]
+[mm]
+[torr]
+
+
+;===============================
+; weather conditions for icon determination
+; Note: please refer to the sample "langpack_defweather.txt"
+
+
+*************************************************************************************
+******************** TRANSLATION STRINGS FROM 0.0.0.1 TO 0.2.5.1 ********************
+*************************************************************************************
+
+;==============================
+; Dialogs
+
+; ------ Edit Settings ------
+[Weather Station]
+[Description]
+[ID]
+[Log Information]
+[Use internal history]
+[Use external file]
+[Overwrite file upon update]
+[Path:]
+[Link Settings]
+[More Info URL]
+[Weather Map]
+[Other Options]
+[Set as default station]
+[Disable PopUp for this station]
+[Change]
+[Cancel]
+
+; ------ Option dialog ------
+[Options]
+[Show main menu items]
+[Update weather information every]
+[minutes.]
+[Do not display weather condition as protocol status]
+
+[Degree sign:]
+[Change]
+
+; ------ Popup option dialog ------
+[PopUp Options]
+[Enable popups]
+[Popup only when condition changes]
+[Show informations and warnings]
+
+[Popup Actions]
+[Left Click]
+[Right Click]
+[Dismiss PopUp]
+[Open brief information]
+[Open complete forecast]
+[Open weather map]
+[View history]
+[Open log file]
+[Show user menu]
+
+[Colours]
+[Background colour]
+[Text colour]
+[Use Windows colours]
+[Preview]
+
+[Popup Delay]
+[Delay]
+[seconds]
+
+[PopUp Text]
+[Popup Title]
+[Popup Text]
+[Variables]
+
+; ------ Text options dialog ------
+[Weather Protocol Text Options]
+[Contact List]
+[Brief Info]
+[External Log]
+[History Log]
+[Variable List]
+[Okay]
+[Cancel]
+
+
+;==============================
+; Translation in Codes
+
+; ------ weather.c ------
+; weather.h
+[N/A]
+[Weather Protocol]
+[Weather]
+
+; weather_addstn.c
+; adding new station
+[Current weather information for %s.]
+[%s is now the default weather station]
+
+; searching for a station
+[Please try again after weather update is completed.]
+
+; ------ weather_contacts.c ------
+; view log
+[Weather condition was not logged.]
+
+; menu item texts
+[Update Weather]
+[Brief Information]
+[Read Complete Forecast]
+[Weather Map]
+[View Log]
+[Edit Settings]
+[Weather Notification]
+
+; contact info dialog
+[Current condition for %n]
+[Last update on: %d %u]
+
+; brief info dialog
+[No information available.\nPlease update weather condition first.]
+[Do you want to view more information?]
+[Brief information for ]
+
+; edit setting dialog
+[Current weather information for %s.]
+
+; ------ weather_conv.c ------
+[<unknown time>]
+
+; ------ weather_http.c ------
+[Unable to retrieve weather information for %s]
+
+; ------ weather_ini.c ------
+; currently none
+
+; ------ weather_popup.c ------
+; popup preview
+[Here is a short weather description]
+[This is the name of the city]
+
+; ------- weather_svcs.c ------
+; unique ID
+[Station ID]
+
+
+;===============================
+; weather conditions
+; Note: the following may not be a complete list of all the possible weather conditions
+; here are just a "few" common conditions as there are way too many to identify!!
+
+; sunny
+[Sunny]
+[Clear]
+[Fair]
+[Sunny/Windy]
+[Clear/Windy]
+[Fair/Windy]
+[Windy]
+
+; partly cloudy
+[Partly Sunny]
+[Mostly Cloudy]
+[Mostly Clear]
+[Partly Sunny/Windy]
+[Mostly Clear/Windy]
+[Mostly Sunny]
+[Mostly Sunny/Windy]
+
+; cloudy
+[Cloudy]
+[Overcast]
+[Cloudy/Windy]
+[Overcast/Windy]
+[Mostly Cloudy/Windy]
+[Mostly Cloudy]
+
+; rain
+[Light Drizzle]
+[Drizzle]
+[Light Rain]
+[Rain]
+[Heavy Rain]
+[Light Rain/Fog]
+[Rain/Fog]
+[Light Drizzle/Windy]
+[Drizzle/Windy]
+[Light Rain/Windy]
+[Rain/Windy]
+[Heavy Rain/Windy]
+[AM Light Rain]
+[PM Light Rain]
+[AM Light Rain/Windy]
+[PM Light Rain/Windy]
+
+; showers
+[Rain Shower]
+[Showers]
+[Heavy Rain Shower]
+[Heavy Rain Shower/Windy]
+[Light Rain Shower]
+[AM Shower]
+[PM Shower]
+[Scattered Shower]
+[Rain Shower/Windy]
+[Shower/Windy]
+[Light Rain Shower/Windy]
+[AM Shower/Windy]
+[PM Shower/Windy]
+[Scattered Shower/Windy]
+[Few Showers]
+[Few Showers/Windy]
+[Showers in the Vicinity]
+[Thunder in the Vicinity]
+
+; snow
+[Light Snow]
+[Snow]
+[Heavy Snow]
+[Light Snow Pellets]
+[Snow Pellets]
+[Light Ice Pellets]
+[Ice Pellets]
+[Wintery Weather]
+[Light Freezing Rain]
+[Freezing Rain]
+[Flurries/Windy]
+[Light Flurries/Windy]
+[Light Snow/Windy]
+[Snow/Windy]
+[Heavy Snow/Windy]
+[Light Snow Pellets/Windy]
+[Snow Pellets/Windy]
+[Light Ice Pellets/Windy]
+[Ice Pellets/Windy]
+[Light Freezing Rain/Windy]
+[Freezing Rain/Windy]
+[Wintery Mix]
+[Light Snow Grains]
+[Snow Grains]
+[Rain/Snow]
+[Rain/Show/Windy]
+[Light Rain/Freezing Rain]
+[Rain/Freezing Rain]
+[Light Rain/Freezing Rain/Windy]
+[Rain/Freezing Rain/Windy]
+[AM Snow]
+[PM Snow]
+[AM Light Snow]
+[PM Light Snow]
+[Ice Crystals]
+[Ice Crystals/Windy]
+
+; snow showers
+[Snow Showers]
+[Heavy Snow Shower]
+[Heavy Snow Shower/Windy]
+[PM Snow Showers]
+[AM Snow Showers]
+[Rain/Snow Showers]
+[Snow Showers/Windy]
+[PM Snow Showers/Windy]
+[AM Snow Showers/Windy]
+[Rain/Snow Showers/Windy]
+[Light Snow Showers]
+[Light Snow Showers/Windy]
+[Flurries]
+[Light Flurries]
+[Scattered Flurries]
+[Few Flurries]
+[Few Flurries/Windy]
+[Scattered Snow Showers]
+[Scattered Snow Showers/Windy]
+[Few Snow Showers]
+[Few Snow Showers/Windy]
+[Freezing Drizzle]
+[Light Freezing Drizzle]
+[Freezing Drizzle/Windy]
+[Light Freezing Drizzle/Windy]
+[Drifting Snow]
+
+; thunder
+[Thunderstorms]
+[Scattered Thunderstorms]
+[Thunderstorms/Windy]
+[Scattered Thunderstorms/Windy]
+[Rain/Thunder]
+[Light Thunderstorms/Rain]
+[Thunderstorms/Rain]
+[Light Rain with Thunder]
+[Rain with Thunder]
+[T-Storm]
+
+; fog
+[Fog]
+[Haze]
+[Mist]
+[Fog/Windy]
+[Haze/Windy]
+[Mist/Windy]
+[Partial Fog]
+[Smoke]
+[Foggy]
+[AM Fog/PM Sun]
+[Blowing Sand]
+[Low Drifting Sand]
+[Blowing Dust]
+[Widespread Dust/Windy]
+[Widespread Dust]
+[Duststorm]
+
+; n/a
+[Data Not Available]
+[N/A]
+; and any other possible modes
diff --git a/plugins/weather/weather.c b/plugins/weather/weather.c
new file mode 100644
index 0000000000..8b98fc247a
--- /dev/null
+++ b/plugins/weather/weather.c
@@ -0,0 +1,308 @@
+/*
+Weather Protocol plugin for Miranda IM
+Copyright (C) 2005-2011 Boris Krasnovskiy All Rights Reserved
+Copyright (C) 2002-2005 Calvin Che
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; version 2
+of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+Main file for the Weather Protocol, includes loading, unloading,
+upgrading, support for plugin uninsaller, and anything that doesn't
+belong to any other file.
+*/
+
+#include "weather.h"
+
+//============ GLOBAL VARIABLES ============
+
+WIDATALIST *WIHead;
+WIDATALIST *WITail;
+
+HINSTANCE hInst;
+HWND hPopupWindow;
+
+HANDLE hHookWeatherUpdated;
+HANDLE hHookWeatherError;
+
+static HANDLE hHooks[9];
+
+HANDLE hDataWindowList;
+HANDLE hWindowList;
+int hLangpack;
+
+HANDLE hUpdateMutex;
+
+unsigned status;
+unsigned old_status;
+
+UINT_PTR timerId;
+int hLangpack;
+
+MYOPTIONS opt;
+
+// check if weather is currently updating
+BOOL ThreadRunning;
+
+// variable to determine if module loaded
+BOOL ModuleLoaded;
+
+struct MM_INTERFACE mmi;
+struct UTF8_INTERFACE utfi;
+
+
+PLUGINLINK *pluginLink;
+
+// plugin info
+// VER = version, AUTH = author, defined in weather.h
+static const PLUGININFOEX pluginInfoEx =
+{
+ sizeof(PLUGININFOEX),
+#ifdef _WIN64
+ "Weather Protocol x64",
+#else
+ "Weather Protocol",
+#endif
+ __VERSION_DWORD,
+ "Retrieve weather information and display them in your contact list",
+ AUTH,
+ "borkra@miranda-im.org",
+ "(c) 2002-2005 NoName, 2005-2010 Boris Krasnovskiy",
+ "http://addons.miranda-im.org/details.php?action=viewfile&id=2322",
+ UNICODE_AWARE,
+ 0,
+ MIID_WEATHER
+};
+
+__declspec(dllexport) const PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion)
+{
+ if (mirandaVersion < PLUGIN_MAKE_VERSION(0,8,0,0)) {
+ MessageBox(NULL, "Weather Protocol requires Miranda 0.8.0.0 or later to run.", "Weather Protocol", MB_OK|MB_ICONERROR|MB_APPLMODAL);
+ return NULL;
+ }
+ // if Miranda version is higher than 0.7.0
+ else
+ return &pluginInfoEx;
+}
+
+// MirandaPluginInterfaces - returns the protocol interface to the core
+static const MUUID interfaces[] = {MIID_PROTOCOL, MIID_LAST};
+__declspec(dllexport) const MUUID* MirandaPluginInterfaces(void)
+{
+ return interfaces;
+}
+
+BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+{
+ switch(fdwReason)
+ {
+ case DLL_PROCESS_ATTACH:
+ hInst = hinstDLL;
+ DisableThreadLibraryCalls(hinstDLL);
+ break;
+ }
+
+ return TRUE;
+}
+
+
+int WeatherShutdown(WPARAM wParam,LPARAM lParam)
+{
+ KillTimer(NULL, timerId); // kill update timer
+
+ SaveOptions(); // save options once more
+ status = ID_STATUS_OFFLINE; // set status to offline
+
+ CallService(MS_NETLIB_SHUTDOWN, (WPARAM)hNetlibHttp, 0);
+
+ WindowList_Broadcast(hWindowList, WM_CLOSE, 0, 0);
+ WindowList_Broadcast(hDataWindowList, WM_CLOSE, 0, 0);
+ SendMessage(hWndSetup, WM_CLOSE, 0, 0);
+
+ return 0;
+}
+
+// update some settings/db values for new version
+// lastver = dword value for the last version made by PLUGIN_MAKE_VERSION
+void Upgrade(DWORD lastver)
+{
+ // for version below v0.3.2.3, remove the "TriggerText" setting
+ if (lastver < PLUGIN_MAKE_VERSION(0,3,2,3))
+ DBDeleteContactSetting(NULL, WEATHERPROTONAME, "TriggerText");
+ if (lastver < PLUGIN_MAKE_VERSION(0,3,3,13))
+ DBDeleteContactSetting(NULL, "KnownModules", "Weather");
+
+ DBWriteContactSettingDword(NULL, WEATHERPROTONAME, "Version", __VERSION_DWORD);
+}
+
+// weather protocol initialization function
+// run after the event ME_SYSTEM_MODULESLOADED occurs
+int WeatherInit(WPARAM wParam,LPARAM lParam)
+{
+ // initialize netlib
+ NetlibInit();
+
+ InitIcons();
+ InitMwin();
+
+ // load weather menu items
+ AddMenuItems();
+
+ // timer for the first update
+ timerId = SetTimer(NULL, 0, 5000, (TIMERPROC)timerProc2); // first update is 5 sec after load
+
+ // weather user detail
+ hHooks[0] = HookEvent(ME_USERINFO_INITIALISE, UserInfoInit);
+
+ hDataWindowList = (HANDLE)CallService(MS_UTILS_ALLOCWINDOWLIST,0,0);
+ hWindowList = (HANDLE)CallService(MS_UTILS_ALLOCWINDOWLIST,0,0);
+
+ return 0;
+}
+
+// update some settings/db values for new version, this one is for contact
+// lastver = dword value for the last version made by PLUGIN_MAKE_VERSION
+// hContact = current contact
+void UpgradeContact(DWORD lastver, HANDLE hContact)
+{
+ // for version below v0.3.2.3, suppress online notifications for all weather contacts
+ if (lastver < PLUGIN_MAKE_VERSION(0,3,2,3))
+ {
+ DBWriteContactSettingDword(hContact, "Ignore", "Mask", 8);
+ DBWriteContactSettingDword(hContact, "Ignore", "Mask1", 8);
+ }
+}
+
+//============ MISC FUNCTIONS ============
+
+// initialize the global variables at startup
+void InitVar()
+{
+ // setup the linklist for weather update list
+ UpdateListTail = NULL;
+ UpdateListHead = NULL;
+
+ // other settings
+ timerId=0;
+ opt.DefStn = NULL;
+ ModuleLoaded = FALSE;
+}
+
+// unload function
+int __declspec(dllexport) Unload(void)
+{
+ unsigned i;
+
+ DestroyMwin();
+ DestroyWindow(hPopupWindow);
+
+ for (i = sizeof(hHooks)/sizeof(HANDLE); i--; )
+ UnhookEvent(hHooks[i]);
+
+ DestroyHookableEvent(hHookWeatherUpdated);
+ DestroyHookableEvent(hHookWeatherError);
+
+ DestroyServices();
+
+ NetlibHttpDisconnect();
+ Netlib_CloseHandle(hNetlibUser);
+
+ DestroyUpdateList();
+ DestroyOptions();
+ DestroyWIList(); // unload all ini data from memory
+
+ CloseHandle(hUpdateMutex);
+
+ return 0;
+}
+
+int __declspec(dllexport) Load(PLUGINLINK *link)
+{
+ PROTOCOLDESCRIPTOR pd = {0};
+ char SvcFunc[100];
+ DWORD lastver;
+
+ pluginLink = link;
+
+ mir_getMMI(&mmi);
+ mir_getUTFI(&utfi);
+ mir_getLP(&pluginInfoEx);
+
+ // initialize global variables
+ InitVar();
+ InitUniConv();
+
+ // load options and set defaults
+ LoadOptions();
+
+ // upgrade check
+ // I only support version check and upgrade for my own version, so check if the author is my name
+ if (strstr(AUTH, "NoName") != NULL)
+ {
+ lastver = DBGetContactSettingDword(NULL, WEATHERPROTONAME, "Version", PLUGIN_MAKE_VERSION(0,3,1,8));
+ if (lastver < __VERSION_DWORD) Upgrade(lastver);
+ }
+ else // if it is not my build, ignore upgrade procedure
+ lastver = PLUGIN_MAKE_VERSION(255,255,255,255);
+
+ // reset the weather data at startup for individual contacts
+ EraseAllInfo(lastver);
+
+ // load weather update data
+ LoadWIData(TRUE);
+
+ // set status to online if "Do not display weather condition as protocol status" is enabled
+ old_status = status = ID_STATUS_OFFLINE;
+
+ // add an event on weather update and error
+ hHookWeatherUpdated = CreateHookableEvent(ME_WEATHER_UPDATED);
+ hHookWeatherError = CreateHookableEvent(ME_WEATHER_ERROR);
+
+ // initialize options and network
+ hHooks[1] = HookEvent(ME_OPT_INITIALISE, OptInit);
+ hHooks[2] = HookEvent(ME_SYSTEM_MODULESLOADED, WeatherInit);
+ hHooks[3] = HookEvent(ME_DB_CONTACT_DELETED, ContactDeleted);
+ hHooks[4] = HookEvent(ME_CLIST_DOUBLECLICKED, BriefInfo);
+ hHooks[5] = HookEvent(ME_WEATHER_UPDATED, WeatherPopup);
+ hHooks[6] = HookEvent(ME_WEATHER_ERROR, WeatherError);
+ hHooks[7] = HookEvent(ME_SYSTEM_PRESHUTDOWN, WeatherShutdown);
+ hHooks[8] = HookEvent(ME_CLIST_PREBUILDCONTACTMENU, BuildContactMenu);
+
+ hUpdateMutex = CreateMutex(NULL, FALSE, NULL);
+
+ // register weather protocol
+ pd.cbSize = sizeof(pd);
+ pd.szName = WEATHERPROTONAME;
+ pd.type = PROTOTYPE_PROTOCOL;
+ CallService(MS_PROTO_REGISTERMODULE,0,(LPARAM)&pd);
+
+ // initialize weather protocol services
+ InitServices();
+
+ // add our modules to the KnownModules list
+ DBWriteContactSettingString(NULL, "KnownModules", "Weather Protocol", "Weather,WeatherCondition,Current");
+
+ // add sound event
+ SkinAddNewSound("weatherupdated", Translate("Weather Condition Changed"), "");
+ SkinAddNewSound("weatheralert", Translate("Weather Alert Issued"), "");
+
+ // window needed for popup commands
+ strcpy(SvcFunc, WEATHERPROTONAME);
+ strcat(SvcFunc, "_PopupWindow");
+ hPopupWindow = CreateWindowEx(WS_EX_TOOLWINDOW,"static",SvcFunc,0,CW_USEDEFAULT,CW_USEDEFAULT,
+ CW_USEDEFAULT,CW_USEDEFAULT,HWND_DESKTOP,NULL,hInst,NULL);
+ SetWindowLongPtr(hPopupWindow, GWLP_WNDPROC, (LONG_PTR)PopupWndProc);
+
+ return 0;
+}
diff --git a/plugins/weather/weather.dsp b/plugins/weather/weather.dsp
new file mode 100644
index 0000000000..68598246bc
--- /dev/null
+++ b/plugins/weather/weather.dsp
@@ -0,0 +1,241 @@
+# Microsoft Developer Studio Project File - Name="Weather" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=Weather - Win32 Release
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "weather.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "weather.mak" CFG="Weather - Win32 Release"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "Weather - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Weather___Win32"
+# PROP BASE Intermediate_Dir "Weather___Win32"
+# PROP BASE Ignore_Export_Lib 1
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release\Obj"
+# PROP Ignore_Export_Lib 1
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /GX /O1 /YX /FD /c
+# SUBTRACT BASE CPP /Fr
+# ADD CPP /nologo /MD /W3 /O1 /Ob0 /I "..\..\include" /FAcs /Fr /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x417 /d "NDEBUG"
+# ADD RSC /l 0x409 /fo"Release\Obj\weather.res" /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo /o"Intermediate/weather.bsc"
+LINK32=link.exe
+# ADD BASE LINK32 user32.lib shell32.lib gdi32.lib /nologo /base:"0x67100000" /dll /machine:I386 /filealign:0x200
+# SUBTRACT BASE LINK32 /pdb:none /map
+# ADD LINK32 user32.lib shell32.lib gdi32.lib comdlg32.lib wsock32.lib /nologo /base:"0x72030000" /version:3.64 /dll /pdb:none /map /machine:I386 /filealign:512
+# Begin Target
+
+# Name "Weather - Win32 Release"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\weather.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\weather_addstn.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\weather_contacts.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\weather_conv.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\weather_data.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\weather_http.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\weather_icons.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\weather_info.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\weather_ini.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\weather_mwin.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\weather_opt.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\weather_popup.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\weather_svcs.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\weather_update.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\weather_userinfo.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\m_cluiframes.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\m_weather.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\version.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\weather.h
+# End Source File
+# End Group
+# Begin Group "Documentations"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\copying.txt
+# End Source File
+# Begin Source File
+
+SOURCE=".\Release\weather-doc\langpack_defweather.txt"
+# End Source File
+# Begin Source File
+
+SOURCE=".\Release\weather-doc\sample_ini.ini"
+# End Source File
+# Begin Source File
+
+SOURCE=".\weather-history.txt"
+# End Source File
+# Begin Source File
+
+SOURCE=".\Release\weather-doc\weather-readme.html"
+# End Source File
+# Begin Source File
+
+SOURCE=".\Release\weather-doc\weather-translation.txt"
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# Begin Group "Plugin Icons"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\res\brief.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\disabled.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\edit.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\icon.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\infologo.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\log.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\map.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\more.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\popup.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\popup_no.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\reload.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\update.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\update2.ico
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\resource.rc
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/plugins/weather/weather.h b/plugins/weather/weather.h
new file mode 100644
index 0000000000..f2459849f0
--- /dev/null
+++ b/plugins/weather/weather.h
@@ -0,0 +1,547 @@
+/*
+Weather Protocol plugin for Miranda IM
+Copyright (C) 2005-2011 Boris Krasnovskiy All Rights Reserved
+Copyright (C) 2002-2005 Calvin Che
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; version 2
+of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* This file contains the includes, weather constants/declarations,
+ the structs, and the primitives for some of the functions.
+*/
+
+//============ THE INCLUDES ===========
+#include <m_stdhdr.h>
+
+#include <stdio.h>
+#include <io.h>
+#include <share.h>
+#include <direct.h>
+#include <process.h>
+#include <time.h>
+
+#include <windows.h>
+#include <commctrl.h>
+#include <richedit.h>
+
+#include <win2k.h>
+
+#define MIRANDA_VER 0x0700
+#define MIRANDA_CUSTOM_LP
+
+#include <newpluginapi.h>
+#include <m_system.h>
+#include <m_protomod.h>
+#include <m_protosvc.h>
+#include <m_clist.h>
+#include <m_icolib.h>
+#include <m_options.h>
+#include <m_langpack.h>
+#include <m_skin.h>
+#include <m_database.h>
+#include <m_history.h>
+#include <m_utils.h>
+#include <m_userinfo.h>
+#include <m_netlib.h>
+#include <m_ignore.h>
+#include <m_findadd.h>
+#include <m_button.h>
+#include <m_avatars.h>
+#include <m_clui.h>
+#include <m_clc.h>
+#include <m_fontservice.h>
+#include "m_cluiframes.h"
+
+#include <m_popup.h>
+
+#include "m_weather.h"
+#include "resource.h"
+#include "version.h"
+
+//============ CONSTANTS ============
+
+// status
+#define NOSTATUSDATA 1
+
+// limits
+#define MAX_TEXT_SIZE 4096
+#define MAX_DATA_LEN 1024
+
+// db info mangement mode
+#define WDBM_REMOVE 1
+#define WDBM_DETAILDISPLAY 2
+
+// more info list column width
+#define LIST_COLUMN 150
+
+// others
+#define NODATA Translate("N/A")
+#define UM_SETCONTACT 40000
+
+// weather update error codes
+#define INVALID_ID_FORMAT 10
+#define INVALID_SVC 11
+#define INVALID_ID 12
+#define SVC_NOT_FOUND 20
+#define NETLIB_ERROR 30
+#define DATA_EMPTY 40
+#define DOC_NOT_FOUND 42
+#define DOC_TOO_SHORT 43
+#define UNKNOWN_ERROR 99
+
+// weather update error text
+#define E10 Translate("Invalid ID format, missing \"/\" (10)")
+#define E11 Translate("Invalid service (11)")
+#define E12 Translate("Invalid station (12)")
+#define E20 Translate("Weather service ini for this station is not found (20)")
+#define E30 Translate("Netlib error - check your internet connection (30)")
+#define E40 Translate("Empty data is retrieved (40)")
+#define E42 Translate("Document not found (42)")
+#define E43 Translate("Document too short to contain any weather data (43)")
+#define E99 Translate("Unknown error (99)")
+
+// HTTP error... not all translated
+// 100 Continue
+// 101 Switching Protocols
+// 200 OK
+// 201 Created
+// 202 Accepted
+// 203 Non-Authoritative Information
+#define E204 Translate("HTTP Error: No content (204)")
+// 205 Reset Content
+// 206 Partial Content
+// 300 Multiple Choices
+#define E301 Translate("HTTP Error: Data moved (301)")
+// 302 Found
+// 303 See Other
+// 304 Not Modified
+#define E305 Translate("HTTP Error: Use proxy (305)")
+// 306 (Unused)
+#define E307 Translate("HTTP Error: Temporary redirect (307)")
+#define E400 Translate("HTTP Error: Bad request (400)")
+#define E401 Translate("HTTP Error: Unauthorized (401)")
+#define E402 Translate("HTTP Error: Payment required (402)")
+#define E403 Translate("HTTP Error: Forbidden (403)")
+#define E404 Translate("HTTP Error: Not found (404)")
+#define E405 Translate("HTTP Error: Method not allowed (405)")
+// 406 Not Acceptable
+#define E407 Translate("HTTP Error: Proxy authentication required (407)")
+// 408 Request Timeout
+// 409 Conflict
+#define E410 Translate("HTTP Error: Gone (410)")
+// 411 Length Required
+// 412 Precondition Failed
+// 413 Request Entity Too Large
+// 414 Request-URI Too Long
+// 415 Unsupported Media Type
+// 416 Requested Range Not Satisfiable
+// 417 Expectation Failed
+#define E500 Translate("HTTP Error: Internal server error (500)")
+// 501 Not Implemented
+#define E502 Translate("HTTP Error: Bad gateway (502)")
+#define E503 Translate("HTTP Error: Service unavailable (503)")
+#define E504 Translate("HTTP Error: Gateway timeout (504)")
+// 505 HTTP Version Not Supported
+
+// defaults constants
+#define C_DEFAULT Translate("%n [%t, %c]")
+#define N_DEFAULT Translate("%c\nTemperature: %t\nFeel-Like: %f\nPressure: %p\nWind: %i %w\nHumidity: %m\nDew Point: %e\nVisibility: %v\n\nSun Rise: %r\nSun Set: %y\n\n5 Days Forecast:\n%[Forecast Day 1]\n%[Forecast Day 2]\n%[Forecast Day 3]\n%[Forecast Day 4]\n%[Forecast Day 5]")
+#define B_DEFAULT Translate("Feel-Like: %f\nPressure: %p\nWind: %i %w\nHumidity: %m\nDew Point: %e\nVisibility: %v\n\nSun Rise: %r\nSun Set: %y\n\n5 Days Forecast:\n%[Forecast Day 1]\n%[Forecast Day 2]\n%[Forecast Day 3]\n%[Forecast Day 4]\n%[Forecast Day 5]")
+#define b_DEFAULT Translate("Weather Condition for %n as of %u")
+#define X_DEFAULT N_DEFAULT
+#define H_DEFAULT Translate("%c, %t (feel-like %f) Wind: %i %w Humidity: %m")
+#define E_DEFAULT Translate("%n at %u: %c, %t (feel-like %f) Wind: %i %w Humidity: %m")
+#define P_DEFAULT Translate("%n (%u)")
+#define p_DEFAULT Translate("%c, %t\nToday: High %h, Low %l")
+
+
+//============ OPTION STRUCT ============
+
+// option struct
+typedef struct {
+// main options
+ BOOL AutoUpdate;
+ BOOL CAutoUpdate;
+ BOOL StartupUpdate;
+ WORD UpdateTime;
+ WORD AvatarSize;
+ BOOL NewBrowserWin;
+ BOOL NoProtoCondition;
+ BOOL UpdateOnlyConditionChanged;
+ BOOL RemoveOldData;
+ BOOL MakeItalic;
+// units
+ WORD tUnit;
+ WORD wUnit;
+ WORD vUnit;
+ WORD pUnit;
+ WORD dUnit;
+ char DegreeSign[4];
+ BOOL DoNotAppendUnit;
+ BOOL NoFrac;
+// texts
+ char *cText;
+ char *bTitle;
+ char *bText;
+ char *nText;
+ char *eText;
+ char *hText;
+ char *xText;
+ char *sText;
+// advanced
+ BOOL DisCondIcon;
+// popup options
+ BOOL UsePopup;
+ BOOL UpdatePopup;
+ BOOL AlertPopup;
+ BOOL PopupOnChange;
+ BOOL ShowWarnings;
+// popup colors
+ BOOL UseWinColors;
+ COLORREF BGColour;
+ COLORREF TextColour;
+// popup actions
+ DWORD LeftClickAction;
+ DWORD RightClickAction;
+// popup delay
+ DWORD pDelay;
+// popup texts
+ char *pTitle;
+ char *pText;
+// other misc stuff
+ char Default[64];
+ HANDLE DefStn;
+} MYOPTIONS;
+
+void DestroyOptions(void);
+
+//============ STRUCT USED TO MAKE AN UPDATE LIST ============
+
+struct WCONTACTLIST {
+ HANDLE hContact;
+ struct WCONTACTLIST *next;
+};
+
+typedef struct WCONTACTLIST UPDATELIST;
+
+extern UPDATELIST *UpdateListHead;
+extern UPDATELIST *UpdateListTail;
+
+void DestroyUpdateList(void);
+
+//============ DATA FORMAT STRUCT ============
+
+#define WID_NORMAL 0
+#define WID_SET 1
+#define WID_BREAK 2
+
+typedef struct {
+ char *Name;
+ char *Start;
+ char *End;
+ char *Unit;
+ char *Url;
+ char *Break;
+ int Type;
+} WIDATAITEM;
+
+struct WITEMLIST {
+ WIDATAITEM Item;
+ struct WITEMLIST *Next;
+};
+
+typedef struct WITEMLIST WIDATAITEMLIST;
+
+typedef struct {
+ BOOL Available;
+ char *SearchURL;
+ char *NotFoundStr;
+ WIDATAITEM Name;
+} WIIDSEARCH;
+
+typedef struct {
+ BOOL Available;
+ char *First;
+ WIDATAITEM Name;
+ WIDATAITEM ID;
+} WINAMESEARCHTYPE;
+
+typedef struct {
+ char *SearchURL;
+ char *NotFoundStr;
+ char *SingleStr;
+ WINAMESEARCHTYPE Single;
+ WINAMESEARCHTYPE Multiple;
+} WINAMESEARCH;
+
+struct STRLIST {
+ char *Item;
+ struct STRLIST *Next;
+};
+
+typedef struct STRLIST WICONDITEM;
+
+typedef struct {
+ WICONDITEM *Head;
+ WICONDITEM *Tail;
+} WICONDLIST;
+
+typedef struct {
+ char *FileName;
+ char *ShortFileName;
+ BOOL Enabled;
+// header
+ char *DisplayName;
+ char *InternalName;
+ char *Description;
+ char *Author;
+ char *Version;
+ int InternalVer;
+ size_t MemUsed;
+// default
+ char *DefaultURL;
+ char *DefaultMap;
+ char *UpdateURL;
+ char *UpdateURL2;
+ char *UpdateURL3;
+ char *UpdateURL4;
+ char *Cookie;
+// items
+ int UpdateDataCount;
+ WIDATAITEMLIST *UpdateData;
+ WIDATAITEMLIST *UpdateDataTail;
+ WIIDSEARCH IDSearch;
+ WINAMESEARCH NameSearch;
+ WICONDLIST CondList[10];
+} WIDATA;
+
+//============ DATA LIST (LINKED LIST) ============
+
+struct DATALIST {
+ WIDATA Data;
+ struct DATALIST *next;
+};
+
+typedef struct DATALIST WIDATALIST;
+
+//============ GLOBAL VARIABLES ============
+
+extern WIDATALIST *WIHead;
+extern WIDATALIST *WITail;
+
+extern HINSTANCE hInst;
+extern HWND hPopupWindow;
+extern HWND hWndSetup;
+
+extern MYOPTIONS opt;
+
+extern unsigned status;
+extern unsigned old_status;
+
+extern HANDLE hDataWindowList;
+extern HANDLE hNetlibUser, hNetlibHttp;
+extern HANDLE hHookWeatherUpdated;
+extern HANDLE hHookWeatherError;
+extern HANDLE hWindowList;
+extern HANDLE hMwinMenu;
+
+extern UINT_PTR timerId;
+
+// check if weather is currently updating
+extern BOOL ThreadRunning;
+
+//============ FUNCTION PRIMITIVES ============
+
+// functions in weather.c
+void UpgradeContact(DWORD lastver, HANDLE hContact);
+
+// functions in weather_addstn.c
+INT_PTR WeatherAddToList(WPARAM wParam,LPARAM lParam);
+BOOL CheckSearch();
+
+int IDSearch(char *id, const int searchId);
+int NameSearch(char *name, const int searchId);
+
+INT_PTR WeatherBasicSearch(WPARAM wParam,LPARAM lParam);
+INT_PTR WeatherCreateAdvancedSearchUI(WPARAM wParam, LPARAM lParam);
+INT_PTR WeatherAdvancedSearch(WPARAM wParam, LPARAM lParam);
+
+int WeatherAdd(WPARAM wParam, LPARAM lParam);
+
+// functions used in weather_contacts.c
+INT_PTR ViewLog(WPARAM wParam,LPARAM lParam);
+INT_PTR LoadForecast(WPARAM wParam,LPARAM lParam);
+INT_PTR WeatherMap(WPARAM wParam,LPARAM lParam);
+
+INT_PTR EditSettings(WPARAM wParam,LPARAM lParam);
+INT_PTR CALLBACK DlgProcChange(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+
+int ContactDeleted(WPARAM wParam,LPARAM lParam);
+
+BOOL IsMyContact(HANDLE hContact);
+
+// functions in weather_conv.c
+BOOL is_number(char *s);
+
+extern unsigned lpcp;
+void InitUniConv(void);
+LPWSTR ConvToUnicode(LPCSTR str2);
+UINT GetDlgItemTextWth(HWND hDlg, int nIDDlgItem, LPSTR lpString, int nMaxCount);
+BOOL SetDlgItemTextWth(HWND hDlg, int nIDDlgItem, LPCSTR lpString);
+BOOL SetWindowTextWth(HWND hWnd, LPCSTR lpString);
+void ListView_SetItemTextWth(HWND hwndLV, int i, int iSubItem_, LPSTR pszText_);
+int ListView_InsertItemWth(HWND hwnd, LV_ITEM *pitem);
+int ListView_InsertColumnWth(HWND hwnd, int iCol, LV_COLUMN *pitem);
+
+void GetTemp(char *tempchar, char *unit, char *str);
+void GetSpeed(char *tempchar, char *unit, char *str);
+void GetPressure(char *tempchar, char *unit, char *str);
+void GetDist(char *tempchar, char *unit, char *str);
+
+WORD GetIcon(const char* cond, WIDATA *Data);
+void FixStr(const char *orig, char* str);
+void CaseConv(char *str);
+void TrimString(char *str);
+void ConvertBackslashes(char *str);
+char *GetSearchStr(char *dis);
+
+char *GetDisplay(WEATHERINFO *w, const char *dis, char* str);
+INT_PTR GetDisplaySvcFunc(WPARAM wParam, LPARAM lParam);
+
+void GetSvc(char *pszID);
+void GetID(char *pszID);
+
+char *GetError(int code);
+
+// functions in weather_data.c
+void GetStationID(HANDLE hContact, char* id, size_t idlen);
+WEATHERINFO LoadWeatherInfo(HANDLE Change);
+int DBGetData(HANDLE hContact, char *setting, DBVARIANT *dbv);
+int DBGetStaticString(HANDLE hContact, const char *szModule, const char *valueName, char *dest, size_t dest_len);
+
+void EraseAllInfo(DWORD lastver);
+
+void LoadStationData(char *pszFile, char *pszShortFile, WIDATA *Data);
+void GetDataValue(WIDATAITEM *UpdateData, char *Data, char** szInfo);
+void ConvertDataValue(WIDATAITEM *UpdateData, char *Data);
+void wSetData(char **Data, const char *Value);
+void wfree(char **Data);
+
+void DBDataManage(HANDLE hContact, WORD Mode, WPARAM wParam, LPARAM lParam);
+int GetWeatherDataFromDB(const char *szSetting, LPARAM lparam);
+
+// functions in weather_http.c
+int InternetDownloadFile (char *szUrl, char *cookie, char** szData);
+void NetlibInit();
+void NetlibHttpDisconnect(void);
+
+// functions in weather_ini.c
+void WIListAdd(WIDATA Data);
+WIDATA* GetWIData(char *pszServ);
+
+BOOL IsContainedInCondList(const char *pszStr, WICONDLIST *List);
+
+void DestroyWIList();
+BOOL LoadWIData(BOOL dial);
+void FreeWIData(WIDATA *Data);
+
+INT_PTR CALLBACK DlgProcSetup(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+
+// functions in weather_info.c
+void GetINIInfo(char *pszSvc);
+
+void MoreVarList();
+
+// functions in weather_opt.c
+void SetTextDefault(const char* in);
+void LoadOptions();
+void SaveOptions();
+
+int OptInit(WPARAM wParam,LPARAM lParam);
+
+INT_PTR CALLBACK OptionsProc(HWND hdlg,UINT msg,WPARAM wparam,LPARAM lparam);
+void SetIconDefault();
+void RemoveIconSettings();
+
+BOOL CALLBACK TextOptionsProc(HWND hdlg,UINT msg,WPARAM wparam,LPARAM lparam);
+BOOL CALLBACK AdvOptionsProc(HWND hdlg,UINT msg,WPARAM wparam,LPARAM lparam);
+INT_PTR CALLBACK DlgProcText(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+INT_PTR CALLBACK DlgPopUpOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+
+// functions in weather_popup.c
+int WeatherPopup(WPARAM wParam, LPARAM lParam);
+int WeatherError(WPARAM wParam, LPARAM lParam);
+int WPShowMessage(char* lpzText, WORD kind);
+
+LRESULT CALLBACK PopupDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
+LRESULT CALLBACK PopupWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+
+void SelectMenuItem(HMENU hMenu, int Check);
+
+// functions in weather_svcs.c
+void InitServices(void);
+void DestroyServices(void);
+
+INT_PTR WeatherSetStatus(WPARAM new_status, LPARAM lParam);
+INT_PTR WeatherGetCaps(WPARAM wParam, LPARAM lParam);
+INT_PTR WeatherGetName(WPARAM wParam, LPARAM lParam);
+INT_PTR WeatherGetStatus(WPARAM wParam, LPARAM lParam);
+INT_PTR WeatherLoadIcon(WPARAM wParam, LPARAM lParam);
+
+void UpdateMenu(BOOL State);
+void UpdatePopupMenu(BOOL State);
+void AddMenuItems();
+void AvatarDownloaded(HANDLE hContact);
+
+// functions in weather_update.c
+int UpdateWeather(HANDLE hContact);
+
+int RetrieveWeather(HANDLE hContact, WEATHERINFO *winfo);
+
+void UpdateAll(BOOL AutoUpdate, BOOL RemoveOld);
+void UpdateThreadProc(LPVOID hWnd);
+INT_PTR UpdateSingleStation(WPARAM wParam,LPARAM lParam);
+INT_PTR UpdateAllInfo(WPARAM wParam,LPARAM lParam);
+INT_PTR UpdateSingleRemove(WPARAM wParam,LPARAM lParam);
+INT_PTR UpdateAllRemove(WPARAM wParam,LPARAM lParam);
+
+int GetWeatherData(HANDLE hContact);
+
+void CALLBACK timerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime);
+void CALLBACK timerProc2(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime);
+
+// function from multiwin module
+void InitMwin(void);
+void DestroyMwin(void);
+INT_PTR Mwin_MenuClicked(WPARAM wParam, LPARAM lParam);
+int BuildContactMenu(WPARAM wparam, LPARAM lparam);
+void UpdateMwinData(HANDLE hContact);
+void removeWindow(HANDLE hContact);
+
+// functions in weather_userinfo.c
+int UserInfoInit(WPARAM wParam, LPARAM lParam);
+INT_PTR CALLBACK DlgProcUIPage(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+INT_PTR CALLBACK DlgProcMoreData(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+
+#define WM_UPDATEDATA WM_USER + 2687
+
+int BriefInfo(WPARAM wParam, LPARAM lParam);
+INT_PTR BriefInfoSvc(WPARAM wParam, LPARAM lParam);
+void LoadBriefInfoText(HWND hwndDlg, HANDLE hContact);
+INT_PTR CALLBACK DlgProcBrief(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+
+void InitIcons(void);
+HICON LoadIconEx(const char* name, BOOL big);
+HANDLE GetIconHandle(const char* name);
+void ReleaseIconEx(HICON hIcon);
diff --git a/plugins/weather/weather_10.vcxproj b/plugins/weather/weather_10.vcxproj
new file mode 100644
index 0000000000..6979e25935
--- /dev/null
+++ b/plugins/weather/weather_10.vcxproj
@@ -0,0 +1,485 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug Unicode|Win32">
+ <Configuration>Debug Unicode</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug Unicode|x64">
+ <Configuration>Debug Unicode</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release Unicode|Win32">
+ <Configuration>Release Unicode</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release Unicode|x64">
+ <Configuration>Release Unicode</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectName>Weather</ProjectName>
+ <ProjectGuid>{6BFE3E13-BD5D-4C1C-BB29-A82FB51A16CE}</ProjectGuid>
+ <RootNamespace>Weather</RootNamespace>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)/Obj/$(ProjectName)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">$(SolutionDir)$(Configuration)/Obj/$(ProjectName)\</IntDir>
+ <IgnoreImportLibrary Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</IgnoreImportLibrary>
+ <IgnoreImportLibrary Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">true</IgnoreImportLibrary>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">false</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Configuration)64\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">$(Configuration)64\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Configuration)64\Obj\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">$(Configuration)64\Obj\</IntDir>
+ <IgnoreImportLibrary Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</IgnoreImportLibrary>
+ <IgnoreImportLibrary Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">true</IgnoreImportLibrary>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">false</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)/Plugins\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">$(SolutionDir)$(Configuration)/Plugins\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)/Obj/$(ProjectName)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">$(SolutionDir)$(Configuration)/Obj/$(ProjectName)\</IntDir>
+ <IgnoreImportLibrary Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</IgnoreImportLibrary>
+ <IgnoreImportLibrary Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">true</IgnoreImportLibrary>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">true</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">c:\Miranda IM\Plugins\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">c:\Miranda IM\Plugins\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)64\Obj\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">$(Configuration)64\Obj\</IntDir>
+ <IgnoreImportLibrary Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</IgnoreImportLibrary>
+ <IgnoreImportLibrary Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">true</IgnoreImportLibrary>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">true</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)/Plugins\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">$(SolutionDir)$(Configuration)/Plugins\</OutDir>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>MinSpace</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <OmitFramePointers>true</OmitFramePointers>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <AdditionalIncludeDirectories>..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>false</ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ <WarningLevel>Level3</WarningLevel>
+ <PrecompiledHeaderFile>weather.h</PrecompiledHeaderFile>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ResourceOutputFileName>$(IntDir)weather.res</ResourceOutputFileName>
+ </ResourceCompile>
+ <Link>
+ <AdditionalOptions>/ALIGN:4096 /filealign:0x200 /ignore:4108 %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <BaseAddress>0x72030000</BaseAddress>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ <TypeLibraryName>.\release/weather.tlb</TypeLibraryName>
+ <HeaderFileName>
+ </HeaderFileName>
+ </Midl>
+ <ClCompile>
+ <Optimization>MinSpace</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <OmitFramePointers>true</OmitFramePointers>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <AdditionalIncludeDirectories>..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <CompileAs>Default</CompileAs>
+ <PrecompiledHeaderFile>weather.h</PrecompiledHeaderFile>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ResourceOutputFileName>$(IntDir)weather.res</ResourceOutputFileName>
+ </ResourceCompile>
+ <Link>
+ <AdditionalOptions>/ALIGN:4096 /filealign:0x200 /ignore:4108 %(AdditionalOptions)</AdditionalOptions>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <ProgramDatabaseFile>
+ </ProgramDatabaseFile>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <BaseAddress>0x72030000</BaseAddress>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <ImportLibrary>
+ </ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <Optimization>MinSpace</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <AdditionalIncludeDirectories>..\..\miranda\miranda\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>false</ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ <PrecompiledHeaderFile>weather.h</PrecompiledHeaderFile>
+ <WarningLevel>Level3</WarningLevel>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ResourceOutputFileName>$(IntDir)weather.res</ResourceOutputFileName>
+ </ResourceCompile>
+ <Link>
+ <AdditionalOptions>/ALIGN:4096 /filealign:0x200 /ignore:4108 %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <BaseAddress>0x72030000</BaseAddress>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>X64</TargetEnvironment>
+ <TypeLibraryName>.\release/weather.tlb</TypeLibraryName>
+ <HeaderFileName>
+ </HeaderFileName>
+ </Midl>
+ <ClCompile>
+ <Optimization>MinSpace</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <AdditionalIncludeDirectories>..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ <PrecompiledHeaderFile>weather.h</PrecompiledHeaderFile>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <CompileAs>Default</CompileAs>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ResourceOutputFileName>$(IntDir)weather.res</ResourceOutputFileName>
+ </ResourceCompile>
+ <Link>
+ <AdditionalOptions>/ALIGN:4096 /filealign:0x200 /ignore:4108 %(AdditionalOptions)</AdditionalOptions>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <ProgramDatabaseFile>
+ </ProgramDatabaseFile>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <BaseAddress>0x72030000</BaseAddress>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <ImportLibrary>
+ </ImportLibrary>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <SmallerTypeCheck>true</SmallerTypeCheck>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <PrecompiledHeaderFile>weather.h</PrecompiledHeaderFile>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ </ClCompile>
+ <ResourceCompile>
+ <ResourceOutputFileName>$(IntDir)weather.res</ResourceOutputFileName>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <BaseAddress>0x72030000</BaseAddress>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <SmallerTypeCheck>true</SmallerTypeCheck>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <PrecompiledHeaderFile>weather.h</PrecompiledHeaderFile>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ </ClCompile>
+ <ResourceCompile>
+ <ResourceOutputFileName>$(IntDir)weather.res</ResourceOutputFileName>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <BaseAddress>0x72030000</BaseAddress>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <ImportLibrary>
+ </ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\miranda\miranda\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <PrecompiledHeaderFile>weather.h</PrecompiledHeaderFile>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <ResourceCompile>
+ <ResourceOutputFileName>$(IntDir)weather.res</ResourceOutputFileName>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <BaseAddress>0x72030000</BaseAddress>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <PrecompiledHeaderFile>weather.h</PrecompiledHeaderFile>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ </ClCompile>
+ <ResourceCompile>
+ <ResourceOutputFileName>$(IntDir)weather.res</ResourceOutputFileName>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <BaseAddress>0x72030000</BaseAddress>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <ImportLibrary>
+ </ImportLibrary>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="weather.c" />
+ <ClCompile Include="weather_addstn.c" />
+ <ClCompile Include="weather_contacts.c" />
+ <ClCompile Include="weather_conv.c" />
+ <ClCompile Include="weather_data.c" />
+ <ClCompile Include="weather_http.c" />
+ <ClCompile Include="weather_icons.c" />
+ <ClCompile Include="weather_info.c" />
+ <ClCompile Include="weather_ini.c" />
+ <ClCompile Include="weather_mwin.c" />
+ <ClCompile Include="weather_opt.c" />
+ <ClCompile Include="weather_popup.c" />
+ <ClCompile Include="weather_svcs.c" />
+ <ClCompile Include="weather_update.c" />
+ <ClCompile Include="weather_userinfo.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="m_weather.h" />
+ <ClInclude Include="resource.h" />
+ <ClInclude Include="version.h" />
+ <ClInclude Include="weather.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="langpack_defweather.txt" />
+ <None Include="sample_ini.ini" />
+ <None Include="weather-history.txt" />
+ <None Include="weather-readme.html" />
+ <None Include="weather-translation.txt" />
+ <None Include="res\brief.ico" />
+ <None Include="res\disabled.ico" />
+ <None Include="res\edit.ico" />
+ <None Include="res\icon.ico" />
+ <None Include="res\log.ico" />
+ <None Include="res\map.ico" />
+ <None Include="res\more.ico" />
+ <None Include="res\popup.ico" />
+ <None Include="res\popup_no.ico" />
+ <None Include="res\update.ico" />
+ <None Include="res\update2.ico" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="resource.rc" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/plugins/weather/weather_10.vcxproj.filters b/plugins/weather/weather_10.vcxproj.filters
new file mode 100644
index 0000000000..9135282dda
--- /dev/null
+++ b/plugins/weather/weather_10.vcxproj.filters
@@ -0,0 +1,136 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{ae98b833-66fd-4d03-8883-da86b699da8e}</UniqueIdentifier>
+ <Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{229b056a-ba07-4698-ad86-26548bd87e32}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl</Extensions>
+ </Filter>
+ <Filter Include="Documentations">
+ <UniqueIdentifier>{3433a4a3-b1af-4761-ab98-0d4ada361b3a}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{4be16e1a-70ca-4330-b259-db32ec58dcc0}</UniqueIdentifier>
+ <Extensions>ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="weather.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="weather_addstn.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="weather_contacts.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="weather_conv.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="weather_data.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="weather_http.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="weather_icons.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="weather_info.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="weather_ini.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="weather_mwin.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="weather_opt.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="weather_popup.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="weather_svcs.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="weather_update.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="weather_userinfo.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="m_weather.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="resource.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="version.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="weather.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="langpack_defweather.txt">
+ <Filter>Documentations</Filter>
+ </None>
+ <None Include="sample_ini.ini">
+ <Filter>Documentations</Filter>
+ </None>
+ <None Include="weather-history.txt">
+ <Filter>Documentations</Filter>
+ </None>
+ <None Include="weather-readme.html">
+ <Filter>Documentations</Filter>
+ </None>
+ <None Include="weather-translation.txt">
+ <Filter>Documentations</Filter>
+ </None>
+ <None Include="res\brief.ico">
+ <Filter>Resource Files</Filter>
+ </None>
+ <None Include="res\disabled.ico">
+ <Filter>Resource Files</Filter>
+ </None>
+ <None Include="res\edit.ico">
+ <Filter>Resource Files</Filter>
+ </None>
+ <None Include="res\icon.ico">
+ <Filter>Resource Files</Filter>
+ </None>
+ <None Include="res\log.ico">
+ <Filter>Resource Files</Filter>
+ </None>
+ <None Include="res\map.ico">
+ <Filter>Resource Files</Filter>
+ </None>
+ <None Include="res\more.ico">
+ <Filter>Resource Files</Filter>
+ </None>
+ <None Include="res\popup.ico">
+ <Filter>Resource Files</Filter>
+ </None>
+ <None Include="res\popup_no.ico">
+ <Filter>Resource Files</Filter>
+ </None>
+ <None Include="res\update.ico">
+ <Filter>Resource Files</Filter>
+ </None>
+ <None Include="res\update2.ico">
+ <Filter>Resource Files</Filter>
+ </None>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="resource.rc">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/plugins/weather/weather_addstn.c b/plugins/weather/weather_addstn.c
new file mode 100644
index 0000000000..24b965ce19
--- /dev/null
+++ b/plugins/weather/weather_addstn.c
@@ -0,0 +1,438 @@
+/*
+Weather Protocol plugin for Miranda IM
+Copyright (C) 2005-2011 Boris Krasnovskiy All Rights Reserved
+Copyright (C) 2002-2005 Calvin Che
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; version 2
+of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* This file contain the source related to search and add a weather station
+to the contact list. Contain code for both name and ID search.
+*/
+
+#include "weather.h"
+
+// variables used for weather_addstn.c
+static int searchId=-1;
+static char sID[32];
+static char name1[256];
+
+//============ ADDING NEW STATION ============
+
+// protocol service function for adding a new contact onto contact list
+// lParam = PROTOSEARCHRESULT
+INT_PTR WeatherAddToList(WPARAM wParam,LPARAM lParam)
+{
+ PROTOSEARCHRESULT *psr=(PROTOSEARCHRESULT*)lParam;
+ char str[256], svc[256];
+ WIDATA *sData;
+
+ // search for existing contact
+ HANDLE hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0);
+ while(hContact != NULL)
+ {
+ // check if it is a weather contact
+ if(IsMyContact(hContact))
+ {
+ DBVARIANT dbv;
+ // check ID to see if the contact already exist in the database
+ if(!DBGetContactSettingString(hContact,WEATHERPROTONAME,"ID",&dbv))
+ {
+ if(!_stricmp(psr->email,dbv.pszVal))
+ {
+ // remove the flag for not on list and hidden, thus make the contact visible
+ // and add them on the list
+ if (DBGetContactSettingByte(hContact,"CList","NotOnList",1))
+ {
+ DBDeleteContactSetting(hContact,"CList","NotOnList");
+ DBDeleteContactSetting(hContact,"CList","Hidden");
+ }
+ DBFreeVariant(&dbv);
+ // contact is added, function quitting
+ return (INT_PTR)hContact;
+ }
+ DBFreeVariant(&dbv);
+ }
+ }
+ hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hContact,0);
+ }
+
+ // if contact with the same ID was not found, add it
+ if (psr->cbSize < sizeof(PROTOSEARCHRESULT)) return 0;
+ hContact = (HANDLE) CallService(MS_DB_CONTACT_ADD, 0, 0);
+ CallService(MS_PROTO_ADDTOCONTACT, (WPARAM)hContact, (LPARAM)WEATHERPROTONAME);
+ // suppress online notification for the new contact
+ CallService(MS_IGNORE_IGNORE,(WPARAM)hContact, IGNOREEVENT_USERONLINE);
+ // set contact info and settings
+ strncpy(svc, psr->email, sizeof(svc)); svc[sizeof(svc)-1] = 0;
+ GetSvc(svc);
+ // set settings by obtaining the default for the service
+ if (psr->lastName[0] != 0)
+ {
+ sData = GetWIData(svc);
+ DBWriteContactSettingString(hContact, WEATHERPROTONAME, "MapURL", sData->DefaultMap);
+ DBWriteContactSettingString(hContact, WEATHERPROTONAME, "InfoURL", sData->DefaultURL);
+ }
+ else // if no valid service is found, create empty strings for MapURL and InfoURL
+ {
+ DBWriteContactSettingString(hContact, WEATHERPROTONAME, "MapURL", "");
+ DBWriteContactSettingString(hContact, WEATHERPROTONAME, "InfoURL", "");
+ }
+ // write the other info and settings to the database
+ DBWriteContactSettingString(hContact, WEATHERPROTONAME, "ID", psr->email);
+ DBWriteContactSettingString(hContact, WEATHERPROTONAME, "Nick", psr->nick);
+ wsprintf(str, Translate("Current weather information for %s."), psr->nick);
+ DBWriteContactSettingWord(hContact, WEATHERPROTONAME, "Status", ID_STATUS_OFFLINE);
+ AvatarDownloaded(hContact);
+ DBWriteContactSettingString(hContact, WEATHERPROTONAME, "About", str);
+ // make the last update tags to something invalid
+ DBWriteContactSettingString(hContact, WEATHERPROTONAME, "LastLog", "never");
+ DBWriteContactSettingString(hContact, WEATHERPROTONAME, "LastCondition", "None");
+ DBWriteContactSettingString(hContact, WEATHERPROTONAME, "LastTemperature", "None");
+
+ // ignore status change
+ DBWriteContactSettingDword(hContact, "Ignore", "Mask", 8);
+
+ // if no default station is found, set the new contact as default station
+ if (opt.Default[0] == 0)
+ {
+ DBVARIANT dbv;
+ GetStationID(hContact, opt.Default, sizeof(opt.Default));
+
+ opt.DefStn = hContact;
+ if (!DBGetContactSettingString(hContact,WEATHERPROTONAME,"Nick",&dbv))
+ {
+ // notification message box
+ wsprintf(str, Translate("%s is now the default weather station"), dbv.pszVal);
+ DBFreeVariant(&dbv);
+ MessageBox(NULL, str, Translate("Weather Protocol"), MB_OK|MB_ICONINFORMATION);
+ }
+ DBWriteContactSettingString(NULL, WEATHERPROTONAME, "Default", opt.Default);
+ }
+ // display the Edit Settings dialog box
+ EditSettings((WPARAM)hContact, 0);
+ return (INT_PTR)hContact;
+}
+
+//============ WARNING DIALOG ============
+
+// show a message box and cancel search if update is in process
+BOOL CheckSearch() {
+ if (UpdateListHead != NULL) {
+ MessageBox(NULL, Translate("Please try again after weather update is completed."), Translate("Weather Protocol"), MB_OK|MB_ICONERROR);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+//============ BASIC ID SEARCH ============
+
+// A timer process for the ID search (threaded)
+static void __cdecl BasicSearchTimerProc(LPVOID hWnd)
+{
+ int result;
+ // search only when it's not current updating weather.
+ if (CheckSearch()) result = IDSearch(sID, searchId);
+ // broadcast the search result
+ ProtoBroadcastAck(WEATHERPROTONAME,NULL,ACKTYPE_SEARCH,ACKRESULT_SUCCESS,(HANDLE)searchId,0);
+
+ // exit the search
+ searchId=-1;
+}
+
+// the service function for ID search
+// lParam = ID search string
+INT_PTR WeatherBasicSearch(WPARAM wParam,LPARAM lParam)
+{
+ if(searchId != -1) return 0; //only one search at a time
+ strncpy(sID, (char*)lParam, sizeof(sID));
+ sID[sizeof(sID)-1] = 0;
+ searchId=1;
+ // create a thread for the ID search
+ mir_forkthread(BasicSearchTimerProc, NULL);
+ return searchId;
+}
+
+//============ NAME SEARCH ============
+
+// name search timer process (threaded)
+static void __cdecl NameSearchTimerProc(LPVOID hWnd)
+{
+ // search only when it's not current updating weather.
+ if (CheckSearch())
+ {
+ if (name1[0] != 0) NameSearch(name1, searchId); // search nickname field
+ }
+ // broadcast the result
+ ProtoBroadcastAck(WEATHERPROTONAME, NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)searchId, 0);
+
+ // exit the search
+ searchId = -1;
+}
+
+static INT_PTR CALLBACK WeatherSearchAdvancedDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hwndDlg);
+ SetFocus(GetDlgItem(hwndDlg, IDC_SEARCHCITY));
+ return TRUE;
+
+ case WM_COMMAND:
+ if (HIWORD(wParam) == EN_SETFOCUS)
+ PostMessage(GetParent(hwndDlg), WM_COMMAND, MAKEWPARAM(0, EN_SETFOCUS), (LPARAM)hwndDlg);
+ }
+ return FALSE;
+}
+
+INT_PTR WeatherCreateAdvancedSearchUI(WPARAM wParam, LPARAM lParam)
+{
+ HWND parent = (HWND)lParam;
+
+ if (parent)
+ return (INT_PTR)CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_SEARCHCITY), parent, WeatherSearchAdvancedDlgProc, 0);
+
+ return 0;
+}
+
+// service function for name search
+INT_PTR WeatherAdvancedSearch(WPARAM wParam, LPARAM lParam)
+{
+ if (searchId != -1) return 0; //only one search at a time
+ searchId = 1;
+
+ GetDlgItemText((HWND)lParam, IDC_SEARCHCITY, name1, 256);
+
+ // search for the weather station using a thread
+ mir_forkthread(NameSearchTimerProc, NULL);
+ return searchId;
+}
+
+//============ SEARCH FOR A WEATHER STATION USING ID ============
+
+// Seaching station ID from a single weather service (Threaded)
+// sID = search string for the station ID
+// searchId = -1
+// sData = the ID search data for that particular weather service
+// svcname = the name of the weather service that is currently searching (ie. Yahoo Weather)
+int IDSearchProc(char *sID, const int searchId, WIIDSEARCH *sData, char *svc, char *svcname)
+{
+ PROTOSEARCHRESULT psr = {0};
+ char str[MAX_DATA_LEN] = "", newID[MAX_DATA_LEN];
+
+ if (sData->Available)
+ {
+ char loc[255], *szData = NULL;
+
+ // load the page
+ mir_snprintf(loc, sizeof(loc), sData->SearchURL , sID);
+ if (InternetDownloadFile(loc, NULL, &szData) == 0)
+ {
+ char* szInfo = szData;
+
+ // not found
+ if (strstr(szInfo, sData->NotFoundStr) == NULL)
+ GetDataValue(&sData->Name, str, &szInfo);
+ }
+ mir_free(szData);
+ // Station not found exit
+ if (str[0] == 0) return 1;
+ }
+
+ // give no station name but only ID if the search is unavailable
+ else strcpy(str, Translate("<Enter station name here>"));
+ mir_snprintf(newID, sizeof(newID), "%s/%s", svc, sID);
+
+ // set the search result and broadcast it
+ psr.cbSize=sizeof(psr);
+ psr.nick=str;
+ psr.firstName=" ";
+ psr.lastName=svcname;
+ psr.email=newID;
+ ProtoBroadcastAck(WEATHERPROTONAME, NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, (HANDLE)searchId, (LPARAM)&psr);
+
+ return 0;
+}
+
+// ID search (Threaded)
+// sID: the ID to search for
+// searchId: don't change
+// return 0 if no error
+int IDSearch(char *sID, const int searchId)
+{
+ // for a normal ID search (ID != #)
+ if (strcmp(sID, "#"))
+ {
+ WIDATALIST *Item = WIHead;
+
+ // search every weather service using the search station ID
+ while (Item != NULL)
+ {
+ IDSearchProc(sID, searchId, &Item->Data.IDSearch, Item->Data.InternalName, Item->Data.DisplayName);
+ Item = Item->next;
+ }
+ NetlibHttpDisconnect();
+ }
+ // if the station ID is #, return a dummy result and quit the funciton
+ else
+ {
+ PROTOSEARCHRESULT psr = {0};
+ // return an empty contact on "#"
+ psr.cbSize=sizeof(psr);
+ psr.nick=Translate("<Enter station name here>"); // to be entered
+ psr.firstName=" ";
+ psr.lastName="";
+ psr.email=Translate("<Enter station ID here>"); // to be entered
+ ProtoBroadcastAck(WEATHERPROTONAME,NULL,ACKTYPE_SEARCH,ACKRESULT_DATA,(HANDLE)searchId,(LPARAM)&psr);
+ }
+
+ return 0;
+}
+
+//============ SEARCH FOR A WEATHER STATION BY NAME ============
+
+// Seaching station name from a single weather service (Threaded)
+// name = the name of the weather station to be searched
+// searchId = -1
+// sData = the name search data for that particular weather service
+// svcname = the name of the weather service that is currently searching (ie. Yahoo Weather)
+int NameSearchProc(char *name, const int searchId, WINAMESEARCH *sData, char *svc, char *svcname)
+{
+ PROTOSEARCHRESULT psr;
+ char *search, str[MAX_DATA_LEN], loc[256], sID[MAX_DATA_LEN], Name[MAX_DATA_LEN], *szData = NULL;
+
+ // replace spaces with %20
+ char *pstr = (char*)CallService(MS_NETLIB_URLENCODE, 0, (LPARAM) name);
+ wsprintf(loc, sData->SearchURL, pstr);
+ HeapFree(GetProcessHeap(), 0, pstr);
+
+ if (InternetDownloadFile(loc, NULL, &szData) == 0)
+ {
+ char* szInfo = szData;
+ search = strstr(szInfo, sData->NotFoundStr); // determine if data is available
+ if (search == NULL) // if data is found
+ {
+ // test if it is single result
+ if (sData->Single.Available && sData->Multiple.Available)
+ search = strstr(szInfo, sData->SingleStr);
+ // for single result
+ if (sData->Single.Available && (search != NULL || !sData->Multiple.Available)) // single result
+ {
+ // if station ID appears first in the downloaded data
+ if (!_stricmp(sData->Single.First, "ID"))
+ {
+ GetDataValue(&sData->Single.ID, str, &szInfo);
+ wsprintf(sID, "%s/%s", svc, str);
+ GetDataValue(&sData->Single.Name, Name, &szInfo);
+ }
+ // if station name appears first in the downloaded data
+ else if (!_stricmp(sData->Single.First, "NAME"))
+ {
+ GetDataValue(&sData->Single.Name, Name, &szInfo);
+ GetDataValue(&sData->Single.ID, str, &szInfo);
+ wsprintf(sID, "%s/%s", svc, str);
+ }
+ // if no station ID is obtained, quit the search
+ if (str[0] == 0)
+ {
+ mir_free(szData);
+ return 1;
+ }
+ // if can't get the name, use the search string as name
+ if (Name[0] == 0) strcpy(Name, name);
+
+ // set the data and broadcast it
+ memset(&psr,0,sizeof(psr));
+ psr.cbSize=sizeof(psr);
+ psr.nick=Name;
+ psr.firstName=" ";
+ psr.lastName=svcname;
+ psr.email=sID;
+ psr.id=sID;
+ ProtoBroadcastAck(WEATHERPROTONAME,NULL,ACKTYPE_SEARCH,ACKRESULT_DATA,(HANDLE)searchId,(LPARAM)&psr);
+ mir_free(szData);
+ return 0;
+ }
+ // for multiple result
+ else if (sData->Multiple.Available) // multiple results
+ {
+ // search for the next occurrence of the string
+ for (;;)
+ {
+ // if station ID appears first in the downloaded data
+ if (!_stricmp(sData->Multiple.First, "ID")) {
+ GetDataValue(&sData->Multiple.ID, str, &szInfo);
+ wsprintf(sID, "%s/%s", svc, str);
+ GetDataValue(&sData->Multiple.Name, Name, &szInfo);
+ }
+ // if station name appears first in the downloaded data
+ else if (!_stricmp(sData->Multiple.First, "NAME")) {
+ GetDataValue(&sData->Multiple.Name, Name, &szInfo);
+ GetDataValue(&sData->Multiple.ID, str, &szInfo);
+ wsprintf(sID, "%s/%s", svc, str);
+ }
+ // if no station ID is obtained, search completed and quit the search
+ if (str[0] == 0) break;
+ // if can't get the name, use the search string as name
+ if (Name[0] == 0) strcpy(Name, name);
+
+ memset(&psr,0,sizeof(psr));
+ psr.cbSize=sizeof(psr);
+ psr.nick=Name;
+ psr.firstName="";
+ psr.lastName=svcname;
+ psr.email=sID;
+ psr.id=sID;
+ ProtoBroadcastAck(WEATHERPROTONAME,NULL,ACKTYPE_SEARCH,ACKRESULT_DATA,
+ (HANDLE)searchId,(LPARAM)&psr);
+ }
+ }
+ }
+ mir_free(szData);
+ return 0;
+ }
+ mir_free(szData);
+ return 1;
+}
+
+// name search (Threaded)
+// name: the station name to search for
+// searchId: don't change
+// return 0 if no error
+int NameSearch(char *name, const int searchId)
+{
+ WIDATALIST *Item = WIHead;
+
+ // search every weather service using the search station name
+ while (Item != NULL)
+ {
+ if (Item->Data.NameSearch.Single.Available || Item->Data.NameSearch.Multiple.Available)
+ NameSearchProc(name, searchId, &Item->Data.NameSearch, Item->Data.InternalName, Item->Data.DisplayName);
+ Item = Item->next;
+ }
+ NetlibHttpDisconnect();
+
+ return 0;
+}
+
+//====================== MENU ITEM FUNCTION ============
+
+// add a new weather station via find/add dialog
+int WeatherAdd(WPARAM wParam, LPARAM lParam)
+{
+ DBWriteContactSettingString(NULL, "FindAdd", "LastSearched", "Weather");
+ CallService(MS_FINDADD_FINDADD, 0, 0);
+ return 0;
+}
diff --git a/plugins/weather/weather_contacts.c b/plugins/weather/weather_contacts.c
new file mode 100644
index 0000000000..da876963b0
--- /dev/null
+++ b/plugins/weather/weather_contacts.c
@@ -0,0 +1,515 @@
+/*
+Weather Protocol plugin for Miranda IM
+Copyright (C) 2005-2011 Boris Krasnovskiy All Rights Reserved
+Copyright (C) 2002-2005 Calvin Che
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; version 2
+of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* This file contain the source that is related to weather contacts,
+include the links, edit settings, and loading weather information for
+the contact.
+*/
+
+#include "weather.h"
+
+//============ BASIC CONTACTS FUNCTIONS AND LINKS ============
+
+// view weather log for the contact
+// wParam = current contact
+INT_PTR ViewLog(WPARAM wParam,LPARAM lParam)
+{
+ DBVARIANT dbv;
+ // see if the log path is set
+ if (!DBGetContactSettingTString((HANDLE)wParam,WEATHERPROTONAME,"Log",&dbv))
+ {
+ if (dbv.pszVal[0] != 0)
+ ShellExecute((HWND)lParam, _T("open"), dbv.ptszVal, _T(""), _T(""), SW_SHOW);
+ DBFreeVariant(&dbv);
+ }
+ else // display warning dialog if no path is specified
+ MessageBox(NULL, TranslateT("Weather condition was not logged."),
+ TranslateT("Weather Protocol"), MB_OK | MB_ICONINFORMATION);
+ return 0;
+}
+
+// read complete forecast
+// wParam = current contact
+INT_PTR LoadForecast(WPARAM wParam,LPARAM lParam)
+{
+ char id[256], loc[256], loc2[256];
+
+ // get station ID
+ GetStationID((HANDLE)wParam, id, sizeof(id));
+
+ if (id[0] != 0)
+ {
+ GetID(id);
+
+ // check if the complte forecast URL is set. If it is not, display warning and quit
+ if (DBGetStaticString((HANDLE)wParam, WEATHERPROTONAME, "InfoURL", loc2, sizeof(loc2)) || loc2[0] == 0)
+ {
+ MessageBox(NULL, TranslateT("The URL for complete forcast have not been set. You can set it from the Edit Settings dialog."),
+ TranslateT("Weather Protocol"), MB_ICONINFORMATION);
+ return 1;
+ }
+ // set the url and open the webpage
+ mir_snprintf(loc, sizeof(loc), loc2, id);
+ CallService(MS_UTILS_OPENURL, opt.NewBrowserWin, (WPARAM)loc);
+ }
+ return 0;
+}
+
+// load weather map
+// wParam = current contact
+INT_PTR WeatherMap(WPARAM wParam,LPARAM lParam)
+{
+ char id[256], loc[256], loc2[256];
+
+ GetStationID((HANDLE)wParam, id, sizeof(id));
+
+ if (id[0] != 0)
+ {
+ GetID(id);
+
+ // check if the weather map URL is set. If it is not, display warning and quit
+ if (DBGetStaticString((HANDLE)wParam, WEATHERPROTONAME, "MapURL", loc2, sizeof(loc2)) || loc2[0] == 0)
+ {
+ MessageBox(NULL, TranslateT("The URL for weather map have not been set. You can set it from the Edit Settings dialog."), TranslateT("Weather Protocol"), MB_ICONINFORMATION);
+ return 1;
+ }
+ // set the url and open the webpage
+ mir_snprintf(loc, sizeof(loc), loc2, id);
+ CallService(MS_UTILS_OPENURL, opt.NewBrowserWin, (WPARAM)loc);
+ }
+
+ return 0;
+}
+
+//============ EDIT SETTINGS ============
+
+// show edit settings dialog
+// wParam = current contact
+INT_PTR EditSettings(WPARAM wParam,LPARAM lParam)
+{
+ HWND hEditDlg = WindowList_Find(hWindowList, (HANDLE)wParam);
+
+ // search the dialog list to prevent multiple instance of dialog for the same contact
+ if (hEditDlg != NULL)
+ {
+ // if the dialog box already opened, bring it to the front
+ SetForegroundWindow(hEditDlg);
+ SetFocus(hEditDlg);
+ }
+ else
+ {
+ if(IsMyContact((HANDLE)wParam))
+ {
+ // if the dialog box is not opened, open a new one
+ CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_EDIT), NULL, DlgProcChange, (LPARAM)wParam);
+ }
+ }
+
+ return 0;
+}
+
+typedef struct
+{
+ HANDLE hContact;
+ HICON hRename;
+ HICON hUserDetail;
+ HICON hFile;
+ HICON hSrchAll;
+} CntSetWndDataType;
+
+// edit weather settings
+// lParam = current contact
+INT_PTR CALLBACK DlgProcChange(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ DBVARIANT dbv;
+ char str[256], str2[256], city[256], filter[256], *pfilter, loc[512], *chop;
+ OPENFILENAME ofn; // common dialog box structure
+ HANDLE hContact;
+ WIDATA *sData;
+ CntSetWndDataType *wndData = NULL;
+
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hwndDlg);
+
+ wndData = mir_alloc(sizeof(CntSetWndDataType));
+ wndData->hContact = hContact = (HANDLE)lParam;
+ wndData->hRename = LoadSkinnedIcon(SKINICON_OTHER_RENAME);
+ wndData->hUserDetail = LoadSkinnedIcon(SKINICON_OTHER_USERDETAILS);
+ wndData->hFile = LoadSkinnedIcon(SKINICON_EVENT_FILE);
+ wndData->hSrchAll = LoadSkinnedIcon(SKINICON_OTHER_SEARCHALL);
+
+ SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)wndData);
+
+ // set button images
+ SendDlgItemMessage(hwndDlg, IDC_GETNAME, BM_SETIMAGE, IMAGE_ICON, (LPARAM)wndData->hRename);
+ SendDlgItemMessage(hwndDlg, IDC_SVCINFO, BM_SETIMAGE, IMAGE_ICON, (LPARAM)wndData->hUserDetail);
+ SendDlgItemMessage(hwndDlg, IDC_BROWSE, BM_SETIMAGE, IMAGE_ICON, (LPARAM)wndData->hFile);
+ SendDlgItemMessage(hwndDlg, IDC_VIEW1, BM_SETIMAGE, IMAGE_ICON, (LPARAM)wndData->hSrchAll);
+ SendDlgItemMessage(hwndDlg, IDC_RESET1, BM_SETIMAGE, IMAGE_ICON, (LPARAM)wndData->hRename);
+ SendDlgItemMessage(hwndDlg, IDC_VIEW2, BM_SETIMAGE, IMAGE_ICON, (LPARAM)wndData->hSrchAll);
+ SendDlgItemMessage(hwndDlg, IDC_RESET2, BM_SETIMAGE, IMAGE_ICON, (LPARAM)wndData->hRename);
+
+ // make all buttons flat
+ SendDlgItemMessage(hwndDlg,IDC_GETNAME, BUTTONSETASFLATBTN, 0, 0);
+ SendDlgItemMessage(hwndDlg,IDC_SVCINFO, BUTTONSETASFLATBTN, 0, 0);
+ SendDlgItemMessage(hwndDlg,IDC_BROWSE, BUTTONSETASFLATBTN, 0, 0);
+ SendDlgItemMessage(hwndDlg,IDC_VIEW1, BUTTONSETASFLATBTN, 0, 0);
+ SendDlgItemMessage(hwndDlg,IDC_RESET1, BUTTONSETASFLATBTN, 0, 0);
+ SendDlgItemMessage(hwndDlg,IDC_VIEW2, BUTTONSETASFLATBTN, 0, 0);
+ SendDlgItemMessage(hwndDlg,IDC_RESET2, BUTTONSETASFLATBTN, 0, 0);
+
+ // set tooltip for the buttons
+ SendDlgItemMessage(hwndDlg,IDC_GETNAME, BUTTONADDTOOLTIP, (WPARAM)"Get city name from ID", 0);
+ SendDlgItemMessage(hwndDlg,IDC_SVCINFO, BUTTONADDTOOLTIP, (WPARAM)"Weather INI information", 0);
+ SendDlgItemMessage(hwndDlg,IDC_BROWSE, BUTTONADDTOOLTIP, (WPARAM)"Browse", 0);
+ SendDlgItemMessage(hwndDlg,IDC_VIEW1, BUTTONADDTOOLTIP, (WPARAM)"View webpage", 0);
+ SendDlgItemMessage(hwndDlg,IDC_RESET1, BUTTONADDTOOLTIP, (WPARAM)"Reset to default", 0);
+ SendDlgItemMessage(hwndDlg,IDC_VIEW2, BUTTONADDTOOLTIP, (WPARAM)"View webpage", 0);
+ SendDlgItemMessage(hwndDlg, IDC_RESET2, BUTTONADDTOOLTIP, (WPARAM)"Reset to default", 0);
+
+ // save the handle for the contact
+ WindowList_Add(hWindowList, hwndDlg, hContact);
+
+ // start to get the settings
+ // if the setting not exist, leave the dialog box blank
+ if(!DBGetContactSettingString(hContact,WEATHERPROTONAME,"ID",&dbv))
+ {
+ SetDlgItemTextA(hwndDlg,IDC_ID,dbv.pszVal);
+ // check if the station is a default station
+ if (!strcmp(dbv.pszVal, opt.Default))
+ CheckDlgButton(hwndDlg, IDC_DEFA, TRUE);
+ else CheckDlgButton(hwndDlg, IDC_DEFA, FALSE);
+ DBFreeVariant(&dbv);
+ }
+ if(!DBGetContactSettingTString(hContact,WEATHERPROTONAME,"Nick",&dbv))
+ {
+ SetDlgItemText(hwndDlg,IDC_NAME,dbv.ptszVal);
+ DBFreeVariant(&dbv);
+ }
+ if(!DBGetContactSettingTString(hContact,WEATHERPROTONAME,"Log",&dbv))
+ {
+ SetDlgItemText(hwndDlg, IDC_LOG, dbv.ptszVal);
+ // if the log path is not empty, check the checkbox for external log
+ if (dbv.ptszVal[0]) CheckDlgButton(hwndDlg, IDC_External, TRUE);
+ DBFreeVariant(&dbv);
+ }
+ // enable/disable the browse button depending on the value of external log checkbox
+ EnableWindow(GetDlgItem(hwndDlg,IDC_BROWSE),(BYTE)IsDlgButtonChecked(hwndDlg,IDC_External));
+
+ // other checkbox options
+ CheckDlgButton(hwndDlg, IDC_DPop, DBGetContactSettingByte(hContact,WEATHERPROTONAME,"DPopUp",FALSE));
+ CheckDlgButton(hwndDlg, IDC_DAutoUpdate, DBGetContactSettingByte(hContact,WEATHERPROTONAME,
+ "DAutoUpdate",FALSE));
+ CheckDlgButton(hwndDlg, IDC_Internal, DBGetContactSettingByte(hContact,WEATHERPROTONAME,"History",0));
+ if (!DBGetContactSettingString(hContact,WEATHERPROTONAME,"InfoURL",&dbv))
+ {
+ SetDlgItemText(hwndDlg,IDC_IURL,dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+ if (!DBGetContactSettingString(hContact,WEATHERPROTONAME,"MapURL",&dbv))
+ {
+ SetDlgItemText(hwndDlg,IDC_MURL,dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+
+ // display the dialog box and free memory
+ Utils_RestoreWindowPositionNoMove(hwndDlg,NULL,WEATHERPROTONAME,"EditSetting_");
+ ShowWindow(hwndDlg,SW_SHOW);
+ break;
+
+ case WM_COMMAND:
+ wndData = (CntSetWndDataType*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
+ hContact = wndData ? wndData->hContact : NULL;
+
+ switch(LOWORD(wParam))
+ {
+ case IDC_ID:
+ // check if there are 2 parts in the ID (svc/id) seperated by "/"
+ // if not, don't let user change the setting
+ GetDlgItemText(hwndDlg,IDC_ID,str,sizeof(str));
+ chop = strstr(str, "/");
+ if (chop == NULL)
+ EnableWindow(GetDlgItem(hwndDlg,IDC_CHANGE),FALSE);
+ else
+ EnableWindow(GetDlgItem(hwndDlg,IDC_CHANGE),TRUE);
+ break;
+ case IDC_NAME:
+ // check if station name is entered
+ // if not, don't let user change the setting
+ GetDlgItemText(hwndDlg,IDC_NAME,str,sizeof(str));
+ EnableWindow(GetDlgItem(hwndDlg,IDC_CHANGE),str[0] != 0);
+ break;
+ case IDC_GETNAME:
+ {
+ // the button for getting station name from the internet
+ // this function uses the ID search for add/find weather station
+ WIDATA *sData;
+
+ if (!CheckSearch()) return TRUE; // don't download if update is in progress
+ // get the weather update data using the string in the ID field
+ GetDlgItemText(hwndDlg,IDC_ID,str,sizeof(str));
+ GetSvc(str);
+ sData = GetWIData(str);
+ GetDlgItemText(hwndDlg,IDC_ID,str,sizeof(str));
+ GetID(str);
+ // if ID search is available, do it
+ if (sData->IDSearch.Available)
+ {
+ char *szData = NULL;
+
+ // load the page
+ wsprintf(loc, sData->IDSearch.SearchURL, str);
+ str[0] = 0;
+ if (InternetDownloadFile(loc, NULL, &szData) == 0)
+ {
+ char *szInfo = szData;
+ char* search = strstr(szInfo, sData->IDSearch.NotFoundStr);
+
+ // if the page is found (ie. valid ID), get the name of the city
+ if (search == NULL)
+ GetDataValue(&sData->IDSearch.Name, str, &szInfo);
+
+ // free memory
+ mir_free(szData);
+ }
+ NetlibHttpDisconnect();
+ }
+ // give no station name but only ID if the search is unavailable
+ if (str[0] != 0) SetDlgItemText(hwndDlg,IDC_NAME,str);
+ break;
+ }
+ case IDC_External:
+ // enable/disable the borwse button depending if the external log is enabled
+ EnableWindow(GetDlgItem(hwndDlg,IDC_BROWSE),(BYTE)IsDlgButtonChecked(hwndDlg,IDC_External));
+ if (!(BYTE)IsDlgButtonChecked(hwndDlg,IDC_External)) return TRUE;
+
+ case IDC_BROWSE: // fall through
+ // browse for the external log file
+ GetDlgItemText(hwndDlg,IDC_LOG,str,sizeof(str));
+ // Initialize OPENFILENAME
+ ZeroMemory(&ofn, sizeof(OPENFILENAME));
+ ofn.lStructSize = sizeof(OPENFILENAME);
+ ofn.hwndOwner = hwndDlg;
+ ofn.lpstrFile = str;
+ ofn.nMaxFile = sizeof(str);
+ // set filters
+ strcpy(filter,Translate("Text Files"));
+ strcat(filter," (*.txt)");
+ pfilter=filter+strlen(filter)+1;
+ strcpy(pfilter,"*.txt");
+ pfilter=pfilter+strlen(pfilter)+1;
+ strcpy(pfilter,Translate("All Files"));
+ strcat(pfilter," (*.*)");
+ pfilter=pfilter+strlen(pfilter)+1;
+ strcpy(pfilter,"*.*");
+ pfilter=pfilter+strlen(pfilter)+1;
+ *pfilter='\0';
+ ofn.lpstrFilter = filter;
+ ofn.nFilterIndex = 1;
+ ofn.lpstrFileTitle = NULL;
+ ofn.nMaxFileTitle = 0;
+ ofn.lpstrInitialDir = NULL;
+ ofn.Flags = OFN_PATHMUSTEXIST;
+
+ // Display a Open dialog box and put the file name on the dialog
+ if(GetOpenFileName(&ofn))
+ SetDlgItemText(hwndDlg,IDC_LOG,ofn.lpstrFile);
+ // if there is no log file specified, disable external logging
+ EnableWindow(GetDlgItem(hwndDlg,IDC_CHANGE),ofn.lpstrFile[0] != 0);
+ break;
+
+ case IDC_VIEW1:
+ // view the page for more info
+ GetDlgItemText(hwndDlg,IDC_IURL,str,sizeof(str));
+ if (str[0] == 0) return TRUE;
+ GetDlgItemText(hwndDlg,IDC_ID,str2,sizeof(str2));
+ GetID(str2);
+ wsprintf(loc, str, str2);
+ CallService(MS_UTILS_OPENURL, opt.NewBrowserWin, (WPARAM)loc);
+ break;
+
+ case IDC_VIEW2:
+ // view the page for weather map
+ GetDlgItemText(hwndDlg,IDC_MURL,str,sizeof(str));
+ if (str[0] == 0) return TRUE;
+ GetDlgItemText(hwndDlg,IDC_ID,str2,sizeof(str2));
+ GetID(str2);
+ wsprintf(loc, str, str2);
+ CallService(MS_UTILS_OPENURL, opt.NewBrowserWin, (WPARAM)loc);
+ break;
+
+ case IDC_RESET1:
+ // reset the more info url to service default
+ GetDlgItemText(hwndDlg,IDC_ID,str,sizeof(str));
+ GetSvc(str);
+ sData = GetWIData(str);
+ SetDlgItemText(hwndDlg,IDC_IURL,sData->DefaultURL);
+ break;
+
+ case IDC_RESET2:
+ // reset the weathe map url to service default
+ GetDlgItemText(hwndDlg,IDC_ID,str,sizeof(str));
+ GetSvc(str);
+ sData = GetWIData(str);
+ SetDlgItemText(hwndDlg,IDC_MURL,sData->DefaultMap);
+ break;
+
+ case IDC_SVCINFO:
+ // display the information of the ini file used by the weather station
+ GetDlgItemText(hwndDlg,IDC_ID,str,sizeof(str));
+ GetSvc(str);
+ GetINIInfo(str);
+ break;
+
+ case IDC_CHANGE:
+ // temporary disable the protocol while applying the change
+ // start writing the new settings to database
+ GetDlgItemText(hwndDlg,IDC_ID,str,sizeof(str));
+ DBWriteContactSettingString(hContact, WEATHERPROTONAME, "ID", str);
+ if ((BYTE)IsDlgButtonChecked(hwndDlg,IDC_DEFA)) { // if default station is set
+ strcpy(opt.Default, str);
+ opt.DefStn = hContact;
+ DBWriteContactSettingString(NULL, WEATHERPROTONAME, "Default", opt.Default);
+ }
+ GetDlgItemText(hwndDlg,IDC_NAME,city,sizeof(city));
+ DBWriteContactSettingString(hContact, WEATHERPROTONAME, "Nick", city);
+ wsprintf(str2, Translate("Current weather information for %s."), city);
+ if ((BYTE)IsDlgButtonChecked(hwndDlg,IDC_External))
+ {
+ GetDlgItemText(hwndDlg,IDC_LOG,str,sizeof(str));
+ DBWriteContactSettingString(hContact, WEATHERPROTONAME, "Log", str);
+ }
+ else
+ DBDeleteContactSetting(hContact, WEATHERPROTONAME, "Log");
+ GetDlgItemTextA(hwndDlg,IDC_IURL,str,sizeof(str));
+ DBWriteContactSettingString(hContact, WEATHERPROTONAME, "InfoURL", str);
+ GetDlgItemTextA(hwndDlg,IDC_MURL,str,sizeof(str));
+ DBWriteContactSettingString(hContact, WEATHERPROTONAME, "MapURL", str);
+ DBWriteContactSettingWord(hContact, WEATHERPROTONAME, "Status", ID_STATUS_OFFLINE);
+ DBWriteContactSettingWord(hContact, WEATHERPROTONAME, "StatusIcon", ID_STATUS_OFFLINE);
+ AvatarDownloaded(hContact);
+ DBWriteContactSettingString(hContact, WEATHERPROTONAME, "About", str2);
+ DBWriteContactSettingByte(hContact,WEATHERPROTONAME,"History",(BYTE)IsDlgButtonChecked(hwndDlg,IDC_Internal));
+ DBWriteContactSettingByte(hContact,WEATHERPROTONAME,"Overwrite",(BYTE)IsDlgButtonChecked(hwndDlg,IDC_Overwrite));
+ DBWriteContactSettingByte(hContact,WEATHERPROTONAME,"File",(BYTE)IsDlgButtonChecked(hwndDlg,IDC_External));
+ DBWriteContactSettingByte(hContact,WEATHERPROTONAME,"DPopUp",(BYTE)IsDlgButtonChecked(hwndDlg,IDC_DPop));
+ DBWriteContactSettingByte(hContact,WEATHERPROTONAME,"DAutoUpdate",(BYTE)IsDlgButtonChecked(hwndDlg,IDC_DAutoUpdate));
+
+ // re-enable the protocol and update the data for the station
+ DBWriteContactSettingString(hContact, WEATHERPROTONAME, "LastCondition", "None");
+ UpdateSingleStation((WPARAM)hContact, 0);
+
+ case IDCANCEL: // fall through
+ // remove the dialog from window list and close it
+ DestroyWindow(hwndDlg);
+ break;
+ }
+ break;
+
+ case WM_CLOSE:
+ // remove the dialog from window list and close it
+ DestroyWindow(hwndDlg);
+ break;
+
+ case WM_DESTROY:
+ wndData = (CntSetWndDataType*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
+ CallService(MS_SKIN2_RELEASEICON, (WPARAM)wndData->hFile, 0);
+ CallService(MS_SKIN2_RELEASEICON, (WPARAM)wndData->hRename, 0);
+ CallService(MS_SKIN2_RELEASEICON, (WPARAM)wndData->hSrchAll, 0);
+ CallService(MS_SKIN2_RELEASEICON, (WPARAM)wndData->hUserDetail, 0);
+ mir_free(wndData);
+ SetWindowLongPtr(hwndDlg, GWLP_USERDATA, 0);
+
+ WindowList_Remove(hWindowList, hwndDlg);
+ Utils_SaveWindowPosition(hwndDlg,NULL,WEATHERPROTONAME,"EditSetting_");
+ break;
+ }
+ return FALSE;
+}
+
+//============ CONTACT DELETION ============
+
+// when a contact is deleted, make sure some other contact take over the default station
+// wParam = deleted contact
+int ContactDeleted(WPARAM wParam,LPARAM lParam)
+{
+ DBVARIANT dbv;
+
+ if(!IsMyContact((HANDLE)wParam)) return 0;
+
+ removeWindow((HANDLE)wParam);
+
+ // exit this function if it is not default station
+ if (!DBGetContactSettingString((HANDLE)wParam, WEATHERPROTONAME, "ID", &dbv))
+ {
+ if (strcmp(dbv.pszVal, opt.Default))
+ {
+ DBFreeVariant(&dbv);
+ return 0;
+ }
+ DBFreeVariant(&dbv);
+ }
+
+ // now the default station is deleted, try to get a new one
+ {
+ // start looking for other weather stations
+ HANDLE hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ while(hContact)
+ {
+ if(IsMyContact(hContact))
+ {
+ if (!DBGetContactSettingString(hContact, WEATHERPROTONAME, "ID", &dbv))
+ {
+ // if the station is not a default station, set it as the new default station
+ // this is the first weather station encountered from the search
+ if (strcmp(opt.Default, dbv.pszVal))
+ {
+ strcpy(opt.Default, dbv.pszVal);
+ opt.DefStn = hContact;
+ DBFreeVariant(&dbv);
+ if (!DBGetContactSettingTString(hContact,WEATHERPROTONAME,"Nick",&dbv))
+ {
+ TCHAR str[255];
+ mir_sntprintf(str, SIZEOF(str), TranslateT("%s is now the default weather station"), dbv.ptszVal);
+ DBFreeVariant(&dbv);
+ MessageBox(NULL, str, TranslateT("Weather Protocol"), MB_OK | MB_ICONINFORMATION);
+ }
+ DBWriteContactSettingString(NULL, WEATHERPROTONAME, "Default", opt.Default);
+ return 0; // exit this function quickly
+ }
+ DBFreeVariant(&dbv);
+ }
+ }
+ hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0);
+ }
+ // got here if no more weather station left
+ opt.Default[0] = 0; // no default station
+ opt.DefStn = NULL;
+ DBWriteContactSettingString(NULL, WEATHERPROTONAME, "Default", opt.Default);
+ }
+ return 0;
+}
+
+BOOL IsMyContact(HANDLE hContact)
+{
+ const char* szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
+ return szProto != NULL && strcmp(WEATHERPROTONAME, szProto) == 0;
+}
diff --git a/plugins/weather/weather_conv.c b/plugins/weather/weather_conv.c
new file mode 100644
index 0000000000..82e86a7765
--- /dev/null
+++ b/plugins/weather/weather_conv.c
@@ -0,0 +1,809 @@
+/*
+Weather Protocol plugin for Miranda IM
+Copyright (C) 2005-2011 Boris Krasnovskiy All Rights Reserved
+Copyright (C) 2002-2005 Calvin Che
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; version 2
+of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+This file contain the source related unit conversion, icon assignment,
+string conversions, display text parsing, etc
+*/
+
+#include "weather.h"
+
+//============ SOME HELPER FUNCTIONS ============
+
+// see if a string is a number
+// s = the string to be determined
+// return value = true if the string is a number, false if it isn't
+BOOL is_number(char *s)
+{
+ BOOL tag = FALSE;
+ // looking character by character
+ // for a number: numerous spaces in front, then optional +/-, then the number
+ // don't care anything that comes after it
+ while(*s != '\0')
+ {
+ if (*s >= '0' && *s <='9') return TRUE;
+ else if (*s == ' ');
+ else if (*s != '+' && *s != '-') return FALSE;
+ else if ((*s == '+' || *s == '-') && !tag) tag = TRUE;
+ else return FALSE;
+ s++;
+ }
+ return FALSE;
+}
+
+static void numToStr(double num, char* str)
+{
+ int i = (int)(num * (opt.NoFrac ? 10 : 100));
+ int u = abs(i);
+
+ int r = u % 10;
+ int w = u / 10 + (r >= 5);
+
+ if (opt.NoFrac)
+ {
+ r = 0;
+ }
+ else
+ {
+ r = w % 10;
+ w /= 10;
+ }
+
+ if (i < 0 && (w || r)) *(str++) = '-';
+ if (r)
+ sprintf(str, "%i.%i", w, r);
+ else
+ sprintf(str, "%i", w);
+}
+
+//============ UNIT CONVERSIONS ============
+
+// temperature conversion
+// tempchar = the string containing the temperature value
+// unit = the unit for temperature
+// return value = the converted temperature with degree sign and unit; if fails, return N/A
+void GetTemp(char *tempchar, char *unit, char* str)
+{
+ // unit can be C, F
+ double temp;
+ char tstr[20];
+
+ TrimString(tempchar);
+ if (tempchar[0] == '-' && tempchar[1] == ' ')
+ memmove(&tempchar[1], &tempchar[2], strlen(&tempchar[2])+1);
+
+ // quit if the value obtained is N/A or not a number
+ if (!strcmp(tempchar, NODATA) || !strcmp(tempchar, "N/A"))
+ {
+ strcpy(str, tempchar);
+ return;
+ }
+ if (!is_number(tempchar))
+ {
+ strcpy(str, NODATA);
+ return;
+ }
+
+ // convert the string to an integer
+ temp = atof(tempchar);
+
+ // convert all to F first
+ if (!_stricmp(unit, "C")) temp = (temp*9/5)+32;
+ else if (!_stricmp(unit, "K")) temp = ((temp-273.15)*9/5)+32;
+
+ // convert to apporiate unit
+ switch (opt.tUnit)
+ {
+ case 1:
+ // rounding
+ numToStr((temp-32)/9*5, tstr);
+ if (opt.DoNotAppendUnit)
+ sprintf(str, "%s", tstr);
+ else
+ sprintf(str, "%s%sC", tstr, opt.DegreeSign);
+ break;
+
+ case 2:
+ numToStr(temp, tstr);
+ if (opt.DoNotAppendUnit)
+ sprintf(str, "%s", tstr);
+ else
+ sprintf(str, "%s%sF", tstr, opt.DegreeSign);
+ break;
+ }
+}
+
+// temperature conversion
+// tempchar = the string containing the pressure value
+// unit = the unit for pressure
+// return value = the converted pressure with unit; if fail, return the original string
+void GetPressure(char *tempchar, char *unit, char* str)
+{
+ // unit can be kPa, hPa, mb, in, mm, torr
+ double tempunit = 0, output;
+ int intunit;
+
+ // convert the string to a floating point number (always positive)
+ // if it end up with 0, then it's not a number, return the original string and quit
+ output = atof(tempchar);
+ if (output == 0)
+ {
+ strcpy(str, tempchar);
+ return;
+ }
+
+ // convert all to mb first
+ if (!_stricmp(unit, "KPA"))
+ tempunit = (double)output * 10;
+ else if (!_stricmp(unit, "HPA"))
+ tempunit = (double)output;
+ else if (!_stricmp(unit, "MB"))
+ tempunit = (double)output;
+ else if (!_stricmp(unit, "IN"))
+ tempunit = (double)output * 33.86388;
+ else if (!_stricmp(unit, "MM"))
+ tempunit = (double)output * 1.33322;
+ else if (!_stricmp(unit, "TORR"))
+ tempunit = (double)output * 1.33322;
+
+ // convert to apporiate unit
+ switch (opt.pUnit)
+ {
+ case 1:
+ intunit = (int)(tempunit + 0.5);
+ wsprintf(str, "%i.%i %s", intunit/10, intunit%10, opt.DoNotAppendUnit ? "" : Translate("kPa"));
+ break;
+ case 2:
+ intunit = (int)(tempunit + 0.5);
+ wsprintf(str, "%i %s", intunit, opt.DoNotAppendUnit ? "" : Translate("mb"));
+ break;
+ case 3:
+ intunit = (int)((tempunit*10 / 33.86388) + 0.5);
+ wsprintf(str, "%i.%i %s", intunit/10, intunit%10, opt.DoNotAppendUnit ? "" : Translate("in"));
+ break;
+ case 4:
+ intunit = (int)((tempunit*10 / 1.33322) + 0.5);
+ wsprintf(str, "%i.%i %s", intunit/10, intunit%10, opt.DoNotAppendUnit ? "" : Translate("mm"));
+ break;
+ default:
+ strcpy(str, tempchar);
+ break;
+
+ }
+}
+
+// speed conversion
+// tempchar = the string containing the speed value
+// unit = the unit for speed
+// return value = the converted speed with unit; if fail, return ""
+void GetSpeed(char *tempchar, char *unit, char *str)
+{
+ // unit can be km/h, mph, m/s, knots
+ double tempunit;
+ char tstr[20];
+
+ str[0] = 0;
+
+ // convert the string into an integer (always positive)
+ // if the result is 0, then the string is not a number, return ""
+ tempunit = atof(tempchar);
+ if (tempunit == 0 && tempchar[0] != '0') return;
+
+ // convert all to m/s first
+ if (!_stricmp(unit, "KM/H"))
+ tempunit /= 3.6;
+// else if (!_stricmp(unit, "M/S"))
+// tempunit = tempunit;
+ else if (!_stricmp(unit, "MPH"))
+ tempunit *= 0.44704;
+ else if (!_stricmp(unit, "KNOTS"))
+ tempunit *= 0.514444;
+
+ // convert to apporiate unit
+ switch (opt.wUnit)
+ {
+ case 1:
+ numToStr(tempunit * 3.6, tstr);
+ sprintf(str, "%s %s", tstr, opt.DoNotAppendUnit ? "" : Translate("km/h"));
+ break;
+ case 2:
+ numToStr(tempunit, tstr);
+ sprintf(str, "%s %s", tstr, opt.DoNotAppendUnit ? "" : Translate("m/s"));
+ break;
+ case 3:
+ numToStr(tempunit / 0.44704, tstr);
+ sprintf(str, "%s %s", tstr, opt.DoNotAppendUnit ? "" : Translate("mph"));
+ break;
+ case 4:
+ numToStr(tempunit / 0.514444, tstr);
+ sprintf(str, "%s %s", tstr, opt.DoNotAppendUnit ? "" : Translate("knots"));
+ break;
+ }
+}
+
+// distance conversion
+// tempchar = the string containing the distance value
+// unit = the unit for distance
+// return value = the converted distance with unit; if fail, return original string
+void GetDist(char *tempchar, char *unit, char *str)
+{
+ // unit can be km, miles
+ double tempunit = 0, output;
+ int intunit;
+
+ // convert the string to a floating point number (always positive)
+ // if it end up with 0, then it's not a number, return the original string and quit
+ output = atof(tempchar);
+ if (output == 0)
+ {
+ strcpy(str, tempchar);
+ return;
+ }
+
+ // convert all to km first
+ if (!_stricmp(unit, "KM"))
+ tempunit = (double)output;
+ else if (!_stricmp(unit, "MILES"))
+ tempunit = (double)output * 1.609;
+
+ // convert to apporiate unit
+ switch (opt.vUnit)
+ {
+ case 1:
+ intunit = (int)((tempunit*10) + 0.5);
+ wsprintf(str, "%i.%i %s", intunit/10, intunit%10, opt.DoNotAppendUnit ? "" : Translate("km"));
+ break;
+ case 2:
+ intunit = (int)((tempunit*10 / 1.609) + 0.5);
+ wsprintf(str, "%i.%i %s", intunit/10, intunit%10, opt.DoNotAppendUnit ? "" : Translate("miles"));
+ break;
+ default:
+ strcpy(str, tempchar);
+ break;
+ }
+}
+
+//============ CONDITION ICON ASSIGNMENT ============
+
+// assign the contact icon (status) from the condition string
+// the description may be different between different sources
+// cond = the string for weather condition
+// return value = status for the icon (ONLINE, OFFLINE, etc)
+WORD GetIcon(const char* cond, WIDATA *Data)
+{
+ int i;
+
+ static const
+ char *statusStr[10] =
+ {
+ "Lightning",
+ "Fog",
+ "Snow Shower",
+ "Snow",
+ "Rain Shower",
+ "Rain",
+ "Partly Cloudy",
+ "Cloudy",
+ "Sunny",
+ "N/A"
+ };
+
+ static const
+ WORD statusValue[10] =
+ {
+ LIGHT,
+ FOG,
+ SSHOWER,
+ SNOW,
+ RSHOWER,
+ RAIN,
+ PCLOUDY,
+ CLOUDY,
+ SUNNY,
+ NA
+ };
+
+ // set the icon using ini
+ for (i=0; i<10; i++) {
+ if (IsContainedInCondList(cond, &Data->CondList[i]))
+ return statusValue[i];
+ }
+
+ // internal detection
+ if (
+ strstr(cond, "mainy sunny") != NULL ||
+ strstr(cond, "mainy clear") != NULL ||
+ strstr(cond, "partly cloudy") != NULL ||
+ strstr(cond, "mostly") != NULL ||
+ strstr(cond, "clouds") != NULL) {
+ return PCLOUDY;
+ }
+ else if (
+ strstr(cond, "sunny") != NULL ||
+ strstr(cond, "clear") != NULL ||
+ strstr(cond, "fair") != NULL) {
+ return SUNNY;
+ }
+ else if (
+ strstr(cond, "thunder") != NULL ||
+ strstr(cond, "t-storm") != NULL) {
+ return LIGHT;
+ }
+ else if (
+ strstr(cond, "cloud") != NULL ||
+ strstr(cond, "overcast") != NULL) {
+ return CLOUDY;
+ }
+ else if (
+ strstr(cond, "fog") != NULL ||
+ strstr(cond, "mist") != NULL ||
+ strstr(cond, "smoke") != NULL ||
+ strstr(cond, "sand") != NULL ||
+ strstr(cond, "dust") != NULL ||
+ strstr(cond, "haze") != NULL) {
+ return FOG;
+ }
+ else if (
+ (strstr(cond, "shower") != NULL && strstr(cond, "snow") != NULL) ||
+ strstr(cond, "flurries") != NULL) {
+ return SSHOWER;
+ }
+ else if (
+ strstr(cond, "rain shower") != NULL ||
+ strstr(cond, "shower") != NULL)
+ {
+ return RSHOWER;
+ }
+ else if (
+ strstr(cond, "snow") != NULL ||
+ strstr(cond, "ice") != NULL ||
+ strstr(cond, "freezing") != NULL ||
+ strstr(cond, "wintry") != NULL) {
+ return SNOW;
+ }
+ else if (
+ strstr(cond, "drizzle") != NULL ||
+ strstr(cond, "rain") != NULL)
+ {
+ return RAIN;
+ }
+
+ // set the icon using langpack
+ for (i=0; i<9; i++)
+ {
+ char LangPackStr[64];
+ char LangPackStr1[128];
+ int j = 0;
+ do
+ {
+ j++;
+ // using the format "# Weather <condition name> <counter> #"
+ mir_snprintf(LangPackStr, sizeof(LangPackStr), "# Weather %s %i #", statusStr[i], j);
+ mir_snprintf(LangPackStr1, sizeof(LangPackStr1), "%s", Translate(LangPackStr));
+ CharLowerBuff(LangPackStr1, (DWORD)strlen(LangPackStr1));
+ if (strstr(cond, LangPackStr1) != NULL)
+ return statusValue[i];
+ // loop until the translation string exists (ie, the translated string is differ from original)
+ }
+ while (strcmp(Translate(LangPackStr), LangPackStr));
+ }
+
+ return NA;
+}
+
+//============ STRING CONVERSIONS ============
+
+// language pack can't translate str with /r; text box can't display properly for str without /r
+void FixStr(const char *orig, char* str)
+{
+ size_t i, ci = 0, li = strlen(orig);
+ for (i = 0; i < li; i++)
+ {
+ if (orig[i] == '\n') str[ci++] = '\r';
+ str[ci++] = orig[i];
+ }
+ str[ci] = 0;
+}
+
+// this function convert the string to the format with 1 upper case followed by lower case char
+void CaseConv(char *str)
+{
+ char *pstr;
+ BOOL nextUp = TRUE;
+
+ CharLowerBuff(str, (DWORD)strlen(str));
+ for(pstr=str; *pstr; pstr++)
+ {
+ if (*pstr==' ' || *pstr=='-')
+ nextUp = TRUE;
+ else
+ {
+ unsigned ch = *(unsigned char*)pstr;
+ if (nextUp) *pstr = (char)(unsigned)CharUpper((LPSTR)ch);
+ nextUp = FALSE;
+ }
+ }
+}
+
+// the next 2 functions are copied from miranda source
+// str = the string to modify
+void TrimString(char *str)
+{
+ size_t len, start;
+
+ len = strlen(str);
+ while(len && (unsigned char)str[len-1] <= ' ') str[--len] = 0;
+ for(start=0; (unsigned char)str[start]<=' ' && str[start]; start++);
+ memmove(str, str+start, len-start+1);
+}
+
+// convert \t to tab and \n to linefeed
+void ConvertBackslashes(char *str)
+{
+ char *pstr;
+ for(pstr=str;*pstr;pstr=CharNext(pstr))
+ {
+ if(*pstr=='\\')
+ {
+ switch(pstr[1])
+ {
+ case 'n': *pstr='\n'; break;
+ case 't': *pstr='\t'; break;
+ default: *pstr=pstr[1]; break;
+ }
+ memmove(pstr+1,pstr+2,strlen(pstr+2)+1);
+ }
+ }
+}
+
+// replace spaces with "%20"
+// dis = original string
+// return value = the modified string with space -> "%20"
+char *GetSearchStr(char *dis)
+{
+ char *pstr = dis;
+ size_t len = strlen(dis);
+ while (*pstr != 0)
+ {
+ if (*pstr == ' ')
+ {
+ memmove(pstr+3, pstr+1, len);
+ memcpy(pstr, "%20", 3);
+ pstr += 2;
+ }
+ pstr++;
+ len--;
+ }
+ return dis;
+}
+
+//============ ICON ASSIGNMENT ============
+
+// make display and history strings
+// w = WEATHERINFO data to be parsed
+// dis = the string to parse
+// return value = the parsed string
+char* GetDisplay(WEATHERINFO *w, const char *dis, char* str)
+{
+ char lpzDate[32], chr, name[256], temp[2];
+ DBVARIANT dbv;
+ size_t i;
+
+ // Clear the string
+ str[0] = 0;
+
+ // looking character by character
+ for (i=0; i<strlen(dis); i++)
+ {
+ // for the escape characters
+ if (dis[i] == '\\')
+ {
+ i++;
+ chr = dis[i];
+ switch (chr)
+ {
+ case '%': strcat(str, "%"); break;
+ case 't': strcat(str, "\t"); break;
+ case 'n': strcat(str, "\r\n"); break;
+ case '\\': strcat(str, "\\"); break;
+ }
+ }
+ // for the % varaibles
+ else if (dis[i] == '%')
+ {
+ i++;
+ chr = dis[i];
+ // turn capitalized characters to small case
+ if (chr < 'a' && chr != '[' && chr != '%') chr = (char)((int)chr + 32);
+ switch (chr) {
+ case 'c': strcat(str, w->cond); break;
+ case 'd': // get the current date
+ GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, NULL, NULL, lpzDate, sizeof(lpzDate));
+ strcat(str, lpzDate); break;
+ case 'e': strcat(str, w->dewpoint); break;
+ case 'f': strcat(str, w->feel); break;
+ case 'h': strcat(str, w->high); break;
+ case 'i': strcat(str, w->winddir); break;
+ case 'l': strcat(str, w->low); break;
+ case 'm': strcat(str, w->humid); break;
+ case 'n': strcat(str, w->city); break;
+ case 'p': strcat(str, w->pressure); break;
+ case 'r': strcat(str, w->sunrise); break;
+ case 's': strcat(str, w->id); break;
+ case 't': strcat(str, w->temp); break;
+ case 'u':
+ if (strcmp(w->update, NODATA)) strcat(str, w->update);
+ else strcat(str, Translate("<unknown time>"));
+ break;
+ case 'v': strcat(str, w->vis); break;
+ case 'w': strcat(str, w->wind); break;
+ case 'y': strcat(str, w->sunset); break;
+ case '%': strcat(str, "%"); break;
+ case '[': // custom variables
+ i++;
+ name[0] = 0;
+ // read the entire variable name
+ while (dis[i] != ']' && i < strlen(dis)) {
+ wsprintf(temp, "%c", dis[i++]);
+ strcat(name, temp);
+ }
+ // access the database to get its value
+ if (!DBGetContactSettingString(w->hContact, WEATHERCONDITION, name, &dbv))
+ {
+ if (dbv.pszVal != Translate(NODATA) && dbv.pszVal != Translate("<Error>"))
+ strcat(str, dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+ break;
+ }
+ }
+ // if the character is not a variable, write the original character to the new string
+ else
+ {
+ wsprintf(temp, "%c", dis[i]);
+ strcat(str, temp);
+ }
+ }
+ return str;
+}
+
+char svcReturnText[MAX_TEXT_SIZE];
+INT_PTR GetDisplaySvcFunc(WPARAM wParam, LPARAM lParam)
+{
+ WEATHERINFO winfo = LoadWeatherInfo((HANDLE)wParam);
+ return (INT_PTR)GetDisplay(&winfo, (char *)lParam, svcReturnText);
+}
+
+//============ ID MANAGEMENT ============
+
+// get service data module internal name
+// mod/id <- the mod part
+// pszID = original 2-part id, return the service internal name
+void GetSvc(char *pszID)
+{
+ char *chop;
+
+ chop = strstr(pszID, "/");
+ if (chop != NULL) *chop = '\0';
+ else pszID[0] = 0;
+}
+
+// get the id use for update without the service internal name
+// mod/id <- the id part
+// pszID = original 2-part id, return the single part id
+void GetID(char *pszID)
+{
+ char *chop;
+
+ chop = strstr(pszID, "/");
+ if (chop != NULL) strcpy(pszID, chop+1);
+ else pszID[0] = 0;
+}
+
+//============ WEATHER ERROR CODE ============
+
+// Get the text when an error code is specified
+// code = the error code obtained when updating weather
+// str = the string for the error
+
+char *GetError(int code)
+{
+ char *str, str2[100];
+ switch (code)
+ {
+ case 10: str = E10; break;
+ case 11: str = E11; break;
+ case 12: str = E12; break;
+ case 20: str = E20; break;
+ case 30: str = E30; break;
+ case 40: str = E40; break;
+ case 42: str = E42; break;
+ case 43: str = E43; break;
+ case 99: str = E99; break;
+ case 204: str = E204; break;
+ case 301: str = E301; break;
+ case 305: str = E305; break;
+ case 307: str = E307; break;
+ case 400: str = E400; break;
+ case 401: str = E401; break;
+ case 402: str = E402; break;
+ case 403: str = E403; break;
+ case 404: str = E404; break;
+ case 405: str = E405; break;
+ case 407: str = E407; break;
+ case 410: str = E410; break;
+ case 500: str = E500; break;
+ case 502: str = E502; break;
+ case 503: str = E503; break;
+ case 504: str = E504; break;
+ default:
+ mir_snprintf(str2, sizeof(str2), Translate("HTTP Error %i"), code);
+ str = str2;
+ break;
+ }
+ return str;
+}
+
+LPWSTR ConvToUnicode(LPCSTR str2)
+{
+ const size_t nLength = MultiByteToWideChar(lpcp, 0, str2, -1, NULL, 0);
+ LPWSTR res = mir_alloc(sizeof(WCHAR)*nLength);
+ MultiByteToWideChar(lpcp, 0, str2, -1, res, (int)nLength);
+ return res;
+}
+
+typedef BOOL (WINAPI *ft_SetDlgItemTextW) (
+ HWND hDlg,
+ int nIDDlgItem,
+ LPCWSTR lpString
+ );
+
+typedef BOOL (WINAPI *ft_SetWindowTextW) (
+ HWND hWnd,
+ LPCWSTR lpString
+ );
+
+typedef UINT (WINAPI *ft_GetDlgItemTextW) (
+ HWND hDlg,
+ int nIDDlgItem,
+ LPWSTR lpString,
+ int nMaxCount
+ );
+
+static ft_GetDlgItemTextW f_GetDlgItemTextW = NULL;
+static ft_SetDlgItemTextW f_SetDlgItemTextW = NULL;
+static ft_SetWindowTextW f_SetWindowTextW = NULL;
+
+unsigned lpcp;
+
+void InitUniConv(void)
+{
+ HMODULE hUser = GetModuleHandle("user32.dll");
+ f_GetDlgItemTextW = (ft_GetDlgItemTextW)GetProcAddress(hUser, "GetDlgItemTextW");
+ f_SetDlgItemTextW = (ft_SetDlgItemTextW)GetProcAddress(hUser, "SetDlgItemTextW");
+ f_SetWindowTextW = (ft_SetWindowTextW) GetProcAddress(hUser, "SetWindowTextW");
+
+ lpcp = (unsigned)CallService(MS_LANGPACK_GETCODEPAGE, 0, 0);
+ if (lpcp == CALLSERVICE_NOTFOUND || lpcp == GetUserDefaultLangID())
+ lpcp = CP_ACP;
+}
+
+UINT GetDlgItemTextWth(HWND hDlg, int nIDDlgItem, LPSTR lpString, int nMaxCount)
+{
+ UINT res;
+
+ if (lpcp != CP_ACP && f_GetDlgItemTextW != NULL)
+ {
+ LPWSTR m_psz = mir_alloc(sizeof(WCHAR) * nMaxCount);
+ res = f_GetDlgItemTextW(hDlg, nIDDlgItem, m_psz, nMaxCount);
+ WideCharToMultiByte( lpcp, 0, m_psz, -1, lpString, nMaxCount, NULL, NULL );
+ mir_free(m_psz);
+ }
+ else
+ res = GetDlgItemText(hDlg, nIDDlgItem, lpString, nMaxCount);
+
+ return res;
+}
+
+BOOL SetDlgItemTextWth(HWND hDlg, int nIDDlgItem, LPCSTR lpString)
+{
+ BOOL res;
+
+ if (lpcp != CP_ACP && f_SetDlgItemTextW != NULL)
+ {
+ LPWSTR m_psz = ConvToUnicode(lpString);
+ res = f_SetDlgItemTextW(hDlg, nIDDlgItem, m_psz);
+ mir_free(m_psz);
+ }
+ else
+ res = SetDlgItemText(hDlg, nIDDlgItem, lpString);
+
+ return res;
+}
+
+BOOL SetWindowTextWth(HWND hWnd, LPCSTR lpString)
+{
+ BOOL res;
+
+ if (lpcp != CP_ACP && f_SetWindowTextW != NULL)
+ {
+ LPWSTR m_psz = ConvToUnicode(lpString);
+ res = f_SetWindowTextW(hWnd, m_psz);
+ mir_free(m_psz);
+ }
+ else
+ res = SetWindowText(hWnd, lpString);
+
+ return res;
+}
+
+void ListView_SetItemTextWth(HWND hwndLV, int i, int iSubItem_, LPSTR pszText_)
+{
+ LV_ITEM _ms_lvi;
+ _ms_lvi.iSubItem = iSubItem_;
+
+ if (lpcp != CP_ACP)
+ {
+ LPWSTR m_psz = ConvToUnicode(pszText_);
+ _ms_lvi.pszText = (LPSTR)m_psz;
+ SendMessage(hwndLV, LVM_SETITEMTEXTW, (WPARAM)(i), (LPARAM)&_ms_lvi);
+ mir_free(m_psz);
+ }
+ else
+ {
+ _ms_lvi.pszText = pszText_;
+ SendMessage(hwndLV, LVM_SETITEMTEXTA, (WPARAM)(i), (LPARAM)&_ms_lvi);
+ }
+}
+
+int ListView_InsertItemWth(HWND hwnd, LV_ITEM *pitem)
+{
+ int res;
+ if (lpcp != CP_ACP)
+ {
+ LPSTR otxt = pitem->pszText;
+ LPWSTR m_psz = ConvToUnicode(otxt);
+ pitem->pszText = (LPSTR)m_psz;
+ res = SendMessage(hwnd, LVM_INSERTITEMW, 0, (LPARAM)pitem);
+ mir_free(m_psz);
+ pitem->pszText = otxt;
+ }
+ else
+ res = SendMessage(hwnd, LVM_INSERTITEMA, 0, (LPARAM)pitem);
+
+ return res;
+}
+
+int ListView_InsertColumnWth(HWND hwnd, int iCol, LV_COLUMN *pitem)
+{
+ int res;
+ if (lpcp != CP_ACP)
+ {
+ LPSTR otxt = pitem->pszText;
+ LPWSTR m_psz = ConvToUnicode(otxt);
+ pitem->pszText = (LPSTR)m_psz;
+ res = SendMessage(hwnd, LVM_INSERTCOLUMNW, iCol, (LPARAM)pitem);
+ mir_free(m_psz);
+ pitem->pszText = otxt;
+ }
+ else
+ res = SendMessage(hwnd, LVM_INSERTCOLUMNA, iCol, (LPARAM)pitem);
+
+ return res;
+}
diff --git a/plugins/weather/weather_data.c b/plugins/weather/weather_data.c
new file mode 100644
index 0000000000..52c681fb6b
--- /dev/null
+++ b/plugins/weather/weather_data.c
@@ -0,0 +1,493 @@
+/*
+Weather Protocol plugin for Miranda IM
+Copyright (C) 2005-2011 Boris Krasnovskiy All Rights Reserved
+Copyright (C) 2002-2005 Calvin Che
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; version 2
+of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+This file contain the source related loading, obtaining, and
+saving individual weather data for a weather contact.
+*/
+
+#include "weather.h"
+
+// temporary counter and storage for removing weather data
+typedef struct
+{
+ char *value[1024];
+ int current;
+} WCOUNTER;
+
+//============ LOAD WEATHER INFO FROM A CONTACT ============
+
+// get station ID from DB
+// hContact = the current contact handle
+// return value = the string for station ID
+void GetStationID(HANDLE hContact, char* id, size_t idlen)
+{
+ // accessing the database
+ if (DBGetStaticString(hContact, WEATHERPROTONAME, "ID", id, idlen))
+ id[0] = 0;
+}
+
+// initialize weather info by loading values from database
+// Change = current contact handle
+// return value = the current weather information in WEATHERINFO struct
+WEATHERINFO LoadWeatherInfo(HANDLE Change)
+{
+ WEATHERINFO winfo;
+
+ winfo.hContact = Change;
+ // obtaining values from the DB
+ // assuming station ID must exist at all time, but others does not have to
+ // if the string is not found in database, a value of "N/A" is stored in the field
+ GetStationID(Change, winfo.id, sizeof(winfo.id));
+
+ if (DBGetStaticString(Change, WEATHERPROTONAME, "Nick", winfo.city, sizeof(winfo.city)))
+ strcpy(winfo.city, NODATA);
+ if (DBGetStaticString(Change, WEATHERCONDITION, "Update", winfo.update, sizeof(winfo.update)))
+ strcpy(winfo.update, NODATA);
+ if (DBGetStaticString(Change, WEATHERCONDITION, "Condition", winfo.cond, sizeof(winfo.cond)))
+ strcpy(winfo.cond, NODATA);
+ if (DBGetStaticString(Change, WEATHERCONDITION, "Temperature", winfo.temp, sizeof(winfo.temp)))
+ strcpy(winfo.temp, NODATA);
+ if (DBGetStaticString(Change, WEATHERCONDITION, "High", winfo.high, sizeof(winfo.high)))
+ strcpy(winfo.high, NODATA);
+ if (DBGetStaticString(Change, WEATHERCONDITION, "Low", winfo.low, sizeof(winfo.low)))
+ strcpy(winfo.low, NODATA);
+ if (DBGetStaticString(Change, WEATHERCONDITION, "Sunset", winfo.sunset, sizeof(winfo.sunset)))
+ strcpy(winfo.sunset, NODATA);
+ if (DBGetStaticString(Change, WEATHERCONDITION, "Sunrise", winfo.sunrise, sizeof(winfo.sunrise)))
+ strcpy(winfo.sunrise, NODATA);
+ if (DBGetStaticString(Change, WEATHERCONDITION, "Wind Speed", winfo.wind, sizeof(winfo.wind)))
+ strcpy(winfo.wind, NODATA);
+ if (DBGetStaticString(Change, WEATHERCONDITION, "Wind Direction", winfo.winddir, sizeof(winfo.winddir)))
+ strcpy(winfo.winddir, NODATA);
+ if (DBGetStaticString(Change, WEATHERCONDITION, "Dewpoint", winfo.dewpoint, sizeof(winfo.dewpoint)))
+ strcpy(winfo.dewpoint, NODATA);
+ if (DBGetStaticString(Change, WEATHERCONDITION, "Pressure", winfo.pressure, sizeof(winfo.pressure)))
+ strcpy(winfo.pressure, NODATA);
+ if (DBGetStaticString(Change, WEATHERCONDITION, "Visibility", winfo.vis, sizeof(winfo.vis)))
+ strcpy(winfo.vis, NODATA);
+ if (DBGetStaticString(Change, WEATHERCONDITION, "Humidity", winfo.humid, sizeof(winfo.humid)))
+ strcpy(winfo.humid, NODATA);
+ if (DBGetStaticString(Change, WEATHERCONDITION, "Feel", winfo.feel, sizeof(winfo.feel)))
+ strcpy(winfo.feel, NODATA);
+
+ winfo.status = (WORD)DBGetContactSettingWord(Change, WEATHERPROTONAME, "StatusIcon", ID_STATUS_OFFLINE);
+ return winfo;
+}
+
+// getting weather setting from database
+// return 0 on success
+int DBGetData(HANDLE hContact, char *setting, DBVARIANT *dbv)
+{
+ if (DBGetContactSettingString(hContact, WEATHERCONDITION, setting, dbv))
+ {
+ size_t len = strlen(setting) + 1;
+ char *set = (char*)alloca(len + 1);
+ *set = '#';
+ memcpy(set + 1, setting, len);
+
+ if (DBGetContactSettingString(hContact, WEATHERCONDITION, set, dbv))
+ return 1;
+ }
+ return 0;
+}
+
+int DBGetStaticString(HANDLE hContact, const char *szModule, const char *valueName, char *dest, size_t dest_len)
+{
+ DBVARIANT dbv;
+ DBCONTACTGETSETTING sVal;
+
+ dbv.pszVal = dest;
+ dbv.cchVal = (WORD)dest_len;
+ dbv.type = DBVT_ASCIIZ;
+
+ sVal.pValue = &dbv;
+ sVal.szModule = szModule;
+ sVal.szSetting = valueName;
+
+ if ( CallService( MS_DB_CONTACT_GETSETTINGSTATIC, ( WPARAM )hContact, ( LPARAM )&sVal ) != 0 )
+ return 1;
+
+ return ( dbv.type != DBVT_ASCIIZ );
+}
+
+
+//============ ERASE OLD SETTINGS ============
+
+// erase all current weather information from database
+// lastver = the last used version number in dword (using PLUGIN_MAKE_VERSION)
+void EraseAllInfo(DWORD lastver)
+{
+ char str[255];
+ int ContactCount = 0;
+ HANDLE hContact, LastContact = NULL;
+ DBVARIANT dbv;
+ // loop through all contacts
+ hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ while(hContact)
+ {
+ // see if the contact is a weather contact
+ if(IsMyContact(hContact))
+ {
+ // check for upgrade
+ if (lastver < __VERSION_DWORD) UpgradeContact(lastver, hContact);
+ DBWriteContactSettingWord(hContact,WEATHERPROTONAME,"Status",ID_STATUS_OFFLINE);
+ DBWriteContactSettingWord(hContact,WEATHERPROTONAME,"StatusIcon",ID_STATUS_OFFLINE);
+ DBDeleteContactSetting(hContact,"CList","MyHandle");
+ // clear all data
+ if (DBGetContactSettingString(hContact, WEATHERPROTONAME, "Nick", &dbv)) {
+ DBWriteContactSettingString(hContact, WEATHERPROTONAME, "Nick", Translate("<Enter city name here>"));
+ DBWriteContactSettingString(hContact, WEATHERPROTONAME, "LastLog", "never");
+ DBWriteContactSettingString(hContact, WEATHERPROTONAME, "LastCondition", "None");
+ DBWriteContactSettingString(hContact, WEATHERPROTONAME, "LastTemperature", "None");
+ }
+ else
+ DBFreeVariant(&dbv);
+/*
+ DBWriteContactSettingString(hContact,WEATHERCONDITION,"Update", NODATA);
+ DBWriteContactSettingString(hContact,WEATHERCONDITION,"Condition", NODATA);
+ DBWriteContactSettingString(hContact,WEATHERCONDITION,"Temperature", NODATA);
+ DBWriteContactSettingString(hContact,WEATHERCONDITION,"High", NODATA);
+ DBWriteContactSettingString(hContact,WEATHERCONDITION,"Low", NODATA);
+ DBWriteContactSettingString(hContact,WEATHERCONDITION,"Humidity", NODATA);
+ DBWriteContactSettingString(hContact,WEATHERCONDITION,"Wind Speed", NODATA);
+ DBWriteContactSettingString(hContact,WEATHERCONDITION,"Wind Direction", NODATA);
+ DBWriteContactSettingString(hContact,WEATHERCONDITION,"Pressure", NODATA);
+ DBWriteContactSettingString(hContact,WEATHERCONDITION,"Visibility", NODATA);
+ DBWriteContactSettingString(hContact,WEATHERCONDITION,"Dewpoint", NODATA);
+ DBWriteContactSettingString(hContact,WEATHERCONDITION,"Feel", NODATA);
+ DBWriteContactSettingString(hContact,WEATHERCONDITION,"Heat Index", NODATA);
+ DBWriteContactSettingString(hContact,WEATHERCONDITION,"Sunrise", NODATA);
+ DBWriteContactSettingString(hContact,WEATHERCONDITION,"Sunset", NODATA);
+*/
+ DBDataManage(hContact, WDBM_REMOVE, 0, 0);
+ DBWriteContactSettingString(hContact, "UserInfo", "MyNotes", "");
+ // reset update tag
+ DBWriteContactSettingByte(hContact,WEATHERPROTONAME,"IsUpdated",FALSE);
+ // reset logging settings
+ if (!DBGetContactSettingString(hContact,WEATHERPROTONAME,"Log",&dbv))
+ {
+ DBWriteContactSettingByte(hContact,WEATHERPROTONAME,"File",(BYTE)(dbv.pszVal[0] != 0));
+ DBFreeVariant(&dbv);
+ }
+ else
+ DBWriteContactSettingByte(hContact,WEATHERPROTONAME,"File",FALSE);
+ // if no default station find, assign a new one
+ if (opt.Default[0] == 0)
+ {
+ GetStationID(hContact, opt.Default, sizeof(opt.Default));
+
+ opt.DefStn = hContact;
+ if (!DBGetContactSettingString(hContact,WEATHERPROTONAME,"Nick",&dbv))
+ {
+ wsprintf(str, Translate("%s is now the default weather station"), dbv.pszVal);
+ DBFreeVariant(&dbv);
+ MessageBox(NULL, str, Translate("Weather Protocol"), MB_OK|MB_ICONINFORMATION);
+ }
+ }
+ // get the handle of the default station
+ if (opt.DefStn == NULL) {
+ if (!DBGetContactSettingString(hContact,WEATHERPROTONAME,"ID",&dbv))
+ {
+ if (!strcmp(dbv.pszVal, opt.Default)) opt.DefStn = hContact;
+ DBFreeVariant(&dbv);
+ }
+ }
+ ContactCount++; // increment counter
+ LastContact = hContact;
+ }
+ hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0);
+ }
+ // if weather contact exists, set the status to online so it is ready for update
+ // if (ContactCount != 0) status = ONLINE;
+ // in case where the default station is missing
+ if (opt.DefStn == NULL && ContactCount != 0)
+ {
+ if (!DBGetContactSettingString(LastContact,WEATHERPROTONAME,"ID",&dbv))
+ {
+ strcpy(opt.Default, dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+ opt.DefStn = LastContact;
+ if (!DBGetContactSettingString(LastContact,WEATHERPROTONAME,"Nick",&dbv))
+ {
+ wsprintf(str, Translate("%s is now the default weather station"), dbv.pszVal);
+ DBFreeVariant(&dbv);
+ MessageBox(NULL, str, Translate("Weather Protocol"), MB_OK|MB_ICONINFORMATION);
+ }
+ }
+ // save option in case of default station changed
+ DBWriteContactSettingString(NULL, WEATHERPROTONAME, "Default", opt.Default);
+}
+
+void ConvertDataValue(WIDATAITEM *UpdateData, char *Data)
+{
+ char str[MAX_DATA_LEN];
+
+ // convert the unit
+ if (strcmp(Data, Translate("<Error>")) && strcmp(Data, NODATA) && strcmp(Data, Translate(NODATA)))
+ {
+ // temperature
+ if (!strcmp(UpdateData->Name, "Temperature") || !strcmp(UpdateData->Name, "High") ||
+ !strcmp(UpdateData->Name, "Low") || !strcmp(UpdateData->Name, "Feel") ||
+ !strcmp(UpdateData->Name, "Dewpoint") ||
+ !_stricmp(UpdateData->Unit, "C") || !_stricmp(UpdateData->Unit, "F") ||
+ !_stricmp(UpdateData->Unit, "K"))
+ {
+ GetTemp(Data, UpdateData->Unit, str);
+ strcpy(Data, str);
+ }
+ // pressure
+ else if (!strcmp(UpdateData->Name, "Pressure") || !_stricmp(UpdateData->Unit, "HPA") ||
+ !_stricmp(UpdateData->Unit, "KPA") || !_stricmp(UpdateData->Unit, "MB") ||
+ !_stricmp(UpdateData->Unit, "TORR") || !_stricmp(UpdateData->Unit, "IN") ||
+ !_stricmp(UpdateData->Unit, "MM"))
+ {
+ GetPressure(Data, UpdateData->Unit, str);
+ strcpy(Data, str);
+ }
+ // speed
+ else if (!strcmp(UpdateData->Name, "Wind Speed") || !_stricmp(UpdateData->Unit, "KM/H") ||
+ !_stricmp(UpdateData->Unit, "M/S") || !_stricmp(UpdateData->Unit, "MPH") ||
+ !_stricmp(UpdateData->Unit, "KNOTS"))
+ {
+ GetSpeed(Data, UpdateData->Unit, str);
+ strcpy(Data, str);
+ }
+ // visibility
+ else if (!strcmp(UpdateData->Name, "Visibility") || !_stricmp(UpdateData->Unit, "KM") ||
+ !_stricmp(UpdateData->Unit, "MILES"))
+ {
+ GetDist(Data, UpdateData->Unit, str);
+ strcpy(Data, str);
+ }
+ // converting case for condition to the upper+lower format
+ else if (!_stricmp(UpdateData->Unit, "COND"))
+ CaseConv(Data);
+ // degree sign
+ else if (!_stricmp(UpdateData->Unit, "DEG"))
+ {
+ if (!opt.DoNotAppendUnit) strcat(Data, opt.DegreeSign);
+ }
+ // percent sign
+ else if (!_stricmp(UpdateData->Unit, "%"))
+ {
+ if (!opt.DoNotAppendUnit) strcat(Data, "%");
+ }
+ // truncating strings for day/month to 2 or 3 characters
+ else if (!_stricmp(UpdateData->Unit, "DAY") || !_stricmp(UpdateData->Unit, "MONTH"))
+ if (opt.dUnit > 1 && strlen(Data) > opt.dUnit) Data[opt.dUnit] = '\0';
+ }
+}
+
+//============ GET THE VALUE OF A DATAITEM ============
+
+// get the value of the data using the start, end strings
+// UpdateData = the WIDATAITEM struct containing start, end, unit
+// Data = the string containing weather data obtained from UpdateData
+// global var. used: szInfo = the downloaded string
+void GetDataValue(WIDATAITEM *UpdateData, char *Data, char** szData)
+{
+ char last = 0, current, *start, *end;
+ unsigned startloc = 0, endloc = 0, respos = 0;
+ BOOL tag = FALSE, symb = FALSE;
+ char *szInfo = *szData;
+
+ Data[0] = 0;
+ // parse the data if available
+ if (UpdateData->Start[0] == 0 && UpdateData->End[0] == 0) return;
+ start = szInfo;
+ // the start string must be found
+ if (UpdateData->Start[0] != 0) {
+ start = strstr(szInfo, UpdateData->Start);
+ if (start != NULL) {
+ // set the starting location for getting data
+ start += strlen(UpdateData->Start);
+ szInfo = start;
+ }
+ }
+ // the end string must be found too
+ if (UpdateData->End[0] != 0)
+ end = strstr(szInfo, UpdateData->End);
+ else end = strstr(szInfo, " ");
+ if (end != NULL) {
+ // set the ending location
+ startloc = 0;
+ endloc = end - szInfo;
+ end += strlen(UpdateData->End);
+ last = '\n';
+ }
+ // ignore if not both of the string found - this prevent crashes
+ if (start != NULL && end != NULL)
+ {
+ // begin reading the data from start location to end location
+ // remove all HTML tag in between, as well as leading space, ending space,
+ // multiple spaces, tabs, and return key
+ while (startloc < endloc)
+ {
+ if (szInfo[startloc] == '<') tag = TRUE;
+ else if (szInfo[startloc] == '&' &&
+ (szInfo[startloc+1] == ';' || szInfo[startloc+2] == ';' || szInfo[startloc+3] == ';' ||
+ szInfo[startloc+4] == ';' || szInfo[startloc+5] == ';' || szInfo[startloc+6] == ';'))
+ symb = TRUE;
+ else if (szInfo[startloc] == '>') tag = FALSE;
+ else if (szInfo[startloc] == ';') symb = FALSE;
+ else {
+ if (!tag && !symb) {
+ current = szInfo[startloc];
+ if (current == '\n' || current == '\t' || current == ' ' || current == '\r')
+ current = ' ';
+ if (current != ' ' || last != ' ') {
+ if (last != '\n' && (respos != 0 || (respos == 0 && last != ' ')))
+ Data[respos++] = last;
+ last = current;
+ }
+ }
+ }
+ ++startloc;
+ // prevent crashes if the string go over maximun length -> generate an error
+ if (respos >= MAX_DATA_LEN) {
+ if (opt.ShowWarnings && UpdateData->Name[0] != 0 && strcmp(UpdateData->Name, "Ignore")) {
+ mir_snprintf(Data, MAX_DATA_LEN, Translate("Error when obtaining data: %s"), UpdateData->Name);
+ WPShowMessage(Data, SM_WARNING);
+ }
+ strncpy(Data, Translate("<Error>"), MAX_DATA_LEN);
+ last = ' ';
+ respos = MAX_DATA_LEN - 1;
+ break;
+ }
+ }
+
+ // get the last character
+ if (last != ' ')
+ Data[respos++] = last;
+
+ // null terminate the string
+ Data[respos] = 0;
+
+ // write raw data for debug
+ Netlib_Logf(hNetlibUser, "%s: %s", UpdateData->Name, Data);
+
+ // convert the unit
+ ConvertDataValue(UpdateData, Data);
+
+ // remove the string before the data from szInfo
+ szInfo = end;
+ }
+ *szData = szInfo;
+}
+
+//============ ALLOCATE SPACE AND COPY STRING ============
+
+// copy a string into a new memory location
+// Data = the field the data is copied to
+// Value = the original string, the string where data is copied from
+void wSetData(char **Data, const char *Value)
+{
+ if (Value[0] != 0)
+ {
+ char *newData = (char*)mir_alloc(strlen(Value)+3);
+ strcpy(newData, Value);
+ *Data = newData;
+ }
+ else
+ *Data = "";
+}
+
+// A safer free function that free memory for a string
+// Data = the string occuping the data to be freed
+void wfree(char **Data)
+{
+ if (*Data && strlen(*Data) > 0) mir_free(*Data);
+ *Data = NULL;
+}
+
+//============ MANAGE THE ITEMS STORED IN DB ============
+
+// remove or display the weatehr information for a contact
+// hContact - the contact in which the info is going to be removed
+void DBDataManage(HANDLE hContact, WORD Mode, WPARAM wParam, LPARAM lParam)
+{
+ DBCONTACTENUMSETTINGS dbces;
+ DBVARIANT dbv;
+ WCOUNTER wc;
+ wc.current = 0;
+
+ dbces.lParam=(LPARAM)&wc;
+ dbces.pfnEnumProc=GetWeatherDataFromDB;
+ dbces.szModule=WEATHERCONDITION;
+
+ // get all the settings and stored them in a temporary list
+ if(CallService(MS_DB_CONTACT_ENUMSETTINGS,(WPARAM)hContact,(LPARAM)&dbces)==-1)
+ wc.current--;
+
+ // begin deleting settings
+ for (; --wc.current>-1;)
+ {
+ if (!DBGetContactSettingString(hContact, WEATHERCONDITION, wc.value[wc.current], &dbv))
+ {
+ switch (Mode)
+ {
+ case WDBM_REMOVE:
+ DBDeleteContactSetting(hContact, WEATHERCONDITION, wc.value[wc.current]);
+ break;
+
+ case WDBM_DETAILDISPLAY:
+ {
+ HWND hList = GetDlgItem((HWND)wParam, IDC_DATALIST);
+ LV_ITEM lvi = { 0 };
+
+ // skip the "WeatherInfo" variable
+ if (strcmp(wc.value[wc.current], "WeatherInfo") == 0 ||
+ strcmp(wc.value[wc.current], "Ignore") == 0 ||
+ wc.value[wc.current][0] == '#')
+ {
+ wfree(&wc.value[wc.current]);
+ DBFreeVariant(&dbv);
+ continue;
+ }
+
+ lvi.mask = LVIF_TEXT | LVIF_PARAM;
+ lvi.iItem = 0;
+ lvi.iSubItem = 0;
+ lvi.lParam = (LPARAM)wc.current;
+ lvi.pszText = (LPSTR)Translate(wc.value[wc.current]);
+ lvi.iItem = ListView_InsertItemWth(hList, &lvi);
+ lvi.pszText = dbv.pszVal;
+ ListView_SetItemTextWth(hList, lvi.iItem, 1, lvi.pszText);
+ break;
+ }
+ }
+ DBFreeVariant(&dbv);
+ }
+ wfree(&wc.value[wc.current]);
+ }
+}
+
+// get single setting that is found
+// szSetting = the setting name
+// lparam = the counter
+int GetWeatherDataFromDB(const char *szSetting, LPARAM lparam)
+{
+ WCOUNTER *wc = (WCOUNTER*)lparam;
+ wc->value[wc->current] = (char *)mir_alloc(strlen(szSetting) + 1);
+ strcpy(wc->value[wc->current], szSetting);
+ wc->current++;
+ return 0;
+}
diff --git a/plugins/weather/weather_http.c b/plugins/weather/weather_http.c
new file mode 100644
index 0000000000..eb69dd4ca7
--- /dev/null
+++ b/plugins/weather/weather_http.c
@@ -0,0 +1,226 @@
+/*
+Weather Protocol plugin for Miranda IM
+Copyright (C) 2005-2011 Boris Krasnovskiy All Rights Reserved
+Copyright (C) 2002-2005 Calvin Che
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; version 2
+of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+This file contain the source related to downloading weather info
+from the web using netlib
+*/
+
+#include "weather.h"
+
+HANDLE hNetlibUser, hNetlibHttp;
+
+int findHeader(NETLIBHTTPREQUEST *nlhrReply, char *hdr)
+{
+ int res = -1, i;
+ for (i=0; i<nlhrReply->headersCount; i++)
+ {
+ if (_stricmp(nlhrReply->headers[i].szName, hdr) == 0)
+ {
+ res = i;
+ break;
+ }
+ }
+ return res;
+}
+
+//============ DOWNLOAD NEW WEATHER ============
+
+// function to download webpage from the internet
+// szUrl = URL of the webpage to be retrieved
+// return value = 0 for success, 1 or HTTP error code for failure
+// global var used: szData, szInfo = containing the retrieved data
+int InternetDownloadFile (char *szUrl, char* cookie, char** szData)
+{
+ int result = 0xBADBAD;
+ char* szRedirUrl = NULL;
+ NETLIBHTTPREQUEST nlhr = {0}, *nlhrReply;
+ NETLIBHTTPHEADER headers[6];
+
+ // initialize the netlib request
+ nlhr.cbSize = sizeof(nlhr);
+ nlhr.requestType = REQUEST_GET;
+ nlhr.flags = NLHRF_DUMPASTEXT | NLHRF_HTTP11;
+ nlhr.szUrl = szUrl;
+ nlhr.nlc = hNetlibHttp;
+
+ if (CallService(MS_SYSTEM_GETVERSION, 0, 0) >= PLUGIN_MAKE_VERSION(0,9,0,5))
+ nlhr.flags |= NLHRF_PERSISTENT | NLHRF_REDIRECT;
+
+ // change the header so the plugin is pretended to be IE 6 + WinXP
+ nlhr.headersCount = 5;
+ nlhr.headers = headers;
+ nlhr.headers[0].szName = "User-Agent";
+ nlhr.headers[0].szValue = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)";
+ nlhr.headers[1].szName = "Cache-Control";
+ nlhr.headers[1].szValue = "no-cache";
+ nlhr.headers[2].szName = "Pragma";
+ nlhr.headers[2].szValue = "no-cache";
+ nlhr.headers[3].szName = "Connection";
+ nlhr.headers[3].szValue = "close";
+ nlhr.headers[4].szName = "Cookie";
+ nlhr.headers[4].szValue = cookie;
+// nlhr.headers[5].szName = "If-Modified-Since";
+// nlhr.headers[5].szValue = "Tue, 24 Feb 2009 03:44:23 GMT";
+
+ if (cookie == NULL || cookie[0] == 0) --nlhr.headersCount;
+
+ while (result == 0xBADBAD)
+ {
+ // download the page
+ nlhrReply = (NETLIBHTTPREQUEST*)CallService(MS_NETLIB_HTTPTRANSACTION,
+ (WPARAM)hNetlibUser,(LPARAM)&nlhr);
+
+ if (nlhrReply)
+ {
+ // if the recieved code is 200 OK
+ if(nlhrReply->resultCode == 200)
+ {
+ if (nlhrReply->dataLength)
+ {
+ char* end;
+ int i;
+
+ result = 0;
+
+// i = findHeader(nlhrReply, "Date-Modified");
+
+ // allocate memory and save the retrieved data
+ *szData = (char *)mir_alloc(nlhrReply->dataLength + 2);
+
+ memcpy(*szData, nlhrReply->pData, nlhrReply->dataLength);
+ (*szData)[nlhrReply->dataLength] = 0;
+
+ i = findHeader(nlhrReply, "Content-Type");
+ if (i != -1)
+ {
+ if (strstr(_strlwr((char*)nlhrReply->headers[i].szValue), "utf-8"))
+ mir_utf8decode(*szData, NULL);
+ }
+
+ end = *szData;
+ for (;;)
+ {
+ char* beg = strstr(end, "<meta");
+ if (beg == NULL) break;
+ else
+ {
+ char* method, tmp;
+ end = strchr(beg, '>');
+ tmp = *end; *end = 0;
+
+ method = strstr(beg, "http-equiv=\"");
+ if (method && _strnicmp(method+12, "Content-Type", 12) == 0 && strstr(method, "utf-8"))
+ {
+ *end = tmp;
+ mir_utf8decode(*szData, NULL);
+ break;
+ }
+ else
+ *end = tmp;
+ }
+ }
+ }
+ else
+ result = DATA_EMPTY;
+ }
+ // if the recieved code is 302 Moved, Found, etc
+ // workaround for url forwarding
+ else if(nlhrReply->resultCode == 302 || nlhrReply->resultCode == 301 || nlhrReply->resultCode == 303 ) // page moved
+ {
+ // get the url for the new location and save it to szInfo
+ // look for the reply header "Location"
+ int i = findHeader(nlhrReply, "Location");
+
+ if (i != -1)
+ {
+ size_t rlen = 0;
+ if (nlhrReply->headers[i].szValue[0] == '/')
+ {
+ char* szPath;
+ char* szPref = strstr(szUrl, "://");
+ szPref = szPref ? szPref + 3 : szUrl;
+ szPath = strchr(szPref, '/');
+ rlen = szPath != NULL ? szPath - szUrl : strlen(szUrl);
+ }
+
+ szRedirUrl = (char*)mir_realloc(szRedirUrl,
+ rlen + strlen(nlhrReply->headers[i].szValue)*3 + 1);
+
+ strncpy(szRedirUrl, szUrl, rlen);
+ strcpy(szRedirUrl+rlen, nlhrReply->headers[i].szValue);
+
+ GetSearchStr(szRedirUrl);
+
+ nlhr.szUrl = szRedirUrl;
+ }
+ }
+ // return error code if the recieved code is neither 200 OK nor 302 Moved
+ else
+ {
+ *szData = (char *)mir_alloc(512);
+ // store the error code in szData
+ wsprintf(*szData, "Error occured! HTTP Error: %i\n", nlhrReply->resultCode);
+ result = (int)nlhrReply->resultCode;
+ }
+
+ hNetlibHttp = nlhrReply->nlc;
+ // make a copy of the retrieved data, then free the memory of the http reply
+ CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT,0,(LPARAM)nlhrReply);
+ }
+ // if the data does not downloaded successfully (ie. disconnected), then return 1000 as error code
+ else
+ {
+ *szData = (char *)mir_alloc(512);
+ // store the error code in szData
+ strcpy(*szData, "NetLib error occurred!!");
+ result = NETLIB_ERROR;
+ hNetlibHttp = NULL;
+ }
+
+ }
+
+ mir_free(szRedirUrl);
+
+ return result;
+}
+
+//============ NETLIB INITIALIZATION ============
+
+// initialize netlib support for weather protocol
+void NetlibInit(void)
+{
+ NETLIBUSER nlu = {0};
+ nlu.cbSize = sizeof(nlu);
+ nlu.flags = NUF_OUTGOING|NUF_HTTPCONNS|NUF_NOHTTPSOPTION;
+ nlu.szSettingsModule = WEATHERPROTONAME;
+ nlu.szDescriptiveName = Translate("Weather HTTP connections");
+ hNetlibUser=(HANDLE)CallService(MS_NETLIB_REGISTERUSER,0,(LPARAM)&nlu);
+}
+
+void NetlibHttpDisconnect(void)
+{
+ if (hNetlibHttp)
+ {
+ HANDLE hConn = hNetlibHttp;
+ hNetlibHttp = NULL;
+ Netlib_CloseHandle(hConn);
+ }
+}
+
diff --git a/plugins/weather/weather_icons.c b/plugins/weather/weather_icons.c
new file mode 100644
index 0000000000..e1b95c4405
--- /dev/null
+++ b/plugins/weather/weather_icons.c
@@ -0,0 +1,90 @@
+/*
+Weather Protocol plugin for Miranda IM
+Copyright (C) 2005-2011 Boris Krasnovskiy All Rights Reserved
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; version 2
+of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#include "weather.h"
+
+HANDLE hIcoLibIconsChanged = NULL;
+
+struct _tag_iconList
+{
+ char* szDescr;
+ char* szName;
+ int defIconID;
+ HANDLE hIconLibItem;
+}
+static iconList[] =
+{
+ { "Protocol icon", "main", IDI_ICON },
+ { "Update Disabled", "disabled", IDI_DISABLED },
+ { "View Log", "log", IDI_LOG },
+ { "Update with Clear", "update2", IDI_UPDATE2 },
+ { "View Brief", "brief", IDI_S },
+ { "View Complete", "read", IDI_READ },
+ { "Weather Update", "update", IDI_UPDATE },
+ { "Weather Map", "map", IDI_MAP },
+ { "Popup", "popup", IDI_POPUP },
+ { "No Popup", "nopopup", IDI_NOPOPUP },
+ { "Edit Settings", "edit", IDI_EDIT },
+};
+
+void InitIcons(void)
+{
+ char szFile[MAX_PATH];
+ char szSettingName[100];
+ SKINICONDESC sid = {0};
+ unsigned i;
+
+ GetModuleFileName(hInst, szFile, MAX_PATH);
+
+ sid.cbSize = sizeof(SKINICONDESC);
+ sid.pszDefaultFile = szFile;
+ sid.pszName = szSettingName;
+ sid.pszSection = WEATHERPROTONAME;
+
+ for (i = 0; i < SIZEOF(iconList); i++)
+ {
+ mir_snprintf(szSettingName, sizeof( szSettingName ), "%s_%s", WEATHERPROTONAME, iconList[i].szName);
+
+ sid.pszDescription = iconList[i].szDescr;
+ sid.iDefaultIndex = -iconList[i].defIconID;
+ iconList[i].hIconLibItem = ( HANDLE )CallService(MS_SKIN2_ADDICON, 0, (LPARAM)&sid);
+ }
+}
+
+
+HICON LoadIconEx(const char* name, BOOL big)
+{
+ char szSettingName[100];
+ mir_snprintf(szSettingName, sizeof(szSettingName), "%s_%s", WEATHERPROTONAME, name);
+ return (HICON)CallService(MS_SKIN2_GETICON, big, (LPARAM)szSettingName);
+}
+
+HANDLE GetIconHandle(const char* name)
+{
+ unsigned i;
+ for (i=0; i < SIZEOF(iconList); i++)
+ if (strcmp(iconList[i].szName, name) == 0)
+ return iconList[i].hIconLibItem;
+ return NULL;
+}
+
+void ReleaseIconEx(HICON hIcon)
+{
+ CallService(MS_SKIN2_RELEASEICON, (WPARAM)hIcon, 0);
+}
diff --git a/plugins/weather/weather_info.c b/plugins/weather/weather_info.c
new file mode 100644
index 0000000000..b5997feb6c
--- /dev/null
+++ b/plugins/weather/weather_info.c
@@ -0,0 +1,253 @@
+/*
+Weather Protocol plugin for Miranda IM
+Copyright (C) 2005-2011 Boris Krasnovskiy All Rights Reserved
+Copyright (C) 2002-2005 Calvin Che
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; version 2
+of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+/*
+This file contain the source for displaying information for the
+ini files, as well as function that are used for debug purpose
+regrading the loading of ini contents
+*/
+
+#include "weather.h"
+
+//============ INI INFORMATION ============
+
+// List INI Information for all loaded INI files
+void INIInfo(HWND hwndDlg)
+{
+ char str[16];
+ size_t memused = 0;
+ LVITEM lvi = {0};
+ WIDATALIST *Item = WIHead;
+
+ HWND hIniList = GetDlgItem(hwndDlg, IDC_INFOLIST);
+
+ ListView_DeleteAllItems(hIniList);
+
+ lvi.mask = LVIF_TEXT;
+ lvi.iItem = 0;
+ while (Item != NULL)
+ {
+ // get the data for the ini file
+ lvi.iSubItem = 0;
+ lvi.pszText = Item->Data.InternalName;
+ ListView_InsertItem(hIniList, &lvi);
+ lvi.iSubItem = 1;
+ lvi.pszText = Item->Data.Author;
+ ListView_SetItem(hIniList, &lvi);
+ lvi.iSubItem = 2;
+ lvi.pszText = Item->Data.Version;
+ ListView_SetItem(hIniList, &lvi);
+ lvi.iSubItem = 3;
+ switch (Item->Data.InternalVer)
+ {
+ case 1: lvi.pszText = "1.0"; break;
+ case 2: lvi.pszText = "1.1"; break;
+ case 3: lvi.pszText = "1.1a"; break;
+ case 4: lvi.pszText = "1.2"; break;
+ case 5: lvi.pszText = "1.3"; break;
+ case 6: lvi.pszText = "1.4"; break;
+ default: lvi.pszText = ""; break;
+ }
+ ListView_SetItem(hIniList, &lvi);
+ lvi.iSubItem = 4;
+ lvi.pszText = _ltoa(Item->Data.UpdateDataCount, str, 10);
+ ListView_SetItem(hIniList, &lvi);
+ lvi.iSubItem = 5;
+ lvi.pszText = Item->Data.DisplayName;
+ ListView_SetItem(hIniList, &lvi);
+ lvi.iSubItem = 6;
+ lvi.pszText = Item->Data.ShortFileName;
+ ListView_SetItem(hIniList, &lvi);
+
+ memused += Item->Data.MemUsed;
+
+ Item = Item->next;
+ ++lvi.iItem;
+ }
+ SetDlgItemText(hwndDlg, IDC_INICOUNT, _itoa(lvi.iItem, str, 10));
+ SetDlgItemText(hwndDlg, IDC_MEMUSED, _ltoa((long)memused, str, 10));
+}
+
+static const struct tag_Columns
+{
+ const char *name;
+ unsigned size;
+}
+columns[] =
+{
+ { "Name" , 70 },
+ { "Author" , 100 },
+ { "File Version" , 70 },
+ { "INI Version" , 70 },
+ { "Items" , 40 },
+ { "Display Name" , 200 },
+ { "File Name" , 150 },
+};
+
+
+INT_PTR CALLBACK DlgProcINIPage(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hwndDlg);
+ {
+ unsigned i;
+
+ HWND hIniList = GetDlgItem(hwndDlg, IDC_INFOLIST);
+ LVCOLUMN lvc = {0};
+
+ lvc.mask = LVCF_FMT | LVCF_SUBITEM | LVCF_TEXT | LVCF_WIDTH;
+ lvc.fmt = LVCFMT_LEFT;
+ for (i=0; i<7; ++i)
+ {
+ lvc.iSubItem = i;
+ lvc.pszText = Translate(columns[i].name);
+ lvc.cx = columns[i].size;
+ ListView_InsertColumnWth(hIniList, i, &lvc);
+ }
+ INIInfo(hwndDlg);
+ }
+
+ break;
+
+ case WM_DESTROY:
+ break;
+
+ case WM_COMMAND:
+ if ( HIWORD(wParam) == BN_CLICKED &&
+ LOWORD(wParam) == IDC_RELOADINI )
+ {
+ DestroyWIList();
+ LoadWIData(TRUE);
+ INIInfo(hwndDlg);
+ }
+ break;
+ }
+ return 0;
+}
+
+
+// get the info of individual ini file
+// pszSvc = the internal name of the service to get the data
+void GetINIInfo(char *pszSvc) {
+ char str2[2048];
+ WIDATA *sData = GetWIData(pszSvc);
+ // if the service does not exist among the loaded INI's
+ if (sData == NULL)
+ {
+ wsprintf(str2, Translate("The corresponding INI file for \"%s\" is not found."), pszSvc);
+ MessageBox(NULL, str2, Translate("Weather INI information"), MB_OK|MB_ICONINFORMATION);
+ }
+ // if exist, get the information
+ else
+ {
+ wsprintf(str2, Translate("Weather INI information for \"%s\":"), pszSvc);
+ strcat(str2, "\n\n");
+ strcat(str2, Translate("Name:"));
+ strcat(str2, "\t\t");
+ strcat(str2, sData->DisplayName);
+ strcat(str2, "\n");
+ strcat(str2, Translate("Internal Name:"));
+ strcat(str2, "\t");
+ strcat(str2, sData->InternalName);
+ strcat(str2, "\n");
+ strcat(str2, Translate("Author:"));
+ strcat(str2, "\t\t");
+ strcat(str2, sData->Author);
+ strcat(str2, "\n");
+ strcat(str2, Translate("Version:"));
+ strcat(str2, "\t\t");
+ strcat(str2, sData->Version);
+ strcat(str2, "\n");
+ strcat(str2, Translate("INI Version:"));
+ strcat(str2, "\t");
+ switch (sData->InternalVer)
+ {
+ case 1: strcat(str2, "1.0"); break;
+ case 2: strcat(str2, "1.1"); break;
+ case 3: strcat(str2, "1.1a"); break;
+ case 4: strcat(str2, "1.2"); break;
+ case 5: strcat(str2, "1.3"); break;
+ case 6: strcat(str2, "1.4"); break;
+ }
+ strcat(str2, "\n");
+ strcat(str2, Translate("File Name:"));
+ strcat(str2, "\t");
+ strcat(str2, sData->ShortFileName);
+ strcat(str2, "\n");
+ strcat(str2, Translate("Item Count:"));
+ wsprintf(str2, "%s\t%i\n", str2, sData->UpdateDataCount);
+ strcat(str2, Translate("Memory Used:"));
+ wsprintf(str2, "%s\t%i ", str2, sData->MemUsed);
+ strcat(str2, Translate("bytes"));
+ strcat(str2, "\n\n");
+ strcat(str2, Translate("Description:"));
+ strcat(str2, "\n");
+ strcat(str2, sData->Description);
+
+ // display the message box and quit
+ MessageBox(NULL, str2, Translate("Weather INI information"), MB_OK|MB_ICONINFORMATION);
+ }
+}
+
+//============ DISPLAY A LIST FOR CUSTOM VARIABLES ============
+
+// a message box for displaying the list of custom variables
+// can be found when click on "More" in text option dialog
+void MoreVarList(void)
+{
+ char str[10240], tempstr[1024], *find;
+
+ WIDATALIST *Item = WIHead;
+ // heading
+ strcpy(str, Translate("Here is a list of custom variables that are currently available"));
+ strcat(str, "\n\n");
+ // loop through all weather services to find custom variables
+ while (Item != NULL)
+ {
+ WIDATAITEMLIST* WItem;
+ WItem = Item->Data.UpdateData;
+ // loop through all update items in a service
+ while (WItem != NULL)
+ {
+ // the custom variable is defined as "%[<variable name>]"
+ // ignore the "hi" item and hidden items
+ if (strcmp(WItem->Item.Name, "Ignore") && WItem->Item.Name[0] != '#') {
+ wsprintf(tempstr, "%c[%s]", '%', WItem->Item.Name);
+ find = strstr(str, tempstr);
+ // if the custom variable does not exist in the list, add it to the list
+ if (find == NULL) {
+ strcat(str, tempstr);
+ strcat(str, ", ");
+ }
+ }
+ WItem = WItem->Next;
+ }
+ Item = Item->next;
+ }
+ // remove the last comma in the list
+ find = strrchr(str, ',');
+ if (find != NULL) *find = '\0';
+
+ // display the list in a message box
+ MessageBox(NULL, str, Translate("More Variables"), MB_OK|MB_ICONINFORMATION|MB_TOPMOST);
+}
+
diff --git a/plugins/weather/weather_ini.c b/plugins/weather/weather_ini.c
new file mode 100644
index 0000000000..eba127bdaf
--- /dev/null
+++ b/plugins/weather/weather_ini.c
@@ -0,0 +1,628 @@
+/*
+Weather Protocol plugin for Miranda IM
+Copyright (C) 2005-2011 Boris Krasnovskiy All Rights Reserved
+Copyright (C) 2002-2005 Calvin Che
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; version 2
+of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+/*
+This file contain the source related to loading the reading the
+weather ini files and store them into memory. Also containing
+code for unloading and getting weather data from the ini settings.
+*/
+
+#include "weather.h"
+
+HWND hWndSetup;
+
+//============ DATA LIST (LINKED LIST) ============
+
+// add an item into weather service data list
+// Data = the service data to be added to the list
+void WIListAdd(WIDATA Data)
+{
+ WIDATALIST *newItem;
+
+ // create a new datalist item and point to the data
+ newItem = (WIDATALIST*)mir_alloc(sizeof(WIDATALIST));
+ newItem->Data = Data;
+ // add to the linked list
+ newItem->next = NULL;
+ if (WITail == NULL) WIHead = newItem;
+ else WITail->next = newItem;
+ WITail = newItem;
+}
+
+// get the service data (from loaded ini file) by internal name
+// pszServ = internal name for the service
+// return value = the matching WIDATA struct for pszServ, NULL if no match found
+WIDATA* GetWIData(char *pszServ)
+{
+ WIDATALIST *Item = WIHead;
+
+ // loop through the list to find matching internal name
+ while (Item != NULL)
+ {
+ // if internal name found, return the data
+ if (strcmp(Item->Data.InternalName, pszServ) == 0) return &Item->Data;
+ Item = Item->next;
+ }
+ // return NULL when no match found
+ return NULL;
+}
+
+// remove all service data from memory
+void DestroyWIList(void)
+{
+ // free the list one by one
+ while (WIHead != NULL)
+ {
+ WIDATALIST *wi = WIHead;
+ WIHead = wi->next;
+ FreeWIData(&wi->Data); // free the data struct
+ mir_free(wi);
+ }
+
+ // make sure the entire list is clear
+ WITail = NULL;
+}
+
+//============ DATA ITEM LIST (LINKED LIST) ============
+
+// add a new update item into the current list
+void WIItemListAdd(WIDATAITEM *DataItem, WIDATA *Data)
+{
+ WIDATAITEMLIST *newItem;
+
+ newItem = (WIDATAITEMLIST*)mir_alloc(sizeof(WIDATAITEMLIST));
+ newItem->Item = *DataItem;
+ newItem->Next = NULL;
+ if (Data->UpdateData == NULL) Data->UpdateData = newItem;
+ else Data->UpdateDataTail->Next = newItem;
+ Data->UpdateDataTail = newItem;
+}
+
+// reset the data item by using empty string
+// Item = the item to set
+// name = the string to store in the "name" field
+void ResetDataItem(WIDATAITEM *Item, const char *name)
+{
+ char str[] = "ID Search - Station Name";
+ Item->Name = mir_alloc(sizeof(str));
+ strcpy(Item->Name, str);
+ Item->Start = "";
+ Item->End = "";
+ Item->Unit = "";
+ Item->Url = "";
+ Item->Break = "";
+ Item->Type = 0;
+}
+
+// free the data item by using empty string
+// Item = the item to free
+void FreeDataItem(WIDATAITEM *Item)
+{
+ wfree(&Item->Name);
+ wfree(&Item->Start);
+ wfree(&Item->End);
+ wfree(&Item->Unit);
+ wfree(&Item->Url);
+ wfree(&Item->Break);
+}
+
+//============ Condition Icon List ============
+
+// initiate icon assignmet list
+void WICondListInit(WICONDLIST *List)
+{
+ List->Tail = NULL;
+ List->Head = NULL;
+}
+
+// add a new update item into the current list
+void WICondListAdd(char *str, WICONDLIST *List)
+{
+ WICONDITEM *newItem;
+
+ newItem = (WICONDITEM*)mir_alloc(sizeof(WICONDITEM));
+ CharLowerBuff(str, (DWORD)strlen(str));
+ wSetData(&newItem->Item, str);
+ newItem->Next = NULL;
+ if (List->Tail == NULL) List->Head = newItem;
+ else List->Tail->Next = newItem;
+ List->Tail = newItem;
+}
+
+// check if the condition string matched for the assignment
+BOOL IsContainedInCondList(const char *pszStr, WICONDLIST *List)
+{
+ WICONDITEM *Item = List->Head;
+
+ // loop through the list to find matching internal name
+ while (Item != NULL)
+ {
+ // if internal name found, return true indicating that the data is found
+ if (strstr(pszStr, Item->Item)) return TRUE;
+ Item = Item->Next;
+ }
+ // return false when no match found
+ return FALSE;
+}
+
+// free the memory for icon assignment list
+void DestroyCondList(WICONDLIST *List)
+{
+ WICONDITEM *temp;
+
+ temp = List->Head;
+
+ // free the list one by one
+ while (temp != NULL)
+ {
+ List->Head = temp->Next;
+ wfree(&temp->Item); // free the data struct
+ mir_free(temp);
+ temp = List->Head;
+ }
+ // make sure the entire list is clear
+ List->Tail = NULL;
+}
+
+
+//============ LOADING INI FILES ============
+
+// load the weather update data form INI files
+BOOL LoadWIData(BOOL dial)
+{
+ HANDLE hFind;
+ char szSearchPath[MAX_PATH], FileName[MAX_PATH], *chop;
+ WIN32_FIND_DATA fd;
+ WIDATA Data;
+
+ // make sure that the current service data list is empty
+ WITail = NULL;
+ WIHead = WITail;
+
+ // find all *.ini file in the plugin\weather directory
+ GetModuleFileName(GetModuleHandle(NULL), szSearchPath, sizeof(szSearchPath));
+ chop = strrchr(szSearchPath, '\\');
+ *chop = '\0';
+ strcat(szSearchPath,"\\Plugins\\Weather\\*.ini");
+ strcpy(FileName, szSearchPath);
+
+ hFind = FindFirstFile(szSearchPath, &fd);
+
+ // load the content of the ini file into memory
+ if (hFind != INVALID_HANDLE_VALUE)
+ {
+ do
+ {
+ chop = strrchr(FileName, '\\');
+ chop[1] = '\0';
+ strcat(FileName, fd.cFileName);
+ if (_stricmp(fd.cFileName, "SAMPLE_INI.INI"))
+ {
+ LoadStationData(FileName, fd.cFileName, &Data);
+ if (Data.Enabled) WIListAdd(Data);
+ }
+ // look through the entire "plugins\weather" directory
+ }
+ while(FindNextFile(hFind, &fd));
+ FindClose(hFind);
+ }
+ if (WIHead == NULL)
+ {
+ // no ini found, display an error message box.
+ if (dial)
+ hWndSetup = CreateDialog(hInst, MAKEINTRESOURCE(IDD_SETUP), NULL, DlgProcSetup);
+ else
+ MessageBox(NULL,
+ Translate("No update data file is found. Please check your Plugins\\Weather directory."),
+ Translate("Weather Protocol"), MB_OK | MB_ICONERROR);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+// load the station data from a file
+// pszFile = the file name + path for the ini file to be loaded
+// pszShortFile = the file name of the ini file, but not including the path
+// Data = the struct to load the ini content to, and return to previous function
+void LoadStationData(char *pszFile, char *pszShortFile, WIDATA *Data)
+{
+ WIDATAITEM DataItem;
+ FILE *pfile;
+ int i;
+ char Line[4096], *Group, *Temp;
+ char *ValName, *Value;
+
+ static const char *statusStr[10] =
+ {
+ "LIGHTNING",
+ "FOG",
+ "SNOW SHOWER",
+ "SNOW",
+ "RAIN SHOWER",
+ "RAIN",
+ "PARTLY CLOUDY",
+ "CLOUDY",
+ "SUNNY",
+ "N/A"
+ };
+
+ // clean up old stuff
+ ZeroMemory(Data, sizeof(Data));
+ Data->Enabled = FALSE;
+
+ // open the ini file
+ pfile = _fsopen(pszFile, "rt", _SH_DENYWR);
+ if (pfile != NULL)
+ {
+ fgets(Line, sizeof(Line), pfile);
+ TrimString(Line);
+ // make sure it is a valid weather protocol ini file
+ if (!strcmp(Line, "[Weather 0.3.x Update Data]"))
+ Data->InternalVer = 1;
+ else if (!strcmp(Line, "[Weather 0.3.x Update Data 1.1]"))
+ Data->InternalVer = 2;
+ else if (!strcmp(Line, "[Weather 0.3.x Update Data 1.1a]"))
+ Data->InternalVer = 3;
+ else if (!strcmp(Line, "[Weather 0.3.x Update Data 1.2]"))
+ Data->InternalVer = 4;
+ else if (!strcmp(Line, "[Weather 0.3.x Update Data 1.3]"))
+ Data->InternalVer = 5;
+ else if (!strcmp(Line, "[Weather 0.3.x Update Data 1.4]"))
+ Data->InternalVer = 6;
+ else
+ {
+ wsprintf(Line, Translate("Invalid ini format for: %s"), pszFile);
+ MessageBox(NULL, Line, Translate("Weather Protocol"), MB_OK|MB_ICONERROR);
+ fclose(pfile);
+ return;
+ }
+
+ // initialize all data fields
+ Group = "";
+ Data->DisplayName = "";
+ Data->InternalName = "";
+ Data->Description = "";
+ Data->Author = "";
+ Data->Version = "";
+ Data->DefaultURL = "";
+ Data->DefaultMap = "";
+ Data->UpdateURL = "";
+ Data->UpdateURL2 = "";
+ Data->UpdateURL3 = "";
+ Data->UpdateURL4 = "";
+ Data->Cookie = "";
+ Data->IDSearch.SearchURL = "";
+ Data->IDSearch.NotFoundStr = "";
+ Data->NameSearch.SearchURL = "";
+ Data->NameSearch.NotFoundStr = "";
+ Data->NameSearch.SingleStr = "";
+ Data->NameSearch.Single.First = "";
+ Data->NameSearch.Multiple.First = "";
+ Data->IDSearch.Available = FALSE;
+ Data->NameSearch.Single.Available = FALSE;
+ Data->NameSearch.Multiple.Available = FALSE;
+ wSetData(&Data->FileName, pszFile);
+ wSetData(&Data->ShortFileName, pszShortFile);
+
+ ResetDataItem(&Data->IDSearch.Name, "ID Search - Station Name");
+ ResetDataItem(&Data->NameSearch.Single.Name, "Name Search Single Result - Station Name");
+ ResetDataItem(&Data->NameSearch.Single.ID, "Name Search Single Result - Station ID");
+ ResetDataItem(&Data->NameSearch.Multiple.Name, "Name Search Multiple Result - Station Name");
+ ResetDataItem(&Data->NameSearch.Multiple.ID, "Name Search Multiple Result - Station ID");
+
+ DataItem.Name = "";
+ DataItem.Start = "";
+ DataItem.End = "";
+ DataItem.Unit = "";
+ DataItem.Url = "";
+ DataItem.Break = "";
+ DataItem.Type = 0;
+
+ Temp = "";
+
+ // initialize the linked list for update items
+ Data->UpdateDataCount = 0;
+ Data->MemUsed = sizeof(WIDATA) + sizeof(WIDATALIST) + strlen(pszShortFile) + strlen(pszFile) + 20;
+ Data->UpdateData = NULL;
+ Data->UpdateDataTail = NULL;
+
+ // initialize the icon assignment list
+ for (i=0; i<10; i++) WICondListInit(&Data->CondList[i]);
+
+ while (!feof(pfile))
+ {
+ // determine current tag
+
+ if (fgets(Line, sizeof(Line), pfile) == NULL) break;
+ TrimString(Line);
+
+ // if the line is a group header/footer
+ if (Line[0] == '[')
+ {
+ char *chop = strchr(Line+1,']');
+ if (chop == NULL) continue;
+ if (Line[1] != '/') // if it is not a footer (for old ini)
+ {
+ // save the group name
+ Temp = (char *)mir_alloc(strlen(Line)+10);
+ strncpy(Temp, Line+1, chop-Line-1);
+ Temp[chop-Line-1] = 0;
+ wfree(&Group);
+ wSetData(&Group, Temp);
+ // see if it is a update item, if it is, add a new item to the linked list
+ // if (_stricmp(Group, "HEADER") && _stricmp(Group, "DEFAULT") && _stricmp(Group, "ID SEARCH") &&
+ // strcmpi(Group, "NAME SEARCH"))
+ // wSetData(&DataItem.Name, Group);
+ if (_stricmp(Group, "HEADER") && _stricmp(Group, "DEFAULT") && _stricmp(Group, "ID SEARCH") &&
+ _stricmp(Group, "NAME SEARCH") && _stricmp(Group, "ICONS"))
+ {
+ wSetData(&DataItem.Name, Temp);
+ DataItem.Type = WID_NORMAL;
+ WIItemListAdd(&DataItem, Data);
+ Data->UpdateDataCount++;
+ }
+ mir_free(Temp);
+ }
+ else
+ {
+ wfree(&Group);
+ wSetData(&Group, "");
+ }
+ }
+ // ignore comments and all lines without an '='
+ Value = strstr(Line, "=");
+ if (Value == NULL) continue;
+
+ // get the string before '=' (ValName) and after '=' (Value)
+ ValName = (char *)mir_alloc(strlen(Line)+1);
+ strncpy(ValName, Line, Value-Line);
+ ValName[Value-Line] = 0;
+ Value++;
+ ConvertBackslashes(Value);
+ // store the value for each string
+ if (!_stricmp(Group, "HEADER"))
+ {
+ if (!_stricmp(ValName, "NAME")) wSetData(&Data->DisplayName, Value);
+ else if (!_stricmp(ValName, "INTERNAL NAME")) wSetData(&Data->InternalName, Value);
+ else if (!_stricmp(ValName, "DESCRIPTION")) wSetData(&Data->Description, Value);
+ else if (!_stricmp(ValName, "AUTHOR")) wSetData(&Data->Author, Value);
+ else if (!_stricmp(ValName, "VERSION")) wSetData(&Data->Version, Value);
+ }
+ else if (!_stricmp(Group, "DEFAULT")) {
+ if (!_stricmp(ValName, "DEFAULT URL")) wSetData(&Data->DefaultURL, Value);
+ else if (!_stricmp(ValName, "DEFAULT MAP")) wSetData(&Data->DefaultMap, Value);
+ else if (!_stricmp(ValName, "UPDATE URL")) wSetData(&Data->UpdateURL, Value);
+ else if (!_stricmp(ValName, "UPDATE URL2")) wSetData(&Data->UpdateURL2, Value);
+ else if (!_stricmp(ValName, "UPDATE URL3")) wSetData(&Data->UpdateURL3, Value);
+ else if (!_stricmp(ValName, "UPDATE URL4")) wSetData(&Data->UpdateURL4, Value);
+ else if (!_stricmp(ValName, "COOKIE")) wSetData(&Data->Cookie, Value);
+ }
+ else if (!_stricmp(Group, "ID SEARCH"))
+ {
+ if (!_stricmp(ValName, "AVAILABLE"))
+ {
+ if (!_stricmp(Value, "TRUE")) Data->IDSearch.Available = TRUE;
+ else Data->IDSearch.Available = FALSE;
+ }
+ else if (!_stricmp(ValName, "SEARCH URL")) wSetData(&Data->IDSearch.SearchURL, Value);
+ else if (!_stricmp(ValName, "NOT FOUND STR")) wSetData(&Data->IDSearch.NotFoundStr, Value);
+ else if (!_stricmp(ValName, "NAME START")) wSetData(&Data->IDSearch.Name.Start, Value);
+ else if (!_stricmp(ValName, "NAME END")) wSetData(&Data->IDSearch.Name.End, Value);
+ }
+ else if (!_stricmp(Group, "NAME SEARCH"))
+ {
+ if (!_stricmp(ValName, "SINGLE RESULT"))
+ {
+ if (!_stricmp(Value, "TRUE")) Data->NameSearch.Single.Available = TRUE;
+ else Data->NameSearch.Single.Available = FALSE;
+ }
+ else if (!_stricmp(ValName, "MULTIPLE RESULT"))
+ {
+ if (!_stricmp(Value, "TRUE")) Data->NameSearch.Multiple.Available = TRUE;
+ else Data->NameSearch.Multiple.Available = FALSE;
+ }
+ else if (!_stricmp(ValName, "SEARCH URL")) wSetData(&Data->NameSearch.SearchURL, Value);
+ else if (!_stricmp(ValName, "NOT FOUND STR")) wSetData(&Data->NameSearch.NotFoundStr, Value);
+ else if (!_stricmp(ValName, "SINGLE RESULT STR")) wSetData(&Data->NameSearch.SingleStr, Value);
+ else if (!_stricmp(ValName, "SINGLE FIRST")) wSetData(&Data->NameSearch.Single.First, Value);
+ else if (!_stricmp(ValName, "SINGLE NAME START"))wSetData(&Data->NameSearch.Single.Name.Start, Value);
+ else if (!_stricmp(ValName, "SINGLE NAME END")) wSetData(&Data->NameSearch.Single.Name.End, Value);
+ else if (!_stricmp(ValName, "SINGLE ID START")) wSetData(&Data->NameSearch.Single.ID.Start, Value);
+ else if (!_stricmp(ValName, "SINGLE ID END")) wSetData(&Data->NameSearch.Single.ID.End, Value);
+ else if (!_stricmp(ValName, "MULT FIRST")) wSetData(&Data->NameSearch.Multiple.First, Value);
+ else if (!_stricmp(ValName, "MULT NAME START")) wSetData(&Data->NameSearch.Multiple.Name.Start, Value);
+ else if (!_stricmp(ValName, "MULT NAME END")) wSetData(&Data->NameSearch.Multiple.Name.End, Value);
+ else if (!_stricmp(ValName, "MULT ID START")) wSetData(&Data->NameSearch.Multiple.ID.Start, Value);
+ else if (!_stricmp(ValName, "MULT ID END")) wSetData(&Data->NameSearch.Multiple.ID.End, Value);
+ }
+ else if (!_stricmp(Group, "ICONS"))
+ {
+ for (i=0; i<10; i++)
+ {
+ if (!_stricmp(ValName, statusStr[i]))
+ {
+ WICondListAdd(Value, &Data->CondList[i]);
+ break;
+ }
+ }
+ }
+ else if (Data->UpdateDataCount != 0)
+ {
+ if (!_stricmp(ValName, "START")) wSetData(&Data->UpdateDataTail->Item.Start, Value);
+ else if (!_stricmp(ValName, "SOURCE")) wSetData(&Data->UpdateDataTail->Item.Start, Value);
+ else if (!_stricmp(ValName, "END")) wSetData(&Data->UpdateDataTail->Item.End, Value);
+ else if (!_stricmp(ValName, "UNIT")) wSetData(&Data->UpdateDataTail->Item.Unit, Value);
+ else if (!_stricmp(ValName, "URL")) wSetData(&Data->UpdateDataTail->Item.Url, Value);
+ else if (!_stricmp(ValName, "HIDDEN"))
+ {
+ if (!_stricmp(Value, "TRUE"))
+ {
+ char *nm = Data->UpdateDataTail->Item.Name;
+ size_t len = strlen(nm) + 1;
+
+ Data->UpdateDataTail->Item.Name = nm = mir_realloc(nm, len + 3);
+ memmove(nm + 1, nm, len);
+ *nm = '#';
+ }
+ }
+ else if (!_stricmp(ValName, "SET DATA"))
+ {
+ Data->UpdateDataTail->Item.Type = WID_SET;
+ wSetData(&Data->UpdateDataTail->Item.End, Value);
+ }
+ else if (!_stricmp(ValName, "BREAK DATA"))
+ {
+ Data->UpdateDataTail->Item.Type = WID_BREAK;
+ wSetData(&Data->UpdateDataTail->Item.Break, Value);
+ }
+ }
+ // recalculate memory used
+ Data->MemUsed += (strlen(Value) + 10);
+ wfree(&ValName);
+ }
+ // calcualate memory used for the ini and close the file
+ Data->MemUsed += sizeof(WIDATAITEMLIST)*Data->UpdateDataCount;
+ Data->Enabled = TRUE; // enable the service
+ fclose(pfile);
+ wfree(&Group);
+ }
+}
+
+//============ FREE WIDATA ITEM FROM MEMORY ============
+
+// free the WIDATA struct from memory
+// Data = the struct to be freed
+void FreeWIData(WIDATA *Data)
+{
+ WIDATAITEMLIST* WItem;
+ int i;
+
+ // free update items linked list first
+ WItem = Data->UpdateData;
+ while (WItem != NULL)
+ {
+ Data->UpdateData = WItem->Next;
+ FreeDataItem(&WItem->Item);
+ mir_free(WItem);
+ WItem = Data->UpdateData;
+ }
+
+ // free the strings in the rest of the struct
+ wfree(&Data->DisplayName);
+ wfree(&Data->InternalName);
+ wfree(&Data->Description);
+ wfree(&Data->Author);
+ wfree(&Data->Version);
+ wfree(&Data->DefaultURL);
+ wfree(&Data->DefaultMap);
+ wfree(&Data->UpdateURL);
+ wfree(&Data->UpdateURL2);
+ wfree(&Data->UpdateURL3);
+ wfree(&Data->UpdateURL4);
+ wfree(&Data->Cookie);
+ wfree(&Data->IDSearch.SearchURL);
+ wfree(&Data->IDSearch.NotFoundStr);
+ FreeDataItem(&Data->IDSearch.Name);
+ wfree(&Data->NameSearch.SearchURL);
+ wfree(&Data->NameSearch.NotFoundStr);
+ wfree(&Data->NameSearch.SingleStr);
+ wfree(&Data->NameSearch.Single.First);
+ FreeDataItem(&Data->NameSearch.Single.Name);
+ FreeDataItem(&Data->NameSearch.Single.ID);
+ wfree(&Data->NameSearch.Multiple.First);
+ FreeDataItem(&Data->NameSearch.Multiple.Name);
+ FreeDataItem(&Data->NameSearch.Multiple.ID);
+ wfree(&Data->ShortFileName);
+ wfree(&Data->FileName);
+ for (i=0; i<10; i++) DestroyCondList(&Data->CondList[i]);
+}
+
+//============ WEATHER INI SETUP DIALOG ============
+
+INT_PTR CALLBACK DlgProcSetup(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hwndDlg);
+
+ // make the buttons flat
+ SendMessage(GetDlgItem(hwndDlg,IDC_STEP1), BUTTONSETASFLATBTN, 0, 0);
+ SendMessage(GetDlgItem(hwndDlg,IDC_STEP2), BUTTONSETASFLATBTN, 0, 0);
+ SendMessage(GetDlgItem(hwndDlg,IDC_STEP3), BUTTONSETASFLATBTN, 0, 0);
+ SendMessage(GetDlgItem(hwndDlg,IDC_STEP4), BUTTONSETASFLATBTN, 0, 0);
+
+ // set icons
+ SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)LoadIconEx("main", TRUE));
+ SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)LoadIconEx("main", FALSE));
+
+ WindowList_Add(hWindowList, hwndDlg, NULL);
+ ShowWindow(hwndDlg, SW_SHOW);
+ break;
+
+ case WM_COMMAND:
+ switch(LOWORD(wParam))
+ {
+ case IDC_STEP1:
+ // update current data
+ CallService(MS_UTILS_OPENURL, opt.NewBrowserWin,
+ (WPARAM)"http://addons.miranda-im.org/index.php?action=display&id=78");
+ break;
+
+ case IDC_STEP2:
+ {
+ char szPath[1024], *chop;
+ GetModuleFileName(GetModuleHandle(NULL), szPath, sizeof(szPath));
+ chop = strrchr(szPath, '\\');
+ *chop = '\0';
+ strcat(szPath,"\\Plugins\\weather\\");
+ _mkdir(szPath);
+ ShellExecute((HWND)lParam, "open", szPath, "", "", SW_SHOW);
+ break;
+ }
+
+ case IDC_STEP3:
+ if (LoadWIData(FALSE))
+ MessageBox(NULL, Translate("All update data has been reloaded."),
+ Translate("Weather Protocol"), MB_OK|MB_ICONINFORMATION);
+ break;
+
+ case IDC_STEP4:
+ WeatherAdd(0, 0);
+
+ case IDCANCEL:
+ // close the info window
+ DestroyWindow(hwndDlg);
+ break;
+ }
+ break;
+
+ case WM_CLOSE:
+ DestroyWindow(hwndDlg);
+ break;
+
+ case WM_DESTROY:
+ ReleaseIconEx((HICON)SendMessage(hwndDlg, WM_SETICON, ICON_BIG, 0));
+ ReleaseIconEx((HICON)SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, 0));
+ break;
+ }
+ return FALSE;
+}
+
diff --git a/plugins/weather/weather_mwin.c b/plugins/weather/weather_mwin.c
new file mode 100644
index 0000000000..ce41e80d17
--- /dev/null
+++ b/plugins/weather/weather_mwin.c
@@ -0,0 +1,449 @@
+/*
+Weather Protocol plugin for Miranda IM
+Copyright (C) 2006-2009 Boris Krasnovskiy All Rights Reserved
+Copyright (C) 2002-2006 Calvin Che
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; version 2
+of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "weather.h"
+#include "m_acc.h"
+
+/* DRAWGLYPH Request structure */
+typedef struct s_SKINDRAWREQUEST
+{
+ char szObjectID[255]; // Unic Object ID (path) to paint
+ RECT rcDestRect; // Rectangle to fit
+ RECT rcClipRect; // Rectangle to paint in.
+ HDC hDC; // Handler to device context to paint in.
+} SKINDRAWREQUEST,*LPSKINDRAWREQUEST;
+
+
+// Request painting glyph object
+// wParam = pointer to SKINDRAWREQUEST structure
+// lParam = 0
+#define MS_SKIN_DRAWGLYPH "ModernList/DrawGlyph"
+
+
+#define MS_TOOLTIP_SHOWTIP "mToolTip/ShowTip"
+#define MS_TOOLTIP_HIDETIP "mToolTip/HideTip"
+
+typedef BOOL (WINAPI *ft_TrackMouseEvent) (LPTRACKMOUSEEVENT lpEventTrack);
+
+static ft_TrackMouseEvent f_TrackMouseEvent = NULL;
+static HANDLE hMwinWindowList;
+static HANDLE hFontHook;
+
+HANDLE hMwinMenu;
+
+typedef struct
+{
+ HANDLE hContact;
+ HWND hAvt;
+ BOOL haveAvatar;
+} MWinDataType;
+
+#define WM_REDRAWWIN (WM_USER + 17369)
+
+static LRESULT CALLBACK wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ MWinDataType *data = (MWinDataType*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
+
+ switch(msg)
+ {
+ case WM_CREATE:
+ data = (MWinDataType*)mir_calloc(sizeof(MWinDataType));
+ SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)data);
+
+ data->hContact = (HANDLE)((LPCREATESTRUCT)lParam)->lpCreateParams;
+ data->hAvt = CreateWindow(AVATAR_CONTROL_CLASS, TEXT(""), WS_CHILD,
+ 0, 0, opt.AvatarSize, opt.AvatarSize, hwnd, NULL, hInst, 0);
+ if (data->hAvt) SendMessage(data->hAvt, AVATAR_SETCONTACT, 0, (LPARAM)data->hContact);
+ break;
+
+ case WM_DESTROY:
+ mir_free(data);
+ break;
+
+ case WM_CONTEXTMENU:
+ {
+ POINT pt;
+ HMENU hMenu;
+
+ hMenu = (HMENU)CallService(MS_CLIST_MENUBUILDCONTACT, (WPARAM)data->hContact, 0);
+ GetCursorPos(&pt);
+ TrackPopupMenu(hMenu, TPM_LEFTALIGN, pt.x, pt.y, 0, hwnd, NULL);
+ DestroyMenu(hMenu);
+ }
+ break;
+
+ case WM_MOUSEMOVE:
+ if (f_TrackMouseEvent)
+ {
+ TRACKMOUSEEVENT tme = {0};
+ tme.cbSize = sizeof(TRACKMOUSEEVENT);
+ tme.hwndTrack = hwnd;
+ tme.dwFlags = TME_QUERY;
+ f_TrackMouseEvent(&tme);
+
+ if (tme.dwFlags == 0)
+ {
+ tme.dwFlags = TME_HOVER | TME_LEAVE;
+ tme.hwndTrack = hwnd;
+ tme.dwHoverTime = CallService(MS_CLC_GETINFOTIPHOVERTIME, 0, 0);
+ f_TrackMouseEvent(&tme);
+ }
+ }
+ break;
+
+ case WM_MOUSEHOVER:
+ {
+ POINT pt;
+ CLCINFOTIP ti = {0};
+
+ GetCursorPos(&pt);
+ GetWindowRect(hwnd, &ti.rcItem);
+
+ ti.cbSize = sizeof(ti);
+ ti.hItem = data->hContact;
+ ti.ptCursor = pt;
+ ti.isTreeFocused = 1;
+ CallService(MS_TOOLTIP_SHOWTIP, 0, (LPARAM)&ti);
+ }
+ break;
+
+ case WM_LBUTTONDBLCLK:
+ BriefInfo((WPARAM)data->hContact, 0);
+ break;
+
+ case WM_COMMAND: //Needed by the contact's context menu
+ if (CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(wParam),MPCF_CONTACTMENU), (LPARAM)data->hContact))
+ break;
+ return FALSE;
+
+ case WM_MEASUREITEM: //Needed by the contact's context menu
+ return CallService(MS_CLIST_MENUMEASUREITEM, wParam, lParam);
+
+ case WM_DRAWITEM: //Needed by the contact's context menu
+ return CallService(MS_CLIST_MENUDRAWITEM, wParam, lParam);
+
+ case WM_NOTIFY:
+ if (((LPNMHDR)lParam)->code == NM_AVATAR_CHANGED)
+ {
+ BOOL newava = CallService(MS_AV_GETAVATARBITMAP, (WPARAM)data->hContact, 0) != 0;
+ if (newava != data->haveAvatar)
+ {
+ LONG_PTR style = GetWindowLongPtr(data->hAvt, GWL_STYLE);
+ data->haveAvatar = newava;
+ SetWindowLongPtr(data->hAvt, GWL_STYLE, newava ? (style | WS_VISIBLE) : (style & ~WS_VISIBLE));
+ RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE);
+ }
+ }
+ break;
+
+ case WM_REDRAWWIN:
+ if (data->hAvt != NULL) MoveWindow(data->hAvt, 0, 0, opt.AvatarSize, opt.AvatarSize, TRUE);
+ RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
+ break;
+
+ case WM_PAINT:
+ {
+ RECT r, rc;
+
+ if(GetUpdateRect(hwnd, &r, FALSE))
+ {
+ DBVARIANT dbv = {0};
+ PAINTSTRUCT ps;
+ HDC hdc;
+ LOGFONT lfnt, lfnt1;
+ COLORREF fntc, fntc1;
+ COLORREF clr;
+ int picSize = opt.AvatarSize;
+ HICON hIcon = NULL;
+
+ if (!data->haveAvatar)
+ {
+ int statusIcon = DBGetContactSettingWord(data->hContact, WEATHERPROTONAME, "Status", 0);
+
+ picSize = GetSystemMetrics(SM_CXICON);
+ hIcon = LoadSkinnedProtoIconBig(WEATHERPROTONAME, statusIcon);
+ if ((INT_PTR)hIcon == CALLSERVICE_NOTFOUND)
+ {
+ picSize = GetSystemMetrics(SM_CXSMICON);
+ hIcon = LoadSkinnedProtoIcon(WEATHERPROTONAME, statusIcon);
+ }
+ }
+
+ clr = DBGetContactSettingDword(NULL, WEATHERPROTONAME, "ColorMwinFrame", GetSysColor(COLOR_3DFACE));
+
+ {
+ FontID fntid = {0};
+ strcpy(fntid.group, WEATHERPROTONAME);
+ strcpy(fntid.name, "Frame Font");
+ fntc = CallService(MS_FONT_GET, (WPARAM)&fntid, (LPARAM)&lfnt);
+
+ strcpy(fntid.name, "Frame Title Font");
+ fntc1 = CallService(MS_FONT_GET, (WPARAM)&fntid, (LPARAM)&lfnt1);
+ }
+
+ DBGetContactSettingString(data->hContact, WEATHERCONDITION, "WeatherInfo", &dbv);
+
+ GetClientRect(hwnd, &rc);
+
+ hdc = BeginPaint(hwnd, &ps);
+
+ if (ServiceExists(MS_SKIN_DRAWGLYPH))
+ {
+ SKINDRAWREQUEST rq;
+ memset(&rq, 0, sizeof(rq));
+ rq.hDC = hdc;
+ rq.rcDestRect = rc;
+ rq.rcClipRect = rc;
+
+ strcpy(rq.szObjectID, "Main,ID=WeatherFrame");
+ CallService(MS_SKIN_DRAWGLYPH, (WPARAM)&rq, 0);
+ }
+
+ if (clr != 0xFFFFFFFF)
+ {
+ HBRUSH hBkgBrush = CreateSolidBrush(clr);
+ FillRect(hdc, &rc, hBkgBrush);
+ DeleteObject(hBkgBrush);
+ }
+
+ if (!data->haveAvatar)
+ DrawIconEx(hdc, 1, 1, hIcon, 0, 0, 0, NULL, DI_NORMAL);
+
+ SetBkMode(hdc, TRANSPARENT);
+
+ {
+ HFONT hfnt = CreateFontIndirect(&lfnt1);
+ HFONT hfntold = SelectObject(hdc, hfnt);
+ SIZE fontSize;
+
+ char *nick = (char*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)data->hContact, 0);
+
+ GetTextExtentPoint32(hdc, _T("|"), 1, &fontSize);
+
+ rc.top += 1;
+ rc.left += picSize + fontSize.cx;
+
+ SetTextColor(hdc, fntc1);
+ DrawText(hdc, nick, -1, &rc, DT_LEFT | DT_EXPANDTABS);
+
+ rc.top += fontSize.cy;
+
+ SelectObject(hdc, hfntold);
+ DeleteObject(hfnt);
+ }
+
+ if (dbv.pszVal)
+ {
+ HFONT hfnt = CreateFontIndirect(&lfnt);
+ HFONT hfntold = SelectObject(hdc, hfnt);
+
+ SetTextColor(hdc, fntc);
+ DrawText(hdc, dbv.pszVal, -1, &rc, DT_LEFT | DT_EXPANDTABS);
+
+ SelectObject(hdc, hfntold);
+ DeleteObject(hfnt);
+ }
+ EndPaint(hwnd, &ps);
+ CallService(MS_SKIN2_RELEASEICON, (WPARAM)hIcon, 0);
+ DBFreeVariant(&dbv);
+ }
+ break;
+ }
+
+ default:
+ return DefWindowProc(hwnd, msg, wParam, lParam);
+ }
+ return(TRUE);
+}
+
+static void addWindow(HANDLE hContact)
+{
+ CLISTFrame Frame = {0};
+ HWND hWnd;
+ DBVARIANT dbv;
+ char winname[512];
+ DWORD frameID;
+
+ DBGetContactSettingString(hContact, WEATHERPROTONAME, "Nick", &dbv);
+ mir_snprintf(winname, sizeof(winname), "Weather: %s", dbv.pszVal);
+ DBFreeVariant(&dbv);
+
+ hWnd = CreateWindow("WeatherFrame", "", WS_CHILD | WS_VISIBLE,
+ 0, 0, 10, 10, (HWND)CallService(MS_CLUI_GETHWND, 0, 0), NULL, hInst, hContact);
+
+ Frame.name = winname;
+ Frame.cbSize = sizeof(Frame);
+ Frame.hWnd = hWnd;
+ Frame.align = alBottom;
+ Frame.Flags = F_VISIBLE|F_NOBORDER;
+ Frame.height = 32;
+
+ WindowList_Add(hMwinWindowList, hWnd, hContact);
+
+ frameID = CallService(MS_CLIST_FRAMES_ADDFRAME, (WPARAM)&Frame, 0);
+ DBWriteContactSettingDword(hContact, WEATHERPROTONAME, "mwin", frameID);
+ DBWriteContactSettingByte(hContact, "CList", "Hidden", TRUE);
+}
+
+void removeWindow(HANDLE hContact)
+{
+ DWORD frameId = DBGetContactSettingDword(hContact, WEATHERPROTONAME, "mwin", 0);
+
+ WindowList_Remove(hMwinWindowList, WindowList_Find(hMwinWindowList, hContact));
+ CallService(MS_CLIST_FRAMES_REMOVEFRAME, frameId, 0);
+
+ DBWriteContactSettingDword(hContact, WEATHERPROTONAME, "mwin", 0);
+ DBDeleteContactSetting(hContact, "CList", "Hidden");
+}
+
+void UpdateMwinData(HANDLE hContact)
+{
+ HWND hwnd = WindowList_Find(hMwinWindowList, hContact);
+ if (hwnd != NULL)
+ RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
+}
+
+
+INT_PTR Mwin_MenuClicked(WPARAM wParam,LPARAM lParam)
+{
+ BOOL addwnd = WindowList_Find(hMwinWindowList, (HANDLE)wParam) == NULL;
+ if (addwnd)
+ addWindow((HANDLE)wParam);
+ else
+ removeWindow((HANDLE)wParam);
+ return 0;
+}
+
+
+int BuildContactMenu(WPARAM wparam,LPARAM lparam)
+{
+ CLISTMENUITEM mi = {0};
+
+ mi.cbSize = sizeof(mi);
+ mi.flags = CMIM_FLAGS |
+ (DBGetContactSettingDword((HANDLE)wparam, WEATHERPROTONAME, "mwin", 0) ? CMIF_CHECKED : 0);
+ CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMwinMenu, (LPARAM)&mi);
+ return 0;
+}
+
+
+int RedrawFrame(WPARAM wParam, LPARAM lParam)
+{
+ WindowList_Broadcast(hMwinWindowList, WM_REDRAWWIN, 0, 0);
+ return 0;
+}
+
+
+void InitMwin(void)
+{
+ HANDLE hContact;
+ HMODULE hUser = GetModuleHandle("user32.dll");
+
+ if (!ServiceExists(MS_CLIST_FRAMES_ADDFRAME)) return;
+
+ f_TrackMouseEvent = (ft_TrackMouseEvent)GetProcAddress(hUser, "TrackMouseEvent");
+
+
+ hMwinWindowList = (HANDLE)CallService(MS_UTILS_ALLOCWINDOWLIST,0,0);
+
+ {
+ WNDCLASS wndclass;
+ wndclass.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
+ wndclass.lpfnWndProc = wndProc;
+ wndclass.cbClsExtra = 0;
+ wndclass.cbWndExtra = 0;
+ wndclass.hInstance = hInst;
+ wndclass.hIcon = NULL;
+ wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
+ wndclass.hbrBackground = 0; //(HBRUSH)(COLOR_3DFACE+1);
+ wndclass.lpszMenuName = NULL;
+ wndclass.lpszClassName = "WeatherFrame";
+ RegisterClass(&wndclass);
+ }
+
+ {
+ FontID fontid = {0};
+ ColourID colourid = {0};
+ HDC hdc;
+
+ colourid.cbSize = sizeof(ColourID);
+ strcpy(colourid.dbSettingsGroup, WEATHERPROTONAME);
+ strcpy(colourid.setting, "ColorMwinFrame");
+ strcpy(colourid.name, "Frame Background");
+ strcpy(colourid.group, WEATHERPROTONAME);
+ colourid.defcolour = GetSysColor(COLOR_3DFACE);
+
+ CallService(MS_COLOUR_REGISTER, (WPARAM)&colourid, 0);
+
+ fontid.cbSize = sizeof(FontID);
+ fontid.flags = FIDF_ALLOWREREGISTER | FIDF_DEFAULTVALID;
+ strcpy(fontid.dbSettingsGroup, WEATHERPROTONAME);
+ strcpy(fontid.group, WEATHERPROTONAME);
+ strcpy(fontid.name, "Frame Font");
+ strcpy(fontid.prefix, "fnt0");
+
+ hdc = GetDC(NULL);
+ fontid.deffontsettings.size = -MulDiv(8, GetDeviceCaps(hdc, LOGPIXELSY), 72);;
+ ReleaseDC(0, hdc);
+
+ fontid.deffontsettings.charset = DEFAULT_CHARSET;
+ strcpy(fontid.deffontsettings.szFace, "Tahoma");
+ strcpy(fontid.backgroundGroup, WEATHERPROTONAME);
+ strcpy(fontid.backgroundName, "Frame Background");
+
+ CallService(MS_FONT_REGISTER, (WPARAM)&fontid, 0);
+
+ fontid.deffontsettings.style = DBFONTF_BOLD;
+ strcpy(fontid.name, "Frame Title Font");
+ strcpy(fontid.prefix, "fnt1");
+
+ CallService(MS_FONT_REGISTER, (WPARAM)&fontid, 0);
+ }
+
+ hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ while(hContact)
+ {
+ // see if the contact is a weather contact
+ if(IsMyContact(hContact))
+ {
+ if (DBGetContactSettingDword(hContact, WEATHERPROTONAME, "mwin", 0))
+ addWindow(hContact);
+ }
+ hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0);
+ }
+ hFontHook = HookEvent(ME_FONT_RELOAD, RedrawFrame);
+}
+
+void DestroyMwin(void)
+{
+ HANDLE hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ while(hContact)
+ {
+ // see if the contact is a weather contact
+ if(IsMyContact(hContact))
+ {
+ DWORD frameId = DBGetContactSettingDword(hContact, WEATHERPROTONAME, "mwin", 0);
+ if (frameId)
+ CallService(MS_CLIST_FRAMES_REMOVEFRAME, frameId, 0);
+ }
+ hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0);
+ }
+ UnregisterClass("WeatherFrame", hInst);
+ UnhookEvent(hFontHook);
+}
diff --git a/plugins/weather/weather_opt.c b/plugins/weather/weather_opt.c
new file mode 100644
index 0000000000..1bc19d0a1a
--- /dev/null
+++ b/plugins/weather/weather_opt.c
@@ -0,0 +1,648 @@
+/*
+Weather Protocol plugin for Miranda IM
+Copyright (C) 2005-2011 Boris Krasnovskiy All Rights Reserved
+Copyright (C) 2002-2005 Calvin Che
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; version 2
+of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* This file contain the source related to weather option pages. It also
+contain code for saving/loading options from the database.
+*/
+
+#include "weather.h"
+
+static BOOL opt_startup;
+int RedrawFrame(WPARAM wParam, LPARAM lParam);
+
+//============ LOADING AND SAVING OPTIONS ===========
+
+// set a string to default
+// in = string to determine which field to set default "CBNEHXPp"
+void SetTextDefault(const char* in)
+{
+ char str[MAX_TEXT_SIZE];
+
+ if (strchr(in, 'C') != NULL)
+ {
+ FixStr(C_DEFAULT, str);
+ wSetData(&opt.cText, str);
+ }
+ if (strchr(in, 'b') != NULL)
+ {
+ FixStr(b_DEFAULT, str);
+ wSetData(&opt.bTitle, str);
+ }
+ if (strchr(in, 'B') != NULL)
+ {
+ FixStr(B_DEFAULT, str);
+ wSetData(&opt.bText, str);
+ }
+ if (strchr(in, 'N') != NULL)
+ {
+ FixStr(N_DEFAULT, str);
+ wSetData(&opt.nText, str);
+ }
+ if (strchr(in, 'E') != NULL)
+ {
+ FixStr(E_DEFAULT, str);
+ wSetData(&opt.eText, str);
+ }
+ if (strchr(in, 'H') != NULL)
+ {
+ FixStr(H_DEFAULT, str);
+ wSetData(&opt.hText, str);
+ }
+ if (strchr(in, 'X') != NULL)
+ {
+ FixStr(X_DEFAULT, str);
+ wSetData(&opt.xText, str);
+ }
+ if (strchr(in, 'P') != NULL)
+ {
+ FixStr(P_DEFAULT, str);
+ wSetData(&opt.pTitle, str);
+ }
+ if (strchr(in, 'p') != NULL)
+ {
+ FixStr(p_DEFAULT, str);
+ wSetData(&opt.pText, str);
+ }
+ if (strchr(in, 'S') != NULL)
+ wSetData(&opt.sText, "");
+}
+
+void DestroyOptions(void)
+{
+ wfree(&opt.cText);
+ wfree(&opt.bTitle);
+ wfree(&opt.bText);
+ wfree(&opt.nText);
+ wfree(&opt.eText);
+ wfree(&opt.hText);
+ wfree(&opt.xText);
+ wfree(&opt.pTitle);
+ wfree(&opt.pText);
+ wfree(&opt.sText);
+}
+
+// load options from database + set default if the setting does not exist
+void LoadOptions(void)
+{
+ DBVARIANT dbv;
+ ZeroMemory(&opt, sizeof(opt));
+
+ // main options
+ opt.StartupUpdate = DBGetContactSettingByte(NULL,WEATHERPROTONAME,"StartupUpdate",TRUE);
+ opt.AutoUpdate = DBGetContactSettingByte(NULL,WEATHERPROTONAME,"AutoUpdate",TRUE);
+ opt.UpdateTime = (WORD)DBGetContactSettingWord(NULL,WEATHERPROTONAME,"UpdateTime",20);
+ opt.NewBrowserWin = DBGetContactSettingByte(NULL,WEATHERPROTONAME,"NewWindow",TRUE);
+ opt.NoProtoCondition = DBGetContactSettingByte(NULL,WEATHERPROTONAME,"NoStatus",TRUE);
+ opt.UpdateOnlyConditionChanged = DBGetContactSettingByte(NULL,WEATHERPROTONAME,"CondChangeAsUpdate",TRUE);
+ opt.RemoveOldData = DBGetContactSettingByte(NULL,WEATHERPROTONAME,"RemoveOld",FALSE);
+ opt.MakeItalic = DBGetContactSettingByte(NULL,WEATHERPROTONAME,"MakeItalic",TRUE);
+ opt.AvatarSize = DBGetContactSettingByte(NULL,WEATHERPROTONAME,"AvatarSize", 32);
+ // units
+ opt.tUnit = (WORD)DBGetContactSettingWord(NULL, WEATHERPROTONAME, "tUnit", 1);
+ opt.wUnit = (WORD)DBGetContactSettingWord(NULL, WEATHERPROTONAME, "wUnit", 1);
+ opt.vUnit = (WORD)DBGetContactSettingWord(NULL, WEATHERPROTONAME, "vUnit", 1);
+ opt.pUnit = (WORD)DBGetContactSettingWord(NULL, WEATHERPROTONAME, "pUnit", 1);
+ opt.dUnit = (WORD)DBGetContactSettingWord(NULL, WEATHERPROTONAME, "dUnit", 1);
+ if (DBGetContactSettingString(NULL,WEATHERPROTONAME,"DegreeSign",&dbv))
+ FixStr(Translate(""), opt.DegreeSign);
+ else
+ {
+ strcpy(opt.DegreeSign, dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+ opt.DoNotAppendUnit = DBGetContactSettingByte(NULL, WEATHERPROTONAME, "DoNotAppendUnit", 0);
+ opt.NoFrac = DBGetContactSettingByte(NULL, WEATHERPROTONAME, "NoFractions", 0);
+ // texts
+ if (DBGetContactSettingString(NULL,WEATHERPROTONAME,"DisplayText",&dbv))
+ SetTextDefault("C");
+ else
+ {
+ wSetData(&opt.cText, dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+ if (DBGetContactSettingString(NULL,WEATHERPROTONAME,"BriefTextTitle",&dbv))
+ SetTextDefault("b");
+ else
+ {
+ wSetData(&opt.bTitle, dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+ if (DBGetContactSettingString(NULL,WEATHERPROTONAME,"BriefText",&dbv))
+ SetTextDefault("B");
+ else
+ {
+ wSetData(&opt.bText, dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+ if (DBGetContactSettingString(NULL,WEATHERPROTONAME,"NoteText",&dbv))
+ SetTextDefault("N");
+ else
+ {
+ wSetData(&opt.nText, dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+ if (DBGetContactSettingString(NULL,WEATHERPROTONAME,"ExtText",&dbv))
+ SetTextDefault("E");
+ else
+ {
+ wSetData(&opt.eText, dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+ if (DBGetContactSettingString(NULL,WEATHERPROTONAME,"HistoryText",&dbv))
+ SetTextDefault("H");
+ else
+ {
+ wSetData(&opt.hText, dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+ if (DBGetContactSettingString(NULL,WEATHERPROTONAME,"ExtraText",&dbv))
+ SetTextDefault("X");
+ else
+ {
+ wSetData(&opt.xText, dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+ if (DBGetContactSettingString(NULL,WEATHERPROTONAME,"StatusText",&dbv))
+ SetTextDefault("S");
+ else
+ {
+ wSetData(&opt.sText, dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+
+ // advanced
+ opt.DisCondIcon = DBGetContactSettingByte(NULL,WEATHERPROTONAME,"DisableConditionIcon",FALSE);
+ // popup options
+ opt.UsePopup = DBGetContactSettingByte(NULL,WEATHERPROTONAME,"UsePopUp",TRUE);
+ opt.UpdatePopup = DBGetContactSettingByte(NULL,WEATHERPROTONAME,"UpdatePopup",TRUE);
+ opt.AlertPopup = DBGetContactSettingByte(NULL,WEATHERPROTONAME,"AlertPopup",TRUE);
+ opt.PopupOnChange = DBGetContactSettingByte(NULL,WEATHERPROTONAME,"PopUpOnChange",TRUE);
+ opt.ShowWarnings = DBGetContactSettingByte(NULL,WEATHERPROTONAME,"ShowWarnings",TRUE);
+ // popup colors
+ opt.BGColour = DBGetContactSettingDword(NULL,WEATHERPROTONAME,"BackgroundColour",GetSysColor(COLOR_BTNFACE));
+ opt.TextColour = DBGetContactSettingDword(NULL,WEATHERPROTONAME,"TextColour",GetSysColor(COLOR_WINDOWTEXT));
+ opt.UseWinColors = (BOOL)DBGetContactSettingByte(NULL,WEATHERPROTONAME, "UseWinColors", FALSE);
+ // popup actions
+ opt.LeftClickAction = DBGetContactSettingDword(NULL,WEATHERPROTONAME,"LeftClickAction",IDM_M1);
+ opt.RightClickAction = DBGetContactSettingDword(NULL,WEATHERPROTONAME,"RightClickAction",IDM_M1);
+ // popup delay
+ opt.pDelay = DBGetContactSettingDword(NULL,WEATHERPROTONAME,"PopupDelay",0);
+ // popup texts
+ if (DBGetContactSettingString(NULL,WEATHERPROTONAME,"PopupTitle",&dbv))
+ SetTextDefault("P");
+ else
+ {
+ wSetData(&opt.pTitle, dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+ if (DBGetContactSettingString(NULL,WEATHERPROTONAME,"PopupText",&dbv))
+ SetTextDefault("p");
+ else
+ {
+ wSetData(&opt.pText, dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+ // misc
+ if (DBGetContactSettingString(NULL,WEATHERPROTONAME,"Default",&dbv))
+ opt.Default[0] = 0;
+ else
+ {
+ strcpy(opt.Default, dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+}
+
+// save the options to database
+void SaveOptions(void)
+{
+ // main options
+ DBWriteContactSettingByte(NULL, WEATHERPROTONAME, "StartupUpdate", (BYTE)opt.StartupUpdate);
+ DBWriteContactSettingByte(NULL, WEATHERPROTONAME, "AutoUpdate", (BYTE)opt.AutoUpdate);
+ DBWriteContactSettingWord(NULL, WEATHERPROTONAME, "UpdateTime", opt.UpdateTime);
+ DBWriteContactSettingByte(NULL, WEATHERPROTONAME, "NewWindow", (BYTE)opt.NewBrowserWin);
+ DBWriteContactSettingByte(NULL, WEATHERPROTONAME, "NoStatus", (BYTE)opt.NoProtoCondition);
+ DBWriteContactSettingByte(NULL, WEATHERPROTONAME, "CondChangeAsUpdate", (BYTE)opt.UpdateOnlyConditionChanged);
+ DBWriteContactSettingByte(NULL, WEATHERPROTONAME, "RemoveOld", (BYTE)opt.RemoveOldData);
+ DBWriteContactSettingByte(NULL, WEATHERPROTONAME, "MakeItalic", (BYTE)opt.MakeItalic);
+ DBWriteContactSettingByte(NULL, WEATHERPROTONAME, "AvatarSize", (BYTE)opt.AvatarSize);
+ // units
+ DBWriteContactSettingWord(NULL, WEATHERPROTONAME, "tUnit", opt.tUnit);
+ DBWriteContactSettingWord(NULL, WEATHERPROTONAME, "wUnit", opt.wUnit);
+ DBWriteContactSettingWord(NULL, WEATHERPROTONAME, "vUnit", opt.vUnit);
+ DBWriteContactSettingWord(NULL, WEATHERPROTONAME, "pUnit", opt.pUnit);
+ DBWriteContactSettingWord(NULL, WEATHERPROTONAME, "dUnit", opt.dUnit);
+ DBWriteContactSettingString(NULL, WEATHERPROTONAME, "DegreeSign", opt.DegreeSign);
+ DBWriteContactSettingByte(NULL, WEATHERPROTONAME, "DoNotAppendUnit", (BYTE)opt.DoNotAppendUnit);
+ DBWriteContactSettingByte(NULL, WEATHERPROTONAME, "NoFractions", (BYTE)opt.NoFrac);
+ // texts
+ DBWriteContactSettingString(NULL, WEATHERPROTONAME, "DisplayText", opt.cText);
+ DBWriteContactSettingString(NULL, WEATHERPROTONAME, "BriefTextTitle", opt.bTitle);
+ DBWriteContactSettingString(NULL, WEATHERPROTONAME, "BriefText", opt.bText);
+ DBWriteContactSettingString(NULL, WEATHERPROTONAME, "NoteText", opt.nText);
+ DBWriteContactSettingString(NULL, WEATHERPROTONAME, "ExtText", opt.eText);
+ DBWriteContactSettingString(NULL, WEATHERPROTONAME, "HistoryText", opt.hText);
+ DBWriteContactSettingString(NULL, WEATHERPROTONAME, "ExtraText", opt.xText);
+ DBWriteContactSettingString(NULL, WEATHERPROTONAME, "StatusText", opt.sText);
+ // advanced
+ DBWriteContactSettingByte(NULL, WEATHERPROTONAME, "DisableConditionIcon", (BYTE)opt.DisCondIcon);
+ // popup options
+ DBWriteContactSettingByte(NULL, WEATHERPROTONAME, "UsePopUp", (BYTE)opt.UsePopup);
+ DBWriteContactSettingByte(NULL, WEATHERPROTONAME, "UpdatePopup", (BYTE)opt.UpdatePopup);
+ DBWriteContactSettingByte(NULL, WEATHERPROTONAME, "AlertPopup", (BYTE)opt.AlertPopup);
+ DBWriteContactSettingByte(NULL, WEATHERPROTONAME, "PopUpOnChange", (BYTE)opt.PopupOnChange);
+ DBWriteContactSettingByte(NULL, WEATHERPROTONAME, "ShowWarnings", (BYTE)opt.ShowWarnings);
+ // popup colors
+ DBWriteContactSettingDword(NULL, WEATHERPROTONAME, "BackgroundColour", opt.BGColour);
+ DBWriteContactSettingDword(NULL, WEATHERPROTONAME, "TextColour", opt.TextColour);
+ DBWriteContactSettingByte(NULL,WEATHERPROTONAME, "UseWinColors", (BYTE)opt.UseWinColors);
+ // popup actions
+ DBWriteContactSettingDword(NULL, WEATHERPROTONAME, "LeftClickAction", opt.LeftClickAction);
+ DBWriteContactSettingDword(NULL, WEATHERPROTONAME, "RightClickAction", opt.RightClickAction);
+ // popup delay
+ DBWriteContactSettingDword(NULL, WEATHERPROTONAME, "PopupDelay", opt.pDelay);
+ // popup texts
+ DBWriteContactSettingString(NULL, WEATHERPROTONAME, "PopupTitle", opt.pTitle);
+ DBWriteContactSettingString(NULL, WEATHERPROTONAME, "PopupText", opt.pText);
+ // misc stuff
+ DBWriteContactSettingString(NULL, WEATHERPROTONAME, "Default", opt.Default);
+}
+
+//============ OPTION INITIALIZATION ============
+
+// register the weather option pages
+int OptInit(WPARAM wParam,LPARAM lParam) {
+ OPTIONSDIALOGPAGE odp = {0};
+
+ odp.cbSize = sizeof(odp);
+ odp.hInstance = hInst;
+
+ // plugin options
+ odp.position = 95600;
+ odp.pszTemplate = MAKEINTRESOURCE(IDD_OPTIONS);
+ odp.pfnDlgProc = OptionsProc;
+ odp.pszGroup = LPGEN("Plugins");
+ odp.pszTitle = WEATHERPROTOTEXT;
+ odp.pszTab = LPGEN("General");
+ odp.flags = ODPF_BOLDGROUPS;
+ CallService(MS_OPT_ADDPAGE,wParam,(LPARAM)&odp);
+
+ // text options
+ odp.pszTemplate = MAKEINTRESOURCE(IDD_TEXTOPT);
+ odp.pfnDlgProc = DlgProcText;
+ odp.pszTab = LPGEN("Display");
+ CallService(MS_OPT_ADDPAGE,wParam,(LPARAM)&odp);
+
+ // if popup service exists, load the weather popup options
+ if ((ServiceExists(MS_POPUP_ADDPOPUP)))
+ {
+ odp.position = 100000000;
+ odp.pszTemplate = MAKEINTRESOURCE(IDD_POPUP);
+ odp.pszGroup = LPGEN("PopUps");
+ odp.groupPosition = 910000000;
+ odp.pszTab = NULL;
+ odp.pfnDlgProc = DlgPopUpOpts;
+ CallService(MS_OPT_ADDPAGE,wParam,(LPARAM)&odp);
+ }
+
+ return 0;
+}
+
+//============ MAIN OPTIONS ============
+
+// weather options
+INT_PTR CALLBACK OptionsProc(HWND hdlg, UINT msg, WPARAM wparam, LPARAM lparam)
+{
+ char str[512];
+
+ switch(msg)
+ {
+ case WM_INITDIALOG:
+ opt_startup = TRUE;
+ TranslateDialogDefault(hdlg);
+ // load settings
+ _ltoa(opt.UpdateTime, str, 10);
+ SetDlgItemTextWth(hdlg, IDC_UPDATETIME, str);
+ SetDlgItemTextWth(hdlg, IDC_DEGREE, opt.DegreeSign);
+
+ SendDlgItemMessage(hdlg, IDC_AVATARSPIN, UDM_SETRANGE32, 0, 999);
+ SendDlgItemMessage(hdlg, IDC_AVATARSPIN, UDM_SETPOS, 0, opt.AvatarSize);
+ SendDlgItemMessage(hdlg, IDC_AVATARSIZE, EM_LIMITTEXT, 3, 0);
+
+ CheckDlgButton(hdlg, IDC_STARTUPUPD, opt.StartupUpdate);
+ CheckDlgButton(hdlg, IDC_UPDATE, opt.AutoUpdate);
+ CheckDlgButton(hdlg, IDC_PROTOCOND, !opt.NoProtoCondition);
+ CheckDlgButton(hdlg, IDC_UPDCONDCHG, opt.UpdateOnlyConditionChanged);
+ CheckDlgButton(hdlg, IDC_NEWWIN, opt.NewBrowserWin);
+ CheckDlgButton(hdlg, IDC_REMOVEOLD, opt.RemoveOldData);
+ CheckDlgButton(hdlg, IDC_MAKEI, opt.MakeItalic);
+ CheckDlgButton(hdlg, IDC_DISCONDICON, opt.DisCondIcon);
+ CheckDlgButton(hdlg, IDC_DONOTAPPUNITS, opt.DoNotAppendUnit);
+ CheckDlgButton(hdlg, IDC_NOFRAC, opt.NoFrac);
+
+ // load units
+ switch (opt.tUnit) { // temperature
+ case 1: CheckRadioButton(hdlg, IDC_T1, IDC_T2, IDC_T1); break;
+ case 2: CheckRadioButton(hdlg, IDC_T1, IDC_T2, IDC_T2); break;
+ }
+ switch (opt.wUnit) { // wind
+ case 1: CheckRadioButton(hdlg, IDC_W1, IDC_W4, IDC_W1); break;
+ case 2: CheckRadioButton(hdlg, IDC_W1, IDC_W4, IDC_W2); break;
+ case 3: CheckRadioButton(hdlg, IDC_W1, IDC_W4, IDC_W3); break;
+ case 4: CheckRadioButton(hdlg, IDC_W1, IDC_W4, IDC_W4); break;
+ }
+ switch (opt.vUnit) { // visibility
+ case 1: CheckRadioButton(hdlg, IDC_V1, IDC_V2, IDC_V1); break;
+ case 2: CheckRadioButton(hdlg, IDC_V1, IDC_V2, IDC_V2); break;
+ }
+ switch (opt.pUnit) { // pressure
+ case 1: CheckRadioButton(hdlg, IDC_P1, IDC_P4, IDC_P1); break;
+ case 2: CheckRadioButton(hdlg, IDC_P1, IDC_P4, IDC_P2); break;
+ case 3: CheckRadioButton(hdlg, IDC_P1, IDC_P4, IDC_P3); break;
+ case 4: CheckRadioButton(hdlg, IDC_P1, IDC_P4, IDC_P4); break;
+ }
+ switch (opt.dUnit) { // pressure
+ case 1: CheckRadioButton(hdlg, IDC_D1, IDC_D3, IDC_D1); break;
+ case 2: CheckRadioButton(hdlg, IDC_D1, IDC_D3, IDC_D2); break;
+ case 3: CheckRadioButton(hdlg, IDC_D1, IDC_D3, IDC_D3); break;
+ }
+
+ opt_startup = FALSE;
+ return 0;
+
+ case WM_COMMAND:
+ if (HIWORD(wparam)==BN_CLICKED && GetFocus()==(HWND)lparam)
+ if (!opt_startup) SendMessage(GetParent(hdlg),PSM_CHANGED,0,0);
+ if (!((LOWORD(wparam) == IDC_UPDATE || LOWORD(wparam) == IDC_DEGREE) &&
+ (HIWORD(wparam) != EN_CHANGE || (HWND)lparam != GetFocus())))
+ if (!opt_startup) SendMessage(GetParent(hdlg),PSM_CHANGED,0,0);
+ return 0;
+
+ case WM_NOTIFY:
+ switch(((LPNMHDR)lparam)->code)
+ {
+ case PSN_APPLY:
+ // change the status for weather protocol
+ if (IsDlgButtonChecked(hdlg, IDC_PROTOCOND) && opt.DefStn != NULL)
+ {
+ old_status = status;
+ status = DBGetContactSettingWord(opt.DefStn, WEATHERPROTONAME, "StatusIcon", NOSTATUSDATA);
+ ProtoBroadcastAck(WEATHERPROTONAME, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, status);
+ }
+
+ // get update time and remove the old timer
+ GetDlgItemText(hdlg, IDC_UPDATETIME, str, sizeof(str));
+ opt.UpdateTime = (WORD)atoi(str);
+ if (opt.UpdateTime < 1) opt.UpdateTime = 1;
+ KillTimer(NULL, timerId);
+ timerId = SetTimer(NULL, 0, opt.UpdateTime*60000, (TIMERPROC)timerProc);
+
+ // other general options
+ GetDlgItemText(hdlg, IDC_DEGREE, opt.DegreeSign, sizeof(opt.DegreeSign));
+ opt.StartupUpdate = IsDlgButtonChecked(hdlg, IDC_STARTUPUPD);
+ opt.AutoUpdate = IsDlgButtonChecked(hdlg, IDC_UPDATE);
+ opt.NewBrowserWin = IsDlgButtonChecked(hdlg, IDC_NEWWIN);
+ opt.NoProtoCondition = !IsDlgButtonChecked(hdlg, IDC_PROTOCOND);
+ opt.DisCondIcon = IsDlgButtonChecked(hdlg, IDC_DISCONDICON);
+ opt.UpdateOnlyConditionChanged = (BYTE)IsDlgButtonChecked(hdlg, IDC_UPDCONDCHG);
+ opt.RemoveOldData = IsDlgButtonChecked(hdlg, IDC_REMOVEOLD);
+ opt.MakeItalic = IsDlgButtonChecked(hdlg, IDC_MAKEI);
+ opt.AvatarSize = GetDlgItemInt(hdlg, IDC_AVATARSIZE, NULL, FALSE);;
+ opt.DoNotAppendUnit = IsDlgButtonChecked(hdlg, IDC_DONOTAPPUNITS);
+ opt.NoFrac = IsDlgButtonChecked(hdlg, IDC_NOFRAC);
+ UpdateMenu(opt.AutoUpdate);
+
+ // save the units
+ if (IsDlgButtonChecked(hdlg, IDC_T1)) opt.tUnit = 1;
+ if (IsDlgButtonChecked(hdlg, IDC_T2)) opt.tUnit = 2;
+ if (IsDlgButtonChecked(hdlg, IDC_W1)) opt.wUnit = 1;
+ if (IsDlgButtonChecked(hdlg, IDC_W2)) opt.wUnit = 2;
+ if (IsDlgButtonChecked(hdlg, IDC_W3)) opt.wUnit = 3;
+ if (IsDlgButtonChecked(hdlg, IDC_W4)) opt.wUnit = 4;
+ if (IsDlgButtonChecked(hdlg, IDC_V1)) opt.vUnit = 1;
+ if (IsDlgButtonChecked(hdlg, IDC_V2)) opt.vUnit = 2;
+ if (IsDlgButtonChecked(hdlg, IDC_P1)) opt.pUnit = 1;
+ if (IsDlgButtonChecked(hdlg, IDC_P2)) opt.pUnit = 2;
+ if (IsDlgButtonChecked(hdlg, IDC_P3)) opt.pUnit = 3;
+ if (IsDlgButtonChecked(hdlg, IDC_P4)) opt.pUnit = 4;
+ if (IsDlgButtonChecked(hdlg, IDC_D1)) opt.dUnit = 1;
+ if (IsDlgButtonChecked(hdlg, IDC_D2)) opt.dUnit = 2;
+ if (IsDlgButtonChecked(hdlg, IDC_D3)) opt.dUnit = 3;
+
+ // save the new weather options
+ SaveOptions();
+
+ RedrawFrame(0, 0);
+
+ return 1;
+ }
+ break;
+ }
+ return 0;
+}
+
+//============ TEXT OPTION DIALOG ============
+
+void LoadTextSettings(HWND hdlg)
+{
+ // load text option settings from memory
+ SetDlgItemTextWth(hdlg, IDC_CTEXT, opt.cText);
+ SetDlgItemTextWth(hdlg, IDC_BTITLE, opt.bTitle);
+ SetDlgItemTextWth(hdlg, IDC_BTEXT, opt.bText);
+ SetDlgItemTextWth(hdlg, IDC_ETEXT, opt.eText);
+ SetDlgItemTextWth(hdlg, IDC_NTEXT, opt.nText);
+ SetDlgItemTextWth(hdlg, IDC_HTEXT, opt.hText);
+ SetDlgItemTextWth(hdlg, IDC_XTEXT, opt.xText);
+ SetDlgItemTextWth(hdlg, IDC_BTITLE2, opt.sText);
+}
+
+// free the display text settings from memory
+void FreeTextVar(void)
+{
+ wfree(&opt.cText);
+ wfree(&opt.bText);
+ wfree(&opt.bTitle);
+ wfree(&opt.eText);
+ wfree(&opt.nText);
+ wfree(&opt.hText);
+ wfree(&opt.xText);
+ wfree(&opt.sText);
+}
+
+// text option dialog
+INT_PTR CALLBACK DlgProcText(HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ RECT rc, pos;
+ HWND button;
+ HMENU hMenu, hMenu1;
+ char str[4096];
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ opt_startup = TRUE;
+ // set windows position, make it top-most
+ GetWindowRect(hdlg, &rc);
+ SetWindowPos(hdlg, HWND_TOPMOST, rc.left, rc.top, 0, 0, SWP_NOSIZE);
+ TranslateDialogDefault(hdlg);
+ // generate the display text for variable list
+ strcpy(str, Translate("%c\tcurrent condition\n%d\tcurrent date\n%e\tdewpoint\n%f\tfeel-like temp\n%h\ttoday's high\n%i\twind direction\n%l\ttoday's low\n%m\thumidity\n%n\tstation name\n%p\tpressure\n%r\tsunrise time\n%s\tstation ID\n%t\ttemperature\n%u\tupdate time\n%v\tvisibility\n%w\twind speed\n%y\tsun set"));
+ SetDlgItemTextWth(hdlg, IDC_VARLIST, str);
+
+ // make the more variable and other buttons flat
+ SendMessage(GetDlgItem(hdlg,IDC_MORE), BUTTONSETASFLATBTN, 0, 0);
+ SendMessage(GetDlgItem(hdlg,IDC_TM1), BUTTONSETASFLATBTN, 0, 0);
+ SendMessage(GetDlgItem(hdlg,IDC_TM2), BUTTONSETASFLATBTN, 0, 0);
+ SendMessage(GetDlgItem(hdlg,IDC_TM3), BUTTONSETASFLATBTN, 0, 0);
+ SendMessage(GetDlgItem(hdlg,IDC_TM4), BUTTONSETASFLATBTN, 0, 0);
+ SendMessage(GetDlgItem(hdlg,IDC_TM5), BUTTONSETASFLATBTN, 0, 0);
+ SendMessage(GetDlgItem(hdlg,IDC_TM6), BUTTONSETASFLATBTN, 0, 0);
+ SendMessage(GetDlgItem(hdlg,IDC_TM7), BUTTONSETASFLATBTN, 0, 0);
+ SendMessage(GetDlgItem(hdlg,IDC_TM8), BUTTONSETASFLATBTN, 0, 0);
+ SendMessage(GetDlgItem(hdlg,IDC_RESET), BUTTONSETASFLATBTN, 0, 0);
+ // load the settings
+ LoadTextSettings(hdlg);
+ opt_startup = FALSE;
+ return TRUE;
+
+ case WM_COMMAND:
+ if (opt_startup) return TRUE;
+ switch(LOWORD(wParam)) {
+ case IDC_CTEXT:
+ case IDC_BTITLE:
+ case IDC_BTEXT:
+ case IDC_NTEXT:
+ case IDC_XTEXT:
+ case IDC_ETEXT:
+ case IDC_HTEXT:
+ case IDC_BTITLE2:
+ if (HIWORD(wParam) == EN_CHANGE)
+ SendMessage(GetParent(hdlg),PSM_CHANGED,0,0);
+ break;
+
+ case IDC_MORE:
+ // display custom variables list
+ MoreVarList();
+ break;
+
+ case IDC_TM1:
+ case IDC_TM2:
+ case IDC_TM3:
+ case IDC_TM4:
+ case IDC_TM5:
+ case IDC_TM6:
+ case IDC_TM7:
+ case IDC_TM8:
+ {
+ static const char *varname[8] = {"C", "b", "B", "N", "X", "E", "H", "S"};
+ static const int cname[8] = {IDC_CTEXT, IDC_BTITLE, IDC_BTEXT, IDC_NTEXT, IDC_XTEXT,
+ IDC_ETEXT, IDC_HTEXT, IDC_BTITLE2 };
+ static char* const *var[8] = {&opt.cText, &opt.bTitle, &opt.bText, &opt.nText,
+ &opt.xText, &opt.eText, &opt.hText, &opt.sText };
+ WEATHERINFO winfo;
+
+ // display the menu
+ button = GetDlgItem(hdlg, LOWORD(wParam));
+ GetWindowRect(button, &pos);
+ hMenu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_TMMENU));
+ hMenu1 = GetSubMenu(hMenu, 0);
+ CallService(MS_LANGPACK_TRANSLATEMENU, (WPARAM)hMenu1, 0);
+ switch(TrackPopupMenu(hMenu1, TPM_LEFTBUTTON|TPM_RETURNCMD, pos.left, pos.bottom, 0, hdlg, NULL))
+ {
+ case ID_MPREVIEW:
+ // show the preview in a message box, using the weather data from the default station
+ winfo = LoadWeatherInfo(opt.DefStn);
+ GetDisplay(&winfo, *var[LOWORD(wParam)-IDC_TM1], str);
+ MessageBox(NULL, str, Translate("Weather Protocol Text Preview"), MB_OK|MB_TOPMOST);
+ break;
+
+ case ID_MRESET:
+ {
+ unsigned varo = LOWORD(wParam) - IDC_TM1;
+ // remove the old setting from db and free memory
+ char* vartmp = *var[varo];
+ wfree(&vartmp);
+ SetTextDefault(varname[varo]);
+ SetDlgItemTextWth(hdlg, cname[varo], *var[varo]);
+ }
+ break;
+ }
+ DestroyMenu(hMenu);
+ break;
+ }
+
+ case IDC_RESET:
+ // left click action selection menu
+ button = GetDlgItem(hdlg, IDC_RESET);
+ GetWindowRect(button, &pos);
+ hMenu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_TMENU));
+ hMenu1 = GetSubMenu(hMenu, 0);
+ CallService(MS_LANGPACK_TRANSLATEMENU, (WPARAM)hMenu1, 0);
+ switch(TrackPopupMenu(hMenu1, TPM_LEFTBUTTON|TPM_RETURNCMD, pos.left, pos.bottom, 0, hdlg, NULL))
+ {
+ case ID_T1:
+ // reset to the strings in memory, discard all changes
+ LoadTextSettings(hdlg);
+ break;
+
+ case ID_T2:
+ // reset to the default setting
+ FreeTextVar();
+ SetTextDefault("CbBENHX");
+ LoadTextSettings(hdlg);
+ break;
+ }
+ DestroyMenu(hMenu);
+ break;
+ }
+ return TRUE;
+ case WM_NOTIFY:
+ switch(((LPNMHDR)lParam)->code)
+ {
+ case PSN_APPLY:
+ {
+ // save the option
+ char textstr[MAX_TEXT_SIZE];
+ // free memory for old settings
+ FreeTextVar();
+ // save new settings to memory
+ GetDlgItemTextWth(hdlg, IDC_CTEXT, textstr, MAX_TEXT_SIZE);
+ wSetData(&opt.cText, textstr);
+ GetDlgItemTextWth(hdlg, IDC_BTEXT, textstr, MAX_TEXT_SIZE);
+ wSetData(&opt.bText, textstr);
+ GetDlgItemTextWth(hdlg, IDC_BTITLE, textstr, MAX_TEXT_SIZE);
+ wSetData(&opt.bTitle, textstr);
+ GetDlgItemTextWth(hdlg, IDC_ETEXT, textstr, MAX_TEXT_SIZE);
+ wSetData(&opt.eText, textstr);
+ GetDlgItemTextWth(hdlg, IDC_NTEXT, textstr, MAX_TEXT_SIZE);
+ wSetData(&opt.nText, textstr);
+ GetDlgItemTextWth(hdlg, IDC_HTEXT, textstr, MAX_TEXT_SIZE);
+ wSetData(&opt.hText, textstr);
+ GetDlgItemTextWth(hdlg, IDC_XTEXT, textstr, MAX_TEXT_SIZE);
+ wSetData(&opt.xText, textstr);
+ GetDlgItemTextWth(hdlg, IDC_BTITLE2, textstr, MAX_TEXT_SIZE);
+ wSetData(&opt.sText, textstr);
+ SaveOptions();
+ UpdateAllInfo(0, 0);
+ break;
+ }
+ }
+ break;
+ }
+ return FALSE;
+}
+
diff --git a/plugins/weather/weather_popup.c b/plugins/weather/weather_popup.c
new file mode 100644
index 0000000000..270f989c73
--- /dev/null
+++ b/plugins/weather/weather_popup.c
@@ -0,0 +1,454 @@
+/*
+Weather Protocol plugin for Miranda IM
+Copyright (C) 2005-2009 Boris Krasnovskiy All Rights Reserved
+Copyright (C) 2002-2005 Calvin Che
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; version 2
+of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* This file contain the source related to weather popups, including popup
+ options, popup display, and the code for popup process.
+*/
+
+#include "weather.h"
+
+// variables for weather_popup.c
+static HANDLE hPopupContact;
+
+//============ SHOW WEATHER POPUPS ============
+
+// display weather popups
+// wParam = the contact to display popup
+// lParam = whether the weather data is changed or not
+int WeatherPopup(WPARAM wParam, LPARAM lParam)
+{
+ // determine if the popup should display or not
+ if (opt.UsePopup && opt.UpdatePopup && (!opt.PopupOnChange || (BOOL)lParam) &&
+ !DBGetContactSettingByte((HANDLE)wParam, WEATHERPROTONAME, "DPopUp", 0))
+ {
+ POPUPDATAEX ppd = {0};
+ WEATHERINFO winfo;
+
+ // setup the popup
+ ppd.lchContact = (HANDLE)wParam;
+// if ((HANDLE)wParam != NULL) { // for actual contact
+ winfo = LoadWeatherInfo((HANDLE)wParam);
+ ppd.PluginData = ppd.lchIcon = LoadSkinnedProtoIcon(WEATHERPROTONAME, winfo.status);
+ GetDisplay(&winfo, opt.pTitle, ppd.lpzContactName);
+ GetDisplay(&winfo, opt.pText, ppd.lpzText);
+ ppd.PluginWindowProc = (WNDPROC)PopupDlgProc;
+// }
+// else { // for preview
+// ppd.lchIcon = LoadSkinnedProtoIcon(WEATHERPROTONAME, ONLINE);
+// strcpy(ppd.lpzContactName, Translate("This is the name of the city"));
+// strcpy(ppd.lpzText, Translate("Here is a short weather description"));
+// ppd.PluginWindowProc = NULL;
+// }
+ ppd.colorBack = (opt.UseWinColors)?GetSysColor(COLOR_BTNFACE):opt.BGColour;
+ ppd.colorText = (opt.UseWinColors)?GetSysColor(COLOR_WINDOWTEXT):opt.TextColour;
+ ppd.iSeconds = opt.pDelay;
+ // display popups
+ if (!ServiceExists(MS_POPUP_ADDPOPUPEX)) // old version
+ CallService(MS_POPUP_ADDPOPUP, (WPARAM)&ppd, 0);
+ else { // new version with delay
+ ppd.iSeconds = opt.pDelay;
+ CallService(MS_POPUP_ADDPOPUPEX, (WPARAM)&ppd, 0);
+ }
+ }
+ return 0;
+}
+
+//============ WEATHER ERROR POPUPS ============
+
+// display weather error or notices (not threaded)
+// wParam = error text
+// lParam = display type
+// Type can either be SM_WARNING, SM_NOTIFY, or SM_WEATHERALERT
+int WeatherError(WPARAM wParam, LPARAM lParam)
+{
+ if (!opt.UsePopup) return 0;
+
+ if ((DWORD)lParam == SM_WARNING)
+ PUShowMessage((char*)wParam, SM_WARNING);
+ else if ((DWORD)lParam == SM_NOTIFY)
+ PUShowMessage((char*)wParam, SM_NOTIFY);
+ else if ((DWORD)lParam == SM_WEATHERALERT)
+ {
+ POPUPDATAEX ppd = {0};
+ char *chop;
+ char str1[512], str2[512];
+
+ // get the 2 strings
+ strcpy(str1, (char*)wParam);
+ strcpy(str2, (char*)wParam);
+ chop = strchr(str1, 255);
+ if (chop != NULL) *chop = '\0';
+ else str1[0] = 0;
+ chop = strchr(str2, 255);
+ if (chop != NULL) strcpy(str2, chop+1);
+ else str2[0] = 0;
+
+ // setup the popup
+ ppd.lchIcon = (HICON)LoadImage(NULL, MAKEINTRESOURCE(OIC_BANG), IMAGE_ICON,
+ GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_SHARED);
+ strcpy(ppd.lpzContactName, str1);
+ strcpy(ppd.lpzText, str2);
+ ppd.colorBack = (opt.UseWinColors)?GetSysColor(COLOR_BTNFACE):opt.BGColour;
+ ppd.colorText = (opt.UseWinColors)?GetSysColor(COLOR_WINDOWTEXT):opt.TextColour;
+ ppd.iSeconds = opt.pDelay;
+
+ // display popups
+ if (!ServiceExists(MS_POPUP_ADDPOPUPEX)) // old version
+ CallService(MS_POPUP_ADDPOPUP, (WPARAM)&ppd, 0);
+ else { // new version with delay
+ ppd.iSeconds = opt.pDelay;
+ CallService(MS_POPUP_ADDPOPUPEX, (WPARAM)&ppd, 0);
+ }
+ }
+ return 0;
+}
+
+// wrapper function for displaying weather warning popup by triggering an event
+// (threaded)
+// lpzText = error text
+// kind = display type (see m_popup.h)
+int WPShowMessage(char* lpzText, WORD kind) {
+ NotifyEventHooks(hHookWeatherError, (WPARAM)lpzText, (LPARAM)kind);
+ return 0;
+}
+
+//============ WEATHER POPUP PROCESSES ============
+
+// popup dialog pocess
+// for selecting actions when click on the popup window
+// use for displaying contact menu
+LRESULT CALLBACK PopupDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ DWORD ID = 0;
+ HANDLE hContact;
+ hContact = PUGetContact(hWnd);
+
+ switch(message)
+ {
+ case WM_COMMAND:
+ ID = opt.LeftClickAction;
+ if (ID != IDM_M7) PUDeletePopUp(hWnd);
+ SendMessage(hPopupWindow, ID, (WPARAM)hContact, 0);
+ return TRUE;
+
+ case WM_CONTEXTMENU:
+ ID = opt.RightClickAction;
+ if (ID != IDM_M7) PUDeletePopUp(hWnd);
+ SendMessage(hPopupWindow, ID, (WPARAM)hContact, 0);
+ return TRUE;
+
+ case UM_FREEPLUGINDATA:
+ CallService(MS_SKIN2_RELEASEICON, (WPARAM)PUGetPluginData(hWnd), 0);
+ return FALSE;
+ }
+
+ return DefWindowProc(hWnd, message, wParam, lParam);
+}
+
+// process for the popup window
+// containing the code for popup actions
+LRESULT CALLBACK PopupWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ POINT pt;
+ HMENU hMenu;
+ switch (uMsg)
+ {
+ case IDM_M2: // brief info
+ BriefInfo(wParam, 0);
+ break;
+
+ case IDM_M3: // read complete forecast
+ LoadForecast(wParam, 0);
+ break;
+
+ case IDM_M4: // display weather map
+ WeatherMap(wParam, 0);
+ break;
+
+ case IDM_M5: // open history window
+ CallService(MS_HISTORY_SHOWCONTACTHISTORY, wParam, 0);
+ break;
+
+ case IDM_M6: // open external log
+ ViewLog(wParam, 0);
+ break;
+
+ case IDM_M7: // display contact menu
+ hMenu=(HMENU)CallService(MS_CLIST_MENUBUILDCONTACT,wParam,0);
+ GetCursorPos(&pt);
+ hPopupContact = (HANDLE)wParam;
+ TrackPopupMenu(hMenu,TPM_LEFTALIGN,pt.x,pt.y,0,hWnd,NULL);
+ DestroyMenu(hMenu);
+ break;
+
+ case IDM_M8: // display contact detail
+ CallService(MS_USERINFO_SHOWDIALOG, wParam, 0);
+
+ case WM_COMMAND: //Needed by the contact's context menu
+ if (CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(wParam),MPCF_CONTACTMENU),(LPARAM)hPopupContact))
+ break;
+ return FALSE;
+
+ case WM_MEASUREITEM: //Needed by the contact's context menu
+ return CallService(MS_CLIST_MENUMEASUREITEM,wParam,lParam);
+
+ case WM_DRAWITEM: //Needed by the contact's context menu
+ return CallService(MS_CLIST_MENUDRAWITEM,wParam,lParam);
+ }
+
+ return DefWindowProc(hWnd, uMsg, wParam, lParam);//FALSE;
+}
+
+//============ POPUP OPTIONS ============
+
+// temporary read the current option to memory
+// but does not write to the database
+void ReadPopupOpt(HWND hdlg)
+{
+ char text[MAX_TEXT_SIZE];
+ int num;
+ char str[512];
+
+ // popup colour
+ opt.TextColour = SendDlgItemMessage(hdlg,IDC_TEXTCOLOUR,CPM_GETCOLOUR,0,0);
+ opt.BGColour = SendDlgItemMessage(hdlg,IDC_BGCOLOUR,CPM_GETCOLOUR,0,0);
+
+ // get delay time
+ GetDlgItemText(hdlg, IDC_DELAY, str, sizeof(str));
+ num = atoi(str);
+ opt.pDelay = num;
+
+ // other options
+ opt.UseWinColors = (BYTE)IsDlgButtonChecked(hdlg, IDC_USEWINCOLORS);
+ opt.UsePopup = (BYTE)IsDlgButtonChecked(hdlg, IDC_E);
+ opt.UpdatePopup = (BYTE)IsDlgButtonChecked(hdlg, IDC_POP1);
+ opt.AlertPopup = (BYTE)IsDlgButtonChecked(hdlg, IDC_POP2);
+ opt.PopupOnChange = (BYTE)IsDlgButtonChecked(hdlg, IDC_CH);
+ opt.ShowWarnings = (BYTE)IsDlgButtonChecked(hdlg, IDC_W);
+
+ // popup texts
+ wfree(&opt.pText);
+ wfree(&opt.pTitle);
+ GetDlgItemTextWth(hdlg, IDC_PText, text, MAX_TEXT_SIZE);
+ wSetData(&opt.pText, text);
+ GetDlgItemTextWth(hdlg, IDC_PTitle, text, MAX_TEXT_SIZE);
+ wSetData(&opt.pTitle, text);
+}
+
+// copied and modified from NewStatusNotify
+INT_PTR CALLBACK DlgPopUpOpts(HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ int ID;
+ char str[512];
+ HMENU hMenu, hMenu1;
+ RECT pos;
+ HWND button;
+ HANDLE hContact;
+
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hdlg);
+ SaveOptions();
+
+ // click actions
+ hMenu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_PMENU));
+ hMenu1 = GetSubMenu(hMenu, 0);
+ GetMenuString(hMenu1, opt.LeftClickAction, str, sizeof(str), MF_BYCOMMAND);
+ SetDlgItemTextWth(hdlg, IDC_LeftClick, Translate(str));
+ GetMenuString(hMenu1, opt.RightClickAction, str, sizeof(str), MF_BYCOMMAND);
+ SetDlgItemTextWth(hdlg, IDC_RightClick, Translate(str));
+ DestroyMenu(hMenu);
+
+ // other options
+ CheckDlgButton(hdlg, IDC_E, opt.UsePopup);
+ CheckDlgButton(hdlg, IDC_POP2, opt.AlertPopup);
+ CheckDlgButton(hdlg, IDC_POP1, opt.UpdatePopup);
+ CheckDlgButton(hdlg, IDC_CH, opt.PopupOnChange);
+ CheckDlgButton(hdlg, IDC_W, opt.ShowWarnings);
+ SetDlgItemTextWth(hdlg,IDC_PText, opt.pText);
+ SetDlgItemTextWth(hdlg,IDC_PTitle, opt.pTitle);
+ // setting popup delay option
+ _ltoa(opt.pDelay, str, 10);
+ SetDlgItemTextWth(hdlg,IDC_DELAY, str);
+ if (opt.pDelay == -1)
+ CheckRadioButton(hdlg, IDC_PD1, IDC_PD3, IDC_PD2);
+ else if (opt.pDelay == 0)
+ CheckRadioButton(hdlg, IDC_PD1, IDC_PD3, IDC_PD1);
+ else
+ CheckRadioButton(hdlg, IDC_PD1, IDC_PD3, IDC_PD3);
+ //Colours. First step is configuring the colours.
+ SendDlgItemMessage(hdlg,IDC_BGCOLOUR,CPM_SETCOLOUR,0,opt.BGColour);
+ SendDlgItemMessage(hdlg,IDC_TEXTCOLOUR,CPM_SETCOLOUR,0,opt.TextColour);
+ //Second step is disabling them if we want to use default Windows ones.
+ CheckDlgButton(hdlg, IDC_USEWINCOLORS,opt.UseWinColors?BST_CHECKED:BST_UNCHECKED);
+ EnableWindow(GetDlgItem(hdlg, IDC_BGCOLOUR), !opt.UseWinColors);
+ EnableWindow(GetDlgItem(hdlg, IDC_TEXTCOLOUR), !opt.UseWinColors);
+
+ // buttons
+ SendMessage(GetDlgItem(hdlg,IDC_PREVIEW), BUTTONSETASFLATBTN, 0, 0);
+ SendMessage(GetDlgItem(hdlg,IDC_PDEF), BUTTONSETASFLATBTN, 0, 0);
+ SendMessage(GetDlgItem(hdlg,IDC_LeftClick), BUTTONSETASFLATBTN, 0, 0);
+ SendMessage(GetDlgItem(hdlg,IDC_RightClick), BUTTONSETASFLATBTN, 0, 0);
+ SendMessage(GetDlgItem(hdlg,IDC_VAR3), BUTTONSETASFLATBTN, 0, 0);
+
+ return TRUE;
+
+ case WM_COMMAND:
+ // enable the "apply" button
+ if (HIWORD(wParam)==BN_CLICKED && GetFocus()==(HWND)lParam)
+ SendMessage(GetParent(hdlg),PSM_CHANGED,0,0);
+ if (!((LOWORD(wParam) == IDC_UPDATE || LOWORD(wParam) == IDC_DEGREE) &&
+ (HIWORD(wParam) != EN_CHANGE || (HWND)lParam != GetFocus())))
+ SendMessage(GetParent(hdlg),PSM_CHANGED,0,0);
+ //These are simple clicks: we don't save, but we tell the Options Page to enable the "Apply" button.
+ switch(LOWORD(wParam))
+ {
+ case IDC_BGCOLOUR: //Fall through
+ case IDC_TEXTCOLOUR:
+ // select new colors
+ if (HIWORD(wParam) == CPN_COLOURCHANGED)
+ SendMessage(GetParent(hdlg), PSM_CHANGED, 0, 0);
+ break;
+
+ case IDC_USEWINCOLORS:
+ // use window color - enable/disable color selection controls
+ EnableWindow(GetDlgItem(hdlg, IDC_BGCOLOUR), !(opt.UseWinColors));
+ EnableWindow(GetDlgItem(hdlg, IDC_TEXTCOLOUR), !(opt.UseWinColors));
+ SendMessage(GetParent(hdlg), PSM_CHANGED, 0, 0);
+ break;
+
+ case IDC_E:
+ case IDC_CH:
+ SendMessage(GetParent(hdlg), PSM_CHANGED, 0, 0);
+ break;
+
+ case IDC_RightClick:
+ // right click action selection menu
+ button = GetDlgItem(hdlg, IDC_RightClick);
+ GetWindowRect(button, &pos);
+
+ hMenu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_PMENU));
+ hMenu1 = GetSubMenu(hMenu, 0);
+ CallService(MS_LANGPACK_TRANSLATEMENU, (WPARAM)hMenu1, 0);
+ SelectMenuItem(hMenu1, opt.RightClickAction);
+ ID = TrackPopupMenu(hMenu1, TPM_LEFTBUTTON|TPM_RETURNCMD, pos.left, pos.bottom, 0, hdlg, NULL);
+ if (ID) opt.RightClickAction = ID;
+ DestroyMenu(hMenu);
+
+ hMenu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_PMENU));
+ hMenu1 = GetSubMenu(hMenu, 0);
+ GetMenuString(hMenu1, opt.RightClickAction, str, sizeof(str), MF_BYCOMMAND);
+ SetDlgItemTextWth(hdlg, IDC_RightClick, Translate(str));
+ DestroyMenu(hMenu);
+ break;
+
+ case IDC_LeftClick:
+ // left click action selection menu
+ button = GetDlgItem(hdlg, IDC_LeftClick);
+ GetWindowRect(button, &pos);
+
+ hMenu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_PMENU));
+ hMenu1 = GetSubMenu(hMenu, 0);
+ CallService(MS_LANGPACK_TRANSLATEMENU, (WPARAM)hMenu1, 0);
+ SelectMenuItem(hMenu1, opt.LeftClickAction);
+ ID = TrackPopupMenu(hMenu1, TPM_LEFTBUTTON|TPM_RETURNCMD, pos.left, pos.bottom, 0, hdlg, NULL);
+ if (ID) opt.LeftClickAction = ID;
+ DestroyMenu(hMenu);
+
+ hMenu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_PMENU));
+ hMenu1 = GetSubMenu(hMenu, 0);
+ GetMenuString(hMenu1, opt.LeftClickAction, str, sizeof(str), MF_BYCOMMAND);
+ SetDlgItemTextWth(hdlg, IDC_LeftClick, Translate(str));
+ DestroyMenu(hMenu);
+ break;
+
+ case IDC_PD1:
+ // Popup delay setting from PopUp plugin
+ SetDlgItemText(hdlg, IDC_DELAY, "0");
+ CheckRadioButton(hdlg, IDC_PD1, IDC_PD3, IDC_PD1);
+ break;
+
+ case IDC_PD2:
+ // Popup delay = permanent
+ SetDlgItemText(hdlg, IDC_DELAY, "-1");
+ CheckRadioButton(hdlg, IDC_PD1, IDC_PD3, IDC_PD2);
+ break;
+
+ case IDC_DELAY:
+ // if text is edited
+ CheckRadioButton(hdlg, IDC_PD1, IDC_PD3, IDC_PD3);
+ break;
+
+ case IDC_PDEF:
+ // set the default value for popup texts
+ SetTextDefault("Pp");
+ SetDlgItemTextWth(hdlg,IDC_PText, opt.pText);
+ SetDlgItemTextWth(hdlg,IDC_PTitle, opt.pTitle);
+ wfree(&opt.pText);
+ wfree(&opt.pTitle);
+ break;
+
+ case IDC_VAR3:
+ // display variable list
+ strcpy(str, " \n"); // to make the message box wider
+ strcat(str, Translate("%c\tcurrent condition\n%d\tcurrent date\n%e\tdewpoint\n%f\tfeel-like temperature\n%h\ttoday's high\n%i\twind direction\n%l\ttoday's low\n%m\thumidity\n%n\tstation name\n%p\tpressure\n%r\tsunrise time\n%s\tstation ID\n%t\ttemperature\n%u\tupdate time\n%v\tvisibility\n%w\twind speed\n%y\tsun set"));
+ strcat(str, "\n");
+ strcat(str, Translate("%[..]\tcustom variables"));
+ MessageBox(NULL, str, Translate("Variable List"), MB_OK|MB_ICONASTERISK|MB_TOPMOST);
+ break;
+
+ case IDC_PREVIEW:
+ // popup preview
+ hContact = opt.DefStn;
+ ReadPopupOpt(hdlg); // read new options to memory
+ WeatherPopup((WPARAM)opt.DefStn, (BOOL)TRUE); // display popup using new opt
+ DestroyOptions();
+ LoadOptions(); // restore old option in memory
+ opt.DefStn = hContact;
+ break;
+ }
+ break;
+ //End WM_COMMAND
+ case WM_NOTIFY: //Here we have pressed either the OK or the APPLY button.
+ switch (((LPNMHDR)lParam)->code)
+ {
+ case PSN_APPLY:
+ {
+ ReadPopupOpt(hdlg);
+
+ // save the options, and update main menu
+ SaveOptions();
+ UpdatePopupMenu(opt.UsePopup);
+ return TRUE;
+ }
+ }
+ break;
+ }
+ return FALSE;
+}
+
+// used to select the menu item for popup action menu
+void SelectMenuItem(HMENU hMenu, int Check)
+{
+ int i;
+ for (i=0; i<=GetMenuItemCount(hMenu)-1; i++)
+ CheckMenuItem(hMenu, i, MF_BYPOSITION|((int)GetMenuItemID(hMenu, i) == Check)*8);
+}
+
diff --git a/plugins/weather/weather_svcs.c b/plugins/weather/weather_svcs.c
new file mode 100644
index 0000000000..89c58c2d6e
--- /dev/null
+++ b/plugins/weather/weather_svcs.c
@@ -0,0 +1,452 @@
+/*
+Weather Protocol plugin for Miranda IM
+Copyright (C) 2005-2011 Boris Krasnovskiy All Rights Reserved
+Copyright (C) 2002-2005 Calvin Che
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; version 2
+of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+This file contain the source related to weather protocol services
+as required for a Miranda protocol. Also, it contains functions for
+building/changing the weather menu items.
+*/
+
+#include "weather.h"
+
+static int hEnableDisablePopupMenu;
+static int hEnableDisableMenu;
+
+static HANDLE hService[27];
+
+//============ MIRANDA PROTOCOL SERVICES ============
+
+// protocol service function for setting weather protocol status
+INT_PTR WeatherSetStatus(WPARAM new_status, LPARAM lParam)
+{
+ new_status = new_status != ID_STATUS_OFFLINE ? ID_STATUS_ONLINE : ID_STATUS_OFFLINE;
+
+ // if we don't want to show status for default station
+ if (opt.NoProtoCondition && status != new_status)
+ {
+ old_status = status;
+ status = new_status != ID_STATUS_OFFLINE ? ID_STATUS_ONLINE : ID_STATUS_OFFLINE;
+ ProtoBroadcastAck(WEATHERPROTONAME, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, status);
+
+ UpdateMenu(new_status != ID_STATUS_OFFLINE);
+ if (new_status != ID_STATUS_OFFLINE) UpdateAll(FALSE, FALSE);
+ }
+
+ return 0;
+}
+
+// get capabilities protocol service function
+INT_PTR WeatherGetCaps(WPARAM wParam, LPARAM lParam)
+{
+ INT_PTR ret = 0;
+
+ switch(wParam)
+ {
+ case PFLAGNUM_1:
+ // support search and visible list
+ ret = PF1_BASICSEARCH | PF1_ADDSEARCHRES | PF1_EXTSEARCH | PF1_VISLIST | PF1_MODEMSGRECV;
+ break;
+
+ case PFLAGNUM_2:
+ ret = PF2_ONLINE | PF2_INVISIBLE | PF2_SHORTAWAY | PF2_LONGAWAY | PF2_LIGHTDND |
+ PF2_HEAVYDND | PF2_FREECHAT | PF2_OUTTOLUNCH | PF2_ONTHEPHONE;
+ break;
+
+ case PFLAGNUM_4:
+ ret = PF4_AVATARS | PF4_NOCUSTOMAUTH | PF4_NOAUTHDENYREASON | PF4_FORCEADDED |
+ PF4_FORCEAUTH;
+ break;
+
+ case PFLAGNUM_5: /* this is PFLAGNUM_5 change when alpha SDK is released */
+ ret = PF2_INVISIBLE | PF2_SHORTAWAY | PF2_LONGAWAY | PF2_LIGHTDND | PF2_HEAVYDND |
+ PF2_FREECHAT | PF2_OUTTOLUNCH | PF2_ONTHEPHONE;
+ // if (!opt.NoProtoCondition) ret |= PF2_ONLINE;
+ break;
+
+ case PFLAG_UNIQUEIDTEXT:
+ ret = (INT_PTR)Translate("Station ID");
+ break;
+
+ case PFLAG_UNIQUEIDSETTING:
+ ret = (INT_PTR)"ID";
+ break;
+ }
+ return ret;
+}
+
+// protocol service function to get weather protocol name
+INT_PTR WeatherGetName(WPARAM wParam,LPARAM lParam)
+{
+ strncpy((char*)lParam,WEATHERPROTOTEXT,wParam-1);
+ *((char*)lParam + wParam-1) = 0;
+ return 0;
+}
+
+// protocol service function to get the current status of the protocol
+INT_PTR WeatherGetStatus(WPARAM wParam,LPARAM lParam)
+{
+ return status;
+}
+
+// protocol service function to get the icon of the protocol
+INT_PTR WeatherLoadIcon(WPARAM wParam,LPARAM lParam)
+{
+ return (LOWORD(wParam) == PLI_PROTOCOL) ? (INT_PTR)CopyIcon(LoadIconEx("main", FALSE)) : 0;
+}
+
+static void __cdecl AckThreadProc(HANDLE param)
+{
+ Sleep(100);
+ ProtoBroadcastAck(WEATHERPROTONAME, param, ACKTYPE_GETINFO, ACKRESULT_SUCCESS, (HANDLE) 1, 0);
+}
+
+// nothing to do here because weather proto do not need to retrieve contact info form network
+// so just return a 0
+INT_PTR WeatherGetInfo(WPARAM wParam,LPARAM lParam)
+{
+ CCSDATA *ccs = (CCSDATA *) lParam;
+ mir_forkthread(AckThreadProc, ccs->hContact);
+ return 0;
+}
+
+
+INT_PTR WeatherGetAvatarInfo(WPARAM wParam, LPARAM lParam)
+{
+ static const char *statusStr[] = {
+ "Light",
+ "Fog",
+ "SShower",
+ "Snow",
+ "RShower",
+ "Rain",
+ "PCloudy",
+ "Cloudy",
+ "Sunny",
+ "NA"
+ };
+
+ static const WORD statusValue[] = {
+ LIGHT,
+ FOG,
+ SSHOWER,
+ SNOW,
+ RSHOWER,
+ RAIN,
+ PCLOUDY,
+ CLOUDY,
+ SUNNY,
+ NA
+ };
+ char szSearchPath[MAX_PATH], *chop;
+ WORD status;
+ unsigned i;
+ PROTO_AVATAR_INFORMATION* ai = ( PROTO_AVATAR_INFORMATION* )lParam;
+
+ GetModuleFileName(GetModuleHandle(NULL), szSearchPath, sizeof(szSearchPath));
+ chop = strrchr(szSearchPath, '\\');
+
+ if (chop) *chop = '\0';
+ else szSearchPath[0] = 0;
+
+ status = (WORD)DBGetContactSettingWord(ai->hContact, WEATHERPROTONAME, "StatusIcon",0);
+ for (i=0; i<10; i++)
+ {
+ if (statusValue[i] == status)
+ break;
+ }
+ if (i >= 10) return GAIR_NOAVATAR;
+
+ ai->format = PA_FORMAT_PNG;
+ wsprintf(ai->filename, "%s\\Plugins\\Weather\\%s.png", szSearchPath, statusStr[i]);
+ if (_access(ai->filename, 4) == 0) return GAIR_SUCCESS;
+
+ ai->format = PA_FORMAT_GIF;
+ wsprintf(ai->filename, "%s\\Plugins\\Weather\\%s.gif", szSearchPath, statusStr[i]);
+ if (_access(ai->filename, 4) == 0) return GAIR_SUCCESS;
+
+ ai->format = PA_FORMAT_UNKNOWN;
+ ai->filename[0] = 0;
+ return GAIR_NOAVATAR;
+}
+
+
+void AvatarDownloaded(HANDLE hContact)
+{
+ int haveAvatar;
+ PROTO_AVATAR_INFORMATION AI = {0};
+ AI.cbSize = sizeof(AI);
+ AI.hContact = hContact;
+
+// ProtoBroadcastAck(WEATHERPROTONAME, hContact, ACKTYPE_AVATAR, ACKRESULT_STATUS, NULL, 0);
+
+ haveAvatar = WeatherGetAvatarInfo(GAIF_FORCE, (LPARAM)&AI) == GAIR_SUCCESS;
+
+ if (haveAvatar)
+ ProtoBroadcastAck(WEATHERPROTONAME, hContact, ACKTYPE_AVATAR, ACKRESULT_SUCCESS, &AI, 0);
+ else
+ ProtoBroadcastAck(WEATHERPROTONAME, hContact, ACKTYPE_AVATAR, ACKRESULT_STATUS, NULL, 0);
+}
+
+
+static void __cdecl WeatherGetAwayMsgThread(HANDLE hContact)
+{
+ DBVARIANT dbv;
+ Sleep(100);
+ if (!DBGetContactSettingString(hContact, "CList", "StatusMsg", &dbv))
+ {
+ ProtoBroadcastAck(WEATHERPROTONAME, hContact, ACKTYPE_AWAYMSG, ACKRESULT_SUCCESS,
+ (HANDLE)1, (LPARAM)dbv.pszVal);
+ DBFreeVariant( &dbv );
+ }
+ else
+ ProtoBroadcastAck(WEATHERPROTONAME, hContact, ACKTYPE_AWAYMSG, ACKRESULT_SUCCESS, (HANDLE)1, 0);
+}
+
+static INT_PTR WeatherGetAwayMsg(WPARAM wParam, LPARAM lParam)
+{
+ CCSDATA* ccs = (CCSDATA*)lParam;
+ if (ccs == NULL)
+ return 0;
+
+ mir_forkthread(WeatherGetAwayMsgThread, ccs->hContact);
+ return 1;
+}
+
+//============ PROTOCOL INITIALIZATION ============
+// protocol services
+void InitServices(void)
+{
+ hService[0] = CreateProtoServiceFunction(WEATHERPROTONAME, PS_GETCAPS, WeatherGetCaps);
+ hService[1] = CreateProtoServiceFunction(WEATHERPROTONAME, PS_GETNAME, WeatherGetName);
+ hService[3] = CreateProtoServiceFunction(WEATHERPROTONAME, PS_LOADICON, WeatherLoadIcon);
+ hService[4] = CreateProtoServiceFunction(WEATHERPROTONAME, PS_SETSTATUS, WeatherSetStatus);
+ hService[5] = CreateProtoServiceFunction(WEATHERPROTONAME, PS_GETSTATUS, WeatherGetStatus);
+ hService[6] = CreateProtoServiceFunction(WEATHERPROTONAME, PS_BASICSEARCH, WeatherBasicSearch);
+ hService[7] = CreateProtoServiceFunction(WEATHERPROTONAME, PS_SEARCHBYEMAIL, WeatherBasicSearch);
+ hService[8] = CreateProtoServiceFunction(WEATHERPROTONAME, PS_ADDTOLIST, WeatherAddToList);
+ hService[9] = CreateProtoServiceFunction(WEATHERPROTONAME, PSS_GETINFO, WeatherGetInfo);
+ hService[10] = CreateProtoServiceFunction(WEATHERPROTONAME, PS_GETAVATARINFO, WeatherGetAvatarInfo);
+ hService[11] = CreateProtoServiceFunction(WEATHERPROTONAME, PSS_GETAWAYMSG, WeatherGetAwayMsg);
+ hService[12] = CreateProtoServiceFunction(WEATHERPROTONAME, PS_CREATEADVSEARCHUI, WeatherCreateAdvancedSearchUI);
+ hService[13] = CreateProtoServiceFunction(WEATHERPROTONAME, PS_SEARCHBYADVANCED, WeatherAdvancedSearch);
+
+ hService[14] = CreateProtoServiceFunction(WEATHERPROTONAME, MS_WEATHER_GETDISPLAY, GetDisplaySvcFunc);
+}
+
+void DestroyServices(void)
+{
+ unsigned i;
+
+ for (i = sizeof(hService)/sizeof(HANDLE); i--; )
+ {
+ if (hService[i] != NULL)
+ DestroyServiceFunction(hService[i]);
+ }
+}
+
+//============ MENU INITIALIZATION ============
+
+void UpdateMenu(BOOL State)
+{
+ // We're here to change something, so let's read the actual value.
+ // TempDisable == FALSE means that right now the popups are enabled
+ // and if we're here, we want to disable them.
+ // The icon works this way:
+ // if the notifications are disabled, the icon hasn't the red circle;
+ // if the notifications are enabled, the icon has the red circle.
+
+ CLISTMENUITEM mi = {0};
+
+ mi.cbSize = sizeof(mi);
+
+ if (State)
+ { // to enable auto-update
+ mi.pszName = "Auto Update Enabled";
+ mi.icolibItem = GetIconHandle("main");
+ }
+ else
+ { // to disable auto-update
+ mi.pszName = "Auto Update Disabled";
+ mi.icolibItem = GetIconHandle("disabled");
+ }
+ // update option setting
+ opt.CAutoUpdate = State;
+ DBWriteContactSettingByte(NULL, WEATHERPROTONAME, "AutoUpdate", (BYTE)opt.AutoUpdate);
+ mi.flags = CMIM_ICON | CMIM_NAME | CMIF_ICONFROMICOLIB;
+
+ // update menu item
+ CallService(MS_CLIST_MODIFYMENUITEM,(WPARAM)hEnableDisableMenu,(LPARAM)&mi);
+}
+
+void UpdatePopupMenu(BOOL State)
+{
+ // We're here to change something, so let's read the actual value.
+ // TempDisable == FALSE means that right now the popups are enabled
+ // and if we're here, we want to disable them.
+ // The icon works this way:
+ // if the notifications are disabled, the icon hasn't the red circle;
+ // if the notifications are enabled, the icon has the red circle.
+
+ CLISTMENUITEM mi = {0};
+
+ mi.cbSize = sizeof(mi);
+
+ if (State)
+ { // to enable popup
+ mi.pszName = "Disable &weather notification";
+ mi.icolibItem = GetIconHandle("popup");
+ }
+ else
+ { // to disable popup
+ mi.pszName = "Enable &weather notification";
+ mi.icolibItem = GetIconHandle("nopopup");
+ }
+ // update option setting
+ opt.UsePopup = State;
+ DBWriteContactSettingByte(NULL, WEATHERPROTONAME, "UsePopUp", (BYTE)opt.UsePopup);
+ mi.flags = CMIM_ICON | CMIM_NAME | CMIF_ICONFROMICOLIB;
+
+ // update menu item
+ CallService(MS_CLIST_MODIFYMENUITEM,(WPARAM)hEnableDisablePopupMenu,(LPARAM)&mi);
+}
+
+// update the weather auto-update menu item when click on it
+INT_PTR EnableDisableCmd(WPARAM wParam,LPARAM lParam)
+{
+ UpdateMenu(wParam == TRUE ? (BOOL)lParam : !opt.CAutoUpdate);
+ return 0;
+}
+
+// update the weather popup menu item when click on it
+INT_PTR MenuitemNotifyCmd(WPARAM wParam,LPARAM lParam)
+{
+ UpdatePopupMenu(!opt.UsePopup);
+ return 0;
+}
+
+// adding weather contact menus
+// copied and modified form "modified MSN Protocol"
+void AddMenuItems(void)
+{
+ CLISTMENUITEM mi = {0};
+
+ mi.cbSize = sizeof(mi);
+ mi.pszContactOwner = WEATHERPROTONAME;
+ mi.flags = CMIF_ICONFROMICOLIB;
+
+ // contact menu
+ hService[15] = CreateServiceFunction(MS_WEATHER_UPDATE, UpdateSingleStation);
+ mi.position=-0x7FFFFFFA;
+ mi.icolibItem = GetIconHandle("update");
+ mi.pszName="Update Weather";
+ mi.pszService = MS_WEATHER_UPDATE;
+ CallService(MS_CLIST_ADDCONTACTMENUITEM,0,(LPARAM)&mi);
+
+ hService[16] = CreateServiceFunction(MS_WEATHER_REFRESH, UpdateSingleRemove);
+ mi.position=-0x7FFFFFF9;
+ mi.icolibItem = GetIconHandle("update2");
+ mi.pszName="Remove Old Data then Update";
+ mi.pszService = MS_WEATHER_REFRESH;
+ CallService(MS_CLIST_ADDCONTACTMENUITEM,0,(LPARAM)&mi);
+
+ hService[17] = CreateServiceFunction(MS_WEATHER_BRIEF, BriefInfoSvc);
+ mi.position=-0x7FFFFFF8;
+ mi.icolibItem = GetIconHandle("brief");
+ mi.pszName="Brief Information";
+ mi.pszService = MS_WEATHER_BRIEF;
+ CallService(MS_CLIST_ADDCONTACTMENUITEM,0,(LPARAM)&mi);
+
+ hService[18] = CreateServiceFunction(MS_WEATHER_COMPLETE, LoadForecast);
+ mi.position=-0x7FFFFFF7;
+ mi.icolibItem = GetIconHandle("read");
+ mi.pszName="Read Complete Forecast";
+ mi.pszService = MS_WEATHER_COMPLETE;
+ CallService(MS_CLIST_ADDCONTACTMENUITEM,0,(LPARAM)&mi);
+
+ hService[19] = CreateServiceFunction(MS_WEATHER_MAP, WeatherMap);
+ mi.position=-0x7FFFFFF6;
+ mi.icolibItem = GetIconHandle("map");
+ mi.pszName="Weather Map";
+ mi.pszService = MS_WEATHER_MAP;
+ CallService(MS_CLIST_ADDCONTACTMENUITEM,0,(LPARAM)&mi);
+
+ hService[20] = CreateServiceFunction(MS_WEATHER_LOG, ViewLog);
+ mi.position=-0x7FFFFFF5;
+ mi.icolibItem = GetIconHandle("log");
+ mi.pszName="View Log";
+ mi.pszService = MS_WEATHER_LOG;
+ CallService(MS_CLIST_ADDCONTACTMENUITEM,0,(LPARAM)&mi);
+
+ hService[21] = CreateServiceFunction(MS_WEATHER_EDIT, EditSettings);
+ mi.position=-0x7FFFFFF4;
+ mi.icolibItem = GetIconHandle("edit");
+ mi.pszName="Edit Settings";
+ mi.pszService = MS_WEATHER_EDIT;
+ CallService(MS_CLIST_ADDCONTACTMENUITEM,0,(LPARAM)&mi);
+
+ // adding main menu items
+ mi.pszPopupName = "Weather";
+ mi.popupPosition = 500099000;
+
+ hService[22] = CreateServiceFunction(MS_WEATHER_ENABLED, EnableDisableCmd);
+ mi.pszName = "Enable/Disable Weather Update";
+ mi.icolibItem = GetIconHandle("main");
+ mi.position=10100001;
+ mi.pszService = MS_WEATHER_ENABLED;
+ hEnableDisableMenu = CallService(MS_CLIST_ADDMAINMENUITEM,0,(LPARAM)&mi);
+ UpdateMenu(opt.AutoUpdate);
+
+ hService[23] = CreateServiceFunction(MS_WEATHER_UPDATEALL, UpdateAllInfo);
+ mi.position=20100001;
+ mi.icolibItem = GetIconHandle("update");
+ mi.pszName="Update All Weather";
+ mi.pszService = MS_WEATHER_UPDATEALL;
+ CallService(MS_CLIST_ADDMAINMENUITEM,0,(LPARAM)&mi);
+
+ hService[24] = CreateServiceFunction(MS_WEATHER_REFRESHALL, UpdateAllRemove);
+ mi.position=20100002;
+ mi.icolibItem = GetIconHandle("update2");
+ mi.pszName="Remove Old Data then Update All";
+ mi.pszService = MS_WEATHER_REFRESHALL;
+ CallService(MS_CLIST_ADDMAINMENUITEM,0,(LPARAM)&mi);
+
+ // only run if popup service exists
+ if (ServiceExists(MS_POPUP_ADDPOPUP))
+ {
+ hService[25] = CreateServiceFunction(WEATHERPROTONAME "/PopupMenu", MenuitemNotifyCmd);
+ mi.pszName = "Weather Notification";
+ mi.icolibItem = GetIconHandle("popup");
+ mi.position = 0;
+ mi.pszPopupName = "PopUps";
+ mi.pszService = WEATHERPROTONAME "/PopupMenu";
+ hEnableDisablePopupMenu = CallService(MS_CLIST_ADDMAINMENUITEM,0,(LPARAM)&mi);
+ UpdatePopupMenu(opt.UsePopup);
+ }
+
+ if (ServiceExists(MS_CLIST_FRAMES_ADDFRAME))
+ {
+ hService[26] = CreateServiceFunction("Weather/mwin_menu", Mwin_MenuClicked);
+ mi.position = -0x7FFFFFF0;
+ mi.hIcon = NULL;
+ mi.flags = 0;
+ mi.pszName = "Display in a frame";
+ mi.pszService = "Weather/mwin_menu";
+ hMwinMenu = (HANDLE)CallService(MS_CLIST_ADDCONTACTMENUITEM,0,(LPARAM)&mi);
+ }
+}
diff --git a/plugins/weather/weather_update.c b/plugins/weather/weather_update.c
new file mode 100644
index 0000000000..9b81b023f5
--- /dev/null
+++ b/plugins/weather/weather_update.c
@@ -0,0 +1,678 @@
+/*
+Weather Protocol plugin for Miranda IM
+Copyright (C) 2005-2011 Boris Krasnovskiy All Rights Reserved
+Copyright (C) 2002-2005 Calvin Che
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; version 2
+of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+This file contain the source related to updating new weather
+information, both automatic (by timer) and manually (by selecting
+menu items).
+*/
+
+#include "weather.h"
+
+UPDATELIST *UpdateListHead;
+UPDATELIST *UpdateListTail;
+
+extern HANDLE hUpdateMutex;
+
+//============ RETRIEVE NEW WEATHER ============
+
+// retrieve weather info and display / log them
+// hContact = current contact
+int UpdateWeather(HANDLE hContact)
+{
+ char str[256], str2[MAX_TEXT_SIZE], logstr[256];
+ int code;
+ FILE *file;
+ DBVARIANT dbv;
+ BOOL Ch = FALSE;
+ WEATHERINFO winfo;
+ HWND hMoreDataDlg;
+ int dbres;
+
+ if (hContact == NULL) return 1; // some error prevention
+
+ dbv.pszVal = "";
+
+ // log to netlib log for debug purpose
+ Netlib_Logf(hNetlibUser, "************************************************************************");
+ dbres = DBGetContactSettingString(hContact, WEATHERPROTONAME, "Nick", &dbv);
+
+ Netlib_Logf(hNetlibUser, "<-- Start update for station: %s -->", dbv.pszVal);
+ mir_snprintf(logstr, sizeof(logstr), "<-- Update successful for station: %s -->", dbv.pszVal);
+
+ // download the info and parse it
+ // result are stored in database
+ code = GetWeatherData(hContact);
+ if (code != 0)
+ {
+ // error occurs if the return value is not equals to 0
+ if (opt.ShowWarnings)
+ { // show warnings by popup
+ mir_snprintf(str, sizeof(str)-105,
+ Translate("Unable to retrieve weather information for %s"), dbv.pszVal);
+ strcat(str, "\n");
+ strcat(str, GetError(code));
+ WPShowMessage(str, SM_WARNING);
+ }
+ // log to netlib
+ Netlib_Logf(hNetlibUser, "Error! Update cannot continue... Start to free memory");
+ Netlib_Logf(hNetlibUser, "<-- Error occurs while updating station: %s -->", dbv.pszVal);
+ if (!dbres) DBFreeVariant(&dbv);
+ return 1;
+ }
+ if (!dbres) DBFreeVariant(&dbv);
+
+ // initialize, load new weather Data
+ winfo = LoadWeatherInfo(hContact);
+
+ // translate weather condition
+ strcpy(winfo.cond, Translate(winfo.cond));
+
+ // compare the old condition and determine if the weather had changed
+ if (opt.UpdateOnlyConditionChanged) // consider condition change
+ {
+ if (!DBGetContactSettingString(hContact, WEATHERPROTONAME, "LastCondition", &dbv))
+ {
+ if (_stricmp(winfo.cond, dbv.pszVal)) Ch = TRUE; // the weather condition is changed
+ DBFreeVariant(&dbv);
+ }
+ else Ch = TRUE;
+ if (!DBGetContactSettingString(hContact, WEATHERPROTONAME, "LastTemperature", &dbv))
+ {
+ if (_stricmp(winfo.temp, dbv.pszVal)) Ch = TRUE; // the temperature is changed
+ DBFreeVariant(&dbv);
+ }
+ else Ch = TRUE;
+ }
+ else // consider update time change
+ {
+ if (!DBGetContactSettingString(hContact, WEATHERPROTONAME, "LastUpdate", &dbv))
+ {
+ if (_stricmp(winfo.update, dbv.pszVal)) Ch = TRUE; // the update time is changed
+ DBFreeVariant(&dbv);
+ }
+ else Ch = TRUE;
+ }
+
+ // have weather alert issued?
+ dbres = DBGetContactSettingString(hContact, WEATHERCONDITION, "Alert", &dbv);
+ if (!dbres && dbv.pszVal[0] != 0)
+ {
+ if (opt.AlertPopup && !DBGetContactSettingByte(hContact, WEATHERPROTONAME, "DPopUp", 0) && Ch)
+ {
+ // display alert popup
+ wsprintf(str, "Alert for %s%c%s", winfo.city, 255, dbv.pszVal);
+ WPShowMessage(str, SM_WEATHERALERT);
+ }
+ // alert issued, set display to italic
+ if (opt.MakeItalic)
+ DBWriteContactSettingWord(hContact, WEATHERPROTONAME, "ApparentMode", ID_STATUS_OFFLINE);
+ SkinPlaySound("weatheralert");
+ }
+ // alert dropped, set the display back to normal
+ else DBDeleteContactSetting(hContact, WEATHERPROTONAME, "ApparentMode");
+ if (!dbres) DBFreeVariant(&dbv);
+
+ // backup current condition for checking if the weather is changed or not
+ DBWriteContactSettingString(hContact, WEATHERPROTONAME, "LastLog", winfo.update);
+ DBWriteContactSettingString(hContact, WEATHERPROTONAME, "LastCondition", winfo.cond);
+ DBWriteContactSettingString(hContact, WEATHERPROTONAME, "LastTemperature", winfo.temp);
+ DBWriteContactSettingString(hContact, WEATHERPROTONAME, "LastUpdate", winfo.update);
+
+ // display condition on contact list
+ if (opt.DisCondIcon && winfo.status != ID_STATUS_OFFLINE)
+ DBWriteContactSettingWord(hContact, WEATHERPROTONAME, "Status", ID_STATUS_ONLINE);
+ else
+ DBWriteContactSettingWord(hContact, WEATHERPROTONAME, "Status", winfo.status);
+ AvatarDownloaded(hContact);
+
+ GetDisplay(&winfo, opt.cText, str2);
+ if (lpcp != CP_ACP)
+ {
+ LPWSTR m_psz = ConvToUnicode(str2);
+ DBWriteContactSettingWString(hContact, "CList", "MyHandle", m_psz);
+ mir_free(m_psz);
+ }
+ else
+ DBWriteContactSettingString(hContact, "CList", "MyHandle", str2);
+
+ GetDisplay(&winfo, opt.sText, str2);
+ if (str2[0])
+ {
+ if (lpcp != CP_ACP)
+ {
+ wchar_t* m_psz = ConvToUnicode(str2);
+ DBWriteContactSettingWString(hContact, "CList", "StatusMsg", m_psz);
+ mir_free(m_psz);
+ }
+ else
+ DBWriteContactSettingString(hContact, "CList", "StatusMsg", str2);
+ }
+ else
+ DBDeleteContactSetting(hContact, "CList", "StatusMsg");
+
+ ProtoBroadcastAck(WEATHERPROTONAME, hContact, ACKTYPE_AWAYMSG, ACKRESULT_SUCCESS, NULL, (LPARAM)(str2[0] ? str2 : 0));
+
+ // save descriptions in MyNotes
+ GetDisplay(&winfo, opt.nText, str2);
+ DBWriteContactSettingString(hContact, "UserInfo", "MyNotes", str2);
+ GetDisplay(&winfo, opt.xText, str2);
+ DBWriteContactSettingString(hContact, WEATHERCONDITION, "WeatherInfo", str2);
+
+ // set the update tag
+ DBWriteContactSettingByte(hContact, WEATHERPROTONAME, "IsUpdated", TRUE);
+
+ // save info for default weather condition
+ if (!strcmp(winfo.id, opt.Default) && !opt.NoProtoCondition) {
+ // save current condition for default station to be displayed after the update
+ old_status = status;
+ status = winfo.status;
+ // a workaround for a default station that currently have an n/a icon assigned
+ if (status == ID_STATUS_OFFLINE) status = NOSTATUSDATA;
+ ProtoBroadcastAck(WEATHERPROTONAME, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, status);
+ }
+
+ // logging
+ if (Ch)
+ {
+ // play the sound event
+ SkinPlaySound("weatherupdated");
+
+ if (DBGetContactSettingByte(hContact, WEATHERPROTONAME, "File", 0))
+ {
+ // external log
+ if (!DBGetContactSettingString(hContact,WEATHERPROTONAME,"Log",&dbv))
+ {
+ // for the option for overwriting the file, delete old file first
+ if (DBGetContactSettingByte(hContact,WEATHERPROTONAME,"Overwrite",0))
+ DeleteFile(dbv.pszVal);
+ // open the file and set point to the end of file
+ file = fopen( dbv.pszVal, "a");
+ DBFreeVariant(&dbv);
+ if (file != NULL)
+ {
+ // write data to the file and close
+ GetDisplay(&winfo, opt.eText, str2);
+ fputs(str2, file);
+ fclose(file);
+ }
+ }
+ }
+
+ if (DBGetContactSettingByte(hContact, WEATHERPROTONAME, "History", 0))
+ {
+ DBEVENTINFO dbei = {0};
+ // internal log using history
+ GetDisplay(&winfo, opt.hText, str2);
+ dbei.cbSize = sizeof(dbei);
+ dbei.szModule = WEATHERPROTONAME;
+ dbei.timestamp = (DWORD)time(NULL);
+ dbei.flags = DBEF_READ;
+ dbei.eventType = EVENTTYPE_MESSAGE;
+ dbei.cbBlob = (DWORD)strlen(str2)+1;
+ dbei.pBlob = (PBYTE)str2;
+
+ // add the history event
+ CallService(MS_DB_EVENT_ADD, (WPARAM)hContact, (LPARAM)&dbei);
+ }
+
+ // show the popup
+ NotifyEventHooks(hHookWeatherUpdated, (WPARAM)hContact, (LPARAM)Ch);
+ }
+
+ Netlib_Logf(hNetlibUser, "Update Completed - Start to free memory");
+
+ // free memory
+ Netlib_Logf(hNetlibUser, logstr);
+
+ // Update frame data
+ UpdateMwinData(hContact);
+
+ // update brief info if its opened
+ hMoreDataDlg = WindowList_Find(hDataWindowList, hContact);
+ if (hMoreDataDlg != NULL) PostMessage(hMoreDataDlg, WM_UPDATEDATA, 0, 0);
+ return 0;
+}
+
+//============ UPDATE LIST ============
+
+// a linked list queue for updating weather station
+// this function add a weather contact to the end of queue for update
+// hContact = current contact
+void UpdateListAdd(HANDLE hContact)
+{
+ UPDATELIST *newItem;
+
+ newItem = (UPDATELIST*)mir_alloc(sizeof(UPDATELIST));
+ newItem->hContact = hContact;
+ newItem->next = NULL;
+
+ WaitForSingleObject(hUpdateMutex, INFINITE);
+
+ if (UpdateListTail == NULL) UpdateListHead = newItem;
+ else UpdateListTail->next = newItem;
+ UpdateListTail = newItem;
+
+ ReleaseMutex(hUpdateMutex);
+}
+
+// get the first item from the update queue and remove it from the queue
+// return value = the contact for next update
+HANDLE UpdateGetFirst()
+{
+ HANDLE hContact = NULL;
+
+ WaitForSingleObject(hUpdateMutex, INFINITE);
+
+ if (UpdateListHead != NULL)
+ {
+ UPDATELIST* Item = UpdateListHead;
+
+ hContact = Item->hContact;
+ UpdateListHead = Item->next;
+ mir_free(Item);
+
+ if (UpdateListHead == NULL) UpdateListTail = NULL;
+ }
+
+ ReleaseMutex(hUpdateMutex);
+
+ return hContact;
+}
+
+void DestroyUpdateList(void)
+{
+ UPDATELIST *temp;
+
+ WaitForSingleObject(hUpdateMutex, INFINITE);
+
+ temp = UpdateListHead;
+
+ // free the list one by one
+ while (temp != NULL)
+ {
+ UpdateListHead = temp->next;
+ mir_free(temp);
+ temp = UpdateListHead;
+ }
+ // make sure the entire list is clear
+ UpdateListTail = NULL;
+
+ ReleaseMutex(hUpdateMutex);
+}
+
+
+//============ UPDATE WEATHER ============
+
+// update all weather station
+// AutoUpdate = true if it is from automatic update using timer
+// false if it is from update by clicking the main menu
+void UpdateAll(BOOL AutoUpdate, BOOL RemoveData)
+{
+ // add all weather contact to the update queue list
+ HANDLE hContact= (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ while (hContact != NULL)
+ {
+ if(IsMyContact(hContact))
+ {
+ if (!DBGetContactSettingByte(hContact,WEATHERPROTONAME,"AutoUpdate",FALSE) || !AutoUpdate)
+ {
+ if (RemoveData) DBDataManage((HANDLE)hContact, WDBM_REMOVE, 0, 0);
+ UpdateListAdd(hContact);
+ }
+ }
+ hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0);
+ }
+
+ // if it is not updating, then start the update thread process
+ // if it is updating, the stations just added to the queue will get updated by the already-running process
+ if (!ThreadRunning)
+ mir_forkthread(UpdateThreadProc, NULL);
+}
+
+// update a single station
+// wParam = handle for the weather station that is going to be updated
+INT_PTR UpdateSingleStation(WPARAM wParam, LPARAM lParam)
+{
+ if(IsMyContact((HANDLE)wParam))
+ {
+ // add the station to the end of the update queue
+ UpdateListAdd((HANDLE)wParam);
+
+ // if it is not updating, then start the update thread process
+ // if it is updating, the stations just added to the queue will get
+ // updated by the already-running process
+ if (!ThreadRunning)
+ mir_forkthread(UpdateThreadProc, NULL);
+ }
+
+ return 0;
+}
+
+// update a single station with removing the old data
+// wParam = handle for the weather station that is going to be updated
+INT_PTR UpdateSingleRemove(WPARAM wParam, LPARAM lParam)
+{
+ if(IsMyContact((HANDLE)wParam))
+ {
+ // add the station to the end of the update queue, and also remove old data
+ DBDataManage((HANDLE)wParam, WDBM_REMOVE, 0, 0);
+ UpdateListAdd((HANDLE)wParam);
+
+ // if it is not updating, then start the update thread process
+ // if it is updating, the stations just added to the queue will get updated by the already-running process
+ if (!ThreadRunning)
+ mir_forkthread(UpdateThreadProc, NULL);
+ }
+
+ return 0;
+}
+
+// update all weather thread
+// this thread update each weather station from the queue
+void UpdateThreadProc(LPVOID hWnd)
+{
+ WaitForSingleObject(hUpdateMutex, INFINITE);
+ if (ThreadRunning)
+ {
+ ReleaseMutex(hUpdateMutex);
+ return;
+ }
+ ThreadRunning = TRUE; // prevent 2 instance of this thread running
+ ReleaseMutex(hUpdateMutex);
+
+ // update weather by getting the first station from the queue until the queue is empty
+ while (UpdateListHead != NULL && !Miranda_Terminated())
+ UpdateWeather(UpdateGetFirst());
+
+ NetlibHttpDisconnect();
+
+ // exit the update thread
+ ThreadRunning = FALSE;
+}
+
+// the "Update All" menu item in main menu
+INT_PTR UpdateAllInfo(WPARAM wParam,LPARAM lParam)
+{
+ if (!ThreadRunning) UpdateAll(FALSE, FALSE);
+ return 0;
+}
+
+// the "Update All" menu item in main menu and remove the old data
+INT_PTR UpdateAllRemove(WPARAM wParam,LPARAM lParam) {
+ if (!ThreadRunning) UpdateAll(FALSE, TRUE);
+ return 0;
+}
+
+//============ GETTING WEATHER DATA ============
+
+// getting weather data and save them into the database
+// hContact = the contact to get the data
+int GetWeatherData(HANDLE hContact)
+{
+ char *loc, id[256], Svc[256], DataValue[MAX_DATA_LEN], *szData = NULL, *szInfo;
+ int retval, i;
+ WIDATAITEMLIST* Item;
+ WIDATA *Data;
+ WORD cond = NA;
+
+ // get eacnh part of the id's
+ GetStationID(hContact, id, sizeof(id));
+
+ // test ID format
+ loc = strchr(id, '/');
+ if (loc == NULL) return INVALID_ID_FORMAT;
+
+ GetID(id);
+ GetStationID(hContact, Svc, sizeof(Svc));
+ GetSvc(Svc);
+
+ // check for invalid station
+ if (id[0] == 0) return INVALID_ID;
+ if (Svc[0] == 0) return INVALID_SVC;
+
+ // get the update strings (loaded to memory from ini files)
+ Data = GetWIData(Svc);
+ if (Data == NULL) return SVC_NOT_FOUND; // the ini for the station cannot be found
+
+ for (i=0; i<4; ++i)
+ {
+ // generate update URL
+ switch(i)
+ {
+ case 0:
+ loc = (char*)mir_alloc(strlen(Data->UpdateURL)+128);
+ wsprintf(loc, Data->UpdateURL, id);
+ break;
+
+ case 1:
+ loc = (char*)mir_alloc(strlen(Data->UpdateURL2)+128);
+ wsprintf(loc, Data->UpdateURL2, id);
+ break;
+
+ case 2:
+ loc = (char*)mir_alloc(strlen(Data->UpdateURL3)+128);
+ wsprintf(loc, Data->UpdateURL3, id);
+ break;
+
+ case 3:
+ loc = (char*)mir_alloc(strlen(Data->UpdateURL4)+128);
+ wsprintf(loc, Data->UpdateURL4, id);
+ break;
+ }
+
+ if (loc[0] == 0)
+ {
+ mir_free(loc);
+ continue;
+ }
+
+ // download the html file from the internet
+ retval = InternetDownloadFile(loc, Data->Cookie, &szData);
+ mir_free(loc);
+
+ if (retval != 0)
+ {
+ mir_free(szData);
+ return retval;
+ }
+ else if (strstr(szData, "Document Not Found") != NULL) {
+ mir_free(szData);
+ return DOC_NOT_FOUND;
+ }
+
+ szInfo = szData;
+
+ Item = Data->UpdateData;
+
+ // begin parsing item by item
+ while (Item != NULL)
+ {
+ if (Item->Item.Url[0] != 0 && Item->Item.Url[0] != (i + '1'))
+ {
+ Item = Item->Next;
+ continue;
+ }
+
+ switch (Item->Item.Type)
+ {
+ case WID_NORMAL:
+ // if it is a normal item with start= and end=, then parse through the downloaded string
+ // to get a data value.
+ GetDataValue(&Item->Item, DataValue, &szInfo);
+ if (strcmp(Item->Item.Name, "Condition") && _stricmp(Item->Item.Unit, "Cond"))
+ strcpy(DataValue, Translate(DataValue));
+ break;
+
+ case WID_SET:
+ {
+ // for the "Set Data=" operation
+ DBVARIANT dbv;
+ char *chop, *str, str2[MAX_DATA_LEN];
+ BOOL hasvar = FALSE;
+ size_t stl;
+
+ // get the set data operation string
+ str = Item->Item.End;
+ DataValue[0] = 0;
+ // go through each part of the operation string seperated by the & operator
+ do {
+ chop = strstr(str, " & ");
+ // the end of the string, last item
+ if (chop == NULL) chop = strchr(str, '\0');
+
+ stl = min(sizeof(str2)-1, (unsigned)(chop-str-2));
+ strncpy(str2, str+1, stl);
+ str2[stl] = 0;
+
+ switch(str[0])
+ {
+ case '[': // variable, add the value to the result string
+ hasvar = TRUE;
+ if (!DBGetData(hContact, str2, &dbv))
+ {
+ strncat(DataValue, dbv.pszVal, sizeof(DataValue)-strlen(DataValue));
+ DataValue[sizeof(DataValue)-1]=0;
+ DBFreeVariant(&dbv);
+ }
+ break;
+
+ case'\"': // constant, add it to the result string
+ strncat(DataValue, Translate(str2), sizeof(DataValue)-strlen(DataValue));
+ DataValue[sizeof(DataValue)-1]=0;
+ break;
+ }
+
+ // remove the front part of the string that is done and continue parsing
+ str = chop + 3;
+ } while (chop[0] && str[0]);
+
+ if (!hasvar) ConvertDataValue(&Item->Item, DataValue);
+ break;
+ }
+ case WID_BREAK:
+ {
+ // for the "Break Data=" operation
+ char *end;
+ DBVARIANT dbv;
+ if (!DBGetData(hContact, Item->Item.Start, &dbv))
+ {
+ strncpy(DataValue, dbv.pszVal, sizeof(DataValue));
+ DataValue[sizeof(DataValue)-1] = 0;
+ DBFreeVariant(&dbv);
+ }
+ else
+ {
+ DataValue[0] = 0;
+ break; // do not continue if the source is invalid
+ }
+
+ // generate the strings
+ end = strstr(DataValue, Item->Item.Break);
+ if (end == NULL)
+ {
+ DataValue[0] = 0;
+ break; // exit if break string is not found
+ }
+ *end = '\0';
+ end+=strlen(Item->Item.Break);
+ while (end[0] == ' ') end++; // remove extra space
+
+ ConvertDataValue(&Item->Item, DataValue);
+
+ // write the 2 strings created from the break operation
+// DBWriteContactSettingString(hContact, WEATHERCONDITION, Item->Item.Name, DataValue);
+ if (Item->Item.End[0])
+ DBWriteContactSettingString(hContact, WEATHERCONDITION, Item->Item.End, end);
+ break;
+ }
+ }
+
+ // don't store data if it is not available
+ if ((DataValue[0] != 0 && strcmp(DataValue, NODATA) &&
+ strcmp(DataValue, Translate(NODATA)) && strcmp(Item->Item.Name, "Ignore")) ||
+ (!strcmp(Item->Item.Name, "Alert") && i == 0))
+ {
+ // temporary workaround for mToolTip to show feel-like temperature
+ if (!strcmp(Item->Item.Name, "Feel"))
+ DBWriteContactSettingString(hContact, WEATHERCONDITION, "Heat Index", DataValue);
+ GetStationID(hContact, Svc, sizeof(Svc));
+ if (strcmp(Svc, opt.Default) == 0)
+ DBWriteContactSettingString(NULL, DEFCURRENTWEATHER, Item->Item.Name, DataValue);
+ if (strcmp(Item->Item.Name, "Condition") == 0)
+ {
+ char buf[128], *cbuf;
+ mir_snprintf(buf, sizeof(buf), "#%s Weather", DataValue);
+ cbuf = Translate(buf);
+ if (cbuf[0] == '#')
+ cbuf = Translate(DataValue);
+ DBWriteContactSettingString(hContact, WEATHERCONDITION, Item->Item.Name, cbuf);
+ CharLowerBuff(DataValue, (int)strlen(DataValue));
+ cond = GetIcon(DataValue, Data);
+ }
+ else if (_stricmp(Item->Item.Unit, "Cond") == 0)
+ {
+ char buf[128], *cbuf;
+ mir_snprintf(buf, sizeof(buf), "#%s Weather", DataValue);
+ cbuf = Translate(buf);
+ if (cbuf[0] == '#')
+ cbuf = Translate(DataValue);
+ DBWriteContactSettingString(hContact, WEATHERCONDITION, Item->Item.Name, cbuf);
+ }
+ else
+ DBWriteContactSettingString(hContact, WEATHERCONDITION, Item->Item.Name, DataValue);
+ }
+ Item = Item->Next;
+ }
+ mir_free(szData);
+ }
+
+ // assign condition icon
+ DBWriteContactSettingWord(hContact, WEATHERPROTONAME, "StatusIcon", cond);
+ DBWriteContactSettingString(hContact, WEATHERPROTONAME, "MirVer", Data->DisplayName);
+
+ return 0;
+}
+
+//============ UPDATE TIMERS ============
+
+// main auto-update timer
+void CALLBACK timerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
+{
+ // only run if it is not current updating and the auto update option is enabled
+ if (!ThreadRunning && opt.CAutoUpdate && !Miranda_Terminated() &&
+ (!opt.NoProtoCondition || status == ID_STATUS_ONLINE))
+ UpdateAll(TRUE, FALSE);
+}
+
+// temporary timer for first run
+// when this is run, it kill the old startup timer and create the permenant one above
+void CALLBACK timerProc2(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
+{
+ KillTimer(NULL, timerId);
+ ThreadRunning = FALSE;
+
+ if (!Miranda_Terminated())
+ {
+ if (opt.StartupUpdate && !opt.NoProtoCondition)
+ UpdateAll(FALSE, FALSE);
+ timerId = SetTimer(NULL, 0, ((int)opt.UpdateTime)*60000, (TIMERPROC)timerProc);
+ }
+}
+
diff --git a/plugins/weather/weather_userinfo.c b/plugins/weather/weather_userinfo.c
new file mode 100644
index 0000000000..07b296f601
--- /dev/null
+++ b/plugins/weather/weather_userinfo.c
@@ -0,0 +1,418 @@
+/*
+Weather Protocol plugin for Miranda IM
+Copyright (C) 2005-2011 Boris Krasnovskiy All Rights Reserved
+Copyright (C) 2002-2005 Calvin Che
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; version 2
+of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+/*
+This file contain the source that is related to display contact
+information, including the one shows in user detail and the brief
+information
+*/
+
+#include "weather.h"
+
+extern INT_PTR CALLBACK DlgProcINIPage(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+
+//============ CONTACT INFORMATION ============
+
+// initialize user info
+// lParam = current contact
+int UserInfoInit(WPARAM wParam, LPARAM lParam)
+{
+ OPTIONSDIALOGPAGE odp = {0};
+
+ odp.cbSize = sizeof(odp);
+ odp.hInstance = hInst;
+ odp.position = 100000000;
+ odp.pszTitle = LPGEN(WEATHERPROTONAME);
+
+ if (lParam == 0)
+ {
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_INFO);
+ odp.pfnDlgProc = DlgProcINIPage;
+ CallService(MS_USERINFO_ADDPAGE, wParam, (LPARAM)&odp);
+ }
+ else
+ {
+ // check if it is a weather contact
+ if(IsMyContact((HANDLE)lParam))
+ {
+ // register the contact info page
+ odp.pszTemplate = MAKEINTRESOURCE(IDD_USERINFO);
+ odp.pfnDlgProc = DlgProcUIPage;
+ odp.flags = ODPF_BOLDGROUPS;
+ CallService(MS_USERINFO_ADDPAGE, wParam, (LPARAM)&odp);
+ }
+ }
+
+ return 0;
+}
+
+// dialog process for the weather tab under user info
+// lParam = current contact
+INT_PTR CALLBACK DlgProcUIPage(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ WEATHERINFO w;
+ char str[MAX_TEXT_SIZE];
+ HANDLE hContact;
+
+ hContact = (HANDLE)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hwndDlg);
+ SendMessage(GetDlgItem(hwndDlg,IDC_MOREDETAIL), BUTTONSETASFLATBTN, 0, 0);
+ // save the contact handle for later use
+ hContact = (HANDLE)lParam;
+ SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)hContact);
+ // load weather info for the contact
+ w = LoadWeatherInfo((HANDLE)lParam);
+ SetDlgItemTextWth(hwndDlg, IDC_INFO1, GetDisplay(&w, Translate("Current condition for %n"), str));
+
+ SendDlgItemMessage(hwndDlg, IDC_INFOICON, STM_SETICON,
+ (WPARAM)LoadSkinnedProtoIcon(WEATHERPROTONAME,
+ DBGetContactSettingWord(hContact, WEATHERPROTONAME, "StatusIcon",0)), 0);
+
+ { // bold and enlarge the current condition
+ LOGFONT lf;
+ HFONT hNormalFont=(HFONT)SendDlgItemMessage(hwndDlg,IDC_INFO2,WM_GETFONT,0,0);
+ GetObject(hNormalFont,sizeof(lf),&lf);
+ lf.lfWeight=FW_BOLD;
+ lf.lfWidth=7;
+ lf.lfHeight=15;
+ SendDlgItemMessage(hwndDlg, IDC_INFO2, WM_SETFONT, (WPARAM)CreateFontIndirect(&lf), 0);
+ }
+ // set the text for displaying other current weather conditions data
+ GetDisplay(&w, "%c %t", str);
+ SetDlgItemTextWth(hwndDlg, IDC_INFO2, str);
+ SetDlgItemTextWth(hwndDlg, IDC_INFO3, w.feel);
+ SetDlgItemTextWth(hwndDlg, IDC_INFO4, w.pressure);
+ GetDisplay(&w, "%i %w", str);
+ SetDlgItemTextWth(hwndDlg, IDC_INFO5, str);
+ SetDlgItemTextWth(hwndDlg, IDC_INFO6, w.dewpoint);
+ SetDlgItemTextWth(hwndDlg, IDC_INFO7, w.sunrise);
+ SetDlgItemTextWth(hwndDlg, IDC_INFO8, w.sunset);
+ SetDlgItemTextWth(hwndDlg, IDC_INFO9, w.high);
+ SetDlgItemTextWth(hwndDlg, IDC_INFO10, w.low);
+ GetDisplay(&w, Translate("Last update on: %u"), str);
+ SetDlgItemTextWth(hwndDlg, IDC_INFO11, str);
+ SetDlgItemTextWth(hwndDlg, IDC_INFO12, w.humid);
+ SetDlgItemTextWth(hwndDlg, IDC_INFO13, w.vis);
+ break;
+
+ case WM_DESTROY:
+ CallService(MS_SKIN2_RELEASEICON, (WPARAM)SendDlgItemMessage(hwndDlg, IDC_INFOICON, STM_SETICON, 0, 0), 0);
+ DeleteObject((HFONT)SendDlgItemMessage(hwndDlg, IDC_INFO2, WM_GETFONT, 0, 0));
+ break;
+
+ case WM_COMMAND:
+ switch(LOWORD(wParam))
+ {
+ case IDC_MOREDETAIL:
+ {
+ HWND hMoreDataDlg;
+
+ hMoreDataDlg = WindowList_Find(hDataWindowList, hContact);
+ if (hMoreDataDlg == NULL)
+ hMoreDataDlg = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_BRIEF), NULL,
+ DlgProcMoreData, (LPARAM)hContact);
+ else
+ {
+ SetForegroundWindow(hMoreDataDlg);
+ SetFocus(hMoreDataDlg);
+ }
+ ShowWindow(GetDlgItem(hMoreDataDlg, IDC_MTEXT), 0);
+ ShowWindow(GetDlgItem(hMoreDataDlg, IDC_DATALIST), 1);
+ break;
+ }
+ }
+ break;
+ }
+ return 0;
+}
+
+//============ BRIEF INFORMATION ============
+
+static int BriefDlgResizer(HWND hwnd, LPARAM lParam, UTILRESIZECONTROL *urc)
+{
+ switch(urc->wId)
+ {
+ case IDC_HEADERBAR:
+ return RD_ANCHORX_LEFT | RD_ANCHORY_TOP | RD_ANCHORX_WIDTH;
+
+ case IDC_MTEXT:
+ case IDC_DATALIST:
+ return RD_ANCHORX_LEFT | RD_ANCHORY_TOP | RD_ANCHORX_WIDTH | RD_ANCHORY_HEIGHT;
+
+ case IDC_MUPDATE:
+ return RD_ANCHORX_LEFT | RD_ANCHORY_BOTTOM;
+
+ case IDC_MTOGGLE:
+ case IDC_MWEBPAGE:
+ case IDCANCEL:
+ return RD_ANCHORX_RIGHT | RD_ANCHORY_BOTTOM;
+ }
+ return RD_ANCHORX_LEFT|RD_ANCHORY_TOP;
+}
+
+
+
+// dialog process for more data in the user info window
+// lParam = contact handle
+INT_PTR CALLBACK DlgProcMoreData(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ static const unsigned tabstops = 48;
+ HANDLE hContact = (HANDLE)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
+
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ // save the contact handle for later use
+ hContact = (HANDLE)lParam;
+ SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)hContact);
+
+ SendDlgItemMessage(hwndDlg, IDC_MTEXT, EM_AUTOURLDETECT, (WPARAM) TRUE, 0);
+ SendDlgItemMessage(hwndDlg, IDC_MTEXT, EM_SETEVENTMASK, 0, ENM_LINK);
+ SendDlgItemMessage(hwndDlg, IDC_MTEXT, EM_SETMARGINS, EC_LEFTMARGIN, 5);
+ SendDlgItemMessage(hwndDlg, IDC_MTEXT, EM_SETTABSTOPS, 1, (LPARAM)&tabstops);
+
+ // get the list to display
+ {
+ LV_COLUMN lvc = { 0 };
+ HWND hList = GetDlgItem(hwndDlg, IDC_DATALIST);
+ RECT aRect = { 0 };
+ GetClientRect(hList, &aRect);
+
+ // managing styles
+ lvc.mask = LVCF_WIDTH | LVCF_TEXT;
+ ListView_SetExtendedListViewStyleEx(hList,
+ LVS_EX_FULLROWSELECT | LVS_EX_INFOTIP,
+ LVS_EX_FULLROWSELECT | LVS_EX_INFOTIP);
+
+ // inserting columns
+ lvc.cx = LIST_COLUMN;
+ lvc.pszText = Translate("Variable");
+ ListView_InsertColumnWth(hList, 0, &lvc);
+
+ lvc.cx = aRect.right - LIST_COLUMN - GetSystemMetrics(SM_CXVSCROLL) - 3;
+ lvc.pszText = Translate("Information");
+ ListView_InsertColumnWth(hList, 1, &lvc);
+
+ // inserting data
+ SendMessage(hwndDlg, WM_UPDATEDATA, 0, 0);
+ }
+ TranslateDialogDefault(hwndDlg);
+
+ // prevent dups of the window
+ WindowList_Add(hDataWindowList, hwndDlg, hContact);
+
+ // restore window position
+ Utils_RestoreWindowPositionNoMove(hwndDlg, NULL, WEATHERPROTONAME, "BriefInfo_");
+ return TRUE;
+
+ case WM_UPDATEDATA:
+ ListView_DeleteAllItems(GetDlgItem(hwndDlg, IDC_DATALIST));
+ LoadBriefInfoText(hwndDlg, hContact);
+ DBDataManage(hContact, WDBM_DETAILDISPLAY, (WPARAM)hwndDlg, 0);
+
+ // set icons
+ {
+ WORD statusIcon = DBGetContactSettingWord(hContact, WEATHERPROTONAME, "StatusIcon", 0);
+
+ ReleaseIconEx((HICON)SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)LoadSkinnedProtoIconBig(WEATHERPROTONAME, statusIcon)));
+ ReleaseIconEx((HICON)SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)LoadSkinnedProtoIcon(WEATHERPROTONAME, statusIcon)));
+ }
+ RedrawWindow(GetDlgItem(hwndDlg, IDC_HEADERBAR), NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
+ break;
+
+ case WM_SIZE:
+ {
+ RECT rc;
+ HWND hList = GetDlgItem(hwndDlg, IDC_DATALIST);
+ GetWindowRect(hList, &rc);
+ ListView_SetColumnWidth(hList, 1, ListView_GetColumnWidth(hList, 1) +
+ (int)LOWORD(lParam) - (rc.right - rc.left));
+ }
+ {
+ UTILRESIZEDIALOG urd = {0};
+ urd.cbSize = sizeof(urd);
+ urd.hwndDlg = hwndDlg;
+ urd.hInstance = hInst;
+ urd.lpTemplate = MAKEINTRESOURCEA(IDD_BRIEF);
+ urd.pfnResizer = BriefDlgResizer;
+ CallService(MS_UTILS_RESIZEDIALOG, 0, (LPARAM)&urd);
+ }
+ break;
+
+ case WM_GETMINMAXINFO:
+ {
+ LPMINMAXINFO mmi = (LPMINMAXINFO)lParam;
+
+ // The minimum width in points
+ mmi->ptMinTrackSize.x = 350;
+ // The minimum height in points
+ mmi->ptMinTrackSize.y = 300;
+ }
+ break;
+
+ case WM_COMMAND:
+ switch(LOWORD(wParam))
+ {
+ case IDCANCEL:
+ // close the info window
+ DestroyWindow(hwndDlg);
+ break;
+
+ case IDC_MUPDATE:
+ {
+ LV_ITEM lvi = {0};
+ HWND hList = GetDlgItem(hwndDlg, IDC_DATALIST);
+
+ // update current data
+ // set the text to "updating"
+ SetDlgItemTextWth(hwndDlg, IDC_MTEXT, Translate("Retrieving new data, please wait..."));
+ ListView_DeleteAllItems(hList);
+ lvi.mask = LVIF_TEXT | LVIF_PARAM;
+ lvi.lParam = 1;
+ lvi.pszText = (LPSTR)"";
+ lvi.iItem = ListView_InsertItemWth(hList, &lvi);
+ lvi.pszText = Translate("Retrieving new data, please wait...");
+ ListView_SetItemTextWth(hList, lvi.iItem, 1, lvi.pszText);
+ UpdateSingleStation((WPARAM)hContact, 0);
+ break;
+ }
+
+ case IDC_MWEBPAGE:
+ LoadForecast((WPARAM)hContact, 0); // read complete forecast
+ break;
+
+ case IDC_MTOGGLE:
+ if (IsWindowVisible(GetDlgItem(hwndDlg,IDC_DATALIST)))
+ SetDlgItemTextWth(hwndDlg, IDC_MTOGGLE, Translate("More Info"));
+ else
+ SetDlgItemTextWth(hwndDlg, IDC_MTOGGLE, Translate("Brief Info"));
+ ShowWindow(GetDlgItem(hwndDlg,IDC_DATALIST), (int)!IsWindowVisible(
+ GetDlgItem(hwndDlg,IDC_DATALIST)));
+ ShowWindow(GetDlgItem(hwndDlg,IDC_MTEXT), (int)!IsWindowVisible(GetDlgItem(hwndDlg,IDC_MTEXT)));
+ break;
+ }
+ break;
+
+ case WM_NOTIFY:
+ {
+ LPNMHDR pNmhdr = (LPNMHDR)lParam;
+ if (pNmhdr->idFrom == IDC_MTEXT && pNmhdr->code == EN_LINK)
+ {
+ ENLINK *enlink = (ENLINK *) lParam;
+ TEXTRANGE tr;
+ switch (enlink->msg)
+ {
+ case WM_LBUTTONUP:
+ tr.chrg = enlink->chrg;
+ tr.lpstrText = mir_alloc(tr.chrg.cpMax - tr.chrg.cpMin + 8);
+ SendMessage(pNmhdr->hwndFrom, EM_GETTEXTRANGE, 0, (LPARAM)&tr);
+ CallService(MS_UTILS_OPENURL, 1, (LPARAM) tr.lpstrText);
+ mir_free(tr.lpstrText);
+ break;
+ }
+ }
+ break;
+ }
+
+ case WM_CLOSE:
+ DestroyWindow(hwndDlg);
+ break;
+
+ case WM_DESTROY:
+ ReleaseIconEx((HICON)SendMessage(hwndDlg, WM_SETICON, ICON_BIG, 0));
+ ReleaseIconEx((HICON)SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, 0));
+
+ Utils_SaveWindowPosition(hwndDlg, NULL, WEATHERPROTONAME, "BriefInfo_");
+ WindowList_Remove(hDataWindowList, hwndDlg);
+ break;
+ }
+
+ return FALSE;
+}
+
+// set the title of the dialog and on the which rectangle
+// also load brief info into message box
+void LoadBriefInfoText(HWND hwndDlg, HANDLE hContact)
+{
+ WEATHERINFO winfo;
+ char str[4096], str2[4096];
+
+ // load weather information from the contact into the WEATHERINFO struct
+ winfo = LoadWeatherInfo(hContact);
+ // check if data exist. If not, display error message box
+ if (!(BOOL)DBGetContactSettingByte(hContact, WEATHERPROTONAME, "IsUpdated", FALSE))
+ {
+ FixStr(Translate("No information available.\nPlease update weather condition first."), str);
+ }
+ else
+ // set the display text and show the message box
+ GetDisplay(&winfo, opt.bText, str);
+
+ if (lpcp != CP_ACP)
+ {
+ SETTEXTEX textex;
+ textex.flags = ST_DEFAULT;
+ textex.codepage = lpcp;
+
+ SendMessage(GetDlgItem(hwndDlg, IDC_MTEXT), EM_SETTEXTEX, (WPARAM)&textex, (LPARAM)str);
+ }
+ else
+ SetDlgItemText(hwndDlg, IDC_MTEXT, str);
+
+ GetDisplay(&winfo, opt.bTitle, str);
+ SetWindowTextWth(hwndDlg, str);
+ GetDisplay(&winfo, "%c, %t", str);
+ mir_snprintf(str2, SIZEOF(str2), "%s\n%s", winfo.city, str);
+ SetDlgItemTextWth(hwndDlg, IDC_HEADERBAR, str2);
+}
+
+// show brief information dialog
+// wParam = current contact
+int BriefInfo(WPARAM wParam, LPARAM lParam)
+{
+ // make sure that the contact is actually a weather one
+ if(IsMyContact((HANDLE)wParam))
+ {
+ HWND hMoreDataDlg = WindowList_Find(hDataWindowList,(HANDLE)wParam);
+ if (hMoreDataDlg != NULL)
+ {
+ SetForegroundWindow(hMoreDataDlg);
+ SetFocus(hMoreDataDlg);
+ }
+ else
+ {
+ hMoreDataDlg = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_BRIEF), NULL, DlgProcMoreData,
+ (LPARAM)wParam);
+ }
+ ShowWindow(GetDlgItem(hMoreDataDlg, IDC_DATALIST), 0);
+ ShowWindow(GetDlgItem(hMoreDataDlg, IDC_MTEXT), 1);
+ SetDlgItemTextWth(hMoreDataDlg, IDC_MTOGGLE, Translate("More Info"));
+ return 1;
+ }
+ return 0;
+}
+
+INT_PTR BriefInfoSvc(WPARAM wParam, LPARAM lParam)
+{
+ return BriefInfo(wParam, lParam);
+}