diff options
author | mataes2007 <mataes2007@e753b5eb-9565-29b2-b5c5-2cc6f99dfbcb> | 2011-11-26 12:28:23 +0000 |
---|---|---|
committer | mataes2007 <mataes2007@e753b5eb-9565-29b2-b5c5-2cc6f99dfbcb> | 2011-11-26 12:28:23 +0000 |
commit | 93d3575dff1db593b516821478510a4fecf0649e (patch) | |
tree | aa407bd7452b3ef9d7b2a42e0d04212315c56621 | |
parent | bc970507965a809727b3d5877884f21605fdf1a6 (diff) |
added ImportTrillian
git-svn-id: http://miranda-plugins.googlecode.com/svn/trunk@211 e753b5eb-9565-29b2-b5c5-2cc6f99dfbcb
-rw-r--r-- | ImportTrillian/docs/InstallScript.xml | 27 | ||||
-rw-r--r-- | ImportTrillian/docs/importTrillian.png | bin | 0 -> 8040 bytes | |||
-rw-r--r-- | ImportTrillian/docs/importTrillian_license.txt | 340 | ||||
-rw-r--r-- | ImportTrillian/docs/importTrillian_readme.txt | 112 | ||||
-rw-r--r-- | ImportTrillian/docs/importTrillian_translate.txt | 43 | ||||
-rw-r--r-- | ImportTrillian/import.ico | bin | 0 -> 3638 bytes | |||
-rw-r--r-- | ImportTrillian/main.c | 925 | ||||
-rw-r--r-- | ImportTrillian/resource.h | 69 | ||||
-rw-r--r-- | ImportTrillian/resource.rc | 247 |
9 files changed, 1763 insertions, 0 deletions
diff --git a/ImportTrillian/docs/InstallScript.xml b/ImportTrillian/docs/InstallScript.xml new file mode 100644 index 0000000..5b762dc --- /dev/null +++ b/ImportTrillian/docs/InstallScript.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="ISO-8859-1" ?>
+<installscript>
+ <info>
+ <name>Trillian history/contact import plugin</name>
+ <author>Daniel 'Spin' Hofer</author>
+ <version>0.2.0.0</version>
+ <type>plugin</type>
+ </info>
+
+ <packageinfo>
+ <title>Plugin File</title>
+ <file>importTrillian.dll</file>
+ </packageinfo>
+
+ <packageinfo>
+ <title>Readme, translate and license files</title>
+ <file>importTrillian_readme.txt</file>
+ <file>importTrillian_translate.txt</file>
+ <file>importTrillian_license.txt</file>
+ <optional/>
+ </packageinfo>
+
+ <autorun>
+ <file>importTrillian_readme.txt</file>
+ <document/>
+ </autorun>
+</installscript>
diff --git a/ImportTrillian/docs/importTrillian.png b/ImportTrillian/docs/importTrillian.png Binary files differnew file mode 100644 index 0000000..3b7b12e --- /dev/null +++ b/ImportTrillian/docs/importTrillian.png diff --git a/ImportTrillian/docs/importTrillian_license.txt b/ImportTrillian/docs/importTrillian_license.txt new file mode 100644 index 0000000..5b6e7c6 --- /dev/null +++ b/ImportTrillian/docs/importTrillian_license.txt @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/ImportTrillian/docs/importTrillian_readme.txt b/ImportTrillian/docs/importTrillian_readme.txt new file mode 100644 index 0000000..d3fcc02 --- /dev/null +++ b/ImportTrillian/docs/importTrillian_readme.txt @@ -0,0 +1,112 @@ +Trillian message history and contacts importer
+----------------------------------------------
+Imports message histories and contacts from Trillian instant messenger.
+Features:
+- Support for ICQ, MSN, AIM, Yahoo! and IRC protocols
+- Succesfully tested on various systems and Trillian log formats
+- New protocols can easily be added, just send me part of a log file
+- Lots of options for importing and yet:
+- Easy to use
+- UTF8 support (and detection)
+
+I included the source code so if you improve the Plugin please let me know:
+dhofer(at)freesurf(dot)ch
+
+Installation
+------------
+Copy the "importTrillian.dll" into your miranda\plugins directory. You can then import
+the history using the main menu entry.
+
+Importing history
+-----------------
+Select the menu entry "Import Trillian history/contacts..." in the main Menu. Then chose
+which protocols should be imported and click "Start". This will only import the history
+of existing contacts.
+It's highly recommended to deactivate any notification plugin/setting before importing
+the history!
+
+Importing contacts
+------------------
+Same as importing history but you have to select the "Add new contacts from history"
+option. If you imported the history of your existing contacts before you should
+deselect the "Import history of existing contacts" to avoid duplicate entires.
+This will ignore contacts with empty chat logs.
+
+ATTENTION
+---------
+This plugin works for my Trillian logs but it might import bogus data with your logs.
+It also doesn't check for dublicate messages so you'll have to let it complete the import.
+I'm not responsible for any damage caused by this plugin, use it at your own risk!
+(I recommend backing up the Miranda database before using it.)
+The import can take a long time (~1h for me).
+
+If you encounter a crash or a false import please send me the part of the Trillian .log
+file that isn't imported correctly and I'll try to fix it.
+
+Changelog
+---------
+
+0.2.0
+-----
+- Fixed some UTF8 importing issues
+- Added user options for log file format
+- Added the option to delete events prior to a specified date
+- Fixed a timestamp detection bug
+- Improved duplicate event handling
+
+0.1.8
+-----
+- Fixed folder selection issue
+
+0.1.7
+-----
+- Added fast mode
+
+0.1.6
+-----
+- Added option to skip duplicate events
+- Improved Trillian v3.1 support
+- Fixed crash bug
+- Fixed name length
+
+0.1.4
+-----
+- Added experimental Trillian v3.1 support
+- Fixed wrong message ordering
+- Fixed whitespace before sent messages
+- Fixed first log file not being imported
+- Fixed crash bug on some rare occasions
+
+0.1.2
+-----
+- Added translation support
+- Speed improvement
+- Recoded some functions
+- Added GPL headers & licence
+
+0.1.0
+-----
+- Added support for Yahoo! message history importing
+- Added support for IRC message history importing
+- Added contact importing
+- Added new options
+- Fixed a memory leak
+
+0.0.4
+------
+- Added support for AIM message history importing
+- Added importing of status report messages
+- Fixed import bug for messages with [h:m:s] time format
+
+0.0.2
+------
+- Added support for MSN message history importing
+- Improved dialogs
+
+0.0.1b
+------
+- Recompiled using proper flags
+
+0.0.1
+-----
+- Initial public release
\ No newline at end of file diff --git a/ImportTrillian/docs/importTrillian_translate.txt b/ImportTrillian/docs/importTrillian_translate.txt new file mode 100644 index 0000000..c1b99a6 --- /dev/null +++ b/ImportTrillian/docs/importTrillian_translate.txt @@ -0,0 +1,43 @@ +;Settins dialog
+[Import settings]
+[Trillian logs directory]
+[Protocols]
+[Contacts]
+[Import]
+[Browse]
+[Start]
+[Cancel]
+[Import ICQ history]
+[Import MSN history]
+[Import AIM history]
+[Import Yahoo! history]
+[Import IRC history]
+[Import IRC channel history]
+[Import history of existing contacts]
+[Add new contacts if a contact from the history is not on the list]
+[Skip duplicate messages]
+[Import messages]
+[Import status reports (filetransfers, away msg, etc.)]
+[Fast mode (backup your db!)]
+[There's nothing to import, please\nselect a protocol.]
+[Invalid settings]
+;Progress dialog
+[Importing History]
+[Import in progress...]
+[Overall (current protocol)]
+[File]
+[OK]
+[WARNING: If you cancel now and continue later you might\nget duplicate entries. Cancel anyways?]
+[Please select the \'logs\' folder in your Trillian directory]
+[Warning]
+[line]
+[No logs found for this protocol.]
+[Done importing %d contact history files!]
+[\nCheck your UIN and path settings. Path musst end with \\logs]
+[Import Trillian history/contacts...]
+[UTF8]
+[Replace duplicate messages]
+[Delete entries before]
+[(Must match this format exactly: MMM DD HH:mm:ss YYYY)]
+[Try to auto-detect UTF8 strings (is slow, detects öäüßéàèç)]
+[Interpret logs as UTF8 files]
\ No newline at end of file diff --git a/ImportTrillian/import.ico b/ImportTrillian/import.ico Binary files differnew file mode 100644 index 0000000..b7c7753 --- /dev/null +++ b/ImportTrillian/import.ico diff --git a/ImportTrillian/main.c b/ImportTrillian/main.c new file mode 100644 index 0000000..05a0724 --- /dev/null +++ b/ImportTrillian/main.c @@ -0,0 +1,925 @@ +/*
+ importTrillian: History & Contacts import plugin for Miranda-IM.
+ Copyright (C) 2005 Daniel 'Spin' Hofer
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+#include <windows.h>
+#include <time.h>
+#include <commctrl.h>
+#include <shlobj.h>
+#include <stdio.h>
+#include <io.h>
+#include "resource.h"
+#include "newpluginapi.h"
+#include "m_langpack.h"
+#include "m_system.h"
+#include "m_database.h"
+#include "m_clist.h"
+#include "m_protomod.h"
+
+#pragma warning( disable: 4311 )
+#pragma warning( disable: 4312 )
+
+#define IMPORT_MODULE "MIMImportTrillian"
+#define IMPORT_SERVICE "MIMImportTrillian/ImportTrillian"
+#define DLG_UPDATE 0x2000
+
+#define SESS_START1 "Session Start ("
+#define SESS_START2 "Start (ICQ - "
+#define SESS_START3 "Start (MSN - "
+#define SESS_START4 "Start (AIM - "
+#define SESS_START5 "Start (Yahoo! - "
+#define SESS_START6 "Start (IRC - "
+#define SESS_STOP "Session Close ("
+
+void Utf8ToAnsi(const char *szIn, char *szOut, int cchOut);
+
+static int ImportCommand( WPARAM wParam,LPARAM lParam );
+static int ImportMessages( );
+static char line[2048];
+static char file[MAX_PATH];
+static char delBeforeDate[MAX_PATH];
+static char icqUin[32];
+
+time_t delBeforeTS;
+static HANDLE hHookModulesLoaded;
+HINSTANCE hInst;
+PLUGINLINK *pluginLink;
+char status[256];
+BOOL importProt[5] = { 1, 1, 1, 1, 1 };
+BOOL importNic = TRUE;
+BOOL importCha = TRUE;
+BOOL importMsg = TRUE;
+BOOL importStat = TRUE;
+BOOL importAdd = FALSE;
+BOOL importEx = TRUE;
+BOOL skipDup = FALSE;
+BOOL repDup = TRUE;
+BOOL delBefore = FALSE;
+BOOL speedMode = TRUE;
+BOOL utf8AutoDetect = FALSE;
+BOOL utf8DoAlways = FALSE;
+int aborting = 0;
+int finished = 0;
+
+int getNick = 0;
+char lastNick[256];
+
+PLUGININFO pluginInfo = {
+ sizeof(PLUGININFO),
+ "Import Trillian history/contacts",
+ PLUGIN_MAKE_VERSION(0,2,0,0),
+ "Miranda IM history/contact import plugin.",
+ "Daniel \'Zpin\' Hofer",
+ "dhofer@freesurf.ch",
+ "©2006 by Daniel \'Zpin\' Hofer",
+ "http://www.zpin.ch",
+ 0,
+ 0
+};
+
+
+BOOL WINAPI DllMain( HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved )
+{
+ hInst = hinstDLL;
+ return TRUE;
+}
+
+static int readLine( FILE *f )
+{
+ int i = 0;
+ char chr;
+ chr = fgetc( f );
+ while( chr != '\n' && !feof( f ) && i < 2047 )
+ {
+ line[i++] = chr;
+ chr = fgetc( f );
+ }
+ line[i] = '\0';
+ return !feof( f );
+}
+
+struct tm string2Tm( char *string )
+{
+ char mon[4];
+ int mt = 0, day, hr, min, sec, yr;
+ struct tm starttime;
+
+ sscanf( string, "%3s %d %d:%d:%d %d", &mon, &day, &hr, &min, &sec, &yr );
+ if( !strcmp( mon, "Jan" ) )
+ mt = 0;
+ else if( !strcmp( mon, "Feb" ) )
+ mt = 1;
+ else if( !strcmp( mon, "Mar" ) )
+ mt = 2;
+ else if( !strcmp( mon, "Apr" ) )
+ mt = 3;
+ else if( !strcmp( mon, "May" ) )
+ mt = 4;
+ else if( !strcmp( mon, "Jun" ) )
+ mt = 5;
+ else if( !strcmp( mon, "Jul" ) )
+ mt = 6;
+ else if( !strcmp( mon, "Aug" ) )
+ mt = 7;
+ else if( !strcmp( mon, "Sep" ) )
+ mt = 8;
+ else if( !strcmp( mon, "Oct" ) )
+ mt = 9;
+ else if( !strcmp( mon, "Nov" ) )
+ mt = 10;
+ else if( !strcmp( mon, "Dec" ) )
+ mt = 11;
+
+ starttime.tm_mon = mt;
+ starttime.tm_mday = day;
+ starttime.tm_hour = hr;
+ starttime.tm_min = min;
+ starttime.tm_sec = sec;
+ starttime.tm_year = yr - 1900;
+ return starttime;
+}
+
+BOOL CALLBACK StartupDialogProc( HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam )
+{
+ FILE *fl;
+ switch( message )
+ {
+ case WM_INITDIALOG:
+ SetWindowText( hdlg, Translate( "Import settings" ) );
+
+ SetDlgItemText( hdlg, IDC_INFO1, Translate( "Trillian logs directory" ) );
+ SetDlgItemText( hdlg, IDC_INFO2, Translate( "Protocols" ) );
+ SetDlgItemText( hdlg, IDC_INFO3, Translate( "Contacts" ) );
+ SetDlgItemText( hdlg, IDC_INFO4, Translate( "Import" ) );
+ SetDlgItemText( hdlg, IDC_BROWSE, Translate( "Browse" ) );
+ SetDlgItemText( hdlg, IDC_UTF8, Translate( "UTF8" ) );
+
+ SetDlgItemText( hdlg, IDOK, Translate( "Start" ) );
+ SetDlgItemText( hdlg, IDCANCEL, Translate( "Cancel" ) );
+
+ SetDlgItemText( hdlg, IDC_IMPICQ, Translate( "Import ICQ history" ) );
+ SetDlgItemText( hdlg, IDC_IMPMSN, Translate( "Import MSN history" ) );
+ SetDlgItemText( hdlg, IDC_IMPAIM, Translate( "Import AIM history" ) );
+ SetDlgItemText( hdlg, IDC_IMPICQ, Translate( "Import ICQ history" ) );
+ SetDlgItemText( hdlg, IDC_IMPYAHOO, Translate( "Import Yahoo! history" ) );
+ SetDlgItemText( hdlg, IDC_IMPIRC, Translate( "Import IRC history" ) );
+ SetDlgItemText( hdlg, IDC_IMPCHA, Translate( "Import IRC channel history" ) );
+
+ SetDlgItemText( hdlg, IDC_IMPEX, Translate( "Import history of existing contacts" ) );
+ SetDlgItemText( hdlg, IDC_IMPADD, Translate( "Add new contacts if a contact from the history is not on the list" ) );
+ SetDlgItemText( hdlg, IDC_IMPMSG, Translate( "Import messages" ) );
+ SetDlgItemText( hdlg, IDC_SKIPDUP, Translate( "Skip duplicate messages" ) );
+ SetDlgItemText( hdlg, IDC_REPDUP, Translate( "Replace duplicate messages" ) );
+ SetDlgItemText( hdlg, IDC_DELBEF, Translate( "Delete entries before" ) );
+ SetDlgItemText( hdlg, IDC_DELBEFINFO, Translate( "(Must match this format exactly: MMM DD HH:mm:ss YYYY)" ) );
+ SetDlgItemText( hdlg, IDC_IMPSTAT, Translate( "Import status reports (filetransfers, away msg, etc.)" ) );
+ SetDlgItemText( hdlg, IDC_SPEEDMODE, Translate( "Fast mode (backup your db!)" ) );
+ SetDlgItemText( hdlg, IDC_UTF8AUTO, Translate( "Try to auto-detect UTF8 strings (is slow, detects öäüßéàèç)" ) );
+ SetDlgItemText( hdlg, IDC_UTF8ALWAYS, Translate( "Interpret logs as UTF8 files" ) );
+
+
+ ShowWindow( hdlg, SW_SHOW );
+ SendMessage( hdlg, WM_SETICON, ICON_BIG, (LPARAM)LoadIcon(hInst,MAKEINTRESOURCE(IDI_IMPORT)));
+ fl = fopen( "importTrillian.ini", "r" );
+ if( fl )
+ {
+ int i = -1;
+ do
+ {
+ i++;
+ file[i] = fgetc( fl );
+ } while( file[i] != EOF && file[i] != '\n' && i < MAX_PATH );
+ file[i] = '\0';
+ fclose( fl );
+ }
+
+ SendDlgItemMessage( hdlg, IDC_LOGDIR, WM_SETTEXT, 0, (DWORD)file );
+ SendDlgItemMessage( hdlg, IDC_DELBEFDATE, WM_SETTEXT, 0, (DWORD)"Mar 16 20:31:29 2005" );
+ CheckDlgButton( hdlg, IDC_IMPICQ, TRUE );
+ CheckDlgButton( hdlg, IDC_IMPMSN, TRUE );
+ CheckDlgButton( hdlg, IDC_IMPAIM, TRUE );
+ CheckDlgButton( hdlg, IDC_IMPYAHOO, TRUE );
+ CheckDlgButton( hdlg, IDC_IMPIRC, TRUE );
+ CheckDlgButton( hdlg, IDC_IMPCHA, TRUE );
+ CheckDlgButton( hdlg, IDC_IMPMSG, TRUE );
+ CheckDlgButton( hdlg, IDC_IMPSTAT, TRUE );
+ CheckDlgButton( hdlg, IDC_IMPEX, TRUE );
+ CheckDlgButton( hdlg, IDC_REPDUP, TRUE );
+ CheckDlgButton( hdlg, IDC_SPEEDMODE, TRUE );
+ return TRUE;
+ case WM_COMMAND:
+ switch( LOWORD( wParam ) )
+ {
+ case IDC_BROWSE:
+ {
+ BROWSEINFO bi = { 0 };
+ LPITEMIDLIST pidl = SHBrowseForFolder( &bi );
+ bi.lpszTitle = Translate( "Please select the \'logs\' folder in your Trillian directory" );
+ if( pidl != 0 )
+ SHGetPathFromIDList ( pidl, file );
+ SendDlgItemMessage( hdlg, IDC_LOGDIR, WM_SETTEXT, 0, (DWORD)file );
+ }
+ break;
+ case IDOK:
+ {
+ struct tm time;
+ importProt[0] = IsDlgButtonChecked( hdlg, IDC_IMPICQ );
+ importProt[1] = IsDlgButtonChecked( hdlg, IDC_IMPMSN );
+ importProt[2] = IsDlgButtonChecked( hdlg, IDC_IMPAIM );
+ importProt[3] = IsDlgButtonChecked( hdlg, IDC_IMPYAHOO );
+ importNic = IsDlgButtonChecked( hdlg, IDC_IMPIRC );
+ importCha = IsDlgButtonChecked( hdlg, IDC_IMPCHA );
+ importProt[4] = importNic || importCha;
+ importMsg = IsDlgButtonChecked( hdlg, IDC_IMPMSG );
+ importStat = IsDlgButtonChecked( hdlg, IDC_IMPSTAT );
+ importAdd = IsDlgButtonChecked( hdlg, IDC_IMPADD );
+ importEx = IsDlgButtonChecked( hdlg, IDC_IMPEX );
+ skipDup = IsDlgButtonChecked( hdlg, IDC_SKIPDUP );
+ repDup = IsDlgButtonChecked( hdlg, IDC_REPDUP );
+ delBefore = IsDlgButtonChecked( hdlg, IDC_DELBEF );
+ speedMode = IsDlgButtonChecked( hdlg, IDC_SPEEDMODE );
+ utf8AutoDetect = IsDlgButtonChecked( hdlg, IDC_UTF8AUTO );
+ utf8DoAlways = IsDlgButtonChecked( hdlg, IDC_UTF8ALWAYS );
+ GetDlgItemText( hdlg, IDC_LOGDIR, file, MAX_PATH-1 );
+ GetDlgItemText( hdlg, IDC_DELBEFDATE, delBeforeDate, MAX_PATH-1 );
+ time = string2Tm( delBeforeDate );
+ delBeforeTS = mktime( &time );
+ fl = fopen( "importTrillian.ini", "w" );
+ if( fl )
+ {
+ fprintf( fl, "%s", file );
+ fclose( fl );
+ }
+ if( ( importProt[0] || importProt[1] || importProt[2] || importProt[3] || importProt[4] ) && ( importMsg || importStat ) )
+ {
+ PostMessage( hdlg, WM_CLOSE, 0, 0 );
+ DestroyWindow(hdlg);
+ ImportMessages( );
+ }
+ else
+ MessageBox( hdlg, Translate( "There's nothing to import, please\nselect a protocol." ), Translate( "Invalid settings" ), 0 );
+ } break;
+ case IDCANCEL:
+ PostMessage( hdlg, WM_CLOSE, 0, 0 );
+ break;
+ }
+ break;
+ case WM_CLOSE:
+ DestroyWindow(hdlg);
+ aborting = 1;
+ break;
+ }
+ return FALSE;
+}
+
+BOOL CALLBACK ProgressDialogProc( HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam )
+{
+ switch( message )
+ {
+ case WM_INITDIALOG:
+ SetWindowText( hdlg, Translate( "Importing History" ) );
+
+ SetDlgItemText( hdlg, IDC_INFO5, Translate( "Import in progress..." ) );
+ SetDlgItemText( hdlg, IDC_INFO6, Translate( "Overall (current protocol)" ) );
+ SetDlgItemText( hdlg, IDC_INFO7, Translate( "File" ) );
+
+ SetDlgItemText( hdlg, IDOK, Translate( "OK" ) );
+ SetDlgItemText( hdlg, IDCANCEL, Translate( "Cancel" ) );
+
+ ShowWindow( hdlg, SW_SHOW );
+ SendMessage( hdlg, WM_SETICON, ICON_BIG, (LPARAM)LoadIcon( hInst,MAKEINTRESOURCE(IDI_IMPORT) ) );
+ return TRUE;
+ case WM_COMMAND:
+ switch( LOWORD( wParam ) )
+ {
+ case IDOK:
+ if( finished )
+ PostMessage( hdlg, WM_CLOSE, 0, 0 );
+ break;
+ case IDCANCEL:
+ {
+ int ret;
+ ret = MessageBox( hdlg, Translate( "WARNING: If you cancel now and continue later you might\nget duplicate entries. Cancel anyways?" ), Translate( "Warning" ), MB_YESNO );
+ if( ret == IDYES )
+ PostMessage( hdlg, WM_CLOSE, 0, 0 );
+ break;
+ }
+ }
+ break;
+ case DLG_UPDATE:
+ SendDlgItemMessage( hdlg, IDC_STATUS, WM_SETTEXT, 0, (DWORD)status );
+ SendDlgItemMessage( hdlg, IDC_FILEP, PBM_SETPOS, wParam, 0 );
+ SendDlgItemMessage( hdlg, IDC_OVERP, PBM_SETPOS, lParam, 0 );
+ break;
+ case WM_CLOSE:
+ DestroyWindow( hdlg );
+ aborting = 1;
+ break;
+ }
+ return FALSE;
+}
+
+HANDLE GetContactByID( char* proto, char *idname, char* id )
+{
+ HANDLE contact;
+ char *otherproto;
+ DBVARIANT dbv;
+ DWORD idnum = atol(id);
+
+ contact = (HANDLE)CallService( MS_DB_CONTACT_FINDFIRST, 0, 0 );
+ while( contact != NULL)
+ {
+ otherproto = (char*)CallService( MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)contact, 0 );
+ if( ( otherproto != NULL ) && !strcmp( otherproto, proto ) )
+ {
+ if( !DBGetContactSetting( contact, proto, idname, &dbv ) )
+ {
+ switch( dbv.type )
+ {
+ case DBVT_BYTE:
+ if( dbv.bVal == idnum )
+ return contact;
+ break;
+ case DBVT_WORD:
+ if( dbv.wVal == idnum )
+ return contact;
+ break;
+ case DBVT_DWORD:
+ if( dbv.dVal == idnum )
+ return contact;
+ break;
+ default:
+ case DBVT_ASCIIZ:
+ if( !strcmp( id, dbv.pszVal ) )
+ {
+ DBFreeVariant( &dbv );
+ return contact;
+ }
+ break;
+ }
+ }
+ }
+ contact = (HANDLE)CallService( MS_DB_CONTACT_FINDNEXT, (WPARAM)contact, 0 );
+ }
+ return INVALID_HANDLE_VALUE;
+}
+
+HANDLE DeleteContactEventsBefore( HANDLE hContact, time_t ts )
+{
+ HANDLE hDbEvent, hPrev;
+ DBEVENTINFO dbei;
+
+ if( !( hDbEvent = (HANDLE)CallService( MS_DB_EVENT_FINDFIRST, (WPARAM)hContact, 0 ) ) )
+ return INVALID_HANDLE_VALUE;
+
+ while( hDbEvent != NULL )
+ {
+ ZeroMemory( &dbei, sizeof(dbei) );
+ dbei.cbSize = sizeof(dbei);
+ dbei.cbBlob = 0;
+ CallService( MS_DB_EVENT_GET, (WPARAM)hDbEvent, (LPARAM)&dbei );
+
+ hPrev = hDbEvent;
+ hDbEvent = (HANDLE)CallService( MS_DB_EVENT_FINDNEXT, (WPARAM)hDbEvent, 0 );
+ if( (time_t)dbei.timestamp < ts )
+ CallService( MS_DB_EVENT_DELETE, (WPARAM)hContact, (LPARAM)hPrev );
+ }
+ return INVALID_HANDLE_VALUE;
+}
+
+//*****************************************
+// MODIFIED CODE FROM THE IMPORT.DLL PLUGIN!
+//*****************************************
+HANDLE IsDuplicateEvent(HANDLE hContact, DBEVENTINFO dbei )
+{
+ HANDLE hExistingDbEvent;
+ DBEVENTINFO dbeiExisting;
+
+ if( !( hExistingDbEvent = (HANDLE)CallService( MS_DB_EVENT_FINDLAST, (WPARAM)hContact, 0 ) ) )
+ return INVALID_HANDLE_VALUE;
+ ZeroMemory( &dbeiExisting, sizeof(dbeiExisting) );
+ dbeiExisting.cbSize = sizeof(dbeiExisting);
+ dbeiExisting.cbBlob = 0;
+ CallService( MS_DB_EVENT_GET, (WPARAM)hExistingDbEvent, (LPARAM)&dbeiExisting );
+ if( dbei.timestamp > dbeiExisting.timestamp )
+ return INVALID_HANDLE_VALUE;
+
+ if( !( hExistingDbEvent = (HANDLE)CallService( MS_DB_EVENT_FINDFIRST, (WPARAM)hContact, 0 ) ) )
+ return INVALID_HANDLE_VALUE;
+ ZeroMemory( &dbeiExisting, sizeof(dbeiExisting) );
+ dbeiExisting.cbSize = sizeof(dbeiExisting);
+ dbeiExisting.cbBlob = 0;
+ CallService( MS_DB_EVENT_GET, (WPARAM)hExistingDbEvent, (LPARAM)&dbeiExisting );
+ if( dbei.timestamp < dbeiExisting.timestamp )
+ return INVALID_HANDLE_VALUE;
+
+
+ while( hExistingDbEvent != NULL )
+ {
+ char *blob;
+ ZeroMemory( &dbeiExisting, sizeof(dbeiExisting) );
+ dbeiExisting.cbSize = sizeof(dbeiExisting);
+ dbeiExisting.cbBlob = CallService( MS_DB_EVENT_GETBLOBSIZE, (WPARAM)hExistingDbEvent, (LPARAM)0 );
+ blob = malloc( dbeiExisting.cbBlob );
+ dbeiExisting.pBlob = blob;
+ CallService( MS_DB_EVENT_GET, (WPARAM)hExistingDbEvent, (LPARAM)&dbeiExisting );
+ if( dbei.timestamp < dbeiExisting.timestamp )
+ {
+ free( blob );
+ return INVALID_HANDLE_VALUE;
+ }
+ // Compare event with import candidate
+ if( ( dbei.timestamp == dbeiExisting.timestamp ) &&
+ ( dbei.eventType == dbeiExisting.eventType ) &&
+ ( dbei.cbBlob == dbeiExisting.cbBlob ) )
+ {
+ if( !strcmp( dbei.pBlob, dbeiExisting.pBlob ) )
+ {
+ free( blob );
+ return hExistingDbEvent;
+ }
+ }
+ free( blob );
+ // Get next event in chain
+ hExistingDbEvent = (HANDLE)CallService( MS_DB_EVENT_FINDNEXT, (WPARAM)hExistingDbEvent, 0 );
+ }
+ return INVALID_HANDLE_VALUE;
+}
+
+HANDLE AddNumericContact( char* pszProtoName, char* pszUniqueSetting, DWORD dwID, char* pzsNick )
+{
+ HANDLE hContact = INVALID_HANDLE_VALUE;
+ hContact = (HANDLE)CallService( MS_DB_CONTACT_ADD, 0, 0 );
+ if( CallService( MS_PROTO_ADDTOCONTACT, (WPARAM)hContact, (LPARAM)pszProtoName ) != 0 )
+ {
+ CallService( MS_DB_CONTACT_DELETE, (WPARAM)hContact, 0 );
+ return INVALID_HANDLE_VALUE;
+ }
+ DBWriteContactSettingDword( hContact, pszProtoName, pszUniqueSetting, dwID );
+ if( pzsNick && pzsNick[0] )
+ DBWriteContactSettingString( hContact, "CList", "MyHandle", pzsNick );
+ return hContact;
+}
+
+HANDLE AddContact( char* pszProtoName, char* pszUniqueSetting, char* pszID, char* pzsNick )
+{
+ HANDLE hContact = INVALID_HANDLE_VALUE;
+ hContact = (HANDLE)CallService( MS_DB_CONTACT_ADD, 0, 0 );
+ if( CallService( MS_PROTO_ADDTOCONTACT, (WPARAM)hContact, (LPARAM)pszProtoName ) != 0 )
+ {
+ CallService( MS_DB_CONTACT_DELETE, (WPARAM)hContact, 0 );
+ return INVALID_HANDLE_VALUE;
+ }
+ DBWriteContactSettingString( hContact, pszProtoName, pszUniqueSetting, pszID );
+ if( pzsNick && pzsNick[0] )
+ DBWriteContactSettingString( hContact, "CList", "MyHandle", pzsNick );
+ return hContact;
+}
+
+// szIn, pointer to source string
+// szOut, pointer to destination buffer
+// cchOut, size of destination buffer
+void Utf8ToAnsi( const char *szIn, char *szOut, int cchOut )
+{
+ if( GetVersion( ) != 4 || !( GetVersion( ) & 0x80000000 ) )
+ {
+ WCHAR *wszTemp;
+ int inlen;
+ inlen = (int)strlen(szIn);
+ wszTemp = (WCHAR *)malloc( sizeof(WCHAR) * (inlen + 1) );
+ MultiByteToWideChar( CP_UTF8, 0, szIn, -1, wszTemp, inlen + 1 );
+ WideCharToMultiByte( CP_ACP, 0, wszTemp, -1, szOut, cchOut, NULL, NULL );
+ free(wszTemp);
+ }
+ else
+ {
+ for( ; *szIn && cchOut > 1; szIn++ )
+ {
+ if( *szIn >= 0 )
+ {
+ *szOut++ = *szIn;
+ cchOut--;
+ }
+ else
+ {
+ unsigned short wideChar;
+ if( (unsigned char)*szIn >= 0xe0 )
+ {
+ wideChar = ((szIn[0]&0x0f) << 12)
+ | ((szIn[1]&0x3f) << 6)
+ | (szIn[2]&0x3f);
+ szIn += 2;
+ }
+ else
+ {
+ wideChar = ( (szIn[0]&0x1f) << 6 ) | ( szIn[1]&0x3f );
+ szIn++;
+ }
+ if( wideChar >= 0x100 ) *szOut++ = '?';
+ else *szOut++ = (char)wideChar;
+ cchOut--;
+ }
+ }
+ *szOut = '\0';
+ }
+}
+//*****************************************
+// END CODE FROM THE IMPORT.DLL PLUGIN!
+//*****************************************
+
+BOOL importSingleHistory( char *logpath, HANDLE *hContact, char *prot, HWND *dlg, float overal )
+{
+ int i = 0, lineNr, lineTotal = 0, lastflag = 0, imp = 0;
+ char *time;
+ char *message;
+ DBEVENTINFO dbev;
+ HANDLE dup;
+ FILE *msg;
+ char other[256];
+ time_t startts, prev = 0;
+ struct tm starttime;
+ int hasTime = -1, timeType = 0;
+ int nameoffset[2][2] = { { 0, 8 }, { 0, 11 } };
+ BOOL doConversion = FALSE;
+ MSG pm;
+
+ msg = fopen( logpath, "r" );
+ lineTotal = 0;
+ startts = 0;
+ if( msg )
+ {
+ while( !feof( msg ) )
+ {
+ if( fgetc( msg ) == '\n' )
+ lineTotal++;
+ }
+ fseek( msg, 0, SEEK_SET );
+
+ lineNr = 0;
+ imp = FALSE;
+ }
+ lineTotal = max( 1, lineTotal );
+ while( msg && readLine( msg ) )
+ {
+ if( aborting )
+ return FALSE;
+ lineNr++;
+ ZeroMemory( &dbev, sizeof( dbev ) );
+ dbev.cbSize = sizeof(dbev);
+ dbev.eventType = EVENTTYPE_MESSAGE;
+ dbev.szModule = prot;
+
+ if( !( lineNr % 10 ) )
+ {
+ SendMessage( *dlg, DLG_UPDATE, 100 * lineNr / lineTotal, (LPARAM)overal );
+ wsprintf( status, "%s: %s %d/~%d", logpath, Translate( "line" ), lineNr, lineTotal );
+ }
+
+ if( !strlen( line ) )
+ {
+ }
+ // Inefficient but quite save.
+ else if( strstr( line, SESS_START1 )
+ || strstr( line, SESS_START2 )
+ || strstr( line, SESS_START3 )
+ || strstr( line, SESS_START4 )
+ || strstr( line, SESS_START5 ) )
+ {
+ if( !strrchr( line, ')' ) )
+ continue;
+ time = strrchr( line, ')' ) + 7;
+ starttime = string2Tm( time );
+ startts = mktime( &starttime );
+
+ hasTime = -1;
+
+ strncpy( other, strchr( line, ':' ) + 1, 255 );
+ if( strrchr( other, ')' ) )
+ *strrchr( other, ')' ) = '\0';
+ strcpy( lastNick, other );
+ }
+ else if( strstr( line, SESS_STOP ) )
+ {
+ }
+ else if( startts )
+ {
+ //FILE *f;
+ if( hasTime == -1 )
+ {
+ hasTime = 0;
+ if( line[0] == '[' && strncmp( line, other, strlen(other) ) )
+ {
+ int timelen = ( (int)strchr( line, ']' ) - (int)line );
+ if( timelen == 9 )
+ {
+ hasTime = 1;
+ timeType = 1;
+ }
+ else if( timelen == 6 )
+ {
+ hasTime = 1;
+ timeType = 0;
+ }
+ }
+ }
+
+ /*f = fopen( "test.log", "w" );
+ fprintf( f, "%s\n%s", &line[nameoffset[timeType][hasTime]], other );
+ fclose( f );*/
+ if( hasTime && line[0] != '[' )
+ {
+ if( !importMsg )
+ continue;
+ message = line;
+ dbev.flags = lastflag;
+ }
+ else if( !strncmp( &line[nameoffset[timeType][hasTime]], other, strlen(other) ) )
+ {
+ if( !importMsg )
+ continue;
+ dbev.flags = DBEF_READ;
+ message = line + nameoffset[timeType][hasTime] + strlen( other ) + 2;
+ }
+ else if( !strncmp( &line[nameoffset[timeType][hasTime]], "*** ", 4 ) )
+ {
+ if( !importStat )
+ continue;
+ dbev.flags = DBEF_READ;
+ message = line + nameoffset[timeType][hasTime];
+ }
+ else
+ {
+ if( !importMsg )
+ continue;
+ message = strchr( line + nameoffset[timeType][hasTime], ':' ) + 2;
+ if( (int)message == 2 )
+ message = line + nameoffset[timeType][hasTime] + 1;
+ dbev.flags = DBEF_SENT | DBEF_READ;
+ }
+
+ if( hasTime && line[0] == '[' && line[3] == ':')
+ {
+ int hr, min, sec;
+ if( timeType == 1 )
+ {
+ sscanf( line, "[%d:%d:%d", &hr, &min, &sec );
+ starttime.tm_sec = sec;
+ }
+ else
+ {
+ sscanf( line, "[%d:%d", &hr, &min );
+ starttime.tm_sec = 0;
+ }
+ starttime.tm_hour = hr;
+ starttime.tm_min = min;
+ startts = mktime( &starttime );
+ }
+ //if( startts == prev )
+ // startts += 4;
+
+ doConversion = FALSE;
+ if( utf8AutoDetect )
+ {
+ //Whatever :)
+ if( strstr( message, "ä" )
+ || strstr( message, "ö" )
+ || strstr( message, "ü" )
+ || strstr( message, "Ä" )
+ || strstr( message, "Ö" )
+ || strstr( message, "Ü" )
+ || strstr( message, "ß" )
+ || strstr( message, "é" )
+ || strstr( message, "Ã " )
+ || strstr( message, "è" )
+ || strstr( message, "É" )
+ || strstr( message, "À" )
+ || strstr( message, "È" )
+ || strstr( message, "ç" ) )
+ doConversion = TRUE;
+ }
+ else if( utf8DoAlways )
+ doConversion = TRUE;
+ if( doConversion )
+ Utf8ToAnsi( message, message, (int)strlen(message) );
+ imp = TRUE;
+
+ lastflag = dbev.flags;
+ dbev.timestamp = (DWORD)startts;
+ dbev.cbBlob = (DWORD)strlen( message ) + 1;
+ dbev.pBlob = (PBYTE)malloc( dbev.cbBlob );
+ CopyMemory( dbev.pBlob, message, dbev.cbBlob );
+ dbev.pBlob[dbev.cbBlob - 1] = 0;
+ if( ( dup = IsDuplicateEvent( *hContact, dbev ) ) == INVALID_HANDLE_VALUE )
+ CallService( MS_DB_EVENT_ADD, (WPARAM)*hContact, (LPARAM)&dbev );
+ else if( repDup )
+ {
+ CallService( MS_DB_EVENT_DELETE, (WPARAM)*hContact, (LPARAM)dup );
+ CallService( MS_DB_EVENT_ADD, (WPARAM)*hContact, (LPARAM)&dbev );
+ }
+ else
+ wsprintf( status, "Skipping dublicate entries..." );
+
+ prev = startts;
+ free( dbev.pBlob );
+ }
+ if( PeekMessage( &pm, NULL, 0, 0, PM_REMOVE ) )
+ {
+ TranslateMessage( &pm );
+ DispatchMessage( &pm );
+ }
+ }
+ if( msg )
+ fclose( msg );
+ return imp;
+}
+
+struct import
+{
+ char prot[8];
+ char id[8];
+ int num;
+};
+
+int numFiles( char *path )
+{
+ struct _finddata_t fl;
+ long curFl;
+ int num = 0;
+
+ if( ( curFl = (long)_findfirst( path, &fl ) ) == -1L )
+ return num;
+
+ while( _findnext( curFl, &fl ) == 0 )
+ {
+ num++;
+ }
+ _findclose( curFl );
+ return num;
+}
+
+struct import importList[6] =
+{
+ { "ICQ", "UIN", 1 },
+ { "MSN", "e-mail", 0 },
+ { "AIM", "SN", 0 },
+ { "YAHOO", "yahoo_id", 0 },
+ { "IRC", "Nick", 0 },
+ { "", "", 0 }
+};
+
+static int ImportMessages( )
+{
+ int i = 0, numImp = 0, contTotal = 0, contNr = 0, o;
+ HANDLE hContact;
+ char msgpath[128];
+ char id[64];
+ HWND dlg;
+ MSG pm;
+ struct _finddata_t fl;
+ long curFl;
+ int len, first = 1;
+
+ aborting = 0;
+ finished = 0;
+
+ dlg = CreateDialog( hInst, MAKEINTRESOURCE(IDD_TRILLIAN), NULL, (DLGPROC)ProgressDialogProc );
+ //contTotal = (int)CallService( MS_DB_CONTACT_GETCOUNT, 0, 0 );
+
+ if( speedMode )
+ CallService( MS_DB_SETSAFETYMODE, (WPARAM)FALSE, 0 );
+
+ while( !aborting && strlen( importList[i].prot ) )
+ {
+ if( !importProt[i] )
+ {
+ i++;
+ continue;
+ }
+ for( o = 0; o < 2; o++ )
+ {
+ first = 1;
+ contNr = -1;
+ sprintf( msgpath, "%s\\%s%s\\*.log", file, importList[i].prot, o == 0 ? "" : "\\Query" );
+ contTotal = numFiles( msgpath );
+
+ curFl = (long)_findfirst( msgpath, &fl );
+ //if( ( curFl = (long)_findfirst( msgpath, &fl ) ) == -1L )
+ // MessageBox( dlg, Translate( "No logs found for this protocol." ), importList[i].prot, 0 );
+
+ while( !aborting && ( ( first && curFl != -1 ) || ( _findnext( curFl, &fl ) == 0 ) ) )
+ {
+ first = 0;
+ contNr++;
+ if( !strncmp( fl.name, importList[i].prot, strlen( importList[i].prot ) ) )
+ continue;
+ if( !strcmp( importList[i].prot, "IRC" ) )
+ {
+ if( strchr( fl.name, '#' ) )
+ {
+ if( !importCha )
+ continue;
+ }
+ else if( !importNic )
+ continue;
+ }
+ len = (long)strrchr( fl.name, '.' ) - (long)fl.name;
+ strncpy( id, fl.name, len );
+ id[len] = '\0';
+ getNick = FALSE;
+
+ hContact = GetContactByID( importList[i].prot, importList[i].id, id );
+
+ sprintf( msgpath, "%s\\%s%s\\%s.log", file, importList[i].prot, o == 0 ? "" : "\\Query", id );
+ if( ( hContact == INVALID_HANDLE_VALUE ) && importAdd )
+ {
+ if( importList[i].num )
+ hContact = AddNumericContact( importList[i].prot, importList[i].id, atol(id), 0 );
+ else
+ hContact = AddContact( importList[i].prot, importList[i].id, id, 0 );
+ getNick = TRUE;
+ }
+ else if( !importEx )
+ continue;
+ if( delBefore )
+ DeleteContactEventsBefore( hContact, delBeforeTS );
+ if( ( hContact != INVALID_HANDLE_VALUE ) && importSingleHistory( msgpath, &hContact, importList[i].prot, &dlg, 100.0f * contNr / contTotal ) )
+ numImp++;
+ if( getNick )
+ DBWriteContactSettingString( hContact, "CList", "MyHandle", lastNick );
+ }
+ _findclose( curFl );
+ }
+ i++;
+ }
+
+ if( speedMode )
+ CallService( MS_DB_SETSAFETYMODE, (WPARAM)TRUE, 0 );
+
+ finished = 1;
+
+ wsprintf( status, Translate( "Done importing %d contact history files!" ), numImp );
+ if( numImp == 0 )
+ strcat( status, Translate( "\nCheck your UIN and path settings. Path musst end with \\logs" ) );
+ SendMessage( dlg, DLG_UPDATE, 100, 100 );
+
+ while( PeekMessage( &pm, NULL, 0, 0, PM_REMOVE ) )
+ {
+ TranslateMessage( &pm );
+ DispatchMessage( &pm );
+ }
+ return 0;
+}
+
+static int ImportCommand( WPARAM wParam,LPARAM lParam )
+{
+ HWND dlg;
+ strcpy( file, "C:\\Program Files\\Trillian\\users\\default\\logs" );
+ dlg = CreateDialog( hInst, MAKEINTRESOURCE(IDD_STARTUP), NULL, (DLGPROC)StartupDialogProc );
+ return 0;
+}
+
+__declspec(dllexport) PLUGININFO* MirandaPluginInfo( DWORD mirandaVersion )
+{
+ if (mirandaVersion < PLUGIN_MAKE_VERSION(0, 1, 1, 0))
+ return NULL;
+
+ return &pluginInfo;
+}
+
+int __declspec(dllexport) Load( PLUGINLINK *link )
+{
+ CLISTMENUITEM mi;
+
+ pluginLink = link;
+ CreateServiceFunction( IMPORT_SERVICE, ImportCommand );
+
+ ZeroMemory( &mi, sizeof( mi ) );
+ mi.cbSize = sizeof( mi );
+ mi.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_IMPORT));
+ mi.pszName = Translate( Translate( "Import Trillian history/contacts..." ) );
+ mi.position = 500050000;
+ mi.pszService = IMPORT_SERVICE;
+ CallService( MS_CLIST_ADDMAINMENUITEM, 0, (LPARAM)&mi );
+ return 0;
+}
+
+
+int __declspec(dllexport) Unload( void )
+{
+ return 0;
+}
\ No newline at end of file diff --git a/ImportTrillian/resource.h b/ImportTrillian/resource.h new file mode 100644 index 0000000..a588d3b --- /dev/null +++ b/ImportTrillian/resource.h @@ -0,0 +1,69 @@ +//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by resource.rc
+//
+#define IDC_BACK 3
+#define IDD_TRILLIAN 105
+#define IDD_DIALOG1 106
+#define IDD_STARTUP 106
+#define IDI_IMPORT 177
+#define IDC_MIRABILIS 1000
+#define IDC_DONTLOADPLUGIN 1001
+#define IDC_MIRANDA 1001
+#define IDC_USEFINDADD 1004
+#define IDC_OTHER 1005
+#define IDC_LIST 1006
+#define IDC_FILENAME 1007
+#define IDC_PROGRESS 1008
+#define IDC_FILEP 1008
+#define IDC_STATUS 1009
+#define IDC_MIRABILISRUNNING 1010
+#define IDC_OVERP 1010
+#define IDC_RADIO_ALL 1016
+#define IDC_RADIO_CONTACTS 1017
+#define IDC_STATIC_ALL 1019
+#define IDC_STATIC_CONTACTS 1020
+#define IDC_ICQUIN 1025
+#define IDC_LOGDIR 1027
+#define IDC_BROWSE 1028
+#define IDC_IMPICQ 1029
+#define IDC_IMPMSN 1030
+#define IDC_IMPAIM 1031
+#define IDC_IMPIRC 1032
+#define IDC_IMPMSG 1033
+#define IDC_IMPSTAT 1034
+#define IDC_IMPADD 1035
+#define IDC_IMPEX 1036
+#define IDC_IMPYAHOO 1037
+#define IDC_IMPIRC2 1038
+#define IDC_IMPCHA 1038
+#define IDC_INFO1 1039
+#define IDC_INFO2 1040
+#define IDC_INFO3 1041
+#define IDC_INFO4 1042
+#define IDC_INFO5 1043
+#define IDC_SKIPDUP 1043
+#define IDC_INFO6 1044
+#define IDC_IMPSTAT2 1044
+#define IDC_SPEEDMODE 1044
+#define IDC_REPDUP 1045
+#define IDC_DELBEFDATE 1046
+#define IDC_DELBEF 1047
+#define IDC_UTF8ALWAYS 1048
+#define IDC_UTF8h 1049
+#define IDC_UTF8AUTO 1049
+#define IDC_UTF8 1050
+#define IDC_STATIC -1
+#define IDC_INFO7 -1
+#define IDC_DELBEFINFO -1
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 107
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1051
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/ImportTrillian/resource.rc b/ImportTrillian/resource.rc new file mode 100644 index 0000000..ce5e864 --- /dev/null +++ b/ImportTrillian/resource.rc @@ -0,0 +1,247 @@ +// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include <windows.h>
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// German (Switzerland) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DES)
+#ifdef _WIN32
+LANGUAGE LANG_GERMAN, SUBLANG_GERMAN_SWISS
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+ IDD_TRILLIAN, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 265
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 83
+ END
+
+ IDD_STARTUP, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 239
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 246
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_TRILLIAN DIALOGEX 0, 0, 272, 90
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP |
+ WS_CAPTION
+CAPTION "Importing History"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ DEFPUSHBUTTON "OK",IDOK,215,7,50,14,BS_FLAT
+ PUSHBUTTON "Cancel",IDCANCEL,215,24,50,14,BS_FLAT
+ LTEXT "Import in progress...",IDC_INFO5,7,7,85,9
+ LTEXT "Static",IDC_STATUS,7,22,206,22
+ CONTROL "",IDC_FILEP,"msctls_progress32",WS_BORDER | 0x1,7,75,
+ 197,8
+ LTEXT "File",IDC_INFO7,7,64,48,8
+ CONTROL "",IDC_OVERP,"msctls_progress32",WS_BORDER | 0x1,7,55,
+ 197,8
+ LTEXT "Overall (current protocol)",IDC_INFO6,7,47,118,8
+END
+
+IDD_STARTUP DIALOGEX 0, 0, 246, 254
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP |
+ WS_CAPTION
+CAPTION "Import settings"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ PUSHBUTTON "Cancel",IDCANCEL,64,65,50,14,BS_FLAT
+ EDITTEXT IDC_LOGDIR,7,17,232,12,ES_AUTOHSCROLL | NOT WS_BORDER,
+ WS_EX_STATICEDGE
+ LTEXT "Trillian logs directory",IDC_INFO1,7,7,67,8
+ PUSHBUTTON "Browse",IDC_BROWSE,75,7,32,10,BS_FLAT
+ CONTROL "Import ICQ history",IDC_IMPICQ,"Button",BS_AUTOCHECKBOX |
+ BS_FLAT | WS_TABSTOP,12,94,81,8
+ CONTROL "Import MSN history",IDC_IMPMSN,"Button",BS_AUTOCHECKBOX |
+ BS_FLAT | WS_TABSTOP,12,109,82,8
+ CONTROL "Import AIM history",IDC_IMPAIM,"Button",BS_AUTOCHECKBOX |
+ BS_FLAT | WS_TABSTOP,12,124,82,8
+ DEFPUSHBUTTON "Start",IDOK,7,65,50,14,BS_FLAT
+ CONTROL "Import messages",IDC_IMPMSG,"Button",BS_AUTOCHECKBOX |
+ BS_FLAT | WS_TABSTOP,108,143,123,8
+ CONTROL "Import status reports (filetransfers, away msg, etc.)",
+ IDC_IMPSTAT,"Button",BS_AUTOCHECKBOX | BS_MULTILINE |
+ BS_FLAT | WS_TABSTOP,108,178,128,16
+ GROUPBOX "Protocols",IDC_INFO2,7,84,91,124
+ GROUPBOX "Contacts",IDC_INFO3,103,84,136,46
+ CONTROL "Import IRC history",IDC_IMPIRC,"Button",BS_AUTOCHECKBOX |
+ BS_FLAT | WS_TABSTOP,12,155,78,8
+ CONTROL "Add new contacts if a contact from the history is not on the list",
+ IDC_IMPADD,"Button",BS_AUTOCHECKBOX | BS_MULTILINE |
+ BS_FLAT | WS_TABSTOP,108,110,126,16
+ CONTROL "Import history of existing contacts",IDC_IMPEX,"Button",
+ BS_AUTOCHECKBOX | BS_MULTILINE | BS_FLAT | WS_TABSTOP,
+ 108,94,125,14
+ CONTROL "Import Yahoo! history",IDC_IMPYAHOO,"Button",
+ BS_AUTOCHECKBOX | BS_FLAT | WS_TABSTOP,12,139,84,8
+ CONTROL "Import IRC channel history",IDC_IMPCHA,"Button",
+ BS_AUTOCHECKBOX | BS_MULTILINE | BS_FLAT | WS_TABSTOP,12,
+ 168,78,16
+ GROUPBOX "Import",IDC_INFO4,103,133,136,75
+ CONTROL "Skip duplicate messages",IDC_SKIPDUP,"Button",
+ BS_AUTOCHECKBOX | BS_FLAT | WS_TABSTOP,108,155,123,8
+ CONTROL "Fast mode (backup your db!)",IDC_SPEEDMODE,"Button",
+ BS_AUTOCHECKBOX | BS_MULTILINE | BS_FLAT | WS_TABSTOP,
+ 108,195,128,8
+ CONTROL "Replace duplicate messages",IDC_REPDUP,"Button",
+ BS_AUTOCHECKBOX | BS_FLAT | WS_TABSTOP,108,168,123,8
+ EDITTEXT IDC_DELBEFDATE,93,32,146,12,ES_AUTOHSCROLL | NOT
+ WS_BORDER,WS_EX_STATICEDGE
+ CONTROL "Delete entries before",IDC_DELBEF,"Button",
+ BS_AUTOCHECKBOX | BS_FLAT | WS_TABSTOP,8,35,83,8
+ LTEXT "(Must match this format exactly: MMM DD HH:mm:ss YYYY)",
+ IDC_DELBEFINFO,7,47,232,11
+ GROUPBOX "UTF8",IDC_UTF8,7,211,232,35
+ CONTROL "Interpret logs as UTF8 files",IDC_UTF8ALWAYS,"Button",
+ BS_AUTOCHECKBOX | BS_MULTILINE | BS_FLAT | WS_TABSTOP,13,
+ 222,128,8
+ CONTROL "Try to auto-detect UTF8 strings (is slow, detects öäüßéàèç)",
+ IDC_UTF8AUTO,"Button",BS_AUTOCHECKBOX | BS_MULTILINE |
+ BS_FLAT | WS_TABSTOP,13,234,209,8
+END
+
+#endif // German (Switzerland) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.K.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include <windows.h>\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // English (U.K.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (Australia) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENA)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_AUS
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_IMPORT ICON "import.ico"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 0,2,0,0
+ PRODUCTVERSION 0,0,0,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "000004b0"
+ BEGIN
+ VALUE "Comments", "Licensed under the terms of the GNU General Public License"
+ VALUE "CompanyName", " "
+ VALUE "FileDescription", "Miranda IM Message/Contact Import Plugin"
+ VALUE "FileVersion", "0.2.0"
+ VALUE "InternalName", "importTrillian"
+ VALUE "LegalCopyright", "Copyright © 2006 Daniel 'Zpin' Hofer"
+ VALUE "OriginalFilename", "importTrillian.dll"
+ VALUE "ProductVersion", "0, 0, 0, 0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x0, 1200
+ END
+END
+
+#endif // English (Australia) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
|