From 725f68b6808a8a30778f58223fac75386f082785 Mon Sep 17 00:00:00 2001 From: Kirill Volinsky Date: Fri, 18 May 2012 22:10:43 +0000 Subject: plugins folders renaming git-svn-id: http://svn.miranda-ng.org/main/trunk@61 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/Weather/langpack_defweather.txt | 126 +++ protocols/Weather/license.txt | 340 ++++++++ protocols/Weather/mingw-comp.bat | 2 + protocols/Weather/proto_weather/mingw-comp.bat | 2 + protocols/Weather/proto_weather/proto_weather.dsp | 118 +++ .../Weather/proto_weather/proto_weather.vcproj | 173 ++++ .../Weather/proto_weather/proto_weather_10.vcxproj | 223 +++++ .../proto_weather/proto_weather_10.vcxproj.filters | 59 ++ .../Weather/proto_weather/proto_weather_8.vcproj | 254 ++++++ .../Weather/proto_weather/proto_weather_9.vcproj | 413 +++++++++ protocols/Weather/proto_weather/resource.h | 26 + protocols/Weather/proto_weather/resource.rc | 41 + protocols/Weather/proto_weather/wicons/Cloud.ico | Bin 0 -> 6830 bytes protocols/Weather/proto_weather/wicons/FOG.ico | Bin 0 -> 6830 bytes protocols/Weather/proto_weather/wicons/LIGHT.ICO | Bin 0 -> 6830 bytes protocols/Weather/proto_weather/wicons/NA.ico | Bin 0 -> 6830 bytes protocols/Weather/proto_weather/wicons/PCLOUDY.ico | Bin 0 -> 6830 bytes protocols/Weather/proto_weather/wicons/RAIN.ico | Bin 0 -> 6830 bytes protocols/Weather/proto_weather/wicons/RSHOWER.ico | Bin 0 -> 6830 bytes protocols/Weather/proto_weather/wicons/SNOW.ICO | Bin 0 -> 6830 bytes protocols/Weather/proto_weather/wicons/SSHOWER.ico | Bin 0 -> 6830 bytes protocols/Weather/proto_weather/wicons/SUN.ICO | Bin 0 -> 6830 bytes protocols/Weather/res/brief.ico | Bin 0 -> 2550 bytes protocols/Weather/res/disabled.ico | Bin 0 -> 2550 bytes protocols/Weather/res/edit.ico | Bin 0 -> 2550 bytes protocols/Weather/res/icon.ico | Bin 0 -> 6830 bytes protocols/Weather/res/info.ico | Bin 0 -> 2550 bytes protocols/Weather/res/infologo.ico | Bin 0 -> 2238 bytes protocols/Weather/res/log.ico | Bin 0 -> 2550 bytes protocols/Weather/res/map.ico | Bin 0 -> 2550 bytes protocols/Weather/res/more.ico | Bin 0 -> 2550 bytes protocols/Weather/res/popup.ico | Bin 0 -> 2550 bytes protocols/Weather/res/popup_no.ico | Bin 0 -> 2550 bytes protocols/Weather/res/reload.ico | Bin 0 -> 2550 bytes protocols/Weather/res/update.ico | Bin 0 -> 2550 bytes protocols/Weather/res/update2.ico | Bin 0 -> 2550 bytes protocols/Weather/resource.h | 176 ++++ protocols/Weather/resource.rc | 467 +++++++++++ protocols/Weather/sample_ini.ini | 421 ++++++++++ protocols/Weather/version.h | 6 + protocols/Weather/weather-history.txt | 930 +++++++++++++++++++++ protocols/Weather/weather-readme.html | 230 +++++ protocols/Weather/weather-translation.txt | 798 ++++++++++++++++++ protocols/Weather/weather.cpp | 307 +++++++ protocols/Weather/weather.h | 548 ++++++++++++ protocols/Weather/weather_10.sln | 36 + protocols/Weather/weather_10.vcxproj | 251 ++++++ protocols/Weather/weather_10.vcxproj.filters | 136 +++ protocols/Weather/weather_addstn.cpp | 438 ++++++++++ protocols/Weather/weather_contacts.cpp | 515 ++++++++++++ protocols/Weather/weather_conv.cpp | 838 +++++++++++++++++++ protocols/Weather/weather_data.cpp | 500 +++++++++++ protocols/Weather/weather_http.cpp | 226 +++++ protocols/Weather/weather_icons.cpp | 90 ++ protocols/Weather/weather_info.cpp | 253 ++++++ protocols/Weather/weather_ini.cpp | 628 ++++++++++++++ protocols/Weather/weather_mwin.cpp | 449 ++++++++++ protocols/Weather/weather_opt.cpp | 660 +++++++++++++++ protocols/Weather/weather_popup.cpp | 454 ++++++++++ protocols/Weather/weather_svcs.cpp | 452 ++++++++++ protocols/Weather/weather_update.cpp | 678 +++++++++++++++ protocols/Weather/weather_userinfo.cpp | 418 +++++++++ 62 files changed, 12682 insertions(+) create mode 100644 protocols/Weather/langpack_defweather.txt create mode 100644 protocols/Weather/license.txt create mode 100644 protocols/Weather/mingw-comp.bat create mode 100644 protocols/Weather/proto_weather/mingw-comp.bat create mode 100644 protocols/Weather/proto_weather/proto_weather.dsp create mode 100644 protocols/Weather/proto_weather/proto_weather.vcproj create mode 100644 protocols/Weather/proto_weather/proto_weather_10.vcxproj create mode 100644 protocols/Weather/proto_weather/proto_weather_10.vcxproj.filters create mode 100644 protocols/Weather/proto_weather/proto_weather_8.vcproj create mode 100644 protocols/Weather/proto_weather/proto_weather_9.vcproj create mode 100644 protocols/Weather/proto_weather/resource.h create mode 100644 protocols/Weather/proto_weather/resource.rc create mode 100644 protocols/Weather/proto_weather/wicons/Cloud.ico create mode 100644 protocols/Weather/proto_weather/wicons/FOG.ico create mode 100644 protocols/Weather/proto_weather/wicons/LIGHT.ICO create mode 100644 protocols/Weather/proto_weather/wicons/NA.ico create mode 100644 protocols/Weather/proto_weather/wicons/PCLOUDY.ico create mode 100644 protocols/Weather/proto_weather/wicons/RAIN.ico create mode 100644 protocols/Weather/proto_weather/wicons/RSHOWER.ico create mode 100644 protocols/Weather/proto_weather/wicons/SNOW.ICO create mode 100644 protocols/Weather/proto_weather/wicons/SSHOWER.ico create mode 100644 protocols/Weather/proto_weather/wicons/SUN.ICO create mode 100644 protocols/Weather/res/brief.ico create mode 100644 protocols/Weather/res/disabled.ico create mode 100644 protocols/Weather/res/edit.ico create mode 100644 protocols/Weather/res/icon.ico create mode 100644 protocols/Weather/res/info.ico create mode 100644 protocols/Weather/res/infologo.ico create mode 100644 protocols/Weather/res/log.ico create mode 100644 protocols/Weather/res/map.ico create mode 100644 protocols/Weather/res/more.ico create mode 100644 protocols/Weather/res/popup.ico create mode 100644 protocols/Weather/res/popup_no.ico create mode 100644 protocols/Weather/res/reload.ico create mode 100644 protocols/Weather/res/update.ico create mode 100644 protocols/Weather/res/update2.ico create mode 100644 protocols/Weather/resource.h create mode 100644 protocols/Weather/resource.rc create mode 100644 protocols/Weather/sample_ini.ini create mode 100644 protocols/Weather/version.h create mode 100644 protocols/Weather/weather-history.txt create mode 100644 protocols/Weather/weather-readme.html create mode 100644 protocols/Weather/weather-translation.txt create mode 100644 protocols/Weather/weather.cpp create mode 100644 protocols/Weather/weather.h create mode 100644 protocols/Weather/weather_10.sln create mode 100644 protocols/Weather/weather_10.vcxproj create mode 100644 protocols/Weather/weather_10.vcxproj.filters create mode 100644 protocols/Weather/weather_addstn.cpp create mode 100644 protocols/Weather/weather_contacts.cpp create mode 100644 protocols/Weather/weather_conv.cpp create mode 100644 protocols/Weather/weather_data.cpp create mode 100644 protocols/Weather/weather_http.cpp create mode 100644 protocols/Weather/weather_icons.cpp create mode 100644 protocols/Weather/weather_info.cpp create mode 100644 protocols/Weather/weather_ini.cpp create mode 100644 protocols/Weather/weather_mwin.cpp create mode 100644 protocols/Weather/weather_opt.cpp create mode 100644 protocols/Weather/weather_popup.cpp create mode 100644 protocols/Weather/weather_svcs.cpp create mode 100644 protocols/Weather/weather_update.cpp create mode 100644 protocols/Weather/weather_userinfo.cpp (limited to 'protocols/Weather') diff --git a/protocols/Weather/langpack_defweather.txt b/protocols/Weather/langpack_defweather.txt new file mode 100644 index 0000000000..211c2451da --- /dev/null +++ b/protocols/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 #] +; 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/protocols/Weather/license.txt b/protocols/Weather/license.txt new file mode 100644 index 0000000000..45645b4b53 --- /dev/null +++ b/protocols/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. + + + Copyright (C) + + 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. + + , 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/protocols/Weather/mingw-comp.bat b/protocols/Weather/mingw-comp.bat new file mode 100644 index 0000000000..7c88825ecd --- /dev/null +++ b/protocols/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/protocols/Weather/proto_weather/mingw-comp.bat b/protocols/Weather/proto_weather/mingw-comp.bat new file mode 100644 index 0000000000..167ee1786a --- /dev/null +++ b/protocols/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/protocols/Weather/proto_weather/proto_weather.dsp b/protocols/Weather/proto_weather/proto_weather.dsp new file mode 100644 index 0000000000..9c4e9e5075 --- /dev/null +++ b/protocols/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/protocols/Weather/proto_weather/proto_weather.vcproj b/protocols/Weather/proto_weather/proto_weather.vcproj new file mode 100644 index 0000000000..73395dc20c --- /dev/null +++ b/protocols/Weather/proto_weather/proto_weather.vcproj @@ -0,0 +1,173 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/protocols/Weather/proto_weather/proto_weather_10.vcxproj b/protocols/Weather/proto_weather/proto_weather_10.vcxproj new file mode 100644 index 0000000000..408b20b82a --- /dev/null +++ b/protocols/Weather/proto_weather/proto_weather_10.vcxproj @@ -0,0 +1,223 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + Proto_Weather + {B2F4BA6C-1BD6-4A50-A706-DCBC6A5D439B} + proto_weather + Win32Proj + + + + DynamicLibrary + MultiByte + + + DynamicLibrary + NotSet + + + DynamicLibrary + MultiByte + + + DynamicLibrary + NotSet + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(Configuration)\ + $(Configuration)\Obj\ + true + $(Configuration)\ + $(Configuration)\Obj\ + true + $(Configuration)64\ + $(Configuration)64\Obj\ + true + false + $(Configuration)64\ + $(Configuration)64\Obj\ + true + false + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;PROTO_WEATHER_EXPORTS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + + + Level3 + EditAndContinue + + + false + + + true + + + Windows + true + false + + + + + MachineX86 + + + + + WIN32;NDEBUG;_WINDOWS;_USRDLL;PROTO_WEATHER_EXPORTS;%(PreprocessorDefinitions) + MultiThreaded + + + Level3 + ProgramDatabase + + + true + Windows + true + true + true + false + + + + + MachineX86 + + + + + X64 + + + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;PROTO_WEATHER_EXPORTS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + + + Level3 + ProgramDatabase + + + false + + + true + true + $(OutDir)proto_weather.pdb + true + true + true + false + MachineX64 + + + + + X64 + + + WIN32;NDEBUG;_WINDOWS;_USRDLL;PROTO_WEATHER_EXPORTS;%(PreprocessorDefinitions) + MultiThreaded + + + Level3 + ProgramDatabase + + + true + false + Windows + true + true + true + false + + + + + MachineX64 + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/protocols/Weather/proto_weather/proto_weather_10.vcxproj.filters b/protocols/Weather/proto_weather/proto_weather_10.vcxproj.filters new file mode 100644 index 0000000000..a94cf28821 --- /dev/null +++ b/protocols/Weather/proto_weather/proto_weather_10.vcxproj.filters @@ -0,0 +1,59 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx + + + + + Header Files + + + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + + + Resource Files + + + \ No newline at end of file diff --git a/protocols/Weather/proto_weather/proto_weather_8.vcproj b/protocols/Weather/proto_weather/proto_weather_8.vcproj new file mode 100644 index 0000000000..72fb5f964c --- /dev/null +++ b/protocols/Weather/proto_weather/proto_weather_8.vcproj @@ -0,0 +1,254 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/protocols/Weather/proto_weather/proto_weather_9.vcproj b/protocols/Weather/proto_weather/proto_weather_9.vcproj new file mode 100644 index 0000000000..4ddb33d5a1 --- /dev/null +++ b/protocols/Weather/proto_weather/proto_weather_9.vcproj @@ -0,0 +1,413 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/protocols/Weather/proto_weather/resource.h b/protocols/Weather/proto_weather/resource.h new file mode 100644 index 0000000000..0ac64a0f1c --- /dev/null +++ b/protocols/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/protocols/Weather/proto_weather/resource.rc b/protocols/Weather/proto_weather/resource.rc new file mode 100644 index 0000000000..930886b96f --- /dev/null +++ b/protocols/Weather/proto_weather/resource.rc @@ -0,0 +1,41 @@ +//Microsoft Developer Studio generated resource script. +// + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "winres.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 + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +104 ICON DISCARDABLE "wicons\\SUN.ico" +105 ICON DISCARDABLE "wicons\\NA.ico" +128 ICON DISCARDABLE "wicons\\PCLOUDY.ico" +129 ICON DISCARDABLE "wicons\\RSHOWER.ico" +130 ICON DISCARDABLE "wicons\\LIGHT.ico" +131 ICON DISCARDABLE "wicons\\RAIN.ico" +158 ICON DISCARDABLE "wicons\\SNOW.ico" +159 ICON DISCARDABLE "wicons\\CLOUD.ico" +1002 ICON DISCARDABLE "wicons\\SSHOWER.ico" +1003 ICON DISCARDABLE "wicons\\FOG.ico" + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/protocols/Weather/proto_weather/wicons/Cloud.ico b/protocols/Weather/proto_weather/wicons/Cloud.ico new file mode 100644 index 0000000000..2edb539dcb Binary files /dev/null and b/protocols/Weather/proto_weather/wicons/Cloud.ico differ diff --git a/protocols/Weather/proto_weather/wicons/FOG.ico b/protocols/Weather/proto_weather/wicons/FOG.ico new file mode 100644 index 0000000000..fbd81b9a03 Binary files /dev/null and b/protocols/Weather/proto_weather/wicons/FOG.ico differ diff --git a/protocols/Weather/proto_weather/wicons/LIGHT.ICO b/protocols/Weather/proto_weather/wicons/LIGHT.ICO new file mode 100644 index 0000000000..d266094fbe Binary files /dev/null and b/protocols/Weather/proto_weather/wicons/LIGHT.ICO differ diff --git a/protocols/Weather/proto_weather/wicons/NA.ico b/protocols/Weather/proto_weather/wicons/NA.ico new file mode 100644 index 0000000000..3e4a3aa324 Binary files /dev/null and b/protocols/Weather/proto_weather/wicons/NA.ico differ diff --git a/protocols/Weather/proto_weather/wicons/PCLOUDY.ico b/protocols/Weather/proto_weather/wicons/PCLOUDY.ico new file mode 100644 index 0000000000..be3d0c88bd Binary files /dev/null and b/protocols/Weather/proto_weather/wicons/PCLOUDY.ico differ diff --git a/protocols/Weather/proto_weather/wicons/RAIN.ico b/protocols/Weather/proto_weather/wicons/RAIN.ico new file mode 100644 index 0000000000..4b65fb6714 Binary files /dev/null and b/protocols/Weather/proto_weather/wicons/RAIN.ico differ diff --git a/protocols/Weather/proto_weather/wicons/RSHOWER.ico b/protocols/Weather/proto_weather/wicons/RSHOWER.ico new file mode 100644 index 0000000000..442552e155 Binary files /dev/null and b/protocols/Weather/proto_weather/wicons/RSHOWER.ico differ diff --git a/protocols/Weather/proto_weather/wicons/SNOW.ICO b/protocols/Weather/proto_weather/wicons/SNOW.ICO new file mode 100644 index 0000000000..1a482c3bc8 Binary files /dev/null and b/protocols/Weather/proto_weather/wicons/SNOW.ICO differ diff --git a/protocols/Weather/proto_weather/wicons/SSHOWER.ico b/protocols/Weather/proto_weather/wicons/SSHOWER.ico new file mode 100644 index 0000000000..0bd2264413 Binary files /dev/null and b/protocols/Weather/proto_weather/wicons/SSHOWER.ico differ diff --git a/protocols/Weather/proto_weather/wicons/SUN.ICO b/protocols/Weather/proto_weather/wicons/SUN.ICO new file mode 100644 index 0000000000..b37fc6ad2a Binary files /dev/null and b/protocols/Weather/proto_weather/wicons/SUN.ICO differ diff --git a/protocols/Weather/res/brief.ico b/protocols/Weather/res/brief.ico new file mode 100644 index 0000000000..717ef66669 Binary files /dev/null and b/protocols/Weather/res/brief.ico differ diff --git a/protocols/Weather/res/disabled.ico b/protocols/Weather/res/disabled.ico new file mode 100644 index 0000000000..ed6e27b691 Binary files /dev/null and b/protocols/Weather/res/disabled.ico differ diff --git a/protocols/Weather/res/edit.ico b/protocols/Weather/res/edit.ico new file mode 100644 index 0000000000..f59dc79b9c Binary files /dev/null and b/protocols/Weather/res/edit.ico differ diff --git a/protocols/Weather/res/icon.ico b/protocols/Weather/res/icon.ico new file mode 100644 index 0000000000..be3d0c88bd Binary files /dev/null and b/protocols/Weather/res/icon.ico differ diff --git a/protocols/Weather/res/info.ico b/protocols/Weather/res/info.ico new file mode 100644 index 0000000000..97d34dc4a5 Binary files /dev/null and b/protocols/Weather/res/info.ico differ diff --git a/protocols/Weather/res/infologo.ico b/protocols/Weather/res/infologo.ico new file mode 100644 index 0000000000..cf22ece1b1 Binary files /dev/null and b/protocols/Weather/res/infologo.ico differ diff --git a/protocols/Weather/res/log.ico b/protocols/Weather/res/log.ico new file mode 100644 index 0000000000..86139d5e23 Binary files /dev/null and b/protocols/Weather/res/log.ico differ diff --git a/protocols/Weather/res/map.ico b/protocols/Weather/res/map.ico new file mode 100644 index 0000000000..8c4c70742d Binary files /dev/null and b/protocols/Weather/res/map.ico differ diff --git a/protocols/Weather/res/more.ico b/protocols/Weather/res/more.ico new file mode 100644 index 0000000000..47e13df383 Binary files /dev/null and b/protocols/Weather/res/more.ico differ diff --git a/protocols/Weather/res/popup.ico b/protocols/Weather/res/popup.ico new file mode 100644 index 0000000000..7e0301b42f Binary files /dev/null and b/protocols/Weather/res/popup.ico differ diff --git a/protocols/Weather/res/popup_no.ico b/protocols/Weather/res/popup_no.ico new file mode 100644 index 0000000000..08de082ec2 Binary files /dev/null and b/protocols/Weather/res/popup_no.ico differ diff --git a/protocols/Weather/res/reload.ico b/protocols/Weather/res/reload.ico new file mode 100644 index 0000000000..3c81203c03 Binary files /dev/null and b/protocols/Weather/res/reload.ico differ diff --git a/protocols/Weather/res/update.ico b/protocols/Weather/res/update.ico new file mode 100644 index 0000000000..ccc4d4611d Binary files /dev/null and b/protocols/Weather/res/update.ico differ diff --git a/protocols/Weather/res/update2.ico b/protocols/Weather/res/update2.ico new file mode 100644 index 0000000000..f71be51ee2 Binary files /dev/null and b/protocols/Weather/res/update2.ico differ diff --git a/protocols/Weather/resource.h b/protocols/Weather/resource.h new file mode 100644 index 0000000000..e88e4c19de --- /dev/null +++ b/protocols/Weather/resource.h @@ -0,0 +1,176 @@ +//{{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 IDC_E1 2128 +#define IDC_E2 2129 +#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/protocols/Weather/resource.rc b/protocols/Weather/resource.rc new file mode 100644 index 0000000000..79854b8c84 --- /dev/null +++ b/protocols/Weather/resource.rc @@ -0,0 +1,467 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include +#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, 222 +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,43,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,80,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 + LTEXT "Elevation",IDC_STATIC,8,163,53,8 + CONTROL "ft",IDC_E1,"Button",BS_AUTORADIOBUTTON,65,163,34,8 + CONTROL "m",IDC_E2,"Button",BS_AUTORADIOBUTTON,120,163,34,8 + CONTROL "Do not append units to values",IDC_DONOTAPPUNITS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,174,144,8 + CONTROL "Do not display fractional values",IDC_NOFRAC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,155,174,146,8 + GROUPBOX "Frame",IDC_STATIC,3,187,300,29 + EDITTEXT IDC_AVATARSIZE,11,197,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,197,11,14 + LTEXT "Avatar size",IDC_STATIC,42,200,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,77,9,WS_EX_WINDOWEDGE | WS_EX_NOACTIVATE | 0x10000000L + EDITTEXT IDC_CTEXT,80,8,124,12,ES_AUTOHSCROLL + CONTROL "Brief Info Title",IDC_TM2,"MButtonClass",WS_TABSTOP,2,41,77,9,WS_EX_WINDOWEDGE | WS_EX_NOACTIVATE | 0x10000000L + EDITTEXT IDC_BTITLE,80,40,124,12,ES_AUTOHSCROLL + CONTROL "Brief Info",IDC_TM3,"MButtonClass",WS_TABSTOP,2,55,77,9,WS_EX_WINDOWEDGE | WS_EX_NOACTIVATE | 0x10000000L + EDITTEXT IDC_BTEXT,80,54,124,44,ES_MULTILINE | ES_AUTOVSCROLL | ES_WANTRETURN | WS_VSCROLL + CONTROL "Note Text",IDC_TM4,"MButtonClass",WS_TABSTOP,2,101,77,9,WS_EX_WINDOWEDGE | WS_EX_NOACTIVATE | 0x10000000L + EDITTEXT IDC_NTEXT,80,100,124,44,ES_MULTILINE | ES_AUTOVSCROLL | ES_WANTRETURN | WS_VSCROLL + CONTROL "Extra Text",IDC_TM5,"MButtonClass",WS_TABSTOP,2,147,77,9,WS_EX_WINDOWEDGE | WS_EX_NOACTIVATE | 0x10000000L + EDITTEXT IDC_XTEXT,80,146,124,44,ES_MULTILINE | ES_AUTOVSCROLL | ES_WANTRETURN | WS_VSCROLL + CONTROL "External Log",IDC_TM6,"MButtonClass",WS_TABSTOP,2,193,77,9,WS_EX_WINDOWEDGE | WS_EX_NOACTIVATE | 0x10000000L + EDITTEXT IDC_ETEXT,80,192,124,12,ES_AUTOHSCROLL + CONTROL "History Log",IDC_TM7,"MButtonClass",WS_TABSTOP,2,208,77,9,WS_EX_WINDOWEDGE | WS_EX_NOACTIVATE | 0x10000000L + EDITTEXT IDC_HTEXT,80,207,124,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,80,24,124,12,ES_AUTOHSCROLL + CONTROL "Status Message",IDC_TM8,"MButtonClass",WS_TABSTOP | 0x100,2,25,77,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 \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/protocols/Weather/sample_ini.ini b/protocols/Weather/sample_ini.ini new file mode 100644 index 0000000000..dc36eda754 --- /dev/null +++ b/protocols/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: +; symbols example:   +; 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 +; "Partly   Cloudy +; The code to give "Partly Cloudy" (without quotation): +; [Condition] +; Start= +; End= + +; 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: +; 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/protocols/Weather/version.h b/protocols/Weather/version.h new file mode 100644 index 0000000000..133e5f0818 --- /dev/null +++ b/protocols/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/protocols/Weather/weather-history.txt b/protocols/Weather/weather-history.txt new file mode 100644 index 0000000000..ff936f56f2 --- /dev/null +++ b/protocols/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 - + +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/protocols/Weather/weather-readme.html b/protocols/Weather/weather-readme.html new file mode 100644 index 0000000000..ff81561171 --- /dev/null +++ b/protocols/Weather/weather-readme.html @@ -0,0 +1,230 @@ + + + + Read Me for Weather Protocol + + + +

Read Me for Weather Protocol

+
+
+
+*** IMPORTANT NOTICE ***
+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.
+
+
+
+
+
+
+File Content
+
+Features
+Files Included
+System Requirement
+Installation
+Frequently Asked Questions
+License
+
+
+
+
+
+Features
+
+ - 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.
+
+
+Files Included
+
+ - plugins\weather.dll
+    The core to the weather plugin.  Required component
+ - langpack_defweather.txt  (stored in the documentation folder by default)
+    Langpack for weather icon assignment, containing documentation for how to use
+ - plugins\weather-doc\weather-readme.html
+    Documentation and FAQ for Weather Protocol (this file).
+ - plugins\weather-doc\sample_ini.ini
+    Documentation of the format of the weather INI file.
+ - plugins\weather-doc\weather-translation.txt
+    A file that contains a translation of hopefully all string used in Weather Protocol.
+
+
+System Requirement
+
+ - Miranda IM  (v0.7.3.0 or later)
+ - Weather INI file
+ - Weather icons (Optional)
+     Numerous choices available in icon downloads.
+ - YAPP plugin by sje or PopUp Plus plugin by nullbie (Optional)
+
+
+Installation
+ 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.
+
+
+Frequently Asked Question
+
+Setting Up Weather Protocol
+For installation, follow the steps describe in the installation section of the readme.
+
+Q1-1. Weather Protocol does not do anything after I installed it, and it
+      cannot go online.
+A. You need to add a new station before you can go online.
+
+Q1-2. How do I add new stations?
+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.
+
+Q1-3. I can't find my station! Any help?
+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 here.
+
+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.
+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 nightly builds 
+   (Note: They are experimental builds!)
+   Also, if you are using traffic counter plugin, 
+   please make sure that you are using the latest version. The old version stops Weather 
+   and some other plugin from working.
+
+INI and Development Related Questions
+
+Q2-1. What are those INI files for?
+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 here.
+
+Q2-2. Can I install or modify the INI files without restarting Miranda?
+A. Yes, choose: M (main menu) -> Weather -> Reload Weather Data
+
+Q2-3. I want to retrieve weather information from a different source than those
+      that are currently available.  How can this be done?
+A. You can write your own INI file.  For more information, click here.
+
+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?
+A. You can use translation string for assigning icons. For more information, click here.
+
+Q2-5. How does weather assign status icons for each status?
+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
+
+Obtaining Weather Data
+
+Q3-1. Does weather protocol retreve weather forecasts?
+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.
+
+Q3-2. How long should the time between update be?
+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.
+
+Q3-3. How can I temporary disable weather procotol?
+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.
+
+Q3-4. Why are the name of some weather contacts italic on my contact?
+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.
+
+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?
+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.
+
+Customizing the Weather Protocol
+
+Q4-1. Can I hide Weather from status bar and protocol menu?
+A. Go to Options->Plugins->Weather, enable "Hide Weather in status bar and status menu".
+
+Q4-2. I can't find Weather in the icon option drop-down list.  How can I change
+      weather icons?
+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.
+
+Q4-3. I can't find the options for changing display text.
+A. Go to Options->Plugins->Weather, then click on the icon beside "Change display texts"
+
+Q4-4. How can I change the display name of my city?
+A. Right-click on the city and select "Edit Settings".  Change the field "City name"
+   to the new display name.
+
+Q4-5. How can I change the default station?
+A. Use the Edit Settings dialog (See A4-4).  Note that only 1 station can be default.
+
+Q4-6. What is the %[..] variable for?
+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 Database Editor or refer to the readme of the ini file.
+
+Q4-7. What are the "Extra Text" for?
+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.
+
+Q4-8. I want weather protocol to have the same status as the other protocols.
+      Is such option available?
+A. 
+Disable the option "Use weather condition as protocol status", then you will be
+   able to change the status freely.
+
+Q4-9. How do I create avatars for each weather condition?
+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
+
+
+License 
+
+This plugin is released under GPL.
+
+ + diff --git a/protocols/Weather/weather-translation.txt b/protocols/Weather/weather-translation.txt new file mode 100644 index 0000000000..72a74ea9f8 --- /dev/null +++ b/protocols/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 ------ +[] + + +************************************************************************************* +********************************** 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 +[] +[] + +; ------ weather_contacts.c ------ +[All update data has been reloaded.] + +; ------ weather_ini.c ------ +; crash preventions +[Error when obtaining data: %s] +[] + + +************************************************************************************* +********************************** 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 ------ +[] + +; ------ 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/protocols/Weather/weather.cpp b/protocols/Weather/weather.cpp new file mode 100644 index 0000000000..e4e5ee88d6 --- /dev/null +++ b/protocols/Weather/weather.cpp @@ -0,0 +1,307 @@ +/* +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 . +*/ + +/* +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; + +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 Mataes Release", +#else + "Weather Protocol Mataes Release", +#endif + __VERSION_DWORD, + "Retrieve weather information and display them in your contact list. Mod for Mataes Pack.", + 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 +}; + +extern "C" __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}; +extern "C" __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 +extern "C" 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; +} + +extern "C" 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 = PROTOCOLDESCRIPTOR_V3_SIZE; + 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/protocols/Weather/weather.h b/protocols/Weather/weather.h new file mode 100644 index 0000000000..46c5ec6bae --- /dev/null +++ b/protocols/Weather/weather.h @@ -0,0 +1,548 @@ +/* +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 . +*/ + +/* This file contains the includes, weather constants/declarations, + the structs, and the primitives for some of the functions. +*/ + +//============ THE INCLUDES =========== +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#define MIRANDA_VER 0x0A00 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "m_cluiframes.h" + +#include + +#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 "%n" +#define N_DEFAULT "" +#define B_DEFAULT "Max/Min: %[Max]/%[Min]\r\nCondition: %[Condition]\r\nTemperature: %[Temperature]\r\nPressure: %[Pressure] (%[Pressure Change])\r\nWind: %[Wind Direction], %[Wind Speed]\r\nHumidity: %[Humidity]\r\nVisibility: %[Visibility]\r\nDew Point: %[Dewpoint]\r\nUV Index: %[UV Index]\r\nMoon: %[Moon]\r\nCoordinates: Latitude: %[Latitude] Longitude: %[Longitude]\r\n\r\nSunrise: %[Sunrise]\r\nSunset: %[Sunset]\r\nDay Length: %[Day Length]\r\n\r\n5 Days Forecast:\r\n%[Forecast Day 1]\r\n%[Forecast Day 2]\r\n%[Forecast Day 3]\r\n%[Forecast Day 4]\r\n%[Forecast Day 5]" +#define b_DEFAULT "Weather Condition for %n as of %u" +#define X_DEFAULT N_DEFAULT +#define H_DEFAULT "" +#define E_DEFAULT "" +#define P_DEFAULT "Weather Condition for %n as of %u" +#define p_DEFAULT "Condition: %[Condition]\r\nTemperature: %[Temperature]\r\nPressure: %[Pressure] (%[Pressure Change])\r\nWind: %[Wind Direction], %[Wind Speed]\r\nHumidity: %[Humidity]\r\nVisibility: %[Visibility]\r\nUV Index: %[UV Index]" +#define s_DEFAULT "Temperature: %[Temperature]" + + +//============ 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; + WORD eUnit; + 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); +void GetElev(char *tempchar, char *unit, char *str); + +WORD GetIcon(const char* cond, WIDATA *Data); +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/protocols/Weather/weather_10.sln b/protocols/Weather/weather_10.sln new file mode 100644 index 0000000000..d9a98c21a2 --- /dev/null +++ b/protocols/Weather/weather_10.sln @@ -0,0 +1,36 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Weather", "weather_10.vcxproj", "{6BFE3E13-BD5D-4C1C-BB29-A82FB51A16CE}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Proto_Weather", "proto_weather\proto_weather_10.vcxproj", "{B2F4BA6C-1BD6-4A50-A706-DCBC6A5D439B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6BFE3E13-BD5D-4C1C-BB29-A82FB51A16CE}.Debug|Win32.ActiveCfg = Debug|Win32 + {6BFE3E13-BD5D-4C1C-BB29-A82FB51A16CE}.Debug|Win32.Build.0 = Debug|Win32 + {6BFE3E13-BD5D-4C1C-BB29-A82FB51A16CE}.Debug|x64.ActiveCfg = Debug|x64 + {6BFE3E13-BD5D-4C1C-BB29-A82FB51A16CE}.Debug|x64.Build.0 = Debug|x64 + {6BFE3E13-BD5D-4C1C-BB29-A82FB51A16CE}.Release|Win32.ActiveCfg = Release|Win32 + {6BFE3E13-BD5D-4C1C-BB29-A82FB51A16CE}.Release|Win32.Build.0 = Release|Win32 + {6BFE3E13-BD5D-4C1C-BB29-A82FB51A16CE}.Release|x64.ActiveCfg = Release|x64 + {6BFE3E13-BD5D-4C1C-BB29-A82FB51A16CE}.Release|x64.Build.0 = Release|x64 + {B2F4BA6C-1BD6-4A50-A706-DCBC6A5D439B}.Debug|Win32.ActiveCfg = Debug|Win32 + {B2F4BA6C-1BD6-4A50-A706-DCBC6A5D439B}.Debug|Win32.Build.0 = Debug|Win32 + {B2F4BA6C-1BD6-4A50-A706-DCBC6A5D439B}.Debug|x64.ActiveCfg = Debug|x64 + {B2F4BA6C-1BD6-4A50-A706-DCBC6A5D439B}.Debug|x64.Build.0 = Debug|x64 + {B2F4BA6C-1BD6-4A50-A706-DCBC6A5D439B}.Release|Win32.ActiveCfg = Release|Win32 + {B2F4BA6C-1BD6-4A50-A706-DCBC6A5D439B}.Release|Win32.Build.0 = Release|Win32 + {B2F4BA6C-1BD6-4A50-A706-DCBC6A5D439B}.Release|x64.ActiveCfg = Release|x64 + {B2F4BA6C-1BD6-4A50-A706-DCBC6A5D439B}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/protocols/Weather/weather_10.vcxproj b/protocols/Weather/weather_10.vcxproj new file mode 100644 index 0000000000..988018944f --- /dev/null +++ b/protocols/Weather/weather_10.vcxproj @@ -0,0 +1,251 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + Weather + {6BFE3E13-BD5D-4C1C-BB29-A82FB51A16CE} + weather + + + + DynamicLibrary + + + DynamicLibrary + true + + + DynamicLibrary + + + DynamicLibrary + true + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(SolutionDir)$(Configuration)/Obj/$(ProjectName)\ + true + false + $(SolutionDir)$(Configuration)64/Plugins\ + $(SolutionDir)$(Configuration)64/Obj/$(ProjectName)\ + true + false + $(SolutionDir)$(Configuration)/Plugins\ + $(SolutionDir)$(Configuration)/Obj/$(ProjectName)\ + true + true + $(SolutionDir)$(Configuration)64/Plugins\ + $(SolutionDir)$(Configuration)64/Obj/$(ProjectName)\ + true + true + $(SolutionDir)$(Configuration)/Plugins\ + E:\Sources\include;$(IncludePath) + + + + Full + OnlyExplicitInline + true + Size + true + true + ../../include;../../plugins/ExternalAPI;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + false + MultiThreadedDLL + false + true + Fast + false + Level3 + weather.h + + + NDEBUG;%(PreprocessorDefinitions) + $(IntDir)weather.res + + + /ALIGN:4096 /filealign:0x200 /ignore:4108 %(AdditionalOptions) + %(AdditionalLibraryDirectories) + true + true + 0x72030000 + false + MachineX86 + $(IntDir)$(TargetName).lib + true + + + + + Full + OnlyExplicitInline + true + Size + true + ../../include;../../plugins/ExternalAPI;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + false + MultiThreadedDLL + false + true + Fast + false + weather.h + Level3 + + + NDEBUG;%(PreprocessorDefinitions) + $(IntDir)weather.res + + + /ALIGN:4096 /filealign:0x200 /ignore:4108 %(AdditionalOptions) + %(AdditionalLibraryDirectories) + true + true + 0x72030000 + false + MachineX64 + $(IntDir)$(TargetName).lib + true + + + + + Disabled + ../../include;../../plugins/ExternalAPI;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + EnableFastChecks + true + MultiThreadedDebugDLL + true + weather.h + Level3 + EditAndContinue + + + $(IntDir)weather.res + + + wsock32.lib;%(AdditionalDependencies) + %(AdditionalLibraryDirectories) + true + 0x72030000 + false + MachineX86 + $(IntDir)$(TargetName).lib + + + + + Disabled + ../../include;../../plugins/ExternalAPI;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + true + Fast + weather.h + Level3 + ProgramDatabase + + + $(IntDir)weather.res + + + %(AdditionalDependencies) + %(AdditionalLibraryDirectories) + true + 0x72030000 + false + MachineX64 + $(IntDir)$(TargetName).lib + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/protocols/Weather/weather_10.vcxproj.filters b/protocols/Weather/weather_10.vcxproj.filters new file mode 100644 index 0000000000..3fe49090b5 --- /dev/null +++ b/protocols/Weather/weather_10.vcxproj.filters @@ -0,0 +1,136 @@ + + + + + {ae98b833-66fd-4d03-8883-da86b699da8e} + cpp;c;cxx;rc;def;r;odl;idl;hpj;bat + + + {229b056a-ba07-4698-ad86-26548bd87e32} + h;hpp;hxx;hm;inl + + + {3433a4a3-b1af-4761-ab98-0d4ada361b3a} + + + {4be16e1a-70ca-4330-b259-db32ec58dcc0} + ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Documentations + + + Documentations + + + Documentations + + + Documentations + + + Documentations + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + + + Resource Files + + + \ No newline at end of file diff --git a/protocols/Weather/weather_addstn.cpp b/protocols/Weather/weather_addstn.cpp new file mode 100644 index 0000000000..24b965ce19 --- /dev/null +++ b/protocols/Weather/weather_addstn.cpp @@ -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 . +*/ + +/* 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("")); + 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(""); // to be entered + psr.firstName=" "; + psr.lastName=""; + psr.email=Translate(""); // 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/protocols/Weather/weather_contacts.cpp b/protocols/Weather/weather_contacts.cpp new file mode 100644 index 0000000000..94aae312fd --- /dev/null +++ b/protocols/Weather/weather_contacts.cpp @@ -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 . +*/ + +/* 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 = ( CntSetWndDataType* )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/protocols/Weather/weather_conv.cpp b/protocols/Weather/weather_conv.cpp new file mode 100644 index 0000000000..7679a6c440 --- /dev/null +++ b/protocols/Weather/weather_conv.cpp @@ -0,0 +1,838 @@ +/* +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 . +*/ + +/* +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; + } +} + +// elevation conversion +// tempchar = the string containing the elevation value +// unit = the unit for elevation +// return value = the converted elevation with unit; if fail, return original string +void GetElev(char *tempchar, char *unit, char *str) +{ + // unit can be ft, m + 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 m first + if (!_stricmp(unit, "M")) + tempunit = (double)output; + else if (!_stricmp(unit, "FT")) + tempunit = (double)output / 3.28; + + // convert to apporiate unit + switch (opt.eUnit) { + case 1: + intunit = (int)((tempunit*10 * 3.28) + 0.5); + wsprintf(str, "%i.%i %s", intunit/10, intunit%10, opt.DoNotAppendUnit ? "" : Translate("ft")); + break; + case 2: + intunit = (int)((tempunit*10) + 0.5); + wsprintf(str, "%i.%i %s", intunit/10, intunit%10, opt.DoNotAppendUnit ? "" : Translate("m")); + 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 #" + 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 ============ + +// 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; icond); 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("")); + 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("")) + 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 = ( LPWSTR )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 = ( LPWSTR )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/protocols/Weather/weather_data.cpp b/protocols/Weather/weather_data.cpp new file mode 100644 index 0000000000..86f051199f --- /dev/null +++ b/protocols/Weather/weather_data.cpp @@ -0,0 +1,500 @@ +/* +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 . +*/ + +/* +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("")); + 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("")) && 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); + } + // elevation + else if (!strcmp(UpdateData->Name, "Elevation") || !_stricmp(UpdateData->Unit, "FT") || + !_stricmp(UpdateData->Unit, "M")) + { + GetElev(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(""), 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/protocols/Weather/weather_http.cpp b/protocols/Weather/weather_http.cpp new file mode 100644 index 0000000000..eb69dd4ca7 --- /dev/null +++ b/protocols/Weather/weather_http.cpp @@ -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 . +*/ + +/* +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; iheadersCount; 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, "'); + 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/protocols/Weather/weather_icons.cpp b/protocols/Weather/weather_icons.cpp new file mode 100644 index 0000000000..e1b95c4405 --- /dev/null +++ b/protocols/Weather/weather_icons.cpp @@ -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 . +*/ + + +#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/protocols/Weather/weather_info.cpp b/protocols/Weather/weather_info.cpp new file mode 100644 index 0000000000..b5997feb6c --- /dev/null +++ b/protocols/Weather/weather_info.cpp @@ -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 . +*/ + + +/* +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 "%[]" + // 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/protocols/Weather/weather_ini.cpp b/protocols/Weather/weather_ini.cpp new file mode 100644 index 0000000000..363f2d364f --- /dev/null +++ b/protocols/Weather/weather_ini.cpp @@ -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 . +*/ + + +/* +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 = ( char* )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 = ( char* )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/protocols/Weather/weather_mwin.cpp b/protocols/Weather/weather_mwin.cpp new file mode 100644 index 0000000000..8f40fde594 --- /dev/null +++ b/protocols/Weather/weather_mwin.cpp @@ -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 . +*/ + +#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 = ( HFONT )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 = ( HFONT )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 = -13; + ReleaseDC(0, hdc); + + fontid.deffontsettings.charset = DEFAULT_CHARSET; + strcpy(fontid.deffontsettings.szFace, "Verdana"); + 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/protocols/Weather/weather_opt.cpp b/protocols/Weather/weather_opt.cpp new file mode 100644 index 0000000000..59419edf1b --- /dev/null +++ b/protocols/Weather/weather_opt.cpp @@ -0,0 +1,660 @@ +/* +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 . +*/ + +/* 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) + { + strcpy(str, C_DEFAULT); + wSetData(&opt.cText, Translate(str)); + } + if (strchr(in, 'b') != NULL) + { + strcpy(str, b_DEFAULT); + wSetData(&opt.bTitle, Translate(str)); + } + if (strchr(in, 'B') != NULL) + { + strcpy(str, B_DEFAULT); + wSetData(&opt.bText, Translate(str)); + } + if (strchr(in, 'N') != NULL) + { + strcpy(str, N_DEFAULT); + wSetData(&opt.nText, Translate(str)); + } + if (strchr(in, 'E') != NULL) + { + strcpy(str, E_DEFAULT); + wSetData(&opt.eText, Translate(str)); + } + if (strchr(in, 'H') != NULL) + { + strcpy(str, H_DEFAULT); + wSetData(&opt.hText, Translate(str)); + } + if (strchr(in, 'X') != NULL) + { + strcpy(str, X_DEFAULT); + wSetData(&opt.xText, Translate(str)); + } + if (strchr(in, 'P') != NULL) + { + strcpy(str, P_DEFAULT); + wSetData(&opt.pTitle, Translate(str)); + } + if (strchr(in, 'p') != NULL) + { + strcpy(str, p_DEFAULT); + wSetData(&opt.pText, Translate(str)); + } + if (strchr(in, 'S') != NULL) + { + strcpy(str, s_DEFAULT); + wSetData(&opt.sText, Translate(str)); + } +} + +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",30); + opt.NewBrowserWin = DBGetContactSettingByte(NULL,WEATHERPROTONAME,"NewWindow",TRUE); + opt.NoProtoCondition = DBGetContactSettingByte(NULL,WEATHERPROTONAME,"NoStatus",0); + 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", 128); + // units + opt.tUnit = (WORD)DBGetContactSettingWord(NULL, WEATHERPROTONAME, "tUnit", 1); + opt.wUnit = (WORD)DBGetContactSettingWord(NULL, WEATHERPROTONAME, "wUnit", 2); + opt.vUnit = (WORD)DBGetContactSettingWord(NULL, WEATHERPROTONAME, "vUnit", 1); + opt.pUnit = (WORD)DBGetContactSettingWord(NULL, WEATHERPROTONAME, "pUnit", 4); + opt.dUnit = (WORD)DBGetContactSettingWord(NULL, WEATHERPROTONAME, "dUnit", 1); + opt.eUnit = (WORD)DBGetContactSettingWord(NULL, WEATHERPROTONAME, "eUnit", 2); + if (DBGetContactSettingString(NULL,WEATHERPROTONAME,"DegreeSign",&dbv)) + strcpy(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, Translate(dbv.pszVal)); + DBFreeVariant(&dbv); + } + if (DBGetContactSettingString(NULL,WEATHERPROTONAME,"BriefTextTitle",&dbv)) + SetTextDefault("b"); + else + { + wSetData(&opt.bTitle, Translate(dbv.pszVal)); + DBFreeVariant(&dbv); + } + if (DBGetContactSettingString(NULL,WEATHERPROTONAME,"BriefText",&dbv)) + SetTextDefault("B"); + else + { + wSetData(&opt.bText, Translate(dbv.pszVal)); + DBFreeVariant(&dbv); + } + if (DBGetContactSettingString(NULL,WEATHERPROTONAME,"NoteText",&dbv)) + SetTextDefault("N"); + else + { + wSetData(&opt.nText, Translate(dbv.pszVal)); + DBFreeVariant(&dbv); + } + if (DBGetContactSettingString(NULL,WEATHERPROTONAME,"ExtText",&dbv)) + SetTextDefault("E"); + else + { + wSetData(&opt.eText, Translate(dbv.pszVal)); + DBFreeVariant(&dbv); + } + if (DBGetContactSettingString(NULL,WEATHERPROTONAME,"HistoryText",&dbv)) + SetTextDefault("H"); + else + { + wSetData(&opt.hText, Translate(dbv.pszVal)); + DBFreeVariant(&dbv); + } + if (DBGetContactSettingString(NULL,WEATHERPROTONAME,"ExtraText",&dbv)) + SetTextDefault("X"); + else + { + wSetData(&opt.xText, Translate(dbv.pszVal)); + DBFreeVariant(&dbv); + } + if (DBGetContactSettingString(NULL,WEATHERPROTONAME,"StatusText",&dbv)) + SetTextDefault("S"); + else + { + wSetData(&opt.sText, Translate(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_M2); + 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); + DBWriteContactSettingWord(NULL, WEATHERPROTONAME, "eUnit", opt.eUnit); + 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("Network"); + 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; + } + + switch (opt.eUnit) { // elev + case 1: CheckRadioButton(hdlg, IDC_E1, IDC_E2, IDC_E1); break; + case 2: CheckRadioButton(hdlg, IDC_E1, IDC_E2, IDC_E2); 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; + if (IsDlgButtonChecked(hdlg, IDC_E1)) opt.eUnit = 1; + if (IsDlgButtonChecked(hdlg, IDC_E2)) opt.eUnit = 2; + + // 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/protocols/Weather/weather_popup.cpp b/protocols/Weather/weather_popup.cpp new file mode 100644 index 0000000000..270f989c73 --- /dev/null +++ b/protocols/Weather/weather_popup.cpp @@ -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 . +*/ + +/* 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/protocols/Weather/weather_svcs.cpp b/protocols/Weather/weather_svcs.cpp new file mode 100644 index 0000000000..89c58c2d6e --- /dev/null +++ b/protocols/Weather/weather_svcs.cpp @@ -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 . +*/ + +/* +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/protocols/Weather/weather_update.cpp b/protocols/Weather/weather_update.cpp new file mode 100644 index 0000000000..9b81b023f5 --- /dev/null +++ b/protocols/Weather/weather_update.cpp @@ -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 . +*/ + +/* +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/protocols/Weather/weather_userinfo.cpp b/protocols/Weather/weather_userinfo.cpp new file mode 100644 index 0000000000..f608978c12 --- /dev/null +++ b/protocols/Weather/weather_userinfo.cpp @@ -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 . +*/ + + +/* +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 = ( LPSTR )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)) + { + strcpy(str, Translate("No information available.\r\nPlease update weather condition first.")); + } + 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); +} -- cgit v1.2.3